@xauyxau/hnch 1.17.2 → 1.19.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.js CHANGED
@@ -1,29 +1,30 @@
1
1
  #!/usr/bin/env node
2
- import Ud from'yargs';import {hideBin}from'yargs/helpers';import wn,{useState,useEffect,useCallback,useMemo,useRef}from'react';import {render,useApp,useInput,Box,Text}from'ink';import {existsSync,readFileSync,writeFileSync,unlinkSync,mkdirSync,chmodSync}from'fs';import {homedir}from'os';import {join}from'path';import {randomUUID}from'crypto';import {createInterface}from'readline';import*as $e from'yjs';import {Awareness}from'y-protocols/awareness';import {WebsocketProvider}from'y-websocket';import ba from'ws';import Ps from'clipboardy';import {jsxs,jsx,Fragment}from'react/jsx-runtime';var $t="hnch_abstain";function ee(e){return e===$t}var Te="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Lt=Te.length,Pn=Math.floor(Lt/2);function ct(e){let t=Te.indexOf(e);if(t===-1)throw new Error(`fractional-index: invalid character '${e}'`);return t}function To(e,t){return e.length>=t?e:e+"0".repeat(t-e.length)}function hi(e){let t=e.length-1;for(;t>0&&e[t]==="0";)t--;return e.slice(0,t+1)}function Si(e,t){let n=e.length,o=Array.from({length:n+1}).fill(0),r=0;for(let i=n-1;i>=0;i--){let d=e[i]+t[i]+r;o[i+1]=d%Lt,r=Math.floor(d/Lt);}o[0]=r;let s=Array.from({length:n+1}).fill(0),a=0;for(let i=0;i<=n;i++){let d=o[i]+a*Lt;s[i]=Math.floor(d/2),a=d%2;}return s.slice(1)}function Nn(e,t){let n=Te[Pn];if(e===null&&t===null)return n+n;if(t===null)return e+n+n+n+n;if(e===null)return xi(t);if(e>=t)throw new Error(`keyBetween: a must be < b (a='${e}', b='${t}')`);return wi(e,t)}function xi(e){for(let t=e.length-1;t>=0;t--){let n=ct(e[t]);if(n>0)return e.slice(0,t)+Te[n-1]+Te[Pn]}if(e.length>1)return e.slice(0,-1);throw new Error(`keyBetween: cannot generate key before '${e}' \u2014 use keyBetween(null, null) for the initial key`)}function wi(e,t){let n=Math.max(e.length,t.length),o=To(e,n).split("").map(d=>ct(d)),r=To(t,n).split("").map(d=>ct(d)),a=Si(o,r).map(d=>Te[d]).join(""),i=hi(a);return i>e&&i<t?i:a>e&&a<t?a:Ci(e,t)}function Ci(e,t){for(let n=0;n<t.length;n++){let o=n<e.length?ct(e[n]):0;if(ct(t[n])===o+1)return (n<e.length?e.slice(0,n+1):e+Te[0])+Te[Pn]}throw new Error(`keyBetween: space exhausted between '${e}' and '${t}'`)}function On(e){let{revealedAt:t,skippedAt:n,discardedAt:o}=e;if(t===void 0&&n===void 0&&o===void 0)return null;let r=[];t!==void 0&&r.push({kind:"revealed",at:t}),n!==void 0&&r.push({kind:"skipped",at:n}),o!==void 0&&r.push({kind:"discarded",at:o});let s={revealed:0,skipped:1,discarded:2};return r.sort((a,i)=>a.at-i.at||s[a.kind]-s[i.kind]),r[0].kind}function lt(e){return e==="revealed"||e==="skipped"||e==="discarded"}function Ut(e){return e==="revealed"||e==="skipped"}function Qe(e){return !lt(e)}var Ht="meta",jt="settings",Ft="participants",Vt="rounds",Jt="agenda",yi=["roomUuid","createdAt","createdBy","sessionEndedAt"],vi=["name","defaultScale","hostParticipantId"],Ii=["displayName","joinedAt","role","leftAt","removedBy","avatarColor"],bi=["id","title","description","ticketId","state","source","externalId","sortKey","createdAt","consumedAt","consumedByRoundId"],Ai=["id","title","description","ticketId","parentRoundId","scale","timerStartedAt","revealedAt","skippedAt","discardedAt","discardedBy","createdBy","createdAt","agendaItemId"];function Bt(e){return e.getMap(Ht)}function Yt(e){return e.getMap(jt)}function Ee(e){return e.getMap(Ft)}function Dn(e){return e.getArray(Vt)}function ut(e){return e.getArray(Jt)}function ft(e,t){let n={};for(let o of t){let r=e.get(o);r!==void 0&&(n[o]=r);}return n}function Ri(e){return ft(Bt(e),yi)}function Ti(e){return ft(Yt(e),vi)}function Ei(e){let t=Ee(e),n=[];return t.forEach((o,r)=>{let s=ft(o,Ii);n.push({id:r,...s});}),n.sort((o,r)=>o.joinedAt-r.joinedAt||o.id.localeCompare(r.id)),n}function ki(e){let t={};return e.forEach((n,o)=>{t[o]=n;}),t}function Pi(e){let t=ft(e,Ai),n=e.get("votes"),o=n?ki(n):{},r=On(t),{revealedAt:s,skippedAt:a,discardedAt:i,...d}=t,u=r??(t.timerStartedAt!==void 0?"voting":"pending"),l=r==="revealed"?s:r==="skipped"?a:r==="discarded"?i:void 0;return l===void 0?{...d,votes:o,status:u}:{...d,votes:o,status:u,terminalAt:l}}function Ni(e){let t=Dn(e),n=[];return t.forEach(o=>{n.push(Pi(o));}),n}function Oi(e){return ft(e,bi)}function Di(e){let t=ut(e),n=[];return t.forEach(o=>{n.push(Oi(o));}),n.sort((o,r)=>o.sortKey.localeCompare(r.sortKey)),n}function q(e){return {meta:Ri(e),settings:Ti(e),participants:Ei(e),rounds:Ni(e),agenda:Di(e)}}function _n(e,t){if(Bt(e).has("roomUuid"))throw new Error("initDoc: doc already seeded");e.transact(()=>{let n=Bt(e);n.set("roomUuid",t.roomUuid),n.set("createdAt",t.createdAt),n.set("createdBy",t.participantId);let o=Yt(e);t.sessionName!==void 0&&o.set("name",t.sessionName),o.set("defaultScale",t.defaultScale),o.set("hostParticipantId",t.participantId);let r=new $e.Map;r.set("displayName",t.displayName),r.set("joinedAt",t.createdAt),t.avatarColor!==void 0&&r.set("avatarColor",t.avatarColor),Ee(e).set(t.participantId,r);});}function Mn(e,t){e.transact(()=>{let n=Ee(e),o=n.get(t.participantId),r=o??new $e.Map;r.set("displayName",t.displayName),o===void 0&&r.set("joinedAt",t.joinedAt),t.avatarColor!==void 0&&r.set("avatarColor",t.avatarColor),r.delete("leftAt"),r.delete("removedBy"),o===void 0&&n.set(t.participantId,r);});}function Wt(e,t){e.transact(()=>{let n=Yt(e);for(let[o,r]of Object.entries(t))r===void 0?n.delete(o):n.set(o,r);});}function $n(e,t){Wt(e,t);}function Ln(e,t,n){e.transact(()=>{let o=Ee(e),r=o.get(t),s=r??new $e.Map;s.set("displayName",n.displayName),s.set("joinedAt",n.joinedAt),n.role!==void 0&&s.set("role",n.role),n.avatarColor!==void 0&&s.set("avatarColor",n.avatarColor),r===void 0&&o.set(t,s);});}function Eo(e,t,n){e.transact(()=>{let r=Ee(e).get(t);r&&r.set("avatarColor",n);});}function ko(e,t){let n=t.scale??Yt(e).get("defaultScale");if(!n)throw new Error("appendRound: no scale (settings.defaultScale missing)");if(t.parentRoundId!==void 0){let o=Le(e,t.parentRoundId);if(o!==void 0&&o.get("discardedAt")!==void 0)throw new Error(`appendRound: parentRoundId ${t.parentRoundId} points at a discarded round`)}return e.transact(()=>{let o=new $e.Map;o.set("id",t.id),o.set("createdAt",t.createdAt),o.set("createdBy",t.createdBy),o.set("scale",n),t.title!==void 0&&o.set("title",t.title),t.description!==void 0&&o.set("description",t.description),t.ticketId!==void 0&&o.set("ticketId",t.ticketId),t.parentRoundId!==void 0&&o.set("parentRoundId",t.parentRoundId),t.agendaItemId!==void 0&&o.set("agendaItemId",t.agendaItemId),o.set("timerStartedAt",t.createdAt),o.set("votes",new $e.Map),Dn(e).push([o]);}),t.id}function Un(e,t,n){let o=Le(e,t);if(!o)throw new Error(`patchRoundDescriptor: round ${t} not found`);e.transact(()=>{n.title!==void 0&&o.set("title",n.title),n.description!==void 0&&o.set("description",n.description);});}function Le(e,t){let n=Dn(e);for(let o=0;o<n.length;o+=1){let r=n.get(o);if(r.get("id")===t)return r}}function Bn(e){return On({revealedAt:e.get("revealedAt"),skippedAt:e.get("skippedAt"),discardedAt:e.get("discardedAt")})}function Po(e,t,n,o){let r=Le(e,t);if(!r)throw new Error(`castVote: round ${t} not found`);r.get("revealedAt")===void 0&&e.transact(()=>{r.get("votes").set(n,o);});}function Hn(e,t,n){let o=Le(e,t);if(!o)throw new Error(`clearVote: round ${t} not found`);o.get("revealedAt")===void 0&&e.transact(()=>{o.get("votes").delete(n);});}function No(e,t,n,o){let r=t.get("agendaItemId");if(r===void 0)return;let s=Kt(e,r);s!==void 0&&s.get("state")==="pending"&&(s.set("state","consumed"),s.set("consumedAt",o),s.set("consumedByRoundId",n));}function Oo(e,t,n){let o=Le(e,t);if(!o)throw new Error(`revealRound: round ${t} not found`);let r=Bn(o);if(r!==null)throw new Error(`revealRound: round ${t} already terminal (${r})`);e.transact(()=>{o.set("revealedAt",n),No(e,o,t,n);});}function Do(e,t,n){let o=Le(e,t);if(!o)throw new Error(`skipRound: round ${t} not found`);let r=Bn(o);if(r!==null)throw new Error(`skipRound: round ${t} already terminal (${r})`);e.transact(()=>{o.set("skippedAt",n),No(e,o,t,n);});}function _o(e,t,n,o){let r=Le(e,t);if(!r)throw new Error(`discardRound: round ${t} not found`);let s=Bn(r);if(s!==null)throw new Error(`discardRound: round ${t} already terminal (${s})`);e.transact(()=>{r.set("discardedAt",n),r.set("discardedBy",o);});}function Mo(e,t){e.transact(()=>{Bt(e).set("sessionEndedAt",t);});}function $o(e,t,n){let r=Ee(e).get(t);r&&e.transact(()=>{r.set("leftAt",n),r.set("removedBy",t);});}function Lo(e,t){let o=Ee(e).get(t);!o||!o.has("leftAt")||e.transact(()=>{o.delete("leftAt"),o.delete("removedBy");});}function Uo(e,t,n,o){if(n===t)return;let s=Ee(e).get(n);s&&e.transact(()=>{s.set("leftAt",o),s.set("removedBy",t);});}function me(e){let{rounds:t}=e;if(t.length===0)return null;for(let n=t.length-1;n>=0;n-=1){let o=t[n];if(o.status==="pending"||o.status==="voting")return o}for(let n=t.length-1;n>=0;n-=1){let o=t[n];if(o.status!=="discarded")return o}return null}function Ze(e){let{rounds:t}=e;for(let n=t.length-1;n>=0;n-=1){let o=t[n];if(Qe(o.status))return o}return null}function jn(e){let t=Object.values(e.votes);return t.length<2?false:t.every(n=>n===t[0])}function Kt(e,t){let n=ut(e);for(let o=0;o<n.length;o++){let r=n.get(o);if(r.get("id")===t)return r}}function pt(e,t){return !!e?.trim()||!!t?.trim()}function Bo(e,t){if(!pt(t.title,t.ticketId))throw new Error("appendAgendaItem: at least one of {title, ticketId} is required");let n=crypto.randomUUID(),o=ut(e),r=null;o.forEach(a=>{if(a.get("state")==="pending"){let i=a.get("sortKey");i!==void 0&&(r===null||i>r)&&(r=i);}});let s=Nn(r,null);return e.transact(()=>{let a=new $e.Map;a.set("id",n),a.set("state","pending"),a.set("source",t.source??"manual"),a.set("sortKey",s),a.set("createdAt",t.createdAt),t.title!==void 0&&a.set("title",t.title),t.description!==void 0&&a.set("description",t.description),t.ticketId!==void 0&&a.set("ticketId",t.ticketId),t.externalId!==void 0&&a.set("externalId",t.externalId),ut(e).push([a]);}),n}function Ho(e,t,n){let o=Kt(e,t);if(!o)throw new Error(`updateAgendaItemFields: item ${t} not found`);let r=o.get("state");if(r==="skipped"||r==="cancelled")throw new Error(`updateAgendaItemFields: item ${t} is ${r} and cannot be edited`);let s=n.title!==void 0?n.title:o.get("title"),a=n.ticketId!==void 0?n.ticketId:o.get("ticketId");if(!pt(s,a))throw new Error("updateAgendaItemFields: at least one of {title, ticketId} must remain non-empty");e.transact(()=>{n.title!==void 0&&o.set("title",n.title),n.ticketId!==void 0&&o.set("ticketId",n.ticketId),n.description!==void 0&&o.set("description",n.description);});}function Fn(e,t,n,o={}){let r=Kt(e,t);if(!r)throw new Error(`setAgendaItemState: item ${t} not found`);let s=r.get("state");if(!(s===n&&n==="consumed")){if(s!=="pending")throw new Error(`setAgendaItemState: invalid transition '${s}' \u2192 '${n}' for item ${t}`);if(n==="consumed"&&o.timestamp===void 0)throw new Error(`setAgendaItemState: timestamp is required when consuming item ${t}`);e.transact(()=>{r.set("state",n),n==="consumed"&&(r.set("consumedAt",o.timestamp),o.consumedByRoundId!==void 0&&r.set("consumedByRoundId",o.consumedByRoundId));});}}function jo(e,t,n,o){let r=Kt(e,t);if(!r)throw new Error(`reorderAgendaItem: item ${t} not found`);let s=r.get("state");if(s!=="pending")throw new Error(`reorderAgendaItem: item ${t} is ${s}; only pending items may be reordered`);let a=Nn(n??null,o??null);e.transact(()=>{r.set("sortKey",a);});}function Ue(e){for(let t of e.agenda)if(t.state==="pending")return t;return null}function Fo(e,t){let n=q(e).agenda.find(o=>o.id===t);return n||{applied:false,reason:"not-found"}}function Vn(e,t){let n=Fo(e,t);return mt(n)?n:n.state!=="pending"?{applied:false,reason:"not-pending"}:n}function _i(e){return e.state==="skipped"||e.state==="cancelled"}function mt(e){return "applied"in e}function Vo(e,t,n=Date.now){if(!pt(t.title,t.ticketId))return {applied:false,reason:"invalid-fields"};let o=n();return {applied:true,id:Bo(e,{...t,createdAt:o}),at:o}}function Jo(e,t,n){let o=Fo(e,t);if(mt(o))return o;if(_i(o))return {applied:false,reason:"not-pending"};let r=n.title!==void 0?n.title:o.title,s=n.ticketId!==void 0?n.ticketId:o.ticketId;return pt(r,s)?(Ho(e,t,n),{applied:true,id:t}):{applied:false,reason:"invalid-fields"}}function Yo(e,t){let n=Vn(e,t);return mt(n)?n:(Fn(e,t,"skipped"),{applied:true,id:t})}function Wo(e,t){let n=Vn(e,t);return mt(n)?n:(Fn(e,t,"cancelled"),{applied:true,id:t})}function Ko(e,t,n,o){let r=Vn(e,t);return mt(r)?r:(jo(e,t,n,o),{applied:true,id:t})}var Jn={"unknown-room":4001,"wrong-password":4002,"invalid-invite":4003,"expired-invite":4004,"invite-already-redeemed":4005,"room-full":4006,"malformed-credentials":4010},Go=new Map(Object.entries(Jn).map(([e,t])=>[t,e])),zo=20;function ge(e){return e.role??"voter"}function we(e){return e.leftAt===void 0}var Gt={id:"fibonacci",cards:["0","1","2","3","5","8","13","21"]},qo={id:"t-shirt",cards:["XS","S","M","L","XL"]},Xo={id:"powers-of-2",cards:["1","2","4","8","16","32","64"]},Qo={id:"linear",cards:["1","2","3","4","5","6","7","8","9","10"]},Zo={id:"risk",cards:["Low","Medium","High","Critical"]},de={[Gt.id]:Gt,[qo.id]:qo,[Xo.id]:Xo,[Qo.id]:Qo,[Zo.id]:Zo},er={fibonacci:"Fibonacci","t-shirt":"T-shirt","powers-of-2":"Powers of 2",linear:"Linear (1\u201310)",risk:"Risk"},Mi="Custom scale",$i=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;function tr(e){if(e in er)return er[e];if(e.length===0)return e;let t=e.startsWith("custom-")?e.slice(7):e;return t!==e&&$i.test(t)?Mi:t.split("-").map(n=>n.length===0?n:n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}function Li(e,t,n){if(!e||e.status!=="voting"&&e.status!=="pending")return false;let o=new Set(t.filter(d=>we(d)&&n.has(d.id)&&ge(d)!=="viewer").map(d=>d.id));if(o.size===0)return false;let r=Object.entries(e.votes).filter(([d])=>o.has(d)),s=r.filter(([,d])=>ee(d)).length,a=r.length-s,i=o.size-s;return i<=0?false:a>=i}function Ui(e,t){return e.participants.some(n=>we(n)&&n.id!==t)}function nr(e){function t(){let o=e.projection();if(!o||!e.presenceTrusted()&&Ui(o,e.selfId()))return;let r=me(o);Li(r,o.participants,e.onlineIds())&&e.reveal();}let n=e.subscribe(t);return t(),{stop(){n();}}}var et={"racing-green":{base:"#0B3D2E",soft:"rgba(11,61,46,0.14)",ink:"#fff",label:"Racing Green"},dijon:{base:"#C9A227",soft:"rgba(201,162,39,0.18)",ink:"#000",label:"Dijon"},blue:{base:"#0A84FF",soft:"rgba(10,132,255,0.14)",ink:"#fff",label:"Blue"},indigo:{base:"#5E5CE6",soft:"rgba(94,92,230,0.14)",ink:"#fff",label:"Indigo"},violet:{base:"#BF5AF2",soft:"rgba(191,90,242,0.14)",ink:"#fff",label:"Violet"},pink:{base:"#FF375F",soft:"rgba(255,55,95,0.14)",ink:"#fff",label:"Pink"},red:{base:"#FF453A",soft:"rgba(255,69,58,0.14)",ink:"#fff",label:"Red"},orange:{base:"#FF9F0A",soft:"rgba(255,159,10,0.16)",ink:"#000",label:"Orange"},amber:{base:"#FFD60A",soft:"rgba(255,214,10,0.18)",ink:"#000",label:"Amber"},green:{base:"#30D158",soft:"rgba(48,209,88,0.14)",ink:"#000",label:"Green"},teal:{base:"#40C8E0",soft:"rgba(64,200,224,0.14)",ink:"#000",label:"Teal"},graphite:{base:"#1C1C1E",soft:"rgba(28,28,30,0.10)",ink:"#fff",label:"Graphite"}};var gt=["racing-green","dijon","blue","indigo","violet","pink","red","orange","amber","green","teal","graphite"],Bi=/^#[0-9a-fA-F]{6}$/;function Hi(e){return Object.hasOwn(et,e)}function Be(e){return e?Hi(e)?et[e].base:Bi.test(e)?e.toLowerCase():null:null}function or(e){let t=5381;for(let o=0;o<e.length;o++)t=(t<<5)+t+e.charCodeAt(o)|0;let n=Math.abs(t)%gt.length;return gt[n]}var ji=5e3;function rr(e,t){let n=new Set;for(let o of e.participants)t.has(o.id)&&we(o)&&n.add(o.id);return n}function Fi(e,t,n){let o=e.settings.hostParticipantId;return o?rr(e,t).has(o)?{kind:"cancel"}:n.missingHostId!==o?{kind:"start-debounce",hostId:o}:{kind:"none"}:{kind:"none"}}function Vi(e,t,n,o){let r=e.settings.hostParticipantId;if(!o||r!==o)return {promote:false};let s=rr(e,t);if(s.has(r))return {promote:false};let a=[...s].toSorted();if(a.length===0)return {promote:false};let i=a[0];return i!==n?{promote:false}:{promote:true,winner:i}}function sr(e){let t=null,n=null;function o(){n!==null&&(clearTimeout(n),n=null),t=null;}function r(){n=null;let i=t;t=null;let d=e.projection(),u=e.myId();if(!d||u===null)return;let l=Vi(d,e.onlineIds(),u,i);l.promote&&e.promote(l.winner);}function s(){let i=e.projection();if(!i||e.myId()===null){o();return}let d=Fi(i,e.onlineIds(),{missingHostId:t});switch(d.kind){case "cancel":o();break;case "start-debounce":o(),t=d.hostId,n=setTimeout(r,ji);break;}}let a=e.subscribe(s);return s(),{stop(){o(),a();}}}function zt(e){let t=Math.max(0,Math.floor(e/1e3)),n=Math.floor(t/60),o=t%60;return `${n}:${o.toString().padStart(2,"0")}`}function ir(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return false}}function Yn(e){if(e===null||typeof e!="object"||Array.isArray(e))return {version:2,entries:{}};let t=e;if(t.version===2&&dr(t.entries)){let n=t.entries,o={};for(let[r,s]of Object.entries(n)){let a=Ji(s);a!==null&&(o[r]=a);}return {version:2,entries:o}}if(typeof t.roomCode=="string"&&typeof t.roomUuid=="string"&&typeof t.lastSeenAt=="number"){let n={roomCode:t.roomCode,roomUuid:t.roomUuid,lastSeenAt:t.lastSeenAt,...typeof t.passwordHash=="string"?{passwordHash:t.passwordHash}:{}};return {version:2,entries:{[n.roomUuid]:n}}}return {version:2,entries:{}}}function ar(e,t,n=864e5){let o={};for(let[r,s]of Object.entries(e.entries))t-s.lastSeenAt>n||(s.lastSeenAt>t?o[r]={...s,lastSeenAt:t}:o[r]=s);return {version:2,entries:o}}function dr(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Ji(e){if(!dr(e))return null;let t=e;return typeof t.roomCode!="string"||typeof t.roomUuid!="string"||typeof t.lastSeenAt!="number"?null:{roomCode:t.roomCode,roomUuid:t.roomUuid,lastSeenAt:t.lastSeenAt,...typeof t.passwordHash=="string"?{passwordHash:t.passwordHash}:{}}}function cr(e,t){let n=t.filter(f=>f.status!=="discarded"),o=new Map;for(let f of n)o.set(f.id,f);let r=o.get(e);if(r===void 0||r.parentRoundId===void 0)return null;let s=new Set([r.id]),a=r,i=1;for(;a.parentRoundId!==void 0;){let f=o.get(a.parentRoundId);if(f===void 0||s.has(f.id))return null;s.add(f.id),a=f,i+=1;}let d=a,u=new Map;for(let f of n){if(f.parentRoundId===void 0)continue;let k=u.get(f.parentRoundId);k===void 0?u.set(f.parentRoundId,[f]):k.push(f);}let l=0,c=[d];for(;c.length>0;){let f=c.shift();l+=1;let k=u.get(f.id);k!==void 0&&c.push(...k);}return {chainRoot:d,depth:i,total:l}}var ht=class extends Error{reason;constructor(t){super(`relay rejected resolve: ${t}`),this.reason=t,this.name="RelayRejectionError";}},Wn=1e4;async function ur(e,t){let n=await fetch(`${e}/rooms`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({}),signal:AbortSignal.timeout(Wn)});if(!n.ok)throw new Error(`POST /rooms failed: ${n.status}`);return await n.json()}function fr(e){if(typeof e!="object"||e===null)return null;let{reason:t}=e;return typeof t=="string"&&Object.hasOwn(Jn,t)?t:null}async function ce(e,t){let n=await fetch(`${e}/rooms/${encodeURIComponent(t)}`,{signal:AbortSignal.timeout(Wn)});if(n.status===404){let o=await n.json().catch(()=>null),r=fr(o);if(r!==null)throw new ht(r)}if(!n.ok)throw new Error(`GET /rooms/:code failed: ${n.status}`);return await n.json()}async function Kn(e,t,n){let o=await fetch(`${e}/rooms/${t}/access`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({passwordHash:n}),signal:AbortSignal.timeout(Wn)});if(!o.ok)throw new Error(`PATCH /rooms/:uuid/access failed: ${o.status}`);return await o.json()}var Wi=1,Ki=6e4,Gi=3,zi=5e3,qi=8e3;async function Xi(e,t,n){let o,r;try{let i=await fetch(`${e}/rooms/${encodeURIComponent(n.roomCode)}`,{signal:AbortSignal.timeout(qi)});o=i.status,r=await i.json().catch(()=>null);}catch{return null}if(o===404)return fr(r)==="unknown-room"?"unknown-room":null;if(o!==200||typeof r!="object"||r===null)return null;let{uuid:s,accessMode:a}=r;return typeof s!="string"?null:s!==t?"unknown-room":a==="password"&&n.passwordHash===void 0?"wrong-password":null}function Qi(e){return e.replace(/^https?:\/\//,t=>t==="https://"?"wss://":"ws://")}function lr(e){let t={did:e.deviceId};return e.passwordHash!==void 0&&(t.pw=e.passwordHash),t}function Zi(){return globalThis.window}function pr(e){let t="connecting",n=null,o=false,r=false,s=false,a=false,i=false,d=[],u=()=>{let T=o&&t!=="connected"&&n===null&&!r&&!a;T!==s&&(s=T,e.onReconnectingChange?.(T));},l=`${Qi(e.httpBaseUrl)}/ws`,c=e.credentials,f=new WebsocketProvider(l,e.roomUuid,e.doc,{params:lr(c),connect:true,...e.awareness!==void 0&&{awareness:e.awareness},...e.WebSocketPolyfill!==void 0&&{WebSocketPolyfill:e.WebSocketPolyfill}}),k=()=>{let{awareness:T}=f;for(let B of T.meta.keys())B!==T.clientID&&!T.states.has(B)&&T.meta.delete(B);},O=()=>{let T=f.awareness.getLocalState();T!==null&&f.awareness.setLocalState(T);},p=T=>{T!==i&&(i=T,e.onSyncedChange?.(T));};k();let g=T=>{t=T.status,T.status==="disconnected"&&k(),T.status==="connected"&&O(),e.onStatusChange?.(T.status),T.status==="connected"&&(o=true,a=false,n=null,e.onRejectionChange?.(null),d.length=0),u();},E=false,A=()=>{E=true;try{f.disconnect();}finally{E=false;}},b=T=>{n=T,e.onRejectionChange?.(T),f.shouldConnect=false,A(),u();},P=false,C=Number.NEGATIVE_INFINITY,L=()=>r||n!==null,I=async()=>{let T=Date.now();if(T<C&&(C=Number.NEGATIVE_INFINITY),P||T-C<zi)return;P=true,C=T;let B=c;try{let Y=await Xi(e.httpBaseUrl,e.roomUuid,B);if(Y===null||L()||t==="connected"||B!==c||a)return;b(Y);}finally{P=false;}},D=T=>{if(E)return;a=false;let B=T===null?void 0:Go.get(T.code);if(B===void 0){let Y=Date.now();d.push(Y);let m=Y-Ki;for(;d.length>0&&d[0]<m;)d.shift();d.length>=Gi&&(d.length=0,e.onRepeatRejection?.()),u(),I();return}b(B);};f.on("status",g),f.on("connection-close",D);let R=f,N=null;if(e.onSynced!==void 0){let T=B=>{B&&(R.off("synced",T),N=null,e.onSynced?.());};N=T,R.on("synced",T);}let J=T=>{p(T);};R.on("synced",J);let G=()=>{r||(t="disconnected",p(false),e.onStatusChange?.("disconnected"),u());},W=()=>{r||n!==null||t!=="connected"&&(f.ws!==null?(f.wsUnsuccessfulReconnects=0,f.ws.close()):f.connect());},y=Zi();y?.addEventListener("offline",G),y?.addEventListener("online",W);let V=false;return {awareness:f.awareness,updateCredentials(T){let B=T.passwordHash??void 0;B!==c.passwordHash&&(c=B===void 0?{roomCode:c.roomCode,deviceId:c.deviceId}:{...c,passwordHash:B},a=t==="connected",n!==null&&(n=null,e.onRejectionChange?.(null)),f.shouldConnect=false,A(),f.params=lr(c),f.connect());},async flush(T){let B=Date.now()+T;for(;;){let Y=f.ws;if(V||Y===null||Y.readyState!==Wi||Y.bufferedAmount===0||Date.now()>=B)return;await new Promise(m=>{setTimeout(m,16);});}},disconnect(){V||(V=true,r=true,u(),f.off("status",g),f.off("connection-close",D),N!==null&&(R.off("synced",N),N=null),R.off("synced",J),p(false),y?.removeEventListener("offline",G),y?.removeEventListener("online",W),f.shouldConnect=false,A(),f.destroy());}}}function St(e,t){return q(e).participants.find(n=>n.id===t)}function mr(e,t,n){let o=q(e);return {isHost:o.settings.hostParticipantId===t,target:o.participants.find(r=>r.id===n)}}function ea(e,t){return q(e).settings.hostParticipantId===t}function gr(e,t){let n=t.role??e.role;return {displayName:t.displayName??e.displayName,joinedAt:e.joinedAt,...n!==void 0&&{role:n},...e.avatarColor!==void 0&&{avatarColor:e.avatarColor}}}function hr(e,t,n){let o=St(e,t);return o?(Ln(e,t,gr(o,{displayName:n})),{applied:true}):{applied:false,reason:"not-found"}}function Sr(e,t,n){return St(e,t)?(Eo(e,t,n),{applied:true}):{applied:false,reason:"not-found"}}function xr(e,t){let n=St(e,t);if(!n)return {applied:false,reason:"not-found"};let o=ge(n)==="voter"?"viewer":"voter";return Ln(e,t,gr(n,{role:o})),{applied:true}}function wr(e,t,n=Date.now){if(!St(e,t))return {applied:false,reason:"not-found"};let o=n();return $o(e,t,o),{applied:true,at:o}}function Cr(e,t){return St(e,t)?(Lo(e,t),{applied:true}):{applied:false,reason:"not-found"}}function yr(e,t,n,o=Date.now){let r=mr(e,t,n);if(!r.isHost)return {applied:false,reason:"not-host"};if(n===t)return {applied:false,reason:"self-target"};if(!r.target)return {applied:false,reason:"not-found"};let s=o();return Uo(e,t,n,s),{applied:true,at:s}}function vr(e,t,n,o){let r=mr(e,t,n);return r.isHost?r.target?o.has(n)?(Wt(e,{hostParticipantId:n}),{applied:true}):{applied:false,reason:"not-online"}:{applied:false,reason:"not-found"}:{applied:false,reason:"not-host"}}function Ir(e,t){return Wt(e,{hostParticipantId:t}),{applied:true}}function br(e,t,n=Date.now){if(!ea(e,t))return {applied:false,reason:"not-host"};let o=n();return Mo(e,o),{applied:true,at:o}}function Ar(e,t={},n=Date.now){let o=q(e).settings.hostParticipantId;if(!o)return {applied:false,reason:"no-host"};let r=crypto.randomUUID(),s=n();return ko(e,{id:r,createdAt:s,createdBy:o,...t.title!==void 0&&{title:t.title},...t.description!==void 0&&{description:t.description},...t.ticketId!==void 0&&{ticketId:t.ticketId},...t.parentRoundId!==void 0&&{parentRoundId:t.parentRoundId},...t.agendaItemId!==void 0&&{agendaItemId:t.agendaItemId}}),{applied:true,id:r,at:s}}function Gn(e){let t=me(q(e));return t?Qe(t.status)?{round:t}:{applied:false,reason:"already-terminal"}:{applied:false,reason:"no-current-round"}}function Rr(e,t=Date.now){let n=Gn(e);if("applied"in n)return n;let o=t();return Oo(e,n.round.id,o),{applied:true,at:o}}function Tr(e,t=Date.now){let n=Gn(e);if("applied"in n)return n;let o=t();return Do(e,n.round.id,o),{applied:true,at:o}}function Er(e,t,n=Date.now){let o=Gn(e);if("applied"in o)return o;let r=n();return _o(e,o.round.id,r,t),{applied:true,at:r}}function kr(e,t,n){let o=q(e),r=Ze(o);if(!r)return {applied:false,reason:"no-active-round"};let s=o.participants.find(a=>a.id===t);return !s||!we(s)||ge(s)!=="voter"?{applied:false,reason:"not-a-voter"}:r.votes[t]===n?(Hn(e,r.id,t),{applied:true,effect:"cleared"}):(Po(e,r.id,t,n),{applied:true,effect:"cast"})}function Pr(e,t){let n=q(e),o=Ze(n);return o?(Hn(e,o.id,t),{applied:true,effect:"cleared"}):{applied:false,reason:"no-active-round"}}function Nr(e){let{doc:t,participantId:n,onlineIds:o}=e,r=e.now??Date.now;return {startRound:s=>Ar(t,s,r),revealCurrentRound:()=>Rr(t,r),skipCurrentRound:()=>Tr(t,r),discardCurrentRound:()=>Er(t,n,r),toggleCurrentVote:s=>kr(t,n,s),clearCurrentVote:()=>Pr(t,n),addItem:s=>Vo(t,s,r),editItem:(s,a)=>Jo(t,s,a),skipItem:s=>Yo(t,s),cancelItem:s=>Wo(t,s),moveItem:(s,a,i)=>Ko(t,s,a,i),rename:s=>hr(t,n,s),recolor:s=>Sr(t,n,s),toggleRole:()=>xr(t,n),leave:()=>wr(t,n,r),kick:s=>yr(t,n,s,r),handoffHost:s=>vr(t,n,s,o()),endSession:()=>br(t,n,r)}}var Or={startRound:()=>({applied:false,reason:"no-session"}),revealCurrentRound:()=>({applied:false,reason:"no-current-round"}),skipCurrentRound:()=>({applied:false,reason:"no-current-round"}),discardCurrentRound:()=>({applied:false,reason:"no-current-round"}),toggleCurrentVote:()=>({applied:false,reason:"no-active-round"}),clearCurrentVote:()=>({applied:false,reason:"no-active-round"}),addItem:()=>({applied:false,reason:"not-found"}),editItem:()=>({applied:false,reason:"not-found"}),skipItem:()=>({applied:false,reason:"not-found"}),cancelItem:()=>({applied:false,reason:"not-found"}),moveItem:()=>({applied:false,reason:"not-found"}),rename:()=>({applied:false,reason:"not-found"}),recolor:()=>({applied:false,reason:"not-found"}),toggleRole:()=>({applied:false,reason:"not-found"}),leave:()=>({applied:false,reason:"not-found"}),kick:()=>({applied:false,reason:"not-found"}),handoffHost:()=>({applied:false,reason:"not-found"}),endSession:()=>({applied:false,reason:"not-found"})};function Dr(e){let{prevName:t,newName:n,isSelf:o,wasSelf:r=false,cause:s=null}=e,a=o?"You are now the host":`${n} is now the host`;if(!t||r||s===null)return a;switch(s){case "left":return `${t} left. ${a}.`;case "disconnected":return `${t} disconnected. ${a}.`}}var ta="Session ended.",na=e=>`Session ended by ${e}`,oa="Removed by host";function qt(e,t){if(t!==null)return e.find(n=>n.id===t)?.displayName||void 0}function _r(e){let t=false,n=null,o=null,r=null,s="unset",a=false,i=[],d=false;function u(p){let g=p.meta.sessionEndedAt;if(g==null){n=null;return}if(g===n)return;n=g;let E=p.settings.hostParticipantId||null,A=qt(p.participants,E)??qt(p.participants,p.meta.createdBy)??"Host";i.push(()=>{let b=e.endedLocally();return {kind:"ended",endedAt:g,endedLocally:b,hostId:E,hostName:A,message:b?ta:na(A)}});}function l(p){let g=p.participants.find(C=>C.id===e.selfId);if(!g)return;let{leftAt:E,removedBy:A}=g;if(E===void 0){s=void 0,r=null;return}if(A===e.selfId){s=E;return}if(!a){s=E;return}if(s==="unset"){s=E;return}if(s!==void 0){s=E;return}if(s=E,E===r)return;r=E;let b=A??null,P={kind:"removed",leftAt:E,removedBy:b,removedByName:b===null?null:qt(p.participants,b)??b,message:oa};i.push(()=>P);}function c(p){let g=p.settings.hostParticipantId||null;if(g===null){o=null;return}if(o===null){o=g;return}if(g===o)return;let E=o;o=g;let A=p.participants.find(D=>D.id===E),b=A===void 0?null:A.displayName||E,P=A!==void 0&&!we(A),C=qt(p.participants,g)??g,L=E===e.selfId,I=g===e.selfId;i.push(()=>{let D=null;return P?D="left":A!==void 0&&e.presenceTrusted()&&!e.onlineIds().has(E)&&(D="disconnected"),{kind:"host-changed",previousHostId:E,previousHostName:b,hostId:g,hostName:C,cause:D,wasSelf:L,isSelf:I,message:Dr({prevName:b,newName:C,isSelf:I,wasSelf:L,cause:D})}});}function f(){d=false;let p=i;i=[];for(let g of p){if(t)return;e.emit(g());}}function k(){if(t)return;let p=e.projection();p&&(!a&&e.firstSyncCompleted()&&(a=true),u(p),l(p),c(p),i.length>0&&!d&&(d=true,queueMicrotask(f)));}let O=e.subscribe(k);return k(),{stop(){t||(t=true,i=[],O());}}}var Lr="participantId";function Mr(e){let t=new Set;for(let n of e.values()){if(typeof n!="object"||n===null)continue;let o=n[Lr];typeof o=="string"&&t.add(o);}return t}function sa(e,t){if(e.size!==t.size)return false;for(let n of e)if(!t.has(n))return false;return true}function Ur(e){let{room:t,self:n,seed:o}=e,r=n.participantId,s=e.now??Date.now,a=new $e.Doc;o.kind==="create"?_n(a,{roomUuid:t.uuid,createdAt:s(),participantId:r,displayName:n.displayName,defaultScale:o.defaultScale,...o.sessionName!==void 0&&{sessionName:o.sessionName},...n.avatarColor!==void 0&&{avatarColor:n.avatarColor}}):Mn(a,{participantId:r,displayName:n.displayName,joinedAt:s(),...n.avatarColor!==void 0&&{avatarColor:n.avatarColor}});let i=new Awareness(a);i.setLocalStateField(Lr,r);let d=false,u=q(a),l=Mr(i.getStates()),c=false,f=false,k=false,O=new Set,p=()=>{for(let y of O)y();},g=y=>(O.add(y),()=>{O.delete(y);}),E=new Set([a.getMap(Ht),a.getMap(jt),a.getMap(Ft),a.getArray(Vt),a.getArray(Jt)]),A=y=>{for(let V of y.changedParentTypes.keys())if(E.has(V))return true;return false},b=y=>{A(y)&&(u=q(a),e.onProjectionChange?.(u),p());};a.on("afterTransaction",b);let P=()=>{let y=Mr(i.getStates());sa(y,l)||(l=y,e.onOnlineIdsChange?.(l)),p();};i.on("change",P),e.onProjectionChange?.(u),e.onOnlineIdsChange?.(l),e.onStatusChange?.("connecting");let C=Nr({doc:a,participantId:r,onlineIds:()=>l,now:s}),L={...C,endSession(){let y=C.endSession();return y.applied&&(k=true),y}},I=sr({projection:()=>u,onlineIds:()=>l,myId:()=>r,subscribe:g,promote(y){Ir(a,y);}}),D=nr({projection:()=>u,onlineIds:()=>l,presenceTrusted:()=>c,selfId:()=>r,subscribe:g,reveal(){L.revealCurrentRound().applied&&e.onAutoReveal?.();}}),R=_r({projection:()=>u,onlineIds:()=>l,presenceTrusted:()=>c,firstSyncCompleted:()=>f,endedLocally:()=>k,selfId:r,subscribe:g,emit(y){e.onSessionEvent?.(y);}}),N={roomCode:t.code,deviceId:e.credentials.deviceId,...e.credentials.passwordHash!==void 0&&{passwordHash:e.credentials.passwordHash}},J=null,{beforeConnect:G}=e;G===void 0?W():Promise.resolve().then(()=>d?void 0:G(a)).then(W,W);function W(){d||(J=pr({httpBaseUrl:e.httpBaseUrl,roomUuid:t.uuid,doc:a,credentials:N,awareness:i,WebSocketPolyfill:e.WebSocketPolyfill,onStatusChange(y){d||e.onStatusChange?.(y);},onRejectionChange(y){d||e.onRejectionChange?.(y);},onReconnectingChange(y){d||e.onReconnectingChange?.(y);},onRepeatRejection(){d||e.onRepeatRejection?.();},onSynced(){d||(f=true,o.kind==="join"&&Cr(a,r),e.onFirstSync?.());},onSyncedChange(y){d||(c=y,e.onSyncedChange?.(y),p());}}));}return {get commands(){return L},updateCredentials(y){d||(N=y===null?{roomCode:N.roomCode,deviceId:N.deviceId}:{...N,passwordHash:y},J?.updateCredentials({passwordHash:y}));},updateSettings(y){d||$n(a,y);},updateRoundDescriptor(y,V){d||Un(a,y,V);},async flushUpdates(y=500){await J?.flush(y);},teardown(){d||(d=true,L=Or,R.stop(),D.stop(),I.stop(),a.off("afterTransaction",b),i.off("change",P),J?.disconnect(),J=null,i.destroy(),a.destroy());}}}var Br="PBKDF2",ia="SHA-256",Hr=new TextEncoder;function aa(e){return Array.from(new Uint8Array(e)).map(t=>t.toString(16).padStart(2,"0")).join("")}var da=/^[\s\u200B-\u200D\u2060]+|[\s\u200B-\u200D\u2060]+$/gu,zn=120;function ke(e){return e.normalize("NFC").replace(da,"")}async function Xt(e,t){let n=await crypto.subtle.importKey("raw",Hr.encode(ke(e)),Br,false,["deriveBits"]),o=await crypto.subtle.deriveBits({name:Br,salt:Hr.encode(t),iterations:1e5,hash:ia},n,256);return aa(o)}var jr="ABCDEFGHJKMNPQRSTUVWXYZ23456789";if(jr.length!==31)throw new Error(`Room code alphabet must be 31 characters, got ${jr.length}`);function qn(e){return e.trim().replaceAll(/-/g,"").toUpperCase()}function Fr(e,t=true){let n=qn(e);return !t||n.length!==6?n:`${n.slice(0,3)}-${n.slice(3)}`}function xt(e,t){let n=0;for(let o of t){if(o.status==="discarded"){if(o.id===e.id)return 0;continue}if(n+=1,o.id===e.id)return n}return 0}function Qn(e,t){let n=cr(e.id,t);return n!==null?`Round ${n.depth}/${n.total} [re-vote]`:`Round ${xt(e,t)}`}function Vr(e){let t=new Set(e).size;return t===1?"unanimous":t===2?"close":"spread"}function ca(e,t){let n=new Map;t.forEach((s,a)=>n.set(s,a));let o=[...new Set(e.filter(s=>!n.has(s)))].toSorted(),r=new Map;return o.forEach((s,a)=>r.set(s,t.length+a)),s=>n.get(s)??r.get(s)??Number.MAX_SAFE_INTEGER}function Xn(e,t){let n=new Map;for(let i of e)n.set(i,(n.get(i)??0)+1);let o=null,r=0,s=[...n.keys()].toSorted((i,d)=>t(i)-t(d));for(let i of s){let d=n.get(i);d>r&&(r=d,o=i);}let a=s.filter(i=>n.get(i)===r).length>1;return {mode:o,modeTied:a}}function la(e,t){let n=Object.values(e);if(n.length===0)return null;let o=ca(n,t.cards);if(t.cards.every(s=>Number.isFinite(parseFloat(s)))){let s=n.map(parseFloat).filter(Number.isFinite);if(s.length===0)return {kind:"categorical",...Xn(n,o),spread:Vr(n)};let a=s.reduce((c,f)=>c+f,0)/s.length,i=[...s].toSorted((c,f)=>c-f),d=Math.floor(i.length/2),u=i.length%2===1?i[d]:(i[d-1]+i[d])/2,l;if(new Set(n).size===1)l="unanimous";else {let c=n.map(O=>o(O)),f=Math.min(...c);l=Math.max(...c)-f<=1?"close":"spread";}return {kind:"numeric",mean:a,median:u,...Xn(n,o),spread:l}}return {kind:"categorical",...Xn(n,o),spread:Vr(n)}}function Qt(e){let t=Object.fromEntries(Object.entries(e.votes).filter(([,n])=>!ee(n)));return la(t,e.scale)}function ua(e){return e==="unanimous"?"Unanimous":e==="close"?"Close":"Spread"}function Zt(e){if(e===null)return null;let t=ua(e.spread),n=e.modeTied?null:e.mode;return e.kind==="numeric"?{kind:"numeric",mean:e.mean.toFixed(1),median:e.median.toFixed(1),mode:n,spread:t}:{kind:"categorical",mode:n,spread:t}}function tt(e){return e.status!=="revealed"||e.terminalAt===void 0||e.timerStartedAt===void 0?null:zt(e.terminalAt-e.timerStartedAt)}function Zn(e){return e.replaceAll(/\|/g,"\\|")}function fa(e){return e.replaceAll(/\\/g,"\\\\").replaceAll(/]/g,"\\]")}function pa(e){let n=(e.match(/`+/g)??[]).reduce((o,r)=>Math.max(o,r.length),0);return "`".repeat(n+1)}function eo(e){if(!e)return "";if(ir(e))return ` ([${fa(e)}](<${e}>))`;let t=pa(e);return ` (${t}${e}${t})`}function ma(e){return e instanceof Map?e:new Map(Object.entries(e))}function ga(e){let t=new Map;for(let r of e)t.set(r.id,r);function n(r){if(!r.parentRoundId)return r;let s=t.get(r.parentRoundId);return s?n(s):r}let o=new Map;for(let r of e){let s=n(r),a=o.get(s.id);a?a.push(r):o.set(s.id,[r]);}return o}function Jr(e,t){let n=new Map;e.scale.cards.forEach((i,d)=>n.set(i,d));let o=new Map,r=[];for(let[i,d]of Object.entries(e.votes)){let u=t.get(i)??i;if(ee(d)){r.push(u);continue}let l=o.get(d);l?l.push(u):o.set(d,[u]);}let s=[...o.entries()].map(([i,d])=>({card:i,scaleIndex:n.get(i)??Number.MAX_SAFE_INTEGER,voters:[...d].toSorted().map(Zn)}));s.sort((i,d)=>{let u=d.voters.length-i.voters.length;return u!==0?u:i.scaleIndex-d.scaleIndex});let a=s.map(i=>`| ${Zn(i.card)} | ${i.voters.join(", ")} |`);return r.length>0&&a.push(`| Abstained | ${[...r].toSorted().map(Zn).join(", ")} |`),["| Vote | Voters |","|------|--------|",...a].join(`
3
- `)}function Yr(e){let t=Zt(Qt(e)),n=tt(e),o=[];return t?.kind==="numeric"?o.push(`Avg ${t.mean} \xB7 Med ${t.median}`):t?.kind==="categorical"&&t.mode!==null&&o.push(`Most common: ${t.mode}`),n!==null&&o.push(`Elapsed ${n}`),o.join(" \xB7 ")}function Wr(e){let{rounds:t}=e,n=ma(e.participants),o=new Map;for(let[l,c]of n)o.set(l,c.displayName);let r=t.filter(l=>l.status==="revealed");if(r.length===0)return "";let s=new Map;for(let l of t)s.set(l.id,xt(l,t));let a=ga(r),i=new Set,d=[];for(let l of r)for(let[c,f]of a)if(f.includes(l)&&!i.has(c)){i.add(c),d.push(c);break}let u=[];for(let l of d){let c=a.get(l),f=c.find(b=>b.id===l),k=c.filter(b=>b.id!==l),O=s.get(f.id)??0,p=f.title?`## Round ${O} \u2014 ${f.title}${eo(f.ticketId)}`:`## Round ${O}${eo(f.ticketId)}`,g=Jr(f,o),E=Yr(f),A=E?`${p}
2
+ import lc from'yargs';import {hideBin}from'yargs/helpers';import kn,{useState,useEffect,useCallback,useMemo,useRef}from'react';import {render,useApp,useInput,Box,Text}from'ink';import {existsSync,readFileSync,unlinkSync,mkdirSync,writeFileSync,chmodSync}from'fs';import {homedir}from'os';import {join}from'path';import {randomUUID,randomBytes}from'crypto';import {createInterface}from'readline';import*as $e from'yjs';import {Awareness}from'y-protocols/awareness';import {WebsocketProvider}from'y-websocket';import za from'ws';import Wi from'clipboardy';import {jsxs,jsx,Fragment}from'react/jsx-runtime';var Lt="hnch_abstain";function ee(e){return e===Lt}var Te="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Mt=Te.length,Un=Math.floor(Mt/2);function lt(e){let t=Te.indexOf(e);if(t===-1)throw new Error(`fractional-index: invalid character '${e}'`);return t}function _o(e,t){return e.length>=t?e:e+"0".repeat(t-e.length)}function Ms(e){let t=e.length-1;for(;t>0&&e[t]==="0";)t--;return e.slice(0,t+1)}function $s(e,t){let n=e.length,o=Array.from({length:n+1}).fill(0),r=0;for(let a=n-1;a>=0;a--){let d=e[a]+t[a]+r;o[a+1]=d%Mt,r=Math.floor(d/Mt);}o[0]=r;let i=Array.from({length:n+1}).fill(0),s=0;for(let a=0;a<=n;a++){let d=o[a]+s*Mt;i[a]=Math.floor(d/2),s=d%2;}return i.slice(1)}function jn(e,t){let n=Te[Un];if(e===null&&t===null)return n+n;if(t===null)return e+n+n+n+n;if(e===null)return Bs(t);if(e>=t)throw new Error(`keyBetween: a must be < b (a='${e}', b='${t}')`);return Hs(e,t)}function Bs(e){for(let t=e.length-1;t>=0;t--){let n=lt(e[t]);if(n>0)return e.slice(0,t)+Te[n-1]+Te[Un]}if(e.length>1)return e.slice(0,-1);throw new Error(`keyBetween: cannot generate key before '${e}' \u2014 use keyBetween(null, null) for the initial key`)}function Hs(e,t){let n=Math.max(e.length,t.length),o=_o(e,n).split("").map(d=>lt(d)),r=_o(t,n).split("").map(d=>lt(d)),s=$s(o,r).map(d=>Te[d]).join(""),a=Ms(s);return a>e&&a<t?a:s>e&&s<t?s:Us(e,t)}function Us(e,t){for(let n=0;n<t.length;n++){let o=n<e.length?lt(e[n]):0;if(lt(t[n])===o+1)return (n<e.length?e.slice(0,n+1):e+Te[0])+Te[Un]}throw new Error(`keyBetween: space exhausted between '${e}' and '${t}'`)}function Fn(e){let{revealedAt:t,skippedAt:n,discardedAt:o}=e;if(t===void 0&&n===void 0&&o===void 0)return null;let r=[];t!==void 0&&r.push({kind:"revealed",at:t}),n!==void 0&&r.push({kind:"skipped",at:n}),o!==void 0&&r.push({kind:"discarded",at:o});let i={revealed:0,skipped:1,discarded:2};return r.sort((s,a)=>s.at-a.at||i[s.kind]-i[a.kind]),r[0].kind}function ut(e){return e==="revealed"||e==="skipped"||e==="discarded"}function $t(e){return e==="revealed"||e==="skipped"}function et(e){return !ut(e)}var Ht="meta",Ut="settings",jt="participants",Ft="rounds",Vt="agenda",js=["roomUuid","createdAt","createdBy","sessionEndedAt"],Fs=["name","defaultScale","hostParticipantId"],Vs=["displayName","joinedAt","role","leftAt","removedBy","avatarColor"],Ks=["id","title","description","ticketId","state","source","externalId","sortKey","createdAt","consumedAt","consumedByRoundId"],Js=["id","title","description","ticketId","parentRoundId","scale","timerStartedAt","revealedAt","skippedAt","discardedAt","discardedBy","createdBy","createdAt","agendaItemId"];function Bt(e){return e.getMap(Ht)}function Kt(e){return e.getMap(Ut)}function ke(e){return e.getMap(jt)}function Vn(e){return e.getArray(Ft)}function ft(e){return e.getArray(Vt)}function pt(e,t){let n={};for(let o of t){let r=e.get(o);r!==void 0&&(n[o]=r);}return n}function Ws(e){return pt(Bt(e),js)}function Ys(e){return pt(Kt(e),Fs)}function Gs(e){let t=ke(e),n=[];return t.forEach((o,r)=>{let i=pt(o,Vs);n.push({id:r,...i});}),n.sort((o,r)=>o.joinedAt-r.joinedAt||o.id.localeCompare(r.id)),n}function zs(e){let t={};return e.forEach((n,o)=>{t[o]=n;}),t}function qs(e){let t=pt(e,Js),n=e.get("votes"),o=n?zs(n):{},r=Fn(t),{revealedAt:i,skippedAt:s,discardedAt:a,...d}=t,l=r??(t.timerStartedAt!==void 0?"voting":"pending"),u=r==="revealed"?i:r==="skipped"?s:r==="discarded"?a:void 0;return u===void 0?{...d,votes:o,status:l}:{...d,votes:o,status:l,terminalAt:u}}function Xs(e){let t=Vn(e),n=[];return t.forEach(o=>{n.push(qs(o));}),n}function Qs(e){return pt(e,Ks)}function Zs(e){let t=ft(e),n=[];return t.forEach(o=>{n.push(Qs(o));}),n.sort((o,r)=>o.sortKey.localeCompare(r.sortKey)),n}function q(e){return {meta:Ws(e),settings:Ys(e),participants:Gs(e),rounds:Xs(e),agenda:Zs(e)}}function Kn(e,t){if(Bt(e).has("roomUuid"))throw new Error("initDoc: doc already seeded");e.transact(()=>{let n=Bt(e);n.set("roomUuid",t.roomUuid),n.set("createdAt",t.createdAt),n.set("createdBy",t.participantId);let o=Kt(e);t.sessionName!==void 0&&o.set("name",t.sessionName),o.set("defaultScale",t.defaultScale),o.set("hostParticipantId",t.participantId);let r=new $e.Map;r.set("displayName",t.displayName),r.set("joinedAt",t.createdAt),t.avatarColor!==void 0&&r.set("avatarColor",t.avatarColor),ke(e).set(t.participantId,r);});}function Jn(e,t){e.transact(()=>{let n=ke(e),o=n.get(t.participantId),r=o??new $e.Map;r.set("displayName",t.displayName),o===void 0&&r.set("joinedAt",t.joinedAt),t.avatarColor!==void 0&&r.set("avatarColor",t.avatarColor),r.delete("leftAt"),r.delete("removedBy"),o===void 0&&n.set(t.participantId,r);});}function Jt(e,t){e.transact(()=>{let n=Kt(e);for(let[o,r]of Object.entries(t))r===void 0?n.delete(o):n.set(o,r);});}function Wn(e,t){Jt(e,t);}function Yn(e,t,n){e.transact(()=>{let o=ke(e),r=o.get(t),i=r??new $e.Map;i.set("displayName",n.displayName),i.set("joinedAt",n.joinedAt),n.role!==void 0&&i.set("role",n.role),n.avatarColor!==void 0&&i.set("avatarColor",n.avatarColor),r===void 0&&o.set(t,i);});}function Lo(e,t,n){e.transact(()=>{let r=ke(e).get(t);r&&r.set("avatarColor",n);});}function Mo(e,t){let n=t.scale??Kt(e).get("defaultScale");if(!n)throw new Error("appendRound: no scale (settings.defaultScale missing)");if(t.parentRoundId!==void 0){let o=Be(e,t.parentRoundId);if(o!==void 0&&o.get("discardedAt")!==void 0)throw new Error(`appendRound: parentRoundId ${t.parentRoundId} points at a discarded round`)}return e.transact(()=>{let o=new $e.Map;o.set("id",t.id),o.set("createdAt",t.createdAt),o.set("createdBy",t.createdBy),o.set("scale",n),t.title!==void 0&&o.set("title",t.title),t.description!==void 0&&o.set("description",t.description),t.ticketId!==void 0&&o.set("ticketId",t.ticketId),t.parentRoundId!==void 0&&o.set("parentRoundId",t.parentRoundId),t.agendaItemId!==void 0&&o.set("agendaItemId",t.agendaItemId),o.set("timerStartedAt",t.createdAt),o.set("votes",new $e.Map),Vn(e).push([o]);}),t.id}function Gn(e,t,n){let o=Be(e,t);if(!o)throw new Error(`patchRoundDescriptor: round ${t} not found`);e.transact(()=>{n.title!==void 0&&o.set("title",n.title),n.description!==void 0&&o.set("description",n.description);});}function Be(e,t){let n=Vn(e);for(let o=0;o<n.length;o+=1){let r=n.get(o);if(r.get("id")===t)return r}}function zn(e){return Fn({revealedAt:e.get("revealedAt"),skippedAt:e.get("skippedAt"),discardedAt:e.get("discardedAt")})}function $o(e,t,n,o){let r=Be(e,t);if(!r)throw new Error(`castVote: round ${t} not found`);r.get("revealedAt")===void 0&&e.transact(()=>{r.get("votes").set(n,o);});}function qn(e,t,n){let o=Be(e,t);if(!o)throw new Error(`clearVote: round ${t} not found`);o.get("revealedAt")===void 0&&e.transact(()=>{o.get("votes").delete(n);});}function Bo(e,t,n,o){let r=t.get("agendaItemId");if(r===void 0)return;let i=Wt(e,r);i!==void 0&&i.get("state")==="pending"&&(i.set("state","consumed"),i.set("consumedAt",o),i.set("consumedByRoundId",n));}function Ho(e,t,n){let o=Be(e,t);if(!o)throw new Error(`revealRound: round ${t} not found`);let r=zn(o);if(r!==null)throw new Error(`revealRound: round ${t} already terminal (${r})`);e.transact(()=>{o.set("revealedAt",n),Bo(e,o,t,n);});}function Uo(e,t,n){let o=Be(e,t);if(!o)throw new Error(`skipRound: round ${t} not found`);let r=zn(o);if(r!==null)throw new Error(`skipRound: round ${t} already terminal (${r})`);e.transact(()=>{o.set("skippedAt",n),Bo(e,o,t,n);});}function jo(e,t,n,o){let r=Be(e,t);if(!r)throw new Error(`discardRound: round ${t} not found`);let i=zn(r);if(i!==null)throw new Error(`discardRound: round ${t} already terminal (${i})`);e.transact(()=>{r.set("discardedAt",n),r.set("discardedBy",o);});}function Fo(e,t){e.transact(()=>{Bt(e).set("sessionEndedAt",t);});}function Vo(e,t,n){let r=ke(e).get(t);r&&e.transact(()=>{r.set("leftAt",n),r.set("removedBy",t);});}function Ko(e,t){let o=ke(e).get(t);!o||!o.has("leftAt")||e.transact(()=>{o.delete("leftAt"),o.delete("removedBy");});}function Jo(e,t,n,o){if(n===t)return;let i=ke(e).get(n);i&&e.transact(()=>{i.set("leftAt",o),i.set("removedBy",t);});}function me(e){let{rounds:t}=e;if(t.length===0)return null;for(let n=t.length-1;n>=0;n-=1){let o=t[n];if(o.status==="pending"||o.status==="voting")return o}for(let n=t.length-1;n>=0;n-=1){let o=t[n];if(o.status!=="discarded")return o}return null}function tt(e){let{rounds:t}=e;for(let n=t.length-1;n>=0;n-=1){let o=t[n];if(et(o.status))return o}return null}function Xn(e){let t=Object.values(e.votes);return t.length<2?false:t.every(n=>n===t[0])}function Wt(e,t){let n=ft(e);for(let o=0;o<n.length;o++){let r=n.get(o);if(r.get("id")===t)return r}}function mt(e,t){return !!e?.trim()||!!t?.trim()}function Wo(e,t){if(!mt(t.title,t.ticketId))throw new Error("appendAgendaItem: at least one of {title, ticketId} is required");let n=crypto.randomUUID(),o=ft(e),r=null;o.forEach(s=>{if(s.get("state")==="pending"){let a=s.get("sortKey");a!==void 0&&(r===null||a>r)&&(r=a);}});let i=jn(r,null);return e.transact(()=>{let s=new $e.Map;s.set("id",n),s.set("state","pending"),s.set("source",t.source??"manual"),s.set("sortKey",i),s.set("createdAt",t.createdAt),t.title!==void 0&&s.set("title",t.title),t.description!==void 0&&s.set("description",t.description),t.ticketId!==void 0&&s.set("ticketId",t.ticketId),t.externalId!==void 0&&s.set("externalId",t.externalId),ft(e).push([s]);}),n}function Yo(e,t,n){let o=Wt(e,t);if(!o)throw new Error(`updateAgendaItemFields: item ${t} not found`);let r=o.get("state");if(r==="skipped"||r==="cancelled")throw new Error(`updateAgendaItemFields: item ${t} is ${r} and cannot be edited`);let i=n.title!==void 0?n.title:o.get("title"),s=n.ticketId!==void 0?n.ticketId:o.get("ticketId");if(!mt(i,s))throw new Error("updateAgendaItemFields: at least one of {title, ticketId} must remain non-empty");e.transact(()=>{n.title!==void 0&&o.set("title",n.title),n.ticketId!==void 0&&o.set("ticketId",n.ticketId),n.description!==void 0&&o.set("description",n.description);});}function Qn(e,t,n,o={}){let r=Wt(e,t);if(!r)throw new Error(`setAgendaItemState: item ${t} not found`);let i=r.get("state");if(!(i===n&&n==="consumed")){if(i!=="pending")throw new Error(`setAgendaItemState: invalid transition '${i}' \u2192 '${n}' for item ${t}`);if(n==="consumed"&&o.timestamp===void 0)throw new Error(`setAgendaItemState: timestamp is required when consuming item ${t}`);e.transact(()=>{r.set("state",n),n==="consumed"&&(r.set("consumedAt",o.timestamp),o.consumedByRoundId!==void 0&&r.set("consumedByRoundId",o.consumedByRoundId));});}}function Go(e,t,n,o){let r=Wt(e,t);if(!r)throw new Error(`reorderAgendaItem: item ${t} not found`);let i=r.get("state");if(i!=="pending")throw new Error(`reorderAgendaItem: item ${t} is ${i}; only pending items may be reordered`);let s=jn(n??null,o??null);e.transact(()=>{r.set("sortKey",s);});}function He(e){for(let t of e.agenda)if(t.state==="pending")return t;return null}function zo(e,t){let n=q(e).agenda.find(o=>o.id===t);return n||{applied:false,reason:"not-found"}}function Zn(e,t){let n=zo(e,t);return gt(n)?n:n.state!=="pending"?{applied:false,reason:"not-pending"}:n}function ea(e){return e.state==="skipped"||e.state==="cancelled"}function gt(e){return "applied"in e}function qo(e,t,n=Date.now){if(!mt(t.title,t.ticketId))return {applied:false,reason:"invalid-fields"};let o=n();return {applied:true,id:Wo(e,{...t,createdAt:o}),at:o}}function Xo(e,t,n){let o=zo(e,t);if(gt(o))return o;if(ea(o))return {applied:false,reason:"not-pending"};let r=n.title!==void 0?n.title:o.title,i=n.ticketId!==void 0?n.ticketId:o.ticketId;return mt(r,i)?(Yo(e,t,n),{applied:true,id:t}):{applied:false,reason:"invalid-fields"}}function Qo(e,t){let n=Zn(e,t);return gt(n)?n:(Qn(e,t,"skipped"),{applied:true,id:t})}function Zo(e,t){let n=Zn(e,t);return gt(n)?n:(Qn(e,t,"cancelled"),{applied:true,id:t})}function er(e,t,n,o){let r=Zn(e,t);return gt(r)?r:(Go(e,t,n,o),{applied:true,id:t})}var eo={"unknown-room":4001,"wrong-password":4002,"invalid-invite":4003,"expired-invite":4004,"invite-already-redeemed":4005,"room-full":4006,"malformed-credentials":4010},tr=new Map(Object.entries(eo).map(([e,t])=>[t,e])),nr=20;function ge(e){return e.role??"voter"}function we(e){return e.leftAt===void 0}var Yt={id:"fibonacci",cards:["0","1","2","3","5","8","13","21"]},or={id:"t-shirt",cards:["XS","S","M","L","XL"]},rr={id:"powers-of-2",cards:["1","2","4","8","16","32","64"]},ir={id:"linear",cards:["1","2","3","4","5","6","7","8","9","10"]},sr={id:"risk",cards:["Low","Medium","High","Critical"]},de={[Yt.id]:Yt,[or.id]:or,[rr.id]:rr,[ir.id]:ir,[sr.id]:sr},ar={fibonacci:"Fibonacci","t-shirt":"T-shirt","powers-of-2":"Powers of 2",linear:"Linear (1\u201310)",risk:"Risk"},ta="Custom scale",na=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;function dr(e){if(e in ar)return ar[e];if(e.length===0)return e;let t=e.startsWith("custom-")?e.slice(7):e;return t!==e&&na.test(t)?ta:t.split("-").map(n=>n.length===0?n:n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}function oa(e,t,n){if(!e||e.status!=="voting"&&e.status!=="pending")return false;let o=new Set(t.filter(d=>we(d)&&n.has(d.id)&&ge(d)!=="viewer").map(d=>d.id));if(o.size===0)return false;let r=Object.entries(e.votes).filter(([d])=>o.has(d)),i=r.filter(([,d])=>ee(d)).length,s=r.length-i,a=o.size-i;return a<=0?false:s>=a}function ra(e,t){return e.participants.some(n=>we(n)&&n.id!==t)}function cr(e){function t(){let o=e.projection();if(!o||!e.presenceTrusted()&&ra(o,e.selfId()))return;let r=me(o);oa(r,o.participants,e.onlineIds())&&e.reveal();}let n=e.subscribe(t);return t(),{stop(){n();}}}var nt={"racing-green":{base:"#0B3D2E",soft:"rgba(11,61,46,0.14)",ink:"#fff",label:"Racing Green"},dijon:{base:"#C9A227",soft:"rgba(201,162,39,0.18)",ink:"#000",label:"Dijon"},blue:{base:"#0A84FF",soft:"rgba(10,132,255,0.14)",ink:"#fff",label:"Blue"},indigo:{base:"#5E5CE6",soft:"rgba(94,92,230,0.14)",ink:"#fff",label:"Indigo"},violet:{base:"#BF5AF2",soft:"rgba(191,90,242,0.14)",ink:"#fff",label:"Violet"},pink:{base:"#FF375F",soft:"rgba(255,55,95,0.14)",ink:"#fff",label:"Pink"},red:{base:"#FF453A",soft:"rgba(255,69,58,0.14)",ink:"#fff",label:"Red"},orange:{base:"#FF9F0A",soft:"rgba(255,159,10,0.16)",ink:"#000",label:"Orange"},amber:{base:"#FFD60A",soft:"rgba(255,214,10,0.18)",ink:"#000",label:"Amber"},green:{base:"#30D158",soft:"rgba(48,209,88,0.14)",ink:"#000",label:"Green"},teal:{base:"#40C8E0",soft:"rgba(64,200,224,0.14)",ink:"#000",label:"Teal"},graphite:{base:"#1C1C1E",soft:"rgba(28,28,30,0.10)",ink:"#fff",label:"Graphite"}};var ht=["racing-green","dijon","blue","indigo","violet","pink","red","orange","amber","green","teal","graphite"],ia=/^#[0-9a-fA-F]{6}$/;function sa(e){return Object.hasOwn(nt,e)}function Ue(e){return e?sa(e)?nt[e].base:ia.test(e)?e.toLowerCase():null:null}function lr(e){let t=5381;for(let o=0;o<e.length;o++)t=(t<<5)+t+e.charCodeAt(o)|0;let n=Math.abs(t)%ht.length;return ht[n]}var aa=5e3;function ur(e,t){let n=new Set;for(let o of e.participants)t.has(o.id)&&we(o)&&n.add(o.id);return n}function da(e,t,n){let o=e.settings.hostParticipantId;return o?ur(e,t).has(o)?{kind:"cancel"}:n.missingHostId!==o?{kind:"start-debounce",hostId:o}:{kind:"none"}:{kind:"none"}}function ca(e,t,n,o){let r=e.settings.hostParticipantId;if(!o||r!==o)return {promote:false};let i=ur(e,t);if(i.has(r))return {promote:false};let s=[...i].toSorted();if(s.length===0)return {promote:false};let a=s[0];return a!==n?{promote:false}:{promote:true,winner:a}}function fr(e){let t=null,n=null;function o(){n!==null&&(clearTimeout(n),n=null),t=null;}function r(){n=null;let a=t;t=null;let d=e.projection(),l=e.myId();if(!d||l===null)return;let u=ca(d,e.onlineIds(),l,a);u.promote&&e.promote(u.winner);}function i(){let a=e.projection();if(!a||e.myId()===null){o();return}let d=da(a,e.onlineIds(),{missingHostId:t});switch(d.kind){case "cancel":o();break;case "start-debounce":o(),t=d.hostId,n=setTimeout(r,aa);break;}}let s=e.subscribe(i);return i(),{stop(){o(),s();}}}function Gt(e){let t=Math.max(0,Math.floor(e/1e3)),n=Math.floor(t/60),o=t%60;return `${n}:${o.toString().padStart(2,"0")}`}function pr(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return false}}function to(e){if(e===null||typeof e!="object"||Array.isArray(e))return {version:2,entries:{}};let t=e;if(t.version===2&&gr(t.entries)){let n=t.entries,o={};for(let[r,i]of Object.entries(n)){let s=la(i);s!==null&&(o[r]=s);}return {version:2,entries:o}}if(typeof t.roomCode=="string"&&typeof t.roomUuid=="string"&&typeof t.lastSeenAt=="number"){let n={roomCode:t.roomCode,roomUuid:t.roomUuid,lastSeenAt:t.lastSeenAt,...typeof t.passwordHash=="string"?{passwordHash:t.passwordHash}:{}};return {version:2,entries:{[n.roomUuid]:n}}}return {version:2,entries:{}}}function mr(e,t,n=864e5){let o={};for(let[r,i]of Object.entries(e.entries))t-i.lastSeenAt>n||(i.lastSeenAt>t?o[r]={...i,lastSeenAt:t}:o[r]=i);return {version:2,entries:o}}function gr(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function la(e){if(!gr(e))return null;let t=e;return typeof t.roomCode!="string"||typeof t.roomUuid!="string"||typeof t.lastSeenAt!="number"?null:{roomCode:t.roomCode,roomUuid:t.roomUuid,lastSeenAt:t.lastSeenAt,...typeof t.passwordHash=="string"?{passwordHash:t.passwordHash}:{}}}function hr(e,t){let n=t.filter(f=>f.status!=="discarded"),o=new Map;for(let f of n)o.set(f.id,f);let r=o.get(e);if(r===void 0||r.parentRoundId===void 0)return null;let i=new Set([r.id]),s=r,a=1;for(;s.parentRoundId!==void 0;){let f=o.get(s.parentRoundId);if(f===void 0||i.has(f.id))return null;i.add(f.id),s=f,a+=1;}let d=s,l=new Map;for(let f of n){if(f.parentRoundId===void 0)continue;let N=l.get(f.parentRoundId);N===void 0?l.set(f.parentRoundId,[f]):N.push(f);}let u=0,c=[d];for(;c.length>0;){let f=c.shift();u+=1;let N=l.get(f.id);N!==void 0&&c.push(...N);}return {chainRoot:d,depth:a,total:u}}var fa=new TextEncoder;async function no(e,t){if(!/^[0-9a-f]{64}$/.test(e))throw new Error("device key must be 64 lowercase hex characters");let n=new Uint8Array(32);for(let i=0;i<32;i+=1)n[i]=Number.parseInt(e.slice(i*2,i*2+2),16);let o=await crypto.subtle.importKey("raw",n,{name:"HMAC",hash:"SHA-256"},false,["sign"]),r=new Uint8Array(await crypto.subtle.sign("HMAC",o,fa.encode(t)));return Array.from(r,i=>i.toString(16).padStart(2,"0")).join("")}var je=class extends Error{reason;constructor(t){super(`relay rejected resolve: ${t}`),this.reason=t,this.name="RelayRejectionError";}},zt=class extends Error{reason;constructor(t){super(`relay refused: ${t}`),this.reason=t,this.name="RelayAccessError";}};function qt(e){return e instanceof zt?e.reason:e instanceof je?"unknown-room":"unreachable"}var Xt=1e4;async function xr(e,t){let n=await fetch(`${e}/rooms`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...t?.passwordHash?{passwordHash:t.passwordHash}:{},...t?.creator!==void 0&&{creator:t.creator}}),signal:AbortSignal.timeout(Xt)});if(!n.ok)throw new Error(`POST /rooms failed: ${n.status}`);return await n.json()}function yr(e){if(typeof e!="object"||e===null)return null;let{reason:t}=e;return typeof t=="string"&&Object.hasOwn(eo,t)?t:null}async function ce(e,t){let n=await fetch(`${e}/rooms/${encodeURIComponent(t)}`,{signal:AbortSignal.timeout(Xt)});if(n.status===404){let o=await n.json().catch(()=>null),r=yr(o);if(r!==null)throw new je(r)}if(!n.ok)throw new Error(`GET /rooms/:code failed: ${n.status}`);return await n.json()}var pa=new Map([[401,["unauthenticated","not-host"]],[409,["bad-target"]]]);async function wr(e,t){let n=await e.json().catch(()=>null),o=typeof n=="object"&&n!==null?n.reason:void 0;if(e.status===404&&o==="unknown-room")throw new je("unknown-room");let r=pa.get(e.status)?.find(i=>i===o);throw r!==void 0?new zt(r):new Error(`${t} failed: ${e.status}`)}function Cr(e){return {"content-type":"application/json",...e!==void 0&&{authorization:`Bearer ${e.pk}`}}}async function vr(e,t,n,o){let r=await fetch(`${e}/rooms/${t}/access`,{method:"PATCH",headers:Cr(o),body:JSON.stringify(o===void 0?{passwordHash:n}:{participantId:o.participantId,passwordHash:n}),signal:AbortSignal.timeout(Xt)});return r.ok?await r.json():wr(r,"PATCH /rooms/:uuid/access")}async function Ir(e,t,n){let o=await fetch(`${e}/rooms/${t}/host`,{method:"POST",headers:Cr(n),body:JSON.stringify({participantId:n.participantId,target:n.target}),signal:AbortSignal.timeout(Xt)});return o.ok?await o.json():wr(o,"POST /rooms/:uuid/host")}var ma=1,ga=6e4,ha=3,Sa=5e3,xa=8e3;async function ya(e,t,n){let o,r;try{let a=await fetch(`${e}/rooms/${encodeURIComponent(n.roomCode)}`,{signal:AbortSignal.timeout(xa)});o=a.status,r=await a.json().catch(()=>null);}catch{return null}if(o===404)return yr(r)==="unknown-room"?"unknown-room":null;if(o!==200||typeof r!="object"||r===null)return null;let{uuid:i,accessMode:s}=r;return typeof i!="string"?null:i!==t?"unknown-room":s==="password"&&n.passwordHash===void 0?"wrong-password":null}function wa(e){return e.replace(/^https?:\/\//,t=>t==="https://"?"wss://":"ws://")}function Sr(e){let t={did:e.deviceId};return e.participantKey!==void 0&&(t.pk=e.participantKey),e.passwordHash!==void 0&&(t.pw=e.passwordHash),t}function Ca(){return globalThis.window}function Rr(e){let t="connecting",n=null,o=false,r=false,i=false,s=false,a=false,d=[],l=()=>{let w=o&&t!=="connected"&&n===null&&!r&&!s;w!==i&&(i=w,e.onReconnectingChange?.(w));},u=`${wa(e.httpBaseUrl)}/ws`,c=e.credentials,f=new WebsocketProvider(u,e.roomUuid,e.doc,{params:Sr(c),connect:true,...e.awareness!==void 0&&{awareness:e.awareness},...e.WebSocketPolyfill!==void 0&&{WebSocketPolyfill:e.WebSocketPolyfill}}),N=()=>{let{awareness:w}=f;for(let M of w.meta.keys())M!==w.clientID&&!w.states.has(M)&&w.meta.delete(M);},P=()=>{let w=f.awareness.getLocalState();w!==null&&f.awareness.setLocalState(w);},g=w=>{w!==a&&(a=w,e.onSyncedChange?.(w));};N();let p=w=>{t=w.status,w.status==="disconnected"&&N(),w.status==="connected"&&P(),e.onStatusChange?.(w.status),w.status==="connected"&&(o=true,s=false,n=null,e.onRejectionChange?.(null),d.length=0),l();},A=false,E=()=>{A=true;try{f.disconnect();}finally{A=false;}},C=w=>{n=w,e.onRejectionChange?.(w),f.shouldConnect=false,E(),l();},k=false,v=Number.NEGATIVE_INFINITY,B=()=>r||n!==null,b=async()=>{let w=Date.now();if(w<v&&(v=Number.NEGATIVE_INFINITY),k||w-v<Sa)return;k=true,v=w;let M=c;try{let J=await ya(e.httpBaseUrl,e.roomUuid,M);if(J===null||B()||t==="connected"||M!==c||s)return;C(J);}finally{k=false;}},_=w=>{if(A)return;s=false;let M=w===null?void 0:tr.get(w.code);if(M===void 0){let J=Date.now();d.push(J);let m=J-ga;for(;d.length>0&&d[0]<m;)d.shift();d.length>=ha&&(d.length=0,e.onRepeatRejection?.()),l(),b();return}C(M);};f.on("status",p),f.on("connection-close",_);let T=f,O=null;if(e.onSynced!==void 0){let w=M=>{M&&(T.off("synced",w),O=null,e.onSynced?.());};O=w,T.on("synced",w);}let Y=w=>{g(w);};T.on("synced",Y);let K=()=>{r||(t="disconnected",g(false),e.onStatusChange?.("disconnected"),l());},G=()=>{r||n!==null||t!=="connected"&&(f.ws!==null?(f.wsUnsuccessfulReconnects=0,f.ws.close()):f.connect());},j=Ca();j?.addEventListener("offline",K),j?.addEventListener("online",G);let I=false;return {awareness:f.awareness,updateCredentials(w){let M=w.passwordHash??void 0;if(M===c.passwordHash)return;let{passwordHash:J,...m}=c;c=M===void 0?m:{...m,passwordHash:M},s=t==="connected",n!==null&&(n=null,e.onRejectionChange?.(null)),f.shouldConnect=false,E(),f.params=Sr(c),f.connect();},async flush(w){let M=Date.now()+w;for(;;){let J=f.ws;if(I||J===null||J.readyState!==ma||J.bufferedAmount===0||Date.now()>=M)return;await new Promise(m=>{setTimeout(m,16);});}},disconnect(){I||(I=true,r=true,l(),f.off("status",p),f.off("connection-close",_),O!==null&&(T.off("synced",O),O=null),T.off("synced",Y),g(false),j?.removeEventListener("offline",K),j?.removeEventListener("online",G),f.shouldConnect=false,E(),f.destroy());}}}function St(e,t){return q(e).participants.find(n=>n.id===t)}function br(e,t,n){let o=q(e);return {isHost:o.settings.hostParticipantId===t,target:o.participants.find(r=>r.id===n)}}function va(e,t){return q(e).settings.hostParticipantId===t}function Ar(e,t){let n=t.role??e.role;return {displayName:t.displayName??e.displayName,joinedAt:e.joinedAt,...n!==void 0&&{role:n},...e.avatarColor!==void 0&&{avatarColor:e.avatarColor}}}function Er(e,t,n){let o=St(e,t);return o?(Yn(e,t,Ar(o,{displayName:n})),{applied:true}):{applied:false,reason:"not-found"}}function Tr(e,t,n){return St(e,t)?(Lo(e,t,n),{applied:true}):{applied:false,reason:"not-found"}}function kr(e,t){let n=St(e,t);if(!n)return {applied:false,reason:"not-found"};let o=ge(n)==="voter"?"viewer":"voter";return Yn(e,t,Ar(n,{role:o})),{applied:true}}function Pr(e,t,n=Date.now){if(!St(e,t))return {applied:false,reason:"not-found"};let o=n();return Vo(e,t,o),{applied:true,at:o}}function Nr(e,t){return St(e,t)?(Ko(e,t),{applied:true}):{applied:false,reason:"not-found"}}function Or(e,t,n,o=Date.now){let r=br(e,t,n);if(!r.isHost)return {applied:false,reason:"not-host"};if(n===t)return {applied:false,reason:"self-target"};if(!r.target)return {applied:false,reason:"not-found"};let i=o();return Jo(e,t,n,i),{applied:true,at:i}}function Dr(e,t,n,o){let r=oo(e,t,n,o);return r!==null?r:(Jt(e,{hostParticipantId:n}),{applied:true})}function oo(e,t,n,o){let r=br(e,t,n);return r.isHost?r.target?o.has(n)?null:{applied:false,reason:"not-online"}:{applied:false,reason:"not-found"}:{applied:false,reason:"not-host"}}function ro(e,t){return Jt(e,{hostParticipantId:t}),{applied:true}}function _r(e,t,n=Date.now){if(!va(e,t))return {applied:false,reason:"not-host"};let o=n();return Fo(e,o),{applied:true,at:o}}function Lr(e,t={},n=Date.now){let o=q(e).settings.hostParticipantId;if(!o)return {applied:false,reason:"no-host"};let r=crypto.randomUUID(),i=n();return Mo(e,{id:r,createdAt:i,createdBy:o,...t.title!==void 0&&{title:t.title},...t.description!==void 0&&{description:t.description},...t.ticketId!==void 0&&{ticketId:t.ticketId},...t.parentRoundId!==void 0&&{parentRoundId:t.parentRoundId},...t.agendaItemId!==void 0&&{agendaItemId:t.agendaItemId}}),{applied:true,id:r,at:i}}function io(e){let t=me(q(e));return t?et(t.status)?{round:t}:{applied:false,reason:"already-terminal"}:{applied:false,reason:"no-current-round"}}function Mr(e,t=Date.now){let n=io(e);if("applied"in n)return n;let o=t();return Ho(e,n.round.id,o),{applied:true,at:o}}function $r(e,t=Date.now){let n=io(e);if("applied"in n)return n;let o=t();return Uo(e,n.round.id,o),{applied:true,at:o}}function Br(e,t,n=Date.now){let o=io(e);if("applied"in o)return o;let r=n();return jo(e,o.round.id,r,t),{applied:true,at:r}}function Hr(e,t,n){let o=q(e),r=tt(o);if(!r)return {applied:false,reason:"no-active-round"};let i=o.participants.find(s=>s.id===t);return !i||!we(i)||ge(i)!=="voter"?{applied:false,reason:"not-a-voter"}:r.votes[t]===n?(qn(e,r.id,t),{applied:true,effect:"cleared"}):($o(e,r.id,t,n),{applied:true,effect:"cast"})}function Ur(e,t){let n=q(e),o=tt(n);return o?(qn(e,o.id,t),{applied:true,effect:"cleared"}):{applied:false,reason:"no-active-round"}}function jr(e){let{doc:t,participantId:n,onlineIds:o}=e,r=e.now??Date.now;return {startRound:i=>Lr(t,i,r),revealCurrentRound:()=>Mr(t,r),skipCurrentRound:()=>$r(t,r),discardCurrentRound:()=>Br(t,n,r),toggleCurrentVote:i=>Hr(t,n,i),clearCurrentVote:()=>Ur(t,n),addItem:i=>qo(t,i,r),editItem:(i,s)=>Xo(t,i,s),skipItem:i=>Qo(t,i),cancelItem:i=>Zo(t,i),moveItem:(i,s,a)=>er(t,i,s,a),rename:i=>Er(t,n,i),recolor:i=>Tr(t,n,i),toggleRole:()=>kr(t,n),leave:()=>Pr(t,n,r),kick:i=>Or(t,n,i,r),handoffHost:i=>Dr(t,n,i,o()),endSession:()=>_r(t,n,r)}}var Fr={startRound:()=>({applied:false,reason:"no-session"}),revealCurrentRound:()=>({applied:false,reason:"no-current-round"}),skipCurrentRound:()=>({applied:false,reason:"no-current-round"}),discardCurrentRound:()=>({applied:false,reason:"no-current-round"}),toggleCurrentVote:()=>({applied:false,reason:"no-active-round"}),clearCurrentVote:()=>({applied:false,reason:"no-active-round"}),addItem:()=>({applied:false,reason:"not-found"}),editItem:()=>({applied:false,reason:"not-found"}),skipItem:()=>({applied:false,reason:"not-found"}),cancelItem:()=>({applied:false,reason:"not-found"}),moveItem:()=>({applied:false,reason:"not-found"}),rename:()=>({applied:false,reason:"not-found"}),recolor:()=>({applied:false,reason:"not-found"}),toggleRole:()=>({applied:false,reason:"not-found"}),leave:()=>({applied:false,reason:"not-found"}),kick:()=>({applied:false,reason:"not-found"}),handoffHost:()=>({applied:false,reason:"not-found"}),endSession:()=>({applied:false,reason:"not-found"})};function Vr(e){let{prevName:t,newName:n,isSelf:o,wasSelf:r=false,cause:i=null}=e,s=o?"You are now the host":`${n} is now the host`;if(!t||r||i===null)return s;switch(i){case "left":return `${t} left. ${s}.`;case "disconnected":return `${t} disconnected. ${s}.`}}var Ia="Session ended.",Ra=e=>`Session ended by ${e}`,ba="Removed by host";function Qt(e,t){if(t!==null)return e.find(n=>n.id===t)?.displayName||void 0}function Kr(e){let t=false,n=null,o=null,r=null,i="unset",s=false,a=[],d=false;function l(g){let p=g.meta.sessionEndedAt;if(p==null){n=null;return}if(p===n)return;n=p;let A=g.settings.hostParticipantId||null,E=Qt(g.participants,A)??Qt(g.participants,g.meta.createdBy)??"Host";a.push(()=>{let C=e.endedLocally();return {kind:"ended",endedAt:p,endedLocally:C,hostId:A,hostName:E,message:C?Ia:Ra(E)}});}function u(g){let p=g.participants.find(v=>v.id===e.selfId);if(!p)return;let{leftAt:A,removedBy:E}=p;if(A===void 0){i=void 0,r=null;return}if(E===e.selfId){i=A;return}if(!s){i=A;return}if(i==="unset"){i=A;return}if(i!==void 0){i=A;return}if(i=A,A===r)return;r=A;let C=E??null,k={kind:"removed",leftAt:A,removedBy:C,removedByName:C===null?null:Qt(g.participants,C)??C,message:ba};a.push(()=>k);}function c(g){let p=g.settings.hostParticipantId||null;if(p===null){o=null;return}if(o===null){o=p;return}if(p===o)return;let A=o;o=p;let E=g.participants.find(_=>_.id===A),C=E===void 0?null:E.displayName||A,k=E!==void 0&&!we(E),v=Qt(g.participants,p)??p,B=A===e.selfId,b=p===e.selfId;a.push(()=>{let _=null;return k?_="left":E!==void 0&&e.presenceTrusted()&&!e.onlineIds().has(A)&&(_="disconnected"),{kind:"host-changed",previousHostId:A,previousHostName:C,hostId:p,hostName:v,cause:_,wasSelf:B,isSelf:b,message:Vr({prevName:C,newName:v,isSelf:b,wasSelf:B,cause:_})}});}function f(){d=false;let g=a;a=[];for(let p of g){if(t)return;e.emit(p());}}function N(){if(t)return;let g=e.projection();g&&(!s&&e.firstSyncCompleted()&&(s=true),l(g),u(g),c(g),a.length>0&&!d&&(d=true,queueMicrotask(f)));}let P=e.subscribe(N);return N(),{stop(){t||(t=true,a=[],P());}}}var Yr="participantId";function Jr(e){let t=new Set;for(let n of e.values()){if(typeof n!="object"||n===null)continue;let o=n[Yr];typeof o=="string"&&t.add(o);}return t}function Ea(e,t){if(e.size!==t.size)return false;for(let n of e)if(!t.has(n))return false;return true}function Gr(e){let{room:t,self:n,seed:o}=e,r=n.participantId,i=e.now??Date.now,s=new $e.Doc;o.kind==="create"?Kn(s,{roomUuid:t.uuid,createdAt:i(),participantId:r,displayName:n.displayName,defaultScale:o.defaultScale,...o.sessionName!==void 0&&{sessionName:o.sessionName},...n.avatarColor!==void 0&&{avatarColor:n.avatarColor}}):Jn(s,{participantId:r,displayName:n.displayName,joinedAt:i(),...n.avatarColor!==void 0&&{avatarColor:n.avatarColor}});let a=new Awareness(s);a.setLocalStateField(Yr,r);let d=false,l=q(s),u=Jr(a.getStates()),c=false,f=false,N=false,P=new Set,g=()=>{for(let I of P)I();},p=I=>(P.add(I),()=>{P.delete(I);}),A=new Set([s.getMap(Ht),s.getMap(Ut),s.getMap(jt),s.getArray(Ft),s.getArray(Vt)]),E=I=>{for(let w of I.changedParentTypes.keys())if(A.has(w))return true;return false},C=I=>{E(I)&&(l=q(s),e.onProjectionChange?.(l),g());};s.on("afterTransaction",C);let k=()=>{let I=Jr(a.getStates());Ea(I,u)||(u=I,e.onOnlineIdsChange?.(u)),g();};a.on("change",k),e.onProjectionChange?.(l),e.onOnlineIdsChange?.(u),e.onStatusChange?.("connecting");let v=jr({doc:s,participantId:r,onlineIds:()=>u,now:i}),B={...v,endSession(){let I=v.endSession();return I.applied&&(N=true),I}},b=fr({projection:()=>l,onlineIds:()=>u,myId:()=>r,subscribe:p,promote(I){ro(s,I);}}),_=cr({projection:()=>l,onlineIds:()=>u,presenceTrusted:()=>c,selfId:()=>r,subscribe:p,reveal(){B.revealCurrentRound().applied&&e.onAutoReveal?.();}}),T=Kr({projection:()=>l,onlineIds:()=>u,presenceTrusted:()=>c,firstSyncCompleted:()=>f,endedLocally:()=>N,selfId:r,subscribe:p,emit(I){e.onSessionEvent?.(I);}}),{participantKey:O}=e.credentials,Y={roomCode:t.code,deviceId:e.credentials.deviceId,...O!==void 0&&{participantKey:O},...e.credentials.passwordHash!==void 0&&{passwordHash:e.credentials.passwordHash}},K=null,{beforeConnect:G}=e;G===void 0?j():Promise.resolve().then(()=>d?void 0:G(s)).then(j,j);function j(){d||(K=Rr({httpBaseUrl:e.httpBaseUrl,roomUuid:t.uuid,doc:s,credentials:Y,awareness:a,WebSocketPolyfill:e.WebSocketPolyfill,onStatusChange(I){d||e.onStatusChange?.(I);},onRejectionChange(I){d||e.onRejectionChange?.(I);},onReconnectingChange(I){d||e.onReconnectingChange?.(I);},onRepeatRejection(){d||e.onRepeatRejection?.();},onSynced(){d||(f=true,o.kind==="join"&&Nr(s,r),e.onFirstSync?.());},onSyncedChange(I){d||(c=I,e.onSyncedChange?.(I),g());}}));}return {get commands(){return B},async handoffHost(I){if(d)return {applied:false,reason:"not-found"};let w=oo(s,r,I,u);if(w!==null)return w;if(O===void 0)return {applied:false,reason:"unauthenticated"};try{await Ir(e.httpBaseUrl,t.uuid,{participantId:r,pk:O,target:I});}catch(M){return {applied:false,reason:qt(M)}}return d?{applied:false,reason:"not-found"}:ro(s,I)},updateCredentials(I){if(d)return;let{passwordHash:w,...M}=Y;Y=I===null?M:{...M,passwordHash:I},K?.updateCredentials({passwordHash:I});},updateSettings(I){d||Wn(s,I);},updateRoundDescriptor(I,w){d||Gn(s,I,w);},async flushUpdates(I=500){await K?.flush(I);},teardown(){d||(d=true,B=Fr,T.stop(),_.stop(),b.stop(),s.off("afterTransaction",C),a.off("change",k),K?.disconnect(),K=null,a.destroy(),s.destroy());}}}var zr="PBKDF2",Ta="SHA-256",qr=new TextEncoder;function ka(e){return Array.from(new Uint8Array(e)).map(t=>t.toString(16).padStart(2,"0")).join("")}var Pa=/^[\s\u200B-\u200D\u2060]+|[\s\u200B-\u200D\u2060]+$/gu,so=120;function Pe(e){return e.normalize("NFC").replace(Pa,"")}async function Zt(e,t){let n=await crypto.subtle.importKey("raw",qr.encode(Pe(e)),zr,false,["deriveBits"]),o=await crypto.subtle.deriveBits({name:zr,salt:qr.encode(t),iterations:1e5,hash:Ta},n,256);return ka(o)}var Xr="ABCDEFGHJKMNPQRSTUVWXYZ23456789";if(Xr.length!==31)throw new Error(`Room code alphabet must be 31 characters, got ${Xr.length}`);function ao(e){return e.trim().replaceAll(/-/g,"").toUpperCase()}function Qr(e,t=true){let n=ao(e);return !t||n.length!==6?n:`${n.slice(0,3)}-${n.slice(3)}`}function xt(e,t){let n=0;for(let o of t){if(o.status==="discarded"){if(o.id===e.id)return 0;continue}if(n+=1,o.id===e.id)return n}return 0}function lo(e,t){let n=hr(e.id,t);return n!==null?`Round ${n.depth}/${n.total} [re-vote]`:`Round ${xt(e,t)}`}function Zr(e){let t=new Set(e).size;return t===1?"unanimous":t===2?"close":"spread"}function Na(e,t){let n=new Map;t.forEach((i,s)=>n.set(i,s));let o=[...new Set(e.filter(i=>!n.has(i)))].toSorted(),r=new Map;return o.forEach((i,s)=>r.set(i,t.length+s)),i=>n.get(i)??r.get(i)??Number.MAX_SAFE_INTEGER}function co(e,t){let n=new Map;for(let a of e)n.set(a,(n.get(a)??0)+1);let o=null,r=0,i=[...n.keys()].toSorted((a,d)=>t(a)-t(d));for(let a of i){let d=n.get(a);d>r&&(r=d,o=a);}let s=i.filter(a=>n.get(a)===r).length>1;return {mode:o,modeTied:s}}function Oa(e,t){let n=Object.values(e);if(n.length===0)return null;let o=Na(n,t.cards);if(t.cards.every(i=>Number.isFinite(parseFloat(i)))){let i=n.map(parseFloat).filter(Number.isFinite);if(i.length===0)return {kind:"categorical",...co(n,o),spread:Zr(n)};let s=i.reduce((c,f)=>c+f,0)/i.length,a=[...i].toSorted((c,f)=>c-f),d=Math.floor(a.length/2),l=a.length%2===1?a[d]:(a[d-1]+a[d])/2,u;if(new Set(n).size===1)u="unanimous";else {let c=n.map(P=>o(P)),f=Math.min(...c);u=Math.max(...c)-f<=1?"close":"spread";}return {kind:"numeric",mean:s,median:l,...co(n,o),spread:u}}return {kind:"categorical",...co(n,o),spread:Zr(n)}}function en(e){let t=Object.fromEntries(Object.entries(e.votes).filter(([,n])=>!ee(n)));return Oa(t,e.scale)}function Da(e){return e==="unanimous"?"Unanimous":e==="close"?"Close":"Spread"}function tn(e){if(e===null)return null;let t=Da(e.spread),n=e.modeTied?null:e.mode;return e.kind==="numeric"?{kind:"numeric",mean:e.mean.toFixed(1),median:e.median.toFixed(1),mode:n,spread:t}:{kind:"categorical",mode:n,spread:t}}function ot(e){return e.status!=="revealed"||e.terminalAt===void 0||e.timerStartedAt===void 0?null:Gt(e.terminalAt-e.timerStartedAt)}function uo(e){return e.replaceAll(/\|/g,"\\|")}function _a(e){return e.replaceAll(/\\/g,"\\\\").replaceAll(/]/g,"\\]")}function La(e){let n=(e.match(/`+/g)??[]).reduce((o,r)=>Math.max(o,r.length),0);return "`".repeat(n+1)}function fo(e){if(!e)return "";if(pr(e))return ` ([${_a(e)}](<${e}>))`;let t=La(e);return ` (${t}${e}${t})`}function Ma(e){return e instanceof Map?e:new Map(Object.entries(e))}function $a(e){let t=new Map;for(let r of e)t.set(r.id,r);function n(r){if(!r.parentRoundId)return r;let i=t.get(r.parentRoundId);return i?n(i):r}let o=new Map;for(let r of e){let i=n(r),s=o.get(i.id);s?s.push(r):o.set(i.id,[r]);}return o}function ei(e,t){let n=new Map;e.scale.cards.forEach((a,d)=>n.set(a,d));let o=new Map,r=[];for(let[a,d]of Object.entries(e.votes)){let l=t.get(a)??a;if(ee(d)){r.push(l);continue}let u=o.get(d);u?u.push(l):o.set(d,[l]);}let i=[...o.entries()].map(([a,d])=>({card:a,scaleIndex:n.get(a)??Number.MAX_SAFE_INTEGER,voters:[...d].toSorted().map(uo)}));i.sort((a,d)=>{let l=d.voters.length-a.voters.length;return l!==0?l:a.scaleIndex-d.scaleIndex});let s=i.map(a=>`| ${uo(a.card)} | ${a.voters.join(", ")} |`);return r.length>0&&s.push(`| Abstained | ${[...r].toSorted().map(uo).join(", ")} |`),["| Vote | Voters |","|------|--------|",...s].join(`
3
+ `)}function ti(e){let t=tn(en(e)),n=ot(e),o=[];return t?.kind==="numeric"?o.push(`Avg ${t.mean} \xB7 Med ${t.median}`):t?.kind==="categorical"&&t.mode!==null&&o.push(`Most common: ${t.mode}`),n!==null&&o.push(`Elapsed ${n}`),o.join(" \xB7 ")}function ni(e){let{rounds:t}=e,n=Ma(e.participants),o=new Map;for(let[u,c]of n)o.set(u,c.displayName);let r=t.filter(u=>u.status==="revealed");if(r.length===0)return "";let i=new Map;for(let u of t)i.set(u.id,xt(u,t));let s=$a(r),a=new Set,d=[];for(let u of r)for(let[c,f]of s)if(f.includes(u)&&!a.has(c)){a.add(c),d.push(c);break}let l=[];for(let u of d){let c=s.get(u),f=c.find(C=>C.id===u),N=c.filter(C=>C.id!==u),P=i.get(f.id)??0,g=f.title?`## Round ${P} \u2014 ${f.title}${fo(f.ticketId)}`:`## Round ${P}${fo(f.ticketId)}`,p=ei(f,o),A=ti(f),E=A?`${g}
4
4
 
