1import{c as ae,r as u,j as e,B as ne,a4 as B,s as b,u as O}from"./index-BCH4IFx8.js";import{B as z}from"./BpSpinner-Bqvfph1h.js";import{C as A,a as I,b as R,c as F,d as Y}from"./card-DaE3Hwfn.js";import{T as C}from"./triangle-alert-m5K6MENR.js";import{S as J}from"./shield-check-CeYzatjO.js";import{S as W}from"./shield-CYKtwov5.js";import{K as re}from"./key-round-DESqIiUD.js";import{C as K}from"./circle-play-CyU0z9QT.js";/** 2 * @license lucide-react v0.462.0 - ISC 3 * 4 * This source code is licensed under the ISC license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const V=ae("FileArchive",[["path",{d:"M10 12v-1",key:"v7bkov"}],["path",{d:"M10 18v-2",key:"1cjy8d"}],["path",{d:"M10 7V6",key:"dljcrl"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M15.5 22H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v16a2 2 0 0 0 .274 1.01",key:"gkbcor"}],["circle",{cx:"10",cy:"20",r:"2",key:"1xzdoj"}]]),y={win32:"Windows",darwin:"macOS"},G={x64:"Intel / x64",arm64:"Apple Silicon",universal:"Universal"};function ie(c){if(!c)return"";const l=y[c.platform||"win32"]||"Windows",o=G[c.arch||"x64"]||"";return o?`${l} · ${o}`:l}function N(){return typeof navigator>"u"?"win32":`${navigator.userAgent} ${navigator.platform||""}`.toLowerCase().includes("mac")?"darwin":"win32"}async function oe(c){try{const l=navigator.userAgentData;if(l!=null&&l.getHighEntropyValues){const o=await l.getHighEntropyValues(["architecture"]);if((o==null?void 0:o.architecture)==="arm")return"arm64";if((o==null?void 0:o.architecture)==="x86")return"x64"}}catch{}return c==="darwin"?"arm64":"x64"}function de(c){if(!c)return"0 B";const l=["B","KB","MB","GB"];let o=0,g=c;for(;g>=1024&&o<l.length-1;)g/=1024,o++;return`${g.toFixed(1)} ${l[o]}`}function ge(){const[c,l]=u.useState(!0),[o,g]=u.useState([]),[H,X]=u.useState({}),[q,U]=u.useState({}),[D,P]=u.useState(null),[v,k]=u.useState(N()),[Z,Q]=u.useState([]),[p,_]=u.useState({platform:N(),arch:N()==="darwin"?"arm64":"x64"});u.useEffect(()=>{let s=!1;const t=N();return oe(t).then(r=>{s||_({platform:t,arch:r})}),()=>{s=!0}},[]);const $=async()=>{l(!0);const{data:s}=await b.auth.getUser();if(!s.user){l(!1);return}const{data:t}=await b.from("bridge_download_grants").select("*").eq("granted_to_user_id",s.user.id).is("revoked_at",null).order("created_at",{ascending:!1}),r=t??[];g(r);const{data:i}=await b.from("bridge_releases").select("id, version, filename, size_bytes, notes, platform, arch").eq("is_active",!0).order("created_at",{ascending:!1}),a={};i==null||i.forEach(n=>{a[n.id]=n}),Q(i??[]);const h=r.map(n=>n.release_id).filter(n=>!!n&&!a[n]);if(h.length){const{data:n}=await b.from("bridge_releases").select("id, version, filename, size_bytes, notes, platform, arch").in("id",Array.from(new Set(h)));n==null||n.forEach(w=>{a[w.id]=w})}X(a);const m=Array.from(new Set(r.map(n=>n.bridge_id).filter(Boolean)));if(m.length){const{data:n}=await b.from("rfid_bridges").select("id, paired_at, last_heartbeat_at").in("id",m),w={};n==null||n.forEach(d=>{w[d.id]=!!d.paired_at&&!!d.last_heartbeat_at}),U(w)}l(!1)};u.useEffect(()=>{$()},[]);const M=s=>{var t;return s.version??(s.release_id?(t=H[s.release_id])==null?void 0:t.version:void 0)},T=(s,t)=>{const r=String(s??"0").split(".").map(a=>parseInt(a,10)||0),i=String(t??"0").split(".").map(a=>parseInt(a,10)||0);for(let a=0;a<Math.max(r.length,i.length);a++){const h=(r[a]??0)-(i[a]??0);if(h!==0)return h}return 0},S=(s,t)=>{var h;const r=M(s),i=Z.filter(m=>(m.platform||"win32")===t&&T(m.version,r)>=0).sort((m,n)=>T(n.version,m.version)),a=(h=i[0])==null?void 0:h.version;return i.filter(m=>m.version===a)},ee=s=>{const t=S(s,p.platform);return t.find(r=>r.arch===p.arch)??t.find(r=>r.arch==="universal")??t[0]},se=async s=>{P(s);try{const t=(await b.auth.getSession()).data.session;if(!(t!=null&&t.access_token))throw new Error("Please sign in again before downloading");const r=`https://hhkjvpdlkhxblpqzugic.supabase.co/functions/v1/bridge-download?grant_id=${s}&platform=${p.platform}&arch=${p.arch}`,i=await fetch(r,{headers:{Authorization:`Bearer ${t.access_token}`,apikey:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imhoa2p2cGRsa2h4YmxwcXp1Z2ljIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjU0Njk0NjAsImV4cCI6MjA4MTA0NTQ2MH0.lmlLUKecJ7qKzZXJm_BIRvXJm7eizBY-cS543YAeD6Y"}}),a=await i.json();if(!i.ok||!(a!=null&&a.url))throw new Error((a==null?void 0:a.error)||"Could not get download link");window.location.href=a.url,O.success("Download startingâ¦"),setTimeout($,1500)}catch(t){O.error(t.message??"Download failed")}finally{P(null)}};return c?e.jsxs("div",{className:"p-8 text-center text-muted-foreground",children:[e.jsx(z,{className:"h-5 w-5 animate-spin inline mr-2"}),"Loadingâ¦"]}):e.jsxs("div",{className:"container mx-auto py-6 max-w-3xl space-y-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Download Beyond Pro Bridge"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"These are your authorized bridge installer
6s. Each grant permits a limited number of downloads and comes with a pairing code that activates the bridge on one machine."})]}),o.length===0&&e.jsx(A,{children:e.jsx(I,{className:"p-6 text-sm text-muted-foreground",children:"You don't have any bridge download grants yet. Contact Beyond Pro support to have one issued."})}),o.map(s=>{const t=ee(s),r=(t==null?void 0:t.version)??M(s),i=!t,a=t?`${t.platform||"win32"}:${t.arch||"x64"}`:"",h=Number((s.downloads_by_variant??{})[a]??0)>=s.max_downloads,m=!!s.revoked_at,n=s.expires_at?new Date(s.expires_at)<new Date:!1,w=!h&&!m&&!n&&!i;return e.jsxs(A,{children:[e.jsxs(R,{children:[e.jsxs(F,{className:"flex items-center gap-2 flex-wrap",children:["Beyond Pro Bridge ",r?`v${r}`:"",t&&!i&&e.jsx("span",{className:"text-xs font-normal px-2 py-0.5 rounded bg-muted text-muted-foreground",children:ie(t)})]}),e.jsxs(Y,{children:[t&&!i?`${t.filename} · ${de(t.size_bytes)}`:"No build available for this computer yet",t!=null&&t.notes&&!i?` · ${t.notes}`:""]})]}),e.jsxs(I,{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-md border p-3 space-y-2",children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-muted-foreground",children:"Your computer â we picked this automatically"}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"flex rounded-md border overflow-hidden text-xs",children:["win32","darwin"].map(d=>{var L;const j=S(s,d),f=j.length>0,E=(L=j[0])==null?void 0:L.version;return e.jsxs("button",{type:"button",disabled:!f,onClick:()=>{_(te=>
6({platform:d,arch:d==="darwin"?te.arch:"x64"})),k(d)},className:`px-3 py-1.5 ${p.platform===d?"bg-primary text-primary-foreground":"bg-background text-muted-foreground"} ${f?"":"opacity-50 cursor-not-allowed"}`,children:[y[d],f?E?` · v${E}`:"":" â not published"]},d)})}),p.platform==="darwin"&&e.jsx("div",{className:"flex rounded-md border overflow-hidden text-xs",children:["arm64","x64"].map(d=>{const j=S(s,"darwin").some(f=>(f.arch||"x64")===d||f.arch==="universal");return e.jsx("button",{type:"button",disabled:!j,onClick:()=>_(f=>({...f,arch:d})),className:`px-3 py-1.5 ${p.arch===d?"bg-primary text-primary-foreground":"bg-background text-muted-foreground"} ${j?"":"opacity-50 cursor-not-allowed"}`,children:G[d]},d)})})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Download on the machine that will actually run the reader. On a Mac, check the Apple menu â About This Mac if you're unsure whether it's Apple Silicon or Intel."})]}),i&&e.jsxs("div",{className:"flex items-start gap-2 rounded-md border border-amber-300 bg-amber-50 p-2 text-xs text-amber-900",children:[e.jsx(C,{className:"h-3.5 w-3.5 mt-0.5 shrink-0"}),e.jsxs("span",{children:["There's no ",y[p.platform]," build uploaded yet. Ask Beyond Pro to publish it, or switch above if you're installing on the other platform."]})]}),s.bridge_id&&q[s.bridge_id]?e.jsxs("div",{className:"rounded-md border p-3 bg-muted/40",children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-muted-foreground mb-1",children:"Bridge paired"}),e.jsxs("div",{className:"text-sm flex items-center gap-1 text-muted-foreground",children:[e.jsx(J,{className:"h-3 w-3"}),"This installer has been activated. The pairing code is no longer needed."]})]}):e.jsxs("div",{className:"rounded-md border p-3 bg-muted/40",children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-muted-foreground mb-1",children:s.downloads_used>0?"Pairing code (bridge not yet activated)":"Pairing code (enter after install)"}),e.jsx("div",{className:"font-mono text-2xl font-semibold tracking-widest",children:s.pairing_code}),e.jsxs("div",{className:"text-xs text-muted-foreground mt-1 flex items-center gap-1",children:[e.jsx(J,{className:"h-3 w-3"}),s.downloads_used>0?"Launch the installed bridge and enter this code to activate. It will disappear once the bridge checks in.":"Locks the installer to one machine. Don't share it."]})]}),e.jsxs("div",{className:"text-sm",children:[e.jsxs("div",{className:"text-xs text-muted-foreground",children:["This grant covers every published build of ",r?`v${r}`:"this version"," â Windows and macOS. Downloads so far: ",s.downloads_used,"."]}),s.expires_at&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Expires: ",new Date(s.expires_at).toLocaleString()]}),s.last_downloaded_at&&e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Last downloaded: ",new Date(s.last_downloaded_at).toLocaleString()]})]}),e.jsxs(ne,{onClick:()=>se(s.id),disabled:!w||D===s.id,size:"lg",children:[D===s.id?e.jsx(z,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(B,{className:"h-4 w-4 mr-2"}),m?"Revoked":n?"Expired":h?`${y[p.platform]} already downloaded`:i?"No build available":`Download ${y[p.platform]} installer`]})]})]},s.id)}),e.jsxs(A,{children:[e.jsx(R,{children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx(F,{className:"text-base",children:"Install & pair â step by step"}),e.jsxs(Y,{children:["Do these on the ",v==="darwin"?"Mac":"Windows laptop"," that will run the RFID reader."]})]}),e.jsxs("div",{className:"flex rounded-md border overflow-hidden text-xs",children:[e.jsx("button",{type:"button",onClick:()=>k("win32"),className:`px-3 py-1.5 ${v==="win32"?"bg-primary text-primary-foreground":"bg-background text-muted-foreground"}`,children:"Windows"}),e.jsx("button",{type:"button",onClick:()=>k("darwin"),className:`px-3 py-1.5 ${v==="darwin"?"bg-primary text-primary-foreground":"bg-background text-muted-foreground"}`,children:"macOS"})]})]})}),e.jsxs(I,{className:"space-y-4 text-sm",children:[v==="darwin"?e.jsxs(e.Fragment,{children:[e.jsxs(x,{n:1,icon:e.jsx(B,{className:"h-4 w-4"}),title:"Download the installer",children:["Click ",e.jsx("span",{className:"font-medium",children:"Download installer"})," above on the Mac itself. You'll get a",e.jsx("span",{className:"font-mono",children:" .dmg"})," file in your Downloads folder. Pick the",e.jsx("span",{className:"font-medium",children:" Apple Silicon"})," build for M1/M2/M3/M4 Macs and the",e.jsx("span",{className:"font-medium",children:" Intel"})," build for older Macs â the badge on the card above tells you which one it is."]}),e.jsxs(x,{n:2,icon:e.jsx(V,{className:"h-4 w-4"}),title:"Open the .dmg and drag to Applications",children:["Double-click the ",e.jsx("span",{className:"font-mono",children:".dmg"}),". A window opens showing the",e.jsx("span",{className:"font-medium",children:" Beyond Pro Bridge"})," icon next to an",e.jsx("span",{className:"font-medium",children:" Applications"}
6)," folder â drag the icon onto Applications. Then eject the disk image from the Finder sidebar."]}),e.jsxs(x,{n:3,icon:e.jsx(W,{className:"h-4 w-4"}),title:"Get past the macOS security warning",children:["The app isn't signed by Apple yet, so the first launch is blocked. Open",e.jsx("span",{className:"font-medium",children:" Applications"}),", ",e.jsx("span",{className:"font-medium",children:"right-click"}),"(or Control-click) ",e.jsx("span",{className:"font-medium",children:"Beyond Pro Bridge"})," and choose",e.jsx("span",{className:"font-medium",children:" Open"}),", then ",e.jsx("span",{className:"font-medium",children:"Open"})," again in the dialog. This is the Mac version of the Windows SmartScreen prompt and only happens once.",e.jsxs("div",{className:"mt-2 flex items-start gap-2 rounded-md border border-amber-300 bg-amber-50 p-2 text-xs text-amber-900",children:[e.jsx(C,{className:"h-3.5 w-3.5 mt-0.5 shrink-0"}),e.jsxs("span",{children:['If macOS says the app "cannot be opened" with no Open button, go to',e.jsx("span",{className:"font-medium",children:" System Settings â Privacy & Security"}),", scroll down and click ",e.jsx("span",{className:"font-medium",children:"Open Anyway"}),". Also allow the",e.jsx("span",{className:"font-medium",children:" local network"})," prompt when it appears â without it the Mac cannot see the RFID reader."]})]})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs(x,{n:1,icon:e.jsx(B,{className:"h-4 w-4"}),title:"Download the installer",children:["Click ",e.jsx("span",{className:"font-medium",children:"Download installer"})," above. You'll get a",e.jsx("span",{className:"font-mono",children:" .zip"})," file (typically saved to your Downloads folder). Each grant is single-use â if you need to reinstall on a different machine, ask Beyond Pro to revoke the old grant and issue a new one."]}),e.jsxs(x,{n:2,icon:e.jsx(V,{className:"h-4 w-4"}),title:"Extract the zip",children:["Right-click the downloaded ",e.jsx("span",{className:"font-mono",children:".zip"})," and choose",e.jsx("span",{className:"font-medium",children:" Extract Allâ¦"})," Pick a permanent location such as",e.jsx("span",{className:"font-mono",children:" C:\\BeyondProBridge\\"})," (not inside the Downloads folder â Windows sometimes deletes items there). Open the extracted folder."]}),e.jsxs(x,{n:3,icon:e.jsx(W,{className:"h-4 w-4"}),title:"Get past Windows SmartScreen",children:["Double-click ",e.jsx("span",{className:"font-mono",children:"BeyondProBridge.exe"}),". Windows will show a blue",e.jsx("span",{className:"font-medium",children:' "Windows protected your PC"'})," warning because the app isn't signed by a major publisher yet. Click ",e.jsx("span",{className:"font-medium",children:"More info"}),", then",e.jsx("span",{className:"font-medium",children:" Run anyway"}),". This only happens on the first launch.",e.jsxs("div",{className:"mt-2 flex items-start gap-2 rounded-md border border-amber-300 bg-amber-50 p-2 text-xs text-amber-900",children:[e.jsx(C,{className:"h-3.5 w-3.5 mt-0.5 shrink-0"}),e.jsxs("span",{children:['If your browser blocked the download as "not commonly downloaded," click the arrow next to the warning and choose ',e.jsx("span",{className:"font-medium",children:"Keep"})," â",e.jsx("span",{className:"font-medium",children:" Keep anyway"}),"."]})]})]})]}),e.jsxs(x,{n:4,icon:e.jsx(re,{className:"h-4 w-4"}),title:"Enter your pairing code",children:["On first launch the bridge asks for a pairing code. Copy the code from the card above (or type it exactly â it's case-insensitive) and click ",e.jsx("span",{className:"font-medium",children:"Pair"}),". The bridge will contact Beyond Pro, register itself to this laptop, and unlock. The pairing code is single-use and stops working once paired."]}),e.jsxs(x,{n:5,icon:e.jsx(K,{className:"h-4 w-4"}),title:"Open the bridge and leave it running",children:["After pairing, the bridge opens to the ",e.jsx("span",{className:"font-medium",children:"Status"})," tab. You don't need to change anything in the bridge â all settings are already configured. Just leave the bridge open and running on the laptop. It acts as the link between your RFID reader and the timing system."]}),e.jsxs(x,{n:6,icon:e.jsx(K,{className:"h-4 w-4"}),title:"Connect the reader in Timing Lab before timing",children:["In your web browser, open ",e.jsx("span",{className:"font-medium",children:"Timing Lab"})," and click the",e.jsx("span",{className:"font-medium",children:" Run"})," tab in the top-right corner. Plug your RFID reader into the network, then press ",e.jsx("span",{className:"font-medium",children:"Connect"})," in Timing Lab. You'll see your bridge listed there â select it and wait for the status to show connected. This must be done before you can start reading tags and timing a race â once connected, the reader is linked to the timing system and you're ready to go."]}),e.jsx("p",{className:"text-xs text-muted-foreground italic pt-2 border-t",children:"Stuck? Grab a screenshot of the error and contact Beyond Pro supp
6ort â we can see your bridge's status from our side and help remotely."})]})]})]})}function x({n:c,icon:l,title:o,children:g}){return e.jsxs("div",{className:"flex gap-3",children:[e.jsx("div",{className:"flex flex-col items-center",children:e.jsx("div",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-primary text-primary-foreground text-xs font-semibold",children:c})}),e.jsxs("div",{className:"flex-1 space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5 font-medium",children:[l,o]}),e.jsx("div",{className:"text-muted-foreground leading-relaxed",children:g})]})]})}export{ge as default};
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.