{"release_id":"01a1998d-9802-0000-b0f7-33a23307f4ed","chunk_id":"01a1998d-9818-7e33-bf50-634b0f8efb81","file":"BGKgPvfj.mjs","mappings":"qTASO,MAAMA,EAAuB,EAE9BC,EAAY,uBACZC,EAAc,8BAGpB,SAASC,GAAwB,CAChC,GAAI,CACH,OAAO,OAAO,aAAiB,IAAc,KAAO,YACrD,MAAQ,CACP,OAAO,IACR,CACD,CAGO,SAASC,GAA4B,CAC3C,MAAMC,EAAI,OAAOF,EAAA,GAAS,QAAQF,CAAS,GAAK,CAAC,EACjD,OAAO,OAAO,SAASI,CAAC,GAAKA,EAAI,EAAI,KAAK,MAAMA,CAAC,EAAI,CACtD,CAGO,SAASC,GAAwB,CACvC,MAAMC,EAAOH,IAAsB,EACnC,GAAI,CACHD,EAAA,GAAS,QAAQF,EAAW,OAAOM,CAAI,CAAC,CACzC,MAAQ,CAER,CACA,OAAOA,CACR,CAGO,SAASC,EAAkBC,EAAM,KAAK,MAAgB,CAC5D,MAAMC,EAAK,OAAOP,EAAA,GAAS,QAAQD,CAAW,GAAK,CAAC,EACpD,OAAO,OAAO,SAASQ,CAAE,GAAKA,EAAK,GAAKD,EAAMC,EAAK,KACpD,CAEO,SAASC,EAAgBF,EAAM,KAAK,MAAa,CACvD,GAAI,CACHN,EAAA,GAAS,QAAQD,EAAa,OAAOO,CAAG,CAAC,CAC1C,MAAQ,CAER,CACD","names":["THROW_YOUR_OWN_AFTER","COUNT_KEY","DISMISS_KEY","store","beatVotesOnDevice","n","countBeatVote","next","throwOwnDismissed","now","at","dismissThrowOwn"],"sources":["../../../../../../src/lib/beat-voter-next.ts"],"sourcesContent":["/** Beat voters (RAT-528). Client-safe: the device's vote count lives here.\n *\n *  44% of voters leave within 30 minutes, and the only \"make your own\" sat on\n *  closed beats. The hub's first screen had no beat to vote on — only empty\n *  \"your shot\" placeholders when nobody had boosted. Now the spotlight fills\n *  with the top live beats when boosts don't, and from a device's third vote a\n *  live beat asks \"your turn — throw your own\". */\n\n/** The ask comes from this many votes on. */\nexport const THROW_YOUR_OWN_AFTER = 3;\n\nconst COUNT_KEY = 'beat_votes_on_device';\nconst DISMISS_KEY = 'beat_throw_own_dismissed_at';\nconst DISMISS_MS = 24 * 60 * 60 * 1000;\n\nfunction store(): Storage | null {\n\ttry {\n\t\treturn typeof localStorage === 'undefined' ? null : localStorage;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/** Votes this device has cast on beats (counted where they are cast). */\nexport function beatVotesOnDevice(): number {\n\tconst n = Number(store()?.getItem(COUNT_KEY) ?? 0);\n\treturn Number.isFinite(n) && n > 0 ? Math.floor(n) : 0;\n}\n\n/** A vote was counted. Returns the new total. */\nexport function countBeatVote(): number {\n\tconst next = beatVotesOnDevice() + 1;\n\ttry {\n\t\tstore()?.setItem(COUNT_KEY, String(next));\n\t} catch {\n\t\t// storage full / blocked — the ask just won't appear\n\t}\n\treturn next;\n}\n\n/** \"not now\" keeps the ask away for a day. */\nexport function throwOwnDismissed(now = Date.now()): boolean {\n\tconst at = Number(store()?.getItem(DISMISS_KEY) ?? 0);\n\treturn Number.isFinite(at) && at > 0 && now - at < DISMISS_MS;\n}\n\nexport function dismissThrowOwn(now = Date.now()): void {\n\ttry {\n\t\tstore()?.setItem(DISMISS_KEY, String(now));\n\t} catch {\n\t\t// nothing to keep it in; it hides for this page only\n\t}\n}\n"],"version":3}