5
- ${g}
5
+ ${p}
6
6
 
7
- ${E}`:`${p}
7
+ ${A}`:`${g}
8
8
 
9
- ${g}`;u.push(A);for(let b of k){let C=`### Re-vote ${s.get(b.id)??0}${eo(b.ticketId)}`,L=Jr(b,o),I=Yr(b),D=I?`${C}
9
+ ${p}`;l.push(E);for(let C of N){let v=`### Re-vote ${i.get(C.id)??0}${fo(C.ticketId)}`,B=ei(C,o),b=ti(C),_=b?`${v}
10
10
 
11
- ${L}
11
+ ${B}
12
12
 
13
- ${I}`:`${C}
13
+ ${b}`:`${v}
14
14
 
15
- ${L}`;u.push(D);}}return u.join(`
15
+ ${B}`;l.push(_);}}return l.join(`
16
16
 
17
17
  `)+`
18
- `}function en(e,t,n){if(e.startsWith("custom-")){let r=(n??[]).find(s=>s.id===e);return r?{id:r.id,cards:r.cards}:void 0}let o=de[e];if(o){let r=(t??{})[e]??[];if(r.length===0)return o;let s=o.cards.filter((a,i)=>!r.includes(i));return s.length===0?void 0:{id:e,cards:s}}}function tn(e,t){let n=Object.keys(de).map(r=>en(r,e,t)).filter(r=>r!==void 0),o=(t??[]).map(r=>({id:r.id,cards:r.cards}));return [...n,...o]}function He(e,t){if(e.startsWith("custom-")){let n=(t??[]).find(o=>o.id===e);if(n&&n.label.trim().length>0)return n.label}return tr(e)}function Kr(e){return Ze(e)===null?"lobby":"estimating"}var ya="https://hnch.dev";function wt(){let t=process.env.XDG_CONFIG_HOME||join(homedir(),".config");return join(t,"hnch")}function no(){return join(wt(),"config.json")}function qr(){let e=wt();existsSync(e)||mkdirSync(e,{recursive:true});}function je(){let e=no();if(!existsSync(e))return {};try{return JSON.parse(readFileSync(e,"utf-8"))}catch{return {}}}function z(e){qr();let n={...je(),...e};writeFileSync(no(),JSON.stringify(n,null,2)+`
19
- `,"utf-8");}async function va(e){let t=createInterface({input:process.stdin,output:process.stderr});return new Promise(n=>{t.question(e,o=>{t.close(),n(o.trim());});})}function Ia(e){return e.startsWith("wss://")?"https://"+e.slice(6):e.startsWith("ws://")?"http://"+e.slice(5):e}async function le(){let e=je(),t=false;if(e.participantId||(e.participantId=randomUUID(),t=true),!e.displayName){let o=await va("Enter your display name: ");e.displayName=o||`user-${e.participantId.slice(0,6)}`,t=true;}e.relayUrl||(e.relayUrl=ya,t=true),(!e.avatarColor||Be(e.avatarColor)===null)&&(e.avatarColor=or(e.participantId),t=true),t&&z(e);let n=process.env.HNCH_RELAY_URL||e.relayUrl;return n=Ia(n),{participantId:e.participantId,displayName:e.displayName,relayUrl:n,defaultScale:e.defaultScale,defaultSessionName:e.defaultSessionName,defaultPassword:e.defaultPassword,presetOverrides:e.presetOverrides,customScales:e.customScales,avatarColor:e.avatarColor}}function Ct(e){qr();let n={...je()};for(let[o,r]of Object.entries(e))r===""?delete n[o]:r!==void 0&&(n[o]=r);writeFileSync(no(),JSON.stringify(n,null,2)+`
20
- `,"utf-8");}function nn(e){let t=ke(e);return t===""?{ok:false,message:"Password cannot be empty."}:e.trim().length>zn?{ok:false,message:`Password is too long (at most ${zn} characters).`}:{ok:true,password:t}}async function Xr(e){let t=await ur(e.relayUrl),n;return e.password!==void 0&&ke(e.password)!==""&&(n=await Xt(e.password,t.uuid),await Kn(e.relayUrl,t.uuid,n)),Zr({...e,roomCode:t.code,roomUuid:t.uuid,passwordHash:n},{kind:"create",defaultScale:e.defaultScale??Gt,sessionName:e.sessionName})}async function Qr(e){let t=await ce(e.relayUrl,e.roomCode),n;if(t.accessMode==="password"){if(e.password===void 0||ke(e.password)==="")throw new Error("Room requires a password");n=await Xt(e.password,t.uuid);}return yt({...e,roomUuid:t.uuid,passwordHash:n})}function yt(e){return Zr(e,{kind:"join"})}function Zr(e,t){let{relayUrl:n,roomUuid:o}=e,r=new Set,s=new Set,a=new Set,i=false,d=()=>{},u=new Promise(p=>{d=p;}),l,c=new Set,f=()=>{for(let p of r)p();},k=Ur({httpBaseUrl:n,room:{uuid:o,code:e.roomCode},credentials:{deviceId:e.participantId,...e.passwordHash!==void 0&&{passwordHash:e.passwordHash}},self:{participantId:e.participantId,displayName:e.displayName,...e.avatarColor!==void 0&&{avatarColor:e.avatarColor}},seed:t,WebSocketPolyfill:ba,onProjectionChange(p){l=p,f();},onOnlineIdsChange(p){c=p,f();},onStatusChange(p){for(let g of s)g(p);},onRejectionChange(p){p!==null&&(console.error(`Connection rejected: ${p}`),e.onRejection?.(p));},onRepeatRejection(){console.error("Trouble reaching the room \u2014 retrying.");},onFirstSync(){i=true,d();},onSessionEvent(p){for(let g of a)g(p);}});function O(){if(l===void 0)throw new Error("session: no projection reported");return l}return {roomCode:e.roomCode,roomUuid:o,passwordHash:e.passwordHash,get commands(){return k.commands},projection:O,current(){return me(O())},isHost(){return O().settings.hostParticipantId===e.participantId},hasJoined(){return i},whenJoined(){return u},onlineIds(){return c},updateRoundDescriptor(p,g){k.updateRoundDescriptor(p,g);},updateName(p){k.updateSettings({name:p});},updateScale(p){k.updateSettings({defaultScale:p});},async updateAccess(p,g){let E=null;if(p==="password"){let A=nn(g??"");if(!A.ok)throw new Error(A.message);E=await Xt(A.password,o);}await Kn(n,o,E),k.updateCredentials(E);},onChange(p){return r.add(p),()=>r.delete(p)},onStatusChange(p){return s.add(p),()=>s.delete(p)},onSessionEvent(p){return a.add(p),()=>{a.delete(p);}},flushUpdates(p){return k.flushUpdates(p)},teardown(){k.teardown();}}}function es(e){let t=qn(e);return t===""?null:t}function Fe(){return join(wt(),"last-session.json")}function ka(e,t){let n=wt();mkdirSync(n,{recursive:true,mode:448}),chmodSync(n,448),writeFileSync(e,t,{encoding:"utf-8",mode:384}),chmodSync(e,384);}function rs(){let e=Fe();try{unlinkSync(e);}catch(t){if(t.code!=="ENOENT")throw t}}function oo(){let e=Fe();if(!existsSync(e))return {};try{let t=JSON.parse(readFileSync(e,"utf-8"));return {...Yn(t).entries}}catch{return {}}}function ro(e){let t={version:2,entries:e};ka(Fe(),JSON.stringify(t,null,2)+`
21
- `);}function rn(e){let t=Date.now();if(!existsSync(Fe()))return [];let n;try{n=JSON.parse(readFileSync(Fe(),"utf-8"));}catch{return []}let o=Yn(n),r=ar(o,t),s=Object.values(r.entries);return s.length===0?(rs(),[]):s.toSorted((a,i)=>i.lastSeenAt-a.lastSeenAt)}function Pa(e,t){return e!==void 0?{passwordHash:e}:t!==void 0?{passwordHash:t}:{}}function sn(e){let t=Date.now(),n=oo(),o=n[e.roomUuid];n[e.roomUuid]={roomCode:e.roomCode,roomUuid:e.roomUuid,lastSeenAt:e.lastSeenAt??t,...Pa(e.passwordHash,o?.passwordHash)};let r=Object.keys(n);if(r.length>5){let s=r.toSorted((a,i)=>(n[a]?.lastSeenAt??0)-(n[i]?.lastSeenAt??0)).slice(0,r.length-5);for(let a of s)delete n[a];}ro(n);}function vt(e){if(!existsSync(Fe()))return;let t=oo();if(delete t[e],Object.keys(t).length===0){rs();return}ro(t);}function so(e){if(!existsSync(Fe()))return;let t=oo(),n=t[e];if(!n)return;let{passwordHash:o,...r}=n;t[e]=r,ro(t);}async function io(e){let t=true;try{await e.clearLastSession();}catch(n){t=false,e.logger.error(`Failed to clear cached session: ${n instanceof Error?n.message:String(n)}`);}return t?e.logger.error("Session expired (room no longer exists). Cached session cleared."):e.logger.error("Session expired. Could not delete ~/.config/hnch/last-session.json \u2014 please remove it manually."),e.exit(1)}function Oa(e){return e.isTTY===true&&typeof e.setRawMode=="function"}var Da="\r",_a=`
22
- `,Ma="\x7F",$a="\b",La=" ",Ua="",Ba="",Ha="",ja="",Fa="\x1B";function Va(e){return e<" "&&e!==La}function Ja(e,t){let n=e[t+1];if(n===void 0)return 1;if(n==="O")return Math.min(3,e.length-t);if(n!=="[")return 2;for(let o=t+2;o<e.length;o++){let r=e[o];if(r>="@"&&r<="~")return o-t+1}return e.length-t}async function ss(e={}){let t=e.stdin??process.stdin,n=e.stderr??process.stderr,o=e.exit??process.exit;n.write("Password: ");let r=Oa(t)?await Wa(t,n,o):await Ya(t);return ke(r)}function Ya(e){return new Promise(t=>{let n=createInterface({input:e}),o=false,r=s=>{o||(o=true,n.close(),t(s));};n.once("line",r),n.once("close",()=>r(""));})}function Wa(e,t,n){return new Promise(o=>{let r="",s=false;e.setRawMode(true),e.resume(),e.setEncoding("utf8");let a=()=>{s=true,e.setRawMode(false),e.pause(),e.removeListener("data",i);},i=d=>{let u=Array.from(d);for(let l=0;l<u.length&&!s;l++){let c=u[l];if(c===Ua&&(a(),t.write(`
23
- `),n(130)),c===Da||c===_a){a(),t.write(`
24
- `),o(r);return}if(c===Ba){if(r.length===0){a(),t.write(`
25
- `),o(r);return}continue}if(c===Fa){l+=Ja(u,l)-1;continue}if(c===Ma||c===$a){r=Array.from(r).slice(0,-1).join("");continue}if(c===Ha){r="";continue}if(c===ja){r=r.replace(/\S*\s*$/u,"");continue}Va(c)||(r+=c);}};e.on("data",i);})}function an(){let e=null,t;return {refused:()=>e,note(n){e=n,t?.();},attach(n){t=n,e!==null&&n();}}}function is(e,t){switch(e){case "wrong-password":return !t.wasIn&&t.typedPassword?{message:"That password is incorrect.",exitCode:1,remembered:"forget-session"}:{message:`Password changed \u2014 rejoin with: hnch join ${t.roomCode} --password`,exitCode:0,remembered:"forget-password"};case "room-full":return {message:`This room is full (max ${zo} participants).`,exitCode:1,remembered:t.wasIn?"keep":"forget-session"};default:return {message:`The relay refused the connection (${e}).`,exitCode:1,remembered:t.wasIn?"keep":"forget-session"}}}var Ka="@xauyxau/hnch";function dn(e){return Fr(e)}function cn(e){return `${process.env.HNCH_SHARE_ORIGIN??"https://hnch.dev"}/join?code=${e}`}function ln(e){return `npx ${Ka} join ${e}`}function ao(e){let t=e.trim();return t===""?void 0:t}function un(e){return e?{title:e.title??"",ticketId:e.ticketId??"",agendaItemId:e.id}:{title:"",ticketId:"",agendaItemId:void 0}}function as(e,t,n){return [e,ao(t),n]}var Ga={connecting:"yellow",connected:"green",disconnected:"red"};function ls({roomCode:e,sessionName:t,status:n,isHost:o}){let r=t?`${e} \xB7 ${t}`:e;return jsxs(Box,{borderStyle:"single",borderColor:"gray",paddingX:1,justifyContent:"space-between",children:[jsxs(Text,{bold:true,children:["hnch \xB7 ",r]}),jsxs(Box,{gap:2,children:[o&&jsx(Text,{color:"yellow",children:"[host]"}),jsx(Text,{color:Ga[n],children:n})]})]})}function he({items:e,onSelect:t,onClose:n,title:o}){if(e.length===0)return jsxs(Box,{flexDirection:"column",gap:1,children:[o&&jsx(Text,{bold:true,children:o}),jsx(Text,{dimColor:true,children:"(no items)"})]});let r=e.findIndex(i=>!i.disabled),[s,a]=useState(Math.max(r,0));return useInput((i,d)=>{if(d.upArrow)a(u=>{let l=(u-1+e.length)%e.length,c=0;for(;e[l]?.disabled&&c<e.length;)l=(l-1+e.length)%e.length,c++;return l});else if(d.downArrow)a(u=>{let l=(u+1)%e.length,c=0;for(;e[l]?.disabled&&c<e.length;)l=(l+1)%e.length,c++;return l});else if(d.return){let u=e[s];u&&!u.disabled&&t(u.value);}else d.escape&&n?.();}),jsxs(Box,{flexDirection:"column",gap:1,children:[o&&jsx(Text,{bold:true,children:o}),jsx(Box,{flexDirection:"column",children:e.map((i,d)=>{let u=d===s,l=i.disabled??false;return jsxs(Box,{gap:1,children:[jsx(Text,{...u&&{color:"cyan"},dimColor:l,children:u?">":" "}),jsx(Text,{bold:u,dimColor:l,children:i.label}),i.detail&&jsx(Text,{dimColor:true,children:i.detail})]},i.value)})}),jsx(Text,{dimColor:true,children:"\u2191\u2193 select \u23CE confirm esc close"})]})}function K({value:e,onChange:t,onSubmit:n,onCancel:o,placeholder:r,isActive:s=true,mask:a=false}){useInput((l,c)=>{c.escape?o?.():c.return?n(e):c.backspace||c.delete?t(e.slice(0,-1)):l&&!c.ctrl&&!c.meta&&t(e+l);},{isActive:s});let i=a&&e.length>0?"*".repeat(e.length):e,d=i.length>0?i:r??"",u=e.length===0&&r!==void 0;return jsxs(Text,{children:[jsx(Text,{dimColor:u,children:d}),jsx(Text,{inverse:true,children:" "})]})}function ms({mode:e,password:t,onModeChange:n,onPasswordChange:o,onClose:r}){let[s,a]=useState(e==="open"?0:1),[i,d]=useState(false);return useEffect(()=>{a(e==="open"?0:1);},[e]),useInput((u,l)=>{if(l.leftArrow)a(c=>Math.max(0,c-1));else if(l.rightArrow)a(c=>Math.min(1,c+1));else if(l.return){let c=s===0?"open":"password";c!==e&&n(c),c==="password"&&d(true);}else l.escape&&r?.();},{isActive:!i}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{gap:1,children:["open","password"].map((u,l)=>{let c=l===s,f=u===e,k=u==="open"?"Open":"Password";return jsx(Text,{inverse:c,bold:f,...f&&{color:"cyan"},children:f?`[${k}]`:` ${k} `},u)})}),e==="password"&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{children:"Password: "}),jsx(K,{value:t,onChange:o,onSubmit:()=>d(false),onCancel:()=>d(false),placeholder:"(required to join)",isActive:i,mask:true}),!i&&jsx(Text,{dimColor:true,children:"\u23CE edit \u2190 \u2192 switch mode esc close"}),i&&jsx(Text,{dimColor:true,children:"\u23CE done esc cancel"})]}),e==="open"&&jsx(Text,{dimColor:true,children:"\u2190\u2192 toggle \u23CE confirm esc close"})]})}function Ss({scaleId:e,cards:t,disabledIndices:n,onOverrideChange:o,onClose:r}){let s=useMemo(()=>new Set(n),[n]),[a,i]=useState(0),d=u=>{let l=new Set(s);if(l.has(u))l.delete(u);else {if(l.size>=t.length-1)return;l.add(u);}let c=Array.from(l).toSorted((f,k)=>f-k);o(e,c);};return useInput((u,l)=>{l.leftArrow?i(c=>Math.max(0,c-1)):l.rightArrow?i(c=>Math.min(t.length-1,c+1)):u===" "?d(a):(l.return||l.escape)&&r();}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{gap:1,children:t.map((u,l)=>{let c=l===a,f=s.has(l);return jsx(Text,{inverse:c,bold:!f,...!f&&{color:"cyan"},strikethrough:f,dimColor:f,children:u},u)})}),jsx(Text,{dimColor:true,children:" \u2190\u2192 navigate space toggle \u23CE/esc done"})]})}function ho({initialName:e="",initialCards:t=[],onSave:n,onCancel:o}){let r=e.length>0,[s,a]=useState(e),[i,d]=useState(t.length>0?t:[""]),[u,l]=useState(0),[c,f]=useState("editing-name"),[k,O]=useState(""),p=()=>{let A=s.trim();if(A.length===0||A.length>40){O("Name must be 1-40 characters");return}a(A),O(""),f("editing-cards");},g=()=>{let A=s.trim();if(A.length===0||A.length>40){O("Name must be 1-40 characters");return}let b=i.map(C=>C.trim()).filter(C=>C.length>0),P=Array.from(new Set(b));if(P.length<2){O("Need at least 2 unique non-empty cards");return}O(""),n(A,P);};return useInput((A,b)=>{if(c==="editing-cards"){if(b.leftArrow)l(P=>Math.max(0,P-1));else if(b.rightArrow)l(P=>{let C=P+1;return C>=i.length&&i.length<25?(d(L=>[...L,""]),C):Math.min(C,i.length-1)});else if(b.return)g();else if(b.escape)o();else if(b.tab)f("editing-name");else if(b.backspace){let P=i[u]||"";if(P.length===0){if(i.length>2){let C=i.filter((L,I)=>I!==u);d(C),l(Math.max(0,u-1));}}else {let C=[...i];C[u]=P.slice(0,-1),d(C);}}else if(A&&!b.ctrl&&!b.meta){let P=i[u]||"";if(P.length<10){let C=[...i];C[u]=P+A,d(C);}}}},{isActive:c==="editing-cards"}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:r?"\u2500\u2500 Edit Custom Scale \u2500\u2500":"\u2500\u2500 Create Custom Scale \u2500\u2500"}),jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Text,{children:"Name:"}),jsx(K,{value:s,onChange:a,onSubmit:p,onCancel:o,placeholder:"Scale name",isActive:c==="editing-name"})]}),c==="editing-cards"&&jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Text,{children:"Cards:"}),jsx(Box,{gap:1,flexWrap:"wrap",children:i.map((A,b)=>{let P=b===u;return jsx(Text,{inverse:P,...!P&&{color:"cyan"},children:A.length>0?A:"\xB7"},b)})})]}),k&&jsx(Text,{color:"red",children:k}),jsx(Text,{dimColor:true,children:c==="editing-name"?"\u23CE next esc cancel":"\u2190\u2192 navigate typing adds card bsp delete \u23CE save tab name esc cancel"})]})}function mn({scales:e,selectedScaleId:t,presetOverrides:n,customScales:o=[],onSelect:r,onOverrideChange:s,onCustomScaleCreate:a,onCustomScaleEdit:i,onCustomScaleDelete:d,onClose:u,showNoneOption:l=false}){let[c,f]=useState(0),[k,O]=useState(null),[p,g]=useState("browsing"),[E,A]=useState(null),[b,P]=useState(null),C=a?[...e,{id:"__create-custom__",cards:[]}]:e,L=C.length;if(useInput((I,D)=>{if(p==="browsing"){if(D.escape){u();return}if(L===0)return;if(D.upArrow)f(R=>(R-1+L)%L);else if(D.downArrow)f(R=>(R+1)%L);else if(D.return){let R=C[c];if(!R)return;if(R.id==="__create-custom__"){g("creating");return}R.id in de?O(k===R.id?null:R.id):r(R.id);}else if(I===" "){let R=C[c];R&&R.id!=="__create-custom__"&&r(R.id);}else if(I==="e"||I==="E"){let R=C[c];i&&R?.id.startsWith("custom-")&&(A(R.id),g("editing"));}else if(I==="d"||I==="D"){let R=C[c];d&&R?.id.startsWith("custom-")&&(P(R.id),g("confirming-delete"));}}else p==="confirming-delete"&&(I==="y"||I==="Y"?(b&&d&&d(b),P(null),g("browsing")):(I==="n"||I==="N"||D.escape)&&(P(null),g("browsing")));},{isActive:p==="browsing"&&k===null||p==="confirming-delete"}),p==="creating")return jsx(ho,{onSave:(I,D)=>{a&&a(I,D),g("browsing");},onCancel:()=>g("browsing")});if(p==="editing"&&E){let I=o?.find(R=>R.id===E);if(e.find(R=>R.id===E)&&I)return jsx(ho,{initialName:I.label,initialCards:I.cards,onSave:(R,N)=>{i&&i(E,R,N),A(null),g("browsing");},onCancel:()=>{A(null),g("browsing");}})}if(p==="confirming-delete"&&b){let I=C.find(R=>R.id===b),D=I?He(I.id,o):"Unknown";return jsxs(Box,{flexDirection:"column",gap:1,children:[jsxs(Text,{children:["Delete ",D,"? "]}),jsx(Text,{children:"[y] yes [n] no esc cancel"})]})}return C.length===0?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{dimColor:true,children:"(no scales available)"}),jsx(Text,{dimColor:true,children:"esc back"})]}):jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{flexDirection:"column",children:C.map((I,D)=>{let R=D===c,N=I.id===t,J=k===I.id,G=I.id in de,W=I.id==="__create-custom__",y=I.cards.join(", "),V=l&&I.id==="",T=V?"(none)":W?"[+ Create custom scale]":He(I.id,o);return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{...R&&{color:"cyan"},children:R?">":" "}),jsx(Text,{bold:R,children:T}),!V&&!W&&jsx(Text,{dimColor:true,children:y}),N&&jsx(Text,{color:"cyan",children:"[current]"})]}),J&&!V&&!W&&jsx(Box,{paddingLeft:2,children:G?jsx(Ss,{scaleId:I.id,cards:de[I.id]?.cards??[],disabledIndices:n?.[I.id]??[],onOverrideChange:s,onClose:()=>O(null)}):null})]},I.id||"none")})}),jsx(Text,{dimColor:true,children:(()=>{let I=c<C.length?C[c]:null;return I?.id.startsWith("custom-")?`\u2191\u2193 navigate space select${i?" [e] edit":""}${d?" [d] delete":""} esc back`:I&&I.id in de?"\u2191\u2193 navigate \u23CE customize space select esc back":"\u2191\u2193 navigate \u23CE/space select esc back"})()})]})}function dd(e,t){return t?[...e]:e.filter(n=>n.value==="display-name")}function xs({sessionName:e,displayName:t,currentScale:n,accessMode:o,presetOverrides:r,customScales:s,isHost:a=true,onChangeName:i,onChangeScale:d,onChangeDisplayName:u,onChangeAccess:l,onClose:c}){let[f,k]=useState(r??{}),O=useMemo(()=>tn(f,s),[f,s]),[p,g]=useState("main-menu"),[E,A]=useState(e??""),[b,P]=useState(t),[C,L]=useState(o==="password"?"password":"open"),[I,D]=useState(""),[R,N]=useState(false),J=[{label:"Room name",value:"room-name",detail:`[${e??"(none)"}]`},{label:"Scale",value:"scale",detail:`[${He(n.id,s)}]`},{label:"Access",value:"access",detail:`[${o==="open"?"Open":"Password"}]`},{label:"Display name",value:"display-name",detail:`[${t}]`}],G=dd(J,a);function W(m){!a&&m!=="display-name"||(m==="room-name"?(A(e??""),g("editing-room-name")):m==="scale"?g("picking-scale"):m==="access"?g("picking-access"):m==="display-name"&&(P(t),g("editing-display-name")));}function y(m){let w=m.trim()===""?void 0:m.trim();i(w),g("main-menu");}function V(m){let w=m.trim();w.length>0&&(u(w),process.nextTick(()=>z({displayName:w}))),g("main-menu");}function T(m){let w=O.find(_=>_.id===m);w&&d(w),g("main-menu");}function B(m,w){let _={...f};w.length===0?delete _[m]:_[m]=w,k(_),z({presetOverrides:Object.keys(_).length>0?_:void 0});}async function Y(m,w){N(true);try{await l(m,w),L(m),D(m==="password"?w??"":"");}catch(_){console.error(`Failed to update access: ${_}`);}finally{N(false),g("main-menu");}}return p==="main-menu"?jsx(he,{title:"\u2500\u2500 Settings \u2500\u2500",items:G,onSelect:W,onClose:c}):p==="editing-room-name"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Text,{children:"Room name: "}),jsx(K,{value:E,onChange:A,onSubmit:y,onCancel:()=>g("main-menu"),placeholder:"(leave empty to remove)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]}):p==="editing-display-name"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Text,{children:"Display name: "}),jsx(K,{value:b,onChange:P,onSubmit:V,onCancel:()=>g("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]}):p==="picking-scale"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(mn,{scales:O,selectedScaleId:n.id,presetOverrides:f,onSelect:T,onOverrideChange:B,onClose:()=>g("main-menu")})]}):p==="picking-access"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),R&&jsx(Text,{dimColor:true,children:"Updating access..."}),!R&&jsx(ms,{mode:C,password:I,onModeChange:m=>{m==="open"&&Y("open");},onPasswordChange:D,onClose:()=>g("main-menu")})]}):jsx(Box,{})}function Sn({participants:e,onlineIds:t,hostId:n,votes:o,revealed:r,participantId:s}){return jsxs(Box,{flexDirection:"column",children:[jsxs(Text,{bold:true,children:["Participants (",e.length,")"]}),e.map(a=>{let i=t.has(a.id),d=i?"\u25CF":"\u25CB",u=i?"green":"gray",l=a.id===n,c=ge(a)==="viewer",f=a.id===s,k=a.id in o,O=c?" (viewer)":r?o[a.id]?` \u2192 ${o[a.id]}`:"":k?" \u2713":" \xB7",p=f&&!c&&!(r&&o[a.id]);return jsxs(Box,{gap:1,children:[jsx(Text,{color:u,children:d}),jsxs(Text,{children:[a.displayName,l?" (host)":""]}),p?jsx(Text,{color:"cyan",children:"(voter)"}):jsx(Text,{color:c?"gray":k?"green":"gray",children:O})]},a.id)})]})}var cd=[{label:"End session for everyone",value:"end-session",detail:"Disconnects all participants. Cannot be undone."}];function Cs({onPick:e,onClose:t}){return jsx(he,{title:"Host Actions",items:cd,onSelect:e,onClose:t})}function xn({roomCode:e,onPick:t,onClose:n}){let o=[{label:"Copy code",value:"code",detail:dn(e)},{label:"Copy share link",value:"url",detail:cn(e)},{label:"Copy npx command",value:"npx",detail:ln(e)}];return jsx(he,{title:"Share",items:o,onSelect:r=>t(r),onClose:n})}function fd(e){let t=Object.fromEntries(e.participants.map(n=>[n.id,n]));return Wr({rounds:e.rounds,participants:t})}async function ys(e,t,n){let o=fd(e);try{await t(o),n("Results copied to clipboard");}catch{n("Clipboard write failed");}}function vs(e,t){let n=Qn(e,t),o=e.title?` \u2014 ${e.title}`:"",r=e.ticketId?` [${e.ticketId}]`:"",s=e.status==="skipped"?" \u2014 Skipped":" \u2014 Results";return `${n}${o}${r}${s}`}function Is(e,t){let n=Qn(e,t);if(e.status==="skipped"){let c=e.title?` ${e.title}`:"",f=e.ticketId?` [${e.ticketId}]`:"";return `${n}:${c}${f} \u2014 Skipped`}let o=new Map;for(let c of Object.values(e.votes))ee(c)||o.set(c,(o.get(c)??0)+1);let r=[...o.entries()].toSorted((c,f)=>f[1]-c[1]||c[0].localeCompare(f[0])).map(([c,f])=>`${c}\xD7${f}`).join(", "),s=Object.values(e.votes).filter(ee).length,a=s>0?` (${s} abstained)`:"",i=e.title?` ${e.title}`:"",d=e.ticketId?` [${e.ticketId}]`:"",u=tt(e),l=u!==null?` \u2014 ${u}`:"";return `${n}:${i}${d} \u2014 ${r||"(no votes)"}${a}${l}`}function bs({projection:e,onlineIds:t,isHost:n,participantId:o,rounds:r,currentRound:s,settingsOpen:a,onStartRound:i,onNewRound:d,onRevote:u,onOpenSettings:l,onHandoffHost:c,onEndSession:f,onShare:k,shareOpen:O,onSetShareOpen:p,roomCode:g,confirmingQuit:E,myRole:A,onToggleRole:b,roundTitlePromptActive:P,roundTitleInput:C,onRoundTitleChange:L,onRoundTitleSubmit:I,onRoundTitleCancel:D,roundTicketIdPromptActive:R,roundTicketIdInput:N,onRoundTicketIdChange:J,onRoundTicketIdSubmit:G,onRoundTicketIdCancel:W,descriptorPromptActive:y,descriptorInput:V,onDescriptorChange:T,onDescriptorSubmit:B,onDescriptorCancel:Y,onEditDescriptor:m,canExport:w,onExportResults:_,onAgendaAdd:X,agendaAddPromptActive:ue,agendaAddTitleInput:at,onAgendaAddTitleChange:Rn,onAgendaAddTitleSubmit:Ge,onAgendaAddTitleCancel:Ot,agendaAddTicketIdPromptActive:Ie,agendaAddTicketIdInput:Tn,onAgendaAddTicketIdChange:ze,onAgendaAddTicketIdSubmit:qe,onAgendaAddTicketIdCancel:_e}){let[oe,re]=wn.useState("idle"),[Se,be]=wn.useState(null),[dt,ae]=wn.useState(false),[fe,xe]=wn.useState(false);useEffect(()=>{n||(re("idle"),be(null),ae(false),xe(false));},[n]),useInput(v=>{if(v==="c"||v==="C"){p(true);return}if(v==="w"||v==="W"){b();return}if((v==="x"||v==="X")&&w){_();return}if(n){if(v==="a"||v==="A"){X();return}(v==="e"||v==="E")&&l(),(v==="s"||v==="S")&&i(),(v==="h"||v==="H")&&re("picking"),(v==="m"||v==="M")&&ae(true),s!==null&&lt(s.status)&&((v==="n"||v==="N")&&d(),(v==="v"||v==="V")&&s.status!=="skipped"&&u(),(v==="t"||v==="T")&&m());}},{isActive:!a&&!E&&oe==="idle"&&!P&&!R&&!dt&&!fe&&!O&&!y&&!ue&&!Ie}),useInput((v,pe)=>{v==="y"||v==="Y"?(f(),xe(false)):(v==="n"||v==="N"||pe.escape)&&xe(false);},{isActive:fe});let Ae=e.participants.filter(v=>v.id!==o&&t.has(v.id));useInput(v=>{if(oe==="picking"){let pe=parseInt(v,10);!isNaN(pe)&&pe>=1&&pe<=Ae.length?(be(Ae[pe-1].id),re("confirming")):(v==="Escape"||v==="q"||v==="Q")&&re("idle");}},{isActive:oe==="picking"}),useInput(v=>{oe==="confirming"&&Se&&(v==="y"||v==="Y"?(c(Se),re("idle"),be(null)):(v==="n"||v==="N"||v==="Escape")&&(re("idle"),be(null)));},{isActive:oe==="confirming"});let Xe=r.filter(v=>Ut(v.status)),Me=Xe.length>0,Dt=s!==null?Xe.slice(0,-1):Xe;return dt?jsx(Cs,{onPick:v=>{ae(false),v==="end-session"&&xe(true);},onClose:()=>ae(false)}):O?jsx(xn,{roomCode:g,onPick:v=>{p(false),k(v);},onClose:()=>p(false)}):jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:Me?"Session":"Waiting for participants..."}),!Me&&jsx(Text,{dimColor:true,children:"No rounds started yet."}),jsx(Sn,{participants:e.participants,onlineIds:t,hostId:e.settings.hostParticipantId,votes:{},revealed:false,participantId:o}),e.agenda.length>0&&jsx(Sd,{items:e.agenda,nextPending:Ue(e)}),s!==null&&lt(s.status)&&jsx(md,{projection:e,round:s,rounds:r}),Dt.length>0&&jsxs(Box,{flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"\u2500\u2500 History \u2500\u2500"}),Dt.map(v=>jsx(Text,{dimColor:true,children:Is(v,r)},v.id))]}),oe==="picking"&&Ae.length>0&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{children:"Hand off to:"}),Ae.map((v,pe)=>jsxs(Text,{children:["[",pe+1,"] ",v.displayName]},v.id)),jsx(Text,{dimColor:true,children:"[q] Cancel"})]}),oe==="picking"&&Ae.length===0&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{dimColor:true,children:"No other online participants"}),jsx(Text,{dimColor:true,children:"[q] Cancel"})]}),oe==="confirming"&&Se&&jsx(Box,{flexDirection:"column",children:jsxs(Text,{children:["Hand off to ",e.participants.find(v=>v.id===Se)?.displayName,"? [y/n]"]})}),P&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Round title (optional, Enter to skip):"}),jsx(K,{value:C,onChange:L,onSubmit:I,onCancel:D,placeholder:"Enter to skip",isActive:P})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),R&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Ticket ID (optional, Enter to skip):"}),jsx(K,{value:N,onChange:J,onSubmit:G,onCancel:W,placeholder:"e.g. PROJ-1234",isActive:R})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),y&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Edit round title:"}),jsx(K,{value:V,onChange:T,onSubmit:B,onCancel:Y,placeholder:"Enter to save",isActive:y})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel \xB7 empty submit cancels"})]}),fe&&jsxs(Box,{children:[jsx(Text,{color:"red",children:"End session for everyone? This cannot be undone. "}),jsx(Text,{dimColor:true,children:"y/n [Esc] Cancel"})]}),ue&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Agenda title (optional, Enter to skip):"}),jsx(K,{value:at,onChange:Rn,onSubmit:Ge,onCancel:Ot,placeholder:"Enter to skip",isActive:ue})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),Ie&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Agenda ticket ID (optional, Enter to skip):"}),jsx(K,{value:Tn,onChange:ze,onSubmit:qe,onCancel:_e,placeholder:"e.g. PROJ-1234",isActive:Ie})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),oe==="idle"&&!P&&!R&&!y&&!fe&&!ue&&!Ie&&jsxs(Box,{gap:2,children:[n?jsx(Fragment,{children:s!==null&&lt(s.status)?jsxs(Fragment,{children:[s.status!=="skipped"&&jsx(Text,{color:"yellow",children:"[v] Revote"}),jsx(Text,{color:"yellow",children:"[n] Next"}),jsx(Text,{color:"yellow",children:"[t] Edit title"}),jsx(Text,{color:"yellow",children:"[h] Handoff"}),jsx(Text,{color:"yellow",children:"[e] Settings"}),jsx(Text,{color:"yellow",children:"[c] Share"}),w&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",A==="viewer"?"Vote":"Observe"]}),jsx(Text,{color:"yellow",children:"[m] Menu"})]}):jsxs(Fragment,{children:[jsx(Text,{color:"yellow",children:"[s] Start round"}),jsx(Text,{color:"yellow",children:"[a] Agenda"}),jsx(Text,{color:"yellow",children:"[h] Handoff"}),jsx(Text,{color:"yellow",children:"[e] Settings"}),jsx(Text,{color:"yellow",children:"[c] Share"}),w&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",A==="viewer"?"Vote":"Observe"]}),jsx(Text,{color:"yellow",children:"[m] Menu"})]})}):jsxs(Fragment,{children:[jsx(Text,{dimColor:true,children:"Waiting for host to start a round..."}),jsx(Text,{children:"[c] Share"}),w&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",A==="viewer"?"Vote":"Observe"]})]}),jsx(Text,{children:"[q] Quit"})]})]})}function md({projection:e,round:t,rounds:n}){let o=vs(t,n);if(t.status==="skipped")return jsx(Box,{flexDirection:"column",gap:1,children:jsx(Text,{bold:true,children:o})});let r=Zt(Qt(t)),s=new Map(e.participants.map(c=>[c.id,c.displayName])),a=tt(t),i=Object.entries(t.votes),d=i.filter(([,c])=>!ee(c)),u=i.filter(([,c])=>ee(c)).map(([c])=>c),l=d[0]?.[1];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:o}),jn(t)&&l!==void 0&&jsxs(Text,{bold:true,color:"green",children:["Consensus! Everyone voted ",l]}),jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:2,children:[jsx(Text,{bold:true,underline:true,children:"Name".padEnd(20)}),jsx(Text,{bold:true,underline:true,children:"Estimate".padEnd(10)})]}),d.map(([c,f])=>jsxs(Box,{gap:2,children:[jsx(Text,{children:(s.get(c)??c).padEnd(20)}),jsx(Text,{color:"cyan",bold:true,children:f.padEnd(10)})]},c)),u.map(c=>jsxs(Box,{gap:2,children:[jsx(Text,{dimColor:true,children:(s.get(c)??c).padEnd(20)}),jsx(Text,{dimColor:true,children:"(abstained)".padEnd(10)})]},c)),e.participants.filter(c=>!(c.id in t.votes)).map(c=>jsxs(Box,{gap:2,children:[jsx(Text,{dimColor:true,children:c.displayName.padEnd(20)}),jsx(Text,{dimColor:true,children:"(no vote)".padEnd(10)})]},c.id))]}),(r!==null||a!==null)&&jsxs(Box,{gap:2,children:[r?.kind==="numeric"&&jsxs(Text,{children:["Avg: ",jsx(Text,{bold:true,children:r.mean})]}),r?.kind==="numeric"&&jsxs(Text,{children:["Med: ",jsx(Text,{bold:true,children:r.median})]}),r?.kind==="categorical"&&r.mode!==null&&jsxs(Text,{children:["Most common: ",jsx(Text,{bold:true,children:r.mode})]}),r!==null&&jsxs(Text,{children:["Spread: ",jsx(Text,{bold:true,children:r.spread})]}),a!==null&&jsxs(Text,{dimColor:true,children:["\u23F1 ",a]})]})]})}var gd={pending:"\u2022",consumed:"\u2713",skipped:"~",cancelled:"\u2717"},hd={consumed:"green",skipped:"yellow",cancelled:"red"};function Sd({items:e,nextPending:t}){let n=e.filter(o=>o.state!=="cancelled");return jsxs(Box,{flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"\u2500\u2500 Agenda \u2500\u2500"}),n.map(o=>{let r=gd[o.state]??"?",s=hd[o.state],a=t!==null&&o.id===t.id,i=[o.ticketId?`[${o.ticketId}]`:"",o.title??""].filter(Boolean).join(" ").trim()||o.id;return jsxs(Box,{gap:1,children:[s!==void 0?jsx(Text,{color:s,children:r}):jsx(Text,{children:r}),s!==void 0?jsx(Text,{color:s,children:i}):jsx(Text,{children:i}),a&&jsx(Text,{color:"cyan",children:"(next)"})]},o.id)}),n.length===0&&jsx(Text,{dimColor:true,children:"No pending items."})]})}function Ts({scale:e,selected:t,onToggleCurrentVote:n,onClearCurrentVote:o,disabled:r}){let[s,a]=useState(0);return useInput((i,d)=>{r||(d.leftArrow?a(u=>Math.max(0,u-1)):d.rightArrow?a(u=>Math.min(e.cards.length-1,u+1)):d.return?n(e.cards[s]):(d.backspace||d.delete)&&o());}),jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Box,{gap:1,children:e.cards.map((i,d)=>{let u=d===s,l=i===t;return jsx(Text,{inverse:u,bold:l,...l&&{color:"cyan"},children:l?`[${i}]`:` ${i} `},i)})}),jsx(Text,{dimColor:true,children:" \u2190\u2192 navigate \u23CE select \u232B clear"})]})}function Es({projection:e,round:t,onlineIds:n,isHost:o,myId:r,myRole:s,elapsedMs:a,roomCode:i,shareOpen:d,settingsOpen:u,onToggleCurrentVote:l,onClearCurrentVote:c,onReveal:f,onSkip:k,onDiscard:O,onToggleRole:p,onShare:g,onSetShareOpen:E,onOpenSettings:A,confirmingQuit:b}){let P=t.votes[r],C=P!==void 0&&ee(P);if(useInput(N=>{if(N==="e"||N==="E"){A();return}if(N==="c"||N==="C"){E(true);return}if(s==="voter"&&(N==="a"||N==="A")){l($t);return}o&&(N==="r"||N==="R")&&f(),o&&(N==="s"||N==="S")&&k(),o&&(N==="d"||N==="D")&&O(),(N==="w"||N==="W")&&p();},{isActive:!b&&!u&&!d}),d)return jsx(xn,{roomCode:i,onPick:N=>{E(false),g(N);},onClose:()=>E(false)});let L=P,I=xt(t,e.rounds),D=t.title?` \u2014 ${t.title}`:"",R=t.ticketId?` [${t.ticketId}]`:"";return jsxs(Box,{flexDirection:"column",gap:1,children:[jsxs(Box,{gap:2,children:[jsxs(Text,{bold:true,children:["Round ",I,D,R]}),a!==void 0&&jsxs(Text,{dimColor:true,children:["\u23F1 ",zt(a)]})]}),jsxs(Box,{gap:4,children:[jsx(Sn,{participants:e.participants,onlineIds:n,hostId:e.settings.hostParticipantId,votes:t.votes,revealed:false}),s==="viewer"?jsx(Box,{flexDirection:"column",children:jsx(Text,{dimColor:true,children:"You're observing"})}):jsxs(Box,{flexDirection:"column",gap:1,children:[C&&jsx(Text,{dimColor:true,children:"(abstaining this round \u2014 press [a] to vote)"}),jsx(Ts,{scale:t.scale,selected:C?void 0:L,onToggleCurrentVote:l,onClearCurrentVote:c,disabled:b||C})]})]}),jsxs(Box,{gap:2,children:[o&&jsx(Text,{color:"yellow",children:"[r] Reveal"}),o&&jsx(Text,{color:"yellow",children:"[s] Skip"}),o&&jsx(Text,{color:"yellow",children:"[d] Discard"}),s==="voter"&&jsxs(Text,{color:"yellow",children:["[a] ",C?"Vote":"Abstain"]}),jsxs(Text,{color:"yellow",children:["[w] ",s==="viewer"?"Vote":"Observe"]}),jsx(Text,{children:"[e] Settings"}),jsx(Text,{children:"[c] Share"}),jsx(Text,{children:"[q] Quit"})]})]})}var Ad=3e3;function Et(e=Ad){let[t,n]=useState(null),o=useRef(null),r=useCallback(()=>{o.current!==null&&(clearTimeout(o.current),o.current=null);},[]),s=useCallback(i=>{r(),n(i),o.current=setTimeout(()=>{n(null),o.current=null;},e);},[r,e]),a=useCallback(()=>{r(),n(null);},[r]);return useEffect(()=>()=>{r();},[r]),{notice:t,show:s,dismiss:a}}var Ed={"not-host":"only the current host can hand off","not-found":"that participant is not in the session","not-online":"that participant is offline","self-target":"you cannot hand off to yourself"};function vn({session:e,participantId:t,displayName:n,accessMode:o,presetOverrides:r,customScales:s}){let{exit:a}=useApp(),[i,d]=useState(e.projection()),[u,l]=useState("connecting"),[c,f]=useState(e.onlineIds()),[k,O]=useState(),[p,g]=useState(false),[E,A]=useState(o==="password"?"password":"open"),[b,P]=useState(n),[C,L]=useState(false),[I,D]=useState(false),[R,N]=useState(""),[J,G]=useState(false),[W,y]=useState(""),[V,T]=useState(),[B,Y]=useState(false),[m,w]=useState(""),[_,X]=useState(null),[ue,at]=useState(false),[Rn,Ge]=useState(""),[Ot,Ie]=useState(false),[Tn,ze]=useState(""),[qe,_e]=useState(),[oe,re]=useState(),Se=Et(3e3),[be,dt]=useState(false),ae=Et(3e3),fe=Et(3e3),xe=Et(3e3);useEffect(()=>{let x=()=>{d(e.projection()),f(e.onlineIds());},H=e.onChange(x);x();let Re=e.onStatusChange(l),_t=e.onSessionEvent(Mt=>{Mt.kind==="host-changed"&&Se.show(Mt.message);}),gi=setInterval(()=>{let Mt=e.projection(),kn=me(Mt);kn?.timerStartedAt!==void 0&&Qe(kn.status)?O(Date.now()-kn.timerStartedAt):O(void 0);},1e3);return ()=>{H(),Re(),_t(),clearInterval(gi);}},[e,Se.show]),useInput(x=>{(x==="q"||x==="Q")&&L(true);},{isActive:!p&&!C&&!I&&!J&&!B&&!be&&!ue&&!Ot}),useInput((x,H)=>{x==="y"||x==="Y"?(e.teardown(),a()):(x==="n"||x==="N"||H.escape)&&L(false);},{isActive:C});let Ae=Kr(i),Xe=me(i),Me=i.settings.hostParticipantId===t,Dt=i.participants.find(x=>x.id===t),v=ge(Dt??{}),pe=useCallback(()=>{let x=un(Ue(i));N(x.title),re(x.agendaItemId),D(true);},[i]),Hs=useCallback(x=>{D(false),N(""),T(ao(x));let H=un(Ue(i));y(H.ticketId),G(true);},[i]),js=useCallback(()=>{D(false),N(""),T(void 0),re(void 0);},[]),Fs=useCallback(x=>{G(false),y("");let[H,Re,_t]=as(V,x,oe);e.commands.startRound({...H!==void 0&&{title:H},...Re!==void 0&&{ticketId:Re},..._t!==void 0&&{agendaItemId:_t}}),T(void 0),re(void 0);},[e,V,oe]),Vs=useCallback(()=>{G(false),y(""),T(void 0),re(void 0);},[]),Js=useCallback(()=>{let x=e.current();!x||x.status!=="revealed"||(X(x.id),w(x.title??""),Y(true));},[e]),Ys=useCallback(x=>{let H=_;if(Y(false),X(null),!H)return;let Re=x.trim();Re!==""&&e.updateRoundDescriptor(H,{title:Re});},[e,_]),Ws=useCallback(()=>{Y(false),X(null);},[]),Ks=useCallback(x=>{e.commands.toggleCurrentVote(x);},[e]),Gs=useCallback(()=>{e.commands.clearCurrentVote();},[e]),zs=useCallback(()=>{e.commands.revealCurrentRound();},[e]),qs=useCallback(()=>{e.commands.skipCurrentRound();},[e]),Xs=useCallback(()=>{e.commands.discardCurrentRound();},[e]),Qs=useCallback(()=>{let x=un(Ue(i));N(x.title),re(x.agendaItemId),D(true);},[i]),Zs=useCallback(()=>{let x=e.current();x&&e.commands.startRound({parentRoundId:x.id,...x.title!==void 0&&{title:x.title},...x.description!==void 0&&{description:x.description},...x.ticketId!==void 0&&{ticketId:x.ticketId},...x.agendaItemId!==void 0&&{agendaItemId:x.agendaItemId}});},[e]),bo=useCallback(()=>{e.commands.toggleRole();},[e]),ei=useCallback(x=>{e.updateName(x);},[e]),ti=useCallback(x=>{e.updateScale(x);},[e]),ni=useCallback(x=>{e.commands.rename(x),P(x);},[e]),oi=useCallback(async(x,H)=>{await e.updateAccess(x,H),A(x);},[e]),ri=useCallback(x=>{let H=e.commands.handoffHost(x);H.applied||console.error(`Handoff failed: ${Ed[H.reason]}`);},[e]),Ao=useCallback(()=>{g(true);},[]),si=useCallback(()=>{g(false);},[]),ii=useCallback(()=>{e.commands.endSession();},[e]),Ro=useCallback(async x=>{let H=x==="code"?dn(e.roomCode):x==="url"?cn(e.roomCode):ln(e.roomCode);try{await Ps.write(H),ae.show("Copied!");}catch{ae.show(`Copy failed \u2014 ${H}`);}},[e.roomCode,ae]),En=i.rounds.filter(x=>Ut(x.status)),ai=En.length>0?En.at(-1):null,di=En.length>0,ci=useCallback(()=>ys(i,x=>Ps.write(x),fe.show),[i,fe.show]),li=useCallback(()=>{Ge(""),at(true);},[]),ui=useCallback(x=>{at(false),Ge("");let H=x.trim()===""?void 0:x.trim();_e(H),ze(""),Ie(true);},[]),fi=useCallback(()=>{at(false),Ge(""),_e(void 0);},[]),pi=useCallback(x=>{Ie(false),ze("");let H=x.trim()===""?void 0:x.trim();if(!qe&&!H){_e(void 0);return}if(!e.commands.addItem({...qe!==void 0&&{title:qe},...H!==void 0&&{ticketId:H}}).applied){xe.show("Add failed \u2014 an agenda item needs a title or a ticket id");return}_e(void 0);},[e,qe,xe]),mi=useCallback(()=>{Ie(false),ze(""),_e(void 0);},[]);return jsxs(Box,{flexDirection:"column",children:[jsx(ls,{roomCode:e.roomCode,sessionName:i.settings.name,status:u,isHost:Me}),Se.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:"yellow",children:Se.notice})}),ae.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:ae.notice.startsWith("Copy failed")?"red":"green",children:ae.notice})}),fe.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:fe.notice.startsWith("Clipboard write failed")?"red":"green",children:fe.notice})}),xe.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:"red",children:xe.notice})}),p?jsx(xs,{sessionName:i.settings.name,displayName:b,currentScale:i.settings.defaultScale,accessMode:E,presetOverrides:r,customScales:s,isHost:Me,onChangeName:ei,onChangeScale:ti,onChangeDisplayName:ni,onChangeAccess:oi,onClose:si}):Ae==="lobby"?jsx(bs,{projection:i,onlineIds:c,isHost:Me,participantId:t,rounds:i.rounds,currentRound:ai,settingsOpen:p,onStartRound:pe,onNewRound:Qs,roundTitlePromptActive:I,roundTitleInput:R,onRoundTitleChange:N,onRoundTitleSubmit:Hs,onRoundTitleCancel:js,roundTicketIdPromptActive:J,roundTicketIdInput:W,onRoundTicketIdChange:y,onRoundTicketIdSubmit:Fs,onRoundTicketIdCancel:Vs,onRevote:Zs,onOpenSettings:Ao,onHandoffHost:ri,onEndSession:ii,onShare:Ro,shareOpen:be,onSetShareOpen:dt,roomCode:e.roomCode,confirmingQuit:C,myRole:v,onToggleRole:bo,descriptorPromptActive:B,descriptorInput:m,onDescriptorChange:w,onDescriptorSubmit:Ys,onDescriptorCancel:Ws,onEditDescriptor:Js,canExport:di,onExportResults:ci,onAgendaAdd:li,agendaAddPromptActive:ue,agendaAddTitleInput:Rn,onAgendaAddTitleChange:Ge,onAgendaAddTitleSubmit:ui,onAgendaAddTitleCancel:fi,agendaAddTicketIdPromptActive:Ot,agendaAddTicketIdInput:Tn,onAgendaAddTicketIdChange:ze,onAgendaAddTicketIdSubmit:pi,onAgendaAddTicketIdCancel:mi}):Ae==="estimating"&&Xe?jsx(Es,{projection:i,round:Xe,onlineIds:c,isHost:Me,myId:t,myRole:v,elapsedMs:k,onToggleCurrentVote:Ks,onClearCurrentVote:Gs,onReveal:zs,onSkip:qs,onDiscard:Xs,onToggleRole:bo,onShare:Ro,onSetShareOpen:dt,shareOpen:be,settingsOpen:p,onOpenSettings:Ao,roomCode:e.roomCode,confirmingQuit:C}):null,C&&jsx(Box,{children:jsx(Text,{dimColor:true,children:"Leave session? y/n"})})]})}function Ns({presetOverrides:e,customScales:t}){let{exit:n}=useApp(),[o,r]=useState("main-menu"),[s,a]=useState(je()),[i,d]=useState(s.displayName??""),[u,l]=useState(s.relayUrl??""),[c,f]=useState(s.defaultSessionName??""),[k,O]=useState(s.avatarColor?.startsWith("#")?s.avatarColor:""),[p,g]=useState(t??[]),[E,A]=useState(e??{});useInput(m=>{(m==="q"||m==="Q")&&n();},{isActive:o==="main-menu"});let b=useMemo(()=>tn(E,p),[E,p]),P=s.defaultScale,C=P?b.find(m=>m.id===P):void 0,L=[{label:"Display name",value:"display-name",detail:`[${s.displayName??"(none)"}]`},{label:"Relay URL",value:"relay-url",detail:`[${s.relayUrl??"(none)"}]`},{label:"Default scale",value:"default-scale",detail:`[${C?He(C.id,p):"(none)"}]`},{label:"Default session name",value:"default-session-name",detail:`[${s.defaultSessionName??"(none)"}]`},{label:"Default password",value:"default-password",detail:`[${s.defaultPassword?"on":"off"}]`},{label:"Avatar color",value:"avatar-color",detail:`[${_d(s.avatarColor)}]`}];function I(m){m==="display-name"?(d(s.displayName??""),r("editing-display-name")):m==="relay-url"?(l(s.relayUrl??""),r("editing-relay-url")):m==="default-scale"?r("picking-scale"):m==="default-session-name"?(f(s.defaultSessionName??""),r("editing-session-name")):m==="default-password"?r("picking-default-password"):m==="avatar-color"&&r("picking-avatar-color");}function D(m){if(m==="custom-hex"){O(s.avatarColor?.startsWith("#")?s.avatarColor:""),r("editing-avatar-hex");return}if(Be(m)===null){r("main-menu");return}a({...s,avatarColor:m}),z({avatarColor:m}),r("main-menu");}function R(m){let w=m.trim();if(w.length===0){r("picking-avatar-color");return}let _=w.startsWith("#")?w.toLowerCase():`#${w.toLowerCase()}`;Be(_)!==null&&(a({...s,avatarColor:_}),z({avatarColor:_}),r("main-menu"));}function N(m){let w=m.trim();if(w.length>0){let _={...s,displayName:w};a(_),z({displayName:w});}r("main-menu");}function J(m){let w=m.trim();if(w.length>0){let _={...s,relayUrl:w};a(_),z({relayUrl:w});}r("main-menu");}function G(m){let w=m.trim(),_=w.length>0?{...s,defaultSessionName:w}:{...s};w.length===0?(delete _.defaultSessionName,a(_),Ct({defaultSessionName:""})):(a(_),z({defaultSessionName:w})),r("main-menu");}function W(m){let w=m.length>0?{...s,defaultScale:m}:{...s};m.length===0?(delete w.defaultScale,a(w),Ct({defaultScale:""})):(a(w),z({defaultScale:m})),r("main-menu");}function y(m,w){let _={...E};w.length===0?delete _[m]:_[m]=w,A(_),z({presetOverrides:Object.keys(_).length>0?_:void 0});}function V(m){let w=m==="on",_={...s,defaultPassword:w};a(_),z({defaultPassword:w}),r("main-menu");}function T(m,w){let _=`custom-${randomUUID()}`,X=[...p,{id:_,label:m,cards:w}];g(X),a({...s,customScales:X}),z({customScales:X});}function B(m,w,_){let X=p.map(ue=>ue.id===m?{id:m,label:w,cards:_}:ue);g(X),a({...s,customScales:X}),z({customScales:X});}function Y(m){let w=p.filter(X=>X.id!==m);g(w);let _={...s,customScales:w};s.defaultScale===m?(_.defaultScale="fibonacci",z({customScales:w,defaultScale:"fibonacci"})):z({customScales:w}),a(_);}if(o==="main-menu")return jsx(he,{title:"\u2500\u2500 Config Settings \u2500\u2500",items:L,onSelect:I,onClose:()=>n()});if(o==="editing-display-name")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Display name: "}),jsx(K,{value:i,onChange:d,onSubmit:N,onCancel:()=>r("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="editing-relay-url")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Relay URL: "}),jsx(K,{value:u,onChange:l,onSubmit:J,onCancel:()=>r("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="editing-session-name")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Default session name: "}),jsx(K,{value:c,onChange:f,onSubmit:G,onCancel:()=>r("main-menu"),placeholder:"(leave empty to clear)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="picking-scale"){let m=[{id:"",cards:[]},...b];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(mn,{scales:m,selectedScaleId:P??"",presetOverrides:E,customScales:p,onSelect:W,onOverrideChange:y,onCustomScaleCreate:T,onCustomScaleEdit:B,onCustomScaleDelete:Y,onClose:()=>r("main-menu"),showNoneOption:true})]})}if(o==="picking-avatar-color"){let m=gt.map(w=>({label:et[w].label,value:w,detail:s.avatarColor===w?"[current]":et[w].base}));return m.push({label:"Custom hex\u2026",value:"custom-hex",detail:s.avatarColor?.startsWith("#")?`[${s.avatarColor}]`:void 0}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(he,{title:"Avatar color:",items:m,onSelect:D,onClose:()=>r("main-menu")})]})}if(o==="editing-avatar-hex")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Custom hex color: "}),jsx(K,{value:k,onChange:O,onSubmit:R,onCancel:()=>r("picking-avatar-color"),placeholder:"#rrggbb",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="picking-default-password"){let m=[{label:"On",value:"on",detail:s.defaultPassword?"[current]":void 0},{label:"Off",value:"off",detail:s.defaultPassword?void 0:"[current]"}];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(he,{title:"Default password:",items:m,onSelect:V,onClose:()=>r("main-menu")})]})}return jsx(Box,{})}function _d(e){return e?e.startsWith("#")?e:gt.includes(e)?et[e].label:e:"(auto)"}var Md=2e3,$d={pending:"\u2022",consumed:"\u2713",skipped:"~",cancelled:"\u2717"};function Ld(e){let t=$d[e.state]??"?",n=[];e.ticketId&&n.push(`[${e.ticketId}]`),e.title&&n.push(e.title);let o=n.join(" ")||e.id;return `${t} ${o}`}function In(e){switch(e){case "not-found":return "no agenda item with that id";case "not-pending":return "the item is no longer pending \u2014 a peer may have skipped, cancelled or estimated it";case "invalid-fields":return "an agenda item needs at least one of --title or --ticket"}}async function Pt(e){let t=yt(e),n;return await Promise.race([t.whenJoined(),new Promise(o=>{n=setTimeout(o,Md);})]),clearTimeout(n),t}async function Nt(){let e=rn();e.length===0&&(console.error("No active session. Join a room first with: hnch join <code>"),process.exit(1));let t=e[0];return {roomCode:t.roomCode,roomUuid:t.roomUuid,...t.passwordHash!==void 0&&{passwordHash:t.passwordHash}}}async function Os(e){!e.title?.trim()&&!e.ticket?.trim()&&(console.error("At least one of --title or --ticket is required"),process.exit(1));let t=await le(),n=await Nt();try{await ce(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let o=await Pt({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{let r=o.commands.addItem({...e.title?.trim()?{title:e.title.trim()}:{},...e.ticket?.trim()?{ticketId:e.ticket.trim()}:{},...e.description?.trim()?{description:e.description.trim()}:{}});r.applied||(console.error(`Add failed: ${In(r.reason)}`),process.exit(1)),await new Promise(s=>{setTimeout(s,300);}),console.log(`Added agenda item: ${r.id}`);}finally{o.teardown();}}async function Ds(){let e=await le(),t=await Nt();try{await ce(e.relayUrl,t.roomCode);}catch{console.error(`Room ${t.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let n=await Pt({relayUrl:e.relayUrl,participantId:e.participantId,displayName:e.displayName,roomCode:t.roomCode,roomUuid:t.roomUuid,...t.passwordHash!==void 0&&{passwordHash:t.passwordHash}});try{let r=n.projection().agenda;if(r.length===0){console.log("No agenda items.");return}r.forEach((s,a)=>{console.log(`${String(a+1).padStart(2)}. ${Ld(s)}`);});}finally{n.teardown();}}async function _s(e){let t=await le(),n=await Nt();try{await ce(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let o=await Pt({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{let r=o.commands.skipItem(e.id);r.applied||(console.error(`Skip failed: ${In(r.reason)}`),process.exit(1)),await new Promise(s=>{setTimeout(s,300);}),console.log(`Skipped agenda item: ${e.id}`);}finally{o.teardown();}}async function Ms(e){let t=await le(),n=await Nt();try{await ce(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let o=await Pt({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{let r=o.commands.cancelItem(e.id);r.applied||(console.error(`Cancel failed: ${In(r.reason)}`),process.exit(1)),await new Promise(s=>{setTimeout(s,300);}),console.log(`Cancelled agenda item: ${e.id}`);}finally{o.teardown();}}async function $s(e){let t=await le(),n=await Nt();try{await ce(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let o=await Pt({relayUrl:t.relayUrl,participantId:t.participantId,displayName:t.displayName,roomCode:n.roomCode,roomUuid:n.roomUuid,...n.passwordHash!==void 0&&{passwordHash:n.passwordHash}});try{let r=o.commands.moveItem(e.id,e.before,e.after);r.applied||(console.error(`Move failed: ${In(r.reason)}`),process.exit(1)),await new Promise(s=>{setTimeout(s,300);}),console.log(`Reordered agenda item: ${e.id}`);}finally{o.teardown();}}async function yo(){let e=await ss(),t=nn(e);return t.ok||(console.error(t.message),process.exit(1)),t.password}function vo(e,t,n){let o=is(e,{roomCode:t.roomCode,...n});o.remembered==="forget-password"&&so(t.roomUuid),o.remembered==="forget-session"&&vt(t.roomUuid),console.error(o.message),t.teardown(),process.exit(o.exitCode);}function it(e){try{vt(e);}catch(t){console.error(`Failed to clear cached session: ${t instanceof Error?t.message:String(t)}`);}}function Io(e){io({clearLastSession:()=>{e!==void 0&&vt(e);},logger:console,exit:process.exit});}async function Hd(e){let t=await le(),n=e.scale??t.defaultScale??"fibonacci",o=e.name??t.defaultSessionName,r=e.password??t.defaultPassword??false,s;r&&(s=await yo());let a=en(n,t.presetOverrides,t.customScales);if(!a){let f=Object.keys(de).join(", ");console.error(`Unknown or fully-disabled scale: "${n}". Builtin IDs: ${f}`),process.exit(1);}let i=an(),d,u=await Xr({participantId:t.participantId,displayName:t.displayName,relayUrl:t.relayUrl,sessionName:o,password:s,defaultScale:a,...t.avatarColor!==void 0&&{avatarColor:t.avatarColor},onRejection(f){f==="unknown-room"?Io(d):i.note(f);}});d=u.roomUuid,sn({roomCode:u.roomCode,roomUuid:u.roomUuid,lastSeenAt:Date.now(),...u.passwordHash!==void 0&&{passwordHash:u.passwordHash}}),console.error(`Room created: ${u.roomCode}`),console.error(`Share: hnch join ${u.roomCode}`),console.error("");let l=render(wn.createElement(vn,{session:u,participantId:t.participantId,displayName:t.displayName,accessMode:s?"password":"open",presetOverrides:t.presetOverrides,customScales:t.customScales}));i.attach(l.unmount),u.onSessionEvent(f=>{f.kind!=="host-changed"&&(console.error(f.message),l.unmount(),it(u.roomUuid),u.teardown(),process.exit(0));}),await l.waitUntilExit();let c=i.refused();c!==null&&vo(c,u,{wasIn:true,typedPassword:s!==void 0}),u.teardown(),it(u.roomUuid),process.exit(0);}async function jd(e){let t=await le(),n=es(e.code);n===null&&(console.error("invalid room code"),process.exit(1));let o;e.password&&(o=await yo());let r=await ce(t.relayUrl,n),s;r.accessMode==="password"&&!e.password?s=await yo():e.password&&(s=o);let a=an(),i=await Qr({participantId:t.participantId,displayName:t.displayName,relayUrl:t.relayUrl,roomCode:n,password:s,...t.avatarColor!==void 0&&{avatarColor:t.avatarColor},onRejection(l){l==="unknown-room"?Io(r.uuid):a.note(l);}});sn({roomCode:i.roomCode,roomUuid:i.roomUuid,lastSeenAt:Date.now(),...i.passwordHash!==void 0&&{passwordHash:i.passwordHash}}),console.error(`Joined room: ${i.roomCode}`),console.error("");let d=render(wn.createElement(vn,{session:i,participantId:t.participantId,displayName:t.displayName,accessMode:r.accessMode,presetOverrides:t.presetOverrides,customScales:t.customScales}));a.attach(d.unmount),i.onSessionEvent(l=>{l.kind!=="host-changed"&&(console.error(l.message),d.unmount(),it(i.roomUuid),i.teardown(),process.exit(0));}),await d.waitUntilExit();let u=a.refused();u!==null&&vo(u,i,{wasIn:i.hasJoined(),typedPassword:s!==void 0}),i.teardown(),it(i.roomUuid),process.exit(0);}function Fd(e,t=Date.now()){let n=t-e,o=Math.floor(n/6e4);return o<60?`${o}m ago`:`${Math.floor(o/60)}h ago`}async function Vd(e){return new Promise((t,n)=>{let o=createInterface({input:process.stdin,output:process.stderr}),r=()=>{process.stderr.write(`Select [1-${e}]: `),o.question("",s=>{let a=parseInt(s.trim(),10);Number.isInteger(a)&&a>=1&&a<=e?(o.close(),t(a)):(process.stderr.write(`Invalid choice \u2014 enter a number between 1 and ${e}.
26
- `),r());});};o.on("close",()=>n(new Error("stdin closed"))),r();})}async function Ls(e,t){let n;try{n=await ce(e.relayUrl,t.roomCode);}catch(i){if(i instanceof ht&&i.reason==="unknown-room")return await io({clearLastSession:()=>vt(t.roomUuid),logger:console,exit:process.exit});console.error("Could not reach relay \u2014 try again later."),process.exit(0);}n.accessMode==="password"&&!t.passwordHash&&(console.error(`Password changed \u2014 rejoin with: hnch join ${t.roomCode} --password`),so(t.roomUuid),process.exit(0)),console.error(`Rejoining room ${t.roomCode}\u2026`),console.error("");let o=an(),r=yt({participantId:e.participantId,displayName:e.displayName,relayUrl:e.relayUrl,roomCode:t.roomCode,roomUuid:t.roomUuid,passwordHash:t.passwordHash,...e.avatarColor!==void 0&&{avatarColor:e.avatarColor},onRejection(i){i==="unknown-room"?Io(t.roomUuid):o.note(i);}});sn({roomCode:r.roomCode,roomUuid:r.roomUuid,lastSeenAt:Date.now(),...t.passwordHash!==void 0&&{passwordHash:t.passwordHash}});let s=render(wn.createElement(vn,{session:r,participantId:e.participantId,displayName:e.displayName,accessMode:n.accessMode,presetOverrides:e.presetOverrides,customScales:e.customScales}));o.attach(s.unmount),r.onSessionEvent(i=>{i.kind!=="host-changed"&&(console.error(i.message),s.unmount(),it(t.roomUuid),r.teardown(),process.exit(0));}),await s.waitUntilExit();let a=o.refused();a!==null&&vo(a,r,{wasIn:true,typedPassword:false}),r.teardown(),it(t.roomUuid),process.exit(0);}async function Jd(){let e=await le(),t=rn();if(t.length===0&&(console.error("No recent session to resume."),process.exit(0)),t.length===1)return Ls(e,t[0]);let n=Date.now();process.stderr.write(`Recent rooms:
27
- `);for(let[r,s]of t.entries()){let a=Fd(s.lastSeenAt,n);process.stderr.write(` ${r+1}. ${s.roomCode} (${a})
18
+ `}function nn(e,t,n){if(e.startsWith("custom-")){let r=(n??[]).find(i=>i.id===e);return r?{id:r.id,cards:r.cards}:void 0}let o=de[e];if(o){let r=(t??{})[e]??[];if(r.length===0)return o;let i=o.cards.filter((s,a)=>!r.includes(a));return i.length===0?void 0:{id:e,cards:i}}}function on(e,t){let n=Object.keys(de).map(r=>nn(r,e,t)).filter(r=>r!==void 0),o=(t??[]).map(r=>({id:r.id,cards:r.cards}));return [...n,...o]}function Fe(e,t){if(e.startsWith("custom-")){let n=(t??[]).find(o=>o.id===e);if(n&&n.label.trim().length>0)return n.label}return dr(e)}function oi(e){return tt(e)===null?"lobby":"estimating"}var Wa="https://hnch.dev",ri=/^[0-9a-f]{64}$/;function yt(){let t=process.env.XDG_CONFIG_HOME||join(homedir(),".config");return join(t,"hnch")}function si(){return join(yt(),"config.json")}function ai(){let e=yt();existsSync(e)||mkdirSync(e,{recursive:true,mode:448});}function di(e){let t=si();writeFileSync(t,JSON.stringify(e,null,2)+`
19
+ `,{encoding:"utf-8",mode:384}),chmodSync(t,384);}function Ve(){let e=si();if(!existsSync(e))return {};try{return JSON.parse(readFileSync(e,"utf-8"))}catch{return {}}}function z(e){ai();let n={...Ve(),...e};di(n);}async function Ya(e){let t=createInterface({input:process.stdin,output:process.stderr});return new Promise(n=>{t.question(e,o=>{t.close(),n(o.trim());});})}function Ga(e){return e.startsWith("wss://")?"https://"+e.slice(6):e.startsWith("ws://")?"http://"+e.slice(5):e}async function le(){let e=Ve(),t=false;e.participantId||(e.participantId=randomUUID(),t=true);let n=e.deviceKey?.toLowerCase();if(n!==e.deviceKey&&n!==void 0&&ri.test(n)&&(e.deviceKey=n,t=true),(!e.deviceKey||!ri.test(e.deviceKey))&&(e.deviceKey=randomBytes(32).toString("hex"),t=true),!e.displayName){let r=await Ya("Enter your display name: ");e.displayName=r||`user-${e.participantId.slice(0,6)}`,t=true;}e.relayUrl||(e.relayUrl=Wa,t=true),(!e.avatarColor||Ue(e.avatarColor)===null)&&(e.avatarColor=lr(e.participantId),t=true),t&&z(e);let o=process.env.HNCH_RELAY_URL||e.relayUrl;return o=Ga(o),{participantId:e.participantId,deviceKey:e.deviceKey,displayName:e.displayName,relayUrl:o,defaultScale:e.defaultScale,defaultSessionName:e.defaultSessionName,defaultPassword:e.defaultPassword,presetOverrides:e.presetOverrides,customScales:e.customScales,avatarColor:e.avatarColor}}function he(e){return {relayUrl:e.relayUrl,participantId:e.participantId,deviceKey:e.deviceKey,displayName:e.displayName}}function rn(e){return e.avatarColor!==void 0?{avatarColor:e.avatarColor}:{}}function wt(e){ai();let n={...Ve()};for(let[o,r]of Object.entries(e))r===""?delete n[o]:r!==void 0&&(n[o]=r);di(n);}function sn(e){let t=Pe(e);return t===""?{ok:false,message:"Password cannot be empty."}:e.trim().length>so?{ok:false,message:`Password is too long (at most ${so} characters).`}:{ok:true,password:t}}var an={unauthenticated:"the relay did not accept this device as the host","unknown-room":"the relay no longer knows this room",unreachable:"the relay could not be reached"};function mo(e){return e.charAt(0).toUpperCase()+e.slice(1)}var ci={"not-host":"Only the host can change the password","bad-target":"The relay refused the change",unauthenticated:mo(an.unauthenticated),"unknown-room":mo(an["unknown-room"]),unreachable:mo(an.unreachable)},li={"not-found":"that participant is not in the session","not-online":"that participant is offline","self-target":"you cannot hand off to yourself","not-host":"only the current host can hand off","bad-target":"the relay cannot hand host to that participant",...an};async function fi(e){let t=await xr(e.relayUrl,{creator:{participantId:e.participantId,deviceKey:e.deviceKey}}),n={participantId:e.participantId,pk:await no(e.deviceKey,t.uuid)},o;if(e.password!==void 0&&Pe(e.password)!==""){o=await Zt(e.password,t.uuid);try{await mi(e.relayUrl,t.uuid,o,n);}catch(r){let i=r.message;throw new Error(`Room ${t.code} was created, but its password was not set: ${i}. The room is open to anyone with the code and was not joined. Run \`hnch create --password\` again.`,{cause:r})}}return gi({...e,roomCode:t.code,roomUuid:t.uuid,passwordHash:o},n.pk,{kind:"create",defaultScale:e.defaultScale??Yt,sessionName:e.sessionName})}async function pi(e){let t=await ce(e.relayUrl,e.roomCode),n;if(t.accessMode==="password"){if(e.password===void 0||Pe(e.password)==="")throw new Error("Room requires a password");n=await Zt(e.password,t.uuid);}return Ct({...e,roomUuid:t.uuid,passwordHash:n})}async function Ct(e){let t=await no(e.deviceKey,e.roomUuid);return gi(e,t,{kind:"join"})}async function mi(e,t,n,o){try{await vr(e,t,n,o);}catch(r){throw new Error(ci[qt(r)],{cause:r})}}var ui=new WeakMap;function qa(e){let t=ui.get(e);if(t===void 0){let{handoffHost:n,...o}=e;t=o,ui.set(e,t);}return t}function gi(e,t,n){let{relayUrl:o,roomUuid:r}=e,i=new Set,s=new Set,a=new Set,d=false,l=()=>{},u=new Promise(p=>{l=p;}),c,f=new Set,N=()=>{for(let p of i)p();},P=Gr({httpBaseUrl:o,room:{uuid:r,code:e.roomCode},credentials:{deviceId:e.participantId,participantKey:t,...e.passwordHash!==void 0&&{passwordHash:e.passwordHash}},self:{participantId:e.participantId,displayName:e.displayName,...e.avatarColor!==void 0&&{avatarColor:e.avatarColor}},seed:n,WebSocketPolyfill:za,onProjectionChange(p){c=p,N();},onOnlineIdsChange(p){f=p,N();},onStatusChange(p){for(let A of s)A(p);},onRejectionChange(p){p!==null&&(console.error(`Connection rejected: ${p}`),e.onRejection?.(p));},onRepeatRejection(){console.error("Trouble reaching the room \u2014 retrying.");},onFirstSync(){d=true,l();},onSessionEvent(p){for(let A of a)A(p);}});function g(){if(c===void 0)throw new Error("session: no projection reported");return c}return {roomCode:e.roomCode,roomUuid:r,passwordHash:e.passwordHash,get commands(){return qa(P.commands)},projection:g,current(){return me(g())},isHost(){return g().settings.hostParticipantId===e.participantId},hasJoined(){return d},whenJoined(){return u},onlineIds(){return f},updateRoundDescriptor(p,A){P.updateRoundDescriptor(p,A);},updateName(p){P.updateSettings({name:p});},updateScale(p){P.updateSettings({defaultScale:p});},async updateAccess(p,A){let E=null;if(p==="password"){let C=sn(A??"");if(!C.ok)throw new Error(C.message);E=await Zt(C.password,r);}await mi(o,r,E,{participantId:e.participantId,pk:t}),P.updateCredentials(E);},handoffHost(p){return P.handoffHost(p)},onChange(p){return i.add(p),()=>i.delete(p)},onStatusChange(p){return s.add(p),()=>s.delete(p)},onSessionEvent(p){return a.add(p),()=>{a.delete(p);}},flushUpdates(p){return P.flushUpdates(p)},teardown(){P.teardown();}}}function hi(e){let t=ao(e);return t===""?null:t}function Ke(){return join(yt(),"last-session.json")}function td(e,t){let n=yt();mkdirSync(n,{recursive:true,mode:448}),chmodSync(n,448),writeFileSync(e,t,{encoding:"utf-8",mode:384}),chmodSync(e,384);}function wi(){let e=Ke();try{unlinkSync(e);}catch(t){if(t.code!=="ENOENT")throw t}}function go(){let e=Ke();if(!existsSync(e))return {};try{let t=JSON.parse(readFileSync(e,"utf-8"));return {...to(t).entries}}catch{return {}}}function ho(e){let t={version:2,entries:e};td(Ke(),JSON.stringify(t,null,2)+`
20
+ `);}function cn(e){let t=Date.now();if(!existsSync(Ke()))return [];let n;try{n=JSON.parse(readFileSync(Ke(),"utf-8"));}catch{return []}let o=to(n),r=mr(o,t),i=Object.values(r.entries);return i.length===0?(wi(),[]):i.toSorted((s,a)=>a.lastSeenAt-s.lastSeenAt)}function nd(e,t){return e!==void 0?{passwordHash:e}:t!==void 0?{passwordHash:t}:{}}function ln(e){let t=Date.now(),n=go(),o=n[e.roomUuid];n[e.roomUuid]={roomCode:e.roomCode,roomUuid:e.roomUuid,lastSeenAt:e.lastSeenAt??t,...nd(e.passwordHash,o?.passwordHash)};let r=Object.keys(n);if(r.length>5){let i=r.toSorted((s,a)=>(n[s]?.lastSeenAt??0)-(n[a]?.lastSeenAt??0)).slice(0,r.length-5);for(let s of i)delete n[s];}ho(n);}function un(e){if(!existsSync(Ke()))return;let t=go();if(delete t[e],Object.keys(t).length===0){wi();return}ho(t);}function fn(e){if(!existsSync(Ke()))return;let t=go(),n=t[e];if(!n)return;let{passwordHash:o,...r}=n;t[e]=r,ho(t);}async function pn(e){let t=true;try{await e.clearLastSession();}catch(n){t=false,e.logger.error(`Failed to clear cached session: ${n instanceof Error?n.message:String(n)}`);}return t?e.logger.error("Session expired (room no longer exists). Cached session cleared."):e.logger.error("Session expired. Could not delete ~/.config/hnch/last-session.json \u2014 please remove it manually."),e.exit(1)}function rd(e){return e.isTTY===true&&typeof e.setRawMode=="function"}var id="\r",sd=`
21
+ `,ad="\x7F",dd="\b",cd=" ",ld="",ud="",fd="",pd="",md="\x1B";function gd(e){return e<" "&&e!==cd}function hd(e,t){let n=e[t+1];if(n===void 0)return 1;if(n==="O")return Math.min(3,e.length-t);if(n!=="[")return 2;for(let o=t+2;o<e.length;o++){let r=e[o];if(r>="@"&&r<="~")return o-t+1}return e.length-t}async function Ci(e={}){let t=e.stdin??process.stdin,n=e.stderr??process.stderr,o=e.exit??process.exit;n.write("Password: ");let r=rd(t)?await xd(t,n,o):await Sd(t);return Pe(r)}function Sd(e){return new Promise(t=>{let n=createInterface({input:e}),o=false,r=i=>{o||(o=true,n.close(),t(i));};n.once("line",r),n.once("close",()=>r(""));})}function xd(e,t,n){return new Promise(o=>{let r="",i=false;e.setRawMode(true),e.resume(),e.setEncoding("utf8");let s=()=>{i=true,e.setRawMode(false),e.pause(),e.removeListener("data",a);},a=d=>{let l=Array.from(d);for(let u=0;u<l.length&&!i;u++){let c=l[u];if(c===ld&&(s(),t.write(`
22
+ `),n(130)),c===id||c===sd){s(),t.write(`
23
+ `),o(r);return}if(c===ud){if(r.length===0){s(),t.write(`
24
+ `),o(r);return}continue}if(c===md){u+=hd(l,u)-1;continue}if(c===ad||c===dd){r=Array.from(r).slice(0,-1).join("");continue}if(c===fd){r="";continue}if(c===pd){r=r.replace(/\S*\s*$/u,"");continue}gd(c)||(r+=c);}};e.on("data",a);})}function mn(){let e=null,t;return {refused:()=>e,note(n){e=n,t?.();},attach(n){t=n,e!==null&&n();}}}function vi(e,t){switch(e){case "wrong-password":return !t.wasIn&&t.typedPassword?{message:"That password is incorrect.",exitCode:1,remembered:"forget-session"}:{message:`Password changed \u2014 rejoin with: hnch join ${t.roomCode} --password`,exitCode:0,remembered:"forget-password"};case "room-full":return {message:`This room is full (max ${nr} participants).`,exitCode:1,remembered:t.wasIn?"keep":"forget-session"};default:return {message:`The relay refused the connection (${e}).`,exitCode:1,remembered:t.wasIn?"keep":"forget-session"}}}function gn(e){let t=e.print??(d=>console.error(d)),n=e.exitProcess??(d=>process.exit(d)),o=e.cache??{removeEntry:un,clearPasswordHash:fn},r,i,s=false;function a(d,l){if(!(l===void 0||d==="keep"))try{d==="forget-password"?o.clearPasswordHash(l.roomUuid):o.removeEntry(l.roomUuid);}catch(u){t(`Failed to clear cached session: ${u instanceof Error?u.message:String(u)}`);}}return {bind(d){r=d;},attach(d){i=d;},async exit(d){if(s)return new Promise(()=>{});s=true;let l=r??e.room,u=d.kind==="refused"&&d.reason!=="unknown-room"?vi(d.reason,{roomCode:l?.roomCode??"",wasIn:e.wasIn(),typedPassword:e.typedPassword}):null;return i?.unmount(),r?.teardown(),d.kind==="refused"?u===null?pn({clearLastSession:()=>{l!==void 0&&o.removeEntry(l.roomUuid);},logger:{error:t},exit:n}):(a(u.remembered,l),t(u.message),n(u.exitCode)):(a("forget-session",l),(d.kind==="ended"||d.kind==="removed")&&t(d.message),n(0))}}}function hn(e,t){return n=>{n==="unknown-room"?t.exit({kind:"refused",reason:n}):e.note(n);}}async function Sn(e,t,n,o){o.attach(t),n.attach(()=>t.unmount()),e.onSessionEvent(i=>{i.kind!=="host-changed"&&o.exit({kind:i.kind,message:i.message});}),await t.waitUntilExit();let r=n.refused();return o.exit(r===null?{kind:"left"}:{kind:"refused",reason:r})}var yd="@xauyxau/hnch";function xn(e){return Qr(e)}function yn(e){return `${process.env.HNCH_SHARE_ORIGIN??"https://hnch.dev"}/join?code=${e}`}function wn(e){return `npx ${yd} join ${e}`}function So(e){let t=e.trim();return t===""?void 0:t}function Cn(e){return e?{title:e.title??"",ticketId:e.ticketId??"",agendaItemId:e.id}:{title:"",ticketId:"",agendaItemId:void 0}}function Ii(e,t,n){return [e,So(t),n]}var wd={connecting:"yellow",connected:"green",disconnected:"red"};function Ai({roomCode:e,sessionName:t,status:n,isHost:o}){let r=t?`${e} \xB7 ${t}`:e;return jsxs(Box,{borderStyle:"single",borderColor:"gray",paddingX:1,justifyContent:"space-between",children:[jsxs(Text,{bold:true,children:["hnch \xB7 ",r]}),jsxs(Box,{gap:2,children:[o&&jsx(Text,{color:"yellow",children:"[host]"}),jsx(Text,{color:wd[n],children:n})]})]})}function Se({items:e,onSelect:t,onClose:n,title:o}){if(e.length===0)return jsxs(Box,{flexDirection:"column",gap:1,children:[o&&jsx(Text,{bold:true,children:o}),jsx(Text,{dimColor:true,children:"(no items)"})]});let r=e.findIndex(a=>!a.disabled),[i,s]=useState(Math.max(r,0));return useInput((a,d)=>{if(d.upArrow)s(l=>{let u=(l-1+e.length)%e.length,c=0;for(;e[u]?.disabled&&c<e.length;)u=(u-1+e.length)%e.length,c++;return u});else if(d.downArrow)s(l=>{let u=(l+1)%e.length,c=0;for(;e[u]?.disabled&&c<e.length;)u=(u+1)%e.length,c++;return u});else if(d.return){let l=e[i];l&&!l.disabled&&t(l.value);}else d.escape&&n?.();}),jsxs(Box,{flexDirection:"column",gap:1,children:[o&&jsx(Text,{bold:true,children:o}),jsx(Box,{flexDirection:"column",children:e.map((a,d)=>{let l=d===i,u=a.disabled??false;return jsxs(Box,{gap:1,children:[jsx(Text,{...l&&{color:"cyan"},dimColor:u,children:l?">":" "}),jsx(Text,{bold:l,dimColor:u,children:a.label}),a.detail&&jsx(Text,{dimColor:true,children:a.detail})]},a.value)})}),jsx(Text,{dimColor:true,children:"\u2191\u2193 select \u23CE confirm esc close"})]})}function W({value:e,onChange:t,onSubmit:n,onCancel:o,placeholder:r,isActive:i=true,mask:s=false}){useInput((u,c)=>{c.escape?o?.():c.return?n(e):c.backspace||c.delete?t(e.slice(0,-1)):u&&!c.ctrl&&!c.meta&&t(e+u);},{isActive:i});let a=s&&e.length>0?"*".repeat(e.length):e,d=a.length>0?a:r??"",l=e.length===0&&r!==void 0;return jsxs(Text,{children:[jsx(Text,{dimColor:l,children:d}),jsx(Text,{inverse:true,children:" "})]})}function Pi({mode:e,password:t,onModeChange:n,onPasswordChange:o,onClose:r}){let[i,s]=useState(e==="open"?0:1),[a,d]=useState(false);return useEffect(()=>{s(e==="open"?0:1);},[e]),useInput((l,u)=>{if(u.leftArrow)s(c=>Math.max(0,c-1));else if(u.rightArrow)s(c=>Math.min(1,c+1));else if(u.return){let c=i===0?"open":"password";c!==e&&n(c),c==="password"&&d(true);}else u.escape&&r?.();},{isActive:!a}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{gap:1,children:["open","password"].map((l,u)=>{let c=u===i,f=l===e,N=l==="open"?"Open":"Password";return jsx(Text,{inverse:c,bold:f,...f&&{color:"cyan"},children:f?`[${N}]`:` ${N} `},l)})}),e==="password"&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{children:"Password: "}),jsx(W,{value:t,onChange:o,onSubmit:()=>d(false),onCancel:()=>d(false),placeholder:"(required to join)",isActive:a,mask:true}),!a&&jsx(Text,{dimColor:true,children:"\u23CE edit \u2190 \u2192 switch mode esc close"}),a&&jsx(Text,{dimColor:true,children:"\u23CE done esc cancel"})]}),e==="open"&&jsx(Text,{dimColor:true,children:"\u2190\u2192 toggle \u23CE confirm esc close"})]})}function Di({scaleId:e,cards:t,disabledIndices:n,onOverrideChange:o,onClose:r}){let i=useMemo(()=>new Set(n),[n]),[s,a]=useState(0),d=l=>{let u=new Set(i);if(u.has(l))u.delete(l);else {if(u.size>=t.length-1)return;u.add(l);}let c=Array.from(u).toSorted((f,N)=>f-N);o(e,c);};return useInput((l,u)=>{u.leftArrow?a(c=>Math.max(0,c-1)):u.rightArrow?a(c=>Math.min(t.length-1,c+1)):l===" "?d(s):(u.return||u.escape)&&r();}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{gap:1,children:t.map((l,u)=>{let c=u===s,f=i.has(u);return jsx(Text,{inverse:c,bold:!f,...!f&&{color:"cyan"},strikethrough:f,dimColor:f,children:l},l)})}),jsx(Text,{dimColor:true,children:" \u2190\u2192 navigate space toggle \u23CE/esc done"})]})}function bo({initialName:e="",initialCards:t=[],onSave:n,onCancel:o}){let r=e.length>0,[i,s]=useState(e),[a,d]=useState(t.length>0?t:[""]),[l,u]=useState(0),[c,f]=useState("editing-name"),[N,P]=useState(""),g=()=>{let E=i.trim();if(E.length===0||E.length>40){P("Name must be 1-40 characters");return}s(E),P(""),f("editing-cards");},p=()=>{let E=i.trim();if(E.length===0||E.length>40){P("Name must be 1-40 characters");return}let C=a.map(v=>v.trim()).filter(v=>v.length>0),k=Array.from(new Set(C));if(k.length<2){P("Need at least 2 unique non-empty cards");return}P(""),n(E,k);};return useInput((E,C)=>{if(c==="editing-cards"){if(C.leftArrow)u(k=>Math.max(0,k-1));else if(C.rightArrow)u(k=>{let v=k+1;return v>=a.length&&a.length<25?(d(B=>[...B,""]),v):Math.min(v,a.length-1)});else if(C.return)p();else if(C.escape)o();else if(C.tab)f("editing-name");else if(C.backspace){let k=a[l]||"";if(k.length===0){if(a.length>2){let v=a.filter((B,b)=>b!==l);d(v),u(Math.max(0,l-1));}}else {let v=[...a];v[l]=k.slice(0,-1),d(v);}}else if(E&&!C.ctrl&&!C.meta){let k=a[l]||"";if(k.length<10){let v=[...a];v[l]=k+E,d(v);}}}},{isActive:c==="editing-cards"}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:r?"\u2500\u2500 Edit Custom Scale \u2500\u2500":"\u2500\u2500 Create Custom Scale \u2500\u2500"}),jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Text,{children:"Name:"}),jsx(W,{value:i,onChange:s,onSubmit:g,onCancel:o,placeholder:"Scale name",isActive:c==="editing-name"})]}),c==="editing-cards"&&jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Text,{children:"Cards:"}),jsx(Box,{gap:1,flexWrap:"wrap",children:a.map((E,C)=>{let k=C===l;return jsx(Text,{inverse:k,...!k&&{color:"cyan"},children:E.length>0?E:"\xB7"},C)})})]}),N&&jsx(Text,{color:"red",children:N}),jsx(Text,{dimColor:true,children:c==="editing-name"?"\u23CE next esc cancel":"\u2190\u2192 navigate typing adds card bsp delete \u23CE save tab name esc cancel"})]})}function Rn({scales:e,selectedScaleId:t,presetOverrides:n,customScales:o=[],onSelect:r,onOverrideChange:i,onCustomScaleCreate:s,onCustomScaleEdit:a,onCustomScaleDelete:d,onClose:l,showNoneOption:u=false}){let[c,f]=useState(0),[N,P]=useState(null),[g,p]=useState("browsing"),[A,E]=useState(null),[C,k]=useState(null),v=s?[...e,{id:"__create-custom__",cards:[]}]:e,B=v.length;if(useInput((b,_)=>{if(g==="browsing"){if(_.escape){l();return}if(B===0)return;if(_.upArrow)f(T=>(T-1+B)%B);else if(_.downArrow)f(T=>(T+1)%B);else if(_.return){let T=v[c];if(!T)return;if(T.id==="__create-custom__"){p("creating");return}T.id in de?P(N===T.id?null:T.id):r(T.id);}else if(b===" "){let T=v[c];T&&T.id!=="__create-custom__"&&r(T.id);}else if(b==="e"||b==="E"){let T=v[c];a&&T?.id.startsWith("custom-")&&(E(T.id),p("editing"));}else if(b==="d"||b==="D"){let T=v[c];d&&T?.id.startsWith("custom-")&&(k(T.id),p("confirming-delete"));}}else g==="confirming-delete"&&(b==="y"||b==="Y"?(C&&d&&d(C),k(null),p("browsing")):(b==="n"||b==="N"||_.escape)&&(k(null),p("browsing")));},{isActive:g==="browsing"&&N===null||g==="confirming-delete"}),g==="creating")return jsx(bo,{onSave:(b,_)=>{s&&s(b,_),p("browsing");},onCancel:()=>p("browsing")});if(g==="editing"&&A){let b=o?.find(T=>T.id===A);if(e.find(T=>T.id===A)&&b)return jsx(bo,{initialName:b.label,initialCards:b.cards,onSave:(T,O)=>{a&&a(A,T,O),E(null),p("browsing");},onCancel:()=>{E(null),p("browsing");}})}if(g==="confirming-delete"&&C){let b=v.find(T=>T.id===C),_=b?Fe(b.id,o):"Unknown";return jsxs(Box,{flexDirection:"column",gap:1,children:[jsxs(Text,{children:["Delete ",_,"? "]}),jsx(Text,{children:"[y] yes [n] no esc cancel"})]})}return v.length===0?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{dimColor:true,children:"(no scales available)"}),jsx(Text,{dimColor:true,children:"esc back"})]}):jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Box,{flexDirection:"column",children:v.map((b,_)=>{let T=_===c,O=b.id===t,Y=N===b.id,K=b.id in de,G=b.id==="__create-custom__",j=b.cards.join(", "),I=u&&b.id==="",w=I?"(none)":G?"[+ Create custom scale]":Fe(b.id,o);return jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{...T&&{color:"cyan"},children:T?">":" "}),jsx(Text,{bold:T,children:w}),!I&&!G&&jsx(Text,{dimColor:true,children:j}),O&&jsx(Text,{color:"cyan",children:"[current]"})]}),Y&&!I&&!G&&jsx(Box,{paddingLeft:2,children:K?jsx(Di,{scaleId:b.id,cards:de[b.id]?.cards??[],disabledIndices:n?.[b.id]??[],onOverrideChange:i,onClose:()=>P(null)}):null})]},b.id||"none")})}),jsx(Text,{dimColor:true,children:(()=>{let b=c<v.length?v[c]:null;return b?.id.startsWith("custom-")?`\u2191\u2193 navigate space select${a?" [e] edit":""}${d?" [d] delete":""} esc back`:b&&b.id in de?"\u2191\u2193 navigate \u23CE customize space select esc back":"\u2191\u2193 navigate \u23CE/space select esc back"})()})]})}function Ld(e,t){return t?[...e]:e.filter(n=>n.value==="display-name")}function _i({sessionName:e,displayName:t,currentScale:n,accessMode:o,presetOverrides:r,customScales:i,isHost:s=true,onChangeName:a,onChangeScale:d,onChangeDisplayName:l,onChangeAccess:u,onClose:c}){let[f,N]=useState(r??{}),P=useMemo(()=>on(f,i),[f,i]),[g,p]=useState("main-menu");useEffect(()=>{!s&&g!=="main-menu"&&g!=="editing-display-name"&&p("main-menu");},[s,g]);let[A,E]=useState(e??""),[C,k]=useState(t),[v,B]=useState(o==="password"?"password":"open"),[b,_]=useState(""),[T,O]=useState(false),Y=[{label:"Room name",value:"room-name",detail:`[${e??"(none)"}]`},{label:"Scale",value:"scale",detail:`[${Fe(n.id,i)}]`},{label:"Access",value:"access",detail:`[${o==="open"?"Open":"Password"}]`},{label:"Display name",value:"display-name",detail:`[${t}]`}],K=Ld(Y,s);function G(m){!s&&m!=="display-name"||(m==="room-name"?(E(e??""),p("editing-room-name")):m==="scale"?p("picking-scale"):m==="access"?p("picking-access"):m==="display-name"&&(k(t),p("editing-display-name")));}function j(m){let y=m.trim()===""?void 0:m.trim();a(y),p("main-menu");}function I(m){let y=m.trim();y.length>0&&(l(y),process.nextTick(()=>z({displayName:y}))),p("main-menu");}function w(m){let y=P.find(D=>D.id===m);y&&d(y),p("main-menu");}function M(m,y){let D={...f};y.length===0?delete D[m]:D[m]=y,N(D),z({presetOverrides:Object.keys(D).length>0?D:void 0});}async function J(m,y){O(true);try{await u(m,y),B(m),_(m==="password"?y??"":"");}catch(D){console.error(`Failed to update access: ${D instanceof Error?D.message:String(D)}`);}finally{O(false),p("main-menu");}}return g==="main-menu"?jsx(Se,{title:"\u2500\u2500 Settings \u2500\u2500",items:K,onSelect:G,onClose:c}):g==="editing-room-name"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Text,{children:"Room name: "}),jsx(W,{value:A,onChange:E,onSubmit:j,onCancel:()=>p("main-menu"),placeholder:"(leave empty to remove)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]}):g==="editing-display-name"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Text,{children:"Display name: "}),jsx(W,{value:C,onChange:k,onSubmit:I,onCancel:()=>p("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]}):g==="picking-scale"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),jsx(Rn,{scales:P,selectedScaleId:n.id,presetOverrides:f,onSelect:w,onOverrideChange:M,onClose:()=>p("main-menu")})]}):g==="picking-access"?jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Settings \u2500\u2500"}),T&&jsx(Text,{dimColor:true,children:"Updating access..."}),!T&&jsx(Pi,{mode:v,password:b,onModeChange:m=>{m==="open"&&J("open");},onPasswordChange:_,onClose:()=>p("main-menu")})]}):jsx(Box,{})}function En({participants:e,onlineIds:t,hostId:n,votes:o,revealed:r,participantId:i}){return jsxs(Box,{flexDirection:"column",children:[jsxs(Text,{bold:true,children:["Participants (",e.length,")"]}),e.map(s=>{let a=t.has(s.id),d=a?"\u25CF":"\u25CB",l=a?"green":"gray",u=s.id===n,c=ge(s)==="viewer",f=s.id===i,N=s.id in o,P=c?" (viewer)":r?o[s.id]?` \u2192 ${o[s.id]}`:"":N?" \u2713":" \xB7",g=f&&!c&&!(r&&o[s.id]);return jsxs(Box,{gap:1,children:[jsx(Text,{color:l,children:d}),jsxs(Text,{children:[s.displayName,u?" (host)":""]}),g?jsx(Text,{color:"cyan",children:"(voter)"}):jsx(Text,{color:c?"gray":N?"green":"gray",children:P})]},s.id)})]})}var Md=[{label:"End session for everyone",value:"end-session",detail:"Disconnects all participants. Cannot be undone."}];function Mi({onPick:e,onClose:t}){return jsx(Se,{title:"Host Actions",items:Md,onSelect:e,onClose:t})}function Tn({roomCode:e,onPick:t,onClose:n}){let o=[{label:"Copy code",value:"code",detail:xn(e)},{label:"Copy share link",value:"url",detail:yn(e)},{label:"Copy npx command",value:"npx",detail:wn(e)}];return jsx(Se,{title:"Share",items:o,onSelect:r=>t(r),onClose:n})}function Hd(e){let t=Object.fromEntries(e.participants.map(n=>[n.id,n]));return ni({rounds:e.rounds,participants:t})}async function $i(e,t,n){let o=Hd(e);try{await t(o),n("Results copied to clipboard");}catch{n("Clipboard write failed");}}function Bi(e,t){let n=lo(e,t),o=e.title?` \u2014 ${e.title}`:"",r=e.ticketId?` [${e.ticketId}]`:"",i=e.status==="skipped"?" \u2014 Skipped":" \u2014 Results";return `${n}${o}${r}${i}`}function Hi(e,t){let n=lo(e,t);if(e.status==="skipped"){let c=e.title?` ${e.title}`:"",f=e.ticketId?` [${e.ticketId}]`:"";return `${n}:${c}${f} \u2014 Skipped`}let o=new Map;for(let c of Object.values(e.votes))ee(c)||o.set(c,(o.get(c)??0)+1);let r=[...o.entries()].toSorted((c,f)=>f[1]-c[1]||c[0].localeCompare(f[0])).map(([c,f])=>`${c}\xD7${f}`).join(", "),i=Object.values(e.votes).filter(ee).length,s=i>0?` (${i} abstained)`:"",a=e.title?` ${e.title}`:"",d=e.ticketId?` [${e.ticketId}]`:"",l=ot(e),u=l!==null?` \u2014 ${l}`:"";return `${n}:${a}${d} \u2014 ${r||"(no votes)"}${s}${u}`}function Ui({projection:e,onlineIds:t,isHost:n,participantId:o,rounds:r,currentRound:i,settingsOpen:s,onStartRound:a,onNewRound:d,onRevote:l,onOpenSettings:u,onHandoffHost:c,onEndSession:f,onShare:N,shareOpen:P,onSetShareOpen:g,roomCode:p,confirmingQuit:A,myRole:E,onToggleRole:C,roundTitlePromptActive:k,roundTitleInput:v,onRoundTitleChange:B,onRoundTitleSubmit:b,onRoundTitleCancel:_,roundTicketIdPromptActive:T,roundTicketIdInput:O,onRoundTicketIdChange:Y,onRoundTicketIdSubmit:K,onRoundTicketIdCancel:G,descriptorPromptActive:j,descriptorInput:I,onDescriptorChange:w,onDescriptorSubmit:M,onDescriptorCancel:J,onEditDescriptor:m,canExport:y,onExportResults:D,onAgendaAdd:X,agendaAddPromptActive:ue,agendaAddTitleInput:dt,onAgendaAddTitleChange:Mn,onAgendaAddTitleSubmit:qe,onAgendaAddTitleCancel:Nt,agendaAddTicketIdPromptActive:Re,agendaAddTicketIdInput:$n,onAgendaAddTicketIdChange:Xe,onAgendaAddTicketIdSubmit:Qe,onAgendaAddTicketIdCancel:Le}){let[oe,re]=kn.useState("idle"),[xe,be]=kn.useState(null),[ct,ae]=kn.useState(false),[fe,ye]=kn.useState(false);useEffect(()=>{n||(re("idle"),be(null),ae(false),ye(false));},[n]),useInput(R=>{if(R==="c"||R==="C"){g(true);return}if(R==="w"||R==="W"){C();return}if((R==="x"||R==="X")&&y){D();return}if(n){if(R==="a"||R==="A"){X();return}(R==="e"||R==="E")&&u(),(R==="s"||R==="S")&&a(),(R==="h"||R==="H")&&re("picking"),(R==="m"||R==="M")&&ae(true),i!==null&&ut(i.status)&&((R==="n"||R==="N")&&d(),(R==="v"||R==="V")&&i.status!=="skipped"&&l(),(R==="t"||R==="T")&&m());}},{isActive:!s&&!A&&oe==="idle"&&!k&&!T&&!ct&&!fe&&!P&&!j&&!ue&&!Re}),useInput((R,pe)=>{R==="y"||R==="Y"?(f(),ye(false)):(R==="n"||R==="N"||pe.escape)&&ye(false);},{isActive:fe});let Ae=e.participants.filter(R=>R.id!==o&&t.has(R.id));useInput(R=>{if(oe==="picking"){let pe=parseInt(R,10);!isNaN(pe)&&pe>=1&&pe<=Ae.length?(be(Ae[pe-1].id),re("confirming")):(R==="Escape"||R==="q"||R==="Q")&&re("idle");}},{isActive:oe==="picking"}),useInput(R=>{oe==="confirming"&&xe&&(R==="y"||R==="Y"?(c(xe),re("idle"),be(null)):(R==="n"||R==="N"||R==="Escape")&&(re("idle"),be(null)));},{isActive:oe==="confirming"});let Ze=r.filter(R=>$t(R.status)),Me=Ze.length>0,Ot=i!==null?Ze.slice(0,-1):Ze;return ct?jsx(Mi,{onPick:R=>{ae(false),R==="end-session"&&ye(true);},onClose:()=>ae(false)}):P?jsx(Tn,{roomCode:p,onPick:R=>{g(false),N(R);},onClose:()=>g(false)}):jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:Me?"Session":"Waiting for participants..."}),!Me&&jsx(Text,{dimColor:true,children:"No rounds started yet."}),jsx(En,{participants:e.participants,onlineIds:t,hostId:e.settings.hostParticipantId,votes:{},revealed:false,participantId:o}),e.agenda.length>0&&jsx(Kd,{items:e.agenda,nextPending:He(e)}),i!==null&&ut(i.status)&&jsx(jd,{projection:e,round:i,rounds:r}),Ot.length>0&&jsxs(Box,{flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"\u2500\u2500 History \u2500\u2500"}),Ot.map(R=>jsx(Text,{dimColor:true,children:Hi(R,r)},R.id))]}),oe==="picking"&&Ae.length>0&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{children:"Hand off to:"}),Ae.map((R,pe)=>jsxs(Text,{children:["[",pe+1,"] ",R.displayName]},R.id)),jsx(Text,{dimColor:true,children:"[q] Cancel"})]}),oe==="picking"&&Ae.length===0&&jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{dimColor:true,children:"No other online participants"}),jsx(Text,{dimColor:true,children:"[q] Cancel"})]}),oe==="confirming"&&xe&&jsx(Box,{flexDirection:"column",children:jsxs(Text,{children:["Hand off to ",e.participants.find(R=>R.id===xe)?.displayName,"? [y/n]"]})}),k&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Round title (optional, Enter to skip):"}),jsx(W,{value:v,onChange:B,onSubmit:b,onCancel:_,placeholder:"Enter to skip",isActive:k})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),T&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Ticket ID (optional, Enter to skip):"}),jsx(W,{value:O,onChange:Y,onSubmit:K,onCancel:G,placeholder:"e.g. PROJ-1234",isActive:T})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),j&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Edit round title:"}),jsx(W,{value:I,onChange:w,onSubmit:M,onCancel:J,placeholder:"Enter to save",isActive:j})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel \xB7 empty submit cancels"})]}),fe&&jsxs(Box,{children:[jsx(Text,{color:"red",children:"End session for everyone? This cannot be undone. "}),jsx(Text,{dimColor:true,children:"y/n [Esc] Cancel"})]}),ue&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Agenda title (optional, Enter to skip):"}),jsx(W,{value:dt,onChange:Mn,onSubmit:qe,onCancel:Nt,placeholder:"Enter to skip",isActive:ue})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),Re&&jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:1,children:[jsx(Text,{children:"Agenda ticket ID (optional, Enter to skip):"}),jsx(W,{value:$n,onChange:Xe,onSubmit:Qe,onCancel:Le,placeholder:"e.g. PROJ-1234",isActive:Re})]}),jsx(Text,{dimColor:true,children:"[Esc] Cancel"})]}),oe==="idle"&&!k&&!T&&!j&&!fe&&!ue&&!Re&&jsxs(Box,{gap:2,children:[n?jsx(Fragment,{children:i!==null&&ut(i.status)?jsxs(Fragment,{children:[i.status!=="skipped"&&jsx(Text,{color:"yellow",children:"[v] Revote"}),jsx(Text,{color:"yellow",children:"[n] Next"}),jsx(Text,{color:"yellow",children:"[t] Edit title"}),jsx(Text,{color:"yellow",children:"[h] Handoff"}),jsx(Text,{color:"yellow",children:"[e] Settings"}),jsx(Text,{color:"yellow",children:"[c] Share"}),y&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",E==="viewer"?"Vote":"Observe"]}),jsx(Text,{color:"yellow",children:"[m] Menu"})]}):jsxs(Fragment,{children:[jsx(Text,{color:"yellow",children:"[s] Start round"}),jsx(Text,{color:"yellow",children:"[a] Agenda"}),jsx(Text,{color:"yellow",children:"[h] Handoff"}),jsx(Text,{color:"yellow",children:"[e] Settings"}),jsx(Text,{color:"yellow",children:"[c] Share"}),y&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",E==="viewer"?"Vote":"Observe"]}),jsx(Text,{color:"yellow",children:"[m] Menu"})]})}):jsxs(Fragment,{children:[jsx(Text,{dimColor:true,children:"Waiting for host to start a round..."}),jsx(Text,{children:"[c] Share"}),y&&jsx(Text,{color:"yellow",children:"[x] Export"}),jsxs(Text,{color:"yellow",children:["[w] ",E==="viewer"?"Vote":"Observe"]})]}),jsx(Text,{children:"[q] Quit"})]})]})}function jd({projection:e,round:t,rounds:n}){let o=Bi(t,n);if(t.status==="skipped")return jsx(Box,{flexDirection:"column",gap:1,children:jsx(Text,{bold:true,children:o})});let r=tn(en(t)),i=new Map(e.participants.map(c=>[c.id,c.displayName])),s=ot(t),a=Object.entries(t.votes),d=a.filter(([,c])=>!ee(c)),l=a.filter(([,c])=>ee(c)).map(([c])=>c),u=d[0]?.[1];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:o}),Xn(t)&&u!==void 0&&jsxs(Text,{bold:true,color:"green",children:["Consensus! Everyone voted ",u]}),jsxs(Box,{flexDirection:"column",children:[jsxs(Box,{gap:2,children:[jsx(Text,{bold:true,underline:true,children:"Name".padEnd(20)}),jsx(Text,{bold:true,underline:true,children:"Estimate".padEnd(10)})]}),d.map(([c,f])=>jsxs(Box,{gap:2,children:[jsx(Text,{children:(i.get(c)??c).padEnd(20)}),jsx(Text,{color:"cyan",bold:true,children:f.padEnd(10)})]},c)),l.map(c=>jsxs(Box,{gap:2,children:[jsx(Text,{dimColor:true,children:(i.get(c)??c).padEnd(20)}),jsx(Text,{dimColor:true,children:"(abstained)".padEnd(10)})]},c)),e.participants.filter(c=>!(c.id in t.votes)).map(c=>jsxs(Box,{gap:2,children:[jsx(Text,{dimColor:true,children:c.displayName.padEnd(20)}),jsx(Text,{dimColor:true,children:"(no vote)".padEnd(10)})]},c.id))]}),(r!==null||s!==null)&&jsxs(Box,{gap:2,children:[r?.kind==="numeric"&&jsxs(Text,{children:["Avg: ",jsx(Text,{bold:true,children:r.mean})]}),r?.kind==="numeric"&&jsxs(Text,{children:["Med: ",jsx(Text,{bold:true,children:r.median})]}),r?.kind==="categorical"&&r.mode!==null&&jsxs(Text,{children:["Most common: ",jsx(Text,{bold:true,children:r.mode})]}),r!==null&&jsxs(Text,{children:["Spread: ",jsx(Text,{bold:true,children:r.spread})]}),s!==null&&jsxs(Text,{dimColor:true,children:["\u23F1 ",s]})]})]})}var Fd={pending:"\u2022",consumed:"\u2713",skipped:"~",cancelled:"\u2717"},Vd={consumed:"green",skipped:"yellow",cancelled:"red"};function Kd({items:e,nextPending:t}){let n=e.filter(o=>o.state!=="cancelled");return jsxs(Box,{flexDirection:"column",children:[jsx(Text,{dimColor:true,children:"\u2500\u2500 Agenda \u2500\u2500"}),n.map(o=>{let r=Fd[o.state]??"?",i=Vd[o.state],s=t!==null&&o.id===t.id,a=[o.ticketId?`[${o.ticketId}]`:"",o.title??""].filter(Boolean).join(" ").trim()||o.id;return jsxs(Box,{gap:1,children:[i!==void 0?jsx(Text,{color:i,children:r}):jsx(Text,{children:r}),i!==void 0?jsx(Text,{color:i,children:a}):jsx(Text,{children:a}),s&&jsx(Text,{color:"cyan",children:"(next)"})]},o.id)}),n.length===0&&jsx(Text,{dimColor:true,children:"No pending items."})]})}function Vi({scale:e,selected:t,onToggleCurrentVote:n,onClearCurrentVote:o,disabled:r}){let[i,s]=useState(0);return useInput((a,d)=>{r||(d.leftArrow?s(l=>Math.max(0,l-1)):d.rightArrow?s(l=>Math.min(e.cards.length-1,l+1)):d.return?n(e.cards[i]):(d.backspace||d.delete)&&o());}),jsxs(Box,{flexDirection:"column",gap:0,children:[jsx(Box,{gap:1,children:e.cards.map((a,d)=>{let l=d===i,u=a===t;return jsx(Text,{inverse:l,bold:u,...u&&{color:"cyan"},children:u?`[${a}]`:` ${a} `},a)})}),jsx(Text,{dimColor:true,children:" \u2190\u2192 navigate \u23CE select \u232B clear"})]})}function Ki({projection:e,round:t,onlineIds:n,isHost:o,myId:r,myRole:i,elapsedMs:s,roomCode:a,shareOpen:d,settingsOpen:l,onToggleCurrentVote:u,onClearCurrentVote:c,onReveal:f,onSkip:N,onDiscard:P,onToggleRole:g,onShare:p,onSetShareOpen:A,onOpenSettings:E,confirmingQuit:C}){let k=t.votes[r],v=k!==void 0&&ee(k);if(useInput(O=>{if(O==="e"||O==="E"){E();return}if(O==="c"||O==="C"){A(true);return}if(i==="voter"&&(O==="a"||O==="A")){u(Lt);return}o&&(O==="r"||O==="R")&&f(),o&&(O==="s"||O==="S")&&N(),o&&(O==="d"||O==="D")&&P(),(O==="w"||O==="W")&&g();},{isActive:!C&&!l&&!d}),d)return jsx(Tn,{roomCode:a,onPick:O=>{A(false),p(O);},onClose:()=>A(false)});let B=k,b=xt(t,e.rounds),_=t.title?` \u2014 ${t.title}`:"",T=t.ticketId?` [${t.ticketId}]`:"";return jsxs(Box,{flexDirection:"column",gap:1,children:[jsxs(Box,{gap:2,children:[jsxs(Text,{bold:true,children:["Round ",b,_,T]}),s!==void 0&&jsxs(Text,{dimColor:true,children:["\u23F1 ",Gt(s)]})]}),jsxs(Box,{gap:4,children:[jsx(En,{participants:e.participants,onlineIds:n,hostId:e.settings.hostParticipantId,votes:t.votes,revealed:false}),i==="viewer"?jsx(Box,{flexDirection:"column",children:jsx(Text,{dimColor:true,children:"You're observing"})}):jsxs(Box,{flexDirection:"column",gap:1,children:[v&&jsx(Text,{dimColor:true,children:"(abstaining this round \u2014 press [a] to vote)"}),jsx(Vi,{scale:t.scale,selected:v?void 0:B,onToggleCurrentVote:u,onClearCurrentVote:c,disabled:C||v})]})]}),jsxs(Box,{gap:2,children:[o&&jsx(Text,{color:"yellow",children:"[r] Reveal"}),o&&jsx(Text,{color:"yellow",children:"[s] Skip"}),o&&jsx(Text,{color:"yellow",children:"[d] Discard"}),i==="voter"&&jsxs(Text,{color:"yellow",children:["[a] ",v?"Vote":"Abstain"]}),jsxs(Text,{color:"yellow",children:["[w] ",i==="viewer"?"Vote":"Observe"]}),jsx(Text,{children:"[e] Settings"}),jsx(Text,{children:"[c] Share"}),jsx(Text,{children:"[q] Quit"})]})]})}var Qd=3e3;function Et(e=Qd){let[t,n]=useState(null),o=useRef(null),r=useCallback(()=>{o.current!==null&&(clearTimeout(o.current),o.current=null);},[]),i=useCallback(a=>{r(),n(a),o.current=setTimeout(()=>{n(null),o.current=null;},e);},[r,e]),s=useCallback(()=>{r(),n(null);},[r]);return useEffect(()=>()=>{r();},[r]),{notice:t,show:i,dismiss:s}}function On({session:e,participantId:t,displayName:n,accessMode:o,presetOverrides:r,customScales:i}){let{exit:s}=useApp(),[a,d]=useState(e.projection()),[l,u]=useState("connecting"),[c,f]=useState(e.onlineIds()),[N,P]=useState(),[g,p]=useState(false),[A,E]=useState(o==="password"?"password":"open"),[C,k]=useState(n),[v,B]=useState(false),[b,_]=useState(false),[T,O]=useState(""),[Y,K]=useState(false),[G,j]=useState(""),[I,w]=useState(),[M,J]=useState(false),[m,y]=useState(""),[D,X]=useState(null),[ue,dt]=useState(false),[Mn,qe]=useState(""),[Nt,Re]=useState(false),[$n,Xe]=useState(""),[Qe,Le]=useState(),[oe,re]=useState(),xe=Et(3e3),[be,ct]=useState(false),ae=Et(3e3),fe=Et(3e3),ye=Et(3e3);useEffect(()=>{let x=()=>{d(e.projection()),f(e.onlineIds());},U=e.onChange(x);x();let Ee=e.onStatusChange(u),Dt=e.onSessionEvent(_t=>{_t.kind==="host-changed"&&xe.show(_t.message);}),Ls=setInterval(()=>{let _t=e.projection(),Hn=me(_t);Hn?.timerStartedAt!==void 0&&et(Hn.status)?P(Date.now()-Hn.timerStartedAt):P(void 0);},1e3);return ()=>{U(),Ee(),Dt(),clearInterval(Ls);}},[e,xe.show]),useInput(x=>{(x==="q"||x==="Q")&&B(true);},{isActive:!g&&!v&&!b&&!Y&&!M&&!be&&!ue&&!Nt}),useInput((x,U)=>{x==="y"||x==="Y"?s():(x==="n"||x==="N"||U.escape)&&B(false);},{isActive:v});let Ae=oi(a),Ze=me(a),Me=a.settings.hostParticipantId===t,Ot=a.participants.find(x=>x.id===t),R=ge(Ot??{}),pe=useCallback(()=>{let x=Cn(He(a));O(x.title),re(x.agendaItemId),_(true);},[a]),ss=useCallback(x=>{_(false),O(""),w(So(x));let U=Cn(He(a));j(U.ticketId),K(true);},[a]),as=useCallback(()=>{_(false),O(""),w(void 0),re(void 0);},[]),ds=useCallback(x=>{K(false),j("");let[U,Ee,Dt]=Ii(I,x,oe);e.commands.startRound({...U!==void 0&&{title:U},...Ee!==void 0&&{ticketId:Ee},...Dt!==void 0&&{agendaItemId:Dt}}),w(void 0),re(void 0);},[e,I,oe]),cs=useCallback(()=>{K(false),j(""),w(void 0),re(void 0);},[]),ls=useCallback(()=>{let x=e.current();!x||x.status!=="revealed"||(X(x.id),y(x.title??""),J(true));},[e]),us=useCallback(x=>{let U=D;if(J(false),X(null),!U)return;let Ee=x.trim();Ee!==""&&e.updateRoundDescriptor(U,{title:Ee});},[e,D]),fs=useCallback(()=>{J(false),X(null);},[]),ps=useCallback(x=>{e.commands.toggleCurrentVote(x);},[e]),ms=useCallback(()=>{e.commands.clearCurrentVote();},[e]),gs=useCallback(()=>{e.commands.revealCurrentRound();},[e]),hs=useCallback(()=>{e.commands.skipCurrentRound();},[e]),Ss=useCallback(()=>{e.commands.discardCurrentRound();},[e]),xs=useCallback(()=>{let x=Cn(He(a));O(x.title),re(x.agendaItemId),_(true);},[a]),ys=useCallback(()=>{let x=e.current();x&&e.commands.startRound({parentRoundId:x.id,...x.title!==void 0&&{title:x.title},...x.description!==void 0&&{description:x.description},...x.ticketId!==void 0&&{ticketId:x.ticketId},...x.agendaItemId!==void 0&&{agendaItemId:x.agendaItemId}});},[e]),No=useCallback(()=>{e.commands.toggleRole();},[e]),ws=useCallback(x=>{e.updateName(x);},[e]),Cs=useCallback(x=>{e.updateScale(x);},[e]),vs=useCallback(x=>{e.commands.rename(x),k(x);},[e]),Is=useCallback(async(x,U)=>{await e.updateAccess(x,U),E(x);},[e]),Rs=useCallback(x=>{e.handoffHost(x).then(U=>{U.applied||console.error(`Handoff failed: ${li[U.reason]}`);});},[e]),Oo=useCallback(()=>{p(true);},[]),bs=useCallback(()=>{p(false);},[]),As=useCallback(()=>{e.commands.endSession();},[e]),Do=useCallback(async x=>{let U=x==="code"?xn(e.roomCode):x==="url"?yn(e.roomCode):wn(e.roomCode);try{await Wi.write(U),ae.show("Copied!");}catch{ae.show(`Copy failed \u2014 ${U}`);}},[e.roomCode,ae]),Bn=a.rounds.filter(x=>$t(x.status)),Es=Bn.length>0?Bn.at(-1):null,Ts=Bn.length>0,ks=useCallback(()=>$i(a,x=>Wi.write(x),fe.show),[a,fe.show]),Ps=useCallback(()=>{qe(""),dt(true);},[]),Ns=useCallback(x=>{dt(false),qe("");let U=x.trim()===""?void 0:x.trim();Le(U),Xe(""),Re(true);},[]),Os=useCallback(()=>{dt(false),qe(""),Le(void 0);},[]),Ds=useCallback(x=>{Re(false),Xe("");let U=x.trim()===""?void 0:x.trim();if(!Qe&&!U){Le(void 0);return}if(!e.commands.addItem({...Qe!==void 0&&{title:Qe},...U!==void 0&&{ticketId:U}}).applied){ye.show("Add failed \u2014 an agenda item needs a title or a ticket id");return}Le(void 0);},[e,Qe,ye]),_s=useCallback(()=>{Re(false),Xe(""),Le(void 0);},[]);return jsxs(Box,{flexDirection:"column",children:[jsx(Ai,{roomCode:e.roomCode,sessionName:a.settings.name,status:l,isHost:Me}),xe.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:"yellow",children:xe.notice})}),ae.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:ae.notice.startsWith("Copy failed")?"red":"green",children:ae.notice})}),fe.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:fe.notice.startsWith("Clipboard write failed")?"red":"green",children:fe.notice})}),ye.notice&&jsx(Box,{paddingX:1,children:jsx(Text,{color:"red",children:ye.notice})}),g?jsx(_i,{sessionName:a.settings.name,displayName:C,currentScale:a.settings.defaultScale,accessMode:A,presetOverrides:r,customScales:i,isHost:Me,onChangeName:ws,onChangeScale:Cs,onChangeDisplayName:vs,onChangeAccess:Is,onClose:bs}):Ae==="lobby"?jsx(Ui,{projection:a,onlineIds:c,isHost:Me,participantId:t,rounds:a.rounds,currentRound:Es,settingsOpen:g,onStartRound:pe,onNewRound:xs,roundTitlePromptActive:b,roundTitleInput:T,onRoundTitleChange:O,onRoundTitleSubmit:ss,onRoundTitleCancel:as,roundTicketIdPromptActive:Y,roundTicketIdInput:G,onRoundTicketIdChange:j,onRoundTicketIdSubmit:ds,onRoundTicketIdCancel:cs,onRevote:ys,onOpenSettings:Oo,onHandoffHost:Rs,onEndSession:As,onShare:Do,shareOpen:be,onSetShareOpen:ct,roomCode:e.roomCode,confirmingQuit:v,myRole:R,onToggleRole:No,descriptorPromptActive:M,descriptorInput:m,onDescriptorChange:y,onDescriptorSubmit:us,onDescriptorCancel:fs,onEditDescriptor:ls,canExport:Ts,onExportResults:ks,onAgendaAdd:Ps,agendaAddPromptActive:ue,agendaAddTitleInput:Mn,onAgendaAddTitleChange:qe,onAgendaAddTitleSubmit:Ns,onAgendaAddTitleCancel:Os,agendaAddTicketIdPromptActive:Nt,agendaAddTicketIdInput:$n,onAgendaAddTicketIdChange:Xe,onAgendaAddTicketIdSubmit:Ds,onAgendaAddTicketIdCancel:_s}):Ae==="estimating"&&Ze?jsx(Ki,{projection:a,round:Ze,onlineIds:c,isHost:Me,myId:t,myRole:R,elapsedMs:N,onToggleCurrentVote:ps,onClearCurrentVote:ms,onReveal:gs,onSkip:hs,onDiscard:Ss,onToggleRole:No,onShare:Do,onSetShareOpen:ct,shareOpen:be,settingsOpen:g,onOpenSettings:Oo,roomCode:e.roomCode,confirmingQuit:v}):null,v&&jsx(Box,{children:jsx(Text,{dimColor:true,children:"Leave session? y/n"})})]})}var Yi="https://github.com/IIxauII/hnch",Gi="AGPL-3.0-only",zi="1.19.0";function qi(e,t){return e.version(`${t}
25
+ Source code: ${Yi} (${Gi})`).epilogue(`Source code: ${Yi}
26
+ License: ${Gi}`)}function Xi({presetOverrides:e,customScales:t}){let{exit:n}=useApp(),[o,r]=useState("main-menu"),[i,s]=useState(Ve()),[a,d]=useState(i.displayName??""),[l,u]=useState(i.relayUrl??""),[c,f]=useState(i.defaultSessionName??""),[N,P]=useState(i.avatarColor?.startsWith("#")?i.avatarColor:""),[g,p]=useState(t??[]),[A,E]=useState(e??{});useInput(m=>{(m==="q"||m==="Q")&&n();},{isActive:o==="main-menu"});let C=useMemo(()=>on(A,g),[A,g]),k=i.defaultScale,v=k?C.find(m=>m.id===k):void 0,B=[{label:"Display name",value:"display-name",detail:`[${i.displayName??"(none)"}]`},{label:"Relay URL",value:"relay-url",detail:`[${i.relayUrl??"(none)"}]`},{label:"Default scale",value:"default-scale",detail:`[${v?Fe(v.id,g):"(none)"}]`},{label:"Default session name",value:"default-session-name",detail:`[${i.defaultSessionName??"(none)"}]`},{label:"Default password",value:"default-password",detail:`[${i.defaultPassword?"on":"off"}]`},{label:"Avatar color",value:"avatar-color",detail:`[${sc(i.avatarColor)}]`}];function b(m){m==="display-name"?(d(i.displayName??""),r("editing-display-name")):m==="relay-url"?(u(i.relayUrl??""),r("editing-relay-url")):m==="default-scale"?r("picking-scale"):m==="default-session-name"?(f(i.defaultSessionName??""),r("editing-session-name")):m==="default-password"?r("picking-default-password"):m==="avatar-color"&&r("picking-avatar-color");}function _(m){if(m==="custom-hex"){P(i.avatarColor?.startsWith("#")?i.avatarColor:""),r("editing-avatar-hex");return}if(Ue(m)===null){r("main-menu");return}s({...i,avatarColor:m}),z({avatarColor:m}),r("main-menu");}function T(m){let y=m.trim();if(y.length===0){r("picking-avatar-color");return}let D=y.startsWith("#")?y.toLowerCase():`#${y.toLowerCase()}`;Ue(D)!==null&&(s({...i,avatarColor:D}),z({avatarColor:D}),r("main-menu"));}function O(m){let y=m.trim();if(y.length>0){let D={...i,displayName:y};s(D),z({displayName:y});}r("main-menu");}function Y(m){let y=m.trim();if(y.length>0){let D={...i,relayUrl:y};s(D),z({relayUrl:y});}r("main-menu");}function K(m){let y=m.trim(),D=y.length>0?{...i,defaultSessionName:y}:{...i};y.length===0?(delete D.defaultSessionName,s(D),wt({defaultSessionName:""})):(s(D),z({defaultSessionName:y})),r("main-menu");}function G(m){let y=m.length>0?{...i,defaultScale:m}:{...i};m.length===0?(delete y.defaultScale,s(y),wt({defaultScale:""})):(s(y),z({defaultScale:m})),r("main-menu");}function j(m,y){let D={...A};y.length===0?delete D[m]:D[m]=y,E(D),z({presetOverrides:Object.keys(D).length>0?D:void 0});}function I(m){let y=m==="on",D={...i,defaultPassword:y};s(D),z({defaultPassword:y}),r("main-menu");}function w(m,y){let D=`custom-${randomUUID()}`,X=[...g,{id:D,label:m,cards:y}];p(X),s({...i,customScales:X}),z({customScales:X});}function M(m,y,D){let X=g.map(ue=>ue.id===m?{id:m,label:y,cards:D}:ue);p(X),s({...i,customScales:X}),z({customScales:X});}function J(m){let y=g.filter(X=>X.id!==m);p(y);let D={...i,customScales:y};i.defaultScale===m?(D.defaultScale="fibonacci",z({customScales:y,defaultScale:"fibonacci"})):z({customScales:y}),s(D);}if(o==="main-menu")return jsx(Se,{title:"\u2500\u2500 Config Settings \u2500\u2500",items:B,onSelect:b,onClose:()=>n()});if(o==="editing-display-name")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Display name: "}),jsx(W,{value:a,onChange:d,onSubmit:O,onCancel:()=>r("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="editing-relay-url")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Relay URL: "}),jsx(W,{value:l,onChange:u,onSubmit:Y,onCancel:()=>r("main-menu"),placeholder:"(required)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="editing-session-name")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Default session name: "}),jsx(W,{value:c,onChange:f,onSubmit:K,onCancel:()=>r("main-menu"),placeholder:"(leave empty to clear)",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="picking-scale"){let m=[{id:"",cards:[]},...C];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Rn,{scales:m,selectedScaleId:k??"",presetOverrides:A,customScales:g,onSelect:G,onOverrideChange:j,onCustomScaleCreate:w,onCustomScaleEdit:M,onCustomScaleDelete:J,onClose:()=>r("main-menu"),showNoneOption:true})]})}if(o==="picking-avatar-color"){let m=ht.map(y=>({label:nt[y].label,value:y,detail:i.avatarColor===y?"[current]":nt[y].base}));return m.push({label:"Custom hex\u2026",value:"custom-hex",detail:i.avatarColor?.startsWith("#")?`[${i.avatarColor}]`:void 0}),jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Se,{title:"Avatar color:",items:m,onSelect:_,onClose:()=>r("main-menu")})]})}if(o==="editing-avatar-hex")return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Text,{children:"Custom hex color: "}),jsx(W,{value:N,onChange:P,onSubmit:T,onCancel:()=>r("picking-avatar-color"),placeholder:"#rrggbb",isActive:true}),jsx(Text,{dimColor:true,children:"\u23CE confirm esc back"})]});if(o==="picking-default-password"){let m=[{label:"On",value:"on",detail:i.defaultPassword?"[current]":void 0},{label:"Off",value:"off",detail:i.defaultPassword?void 0:"[current]"}];return jsxs(Box,{flexDirection:"column",gap:1,children:[jsx(Text,{bold:true,children:"\u2500\u2500 Config Settings \u2500\u2500"}),jsx(Se,{title:"Default password:",items:m,onSelect:I,onClose:()=>r("main-menu")})]})}return jsx(Box,{})}function sc(e){return e?e.startsWith("#")?e:ht.includes(e)?nt[e].label:e:"(auto)"}var ac=2e3,dc={pending:"\u2022",consumed:"\u2713",skipped:"~",cancelled:"\u2717"};function cc(e){let t=dc[e.state]??"?",n=[];e.ticketId&&n.push(`[${e.ticketId}]`),e.title&&n.push(e.title);let o=n.join(" ")||e.id;return `${t} ${o}`}function Dn(e){switch(e){case "not-found":return "no agenda item with that id";case "not-pending":return "the item is no longer pending \u2014 a peer may have skipped, cancelled or estimated it";case "invalid-fields":return "an agenda item needs at least one of --title or --ticket"}}async function kt(e){let t=await Ct(e),n;return await Promise.race([t.whenJoined(),new Promise(o=>{n=setTimeout(o,ac);})]),clearTimeout(n),t}async function Pt(){let e=cn();e.length===0&&(console.error("No active session. Join a room first with: hnch join <code>"),process.exit(1));let t=e[0];return {roomCode:t.roomCode,roomUuid:t.roomUuid,...t.passwordHash!==void 0&&{passwordHash:t.passwordHash}}}async function Qi(e){!e.title?.trim()&&!e.ticket?.trim()&&(console.error("At least one of --title or --ticket is required"),process.exit(1));let t=await le(),n=await Pt();try{await ce(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let o=await kt({...he(t),...n});try{let r=o.commands.addItem({...e.title?.trim()?{title:e.title.trim()}:{},...e.ticket?.trim()?{ticketId:e.ticket.trim()}:{},...e.description?.trim()?{description:e.description.trim()}:{}});r.applied||(console.error(`Add failed: ${Dn(r.reason)}`),process.exit(1)),await new Promise(i=>{setTimeout(i,300);}),console.log(`Added agenda item: ${r.id}`);}finally{o.teardown();}}async function Zi(){let e=await le(),t=await Pt();try{await ce(e.relayUrl,t.roomCode);}catch{console.error(`Room ${t.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let n=await kt({...he(e),...t});try{let r=n.projection().agenda;if(r.length===0){console.log("No agenda items.");return}r.forEach((i,s)=>{console.log(`${String(s+1).padStart(2)}. ${cc(i)}`);});}finally{n.teardown();}}async function es(e){let t=await le(),n=await Pt();try{await ce(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let o=await kt({...he(t),...n});try{let r=o.commands.skipItem(e.id);r.applied||(console.error(`Skip failed: ${Dn(r.reason)}`),process.exit(1)),await new Promise(i=>{setTimeout(i,300);}),console.log(`Skipped agenda item: ${e.id}`);}finally{o.teardown();}}async function ts(e){let t=await le(),n=await Pt();try{await ce(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let o=await kt({...he(t),...n});try{let r=o.commands.cancelItem(e.id);r.applied||(console.error(`Cancel failed: ${Dn(r.reason)}`),process.exit(1)),await new Promise(i=>{setTimeout(i,300);}),console.log(`Cancelled agenda item: ${e.id}`);}finally{o.teardown();}}async function ns(e){let t=await le(),n=await Pt();try{await ce(t.relayUrl,n.roomCode);}catch{console.error(`Room ${n.roomCode} not found on relay \u2014 session may have expired.`),process.exit(1);}let o=await kt({...he(t),...n});try{let r=o.commands.moveItem(e.id,e.before,e.after);r.applied||(console.error(`Move failed: ${Dn(r.reason)}`),process.exit(1)),await new Promise(i=>{setTimeout(i,300);}),console.log(`Reordered agenda item: ${e.id}`);}finally{o.teardown();}}async function Po(){let e=await Ci(),t=sn(e);return t.ok||(console.error(t.message),process.exit(1)),t.password}async function fc(e){let t=await le(),n=e.scale??t.defaultScale??"fibonacci",o=e.name??t.defaultSessionName,r=e.password??t.defaultPassword??false,i;r&&(i=await Po());let s=nn(n,t.presetOverrides,t.customScales);if(!s){let c=Object.keys(de).join(", ");console.error(`Unknown or fully-disabled scale: "${n}". Builtin IDs: ${c}`),process.exit(1);}let a=mn(),d=gn({wasIn:()=>true,typedPassword:i!==void 0}),l=await fi({...he(t),sessionName:o,password:i,defaultScale:s,...rn(t),onRejection:hn(a,d)});d.bind(l),ln({roomCode:l.roomCode,roomUuid:l.roomUuid,lastSeenAt:Date.now(),...l.passwordHash!==void 0&&{passwordHash:l.passwordHash}}),console.error(`Room created: ${l.roomCode}`),console.error(`Share: hnch join ${l.roomCode}`),console.error("");let u=render(kn.createElement(On,{session:l,participantId:t.participantId,displayName:t.displayName,accessMode:i?"password":"open",presetOverrides:t.presetOverrides,customScales:t.customScales}));await Sn(l,u,a,d);}async function pc(e){let t=await le(),n=hi(e.code);n===null&&(console.error("invalid room code"),process.exit(1));let o;e.password&&(o=await Po());let r=await ce(t.relayUrl,n),i;r.accessMode==="password"&&!e.password?i=await Po():e.password&&(i=o);let s=mn(),a=gn({room:{roomCode:n,roomUuid:r.uuid},wasIn:()=>d.hasJoined(),typedPassword:i!==void 0}),d=await pi({...he(t),roomCode:n,password:i,...rn(t),onRejection:hn(s,a)});a.bind(d),ln({roomCode:d.roomCode,roomUuid:d.roomUuid,lastSeenAt:Date.now(),...d.passwordHash!==void 0&&{passwordHash:d.passwordHash}}),console.error(`Joined room: ${d.roomCode}`),console.error("");let l=render(kn.createElement(On,{session:d,participantId:t.participantId,displayName:t.displayName,accessMode:r.accessMode,presetOverrides:t.presetOverrides,customScales:t.customScales}));await Sn(d,l,s,a);}function mc(e,t=Date.now()){let n=t-e,o=Math.floor(n/6e4);return o<60?`${o}m ago`:`${Math.floor(o/60)}h ago`}async function gc(e){return new Promise((t,n)=>{let o=createInterface({input:process.stdin,output:process.stderr}),r=()=>{process.stderr.write(`Select [1-${e}]: `),o.question("",i=>{let s=parseInt(i.trim(),10);Number.isInteger(s)&&s>=1&&s<=e?(o.close(),t(s)):(process.stderr.write(`Invalid choice \u2014 enter a number between 1 and ${e}.
27
+ `),r());});};o.on("close",()=>n(new Error("stdin closed"))),r();})}async function os(e,t){let n;try{n=await ce(e.relayUrl,t.roomCode);}catch(a){if(a instanceof je&&a.reason==="unknown-room")return await pn({clearLastSession:()=>un(t.roomUuid),logger:console,exit:process.exit});console.error("Could not reach relay \u2014 try again later."),process.exit(0);}n.accessMode==="password"&&!t.passwordHash&&(console.error(`Password changed \u2014 rejoin with: hnch join ${t.roomCode} --password`),fn(t.roomUuid),process.exit(0)),console.error(`Rejoining room ${t.roomCode}\u2026`),console.error("");let o=mn(),r=gn({room:{roomCode:t.roomCode,roomUuid:t.roomUuid},wasIn:()=>true,typedPassword:false}),i=await Ct({...he(e),roomCode:t.roomCode,roomUuid:t.roomUuid,passwordHash:t.passwordHash,...rn(e),onRejection:hn(o,r)});r.bind(i),ln({roomCode:i.roomCode,roomUuid:i.roomUuid,lastSeenAt:Date.now(),...t.passwordHash!==void 0&&{passwordHash:t.passwordHash}});let s=render(kn.createElement(On,{session:i,participantId:e.participantId,displayName:e.displayName,accessMode:n.accessMode,presetOverrides:e.presetOverrides,customScales:e.customScales}));await Sn(i,s,o,r);}async function hc(){let e=await le(),t=cn();if(t.length===0&&(console.error("No recent session to resume."),process.exit(0)),t.length===1)return os(e,t[0]);let n=Date.now();process.stderr.write(`Recent rooms:
28
+ `);for(let[r,i]of t.entries()){let s=mc(i.lastSeenAt,n);process.stderr.write(` ${r+1}. ${i.roomCode} (${s})
28
29
  `);}process.stderr.write(`
