1import{r as i,j as tt}from"./chunk-UVKPFVEO-D9yzbXen.js";import{pushEvent as k,getTodayStr as _,getLatestEventTime as E,loadData as h,createDefaultData as q,saveData as B,clearData as et,STORAGE_KEY as st}from"./storage-DZSlhtS0.js";import{R as x,e as nt}from"./useFirestoreConfig-CJ5Wsy2e.js";import{COLLECTABLE_STAMP_IDS as at,STAMP_NAMES as ot,STAMP_LOCATIONS as S,STAMP_IDS as rt,STAMP_NAME_MAP as D,STAMPS as ct,refreshStampsFromFirestore as it}from"./stamp-data-d6wEFa4g.js";function C(t){return t?typeof t.status=="string"?t.status:t.collected?t.consumed?"consumed":"collected":"not_collected":"not_collected"}function O(t){return at.includes(t)}function lt(t){return C(t)!=="not_collected"}function K(t){return Object.entries(t.stamps).filter(([e,n])=>O(e)&&C(n)==="collected").length}function ut(t){return Object.entries(t.stamps).filter(([e,n])=>O(e)&<(n)).length}function ft(t){return K(t)}function dt(t){const e=_();let n=0;for(const[o,l]of Object.entries(t.stamps))O(o)&&C(l)==="collected"&&E(l,"collected")?.startsWith(e)&&n++;return n}function mt(t){return Object.entries(t.stamps).filter(([e,n])=>O(e)&&C(n)==="consumed").length}function F(t){return Math.floor(mt(t)/x)}function gt(t){const e=yt(t),n=new Date().toISOString();return e.forEach(o=>{k(t.stamps[o],"consumed",n)}),e}function yt(t){return Object.entries(t.stamps).filter(([e,n])=>O(e)&&C(n)==="collected").sort((e,n)=>{const o=E(e[1],"collected"),l=E(n[1],"collected"),f=o?new Date(o).getTime():0,c=l?new Date(l).getTime():0;return f-c}).slice(0,x).map(([e])=>e)}function z(){if(typeof window>"u"){console.log("log_stamp: å¿
é å¨ç覽å¨ç°å¢å·è¡");return}const t=h();console.groupCollapsed("log_stamp â Stamp Rally Summary"),console.log("Total collected:",t.totalCollected),console.log("Daily redeem entries:",t.dailyRedeem||{}),console.groupCollapsed("Stamps");const e=Object.keys(t.stamps).sort().map(n=>{const o=parseInt(n.split("_")[1],10)-1,l=ot[o]??n,f=S[n],c=t.stamps[n],p=E(c,"collected")??c.collectedAt??"-",d=E(c,"consumed")??c.consumedAt??"-",P=Array.isArray(c.history)&&c.history.length?c.history.map(A=>`${A.status}@${A.at}`):[];return{index:o+1,id:n,name:l,zone:f?.zone??"-",status:c.status,collectedAt:p,consumedAt:d,history:P.join(", ")}});console.table(e,["index","id","name","status","collectedAt","consumedAt","history"]),console.groupEnd(),console.groupCollapsed("Raw data (stamprally_data)"),console.log(t),console.groupEnd(),console.groupEnd()}function pt(){if(!(typeof window>"u"))try{Object.defineProperty(window,"log_stamp",{configurable:!0,enumerable:!1,writable:!0,value:z})}catch{window.log_stamp=z}}const ht=5e3;function vt(t,e,n,o){const f=(n-t)*Math.PI/180,c=(o-e)*Math.PI/180,p=Math.sin(f/2)**2+Math.cos(t*Math.PI/180)*Math.cos(n*Math.PI/180)*Math.sin(c/2)**2;return 6371e3*2*Math.atan2(Math.sqrt(p),Math.sqrt(1-p))}function St(t,e){const n=S[t];if(!n)return{distance:0,withinRange:!0};const o=vt(e.latitude,e.longitude,n.lat,n.lng);return{distance:o,withinRange:o<=ht}}async function Et(){if(typeof navigator>"u"||!navigator.geolocation)return"unsupported";if(!("permissions"in navigator)||!navigator.permissions?.query)return"unknown";try{return(await navigator.permissions.query({name:"geolocation"})).state}catch{return"unknown"}}function Q(t=9e3){return new Promise((e,n)=>{if(typeof navigator>"u"||!navigator.geolocation){n("UNAVAILABLE");return}navigator.geolocation.getCurrentPosition(o=>{e({latitude:o.coords.latitude,longitude:o.coords.longitude,accuracy:o.coords.accuracy})},o=>{if(o.code===o.PERMISSION_DENIED){n("DENIED");return}if(o.code===o.TIMEOUT){n("TIMEOUT");return}n("UNAVAILABLE")},{timeout:t,maximumAge:3e4,enableHighAccuracy:!0})})}function W(t,e,n,o=!1){const{distance:l,withinRange:f}=St(t,e);if(f)return n?.({status:"ok",message:`ä½ç½®ç¢ºèªæåï¼è·é¢æé»ç´ ${Math.round(l)} å
¬å°º`}),!0;throw n?.({status:"error",message:`è·é¢å¤ªé ï¼${Math.round(l)} å
¬å°ºï¼ï¼è«é è¿æé»å¾å試`}),"TOO_FAR"}function At(t,e,n={}){return new Promise(async(o,l)=>{if(o(!0),!S[t]){o(!0);return}if(n.manualCoords){e?.({status:"checking",message:"æ£å¨ç¨æå座æ¨é©èä½ç½®..."});try{o(W(t,n.manualCoords,e,n.forceValidation))}catch(c){l(c)}return}if(typeof navigator>"u"||!navigator.geolocation){o(!0);return}e?.({status:"checking",message:"æ£å¨ç¢ºèªä½ çä½ç½®..."});try{const c=await Q();o(W(t,c,e,n.forceValidation))}catch(c){e?.(c==="TIMEOUT"?{status:"error",message:"å®ä½é¾æï¼è«é試"}:c==="UNAVAILABLE"?{status:"error",message:"æ¤è£ç½®ä¸æ¯æ´å®ä½ï¼è«æ¹ç¨æååº§æ¨æ¸¬è©¦"}:{status:"error",message:"ç¡æ³åå¾ä½ç½®ï¼è«ç¢ºèªå·²éå
1å®ä½æ¬é"}),l(c)}})}function L(t,e=new Date){if(!t)return{isHomepageOpen:!1,isActivityOpen:!1,homepagePhase:"loading",activityPhase:"loading",message:"æ´»åè³è¨è¼å ¥ä¸â¦"};const n=e>=t.webStart&&e<=t.webEnd,o=e>=t.eventStart&&e<=t.eventEnd,l=e<t.webStart?"before":e>t.webEnd?"after":"during",f=e<t.eventStart?"before":e>t.eventEnd?"after":"during";let c;return!n&&!o?e<t.webStart?c="æ´»åå°æªéå§ï¼æ¬è«æå¾ ï¼":c="æ´»åå·²çµæï¼æè¬æ¨çåèï¼":n&&!o&&(e<t.eventStart?c="æ´»åå³å°éå§ï¼ç®åå éæ¾ç覽è³è¨ã":c="éç« æ´»åå·²çµæï¼æè¬æ¨çåèï¼"),{isHomepageOpen:n,isActivityOpen:o,homepagePhase:l,activityPhase:f,message:c}}const X=i.createContext(null);function Mt({children:t}){const[e,n]=i.useState(q),[o,l]=i.useState(!1),[f,c]=i.useState({visible:!1,icon:"",title:"",subtitle:"",visualStyle:"default",status:void 0}),[p,d]=i.useState(null),[P,A]=i.useState(null),[N,w]=i.useState("unknown"),{schedule:b,loading:$}=nt(),[v,I]=i.useState(()=>L(null));i.useEffect(()=>{if(I(L(b)),!b)return;const s=setInterval(()=>{const a=L(b);I(r=>r.isHomepageOpen===a.isHomepageOpen&&r.isActivityOpen===a.isActivityOpen&&r.homepagePhase===a.homepagePhase&&r.activityPhase===a.activityPhase&&r.message===a.message?r:a)},6e4);return()=>clearInterval(s)},[b]),i.useEffect(()=>{let s=!0,a=null;async function r(){await it(),s&&n(h())}return a=setTimeout(()=>{r()},1200),()=>{s=!1,a&&clearTimeout(a)}},[]),i.useEffect(()=>{const s=h(),a=_();let r=!1;for(const[u,y]of Object.entries(s.stamps))if(y.status==="consumed"){const m=E(y,"consumed");m&&!m.startsWith(a)&&(k(y,"repeatable"),r=!0)}n(s),l(!0),r&&B(s)},[]),i.useEffect(()=>{let s=!0,a=null;async function r(){if(!(typeof navigator>"u"||!navigator.permissions?.query))try{a=await navigator.permissions.query({name:"geolocation"}),s&&w(a.state),a.onchange=()=>{s&&w(a.state)}}catch{}}return r(),()=>{s=!1,a&&(a.onchange=null)}},[]),i.useEffect(()=>{function s(r){try{if(r.key!==st)return;n(h())}catch{}}window.addEventListener("storage",s);let a=null;try{typeof BroadcastChannel<"u"&&(a=new BroadcastChannel("stamprally_data"),a.addEventListener("message",r=>{try{const u=r.data;if(!u)return;(u.type==="update"||u.type==="clear")&&n(h())}catch{}}))}catch{}return()=>{window.removeEventListener("storage",s),a&&a.close()}},[]),i.useEffect(()=>{try{pt()}catch{}},[]);const M=i.useCallback(s=>{n(s),B(s)},[]),g=i.useCallback((s,a,r,u)=>{c({visible:!0,icon:s,title:a,subtitle:r,onClose:u?.onClose,actionLabel:u?.actionLabel,visualStyle:u?.visualStyle??"default",status:u?.status})},[]),V=i.useCallback(()=>{c(s=>({...s,visible:!1})),d(null)},[]),G=i.useCallback(async()=>{d({status:"checking",message:"æ£å¨è«æ±å®ä½æ¬é..."});try{const s=await Q(5e3);return A(s),w("granted"),d({status:"ok",message:s.accuracy?`å·²åå¾ç®åä½ç½®ï¼å®ä½ç²¾åº¦ç´ ${Math.round(s.accuracy)} å ¬å°º`:"å·²åå¾ç®åä½ç½®"}),s}catch(s){console.error("GPS error:",s);const a=await Et();throw w(a==="denied"?"unknown":a),d(s==="TIMEOUT"?{status:"error",message:"å®ä½é¾æï¼è«é試"}:s==="UNAVAILABLE"?{status:"error",message:"æ¤è£ç½®ä¸æ¯æ´å®ä½ï¼è«æ¹ç¨æååº§æ¨æ¸¬è©¦"}:s==="DENIED"?{status:"error",message:"å®ä½æ¬ééæçµï¼è«æåéç½®æ¬éå¾å試"}:{status:"error",message:"ç¡æ³åå¾ä½ç½®ï¼è«ç¢ºèªå·²éåå®ä½æ¬é"}),s}},[]),H=i.useCallback(async(s,a)=>{if(!rt.includes(s))return g("â","ç¡æçéç« é£çµ","æ¤ QR Code é©è失æï¼è«ç¢ºèªæ¯å¦çºæ´»å宿¹ç«çã",a?.overlayOptions),!1;const r=h(),u=r.stamps[s]?.status??"not_collected";if(u==="consumed"){const T=D[s]??s;return g(S[s]?.icon??"ð´","åç« å·²å®æå æï¼",`æ¨ä»æ¥å·²ä½¿ç¨ã${T}ãåç« æåçåµãæ¤æé»å°å¨ææ¥åæ¨ 00:00 éç½®çæ ï¼æ¡è¿å次å便¶éï¼`,{...a?.overlayOptions,status:"consumed"}),!1}else if(u==="collected"){const T=D[s]??s;return g(S[s]?.icon??"ð´","æ¤å°å·²æ¢ç´¢å®æï¼",`æ¨å·²ææã${T}ãçåç« åï¼æéå°åæ¾æ¾å ¶ä»å°é»ç¹¼çºæ¶éå§ï¼`,a?.overlayOptions),!1}if(a?.gpsOverride==="force_fail")return d({status:"error",message:"éç¼æ¨¡å¼ï¼å·²è¨å®ç¡è¦ GPSï¼å¼·å¶æ¶é失æ"}),g("â","éç« å¤±æ","éç¼æ¨¡å¼ï¼å·²è¨å®çºç¡è¦ GPS 並強å¶å¤±æã",a?.overlayOptions),!1;try{a?.gpsOverride==="force_success"?d({status:"ok",message:"éç¼æ¨¡å¼ï¼å·²è¨å®ç¡è¦ GPSï¼å¼·å¶æ¶éæå"}):a?.skipGpsValidation?d(null):await At(s,d,{manualCoords:a?.manualCoords,forceValidation:a?.forceGpsValidation})}catch{}a?.manualCoords&&A(a.manualCoords);const y=new Date().toISOString(),m={...r};m.stamps={...m.stamps};const R={...m.stamps[s]??{status:"not_collected",history:[]}};m.stamps[s]=k(R,"collected",y),m.totalCollected=ut(m),M(m);const J=D[s]??s,Z=S[s]?.icon||"ð´";return g(Z,"æ¢ç´¢æåï¼",`æåç²å¾ã${J}ãåç« ï¼ 2ç®åå·²æ¶é ${m.totalCollected} / ${ct.length} ååç« åï¼`,{...a?.overlayOptions,visualStyle:"stamp-success",status:"collected"}),!0},[M,g]),U=i.useCallback((s,a)=>
2{if(!s)return;const r=h(),u=gt(r);r.dailyRedeem[_()]=s,M(r);const y=F(r);a?.skipOverlay||g("ð",`第 ${y} æ¬¡å ææåï¼`,`æåä½ åå¾éå®èªæµ·ææ¨èªæåï¼ 3å·²æ¶è ${u.length} åç« ï¼å©é¤ç« ç¹¼çºç´¯ç©ä¸ã`)},[M,g]),j=i.useCallback(()=>{et(),n(q()),g("ð","è³æå·²æ¸ é¤","ææéç« é²åº¦å·²éç½®ã")},[g]),Y=i.useMemo(()=>{const s=_(),a=K(e),r=ft(e),u=dt(e),y=!!e.dailyRedeem[s],m=F(e),R=r>=x&&!y;return{data:e,hydrated:o,totalCollected:a,availableCount:r,dailyCount:u,todayRedeemed:y,redeemCount:m,canRedeem:R,overlay:f,gpsResult:p,currentPosition:P,locationPermission:N,isHomepageOpen:v.isHomepageOpen,isActivityOpen:v.isActivityOpen,activityMessage:v.message,homepagePhase:v.homepagePhase,activityPhase:v.activityPhase,scheduleLoading:$,collectStamp:H,requestLocationPermission:G,confirmRedeem:U,clearAllData:j,showOverlay:g,closeOverlay:V}},[e,o,f,p,P,N,v,$,H,G,U,j,g,V]);return tt.jsx(X.Provider,{value:Y,children:t})}function Tt(){const t=i.useContext(X);if(!t)throw new Error("useStampRally must be used within StampRallyProvider");return t}export{Mt as S,ut as g,Tt as u};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.