PageSourceSearch

https://shunpass.vercel.app/shunpass/_next/static/chunks/3r-a_5o5rb1zc.js

js shunpass.vercel.app collected 2026-10-03 07:42:15 UTC 34,632 bytes, 1 lines download raw bytes

1(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,52683,e=>{"use strict";var t=e.i(43476),n=e.i(71645);let r="/shunpass";function l(e){return"/"===e?r:`${r}${e}`}function a(e){return{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.75,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0}}function s({size:e=24}){return(0,t.jsx)("svg",{...a(e),children:(0,t.jsx)("path",{d:"M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14"})})}function i({size:e=24}){return(0,t.jsxs)("svg",{...a(e),children:[(0,t.jsx)("rect",{x:"9",y:"9",width:"12",height:"12",rx:"3"}),(0,t.jsx)("path",{d:"M5 15V5a2 2 0 012-2h8"})]})}function o({size:e=14}){return(0,t.jsx)("svg",{...a(e),children:(0,t.jsx)("path",{d:"M20 6L9 17l-5-5"})})}function c({size:e=20}){return(0,t.jsx)("svg",{...a(e),children:(0,t.jsx)("path",{d:"M15 18l-6-6 6-6"})})}function d(e){if(e.length<=4)return"•".repeat(e.length);let t=e.slice(-4);return`••••${t}`}let u="qr_code",x=l("/wasm/");async function p(){let e,t="function"==typeof(e=globalThis.BarcodeDetector)?e:null;if(null===t)return null;try{if(!(await t.getSupportedFormats()).includes(u))return null;let e=new t({formats:[u]});return{detect:async t=>(await e.detect(t)).map(e=>e.rawValue)}}catch{return null}}async function f(){try{let{BarcodeDetector:t,prepareZXingModule:n}=await e.A(95375);n({overrides:{locateFile:(e,t)=>e.endsWith(".wasm")?`${x}${e}`:`${t}${e}`}});let r=new t({formats:[u]});return{detect:async e=>(await r.detect(e)).map(e=>e.rawValue)}}catch{return null}}async function h(){let e=await p();if(null!==e)return{ok:!0,value:e,engine:"native"};let t=await f();return null!==t?{ok:!0,value:t,engine:"polyfill"}:{ok:!1,reason:"decoder-unavailable"}}let m=new Set(["shunsugu.jp","www.shunsugu.jp"]),g=new Set(["http:","https:"]),b=new Set(["/chance","/chance/"]),j=/^[A-Za-z0-9_-]{1,64}$/;function v(e){let t,n=e.trim();try{t=new URL(n)}catch{return{ok:!1,reason:"invalid-url"}}if(!g.has(t.protocol))return{ok:!1,reason:"invalid-url"};if(!m.has(t.hostname.toLowerCase()))return{ok:!1,reason:"wrong-host"};if(!b.has(t.pathname))return{ok:!1,reason:"wrong-path"};let r=t.searchParams.get("code"),l=t.searchParams.get("serial");return r&&l?j.test(r)&&j.test(l)?{ok:!0,value:{code:r,serial:l}}:{ok:!1,reason:"invalid-format"}:{ok:!1,reason:"missing-params"}}var w=e.i(47167);function N(e){if("string"!=typeof e)return null;let t=e.trim();return""===t?null:t}let y={siteUrl:function(e){let t=N(e);if(null===t)throw Error("NEXT_PUBLIC_SHUNPASS_SITE_URL が未設定です。ローカルでは .env.local に、Vercel では環境変数に設定してください(例: https://example.com/shunpass)。");return t.replace(/\/+$/,"")}("https://seizu.dev/shunpass"),contactEmail:N(w.default.env.NEXT_PUBLIC_SHUNPASS_CONTACT_EMAIL),contactUrl:N(w.default.env.NEXT_PUBLIC_SHUNPASS_CONTACT_URL),repositoryUrl:N("https://github.com/seizu-dev/shunpass"),developerUrl:N("https://seizu.dev"),googleSiteVerification:N("0NbGtb9QChjjleqrSULxykfz1Cn6HIgU344VgnGgZ9M")}
1,k={"invalid-url":"URLとして読み取れませんでした","wrong-host":"旬すぐ(shunsugu.jp)のURLではありません","wrong-path":"/chance のURLではありません","missing-params":"code または serial がURLに含まれていません","invalid-format":"code または serial の形式が不正です"},S={"invalid-input":"入力の形式が不正です",timeout:"旬すぐ側からの応答がタイムアウトしました。時間をおいて再試行してください","upstream-error":"旬すぐ側でエラーが発生しました","csrf-not-found":"旬すぐ側の仕様が変わった可能性があります(CSRFトークンを取得できません)","csrf-rejected":"旬すぐ側の仕様が変わった可能性があります(CSRFトークンが拒否されました)","rate-limited":"リクエストが多すぎます。しばらく待ってから再試行してください","unexpected-response":"旬すぐ側の応答が想定外の形式でした","network-error":"旬すぐ側に接続できませんでした","internal-error":"サーバ内部でエラーが発生しました",aborted:"中断されました"},C={"insecure-context":"HTTPS で開いていないためカメラを使えません。URL貼り付けをご利用ください","no-camera-api":"このブラウザはカメラ入力に対応していません。URL貼り付けをご利用ください","decoder-unavailable":"この環境ではQRコードを読み取れませんでした。URL貼り付けをご利用ください","permission-denied":"カメラの使用が許可されていません。ブラウザの権限設定をご確認ください","no-camera-found":"利用できるカメラが見つかりませんでした","camera-busy":"カメラを他のアプリが使用中の可能性があります。閉じてから再試行してください","camera-error":"カメラを起動できませんでした"},R={"not-configured":"Google Tasks 連携が設定されていません","script-load-failed":"Google の認証スクリプトを読み込めませんでした","auth-cancelled":"認可されませんでした。ポップアップがブロックされていないかご確認ください",unauthorized:"Google の認可が切れました。もう一度「Google Tasks に追加」を押してください","rate-limited":"Google 側のリクエスト上限に達しました。時間をおいて再試行してください","network-error":"Google に接続できませんでした","api-error":"Google Tasks への書き込みに失敗しました"},T=y.siteUrl.replace(/^https?:\/\//,"");function U({isRunning:e,knownSerials:r,onSubmit:a,onAbort:i}){let[o,c]=(0,n.useState)("idle"),[u,x]=(0,n.useState)(null),[p,f]=(0,n.useState)(null),[m,g]=(0,n.useState)([]),b=(0,n.useRef)(null),j=(0,n.useRef)(null),w=(0,n.useRef)(null),N=(0,n.useRef)(null),y=(0,n.useRef)(null),S=(0,n.useRef)(0),R=(0,n.useRef)(0),E=(0,n.useRef)(new Set),L=(0,n.useRef)(r),K=(0,n.useRef)(null),$=(0,n.useRef)(0),A=(0,n.useRef)("idle");function _(e,t){null!==y.current&&window.clearTimeout(y.current),S.current+=1,f({id:S.current,text:e,tone:t}),y.current=window.setTimeout(()=>{y.current=null,f(null)},2500)}(0,n.useEffect)(()=>{L.current=r},[r]);let z=(0,n.useCallback)(()=>{$.current+=1,null!==N.current&&(window.clearTimeout(N.current),N.current=null),w.current=null,R.current=0,K.current=null;let e=j.current;null!==e&&(e.getTracks().forEach(e=>e.stop()),j.current=null);let t=b.current;null!==t&&(t.srcObject=null),A.current="idle",c("idle")},[]);async function P(){N.current=null;let e=w.current,t=b.current;if(null===e||null===t)return;let n=250;if(t.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&t.videoWidth>0)try{let r=await e.detect(t);for(let e of(R.current=0,r))!function(e){let t=v(e);if(!t.ok)return _(k[t.reason],"warn");let{serial:n}=t.value;if(E.current.has(n)||L.current.has(n)){K.current!==n&&_("読み取り済みのQRです","warn"),K.current=n;return}K.current=n,E.current.add(n),g(e=>[...e,t.value]),_(`読み取りました(${E.current.size}件目)`,"ok")}(e);r.length>0&&(n=2e3)}catch{if(R.current+=1,R.current>=5){z(),x("decoder-unavailable");return}}null!==w.current&&(N.current=window.setTimeout(()=>{P()},n))}async function M(){let e;if("idle"!==A.current)return;A.current="starting",c("starting"),x(null);let t=$.current,n=window.isSecureContext?"function"!=typeof navigator.mediaDevices?.getUserMedia?"no-camera-api":null:"insecure-context";if(null!==n){A.current="idle",c("idle"),x(n);return}let r=await h();if(t!==$.current)return;if(!r.ok){A.current="idle",c("idle"),x(r.reason);return}try{e=await navigator.mediaDevices.getUserMedia({video:{facingMode:{ideal:"environment"},width:{ideal:1280},height:{ideal:720}},audio:!1})}catch(e){if(t!==$.current)return;A.current="idle",c("idle"),x(function(e){switch(e instanceof DOMException?e.name:""){case"NotAllowedError":case"SecurityError":return"permission-denied";case"NotFoundError":case"OverconstrainedError":return"no-camera-found";case"NotReadableError":case"AbortError":return"camera-busy";default:return"camera-error"}}(e));return}let l=b.current;
1if(t!==$.current||null===l)return void e.getTracks().forEach(e=>e.stop());j.current=e,w.current=r.value,R.current=0,l.muted=!0,l.srcObject=e;try{await l.play()}catch{}t===$.current&&(A.current="scanning",c("scanning"),P())}(0,n.useEffect)(()=>()=>{null!==y.current&&window.clearTimeout(y.current),z()},[z]),(0,n.useEffect)(()=>{function e(){"hidden"===document.visibilityState&&z()}return document.addEventListener("visibilitychange",e),()=>{document.removeEventListener("visibilitychange",e)}},[z]);let O=m.length>0&&!e,I="idle"!==o;return(0,t.jsxs)("div",{className:"flex flex-col gap-3",children:[(0,t.jsxs)("div",{className:"relative aspect-[4/3] overflow-hidden rounded-[28px] bg-[#2b2724]",children:[(0,t.jsx)("video",{ref:b,className:"h-full w-full object-cover",playsInline:!0,muted:!0,autoPlay:!0}),I?(0,t.jsx)("div",{className:"pointer-events-none absolute inset-0 grid place-items-center",children:(0,t.jsx)("div",{className:"aspect-square w-[58%] rounded-[24px] border-[3px] border-bg/80"})}):(0,t.jsxs)("div",{className:"absolute inset-0 flex flex-col items-center justify-center gap-[18px] px-6 text-center text-[13px] leading-relaxed text-bg/70",children:[(0,t.jsx)("p",{children:"下の「カメラ起動」でQRの読み取りを始めます"}),(0,t.jsxs)("div",{className:"hidden flex-col items-center gap-[10px] pointer-fine:flex",children:[(0,t.jsx)("img",{src:l("/site-url-qr.svg"),alt:"旬パスのURLのQRコード",width:156,height:156,className:"rounded-[10px] bg-white p-2"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-[13px] font-semibold text-bg/85",children:"スマホで開く"}),(0,t.jsx)("div",{className:"mt-0.5 font-mono text-[12px] text-bg/60",children:T})]})]})]}),p&&(0,t.jsx)("div",{className:"pointer-events-none absolute inset-x-[14px] top-[14px] flex justify-center",children:(0,t.jsx)("span",{className:"ok"===p.tone?"on-accent flash-pop rounded-full px-3 py-1.5 text-center text-[12px] font-semibold":"rounded-full bg-text/70 px-3 py-1.5 text-center text-[12px] font-semibold text-bg",children:p.text},p.id)}),(0,t.jsxs)("div",{className:"absolute bottom-[14px] left-[14px] flex items-center gap-[7px] rounded-full bg-text/55 px-3 py-1.5 text-[12px] text-bg",children:[(0,t.jsx)("span",{className:"scanning"===o?"h-[7px] w-[7px] rounded-full bg-accent2-500":"h-[7px] w-[7px] rounded-full bg-neutral-400"}),"scanning"===o?"読み取り中":"starting"===o?"起動中":"停止中"]})]}),null!==u&&(0,t.jsx)("p",{className:"rounded-[20px] border border-accent-400 bg-surface px-4 py-3 text-[12.5px] leading-[1.5] text-accent-800",children:C[u]}),m.length>0&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:"flex items-center gap-[14px] rounded-[26px] bg-accent2-200 px-4 py-3",children:[(0,t.jsx)("div",{className:"grid h-14 w-14 flex-none place-items-center rounded-full bg-accent2-600 font-heading text-[24px] text-bg",children:m.length}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("div",{className:"text-[15px] font-bold text-accent2-900",children:"件が待機中"}),(0,t.jsx)("div",{className:"text-[12.5px] text-accent2-800 opacity-80",children:"続けてQRをかざせます"})]})]}),(0,t.jsx)("ul",{className:"flex flex-col gap-[10px]",children:[...m].reverse().map((e,n)=>(0,t.jsxs)("li",{className:"flex items-center gap-3 rounded-[26px] bg-surface py-3 pr-3 pl-[14px]",children:[(0,t.jsx)("span",{className:"grid h-[34px] w-[34px] flex-none place-items-center rounded-full bg-bg text-[14px] font-semibold text-neutral-700",children:m.length-n}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("div",{className:"truncate font-mono text-[16px] font-semibold",children:e.code}),(0,t.jsxs)("div",{className:"mt-0.5 truncate font-mono text-[12px] opacity-50",children:["serial ",d(e.serial)]})]}),(0,t.jsx)("button",{type:"button",className:"grid h-14 w-14 flex-none place-items-center rounded-full bg-accent-200 text-accent-800","aria-label":"待機リストから削除",onClick:()=>{var t;return t=e.serial,void(E.current.delete(t),g(e=>e.filter(e=>e.serial!==t)))},children:(0,t.jsx)(s,{size:24})})]},e.serial))}),(0,t.jsx)("button",{type:"button",className:"h-11 self-start rounded-full border border-divider px-5 text-[14px] font-semibold",onClick:function(){E.current.clear(),g([])},children:"すべて消去"})]}),(0,t.jsxs)("p",{className:"mt-[14px] text-[11.5px] leading-[1.6] text-text/55",children:["読み取ったQRの情報と取得したクーポンコードは中継のため当方のサーバーを経由しますが、保存もログ出力もしません。旬すぐ運営とは一切関係ありません。",(0,t.jsx)("a",{className:"text-accent-900 underline underline-offset-2",href:l("/about"),target:"_blank",rel:"noopener noreferrer",children:"データの取り扱い・免責事項"})]}),(0,t.jsx)("div",{className:"bar-fade fixed inset-x-0 bottom-0 z-10",children:(0,t.jsxs)("div",{className:"pb-home mx-auto flex w-full max-w-[480px] gap-[10px] px-[18px] pt-[14px]",children:[(0,t.jsx)("button",{type:"button",className:"h-14 w-[118px] flex-none rounded-full border border-divider text-[15px] font-semibold disabled:opacity-40",disabled:e,onClick:I?z:()=>void M(),children:I?"カメラ停止":"カメラ起動"}),e?(0,t.jsx)("button",{type:"button",className:"h-14 flex-1 rounded-full border border-accent text-[15px] font-semibold text-accent-900",onClick:i,children:"中止"}):(0,t.jsxs)("button",{type:"button",className:"on-accent h-14 flex-1 rounded-full font-heading text-[17px] disabled:opacity-40",disabled:!O,onClick:function(){0===m.length||e||(z(),E.current.clear(),g([]),a(m))},children:[m.length,"件を実行"]})]})})]})}function E({isRunning:e,onSubmit:r,onAbort:a}
1){let[s,i]=(0,n.useState)(""),o=(0,n.useMemo)(()=>{let e,t,n,r,l;return e=s.split("\n"),t=[],n=[],r=new Set,l=0,e.forEach((e,a)=>{let s=e.trim();if(""===s)return;let i=v(s);if(!i.ok)return void n.push({line:a+1,reason:i.reason});if(r.has(i.value.serial)){l+=1;return}r.add(i.value.serial),t.push(i.value)}),{items:t,errors:n,duplicateCount:l}},[s]),c=o.items.length>0&&!e;return(0,t.jsxs)("div",{className:"flex flex-col gap-3",children:[(0,t.jsx)("label",{htmlFor:"chance-url-input",className:"text-[13px] font-semibold",children:"旬すぐのQRが指すURLを貼り付け(1行に1件)"}),(0,t.jsx)("textarea",{id:"chance-url-input",className:"min-h-40 w-full rounded-[26px] border border-divider bg-bg p-4 font-mono text-[14px] disabled:opacity-40",placeholder:"https://shunsugu.jp/chance?code=...&serial=...",value:s,onChange:e=>i(e.target.value),disabled:e}),(0,t.jsxs)("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-[12.5px] text-text/60",children:[(0,t.jsxs)("span",{children:["認識: ",o.items.length," 件"]}),o.duplicateCount>0&&(0,t.jsxs)("span",{children:["重複除外: ",o.duplicateCount," 件"]}),o.errors.length>0&&(0,t.jsxs)("span",{children:["解析失敗: ",o.errors.length," 行"]})]}),o.errors.length>0&&(0,t.jsx)("ul",{className:"flex flex-col gap-1 rounded-[20px] border border-accent-400 bg-surface px-4 py-3 text-[12.5px] leading-[1.5] text-accent-800",children:o.errors.map(e=>(0,t.jsxs)("li",{children:[e.line,"行目: ",k[e.reason]]},e.line))}),(0,t.jsxs)("p",{className:"mt-[14px] text-[11.5px] leading-[1.6] text-text/55",children:["読み取ったQRの情報と取得したクーポンコードは中継のため当方のサーバーを経由しますが、保存もログ出力もしません。旬すぐ運営とは一切関係ありません。",(0,t.jsx)("a",{className:"text-accent-900 underline underline-offset-2",href:l("/about"),target:"_blank",rel:"noopener noreferrer",children:"データの取り扱い・免責事項"})]}),(0,t.jsx)("div",{className:"bar-fade fixed inset-x-0 bottom-0 z-10",children:(0,t.jsx)("div",{className:"pb-home mx-auto w-full max-w-[480px] px-[18px] pt-[14px]",children:e?(0,t.jsx)("button",{type:"button",className:"h-14 w-full rounded-full border border-accent text-[15px] font-semibold text-accent-900",onClick:a,children:"中止"}):(0,t.jsxs)("button",{type:"button",className:"on-accent h-14 w-full rounded-full font-heading text-[17px] disabled:opacity-40",disabled:!c,onClick:()=>r(o.items),children:[o.items.length,"件を実行"]})})})]})}async function L(e){try{if(!navigator.clipboard)return!1;return await navigator.clipboard.writeText(e),!0}catch{return!1}}let K="https://tasks.googleapis.com/tasks/v1";function $(e){return"object"==typeof e&&null!==e}function A(){return"258057693036-ngv5hm4qjd8h7jfqu1i8b3sak7tgdk5n.apps.googleusercontent.com"}let _=null;async function z(){let e=A(),t=await (null!==_?_:_=new Promise(e=>{if(window.google?.accounts?.oauth2)return void e({ok:!0,value:void 0});let t=document.createElement("script");t.src="https://accounts.google.com/gsi/client",t.async=!0,t.defer=!0,t.onload=()=>{window.google?.accounts?.oauth2?e({ok:!0,value:void 0}):e({ok:!1,errorKind:"script-load-failed"})},t.onerror=()=>{e({ok:!1,errorKind:"script-load-failed"})},document.head.appendChild(t)}).then(e=>(e.ok||(_=null),e)));if(!t.ok)return t;if(!window.google?.accounts?.oauth2)return{ok:!1,errorKind:"script-load-failed"};let n=window.google.accounts.oauth2;return new Promise(t=>{let r=!1;n.initTokenClient({client_id:e,scope:"https://www.googleapis.com/auth/tasks",callback:e=>{if(!r){if(r=!0,e.error||!e.access_token)return void t({ok:!1,errorKind:"auth-cancelled"});t({ok:!0,value:e.access_token})}},error_callback:()=>{r||(r=!0,t({ok:!1,errorKind:"auth-cancelled"}))}}).requestAccessToken()})}function P(e){return 401===e||403===e?"unauthorized":429===e?"rate-limited":"api-error"}function M(e){return $(e)&&"string"==typeof e.id&&"string"==typeof e.title}async function O(e){let t,n;try{t=await fetch(`${K}/users/@me/lists?maxResults=100`,{headers:{Authorization:`Bearer ${e}`}})}catch{return{ok:!1,errorKind:"network-error"}}if(!t.ok)return{ok:!1,errorKind:P(t.status)};try{n=await t.json()}catch{return{ok:!1,errorKind:"api-error"}}return $(n)?{ok:!0,value:(Array.isArray(n.items)?n.items:[]).filter(M)}:{ok:!1,errorKind:"api-error"}}async function I(e,t,n,r){let l=n.filter(e=>"hit"===e.status&&!!e.couponCode),a=0,s=0;for(let n=0;n<l.length;n+=1){let i,o=l[n],c=function(e){if(null===e)return;let t=new Date(e);if(Number.isNaN(t.getTime()))return;let n=new Date(t.getTime()+324e5).toISOString().slice(0,10);return`${n}T00:00:00.000Z`}(o.expiresAt);try{i=await fetch(`${K}/lists/${encodeURIComponent(t)}/tasks`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({title:o.couponCode,notes:`商品コード: ${o.itemCo
1de}`,...void 0!==c?{due:c}:{}})})}catch{s+=1,r(n+1);continue}if(!i.ok){if("unauthorized"===P(i.status))return{ok:!1,errorKind:"unauthorized"};s+=1,r(n+1);continue}a+=1,r(n+1)}return{ok:!0,value:{createdCount:a,failedCount:s}}}let B="shunpass.googleTasks.listId";function D({results:e,isRunning:r}){let[l,a]=(0,n.useState)(null),[s,i]=(0,n.useState)([]),[o,c]=(0,n.useState)(""),[d,u]=(0,n.useState)(!1),[x,p]=(0,n.useState)(null),[f,h]=(0,n.useState)(null),[m,g]=(0,n.useState)(null),b=e.filter(e=>"hit"===e.status&&!!e.couponCode);if(""===A()||0===b.length)return null;async function j(){u(!0),h(null),g(null);let e=await z();if(!e.ok){g(e.errorKind),u(!1);return}let t=await O(e.value);if(!t.ok){"unauthorized"===t.errorKind&&a(null),g(t.errorKind),u(!1);return}let n=function(){try{return window.localStorage.getItem(B)}catch{return null}}(),r=t.value.find(e=>e.id===n),l=r?.id??t.value[0]?.id??"";a(e.value),i(t.value),c(l),u(!1)}async function v(){if(null===l||""===o)return;u(!0),h(null),g(null),p({done:0,total:b.length});let e=await I(l,o,b,e=>{p({done:e,total:b.length})});if(p(null),!e.ok){"unauthorized"===e.errorKind&&a(null),g(e.errorKind),u(!1);return}try{window.localStorage.setItem(B,o)}catch{}let{createdCount:t,failedCount:n}=e.value;h(n>0?`${t}件を追加しました(${n}件失敗)`:`${t}件を追加しました`),u(!1)}let w=null!==l;return(0,t.jsxs)("div",{className:"flex min-w-0 flex-1 flex-col gap-2",children:[!w&&(0,t.jsx)("button",{type:"button",className:"h-14 w-full rounded-full border border-divider text-[14px] font-semibold disabled:opacity-40",disabled:d||r,onClick:j,children:"Google Tasks に追加"}),w&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("select",{className:"h-14 w-full rounded-full border border-divider bg-bg px-4 text-[14px] font-semibold text-text disabled:opacity-40",value:o,disabled:d||r,onChange:e=>c(e.target.value),children:s.map(e=>(0,t.jsx)("option",{value:e.id,className:"bg-bg text-text",children:e.title},e.id))}),(0,t.jsxs)("button",{type:"button",className:"on-accent h-14 w-full rounded-full text-[14px] font-semibold disabled:opacity-40",disabled:d||r||""===o,onClick:v,children:["追加(",b.length,"件)"]})]}),x&&(0,t.jsxs)("span",{className:"text-[12px] text-text/70",children:[x.done," / ",x.total," 件"]}),f&&(0,t.jsx)("span",{className:"text-[12px] text-text/70",children:f}),m&&(0,t.jsx)("span",{className:"text-[12px] leading-[1.5] text-accent-800",children:R[m]})]})}let G="flex-none rounded-full bg-neutral-100 px-[10px] py-[3px] text-[11px] whitespace-nowrap text-neutral-800",Q="grid h-[30px] w-[30px] flex-none place-items-center rounded-full text-[13px] font-semibold";function F({jobs:e,isRunning:r,onRetry:l,onAbort:a,onBack:s}){let[u,x]=(0,n.useState)(null),[p,f]=(0,n.useState)(null),h=e.filter(e=>e.result?.status==="hit").map(e=>e.result),m=e.filter(e=>"failed"===e.state||"pending"===e.state).length,g=e.filter(e=>"done"===e.state||"failed"===e.state).length,b=e.filter(e=>"done"===e.state&&e.result?.status!=="hit").length,j=e.filter(e=>"failed"===e.state).length,v=e.filter(e=>"pending"===e.state||"running"===e.state).length,w=r?"running":m>0?"incomplete":"complete",N=0===e.length?0:Math.round(g/e.length*100),y=[];async function k(){let e=h.filter(e=>"hit"===e.status&&!!e.couponCode).map(e=>e.couponCode).join("\n");await L(e)?(f(null),x(`${h.length} 件をコピーしました`)):(f(e),x("自動コピーに失敗しました。下のボックスから手動でコピーしてください"))}async function C(e){await L(e)?(f(null),x("コピーしました")):(f(e),x("自動コピーに失敗しました。下のボックスから手動でコピーしてください"))}return b>0&&y.push(`はずれ ${b}件`),j>0&&y.push(`失敗 ${j}件`),v>0&&y.push(`未処理 ${v}件`),(0,t.jsxs)("div",{children:[(0,t.jsxs)("header",{className:"pt-head flex items-center gap-3 px-[18px] pb-3",children:[(0,t.jsx)("button",{type:"button",className:"grid h-10 w-10 flex-none place-items-center rounded-full border border-divider","aria-label":"読み取り画面へ戻る",onClick:s,children:(0,t.jsx)(c,{size:20})}),(0,t.jsx)("h1",{className:"font-heading text-[22px] font-extrabold text-title",children:"結果"}),(0,t.jsx)("div",{className:"flex-1"}),"running"===w&&(0,t.jsxs)("span",{className:"flex flex-none items-center gap-[6px] rounded-full bg-accent2-100 px-[10px] py-[5px] text-[11px] whitespace-nowrap text-accent2-800",children:[(0,t.jsx)("span",{className:"h-[7px] w-[7px] animate-pulse rounded-full bg-accent2-600"}),"取得中 ",g," / ",e.length]}),"complete"===w&&(0,t.jsxs)("span",{className:"on-accent flash-pop flex flex-none items-center gap-[5px] rounded-full px-[10px] py-[5px] text-[11px] font-semibold whitespace-nowrap",children:[(0,t.jsx)(o,{size:13}),"完了 ",e.length,"件"]},"complete"),"incomplete"===w&&(0,t.jsxs)("span",{className:"flex-none rounded-full border border-accent-400 bg-surface px-[10px] py-[4px] text-[11px] whitespace-nowrap text-accent-800",children:["未完了 ",m,"件"]})]}),"running"===w&&(0,t.jsx)("div",{className:"px-[18px] pb-3",children:(0,t.jsx)("div",{className:"h-[6px] w-full overflow-hidden rounded-full bg-surface",children:(0,t.jsx)("div",{className:"h-full rounded-full bg-accent transition-[width] duration-300 ease-out",style:{width:`${N}%`}})})}),(0,t.jsxs)("div",{className:"px-[18px] pb-[130px]",children:[(0,t.jsxs)("div",{className:"flex items-center gap-[14px] rounded-[26px] bg-accent-200 px-4 py-[14px]",children:[(0,t.jsx)("div",{className:"on-accent grid h-[60px] w-[60px] flex-none place-items-center rounded-full font-heading text-[26px]",children:h.length}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("div",{className:"text-[15px] font-bold text-accent-900",children:"件が当たりでした"}),(0,t.jsx)("div",{className:"text-[12.5px] text-accent-800 opacity-85",children:y.length>
10?y.join("・"):"取得を開始しています"})]})]}),(0,t.jsxs)("div",{className:"mt-3 flex flex-col gap-[10px]",children:[(0,t.jsxs)("button",{type:"button",className:"on-accent flex h-[52px] w-full items-center justify-center gap-2 rounded-full font-heading text-[17px] disabled:opacity-40",disabled:0===h.length,onClick:k,children:[(0,t.jsx)(i,{size:19}),"当たり",h.length,"件を一括コピー"]}),(0,t.jsxs)("div",{className:"flex gap-[10px]",children:[(0,t.jsx)(D,{results:h,isRunning:r}),!r&&m>0&&(0,t.jsxs)("button",{type:"button",className:"h-14 flex-1 rounded-full border border-accent text-[14px] font-semibold text-accent-900",onClick:l,children:["未完了 ",m,"件を再実行"]})]})]}),u&&(0,t.jsx)("p",{className:"mt-3 text-[12.5px] text-text/70",children:u}),null!==p&&(0,t.jsx)("textarea",{readOnly:!0,className:"mt-2 w-full rounded-[20px] border border-divider bg-bg p-3 font-mono text-[14px]",value:p,onFocus:e=>e.currentTarget.select()}),(0,t.jsx)("ul",{className:"mt-4 flex flex-col gap-[10px]",children:e.map((e,n)=>{let r=n+1,l=e.result?.itemCode??e.code,a=d(e.serial);if("done"===e.state&&e.result?.status==="hit"&&e.result.couponCode){let n=e.result.couponCode;return(0,t.jsxs)("li",{className:"rounded-[26px] border border-accent-300 bg-accent-100 px-4 py-[14px]",children:[(0,t.jsxs)("div",{className:"flex items-center gap-[10px]",children:[(0,t.jsx)("span",{className:`${Q} on-accent`,children:r}),(0,t.jsx)("span",{className:"on-accent flex-none rounded-full px-[10px] py-[3px] text-[11px] font-semibold whitespace-nowrap",children:"当たり"}),(0,t.jsx)("div",{className:"flex-1"}),(0,t.jsxs)("div",{className:"truncate font-mono text-[11.5px] opacity-55",children:[l," ・ ",a]})]}),(0,t.jsxs)("div",{className:"mt-3 flex items-center gap-3",children:[(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("div",{className:"truncate font-mono text-[21px] font-semibold tracking-[0.04em] text-accent-900",children:n}),(0,t.jsxs)("div",{className:"mt-[3px] text-[12px] text-accent-800 opacity-80",children:["有効期限 ",function(e){if(null===e)return"—";let t=new Date(e);return Number.isNaN(t.getTime())?"—":t.toLocaleDateString("ja-JP",{year:"numeric",month:"2-digit",day:"2-digit"})}(e.result.expiresAt)]})]}),(0,t.jsx)("button",{type:"button",className:"on-accent grid h-14 w-14 flex-none place-items-center rounded-full","aria-label":"このクーポンコードをコピー",onClick:()=>C(n),children:(0,t.jsx)(i,{size:24})})]})]},e.id)}return"failed"===e.state?(0,t.jsxs)("li",{className:"rounded-[26px] border border-accent-400 bg-surface px-4 py-[14px]",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("span",{className:`${Q} bg-bg text-neutral-700`,children:r}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("div",{className:"truncate font-mono text-[14px]",children:l}),(0,t.jsx)("div",{className:"mt-0.5 truncate font-mono text-[11.5px] opacity-50",children:a})]}),(0,t.jsx)("span",{className:"flex-none rounded-full bg-accent-800 px-[10px] py-[3px] text-[11px] whitespace-nowrap text-bg",children:"失敗"})]}),(0,t.jsx)("div",{className:"mt-2 text-[12.5px] leading-[1.5] text-accent-800",children:S[e.errorKind??""]??"不明なエラーが発生しました"})]},e.id):(0,t.jsxs)("li",{className:"flex items-center gap-3 rounded-[26px] bg-surface px-4 py-[14px]",children:[(0,t.jsx)("span",{className:`${Q} bg-bg text-neutral-700`,children:r}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("div",{className:"truncate font-mono text-[14px]",children:l}),(0,t.jsx)("div",{className:"mt-0.5 truncate font-mono text-[11.5px] opacity-50",children:a})]}),"done"===e.state&&(0,t.jsx)("span",{className:G,children:"はずれ"}),"running"===e.state&&(0,t.jsxs)("span",{className:"flex flex-none items-center gap-[5px] rounded-full bg-accent2-100 px-[10px] py-[3px] text-[11px] whitespace-nowrap text-accent2-800",children:[(0,t.jsx)("span",{className:"h-[6px] w-[6px] animate-pulse rounded-full bg-accent2-600"}),"取得中"]}),"pending"===e.state&&(0,t.jsx)("span",{className:G,children:"待機中"})]},e.id)})})]}),(0,t.jsx)("div",{className:"bar-fade fixed inset-x-0 bottom-0 z-10",children:(0,t.jsx)("div",{className:"pb-home mx-auto w-full max-w-[480px] px-[18px] pt-[14px]",children:r?(0,t.jsx)("button",{type:"button",className:"h-14 w-full rounded-full border border-accent text-[15px] font-semibold text-accent-900",onClick:a,children:"中止"}):(0,t.jsx)("button",{type:"button",className:"h-14 w-full rounded-full border border-divider text-[15px] font-semibold",onClick:s,children:"続けて読み取る"})})})]})}function V(){return(0,t.jsxs)("footer",{className:"mt-8 flex flex-wrap gap-x-4 gap-y-1 border-t border-divider px-[18px] pt-3 pb-[150px] text-[12px] text-text/55",children:[null!==y.developerUrl&&(0,t.jsx)("a",{className:"text-accent-900 underline underline-offset-2",href:y.developerUrl,target:"_blank",rel:"noopener noreferrer",children:"開発者"}),null!==y.repositoryUrl&&(0,t.jsx)("a",{className:"text-accent-900 underline underline-offset-2",href:y.repositoryUrl,target:"_blank",rel:"noopener noreferrer",children:"ソースコード"}),(0,t.jsx)("a",{className:"text-accent-900 underline underline-offset-2",href:l("/about"),target:"_blank",rel:"noopener noreferrer",children:"このツールについて"})]})}function q(e){return"object"==typeof e&&null!==e}async function H(e){try{let t=await e.json();if(q(t)&&"string"==typeof t.error)return t.error}catch{}switch(e.status){case 400:return"invalid-input";case 429:return"rate-limited";case 504:return"timeout";default:return"upstream-error"}}async function J(e,t){let n,r;try{n=await fetch(l("/api/chance"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),signal:t})}catch(e){if(e instanceof Error&&"AbortError"===e.name)return{ok:!1,errorKind:"aborted"};return{ok:!1,errorKind:"network-error"}}if(!n.ok)return{ok:!1,errorKind:await H(n)};try{r=await n.json()}
1catch{return{ok:!1,errorKind:"unexpected-response"}}return!function(e){if(!q(e))return!1;let{status:t,couponCode:n,expiresAt:r,itemCode:l,isUnopened:a,isUnused:s,isUsed:i,openedStatus:o}=e;return("hit"===t||"miss"===t)&&(null===n||"string"==typeof n)&&(null===r||"string"==typeof r)&&"string"==typeof l&&"boolean"==typeof a&&"boolean"==typeof s&&"boolean"==typeof i&&("skipped"===o||"succeeded"===o||"failed"===o)}(r)?{ok:!1,errorKind:"unexpected-response"}:{ok:!0,value:r}}async function W(e,t,n){let r=n?.signal;for(let n=0;n<e.length;n+=1){if(r?.aborted)return;t.onStart(n);let l=await J(e[n],r);if(t.onSettled(n,l),r?.aborted)return;n!==e.length-1&&await function(e){return new Promise(t=>{if(e?.aborted)return void t();let n=setTimeout(()=>{e?.removeEventListener("abort",r),t()},1500);function r(){clearTimeout(n),e?.removeEventListener("abort",r),t()}e?.addEventListener("abort",r)})}(r)}}let X=[["camera","カメラ"],["paste","URL貼り付け"]];e.s(["default",0,function(){let[e,r]=(0,n.useState)([]),[a,s]=(0,n.useState)(!1),[i,o]=(0,n.useState)("camera"),[c,d]=(0,n.useState)("input"),u=(0,n.useRef)(null);async function x(e){if(null!==u.current)return;let t=new AbortController;u.current=t,s(!0);let n=e.map(e=>({code:e.code,serial:e.serial}));try{await W(n,{onStart:t=>{let n=e[t].id;r(e=>e.map(e=>e.id===n?{...e,state:"running"}:e))},onSettled:(t,n)=>{let l=e[t].id;r(e=>e.map(e=>e.id!==l?e:n.ok?{...e,state:"done",result:n.value,errorKind:null}:{...e,state:"failed",result:null,errorKind:n.errorKind}))}},{signal:t.signal})}finally{u.current=null,s(!1)}}function p(e){let t=e.map(e=>({id:crypto.randomUUID(),code:e.code,serial:e.serial,state:"pending",result:null,errorKind:null}));r(t),d("results"),x(t)}function f(){u.current?.abort()}(0,n.useEffect)(()=>()=>{u.current?.abort()},[]);let h=e.filter(e=>"done"===e.state||"failed"===e.state).length,m=new Set(e.map(e=>e.serial));return"results"===c?(0,t.jsx)("div",{className:"mx-auto w-full max-w-[480px] flex-1",children:(0,t.jsx)(F,{jobs:e,isRunning:a,onRetry:function(){let t=e.filter(e=>"failed"===e.state||"pending"===e.state);if(0===t.length)return;let n=new Set(t.map(e=>e.id));r(e=>e.map(e=>n.has(e.id)?{...e,state:"pending",errorKind:null}:e)),x(t)},onAbort:f,onBack:()=>d("input")})}):(0,t.jsxs)("div",{className:"mx-auto w-full max-w-[480px] flex-1",children:[(0,t.jsxs)("header",{className:"pt-head px-[18px]",children:[(0,t.jsxs)("div",{className:"flex items-center gap-[10px]",children:[(0,t.jsx)("h1",{className:"min-w-0 flex-1 font-heading text-[26px] leading-[1.1] font-extrabold text-title",children:"旬パス"}),e.length>0&&(0,t.jsxs)("button",{type:"button",className:"flex-none rounded-full bg-neutral-100 px-[10px] py-[6px] text-[11px] whitespace-nowrap text-neutral-800",onClick:()=>d("results"),children:["結果 ",h," / ",e.length]})]}),(0,t.jsxs)("p",{className:"mt-1 text-[12.5px] leading-[1.5] text-text/60",children:["旬すぐのパッケージQRをまとめて読み取り、クーポンコードだけを一覧で取り出します。",(0,t.jsx)("a",{className:"text-accent-900 underline underline-offset-2",href:l("/about"),target:"_blank",rel:"noopener noreferrer",children:"非公式ツール"})]})]}),(0,t.jsx)("div",{className:"px-[18px] py-3",children:(0,t.jsx)("div",{className:"flex gap-1 rounded-full bg-surface p-1",children:X.map(([e,n])=>(0,t.jsx)("button",{type:"button",className:i===e?"h-10 flex-1 rounded-full bg-accent text-[14px] font-semibold whitespace-nowrap text-accent-900 disabled:opacity-40":"h-10 flex-1 rounded-full text-[14px] font-semibold whitespace-nowrap text-text/60 disabled:opacity-40","aria-pressed":i===e,disabled:a,onClick:()=>o(e),children:n},e))})}),(0,t.jsx)("div",{className:"px-[18px]",children:"camera"===i?(0,t.jsx)(U,{isRunning:a,knownSerials:m,onSubmit:p,onAbort:f}):(0,t.jsx)(E,{isRunning:a,onSubmit:p,onAbort:f})}),(0,t.jsx)(V,{})]})}],52683)}]);

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.