29
- `);let o;try{o=await Vd(t.length);}catch{console.error("No selection made."),process.exit(1);}return Ls(e,t[o-1])}async function Yd(e){if(!(e.name!==void 0||e.relayUrl!==void 0||e.scale!==void 0||e.sessionName!==void 0||e.password!==void 0||e.color!==void 0)){let o=await le(),{waitUntilExit:r}=render(wn.createElement(Ns,{presetOverrides:o.presetOverrides,customScales:o.customScales}));await r(),process.exit(0);}let n={};if(e.name!==void 0&&(n.displayName=e.name),e.relayUrl!==void 0&&(n.relayUrl=e.relayUrl),e.scale!==void 0){if(e.scale!==""){let o=je();if(!en(e.scale,o.presetOverrides,o.customScales)){console.error(`Unknown scale: "${e.scale}". Builtin IDs: ${Object.keys(de).join(", ")}`);return}}n.defaultScale=e.scale;}if(e.sessionName!==void 0&&(n.defaultSessionName=e.sessionName),e.password!==void 0&&(n.defaultPassword=e.password),e.color!==void 0){let o=e.color.startsWith("#")||e.color===""?e.color:e.color.toLowerCase();o!==""&&Be(o)===null&&(console.error(`Invalid color: "${e.color}". Pass a palette key or #rrggbb hex literal.`),process.exit(1)),n.avatarColor=o;}Ct(n),console.log("Config updated.");}var Bs=Ud(hideBin(process.argv)).scriptName("hnch").usage("$0 <command> \u2014 terminal pointing poker").command("create","Create a new room",e=>e.option("name",{type:"string",describe:"Session name"}).option("password",{type:"boolean",describe:"Protect room with a password"}).option("scale",{type:"string",describe:"Estimation scale ID (fibonacci, t-shirt, powers-of-2, linear, risk, or custom-<id>)"}),e=>{Hd(e).catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("join <code>","Join an existing room",e=>e.positional("code",{type:"string",demandOption:true,describe:"6-character room code"}).option("password",{type:"boolean",describe:"Room requires a password",default:false}),e=>{jd(e).catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("resume","Rejoin your last session",e=>e,()=>{Jd().catch(e=>{console.error(e instanceof Error?e.message:e),process.exit(1);});}).command("config","View or update CLI config",e=>e.option("name",{type:"string",describe:"Set display name"}).option("relay-url",{type:"string",describe:"Set relay URL"}).option("scale",{type:"string",describe:"Set default estimation scale ID (empty string clears)"}).option("session-name",{type:"string",describe:"Set default session name (empty string clears)"}).option("password",{type:"boolean",describe:"Set default password prompt on (--password) or off (--no-password)"}).option("color",{type:"string",describe:'Set avatar color: a palette key (e.g. "blue", "racing-green") or a #rrggbb hex literal'}),e=>{Yd(e).catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("agenda","Manage the pre-session story agenda",e=>e.command("add","Add an agenda item",t=>t.option("title",{type:"string",describe:"Story title"}).option("ticket",{type:"string",describe:"Issue tracker reference (e.g. PROJ-123)"}).option("description",{type:"string",describe:"Story description"}).check(n=>{if(!n.title?.trim()&&!n.ticket?.trim())throw new Error("At least one of --title or --ticket is required");return true}),t=>{Os(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).command("list","List agenda items in order",t=>t,()=>{Ds().catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("skip <id>","Mark an agenda item as skipped",t=>t.positional("id",{type:"string",demandOption:true,describe:"Agenda item ID"}),t=>{_s(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).command("cancel <id>","Soft-delete (cancel) an agenda item",t=>t.positional("id",{type:"string",demandOption:true,describe:"Agenda item ID"}),t=>{Ms(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).command("mv <id>","Reorder an agenda item (--before <id> | --after <id>)",t=>t.positional("id",{type:"string",demandOption:true,describe:"Agenda item ID to move"}).option("before",{type:"string",describe:"sortKey of item that should come before the moved item"}).option("after",{type:"string",describe:"sortKey of item that should come after the moved item"}).check(n=>{if(n.before!==void 0&&n.after!==void 0)throw new Error("--before and --after are mutually exclusive");if(n.before===void 0&&n.after===void 0)throw new Error("Specify either --before <id> or --after <id>");return true}),t=>{$s(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).demandCommand(1,"Specify an agenda subcommand: add, list, skip, cancel, mv").strict().help(),()=>{}).demandCommand(1,"Specify a command: create, join, resume, config, or agenda").strict().help(),Co=hideBin(process.argv);(Co.length===0||Co.length===1&&Co[0]==="--")&&(Bs.showHelp(),process.exit(0));Bs.parse();
30
+ `);let o;try{o=await gc(t.length);}catch{console.error("No selection made."),process.exit(1);}return os(e,t[o-1])}async function Sc(e){if(!(e.name!==void 0||e.relayUrl!==void 0||e.scale!==void 0||e.sessionName!==void 0||e.password!==void 0||e.color!==void 0)){let o=await le(),{waitUntilExit:r}=render(kn.createElement(Xi,{presetOverrides:o.presetOverrides,customScales:o.customScales}));await r(),process.exit(0);}let n={};if(e.name!==void 0&&(n.displayName=e.name),e.relayUrl!==void 0&&(n.relayUrl=e.relayUrl),e.scale!==void 0){if(e.scale!==""){let o=Ve();if(!nn(e.scale,o.presetOverrides,o.customScales)){console.error(`Unknown scale: "${e.scale}". Builtin IDs: ${Object.keys(de).join(", ")}`);return}}n.defaultScale=e.scale;}if(e.sessionName!==void 0&&(n.defaultSessionName=e.sessionName),e.password!==void 0&&(n.defaultPassword=e.password),e.color!==void 0){let o=e.color.startsWith("#")||e.color===""?e.color:e.color.toLowerCase();o!==""&&Ue(o)===null&&(console.error(`Invalid color: "${e.color}". Pass a palette key or #rrggbb hex literal.`),process.exit(1)),n.avatarColor=o;}wt(n),console.log("Config updated.");}var is=qi(lc(hideBin(process.argv)),zi).scriptName("hnch").usage("$0 <command> \u2014 terminal pointing poker").command("create","Create a new room",e=>e.option("name",{type:"string",describe:"Session name"}).option("password",{type:"boolean",describe:"Protect room with a password"}).option("scale",{type:"string",describe:"Estimation scale ID (fibonacci, t-shirt, powers-of-2, linear, risk, or custom-<id>)"}),e=>{fc(e).catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("join <code>","Join an existing room",e=>e.positional("code",{type:"string",demandOption:true,describe:"6-character room code"}).option("password",{type:"boolean",describe:"Room requires a password",default:false}),e=>{pc(e).catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("resume","Rejoin your last session",e=>e,()=>{hc().catch(e=>{console.error(e instanceof Error?e.message:e),process.exit(1);});}).command("config","View or update CLI config",e=>e.option("name",{type:"string",describe:"Set display name"}).option("relay-url",{type:"string",describe:"Set relay URL"}).option("scale",{type:"string",describe:"Set default estimation scale ID (empty string clears)"}).option("session-name",{type:"string",describe:"Set default session name (empty string clears)"}).option("password",{type:"boolean",describe:"Set default password prompt on (--password) or off (--no-password)"}).option("color",{type:"string",describe:'Set avatar color: a palette key (e.g. "blue", "racing-green") or a #rrggbb hex literal'}),e=>{Sc(e).catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("agenda","Manage the pre-session story agenda",e=>e.command("add","Add an agenda item",t=>t.option("title",{type:"string",describe:"Story title"}).option("ticket",{type:"string",describe:"Issue tracker reference (e.g. PROJ-123)"}).option("description",{type:"string",describe:"Story description"}).check(n=>{if(!n.title?.trim()&&!n.ticket?.trim())throw new Error("At least one of --title or --ticket is required");return true}),t=>{Qi(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).command("list","List agenda items in order",t=>t,()=>{Zi().catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1);});}).command("skip <id>","Mark an agenda item as skipped",t=>t.positional("id",{type:"string",demandOption:true,describe:"Agenda item ID"}),t=>{es(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).command("cancel <id>","Soft-delete (cancel) an agenda item",t=>t.positional("id",{type:"string",demandOption:true,describe:"Agenda item ID"}),t=>{ts(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).command("mv <id>","Reorder an agenda item (--before <id> | --after <id>)",t=>t.positional("id",{type:"string",demandOption:true,describe:"Agenda item ID to move"}).option("before",{type:"string",describe:"sortKey of item that should come before the moved item"}).option("after",{type:"string",describe:"sortKey of item that should come after the moved item"}).check(n=>{if(n.before!==void 0&&n.after!==void 0)throw new Error("--before and --after are mutually exclusive");if(n.before===void 0&&n.after===void 0)throw new Error("Specify either --before <id> or --after <id>");return true}),t=>{ns(t).catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1);});}).demandCommand(1,"Specify an agenda subcommand: add, list, skip, cancel, mv").strict().help(),()=>{}).demandCommand(1,"Specify a command: create, join, resume, config, or agenda").strict().help(),ko=hideBin(process.argv);(ko.length===0||ko.length===1&&ko[0]==="--")&&(is.showHelp(),process.exit(0));is.parse();