1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7336],{10880:(t,e,a)=>{"use strict";a.d(e,{rT:()=>i});let i=t=>{switch(t){case"kph":return"km/h";case"mph":return"mph";default:return t}}},14788:(t,e,a)=>{"use strict";function i(t,e){if(t?.observed_route?.length)return{type:"MultiLineString",coordinates:t.observed_route};let a=t?.predicted_route;if(!a?.length)return null;let i=[...a[a.length-1],...(t.lookahead_path||[]).slice(1)];if(!e||i.length<2)return{type:"MultiLineString",coordinates:a};let n=Math.cos(e[1]*Math.PI/180),s={distance:1/0};for(let t=1;t<i.length;t++){let a=i[t-1],r=i[t],o=(r[0]-a[0])*n,l=r[1]-a[1],c=o*o+l*l,g=c?Math.max(0,Math.min(1,((e[0]-a[0])*n*o+(e[1]-a[1])*l)/c)):0,d=[a[0]+(r[0]-a[0])*g,a[1]+(r[1]-a[1])*g],h=((e[0]-d[0])*n)**2+(e[1]-d[1])**2;h<=s.distance&&(s={distance:h,point:d,i:t})}return s.distance>(100/111320)**2?{type:"MultiLineString",coordinates:a}:{type:"MultiLineString",coordinates:[...a.slice(0,-1),[...i.slice(0,s.i),s.point]]}}a.d(e,{D:()=>i})},21691:(t,e,a)=>{"use strict";a.d(e,{MB:()=>n,pt:()=>s});let i="true"===a(65364).env.NEXT_PUBLIC_E2E_TEST,n=t=>{i&&(window.__tfyiMap=t)},s=t=>{i&&(window.__tfyiLastTrainFeatures=t,window.dispatchEvent(new CustomEvent("tfyi:trains-updated")))}},27336:(t,e,a)=>{"use strict";a.r(e),a.d(e,{default:()=>eI});var i=a(37876);let n="trainsfyi:world-map-controls:v1",s="trainsfyi:world-map-view:v1";function r(){let t=new URLSearchParams(window.location.search);return t.has("train")?`train:${t.get("train")}`:t.has("station")?`station:${t.get("station")}`:""}function o(t){return t?.stationId||(t?`${t.network}:${t.stopId}`:"")}var l=a(28168),c=a(89099),g=a(14232),d=a(75450);a(62544),a(4402);var h=a(372),m=a(27318),u=a(77808),p=a(85044),y=a(65685),b=a(43203),f=a(50792),w=a(48230),x=a.n(w),_=a(75656),v=a(71904),j=a.n(v);function k({className:t=""}){return(0,i.jsx)("span",{"aria-hidden":"true",className:`${j().shimmer} block rounded ${t}`})}var S=a(78240),C=a(44824);let N="trainsfyi.journey-time-mode",I=["train","viewer","relative"],M="train",A="journey-time-mode-change";var L=a(73093);let T=/^(.+?)\s*(?:[-ââ,:|@]\s*)?\b(northbound|southbound|eastbound|westbound|subway)\s+platform(?:\s+(?:towards?|to)\b.*)?\s*$/iu,z=RegExp("^(.+?)\\s*(?:[-ââ,:|@]\\s*)?(?:platform|track|quai|voie|and\xe9n|anden|plataforma|gleis|bahnsteig|binario|perron|spoor|sp\xe5r|spar|spor|laituri|raide|peron|n\xe1stupiÅ¡tÄ|nastupiste|n\xe1stupiÅ¡te|v\xe1g\xe1ny|vagany|platforma|плаÑÑоÑма|пÑÑÑ|αÏοβάθÏα|رصÙÙ|רצ××£)\\s+(.+?)\\s*$","iu"),R=/^(.+?)\s*(?:[-ââ,:|@]\s*)?([\p{L}\p{N}-]+)\s*(?:çªç·|æå°|ç«å°|ì¹ê°ì¥)\s*$/iu;function P(t){return"string"!=typeof t?t:t.replace(/^UP Express\s+/i,"").replace(/\s+GO\/UP\s*$/i,"")}function U(t){if("string"!=typeof t)return t;for(let e of(t=P(t),[T,z,R])){let a=t.match(e);if(a?.[1].trim()&&a[2].trim())return P(a[1].trim())}return t}let E=async t=>{let e=await fetch(t);if(!e.ok)throw Error("Trip details unavailable");return e.json()};function $(t){let e=t.gtfs?.trip_id,a=`${S.QU}/api`,i=`${encodeURIComponent(t.agency)}/trips/${encodeURIComponent(e)}`,{data:n,error:s,isLoading:r}=(0,_.Ay)(e?`${a}/v3/${i}/`:null,E,{revalidateOnFocus:!1,shouldRetryOnError:!1}),{data:o,error:l,isLoading:c}=(0,_.Ay)(e?`${a}/v5/${i}/stop_times/`:null,E,{refreshInterval:3e4,revalidateOnFocus:!1,shouldRetryOnError:!1}),[d,h]=(0,g.useState)(null),[m,u]=(0,g.useState)(null);(0,g.useEffect)(()=>{let e=!1;return n?.shape_points?.length&&n?.stop_times?.length&&(0,L.K)(n,{position:{lat:t.lat,lon:t.lng}}).then(t=>{e||h(t)}).catch(()=>{e||h(null)}).finally(()=>{e||u(n)}),()=>{e=!0}},[n,t.lat,t.lng]);let p=(0,g.useMemo)(()=>{let t=(n?.stop_times??[]).map(t=>({...t.stop,stop_sequence:t.stop_sequence,scheduled_arrival:t.arrival_time,scheduled_departure:t.departure_time})),e=o?.stop_times??[];return t.length?t.map(t=>({...t,...e.find(e=>e.stop_id===t.stop_id&&e.stop_sequence===t.stop_sequence)})).sort((t,e)=>t.stop_sequence-e.stop_sequence):[...e].sort((t,e)=>t.stop_sequence-e.stop_sequence)},[n,o]),y=n?.stop_times?.reduce((t,e)=>!t||e.stop_sequence<t.stop_sequence?e:t,null),b=function(t,e,a){let i=t?.trainIsAtStop;if(i){let n=e?.stop_id!=null&&i.stop_id===e.stop_id&&!t.previousStops?.some(t=>t.stop_id!==e.stop_id)&&!(a>0)&&!(t.progressAlongTotalRoute?.percent>=1);return`${n?"Waiting to depart":"Stopped at"} ${U(i.stop_name)}
1`}let n=t?.nextStops?.[0];return n?`${t.progressBetweenStops?.percent>=.84?"Arriving at":"En route to"} ${U(n.stop_name)}`:null}(d,y?.stop,t.spd);return{stops:p,progress:m===n?d:null,movement:m===n?b:null,route:n?.route,originDeparture:y?.departure_time,status:o?.status==="scheduled"&&t.status?t.status:o?.status||t.status,delay:o?.delay_seconds??t.delay_seconds,timezone:o?.timezone,loading:r||c,tripLoading:r,progressLoading:r||!!(n?.shape_points?.length&&n?.stop_times?.length&&m!==n),error:!p.length&&(s||l),hasTrip:!!e}}function F({value:t,display:e}){if(!t)return(0,i.jsx)("span",{children:"â"});let{time:a,dayLabel:n,title:s}=function(t,{mode:e,zone:a,serviceDate:i,now:n,viewerZone:s}={}){if(!t||!/^\d+:\d{2}(:\d{2})?$/.test(t))return{time:"â"};let[r,o,l=0]=t.split(":").map(Number);if(o>59||l>59)return{time:"â"};let c=Math.floor(r/24),g={time:`${r%24}:${String(o).padStart(2,"0")}`,dayLabel:c?`+${c}d`:null};if("train"===e)return g;if(!a||!i)return{time:"â",title:"Time zone or service date unavailable"};let d=C.c9.fromISO(i,{zone:a}).plus({days:c}).set({hour:r%24,minute:o,second:l,millisecond:0});if(!d.isValid)return{time:"â"};if("relative"===e){let t=Math.round((d.toMillis()-n)/6e4);if(!t)return{time:"Now"};let e=Math.abs(t),a=e<60?`${e} min`:`${Math.floor(e/60)} hr${e%60?` ${e%60} min`:""}`;return{time:t>0?`In ${a}`:`${a} ago`}}let h=s?d.setZone(s):d.toLocal(),m=(s?C.c9.fromMillis(n,{zone:s}):C.c9.fromMillis(n)).startOf("day"),u=Math.round(h.startOf("day").diff(m,"days").days);return{time:h.toFormat("H:mm"),dayLabel:u?`${u>0?"+":""}${u}d`:null}}(t,e);return(0,i.jsxs)("span",{title:s,children:[a,n&&(0,i.jsx)("span",{className:"ml-1 text-[10px]",children:n})]})}function B({journey:t,train:e,color:a,onSelectStation:n}){let{stops:s,progress:r,loading:o,error:l,hasTrip:c,timezone:d}=t,[h,m]=function(){let[t,e]=(0,g.useState)("train");return(0,g.useEffect)(()=>{let t=()=>{try{let t=localStorage.getItem(N);I.includes(t)&&(M=t)}catch{}e(M)};return t(),window.addEventListener("storage",t),window.addEventListener(A,t),()=>{window.removeEventListener("storage",t),window.removeEventListener(A,t)}},[]),[t,t=>{if(I.includes(t)){M=t,e(t);try{localStorage.setItem(N,t)}catch{}window.dispatchEvent(new Event(A))}}]}(),[u,p]=(0,g.useState)(()=>Date.now());(0,g.useEffect)(()=>{let t=setInterval(()=>p(Date.now()),15e3);return()=>clearInterval(t)},[]);let y=function(t,e,a,i){if(!e)return null;let n=C.c9.fromMillis(a,{zone:e});if(!n.isValid)return null;if(t){let a=/^\d{8}$/.test(t)?C.c9.fromFormat(t,"yyyyMMdd",{zone:e}):C.c9.fromISO(t,{zone:e});return a.isValid?a.toISODate():null}let s=60*Number(i?.split(":")[0])+Number(i?.split(":")[1]),r=Number.isFinite(s)?Math.max(0,Math.ceil((s-60*n.hour-n.minute)/1440)):0;return n.minus({days:r}).toISODate()}(e.service_date,d,u,t.originDeparture),b={mode:h,zone:d,serviceDate:y,now:u};return(0,i.jsxs)("section",{"aria-label":"Journey stops","aria-busy":o,className:"py-5",children:[(0,i.jsxs)("div",{className:"mb-1 flex items-center justify-between",children:[(0,i.jsx)("h3",{className:"text-sm font-bold text-gray-900",children:"Stops"}),o&&!s.length?(0,i.jsx)(k,{className:"h-4 w-12"}):s.length>0&&(0,i.jsxs)("span",{className:"text-xs text-gray-500",children:[s.length," stops"]})]}),(0,i.jsx)("div",{className:"mb-4",children:(0,i.jsxs)("select",{"aria-label":"Stop time display",value:h,onChange:t=>m(t.target.value),title:"train"===h?d?.replace(/_/g," "):void 0,className:"cursor-pointer rounded border-0 bg-transparent py-1 pl-0 pr-7 text-xs text-gray-500 hover:text-gray-900 focus:ring-2 focus:ring-blue-500",children:[(0,i.jsx)("option",{value:"train",children:"Trainâs local time"}),(0,i.jsx)("option",{value:"viewer",children:"Your local time"}),(0,i.jsx)("option",{value:"relative",children:"Time from now"})]})}),o&&!s.length?(0,i.jsxs)("div",{role:"status","aria-label":"Loading stops",children:[(0,i.jsx)("span",{className:"sr-only",children:"Loading stopsâ¦"}),(0,i.jsx)("ol",{"aria-hidden":"true",className:"ml-2 border-l-2 border-transparent",children:[0,1,2,3,4].map(t=>(0,i.jsxs)("li",{className:"relative pb-5 pl-5",children:[t<4&&(0,i.jsx)("span",{className:"absolute -left-[2px] top-[10px] h-full w-0.5 bg-gray-100"}),(0,i.jsx)("span",{className:"absolute -left-[7px] top-1 h-3 w-3 rounded-full border-2 border-gray-200 bg-white"}),(0,i.jsx)(k,{className:`h-5 ${t%2?"w-36":"w-44"}`}),(0,i.jsx)(k,{className:"mt-1 h-4 w-20"}),(0,i.jsx)(k,{className:"mt-1 h-4 w-16"})]},t))})]}):s.length?(0,i.jsx)("ol",{className:"ml-2 border-l-2 border-transparent",children:s.map((t,o)=>{let l="ttc"===String(e.agency).toLowerCase()?U(t.stop_name):P(t.stop_name),c=r?.trainIsAtStop?.stop_id===t.stop_id,g=!c&&r?.nextStops?.[0]?.stop_id===t.stop_id,d=!c&&r?.previousStops?.some(e=>e.stop_id===t.stop_id),h=function(t,e,a){if(!e||!a||!a.previousStops?.some(e=>e.stop_id===t.stop_id)||a.trainIsAtStop?.stop_id===t.stop_id)return 0;if(a.trainIsAtStop?.stop_id===e.stop_id||a.previousStops?.some(t=>t.stop_id===e.stop_id))return 1;if(a.nextStops?.[0]?.stop_id!==e.stop_id)return 0;let i=a.progressBetweenStops?.percent;return Number.isFinite(i)?Math.max(0,Math.min(1,i)):0}(t,s[o+1],r),m="skipped"===t.status||"SKIPPED"===t.schedule_relationship,u=t.departure_delay_seconds??t.arrival_delay_seconds,p=t.complex_id||t.station_id,y=p||`${e.agency}:${t.stop_id}`,f=n?`/?station=${encodeURIComponent(y)}`:`/networks/${encodeURIComponent(e.agency)}/stations/${encodeURIComponent(t.stop_id)}/`;return(0,i.jsxs)("li",{className:`relative pb-5 pl-5 ${d?"text-gray-400":"text-gray-900"}`,children:[o<s.length-1&&(0,i.jsx)("span",{"aria-hidden":"true",className:"absolute -left-[2px] top-[10px] h-full w-0.5 bg-gray-100",children:(0,i.jsx)("span",{className:"block w-full",style:{height:`${100*h}%`,backgroundColor:a}})}),(0,i.jsx)("span",{"aria-hidden":"true",className:"absolute -left-[7px] top-1 h-3 w-3 rounded-full border-2 bg-white",style:{borderColor:c||g||d?a:"#d1d5db",backgroundColor:c||d?a:"#fff"}}),(0,i.jsxs)("div",{className:"flex flex-wrap items-center gap-x-2 gap-y-1",children:[(0,i.jsx)(x(),{href:f,onClick:a=>{!n||0!==a.button||a.metaKey||a.ctrlKey||a.shiftKey||a.altKey||(a.preventDefault(),n({stationId:p,network:e.agency,stopId:t.stop_id,stopName:t.stop_name}))},className:`text-sm font-semibold hover:underline ${m?"line-through":""}`,children:l}),(c||g||m)&&(0,i.jsx)("span",{className:"rounded bg-blue-50 px-1.5 py-0.5 text-[10px] font-semibold text-blue-800",children:m?"Skipped":c?"At station":"Next stop"})]}),(0,i.jsxs)("div",{className:"mt-1 space-y-1 text-xs tabular-nums",children:[(o>0||1===s.length)&&(0,i.jsxs)("p",{children:["Arr ",(0,i.jsx)(F,{display:b,value:t.realtime_arrival||t.scheduled_arrival}),t.realtime_arrival&&t.realtime_arrival!==t.scheduled_arrival&&(0,i.jsx)("span",{className:"ml-2 text-gray-400 line-through",children:(0,i.jsx)(F,{display:b,value:t.scheduled_arrival})})]}),o<s.length-1&&(0,i.jsxs)("p",{children:["Dep ",(0,i.jsx)(F,{display:b,value:t.realtime_departure||t.scheduled_departure}),t.realtime_departure&&t.realtime_departure!==t.scheduled_departure&&(0,i.jsx)("span",{className:"ml-2 text-gray-400 line-through",children:(0,i.jsx)(F,{display:b,value:t.scheduled_departure})})]}),m||d?(0,i.jsx)("p",{className:"text-gray-400",children:m?"Not stopping":"Departed"}):Number.isFinite(u)?(0,i.jsx)("p",{className:u>=60?"text-amber-700":"text-emerald-700",children:60>Math.abs(u)?"On time":`${Math.round(Math.abs(u)/60)} min ${u>0?"late":"early"}`}):(0,i.jsx)("p",{className:"text-gray-400",children:"Scheduled"})]})]},`${t.stop_sequence}-${t.stop_id}`)})}):(0,i.jsx)("p",{className:"rounded-lg bg-gray-50 p-4 text-sm text-gray-500",role:"status",children:o?"Loading stopsâ¦":l?"Stop information is temporarily unavailable.":c?"No stops published for this trip.":"No stop schedule is available for this train."})]})}function D(){let t=(0,g.useRef)(null),e=(0,g.useRef)(!1),a=e=>{let a=t.current;if(a&&a.pointerId===e.pointerId&&(t.current=null,a.dragging)){let t=e.currentTarget;t.style.scrollSnapType=a.snapType,delete t.dataset.dragging,t.hasPointerCapture(e.pointerId)&&t.releasePointerCapture(e.pointerId)}};return{onPointerDown(a){e.current=!1,"mouse"===a.pointerType&&0===a.button&&(t.current={pointerId:a.pointerId,x:a.clientX,scrollLeft:a.currentTarget.scrollLeft,dragging:!1,snapType:a.currentTarget.style.scrollSnapType})},onPointerMove(i){let n=t.current;if(!n||n.pointerId!==i.pointerId)return;if(1!==i.buttons)return void a(i);let s=i.clientX-n.x;if(!n.dragging&&5>Math.abs(s))return;let r=i.currentTarget;n.dragging||(n.dragging=!0,e.current=!0,r.setPointerCapture(i.pointerId),r.style.scrollSnapType="none",r.dataset.dragging="true"),i.preventDefault(),r.scrollLeft=n.scrollLeft-s},onPointerUp:a,onPointerCancel:a,onLostPointerCapture:a,onPointerLeave(e){t.current?.dragging||a(e)},onClickCapture(t){e.current&&0!==t.detail&&(t.preventDefault(),t.stopPropagation(),e.current=!1)},onDragStart(t){t.preventDefault()}}}var G=a(81861),O=a(19114),K=a(48485),W=a(20433),J=a(45434),H=a(22128),V=a(17190),q=a(22961),Y=a(85542),Z=a(28766);function Q({isOpen:t,onClose:e,title:a="Track trains on the go",de
1scription:n="Get live train positions, arrivals, and trip info in your pocket. Download the app for iOS or Android."}){return(0,i.jsxs)(V.lG,{open:t,onClose:e,className:"fixed inset-0 z-[1000]",children:[(0,i.jsx)(V.Xi,{className:"fixed inset-0 bg-slate-950/40 backdrop-blur-sm"}),(0,i.jsx)("div",{className:"fixed inset-0 flex items-center justify-center overflow-y-auto p-4",children:(0,i.jsxs)(V.Lj,{className:"relative my-auto w-full max-w-md rounded-2xl bg-white p-6 text-center shadow-2xl sm:p-8",children:[(0,i.jsx)("button",{type:"button",onClick:e,"aria-label":"Close app download popup",className:"absolute right-3 top-3 rounded-full p-2 text-gray-500 hover:bg-gray-100 focus-visible:outline-blue-600",children:(0,i.jsx)(y.A,{className:"h-5 w-5"})}),(0,i.jsx)("img",{src:Z.A.src,alt:"trains.fyi",className:"mx-auto mb-5 mt-3 h-12 w-auto"}),(0,i.jsx)(V.L3,{className:"text-xl font-bold text-gray-900",children:a}),(0,i.jsx)(q.VY,{className:"mt-3 text-sm leading-relaxed text-gray-600",children:n}),(0,i.jsx)("div",{className:"mt-6 flex flex-col justify-center gap-3 sm:flex-row",children:[{href:"/ios/",Icon:Y.eMv,caption:"Download on the",label:"App Store"},{href:"/android/",Icon:Y.N8X,caption:"Get it on",label:"Google Play"}].map(({href:t,Icon:e,caption:a,label:n})=>(0,i.jsxs)("a",{href:t,target:"_blank",rel:"noopener noreferrer",className:"flex items-center justify-center gap-3 rounded-xl bg-gray-950 px-5 py-3 text-white hover:bg-gray-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600",children:[(0,i.jsx)(e,{"aria-hidden":"true",className:"h-6 w-6 shrink-0"}),(0,i.jsxs)("span",{className:"text-left",children:[(0,i.jsx)("span",{className:"block text-[10px] leading-tight",children:a}),(0,i.jsx)("span",{className:"block whitespace-nowrap text-sm font-semibold",children:n})]})]},t))}),(0,i.jsx)("button",{type:"button",onClick:e,className:"mt-5 rounded px-3 py-2 text-sm font-medium text-gray-500 hover:text-gray-900",children:"Maybe later"})]})})]})}function X({children:t,className:e,title:a,description:n}){let[s,r]=(0,g.useState)(!1);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("button",{type:"button",className:e,onClick:()=>r(!0),children:t}),(0,i.jsx)(Q,{isOpen:s,onClose:()=>r(!1),title:a,description:n})]})}var tt=a(1300);async function te([,t,e]){let a=[(0,J._M)("networkSlug","==",t),(0,J._M)("status","==","approved")],i=t=>(0,J.GG)((0,J.P)((0,J.rJ)(tt.db,"vehiclePhotos"),...a,...t,(0,J.My)("createdAt","desc"),(0,J.AB)(2))),n=await i([(0,J._M)("vehicleId","==",e)]),s=!n.empty;s||(n=await i([]));let r=(await Promise.allSettled(n.docs.map(async t=>{let e=t.data(),a=e.thumbnailPath||e.storagePath;return{id:t.id,credit:e.displayName,url:await (0,H.qk)((0,H.KR)((0,H.c7)(tt.A),a))}}))).filter(t=>"fulfilled"===t.status).map(t=>t.value);if(!n.empty&&!r.length)throw Error("Photos could not be loaded");return{exact:s,photos:r}}function ta({train:t,network:e}){let{data:a,error:n,isLoading:s}=(0,_.Ay)(["train-photos",t.agency,t.vid],te,{revalidateOnFocus:!1,shouldRetryOnError:!1}),[r,o]=(0,g.useState)({}),l=(0,g.useRef)(null),c=D(),[d,h]=(0,g.useState)({previous:!1,next:!0}),m=a?.photos.filter(t=>!r[t.id]).slice(0,2)??[],u=t=>{let e=l.current;e&&e.scrollBy({left:t*(e.clientWidth+8),behavior:window.matchMedia("(prefers-reduced-motion: reduce)").matches?"instant":"smooth"})};return s||n||m.length?(0,i.jsx)("section",{"aria-label":"Train photos","aria-busy":s,className:"border-b border-gray-100 py-4",children:m.length>0?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)("div",{className:"relative",children:[(0,i.jsxs)("div",{...c,ref:l,onScroll:t=>{let e=t.currentTarget;h({previous:e.scrollLeft>2,next:e.scrollLeft+e.clientWidth<e.scrollWidth-2})},className:"cursor-grab select-none data-[dragging=true]:cursor-grabbing flex snap-x snap-mandatory gap-2 overflow-x-auto rounded-lg [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:[m.map(n=>(0,i.jsxs)("figure",{className:"w-full shrink-0 snap-center",children:[(0,i.jsx)("img",{draggable:!1,src:n.url,alt:a.exact?`${t.name||"Train"} ${t.vid}`:`${e?.name||t.agency} network train`,className:"aspect-video w-full rounded-lg object-cover",onError:()=>o(t=>({...t,[n.id]:!0}))}),n.credit?.trim()&&(0,i.jsxs)("figcaption",{className:"mt-1 text-[10px] leading-tight text-gray-400",children:["Photo by ",function(t){let[e,...a
1]=(t||"").trim().split(/\s+/);return[e,...a.map(t=>`${Array.from(t)[0].toLocaleUpperCase()}.`)].join(" ")}(n.credit)]})]},n.id)),(0,i.jsx)("div",{className:"w-full shrink-0 snap-center",children:(0,i.jsxs)(X,{title:"See more train photos",description:"Download trains.fyi for iOS or Android to see more train photos.",className:"flex aspect-video w-full flex-col items-center justify-center gap-2 rounded-lg bg-blue-800 px-10 text-center text-white hover:bg-blue-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-4px] focus-visible:outline-white",children:[(0,i.jsx)(G.A,{className:"h-7 w-7","aria-hidden":"true"}),(0,i.jsx)("span",{className:"text-base font-bold",children:"Download the app"}),(0,i.jsx)("span",{className:"text-xs text-blue-100",children:"See more train photos on trains.fyi"})]})})]}),(0,i.jsxs)("div",{className:"pointer-events-none absolute inset-x-0 top-0 flex aspect-video items-center justify-between px-2",children:[d.previous?(0,i.jsx)("button",{type:"button",onClick:()=>u(-1),"aria-label":"Previous photo",className:"pointer-events-auto rounded-full bg-white/90 p-1.5 text-gray-800 shadow-sm hover:bg-white",children:(0,i.jsx)(O.A,{className:"h-4 w-4","aria-hidden":"true"})}):(0,i.jsx)("span",{}),d.next&&(0,i.jsx)("button",{type:"button",onClick:()=>u(1),"aria-label":"Next photo",className:"pointer-events-auto rounded-full bg-white/90 p-1.5 text-gray-800 shadow-sm hover:bg-white",children:(0,i.jsx)(K.A,{className:"h-4 w-4","aria-hidden":"true"})})]})]}),!a.exact&&(0,i.jsx)("p",{className:"mt-2 text-xs text-gray-500",children:"From this network \xb7 no photos of this vehicle yet"})]}):s?(0,i.jsxs)("div",{role:"status","aria-label":"Loading photos",children:[(0,i.jsx)(k,{className:"aspect-video w-full rounded-lg"}),(0,i.jsx)(k,{className:"mt-2 h-4 w-44"})]}):(0,i.jsxs)("div",{className:"rounded-lg bg-gray-50 px-4 py-5 text-center text-sm text-gray-500",children:[(0,i.jsx)(W.A,{className:"mx-auto mb-2 h-6 w-6 text-gray-400","aria-hidden":"true"}),s?"Loading photosâ¦":"Photos are temporarily unavailable."]})}):null}var ti=a(85519),tn=a(24033);let ts=[{label:"Live",description:"The operator has reported this trainâs location, usually by GPS. The map follows its latest position update, which may be a little behind the train."},{label:"Community",description:"This position is estimated from recent location reports by opted-in riders. Reports are checked against the trainâs route and must be independently corroborated; the position expires quickly."},{label:"Inferred",description:"We estimate the trainâs location from recent service updates, such as reported arrivals, departures or delays. Its exact position has not been confirmed by GPS."},{label:"Scheduled",description:"We estimate where the train would be based on its timetable. There are no live updates confirming its location or whether it is running on time."}];function tr({label:t,scheduleFallback:e=!1}){let a=(0,g.useId)(),[n,s]=(0,g.useState)(!1),[r,o]=(0,g.useState)(!1);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)("button",{type:"button",onClick:()=>o(!0),"aria-haspopup":"dialog","aria-label":`${t} position â learn how train locations work`,className:"inline-flex items-center gap-1 rounded font-medium text-gray-700 hover:text-gray-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800",children:[(0,i.jsx)(ti.A,{className:"h-3 w-3 shrink-0 text-gray-500","aria-hidden":"true"}),t]}),"Scheduled"===t&&e&&(0,i.jsxs)("span",{className:"relative inline-flex",children:[(0,i.jsx)("button",{type:"button","aria-label":"Live feed unavailable","aria-describedby":a,onMouseEnter:()=>s(!0),onMouseLeave:()=>s(!1),onFocus:()=>s(!0),onBlur:()=>s(!1),onClick:()=>s(!0),onKeyDown:t=>{"Escape"===t.key&&(t.stopPropagation(),s(!1))},className:"rounded text-red-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-red-600",children:(0,i.jsx)(tn.A,{className:"h-3.5 w-3.5","aria-hidden":"true"})}),(0,i.jsx)("span",{id:a,role:"tooltip",hidden:!n,className:"absolute left-0 top-full z-50 mt-2 w-52 rounded-lg bg-gray-900 px-3 py-2 text-xs font-normal leading-relaxed text-white shadow-lg",children:"Live updates from this networkâs provider are unavailable. Weâre currently showing timetable estimates."})]}),(0,i.jsxs)(V.lG,{open:r,onClose:o,className:"fixed inset-0 z-[1000]",children:[(0,i.jsx)(V.Xi,{className:"fixed inset-0 bg-slate-950/40"}),(0,i.jsx)("div",{className:"fixed inset-0 flex items-center justify-center overflow-y-auto p-5",children:(0,i.jsxs)(V.Lj,{className:"relative my-auto w-full max-w-sm rounded-2xl bg-white p-5 shadow-xl",children:[(0,i.jsx)(V.L3,{className:"pr-8 text-lg font-bold text-gray-900",children:"How we locate trains"}),(0,i.jsxs)(q.VY,{className:"mt-1 text-sm text-gray-500",children:["This trainâs position is ",t.toLowerCase(),"."]}),(0,i.jsx)("button",{type:"button",onClick:()=>o(!1),"aria-label":"Close position explanation",className:"absolute right-3 top-3 rounded-full p-2 text-gray-500 hover:bg-gray-100",children:(0,i.jsx)(y.A,{className:"h-4 w-4","aria-hidden":"true"})}),(0,i.jsx)("dl",{className:"mt-5 space-y-4",children:ts.map(e=>(0,i.jsxs)("div",{children:[(0,i.jsxs)("dt",{className:"flex items-center gap-2 text-sm font-semibold text-gray-900",children:[(0,i.jsx)(ti.A,{className:"h-3 w-3 text-gray-500","aria-hidden":"true"}),(0,i.jsx)("span",{children:e.label}),e.label===t&&(0,i.jsx)("span",{className:"rounded bg-gray-100 px-1.5 py-0.5 text-[10px] font-medium text-gray-500",children:"This train"})]}),(0,i.jsx)("dd",{className:"mt-1 text-sm leading-relaxed text-gray-600",children:e.description})]},e.label))})]})})]})]})}var to=a(95906);let tl=JSON.parse('{"schemaVersion":2,"baseUrl":"https://storage.googleapis.com/trainsfyi-train-artwork/v1","displayHeight":64,"assets":{"generic-freight-loco":{"label":"Generic Freight Loco","role":"locomotive","facing":"left","width":161,"height":64,"leftInset":0.45630098035260774,"rightInset":0.45633647082319406,"variants":[{"file":"[email protected]","density":1,"width":161,"height":64,"bytes":1848},{"file":"[email protected]","density":2,"width":322,"height":128,"bytes":4922}]},"freight-boxcar":{"label":"Freight Boxcar","role":"car","facing":"none","width":142,"height":64,"leftInset":0.4019016054468225,"rightInset":0.4018661612625546,"variants":[{"file":"[email protected]","density":1,"width":142,"height":64,"bytes":1324},{"file":"[email protected]","density":2,"width":284,"height":128,"bytes":3526}]},"freight-tank":{"label":"Freight Tank","role":"car","facing":"none","width":149,"height":64,"leftInset":0.41735566257496093,"rightInset":0.4173556625749445,"variants":[{"file":"[email protected]","density":1,"width":149,"height":64,"bytes":1470},{"file":"[email protected]","density":2,"width":298,"height":128,"bytes":3616}]},"freight-gondola":{"label":"Freight Gondola","role":"car","facing":"none","width":161,"height":64,"leftInset":0.4530827434298659,"rightInset":0.4531182988519403,"variants":[{"file":"[email protected]","density":1,"width":161,"height":64,"bytes":1038},{"file":"[email protected]","density":2,"width":322,"height":128,"bytes":2812}]},"freight-autorack":{"label":"Freight Autorack","role":"car","facing":"none","width":231,"he
1ight":64,"leftInset":0.6470641930299652,"rightInset":0.6470641930299756,"variants":[{"file":"[email protected]","density":1,"width":231,"height":64,"bytes":3056},{"file":"[email protected]","density":2,"width":462,"height":128,"bytes":10508}]},"freight-flatcar":{"label":"Freight Flatcar","role":"car","facing":"none","width":231,"height":64,"leftInset":0.6470653031801863,"rightInset":0.647065303180203,"variants":[{"file":"[email protected]","density":1,"width":231,"height":64,"bytes":1390},{"file":"[email protected]","density":2,"width":462,"height":128,"bytes":3666}]},"eurostar-e320-cab":{"label":"Eurostar E320 Cab","role":"car","facing":"left","width":241,"height":64,"leftInset":0.5550289777091022,"rightInset":0.6660418963127441,"variants":[{"file":"[email protected]","density":1,"width":241,"height":64,"bytes":2966},{"file":"[email protected]","density":2,"width":482,"height":128,"bytes":7250}]},"eurostar-e320-middle":{"label":"Eurostar E320 Middle","role":"car","facing":"none","width":193,"height":64,"leftInset":0.5333947489636113,"rightInset":0.5333947489636113,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":2318},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":5430}]},"eurostar-e320-cab-right":{"label":"Eurostar E320 Cab","role":"car","facing":"right","width":241,"height":64,"leftInset":0.6660418963127441,"rightInset":0.5550289777091043,"variants":[{"file":"[email protected]","density":1,"width":241,"height":64,"bytes":2908},{"file":"[email protected]","density":2,"width":482,"height":128,"bytes":7326}]},"avanti-390-cab":{"label":"Avanti 390 Cab","role":"car","facing":"left","width":190,"height":64,"leftInset":0.5272767652008364,"rightInset":0.5272767652008454,"variants":[{"file":"[email protected]","density":1,"width":190,"height":64,"bytes":1942},{"file":"[email protected]","density":2,"width":380,"height":128,"bytes":5030}]},"avanti-390-middle":{"label":"Avanti 390 Middle","role":"car","facing":"none","width":179,"height":64,"leftInset":0.4970069548431685,"rightInset":0.4970069548431683,"variants":[{"file":"[email protected]","density":1,"width":179,"height":64,"bytes":1816},{"file":"[email protected]","density":2,"width":358,"height":128,"bytes":4468}]},"avanti-390-cab-right":{"label":"Avanti 390 Cab","role":"car","facing":"right","width":190,"height":64,"leftInset":0.5272767652008454,"rightInset":0.5272767652008454,"variants":[{"file":"[email protected]","density":1,"width":190,"height":64,"bytes":1936},{"file":"[email protected]","density":2,"width":380,"height":128,"bytes":5040}]},"elizabeth-345-cab":{"label":"Elizabeth 345 Cab","role":"car","facing":"left","width":234,"height":64,"leftInset":0.6470100062116936,"rightInset":0.647010006211704,"variants":[{"file":"[email protected]","density":1,"width":234,"height":64,"bytes":2842},{"file":"[email protected]","density":2,"width":468,"height":128,"bytes":6796}]},"elizabeth-345-middle":{"label":"Elizabeth 345 Middle","role":"car","facing":"none","width":179,"height":64,"leftInset":0.49769785317251186,"rightInset":0.4976978531725117,"variants":[{"file":"[email protected]","density":1,"width":179,"height":64,"bytes":2234},{"file":"[email protected]","density":2,"width":358,"height":128,"bytes":5188}]},"elizabeth-345-cab-right":{"label":"Elizabeth 345 Cab","role":"car","facing":"right","width":234,"height":64,"leftInset":0.647010006211704,"rightInset":0.647010006211704,"variants":[{"file":"[email protected]","density":1,"width":234,"height":64,"bytes":2872},{"file":"[email protected]","density":2,"width":468,"height":128,"bytes":6928}]},"overground-710-cab":{"label":"Overground 710 Cab","role":"car","facing":"left","width":193,"height":64,"leftInset":0.5343793262574988,"rightInset":0.5343793262574988,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":2764},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":6524}]},"overground-710-middle":{"label":"Overground 710 Middle","role":"car","facing":"none","width":178,"height":64,"leftInset":0.49352503060767194,"rightInset":0.49352503060766395,"variants":[{"file":"[email protected]","density":1,"width":178,"height":64,"bytes":2454},{"file":"[email protected]","density":2,"width":356,"height":128,"bytes":5802}]},"overground-710-cab-right":{"label":"Overground 710 Cab","role":"car","facing":"right","width":193,"height":64,"leftInset":0.5343793262574988,"rightInset":0.5343793262574988,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":2728},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":6594}]},"thameslink-700-cab":{"label":"Thameslink 700 Cab","role":"car","facing":"left","width":162,"height":64,"leftInset":0.44835438151303697,"rightInset":0.44835438151305124,"variants":[{"file":"[email protected]","density":1,"width":162,"height":64,"bytes":1904},{"file":"[email protected]","density":2,"width":324,"height":128,"bytes":4526}]},"thameslink-700-middle":{"label":"Thameslink 700 Middle","role":"car","facing":"none","width":161,"height":64,"leftInset":0.44558121277783597,"rightInset":0.44558121277784174,"variants":[{"file":"[email protected]","density":1,"width":161,"height":64,"bytes":1848},{"file":"[email protected]","density":2,"width":322,"height":128,"bytes":4442}]},"thameslink-700-cab-right":{"label":"Thameslink 700 Cab","role":"car","facing":"right","width":162,"height":64,"leftInset":0.44835438151305124,"rightInset":0.4483543815130311,"variants":[{"file":"thameslink-700-cab-right.2ccc
1[email protected]","density":1,"width":162,"height":64,"bytes":1926},{"file":"[email protected]","density":2,"width":324,"height":128,"bytes":4546}]},"oebb-railjet-loco":{"label":"Oebb Railjet Loco","role":"locomotive","facing":"left","width":148,"height":64,"leftInset":0.4182661928606814,"rightInset":0.41826619286067734,"variants":[{"file":"[email protected]","density":1,"width":148,"height":64,"bytes":1782},{"file":"[email protected]","density":2,"width":296,"height":128,"bytes":4446}]},"oebb-railjet-middle":{"label":"Oebb Railjet Middle","role":"car","facing":"none","width":199,"height":64,"leftInset":0.550235,"rightInset":0.5502350000000054,"variants":[{"file":"[email protected]","density":1,"width":199,"height":64,"bytes":1802},{"file":"[email protected]","density":2,"width":398,"height":128,"bytes":4274}]},"oebb-railjet-cab-right":{"label":"Oebb Railjet Cab","role":"car","facing":"right","width":175,"height":64,"leftInset":0.4838742833602783,"rightInset":0.4838742833602783,"variants":[{"file":"[email protected]","density":1,"width":175,"height":64,"bytes":1780},{"file":"[email protected]","density":2,"width":350,"height":128,"bytes":4388}]},"sj-x2000-power":{"label":"Sj X2000 Power","role":"power","facing":"left","width":157,"height":64,"leftInset":0.4344879183361711,"rightInset":0.43452352334465366,"variants":[{"file":"[email protected]","density":1,"width":157,"height":64,"bytes":2036},{"file":"[email protected]","density":2,"width":314,"height":128,"bytes":5180}]},"sj-x2000-middle":{"label":"Sj X2000 Middle","role":"car","facing":"none","width":177,"height":64,"leftInset":0.49790517166968773,"rightInset":0.49786955868266625,"variants":[{"file":"[email protected]","density":1,"width":177,"height":64,"bytes":1780},{"file":"[email protected]","density":2,"width":354,"height":128,"bytes":4590}]},"sj-x2000-cab-right":{"label":"Sj X2000 Cab","role":"car","facing":"right","width":187,"height":64,"leftInset":0.5177503501110816,"rightInset":0.5177503501110816,"variants":[{"file":"[email protected]","density":1,"width":187,"height":64,"bytes":1922},{"file":"[email protected]","density":2,"width":374,"height":128,"bytes":4786}]},"cp-alfa-cab":{"label":"Cp Alfa Cab","role":"car","facing":"left","width":193,"height":64,"leftInset":0.5346260387811634,"rightInset":0.5346260387811634,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":2152},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":5268}]},"cp-alfa-middle":{"label":"Cp Alfa Middle","role":"car","facing":"none","width":185,"height":64,"leftInset":0.5119926199261992,"rightInset":0.5119926199262186,"variants":[{"file":"[email protected]","density":1,"width":185,"height":64,"bytes":2048},{"file":"[email protected]","density":2,"width":370,"height":128,"bytes":4834}]},"cp-alfa-cab-right":{"label":"Cp Alfa Cab","role":"car","facing":"right","width":193,"height":64,"leftInset":0.5346260387811634,"rightInset":0.5346260387811634,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":2072},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":5256}]},"pkp-ed250-cab":{"label":"Pkp Ed250 Cab","role":"car","facing":"left","width":193,"height":64,"leftInset":0.5343793262574988,"rightInset":0.5343793262574988,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":2510},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":5782}]},"pkp-ed250-middle":{"label":"Pkp Ed250 Middle","role":"car","facing":"none","width":173,"height":64,"leftInset":0.4794477021050952,"rightInset":0.4794477021050941,"variants":[{"file":"[email protected]","density":1,"width":173,"height":64,"bytes":2138},{"file":"[email protected]","density":2,"width":346,"height":128,"bytes":4770}]},"pkp-ed250-cab-right":{"label":"Pkp Ed250 Cab","role":"car","facing":"right","width":193,"height":64,"leftInset":0.5343793262574988,"rightInset":0.5343793262574988,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":2414},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":5732}]},"cd-680-cab":{"label":"Cd 680 Cab","role":"car","facing":"left","width":231,"he
1ight":64,"leftInset":0.63929889298893,"rightInset":0.6392988929889137,"variants":[{"file":"[email protected]","density":1,"width":231,"height":64,"bytes":2976},{"file":"[email protected]","density":2,"width":462,"height":128,"bytes":7510}]},"cd-680-middle":{"label":"Cd 680 Middle","role":"car","facing":"none","width":201,"height":64,"leftInset":0.5565236280707576,"rightInset":0.5565236280707592,"variants":[{"file":"[email protected]","density":1,"width":201,"height":64,"bytes":2530},{"file":"[email protected]","density":2,"width":402,"height":128,"bytes":6058}]},"cd-680-cab-right":{"label":"Cd 680 Cab","role":"car","facing":"right","width":231,"height":64,"leftInset":0.6392988929889137,"rightInset":0.6392988929889137,"variants":[{"file":"[email protected]","density":1,"width":231,"height":64,"bytes":2898},{"file":"[email protected]","density":2,"width":462,"height":128,"bytes":7398}]},"vr-sm3-cab":{"label":"Vr Sm3 Cab","role":"car","facing":"left","width":185,"height":64,"leftInset":0.5122288878634056,"rightInset":0.5976003691739958,"variants":[{"file":"[email protected]","density":1,"width":185,"height":64,"bytes":2598},{"file":"[email protected]","density":2,"width":370,"height":128,"bytes":5932}]},"vr-sm3-middle":{"label":"Vr Sm3 Middle","role":"car","facing":"none","width":210,"height":64,"leftInset":0.5825372078511758,"rightInset":0.5825372078511688,"variants":[{"file":"[email protected]","density":1,"width":210,"height":64,"bytes":2822},{"file":"[email protected]","density":2,"width":420,"height":128,"bytes":6270}]},"vr-sm3-cab-right":{"label":"Vr Sm3 Cab","role":"car","facing":"right","width":185,"height":64,"leftInset":0.5976003691739958,"rightInset":0.512228887863425,"variants":[{"file":"[email protected]","density":1,"width":185,"height":64,"bytes":2532},{"file":"[email protected]","density":2,"width":370,"height":128,"bytes":5802}]},"sncb-am96-cab":{"label":"Sncb Am96 Cab","role":"car","facing":"left","width":182,"height":64,"leftInset":0.5064784133567356,"rightInset":0.5064784133567176,"variants":[{"file":"[email protected]","density":1,"width":182,"height":64,"bytes":1920},{"file":"[email protected]","density":2,"width":364,"height":128,"bytes":4398}]},"sncb-am96-middle":{"label":"Sncb Am96 Middle","role":"car","facing":"none","width":184,"height":64,"leftInset":0.5122969837587006,"rightInset":0.51229698375872,"variants":[{"file":"[email protected]","density":1,"width":184,"height":64,"bytes":2140},{"file":"[email protected]","density":2,"width":368,"height":128,"bytes":4580}]},"sncb-am96-cab-right":{"label":"Sncb Am96 Cab","role":"car","facing":"right","width":182,"height":64,"leftInset":0.5064784133567176,"rightInset":0.5064784133567378,"variants":[{"file":"[email protected]","density":1,"width":182,"height":64,"bytes":1920},{"file":"[email protected]","density":2,"width":364,"height":128,"bytes":4374}]},"irish-22000-cab":{"label":"Irish 22000 Cab","role":"car","facing":"left","width":183,"height":64,"leftInset":0.508082881374086,"rightInset":0.5081185188070156,"variants":[{"file":"[email protected]","density":1,"width":183,"height":64,"bytes":2270},{"file":"[email protected]","density":2,"width":366,"height":128,"bytes":5460}]},"irish-22000-middle":{"label":"Irish 22000 Middle","role":"car","facing":"none","width":176,"height":64,"leftInset":0.49672230491991376,"rightInset":0.4966867765381959,"variants":[{"file":"[email protected]","density":1,"width":176,"height":64,"bytes":2022},{"file":"[email protected]","density":2,"width":352,"height":128,"bytes":4724}]},"irish-22000-cab-right":{"label":"Irish 22000 Cab","role":"car","facing":"right","width":183,"height":64,"leftInset":0.5081185188070156,"rightInset":0.5080828813740882,"variants":[{"file":"[email protected]","density":1,"width":183,"height":64,"bytes":2222},{"file":"[email protected]","density":2,"width":366,"height":128,"bytes":5390}]},"vy-74-cab":{"label":"Vy 74 Cab","role":"car","facing":"left","width":183,"height":64,"leftInset":0.5069100401773406,"rightInset":0.5069455953460354,"variants":[{"file":"[email protected]","density":1,"width":183,"height":64,"bytes":1948},{"file":"[email protected]","density":2,"width":366,"height":128,"bytes":4752}]},"vy-74-middle":{"label":"Vy 74 Middle","role":"car","facing":"none","width":173,"height":64,"leftInset":0.4790052012514605,"rightInset":0.4790052012514594,"variants":[{"file":"[email protected]","density":1,"width":173,"height":64,"bytes":1954},{"file":"[email protected]","density":2,"width":346,"height":128,"bytes":4518}]},"vy-74-cab-right":{"label":"Vy 74 Cab","role":"car","facing":"right","width":183,"height":64,"leftInset":0.5069455953460354,"rightInset":0.5069100401773429,"variants":[{"file":"[email protected]","density":1,"width":183,"height":64,"bytes":1968},{"file":"[email protected]","density":2,"width":366,"height":128,"bytes":4804}]},"sbb-giruno-cab":{"label":"SBB Giruno Cab","role":"car","facing":"left","width":188,"height":64,"leftInset":0.5219849043269916,"rightInset":0.5219849043270144,"variants":[{"file":"[email protected]","density":1,"width":188,"height":64,"bytes":2202},{"file":"[email protected]","density":2,"width":376,"height":128,"bytes":5292}]},"sbb-giruno-middle":{"label":"SBB Giruno Middle","role":"car","facing":"none","width":182,"height":64,"leftInset":0.505774616947128,"rightInset":0.5057746169471503,"variants":[{"file":"[email protected]","density":1,"width":182,"height":64,"bytes":2022},{"file":"[email protected]","density":2,"width":364,"height":128,"bytes":4370}]},"sbb-giruno-cab-right":{"label":"SBB Giruno Cab","role":"car","facing":"right","width":188,"height":64,"leftInset":0.5219849043270144,"rightInset":0.5219849043269741,"variants":[{"file":"[email protected]","density":1,"width":188,"height":64,"bytes":2234},{"file":"[email protected]","density":2,"width":376,"height":128,"bytes":5276}]},"db-regio-loco":{"label":"DB Regio Loco","role":"locomotive","facing":"left","width":141,"height":64,"leftInset":0.39219830374142534,"rightInset":0.3922339840820029,"variants":[{"file":"[email protected]","density":1,"width":141,"height":64,"bytes":1680}
1,{"file":"[email protected]","density":2,"width":282,"height":128,"bytes":4360}]},"db-regio-middle":{"label":"DB Regio Middle","role":"car","facing":"none","width":174,"height":64,"leftInset":0.48199780145431903,"rightInset":0.48199780145431625,"variants":[{"file":"[email protected]","density":1,"width":174,"height":64,"bytes":2200},{"file":"[email protected]","density":2,"width":348,"height":128,"bytes":5182}]},"db-regio-cab-right":{"label":"DB Regio Cab","role":"car","facing":"right","width":174,"height":64,"leftInset":0.48199780145431625,"rightInset":0.48199780145431625,"variants":[{"file":"[email protected]","density":1,"width":174,"height":64,"bytes":2280},{"file":"[email protected]","density":2,"width":348,"height":128,"bytes":5634}]},"mav-v63-loco":{"label":"Mav V63 Loco","role":"locomotive","facing":"left","width":149,"height":64,"leftInset":0.41696628233154015,"rightInset":0.4170018991661068,"variants":[{"file":"[email protected]","density":1,"width":149,"height":64,"bytes":2174},{"file":"[email protected]","density":2,"width":298,"height":128,"bytes":5516}]},"mav-intercity-coach":{"label":"Mav Intercity Coach","role":"car","facing":"none","width":191,"height":64,"leftInset":0.5283412321921633,"rightInset":0.5283412321921725,"variants":[{"file":"[email protected]","density":1,"width":191,"height":64,"bytes":2144},{"file":"[email protected]","density":2,"width":382,"height":128,"bytes":4922}]},"cfr-060-loco":{"label":"Cfr 060 Loco","role":"locomotive","facing":"left","width":134,"height":64,"leftInset":0.37586821331250697,"rightInset":0.37586821331249365,"variants":[{"file":"[email protected]","density":1,"width":134,"height":64,"bytes":2034},{"file":"[email protected]","density":2,"width":268,"height":128,"bytes":5168}]},"cfr-intercity-coach":{"label":"Cfr Intercity Coach","role":"car","facing":"none","width":175,"height":64,"leftInset":0.4888166601965002,"rightInset":0.48881666019649817,"variants":[{"file":"[email protected]","density":1,"width":175,"height":64,"bytes":1688},{"file":"[email protected]","density":2,"width":350,"height":128,"bytes":3856}]},"zssk-350-loco":{"label":"Zssk 350 Loco","role":"locomotive","facing":"left","width":133,"height":64,"leftInset":0.37186235154095176,"rightInset":0.37186235154094976,"variants":[{"file":"[email protected]","density":1,"width":133,"height":64,"bytes":2062},{"file":"[email protected]","density":2,"width":266,"height":128,"bytes":5058}]},"zssk-intercity-coach":{"label":"Zssk Intercity Coach","role":"car","facing":"none","width":161,"height":64,"leftInset":0.448899752479072,"rightInset":0.4488642157665608,"variants":[{"file":"[email protected]","density":1,"width":161,"height":64,"bytes":1930},{"file":"[email protected]","density":2,"width":322,"height":128,"bytes":4498}]},"hzpp-1142-loco":{"label":"Hzpp 1142 Loco","role":"locomotive","facing":"left","width":125,"height":64,"leftInset":0.3499761549248596,"rightInset":0.3499761549248697,"variants":[{"file":"[email protected]","density":1,"width":125,"height":64,"bytes":2032},{"file":"[email protected]","density":2,"width":250,"height":128,"bytes":5094}]},"hzpp-intercity-coach":{"label":"Hzpp Intercity Coach","role":"car","facing":"none","width":167,"height":64,"leftInset":0.38462211981370475,"rightInset":0.384622119813702,"variants":[{"file":"[email protected]","density":1,"width":167,"height":64,"bytes":2142},{"file":"[email protected]","density":2,"width":334,"height":128,"bytes":5124}]},"hellenic-470-cab":{"label":"Hellenic 470 Cab","role":"car","facing":"left","width":192,"height":64,"leftInset":0.4444444444444444,"rightInset":0.5333333333333333,"variants":[{"file":"[email protected]","density":1,"width":192,"height":64,"bytes":2364},{"file":"[email protected]","density":2,"width":384,"height":128,"bytes":5828}]},"hellenic-470-middle":{"label":"Hellenic 470 Middle","role":"car","facing":"none","width":200,"height":64,"leftInset":0.5570969171384181,"rightInset":0.5570969171384198,"variants":[{"file":"[email protected]","density":1,"width":200,"height":64,"bytes":2218},{"file":"[email protected]","density":2,"width":400,"height":128,"bytes":5280}]},"hellenic-470-cab-right":{"label":"Hellenic 470 Cab","role":"car","facing":"right","width":192,"height":64,"leftInset":0.5333333333333333,"rightInset":0.4444444444444444,"variants":[{"file":"[email protected]","density":1,"width":192,"height":64,"bytes":2328},{"file":"[email protected]","density":2,"width":384,"height":128,"bytes":5798}]},"uz-hrcs2-cab":{"label":"Uz Hrcs2 Cab","role":"car","facing":"left","width":175,"height":64,"leftInset":0.4838742833602811,"rightInset":0.4838742833602783,"variants":[{"file":"[email protected]","density":1,"width":175,"height":64,"bytes":2036},{"file":"[email protected]","density":2,"width":350,"height":128,"bytes":4714}]},"uz-hrcs2-middle":{"label":"Uz Hrcs2 Middle","role":"car","facing":"none","width":171,"height":64,"leftInset":0.4730172199170124,"rightInset":0.4730172199170154,"variants":[{"file":"[email protected]","density":1,"width":171,"height":64,"bytes":1890},{"file":"[email protected]","density":2,"width":342,"height":128,"bytes":4618}]},"uz-hrcs2-cab-right":{"label":"Uz Hrcs2 Cab","role":"car","facing":"right","width":175,"height":64,"leftInset":0.4838742833602783,"rightInset":0.4838742833602783,"variants":[{"file":"uz-hrcs2-cab-right.13a4d6b44821@
11x.webp","density":1,"width":175,"height":64,"bytes":1990},{"file":"[email protected]","density":2,"width":350,"height":128,"bytes":4772}]},"bdz-smartron-loco":{"label":"Bdz Smartron Loco","role":"locomotive","facing":"left","width":143,"height":64,"leftInset":0.3966787320466797,"rightInset":0.3966787320466882,"variants":[{"file":"[email protected]","density":1,"width":143,"height":64,"bytes":1818},{"file":"[email protected]","density":2,"width":286,"height":128,"bytes":4740}]},"bdz-intercity-coach":{"label":"Bdz Intercity Coach","role":"car","facing":"none","width":174,"height":64,"leftInset":0.4840088832939444,"rightInset":0.48400888329396186,"variants":[{"file":"[email protected]","density":1,"width":174,"height":64,"bytes":1940},{"file":"[email protected]","density":2,"width":348,"height":128,"bytes":4416}]},"soko-kiss-cab":{"label":"Soko KISS Cab","role":"car","facing":"left","width":183,"height":64,"leftInset":0.33732892253486707,"rightInset":0.5060111286167356,"variants":[{"file":"[email protected]","density":1,"width":183,"height":64,"bytes":2280},{"file":"[email protected]","density":2,"width":366,"height":128,"bytes":5556}]},"soko-kiss-middle":{"label":"Soko KISS Middle","role":"car","facing":"none","width":185,"height":64,"leftInset":0.5162629570572134,"rightInset":0.5162629570571918,"variants":[{"file":"[email protected]","density":1,"width":185,"height":64,"bytes":2274},{"file":"[email protected]","density":2,"width":370,"height":128,"bytes":5660}]},"soko-kiss-cab-right":{"label":"Soko KISS Cab","role":"car","facing":"right","width":183,"height":64,"leftInset":0.5060111286167356,"rightInset":0.33732892253487906,"variants":[{"file":"[email protected]","density":1,"width":183,"height":64,"bytes":2304},{"file":"[email protected]","density":2,"width":366,"height":128,"bytes":5602}]},"vivi-16ev-cab":{"label":"Vivi 16Ev Cab","role":"car","facing":"left","width":217,"height":64,"leftInset":0.6019354889415836,"rightInset":0.6019354889416009,"variants":[{"file":"[email protected]","density":1,"width":217,"height":64,"bytes":3054},{"file":"[email protected]","density":2,"width":434,"height":128,"bytes":7350}]},"vivi-16ev-middle":{"label":"Vivi 16Ev Middle","role":"car","facing":"none","width":225,"height":64,"leftInset":0.6238455527839437,"rightInset":0.6238455527839651,"variants":[{"file":"[email protected]","density":1,"width":225,"height":64,"bytes":2904},{"file":"[email protected]","density":2,"width":450,"height":128,"bytes":6788}]},"vivi-16ev-cab-right":{"label":"Vivi 16Ev Cab","role":"car","facing":"right","width":217,"height":64,"leftInset":0.6019354889416009,"rightInset":0.6019354889416009,"variants":[{"file":"[email protected]","density":1,"width":217,"height":64,"bytes":3094},{"file":"[email protected]","density":2,"width":434,"height":128,"bytes":7252}]},"ltg-730-cab":{"label":"Ltg 730 Cab","role":"car","facing":"left","width":188,"height":64,"leftInset":0.5219849043269916,"rightInset":0.5219849043270144,"variants":[{"file":"[email protected]","density":1,"width":188,"height":64,"bytes":2630},{"file":"[email protected]","density":2,"width":376,"height":128,"bytes":6032}]},"ltg-730-middle":{"label":"Ltg 730 Middle","role":"car","facing":"none","width":183,"height":64,"leftInset":0.5066761410807318,"rightInset":0.506676141080734,"variants":[{"file":"[email protected]","density":1,"width":183,"height":64,"bytes":2528},{"file":"[email protected]","density":2,"width":366,"height":128,"bytes":5690}]},"ltg-730-cab-right":{"label":"Ltg 730 Cab","role":"car","facing":"right","width":188,"height":64,"leftInset":0.5219849043270144,"rightInset":0.5219849043269741,"variants":[{"file":"[email protected]","density":1,"width":188,"height":64,"bytes":2556},{"file":"[email protected]","density":2,"width":376,"height":128,"bytes":6094}]},"elron-flirt-cab":{"label":"Elron FLIRT Cab","role":"car","facing":"left","width":176,"height":64,"leftInset":0.4872994783312333,"rightInset":0.4872994783312313,"variants":[{"file":"[email protected]","density":1,"width":176,"height":64,"bytes":2140},{"file":"[email protected]","density":2,"width":352,"height":128,"bytes":5354}]},"elron-flirt-middle":{"label":"Elron FLIRT Middle","role":"car","facing":"none","width":174,"height":64,"leftInset":0.4822204183817375,"rightInset":0.48222041838173474,"variants":[{"file":"[email protected]","density":1,"width":174,"height":64,"bytes":1946},{"file":"[email protected]","density":2,"width":348,"height":128,"bytes":4528}]},"elron-flirt-cab-right":{"label":"Elron FLIRT Cab","role":"car","facing":"right","width":176,"height":64,"leftInset":0.4872994783312313,"rightInset":0.4872994783312313,"variants":[{"file":"[email protected]","density":1,"width":176,"height":64,"bytes":2108},{"file":"[email protected]","density":2,"width":352,"height":128,"bytes":5270}]},"nightjet-taurus-loco":{"label":"Nightjet Taurus Loco","role":"locomotive","facing":"left","width":145,"height":64,"leftInset":0.4024200198302897,"rightInset":0.40238452992641577,"variants":[{"file":"[email protected]","density":1,"width":145,"height":64,"bytes":2260},{"file":"[email protected]","density":2,"width":290,"height":128,"bytes":5890}]},"nightjet-sleeper":{"label":"Nightjet Sleeper","role":"car","facing":"none","width":181,"height":64,"leftInset":0.5011661512537008,"rightInset":0.5011661512537108,"variants":[{"file":"[email protected]","density":1,"width":181,"height":64,"bytes":2048},{"file":"[email protected]","density":2,"width":362,"height":128,"bytes":4494}]},"nightjet-couchette":{"label":"Nightjet Couchette","role":"car","facing":"none","width":167,"he
1ight":64,"leftInset":0.46175210341585005,"rightInset":0.4617521034158526,"variants":[{"file":"[email protected]","density":1,"width":167,"height":64,"bytes":2030},{"file":"[email protected]","density":2,"width":334,"height":128,"bytes":4618}]},"nightjet-seat":{"label":"Nightjet Seat","role":"car","facing":"none","width":171,"height":64,"leftInset":0.4730172199170124,"rightInset":0.4730172199170154,"variants":[{"file":"[email protected]","density":1,"width":171,"height":64,"bytes":2040},{"file":"[email protected]","density":2,"width":342,"height":128,"bytes":4516}]},"nightjet-cab-right":{"label":"Nightjet Cab","role":"car","facing":"right","width":193,"height":64,"leftInset":0.5336405529953917,"rightInset":0.5336405529953917,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":2170},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":5034}]},"eurostar-red-power":{"label":"Eurostar Red Power","role":"power","facing":"left","width":167,"height":64,"leftInset":0.38444505107942223,"rightInset":0.4613269491863261,"variants":[{"file":"[email protected]","density":1,"width":167,"height":64,"bytes":2126},{"file":"[email protected]","density":2,"width":334,"height":128,"bytes":5264}]},"eurostar-red-coach":{"label":"Eurostar Red Coach","role":"car","facing":"none","width":174,"height":64,"leftInset":0.4828896033457172,"rightInset":0.4828896033457346,"variants":[{"file":"[email protected]","density":1,"width":174,"height":64,"bytes":1942},{"file":"[email protected]","density":2,"width":348,"height":128,"bytes":4624}]},"eurostar-red-power-right":{"label":"Eurostar Red Power","role":"power","facing":"right","width":167,"height":64,"leftInset":0.4613269491863261,"rightInset":0.38444505107941945,"variants":[{"file":"[email protected]","density":1,"width":167,"height":64,"bytes":2122},{"file":"[email protected]","density":2,"width":334,"height":128,"bytes":5228}]},"london-s-cab":{"label":"London S Cab","role":"car","facing":"left","width":181,"height":64,"leftInset":0.5016291338363187,"rightInset":0.5016291338363286,"variants":[{"file":"[email protected]","density":1,"width":181,"height":64,"bytes":2400},{"file":"[email protected]","density":2,"width":362,"height":128,"bytes":5982}]},"london-s-middle":{"label":"London S Middle","role":"car","facing":"none","width":181,"height":64,"leftInset":0.5013975356673274,"rightInset":0.5013975356673374,"variants":[{"file":"[email protected]","density":1,"width":181,"height":64,"bytes":2574},{"file":"[email protected]","density":2,"width":362,"height":128,"bytes":6214}]},"london-s-cab-right":{"label":"London S Cab","role":"car","facing":"right","width":181,"height":64,"leftInset":0.5016291338363286,"rightInset":0.5016291338363286,"variants":[{"file":"[email protected]","density":1,"width":181,"height":64,"bytes":2414},{"file":"[email protected]","density":2,"width":362,"height":128,"bytes":5960}]},"bart-d-cab":{"label":"Bart D Cab","role":"car","facing":"left","width":191,"height":64,"leftInset":0.3520770442266373,"rightInset":0.5280977792810468,"variants":[{"file":"[email protected]","density":1,"width":191,"height":64,"bytes":2478},{"file":"[email protected]","density":2,"width":382,"height":128,"bytes":5842}]},"bart-e-middle":{"label":"Bart E Middle","role":"car","facing":"none","width":189,"height":64,"leftInset":0.43548747658669484,"rightInset":0.5225849719040162,"variants":[{"file":"[email protected]","density":1,"width":189,"height":64,"bytes":2282},{"file":"[email protected]","density":2,"width":378,"height":128,"bytes":5330}]},"bart-d-cab-right":{"label":"Bart D Cab","role":"car","facing":"right","width":191,"height":64,"leftInset":0.5280977792810468,"rightInset":0.3520770442266269,"variants":[{"file":"[email protected]","density":1,"width":191,"height":64,"bytes":2434},{"file":"[email protected]","density":2,"width":382,"height":128,"bytes":5978}]},"wmata-7000-cab":{"label":"Wmata 7000 Cab","role":"car","facing":"left","width":180,"height":64,"leftInset":0.500940184401908,"rightInset":0.5009047020259043,"variants":[{"file":"[email protected]","density":1,"width":180,"height":64,"bytes":2106},{"file":"[email protected]","density":2,"width":360,"height":128,"bytes":5382}]},"wmata-7000-middle":{"label":"Wmata 7000 Middle","role":"car","facing":"none","width":181,"height":64,"leftInset":0.5032563311313292,"rightInset":0.503256331131339,"variants":[{"file":"[email protected]","density":1,"width":181,"height":64,"bytes":2040},{"file":"[email protected]","density":2,"width":362,"height":128,"bytes":4938}]},"wmata-7000-cab-right":{"label":"Wmata 7000 Cab","role":"car","facing":"right","width":180,"height":64,"leftInset":0.5009047020259043,"rightInset":0.500940184401918,"variants":[{"file":"[email protected]","density":1,"width":180,"height":64,"bytes":2116},{"file":"[email protected]","density":2,"width":360,"height":128,"bytes":5482}]},"cta-7000-cab":{"label":"Cta 7000 Cab","role":"car","facing":"left","width":151,"height":64,"leftInset":0.42079822260418703,"rightInset":0.4207982226041829,"variants":[{"file":"[email protected]","density":1,"width":151,"height":64,"bytes":1952},{"file":"[email protected]","density":2,"width":302,"height":128,"bytes":4756}]},"cta-7000-cab-right":{"label":"Cta 7000 Cab","role":"car","facing":"right","width":151,"height":64,"leftInset":0.4207982226041829,"rightInset":0.4207982226041829,"variants":[{"file":"[email protected]","density":1,"width":151,"height":64,"bytes":1994},{"file":"[email protected]","density":2,"width":302,"height":128,"bytes":4732}]},"mbta-red-cab":{"label":"Mbta Red Cab","role":"car","facing":"left","width":180,"height":64,"leftInset":0.498399784525441,"rightInset":0.4983641361609175,"variants":[{"file":"[email protected]","density":1,"width":180,"height":64,"bytes":2372},{"file":"[email protected]","density":2,"width":360,"height":128,"bytes":5480}]},"mbta-red-cab-right":{"label":"Mbta Red Cab","role":"car","facing":"right","width":180,"height":64,"leftInset":0.4983641361609175,"rightInset":0.4983997845254408,"variants":[{"file":"[email protected]","density":1,"width":180,"height":64,"bytes":2390},{"file":"[email protected]","density":2,"width":360,"height":128,"bytes":5696}]},"mnr-m8-cab":{"label":"Mnr M8 Cab","role":"car","facing":"left","width":181,"height":64,"leftInset":0.5011661512537008,"rightInset":0.5011661512537108,"variants":[{"file":"[email protected]","density":1,"width":181,"height":64,"bytes":2560},{"file":"[email protected]","density":2,"width":362,"height":128,"bytes":6200}]},"mnr-m8-cab-right":{"label":"Mnr M8 Cab","role":"car","facing":"right","width":181,"height":64,"leftInset":0.5011661512537108,"rightInset":0.5011661512537108,"variants":[{"file":"[email protected]","density":1,"width":181,"height":64,"bytes":2530},{"file":"[email protected]","density":2,"width":362,"height":128,"bytes":6242}]},"septa-silverliner-cab":{"label":"Septa Silverliner Cab","role":"car","facing":"left","width":175,"height":64,"leftInset":0.32229769959184473,"rightInset":0.4028632281195991,"variants":[{"file":"[email protected]","density":1,"width":175,"height":64,"bytes":2560},{"file":"[email protected]","density":2,"width":350,"height":128,"bytes":6354}]},"septa-silverliner-cab-right":{"label":"Septa Silverliner Cab","role":"car","facing":"right","width":175,"height":64,"leftInset":0.4028632281195991,"rightInset":0.3222976995918534,"variants":[{"file":"[email protected]","density":1,"width":175,"height":64,"bytes":2548},{"file":"[email protected]","density":2,"width":350,"height":128,"bytes":6288}]},"stm-azur-cab":{"label":"Stm Azur Cab","role":"car","facing":"left","width":169,"height":64,"leftInset":0.4707517913650134,"rightInset":0.4707517913650139,"variants":[{"file":"[email protected]","density":1,"width":169,"height":64,"bytes":2316},{"file":"[email protected]","density":2,"width":338,"height":128,"bytes":5346}]},"stm-azur-middle":{"label":"Stm Azur Middle","role":"car","facing":"none","width":193,"height":64,"leftInset":0.5378578816794806,"rightInset":0.5378578816794851,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":2424},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":5154}]},"stm-azur-cab-right":{"label":"Stm Azur Cab","role":"car","facing":"right","width":169,"height":64,"leftInset":0.4707517913650139,"rightInset":0.4707517913650139,"variants":[{"file":"[email protected]","density":1,"width":169,"height":64,"bytes":2330},{"file":"[email protected]","density":2,"width":338,"height":128,"bytes":5282}]}
1,"skytrain-mark3-cab":{"label":"Skytrain Mark3 Cab","role":"car","facing":"left","width":175,"height":64,"leftInset":0.4028632281196063,"rightInset":0.4028632281195991,"variants":[{"file":"[email protected]","density":1,"width":175,"height":64,"bytes":2052},{"file":"[email protected]","density":2,"width":350,"height":128,"bytes":5082}]},"skytrain-mark3-middle":{"label":"Skytrain Mark3 Middle","role":"car","facing":"none","width":174,"height":64,"leftInset":0.48177538997414615,"rightInset":0.4817753899741433,"variants":[{"file":"[email protected]","density":1,"width":174,"height":64,"bytes":1900},{"file":"[email protected]","density":2,"width":348,"height":128,"bytes":4554}]},"skytrain-mark3-cab-right":{"label":"Skytrain Mark3 Cab","role":"car","facing":"right","width":175,"height":64,"leftInset":0.4028632281195991,"rightInset":0.4028632281195991,"variants":[{"file":"[email protected]","density":1,"width":175,"height":64,"bytes":2030},{"file":"[email protected]","density":2,"width":350,"height":128,"bytes":5166}]},"mtr-c-cab":{"label":"Mtr C Cab","role":"car","facing":"left","width":188,"height":64,"leftInset":0.5217434661946471,"rightInset":0.5217434661946294,"variants":[{"file":"[email protected]","density":1,"width":188,"height":64,"bytes":2304},{"file":"[email protected]","density":2,"width":376,"height":128,"bytes":5426}]},"mtr-c-middle":{"label":"Mtr C Middle","role":"car","facing":"none","width":186,"height":64,"leftInset":0.515933981687516,"rightInset":0.5159339816875348,"variants":[{"file":"[email protected]","density":1,"width":186,"height":64,"bytes":2320},{"file":"[email protected]","density":2,"width":372,"height":128,"bytes":5182}]},"mtr-c-cab-right":{"label":"Mtr C Cab","role":"car","facing":"right","width":188,"height":64,"leftInset":0.5217434661946294,"rightInset":0.5217434661946294,"variants":[{"file":"[email protected]","density":1,"width":188,"height":64,"bytes":2262},{"file":"[email protected]","density":2,"width":376,"height":128,"bytes":5406}]},"singapore-r151-cab":{"label":"Singapore R151 Cab","role":"car","facing":"left","width":181,"height":64,"leftInset":0.500935078499546,"rightInset":0.5008995964852013,"variants":[{"file":"[email protected]","density":1,"width":181,"height":64,"bytes":2340},{"file":"[email protected]","density":2,"width":362,"height":128,"bytes":5396}]},"singapore-r151-middle":{"label":"Singapore R151 Middle","role":"car","facing":"none","width":180,"height":64,"leftInset":0.49794013867483866,"rightInset":0.4979401386748385,"variants":[{"file":"[email protected]","density":1,"width":180,"height":64,"bytes":2094},{"file":"[email protected]","density":2,"width":360,"height":128,"bytes":4828}]},"singapore-r151-cab-right":{"label":"Singapore R151 Cab","role":"car","facing":"right","width":181,"height":64,"leftInset":0.5008995964852013,"rightInset":0.5009350784995559,"variants":[{"file":"[email protected]","density":1,"width":181,"height":64,"bytes":2330},{"file":"[email protected]","density":2,"width":362,"height":128,"bytes":5310}]},"ns-virm-cab":{"label":"Ns Virm Cab","role":"car","facing":"left","width":185,"height":64,"leftInset":0.34132841328413277,"rightInset":0.5119926199262186,"variants":[{"file":"[email protected]","density":1,"width":185,"height":64,"bytes":2698},{"file":"[email protected]","density":2,"width":370,"height":128,"bytes":6380}]},"ns-virm-middle":{"label":"Ns Virm Middle","role":"car","facing":"none","width":246,"height":64,"leftInset":0.5678670360110804,"rightInset":0.6814404432132819,"variants":[{"file":"[email protected]","density":1,"width":246,"height":64,"bytes":3272},{"file":"[email protected]","density":2,"width":492,"height":128,"bytes":7800}]},"ns-virm-cab-right":{"label":"Ns Virm Cab","role":"car","facing":"right","width":185,"height":64,"leftInset":0.5119926199262186,"rightInset":0.34132841328414576,"variants":[{"file":"[email protected]","density":1,"width":185,"height":64,"bytes":2748},{"file":"[email protected]","density":2,"width":370,"height":128,"bytes":6356}]},"renfe-103-cab":{"label":"Renfe 103 Cab","role":"car","facing":"left","width":226,"height":64,"leftInset":0.6257507561365587,"rightInset":0.6257507561365803,"variants":[{"file":"[email protected]","density":1,"width":226,"height":64,"bytes":2260},{"file":"[email protected]","density":2,"width":452,"height":128,"bytes":5330}]},"renfe-103-middle":{"label":"Renfe 103 Middle","role":"car","facing":"none","width":228,"height":64,"leftInset":0.6333412500000001,"rightInset":0.6333412499999845,"variants":[{"file":"[email protected]","density":1,"width":228,"height":64,"bytes":2146},{"file":"[email protected]","density":2,"width":456,"height":128,"bytes":4984}]},"renfe-103-cab-right":{"label":"Renfe 103 Cab","role":"car","facing":"right","width":226,"height":64,"leftInset":0.6257507561365803,"rightInset":0.6257507561365397,"variants":[{"file":"[email protected]","density":1,"width":226,"height":64,"bytes":2266},{"file":"[email protected]","density":2,"width":452,"height":128,"bytes":5148}]},"trenitalia-1000-cab":{"label":"Trenitalia 1000 Cab","role":"car","facing":"left","width":177,"height":64,"leftInset":0.4889401319872351,"rightInset":0.48894013198725333,"variants":[{"file":"[email protected]","density":1,"width":177,"height":64,"bytes":2254},{"file":"[email protected]","density":2,"width":354,"height":128,"bytes":5752}]},"trenitalia-1000-middle":{"label":"Trenitalia 1000 Middle","role":"car","facing":"none","width":165,"height":64,"leftInset":0.1519438212434732,"rightInset":0.1519438212434793,"variants":[{"file":"[email protected]","density":1,"width":165,"height":64,"bytes":1786},{"file":"[email protected]","density":2,"width":330,"height":128,"bytes":4230}]},"trenitalia-1000-cab-right":{"label":"Trenitalia 1000 Cab","role":"car","facing":"right","width":177,"height":64,"leftInset":0.48894013198725333,"rightInset":0.4889401319872331,"variants":[{"file":"[email protected]","density":1,"width":177,"height":64,"bytes":2240},{"file":"[email protected]","density":2,"width":354,"height":128,"bytes":5664}]},"go-mp40-left":{"label":"GO MP40","role":"locomotive","facing":"left","width":204,"height":64,"leftInset":0.6790328362740033,"rightInset":0.6790328362739895,"variants":[{"file":"[email protected]","density":1,"width":204,"height":64,"bytes":2772},{"file":"[email protected]","density":2,"width":408,"height":128,"bytes":7140}]},"go-bilevel-coach":{"label":"GO Bilevel Coach","role":"car","facing":"none","width":267,"height":64,"leftInset":0.7506857515684856,"rightInset":0.7506857515685023,"variants":[{"file":"[email protected]","density":1,"width":267,"height":64,"bytes":3508},{"file":"[email protected]","density":2,"width":534,"height":128,"bytes":8054}]},"go-bilevel-cab-right":{"label":"GO Bilevel Cab","role":"car","facing":"right","width":297,"height":64,"leftInset":0.8417805791073915,"rightInset":0.8417373221403363,"variants":[{"file":"[email protected]","density":1,"width":297,"height":64,"bytes":4084},{"file":"[email protected]","density":2,"width":594,"height":128,"bytes":9204}]},"via-charger":{"label":"VIA Charger","role":"locomotive","facing":"left","width":212,"height":64,"leftInset":0.5963365665651641,"rightInset":0.596336566565161,"variants":[{"file":"[email protected]","density":1,"width":212,"height":64,"bytes":3184},{"file":"[email protected]","density":2,"width":424,"height":128,"bytes":8048}]},"via-business":{"label":"VIA business car","role":"car","facing":"none","width":314,"height":64,"leftInset":0.9697441112800506,"rightInset":1.163671599378949,"variants":[{"file":"[email protected]","density":1,"width":314,"height":64,"bytes":2224},{"file":"[email protected]","density":2,"width":628,"height":128,"bytes":4956}]},"via-economy":{"label":"VIA economy car","role":"car","facing":"none","width":346,"height":64,"leftInset":1.0672424429364589,"rightInset":1.280690931523759,"variants":[{"file":"[email protected]","density":1,"width":346,"height":64,"bytes":2570},{"file":"[email protected]","density":2,"width":692,"height":128,"bytes":5294}]},"via-venture-cab-right":{"label":"VIA Venture Cab","role":"car","facing":"right","width":222,"height":64,"leftInset":0.7271945888440575,"rightInset":0.6233045770543699,"variants":[{"file":"[email protected]","density":1,"width":222,"height":64,"bytes":2698},{"file":"[email protected]","density":2,"width":444,"height":128,"bytes":6050}]},"via-f40":{"label":"VIA F40","role":"locomotive","facing":"left","width":153,"height":64,"leftInset":0.4346452282606848,"rightInset":0.43464522826068797,"variants":[{"file":"[email protected]","density":1,"width":153,"height":64,"bytes":2298},{"file":"[email protected]","density":2,"width":306,"height":128,"bytes":5744}]}
1,"via-budd-coach":{"label":"VIA Budd Coach","role":"car","facing":"none","width":184,"height":64,"leftInset":0.5974025974025974,"rightInset":0.59740259740262,"variants":[{"file":"[email protected]","density":1,"width":184,"height":64,"bytes":1888},{"file":"[email protected]","density":2,"width":368,"height":128,"bytes":4688}]},"via-budd-sleeper":{"label":"VIA Budd Sleeper","role":"car","facing":"none","width":205,"height":64,"leftInset":0.5758506944444445,"rightInset":0.5758506944444629,"variants":[{"file":"[email protected]","density":1,"width":205,"height":64,"bytes":2340},{"file":"[email protected]","density":2,"width":410,"height":128,"bytes":6132}]},"via-dome":{"label":"VIA Dome","role":"car","facing":"none","width":193,"height":64,"leftInset":0.537608210987628,"rightInset":0.5376082109876327,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":2582},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":5956}]},"amtrak-p42":{"label":"Amtrak P42","role":"locomotive","facing":"left","width":163,"height":64,"leftInset":0.46505312133039134,"rightInset":0.46505312133039167,"variants":[{"file":"[email protected]","density":1,"width":163,"height":64,"bytes":2150},{"file":"[email protected]","density":2,"width":326,"height":128,"bytes":5442}]},"amtrak-amfleet-coach":{"label":"Amtrak Amfleet Coach","role":"car","facing":"none","width":193,"height":64,"leftInset":0.5388589870093365,"rightInset":0.5388589870093412,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":1610},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":3974}]},"amtrak-amfleet-cafe":{"label":"Amtrak Amfleet Cafe","role":"car","facing":"none","width":236,"height":64,"leftInset":0.6570930159081096,"rightInset":0.6570574242595315,"variants":[{"file":"[email protected]","density":1,"width":236,"height":64,"bytes":2114},{"file":"[email protected]","density":2,"width":472,"height":128,"bytes":5034}]},"amtrak-acs64":{"label":"Amtrak ACS64","role":"locomotive","facing":"left","width":154,"height":64,"leftInset":0.5009418990232636,"rightInset":0.5009418990232534,"variants":[{"file":"[email protected]","density":1,"width":154,"height":64,"bytes":2316},{"file":"[email protected]","density":2,"width":308,"height":128,"bytes":5830}]},"amtrak-baggage":{"label":"Amtrak Baggage","role":"car","facing":"none","width":184,"height":64,"leftInset":0.5985130111524164,"rightInset":0.598513011152439,"variants":[{"file":"[email protected]","density":1,"width":184,"height":64,"bytes":1742},{"file":"[email protected]","density":2,"width":368,"height":128,"bytes":4076}]},"amtrak-viewliner-sleeper":{"label":"Amtrak Viewliner Sleeper","role":"car","facing":"none","width":188,"height":64,"leftInset":0.5273364244494575,"rightInset":0.5273364244494665,"variants":[{"file":"[email protected]","density":1,"width":188,"height":64,"bytes":2066},{"file":"[email protected]","density":2,"width":376,"height":128,"bytes":4744}]},"amtrak-coach":{"label":"Amtrak double-deck coach","role":"car","facing":"none","width":240,"height":64,"leftInset":0.6438558122712242,"rightInset":0.48290074585683745,"variants":[{"file":"[email protected]","density":1,"width":240,"height":64,"bytes":3174},{"file":"[email protected]","density":2,"width":480,"height":128,"bytes":6984}]},"amtrak-lounge":{"label":"Amtrak double-deck lounge","role":"car","facing":"none","width":236,"height":64,"leftInset":0.6331400083933598,"rightInset":0.4748728131351644,"variants":[{"file":"[email protected]","density":1,"width":236,"height":64,"bytes":3370},{"file":"[email protected]","density":2,"width":472,"height":128,"bytes":7486}]},"ttc-rocket-cab":{"label":"TTC Rocket Cab","role":"car","facing":"left","width":183,"height":64,"leftInset":0.5130841121495326,"rightInset":0.5130841121495522,"variants":[{"file":"[email protected]","density":1,"width":183,"height":64,"bytes":1938},{"file":"[email protected]","density":2,"width":366,"height":128,"bytes":4694}]},"ttc-rocket-middle":{"label":"TTC Rocket Middle","role":"car","facing":"none","width":188,"height":64,"leftInset":0.5222265660150222,"rightInset":0.5222265660150045,"variants":[{"file":"[email protected]","density":1,"width":188,"height":64,"bytes":2130},{"file":"[email protected]","density":2,"width":376,"height":128,"bytes":4980}]},"ttc-rocket-cab-right":{"label":"TTC Rocket Cab","role":"car","facing":"right","width":183,"height":64,"leftInset":0.5130841121495522,"rightInset":0.5130841121495522,"variants":[{"file":"[email protected]","density":1,"width":183,"height":64,"bytes":1984},{"file":"[email protected]","density":2,"width":366,"height":128,"bytes":4650}]},"ttc-t1":{"label":"TTC T1","role":"car","facing":"left","width":213,"height":64,"leftInset":0.6028239447419779,"rightInset":0.6028239447419951,"variants":[{"file":"[email protected]","density":1,"width":213,"height":64,"bytes":2566},{"file":"[email protected]","density":2,"width":426,"height":128,"bytes":6592}]},"ttc-t1-right":{"label":"TTC T1","role":"car","facing":"right","width":213,"height":64,"leftInset":0.6028239447419951,"rightInset":0.6028239447419951,"variants":[{"file":"[email protected]","density":1,"width":213,"height":64,"bytes":2588},{"file":"[email protected]","density":2,"width":426,"height":128,"bytes":6508}]},"ttc-flexity":{"label":"TTC Flexity","role":"car","facing":"left","width":226,"height":64,"leftInset":0.6277726317435555,"rightInset":0.627772631743567,"variants":[{"file":"[email protected]","density":1,"width":226,"height":64,"bytes":3100},{"file":"[email protected]","density":2,"width":452,"height":128,"bytes":6882}]},"nyc-r142-cab":{"label":"NYC R142 Cab","role":"car","facing":"left","width":163,"height":64,"leftInset":0.46660628445836744,"rightInset":0.4666062844583677,"variants":[{"file":"[email protected]","density":1,"width":163,"height":64,"bytes":1880},{"file":"[email protected]","density":2,"width":326,"height":128,"bytes":4852}]},"nyc-r142-middle":{"label":"NYC R142 Middle","role":"car","facing":"none","width":151,"height":64,"leftInset":0.4253521126760563,"rightInset":0.42535211267605233,"variants":[{"file":"[email protected]","density":1,"width":151,"height":64,"bytes":1724},{"file":"[email protected]","density":2,"width":302,"height":128,"bytes":4132}]},"nyc-r142-cab-right":{"label":"NYC R142 Cab","role":"car","facing":"right","width":163,"height":64,"leftInset":0.4666062844583677,"rightInset":0.4666062844583677,"variants":[{"file":"[email protected]","density":1,"width":163,"height":64,"bytes":1842},{"file":"[email protected]","density":2,"width":326,"height":128,"bytes":4954}]},"nyc-r160-cab":{"label":"NYC R160 Cab","role":"car","facing":"left","width":158,"height":64,"leftInset":0.44466220208563373,"rightInset":0.4446266916079022,"variants":[{"file":"[email protected]","density":1,"width":158,"height":64,"bytes":1722},{"file":"[email protected]","density":2,"width":316,"height":128,"bytes":4592}]},"nyc-r160-middle":{"label":"NYC R160 Middle","role":"car","facing":"none","width":205,"height":64,"leftInset":0.6637491711233331,"rightInset":0.5689177017181916,"variants":[{"file":"[email protected]","density":1,"width":205,"height":64,"bytes":2226},{"file":"[email protected]","density":2,"width":410,"height":128,"bytes":5502}]},"nyc-r160-cab-right":{"label":"NYC R160 Cab","role":"car","facing":"right","width":158,"height":64,"leftInset":0.4446266916079022,"rightInset":0.4446622020856395,"variants":[{"file":"[email protected]","density":1,"width":158,"height":64,"bytes":1824},{"file":"[email protected]","density":2,"width":316,"height":128,"bytes":4704}]},"lirr-m7-cab":{"label":"LIRR M7 Cab","role":"car","facing":"left","width":192,"height":64,"leftInset":0.5343228200371057,"rightInset":0.5343228200371057,"variants":[{"file":"[email protected]","density":1,"width":192,"height":64,"bytes":1954},{"file":"[email protected]","density":2,"width":384,"height":128,"bytes":4666}]},"lirr-m7-cab-right":{"label":"LIRR M7 Cab","role":"car","facing":"right","width":192,"height":64,"leftInset":0.5343228200371057,"rightInset":0.5343228200371057,"variants":[{"file":"[email protected]","density":1,"width":192,"height":64,"bytes":1978},{"file":"[email protected]","density":2,"width":384,"height":128,"bytes":4894}]},"generic-intercity-loco":{"label":"Generic Intercity Loco","role":"locomotive","facing":"left","width":193,"height":64,"leftInset":0.5451924117722012,"rightInset":0.545192411772224,"variants":[{"file":"[email protected]","density":1,"width":193,"height":64,"bytes":1926},{"file":"[email protected]","density":2,"width":386,"height":128,"bytes":4770}]},"njt-multilevel-coach":{"label":"NJT Multilevel Coach","role":"car","facing":"none","width":191,"height":64,"leftInset":0.5340167753960857,"rightInset":0.5340167753960857,"variants":[{"file":"[email protected]","density":1,"width":191,"height":64,"bytes":2174},{"file":"[email protected]","density":2,"width":382,"height":128,"bytes":5046}]},"njt-multilevel-cab-right":{"label":"NJT Multilevel Cab","role":"car","facing":"right","width":197,"height":64,"leftInset":0.5575409529268509,"rightInset":0.5575409529268509,"variants":[{"file":"njt-multilevel-cab-right.e808a8241542@1
1x.webp","density":1,"width":197,"height":64,"bytes":2418},{"file":"[email protected]","density":2,"width":394,"height":128,"bytes":5870}]},"lner-800-cab":{"label":"LNER 800 Cab","role":"car","facing":"left","width":191,"height":64,"leftInset":0.5392978680323322,"rightInset":0.5392978680323367,"variants":[{"file":"[email protected]","density":1,"width":191,"height":64,"bytes":2370},{"file":"[email protected]","density":2,"width":382,"height":128,"bytes":5682}]},"lner-800-middle":{"label":"LNER 800 Middle","role":"car","facing":"none","width":217,"height":64,"leftInset":0.7124764977150682,"rightInset":0.7124764977150682,"variants":[{"file":"[email protected]","density":1,"width":217,"height":64,"bytes":2268},{"file":"[email protected]","density":2,"width":434,"height":128,"bytes":4674}]},"lner-800-cab-right":{"label":"LNER 800 Cab","role":"car","facing":"right","width":191,"height":64,"leftInset":0.5392978680323367,"rightInset":0.5392978680323367,"variants":[{"file":"[email protected]","density":1,"width":191,"height":64,"bytes":2324},{"file":"[email protected]","density":2,"width":382,"height":128,"bytes":5626}]},"gwr-800-cab":{"label":"GWR 800 Cab","role":"car","facing":"left","width":172,"height":64,"leftInset":0.48314946406557513,"rightInset":0.4831138991436571,"variants":[{"file":"[email protected]","density":1,"width":172,"height":64,"bytes":1750},{"file":"[email protected]","density":2,"width":344,"height":128,"bytes":4654}]},"gwr-800-middle":{"label":"GWR 800 Middle","role":"car","facing":"none","width":224,"height":64,"leftInset":0.6315868606551592,"rightInset":0.6315868606551841,"variants":[{"file":"[email protected]","density":1,"width":224,"height":64,"bytes":2090},{"file":"[email protected]","density":2,"width":448,"height":128,"bytes":5232}]},"gwr-800-cab-right":{"label":"GWR 800 Cab","role":"car","facing":"right","width":172,"height":64,"leftInset":0.4831138991436571,"rightInset":0.48314946406557235,"variants":[{"file":"[email protected]","density":1,"width":172,"height":64,"bytes":1764},{"file":"[email protected]","density":2,"width":344,"height":128,"bytes":4628}]},"sbb-flirt-cab":{"label":"SBB FLIRT Cab","role":"car","facing":"left","width":220,"height":64,"leftInset":0.6094234032380011,"rightInset":0.6093878538356855,"variants":[{"file":"[email protected]","density":1,"width":220,"height":64,"bytes":3050},{"file":"[email protected]","density":2,"width":440,"height":128,"bytes":6894}]},"sbb-flirt-middle":{"label":"SBB FLIRT Middle","role":"car","facing":"none","width":191,"height":64,"leftInset":0.5322805387830933,"rightInset":0.5322805387830933,"variants":[{"file":"[email protected]","density":1,"width":191,"height":64,"bytes":2480},{"file":"[email protected]","density":2,"width":382,"height":128,"bytes":5628}]},"sbb-flirt-cab-right":{"label":"SBB FLIRT Cab","role":"car","facing":"right","width":220,"height":64,"leftInset":0.6093878538356855,"rightInset":0.6094234032379942,"variants":[{"file":"[email protected]","density":1,"width":220,"height":64,"bytes":3028},{"file":"[email protected]","density":2,"width":440,"height":128,"bytes":6936}]},"caltrain-kiss-cab":{"label":"Caltrain KISS Cab","role":"car","facing":"left","width":244,"height":64,"leftInset":0.6825174825174825,"rightInset":0.682517482517468,"variants":[{"file":"[email protected]","density":1,"width":244,"height":64,"bytes":3080},{"file":"[email protected]","density":2,"width":488,"height":128,"bytes":6920}]},"caltrain-kiss-middle":{"label":"Caltrain KISS Middle","role":"car","facing":"none","width":200,"height":64,"leftInset":0.6557541252358248,"rightInset":0.6557186061086784,"variants":[{"file":"[email protected]","density":1,"width":200,"height":64,"bytes":2402},{"file":"[email protected]","density":2,"width":400,"height":128,"bytes":5104}]},"caltrain-kiss-cab-right":{"label":"Caltrain KISS Cab","role":"car","facing":"right","width":244,"height":64,"leftInset":0.682517482517468,"rightInset":0.682517482517468,"variants":[{"file":"[email protected]","density":1,"width":244,"height":64,"bytes":3082},{"file":"[email protected]","density":2,"width":488,"height":128,"bytes":6924}]},"db-ice3-cab":{"label":"DB ICE3 Cab","role":"car","facing":"left","width":201,"height":64,"leftInset":0.5619695465194761,"rightInset":0.5619695465194785,"variants":[{"file":"[email protected]","density":1,"width":201,"height":64,"bytes":2300}
1,{"file":"[email protected]","density":2,"width":402,"height":128,"bytes":5522}]},"db-ice3-middle":{"label":"DB ICE3 Middle","role":"car","facing":"none","width":208,"height":64,"leftInset":0.5812890714726696,"rightInset":0.5812890714726626,"variants":[{"file":"[email protected]","density":1,"width":208,"height":64,"bytes":2340},{"file":"[email protected]","density":2,"width":416,"height":128,"bytes":5196}]},"db-ice3-cab-right":{"label":"DB ICE3 Cab","role":"car","facing":"right","width":201,"height":64,"leftInset":0.5619695465194785,"rightInset":0.5619695465194785,"variants":[{"file":"[email protected]","density":1,"width":201,"height":64,"bytes":2270},{"file":"[email protected]","density":2,"width":402,"height":128,"bytes":5518}]},"sncf-tgv-power":{"label":"SNCF TGV Power","role":"power","facing":"left","width":206,"height":64,"leftInset":0.6725602184734155,"rightInset":0.5765005475153341,"variants":[{"file":"[email protected]","density":1,"width":206,"height":64,"bytes":2530},{"file":"[email protected]","density":2,"width":412,"height":128,"bytes":5964}]},"sncf-tgv-duplex":{"label":"SNCF TGV Duplex","role":"car","facing":"none","width":183,"height":64,"leftInset":0.5958139534883721,"rightInset":0.5958139534883543,"variants":[{"file":"[email protected]","density":1,"width":183,"height":64,"bytes":1936},{"file":"[email protected]","density":2,"width":366,"height":128,"bytes":4274}]},"sncf-tgv-power-right":{"label":"SNCF TGV Power","role":"power","facing":"right","width":206,"height":64,"leftInset":0.5765005475153341,"rightInset":0.6725602184734227,"variants":[{"file":"[email protected]","density":1,"width":206,"height":64,"bytes":2526},{"file":"[email protected]","density":2,"width":412,"height":128,"bytes":5918}]},"tokyo-16000-cab":{"label":"Tokyo 16000 Cab","role":"car","facing":"left","width":206,"height":64,"leftInset":0.5824822848343253,"rightInset":0.5824822848343183,"variants":[{"file":"[email protected]","density":1,"width":206,"height":64,"bytes":2586},{"file":"[email protected]","density":2,"width":412,"height":128,"bytes":6260}]},"tokyo-16000-middle":{"label":"Tokyo 16000 Middle","role":"car","facing":"none","width":177,"height":64,"leftInset":0.4958131205585658,"rightInset":0.49581312055856563,"variants":[{"file":"[email protected]","density":1,"width":177,"height":64,"bytes":1990},{"file":"[email protected]","density":2,"width":354,"height":128,"bytes":4528}]},"tokyo-16000-cab-right":{"label":"Tokyo 16000 Cab","role":"car","facing":"right","width":206,"height":64,"leftInset":0.5824822848343183,"rightInset":0.5824822848343183,"variants":[{"file":"[email protected]","density":1,"width":206,"height":64,"bytes":2552},{"file":"[email protected]","density":2,"width":412,"height":128,"bytes":6338}]},"sydney-waratah-cab":{"label":"Sydney Waratah Cab","role":"car","facing":"left","width":185,"height":64,"leftInset":0.5165031670747838,"rightInset":0.5165031670747622,"variants":[{"file":"[email protected]","density":1,"width":185,"height":64,"bytes":2326},{"file":"[email protected]","density":2,"width":370,"height":128,"bytes":5280}]},"sydney-waratah-middle":{"label":"Sydney Waratah Middle","role":"car","facing":"none","width":174,"height":64,"leftInset":0.5675675510377578,"rightInset":0.5675675510377456,"variants":[{"file":"[email protected]","density":1,"width":174,"height":64,"bytes":2138},{"file":"[email protected]","density":2,"width":348,"height":128,"bytes":4624}]},"sydney-waratah-cab-right":{"label":"Sydney Waratah Cab","role":"car","facing":"right","width":185,"height":64,"leftInset":0.5165031670747622,"rightInset":0.5165031670748026,"variants":[{"file":"[email protected]","density":1,"width":185,"height":64,"bytes":2318},{"file":"[email protected]","density":2,"width":370,"height":128,"bytes":5210}]},"ttc-flexity-freedom":{"label":"Line 5 Flexity Freedom","role":"car","facing":"left","baseUrl":"/train-artwork","width":393,"height":64,"leftInset":0,"rightInset":0,"variants":[{"file":"[email protected]","density":1,"width":393,"height":64,"bytes":4992},{"file":"[email protected]","density":2,"width":786,"height":128,"bytes":11334}]}},"formations":{"freight-default":{"label":"Freight","vehicles":["generic-freight-loco","generic-freight-loco","freight-boxcar","freight-boxcar","freight-boxcar","freight-tank","freight-tank","freight-tank","freight-gondola","freight-gondola","freight-autorack","freight-autorack","freight-flatcar","freight-flatcar"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"eurostar-e320":{"label":"Eurostar e320","vehicles":["eurostar-e320-cab","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-middle","eurostar-e320-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"avanti-pendolino":{"label":"Avanti Pendolino","vehicles":["avanti-390-cab","avanti-390-middle","avanti-390-middle","avanti-390-middle","avanti-390-middle","avanti-390-middle","avanti-390-middle","avanti-390-middle","avanti-390-middle","avanti-390-middle","avanti-390-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"elizabeth-345":{"label":"Elizabeth line Class 345","vehicles":["elizabeth-345-cab","elizabeth-345-middle","elizabeth-345-middle","elizabeth-345-middle","elizabeth-345-middle","elizabeth-345-middle","elizabeth-345-middle","elizabeth-345-middle","elizabeth-345-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"overground-710":{"label":"London Overground Class 710","vehicles":["overground-710-cab","overground-710-middle","overground-710-middle","overground-710-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"thameslink-700":{"label":"Thameslink Class 700","vehicles":["thameslink-700-cab","thameslink-700-middle","thameslink-700-middle","thameslink-700-middle","thameslink-700-middle","thameslink-700-middle","thameslink-700-middle","thameslink-700-middle","thameslink-700-middle","thameslink-700-middle","thameslink-700-middle","thameslink-700-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"oebb-railjet":{"label":"\xd6BB Railjet","vehicles":["oebb-railjet-loco","oebb-railjet-middle","oebb-railjet-middle","oebb-railjet-middle","oebb-railjet-middle","oebb-railjet-middle","oebb-railjet-middle","oebb-railjet-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"sj-x2000":{"label":"SJ X2000","vehicles":["sj-x2000-power","sj-x2000-middle","sj-x2000-middle","sj-x2000-middle","sj-x2000-middle","sj-x2000-middle","sj-x2000-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"cp-alfa":{"label":"CP Alfa Pendular","vehicles":["cp-alfa-cab","cp-alfa-middle","cp-alfa-middle","cp-alfa-middle","cp-alfa-middle","cp-alfa-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"pkp-ed250":{"label":"PKP Intercity Pendolino","vehicles":["pkp-ed250-cab","pkp-ed250-middle","pkp-ed250-middle","pkp-ed250-middle","pkp-ed250-middle","pkp-ed250-middle","pkp-ed250-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"cd-680":{"label":"ÄD Pendolino","vehicles":["cd-680-cab","cd-680-middle","cd-680-middle","cd-680-middle","cd-680-middle","cd-680-middle","cd-680-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"vr-sm3":{"label":"VR Pendolino","vehicles":["vr-sm3-cab","vr-sm3-mid
1dle","vr-sm3-middle","vr-sm3-middle","vr-sm3-middle","vr-sm3-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"sncb-am96":{"label":"SNCB/NMBS AM96","vehicles":["sncb-am96-cab","sncb-am96-middle","sncb-am96-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"irish-22000":{"label":"Irish Rail InterCity","vehicles":["irish-22000-cab","irish-22000-middle","irish-22000-middle","irish-22000-middle","irish-22000-middle","irish-22000-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"vy-74":{"label":"Vy FLIRT","vehicles":["vy-74-cab","vy-74-middle","vy-74-middle","vy-74-middle","vy-74-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"sbb-giruno":{"label":"SBB Giruno","vehicles":["sbb-giruno-cab","sbb-giruno-middle","sbb-giruno-middle","sbb-giruno-middle","sbb-giruno-middle","sbb-giruno-middle","sbb-giruno-middle","sbb-giruno-middle","sbb-giruno-middle","sbb-giruno-middle","sbb-giruno-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"db-regio":{"label":"DB Regio Doppelstock","vehicles":["db-regio-loco","db-regio-middle","db-regio-middle","db-regio-middle","db-regio-middle","db-regio-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"mav-intercity":{"label":"M\xc1V InterCity","vehicles":["mav-v63-loco","mav-intercity-coach","mav-intercity-coach","mav-intercity-coach","mav-intercity-coach","mav-intercity-coach","mav-intercity-coach","mav-intercity-coach"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"cfr-intercity":{"label":"CFR InterCity","vehicles":["cfr-060-loco","cfr-intercity-coach","cfr-intercity-coach","cfr-intercity-coach","cfr-intercity-coach","cfr-intercity-coach","cfr-intercity-coach"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"zssk-intercity":{"label":"ZSSK InterCity","vehicles":["zssk-350-loco","zssk-intercity-coach","zssk-intercity-coach","zssk-intercity-coach","zssk-intercity-coach","zssk-intercity-coach","zssk-intercity-coach"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"hzpp-intercity":{"label":"HŽPP InterCity","vehicles":["hzpp-1142-loco","hzpp-intercity-coach","hzpp-intercity-coach","hzpp-intercity-coach","hzpp-intercity-coach","hzpp-intercity-coach"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"hellenic-470":{"label":"Hellenic Train Pendolino","vehicles":["hellenic-470-cab","hellenic-470-middle","hellenic-470-middle","hellenic-470-middle","hellenic-470-middle","hellenic-470-middle","hellenic-470-middle","hellenic-470-middle","hellenic-470-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"uz-hrcs2":{"label":"Ukrzaliznytsia Intercity+","vehicles":["uz-hrcs2-cab","uz-hrcs2-middle","uz-hrcs2-middle","uz-hrcs2-middle","uz-hrcs2-middle","uz-hrcs2-middle","uz-hrcs2-middle","uz-hrcs2-middle","uz-hrcs2-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"bdz-intercity":{"label":"BDZ InterCity","vehicles":["bdz-smartron-loco","bdz-intercity-coach","bdz-intercity-coach","bdz-intercity-coach","bdz-intercity-coach","bdz-intercity-coach"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"soko-kiss":{"label":"Srbija Voz Soko","vehicles":["soko-kiss-cab","soko-kiss-middle","soko-kiss-middle","soko-kiss-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"vivi-16ev":{"label":"Vivi Škoda 16Ev","vehicles":["vivi-16ev-cab","vivi-16ev-middle","vivi-16ev-middle","vivi-16ev-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"ltg-730":{"label":"LTG Link Pesa","vehicles":["ltg-730-cab","ltg-730-middle","ltg-730-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"elron-flirt":{"label":"Elron FLIRT","vehicles":["elron-flirt-cab","elron-flirt-middle","elron-flirt-middle","elron-flirt-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"nightjet":{"label":"\xd6BB Nightjet","vehicles":["nightjet-taurus-loco","nightjet-sleeper","nightjet-sleeper","nightjet-couchette","nightjet-couchette","nightjet-couchette","nightjet-seat","nightjet-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"eurostar-red":{"label":"Eurostar Red PBKA","vehicles":["eurostar-red-power","eurostar-red-coach","eurostar-red-coach","eurostar-red-coach","eurostar-red-coach","eurostar-red-coach","eurostar-red-coach","eurostar-red-coach","eurostar-red-coach","eurostar-red-power-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"london-s7":{"label":"London Underground S7","vehicles":["london-s-cab","london-s-middle","london-s-middle","london-s-middle","london-s-middle","london-s-middle","london-s-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"london-s8":{"label":"London Underground S8","vehicles":["london-s-cab","london-s-middle","london-s-middle","london-s-middle","london-s-middle","london-s-middle","london-s-middle","london-s-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"bart-future":{"label":"BART Fleet of the Future","vehicles":["bart-d-cab","bart-e-middle","bart-e-middle","bart-e-middle","bart-e-middle","bart-e-middle","bart-e-middle","bart-d-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"wmata-7000":{"label":"Washington Metro 7000","vehicles":["wmata-7000-cab","wmata-7000-middle","wmata-7000-middle","wmata-7000-cab-right","wmata-7000-cab","wmata-7000-middle","wmata-7000-middle","wmata-7000-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"cta-7000":{"label":"Chicago CTA 7000","vehicles":["cta-7000-cab","cta-7000-cab-right","cta-7000-cab","cta-7000-cab-right","cta-7000-cab","cta-7000-cab-right","cta-7000-cab","cta-7000-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"cta-yellow":{"label":"Chicago CTA 7000","vehicles":["cta-7000-cab","cta-7000-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"mbta-red":{"label":"MBTA Red Line","vehicles":["mbta-red-cab","mbta-red-cab-right","mbta-red-cab","mbta-red-cab-right","mbta-red-cab","mbta-red-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"mnr-m8":{"label":"Metro-North M8","vehicles":["mnr-m8-cab","mnr-m8-cab-right","mnr-m8-cab","mnr-m8-cab-right","mnr-m8-cab","mnr-m8-cab-right","mnr-m8-cab","mnr-m8-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"septa-silverliner":{"label":"SEPTA Silverliner V","vehicles":["septa-silverliner-cab","septa-silverliner-cab-right","septa-silverliner-cab","septa-silverliner-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"stm-azur":{"label":"Montr\xe9al AZUR","vehicles":["stm-azur-cab","stm-azur-middle","stm-azur-middle","stm-azur-middle","stm-azur-middle","stm-azur-middle","stm-azur-middle","stm-azur-middle","stm-azur-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"skytrain-mark3":{"label":"Vancouver SkyTrain Mark III","vehicles":["skytrain-mark3-cab","skytrain-mark3-middle","skytrain-mark3-middle","skytrain-mark3-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"mtr-c":{"label":"Hong Kong MTR C-train","vehicles":["mtr-c-cab","mtr-c-middle","mtr-c-middle","mtr-c-middle","mtr-c-middle","mtr-c-middle","mtr-c-middle","mtr-c-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"singapore-r151":{"label":"Singapore MRT R151","vehicles":["singapore-r151-cab","singapore-r151-middle","singapore-r151-middle","singapore-r151-middle","singapore-r151-middle","singapore-r151-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"ns-virm":{"label":"NS VIRM Intercity","vehicles":["ns-virm-cab","ns-virm-middle","ns-virm-middle","ns-virm-middle","ns-virm-middle","ns-virm-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"renfe-103":{"label":"Renfe AVE S-103","vehicles":["renfe-103-cab","renfe-103-middle","renfe-103-middle","renfe-103-middle","renfe-103-middle","renfe-103-middle","renfe-103-middle","renfe-103-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"trenitalia-1000":{"label":"Trenitalia Frecciarossa 1000","vehicles":["trenitalia-1000-cab","trenitalia-1000-middle","trenitalia-1000-middle","trenitalia-1000-middle","trenitalia-1000-middle","trenitalia-1000-middle","trenitalia-1000-middle","trenitalia-1000-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"go":{"label":"GO BiLevel","vehicles":["go-mp40-left","go-bilevel-coach","go-bilevel-coach","go-bilevel-coach","go-bilevel-coach","go-bilevel-coach","go-bilevel-coach","go-bilevel-coach","go-bilevel-coach","go-bilevel-coach","go-bilevel-coach","go-bilevel-coach","go-bilevel-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"via-venture":{"label":"VIA Venture","vehicles":["via-charger","via-business","via-business","via-economy","via-economy","via-venture-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"via-legacy":{"label":"VIA long-distance","vehicles":["via-f40","via-budd-coac
1h","via-budd-coach","via-budd-coach","via-budd-sleeper","via-budd-sleeper","via-budd-sleeper","via-dome"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"amtrak-default":{"label":"Amtrak intercity","vehicles":["amtrak-p42","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-cafe"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"amtrak-regional":{"label":"Amtrak Northeast Regional","vehicles":["amtrak-acs64","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-cafe","amtrak-amfleet-coach"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"amtrak-overnight":{"label":"Amtrak overnight","vehicles":["amtrak-p42","amtrak-baggage","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-coach","amtrak-amfleet-cafe","amtrak-viewliner-sleeper","amtrak-viewliner-sleeper"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"amtrak-superliner":{"label":"Amtrak Superliner","vehicles":["amtrak-p42","amtrak-coach","amtrak-coach","amtrak-coach","amtrak-lounge","amtrak-coach","amtrak-coach","amtrak-coach"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"ttc-rocket":{"label":"Toronto Rocket","vehicles":["ttc-rocket-cab","ttc-rocket-middle","ttc-rocket-middle","ttc-rocket-middle","ttc-rocket-middle","ttc-rocket-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"ttc-sheppard":{"label":"Toronto Rocket","vehicles":["ttc-rocket-cab","ttc-rocket-middle","ttc-rocket-middle","ttc-rocket-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"ttc-t1":{"label":"TTC T1","vehicles":["ttc-t1","ttc-t1","ttc-t1","ttc-t1-right","ttc-t1-right","ttc-t1-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"ttc-streetcar":{"label":"TTC Flexity streetcar","vehicles":["ttc-flexity"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"nyc-r142":{"label":"NYC Subway R142","vehicles":["nyc-r142-cab","nyc-r142-middle","nyc-r142-middle","nyc-r142-middle","nyc-r142-cab-right","nyc-r142-cab","nyc-r142-middle","nyc-r142-middle","nyc-r142-middle","nyc-r142-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"nyc-r160":{"label":"NYC Subway R160","vehicles":["nyc-r160-cab","nyc-r160-middle","nyc-r160-middle","nyc-r160-middle","nyc-r160-cab-right","nyc-r160-cab","nyc-r160-middle","nyc-r160-middle","nyc-r160-middle","nyc-r160-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"lirr":{"label":"LIRR M7","vehicles":["lirr-m7-cab","lirr-m7-cab-right","lirr-m7-cab","lirr-m7-cab-right","lirr-m7-cab","lirr-m7-cab-right","lirr-m7-cab","lirr-m7-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"njt":{"label":"NJ Transit multilevel \xb7 illustrative locomotive","vehicles":["generic-intercity-loco","njt-multilevel-coach","njt-multilevel-coach","njt-multilevel-coach","njt-multilevel-coach","njt-multilevel-coach","njt-multilevel-coach","njt-multilevel-coach","njt-multilevel-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"lner":{"label":"LNER Azuma","vehicles":["lner-800-cab","lner-800-middle","lner-800-middle","lner-800-middle","lner-800-middle","lner-800-middle","lner-800-middle","lner-800-middle","lner-800-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"gwr":{"label":"GWR Intercity Express","vehicles":["gwr-800-cab","gwr-800-middle","gwr-800-middle","gwr-800-middle","gwr-800-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"sbb":{"label":"SBB FLIRT","vehicles":["sbb-flirt-cab","sbb-flirt-middle","sbb-flirt-middle","sbb-flirt-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"caltrain":{"label":"Caltrain electric","vehicles":["caltrain-kiss-cab","caltrain-kiss-middle","caltrain-kiss-middle","caltrain-kiss-middle","caltrain-kiss-middle","caltrain-kiss-middle","caltrain-kiss-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"ice":{"label":"DB ICE 3","vehicles":["db-ice3-cab","db-ice3-middle","db-ice3-middle","db-ice3-middle","db-ice3-middle","db-ice3-middle","db-ice3-middle","db-ice3-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"tgv":{"label":"SNCF TGV Duplex","vehicles":["sncf-tgv-power","sncf-tgv-duplex","sncf-tgv-duplex","sncf-tgv-duplex","sncf-tgv-duplex","sncf-tgv-duplex","sncf-tgv-duplex","sncf-tgv-duplex","sncf-tgv-duplex","sncf-tgv-power-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"tokyo":{"label":"Tokyo Metro 16000","vehicles":["tokyo-16000-cab","tokyo-16000-middle","tokyo-16000-middle","tokyo-16000-middle","tokyo-16000-middle","tokyo-16000-middle","tokyo-16000-middle","tokyo-16000-middle","tokyo-16000-middle","tokyo-16000-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"sydney":{"label":"Sydney Waratah","vehicles":["sydney-waratah-cab","sydney-waratah-middle","sydney-waratah-middle","sydney-waratah-middle","sydney-waratah-middle","sydney-waratah-middle","sydney-waratah-middle","sydney-waratah-cab-right"],"accuracy":"default","disclaimer":"Car count might not be accurate"},"ttc-eglinton":{"label":"Line 5 Flexity Freedom","vehicles":["ttc-flexity-freedom","ttc-flexity-freedom"],"accuracy":"default","disclaimer":"Car count might not be accurate"}},"networks":{"eurostar":{"default":"eurostar-e320","modes":["rail"],"rules":[{"names":["thalys","eurostar red","red eurostar"],"formation":"eurostar-red"}]},"avanti":{"default":"avanti-pendolino","modes":["rail"]},"elizabeth-line":{"default":"elizabeth-345","modes":["rail"]},"london-overground":{"default":"overground-710","modes":["rail"]},"thameslink":{"default":"thameslink-700","modes":["rail"]},"oebb":{"default":"oebb-railjet","modes":["rail"],"rules":[{"names":["nightjet"],"routeIds":["NJ"],"formation":"nightjet"}]},"sj":{"default":"sj-x2000","modes":["rail"]},"cp-portugal":{"default":"cp-alfa","modes":["rail"]},"polish-rail":{"default":"pkp-ed250","modes":["rail"]},"czech-rail":{"default":"cd-680","modes":["rail"]},"digitraffic":{"default":"vr-sm3","modes":["rail"]},"nmbs-belgium":{"default":"sncb-am96","modes":["rail"]},"irishrail":{"default":"irish-22000","modes":["rail"]},"vy":{"default":"vy-74","modes":["rail"]},"db-regio":{"default":"db-regio","modes":["rail"]},"mav":{"default":"mav-intercity","modes":["rail"]},"cfr":{"default":"cfr-intercity","modes":["rail"]},"slovakia-rail":{"default":"zssk-intercity","modes":["rail"]},"hzpp":{"default":"hzpp-intercity","modes":["rail"]},"hellenictrain":{"default":"hellenic-470","modes":["rail"]},"ukrzaliznytsia":{"default":"uz-hrcs2","modes":["rail"]},"bdz":{"default":"bdz-intercity","modes":["rail"]},"srbijavoz":{"default":"soko-kiss","modes":["rail"]},"vivi":{"default":"vivi-16ev","modes":["rail"]},"ltg-link":{"default":"ltg-730","modes":["rail"]},"elron":{"default":"elron-flirt","modes":["rail"]},"tfl-underground":{"default":"london-s7","modes":["metro"],"rules":[{"routeIds":["METROPOLITAN"],"names":["metropolitan"],"formation":"london-s8"}]},"bart":{"default":"bart-future","modes":["metro","rail"]},"wmta":{"default":"wmata-7000","modes":["metro"]},"cta":{"default":"cta-7000","modes":["metro"],"rules":[{"routeIds":["Y"],"names":["yellow"],"formation":"cta-yellow"}]},"mbta":{"default":"mbta-red","modes":["metro"]},"mnr":{"default":"mnr-m8","modes":["rail"]},"septa":{"default":"septa-silverliner","modes":["rail"]},"stm":{"default":"stm-azur","modes":["metro"]},"translink":{"default":"skytrain-mark3","modes":["metro","rail"]},"mtr":{"default":"mtr-c","modes":["metro","rail"]},"sgmrt":{"default":"singapore-r151","modes":["metro","rail"]},"ns":{"default":"ns-virm","modes":["rail"]},"renfe":{"default":"renfe-103","modes":["rail"]},"trenitalia-nazionale":{"default":"trenitalia-1000","modes":["rail"]},"go":{"default":"go","modes":["rail"]},"via":{"default":"via-venture","modes":["rail"],"rules":[{"names":["canadian","ocean","winnipeg","churchill","jasper","prince rupert","sudbury","white river"],"formation":"via-legacy"}
1]},"amtrak":{"default":"amtrak-default","modes":["rail"],"rules":[{"names":["northeast regional","keystone"],"formation":"amtrak-regional"},{"names":["california zephyr","empire builder","southwest chief","coast starlight","sunset limited","texas eagle","auto train","city of new orleans"],"formation":"amtrak-superliner"},{"names":["silver meteor","silver star","floridian","crescent","cardinal","lake shore limited"],"formation":"amtrak-overnight"}]},"ttc":{"default":"ttc-rocket","modes":["metro","tram"],"rules":[{"routeIds":["5"],"names":["eglinton","crosstown"],"formation":"ttc-eglinton"},{"modes":["tram"],"formation":"ttc-streetcar"},{"routeIds":["4"],"names":["sheppard"],"formation":"ttc-sheppard"},{"routeIds":["2"],"names":["bloor","danforth"],"formation":"ttc-t1"}]},"mta":{"default":"nyc-r160","modes":["metro"],"rules":[{"routeIds":["1","2","3","4","5","6","6X"],"formation":"nyc-r142"}]},"lirr":{"default":"lirr","modes":["rail"]},"njt":{"default":"njt","modes":["rail"]},"lner":{"default":"lner","modes":["rail"]},"great-western":{"default":"gwr","modes":["rail"]},"sbb":{"default":"sbb-giruno","modes":["rail"],"rules":[{"names":["flirt"],"formation":"sbb"}]},"caltrain":{"default":"caltrain","modes":["rail"]},"db":{"default":"ice","modes":["rail"]},"sncf":{"default":"tgv","modes":["rail"]},"tokyometro":{"default":"tokyo","modes":["metro","rail"]},"sydneytrains":{"default":"sydney","modes":["rail"]}},"aliases":{"wmata":"wmta","metro-north":"mnr","london-underground":"tfl-underground","singapore-mrt":"sgmrt","go-transit":"go","via-rail":"via","nyc-subway":"mta","nj-transit":"njt","gwr":"great-western","tokyo-metro":"tokyometro","sydney-trains":"sydneytrains"},"freight":{"default":"freight-default","vehicleTypes":{"locomotive":"generic-freight-loco","boxcar":"freight-boxcar","tank":"freight-tank","gondola":"freight-gondola","autorack":"freight-autorack","flatcar":"freight-flatcar"}}}');function tc({train:t,route:e}){let a=function(t,e,a){let i=String(t?.agency||"").toLowerCase(),n=e.aliases?.[i]||i,s=!!t?.freight||"freight"===i,r=s?e.freight:e.networks[n];if(!r)return null;let o=function(t){if(null==t||""===t)return null;let e=String(t).toLowerCase(),a=Number(e);return["2","hr","rail","train"].includes(e)||a>=100&&a<=117?"rail":["1","mr","metro","subway"].includes(e)||a>=400&&a<=405||a>=500&&a<=504?"metro":["0","sc","lr","tram","streetcar","light_rail"].includes(e)||a>=900&&a<=906?"tram":"unsupported"}(t.vt??a?.route_type??t.gtfs?.route_type);if(!s&&o&&!r.modes.includes(o))return null;let l=[a?.route_short_name,a?.route_id,t.gtfs?.route_short_name,t.gtfs?.route_id].filter(t=>null!=t).map(t=>String(t).trim().toUpperCase()),c=[t.name,a?.route_long_name,t.gtfs?.route_long_name].filter(Boolean).join(" ").toLowerCase(),g=r.rules?.find(t=>t.modes?.includes(o)||t.routeIds?.some(t=>l.includes(t))||t.names?.some(t=>c.includes(t))),d=g?.formation||r.default,h=e.formations[d],m=h?.vehicles;if(!Array.isArray(m)||m.length<1||m.length>26||m.some(t=>!e.assets[t]))return null;let u=m.filter(t=>"car"===e.assets[t].role).length,p=m.filter(t=>"locomotive"===e.assets[t].role).length,y=m.filter(t=>"power"===e.assets[t].role).length,b=`${u} ${1===u?"car":"cars"}${p?` + ${1===p?"locomotive":`${p} locomotives`}`:""}${y?` + ${y} power ${1===y?"car":"cars"}`:""}`,f=0;return{formationId:d,label:h.label,summary:b,carCount:u,passengerCarCount:s?0:u,freightCarCount:s?u:0,locomotiveCount:p,powerCarCount:y,accuracy:h.accuracy,disclaimer:h.disclaimer,vehicles:m.map((t,a)=>{let i=e.assets[t],n=e.assets[m[a-1]],s="locomotive"===i.role?"Locomotive":"power"===i.role?"Power car":String(++f);return{id:t,...i,caption:s,description:`${i.label}${"car"===i.role?`, car ${f}`:""}`,marginLeft:n?-(n.rightInset+i.leftInset):0,src:`${i.baseUrl||e.baseUrl}/${i.variants[0].file}`,srcSet:i.variants.map(t=>`${i.baseUrl||e.baseUrl}/${t.file} ${t.density}x`).join(", ")}})}}(t,tl,e);return a?(0,i.jsx)(tg,{consist:a},`${t.agency}:${t.vid}:${a.formationId}`):null}function tg({consist:t}){let e=(0,g.useId)(),[a,n]=(0,g.useState)(!1),s=(0,g.useRef)(null),r=D(),[o,l]=(0,g.useState)({start:!0,end:!1}),[c,d]=(0,g.useState)(!1),h=()=>{let t=s.current;t&&l({start:t.scrollLeft<1,end:t.scrollLeft+t.clientWidth>=t.scrollWidth-1})};(0,g.useEffect)(()=>{let t=s.current;if(!t)return;h();let e=new ResizeObserver(h);return e.observe(t),()=>e.disconnect()},[c]);let m=t=>s.current?.scrollBy({left:t*s.current.clientWidth*.85,behavior:window.matchMedia("(prefers-reduced-motion: reduce)").matches?"auto":"smooth"});return(0,i.jsxs)("section",{"aria-label":"Train cars",className:"min-w-0 pb-2",children:[(0,i.jsxs)("div",{className:"flex items-center justify-end gap-1",children:[(0,i.jsx)("div",{className:"relative flex items-center text-xs text-gray-500",children:(0,i.jsxs)("span",{onMouseEnter:()=>n(!0),onMouseLeave:()=>n(!1),children:[(0,i.jsx)("button",{type:"button","aria-label":"Car count information","aria-describedby":a?e:void 0,onFocus:()=>n(!0),onBlur:()=>n(!1),onClick:()=>n(!0),onKeyDown:t=>{"Escape"===t.key&&(t.stopPropagation(),n(!1))},className:"flex h-4 w-4 items-center justify-center rounded-full text-gray-400 hover:text-gray-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800",children:(0,i.jsx)(to.A,{className:"h-3 w-3","aria-hidden":"true"})}),a&&(0,i.jsx)("span",{id:e,role:"tooltip",className:"absolute right-0 top-full z-20 pt-1",children:(0,i.jsx)("span",{className:"block w-max max-w-[220px] rounded bg-gray-900 px-2 py-1 text-[10px] leading-tight text-white shadow-sm",children:t.disclaimer})})]})}),!c&&(0,i.jsxs)("div",{className:"flex gap-1",children:[(0,i.jsx)("button",{type:"button","aria-label":"Scroll toward front of train",disabled:o.start,onClick:()=>m(-1),className:"rounded-md p-1.5 text-gray-600 hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800 disabled:opacity-30",children:(0,i.jsx)(O.A,{className:"h-4 w-4","aria-hidden":"true"})}),(0,i.jsx)("button",{type:"button","aria-label":"Scroll toward rear cars",disabled:o.end,onClick:()=>m(1),className:"rounded-md p-1.5 text-gray-600 hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800 disabled:opacity-30",children:(0,i.jsx)(K.A,{className:"h-4 w-4","aria-hidden":"true"})})]})]}),c?(0,i.jsx)("p",{className:"py-3 text-xs text-gray-500",children:"Train illustration unavailable."}):(0,i.jsx)("div",{...r,ref:s,role:"region","aria-label":`${t.label} train diagram, ${t.summary}`,tabIndex:0,onScroll:h,className:"cursor-grab select-none data-[dragging=true]:cursor-grabbing w-full overflow-x-auto overscroll-x-contain rounded-md bg-white pb-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden focu
1s-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800",children:(0,i.jsx)("ol",{className:"m-0 flex w-max list-none items-start px-1",children:t.vehicles.map((t,e)=>(0,i.jsxs)("li",{className:"shrink-0",style:{width:t.width,marginLeft:t.marginLeft},children:[(0,i.jsx)("img",{src:t.src,srcSet:t.srcSet,alt:t.description,width:t.width,height:t.height,loading:0===e?"eager":"lazy",decoding:"async",draggable:!1,onError:()=>d(!0),className:"block max-w-none select-none"}),(0,i.jsx)("p",{"aria-hidden":"true",className:"py-1 text-center text-[10px] text-gray-500",children:t.caption})]},`${t.id}:${e}`))})})]})}var td=a(42891),th=a(35176);function tm({train:t,onClose:e}){let a=t.freight,{data:n,error:s}=(0,td.o)(a.source?null:t.vid),{data:r}=(0,td.b)(n),[o,l]=(0,g.useState)(null);return(0,i.jsxs)("div",{className:"flex min-h-0 flex-1 flex-col overflow-y-auto p-5",children:[(0,i.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,i.jsxs)("div",{children:[(0,i.jsx)("h2",{className:"text-lg font-bold",children:t.name}),(0,i.jsx)("p",{className:"text-sm font-medium text-amber-800",children:a.source?"gps"===a.position_source?"Reported freight GPS position":"Last reported freight location":"Estimated freight position"})]}),(0,i.jsx)("button",{onClick:e,"aria-label":"Close train details",className:"rounded-full p-2 hover:bg-gray-100",children:(0,i.jsx)(y.A,{className:"h-5 w-5"})})]}),(0,i.jsx)(tc,{train:t}),a.source?(0,i.jsx)(th.A,{train:a}):(0,i.jsxs)(i.Fragment,{children:[r&&r.url!==o&&(0,i.jsx)("section",{"aria-label":"Train photos",className:"mt-4 border-b border-gray-100 pb-4",children:(0,i.jsxs)("figure",{children:[(0,i.jsx)("img",{src:r.url,alt:`Original sighting of ${t.name}`,className:"aspect-video w-full rounded-lg object-cover",onError:()=>l(r.url)}),(0,i.jsx)("figcaption",{className:"mt-1 text-xs text-gray-500",children:r.href?(0,i.jsx)("a",{href:r.href,className:"hover:underline",children:r.caption}):r.caption})]})}),"unknown"===a.train_type&&(0,i.jsx)("p",{className:"mt-4 text-sm text-amber-800",children:"Camera sighting: freight classification is unconfirmed."}),(0,i.jsx)("p",{className:"mt-5 text-sm text-gray-600",children:"Predicted from the last sighting, assuming constant speed for up to three hours. Stops and junction choices can change the actual position."}),(0,i.jsx)("p",{className:"mt-2 text-xs text-gray-500",children:s?"The predicted route is temporarily unavailable.":n?.predicted_route?.length?"The amber trail follows the predicted railway route from the original sighting. Gaps mark later sighting corrections.":"The route appears when mapped railway coverage is available."}),(0,i.jsxs)("dl",{className:"mt-5 space-y-4 text-sm",children:[(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Last sighted"}),(0,i.jsx)("dd",{children:new Date(a.last_seen).toLocaleString()})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Estimated speed"}),(0,i.jsxs)("dd",{children:[Math.round(a.effective_speed_kmh??a.last_speed_kmh)," km/h"]})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Heading"}),(0,i.jsxs)("dd",{children:[Math.round(t.dir),"\xb0"]})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Prediction expires"}),(0,i.jsx)("dd",{children:new Date(t.valid_until).toLocaleTimeString()})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Rail alignment"}),(0,i.jsx)("dd",{children:a.last_rail_segment_id?"Following mapped railway":"Awaiting railway coverage; approximate bearing only"})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Sightings"}),(0,i.jsx)("dd",{children:a.sighting_count||1})]})]}),(0,i.jsx)("a",{className:"mt-6 rounded-lg bg-amber-800 px-4 py-3 text-center text-sm font-semibold text-white",href:`/freight/?train=${t.vid}`,children:"View sighting details"})]})]})}var tu=a(48166),tp=a(10880),ty=a(77604);let tb=t=>"string"==typeof t&&t.trim()&&!/^unknown(?: origin| destination)?$/i.test(t.trim())?U(t.trim()):null,tf={delayed:"text-amber-700",on_time:"text-emerald-700",early:"text-sky-700"};function tw({label:t,children:e}){return null==e||""===e?null:(0,i.jsxs)("div",{className:"flex items-baseline justify-between gap-4 py-2.5",children:[(0,i.jsx)("dt",{className:"shrink-0 text-xs font-medium uppercase tracking-wide text-gray-500",children:t}),(0,i.jsx)("dd",{className:"min-w-0 text-right text-sm font-medium text-gray-900",children:e})]})}function tx({train:t,network:e,onClose:a,onSelectStation:n}){let{units:s,convertSpeed:r,formatSpeed:o}=(0,tu.t)(),l=$(t),[,c]=(0,g.useState)(0);(0,g.useEffect)(()=>{let t=setInterval(()=>c(t=>t+1),1e3);return()=>clearInterval(t)},[]);let w=(0,g.useMemo)(()=>{let e=t?.normalized?.speed;return e?.has_speed&&null!=e.value?o(r(e.value,e.unit,s),(0,tp.rT)(s)):null},[t,s,r,o]);if(!t)return null;let _="scheduled"===l.status&&Number.isFinite(l.delay)?l.delay>=60?"delayed":l.delay<=-60?"early":"on_time":l.status,v=function(t){if(null==t||!Number.isFinite(t))return null;let e=Math.abs(t);if(e<60)return t>0?"Less than a minute delayed":"On time";let a=Math.round(e/60);if(a<60)return`${a} min ${t>0?"delayed":"early"}`;let i=Math.floor(a/60),n=a%60;return`${i}h${n?` ${n}m`:""} ${t>0?"delayed":"early"}`}(l.delay),j=tf[_]||"text-gray-500",S="on_time"===_?h.A:m.A,C="on_time"===_?"On Time":"delayed"===_?v||"Delayed":"early"===_?v||"Early":_&&!["scheduled","unknown","unavailable"].includes(_)?_.replace(/_/g," "):null,N=t.isGhost||"ghost"===t.position_source?"Scheduled":"community"===t.position_source?"Community":["vehicle","vehicle_positions","gps"].includes(t.position_source)?"Live":["trip_update_synth","trip_update","synth"].includes(t.position_source)?"Inferred":null,I=null!=t.dir&&""!==String(t.dir).trim()&&Number.isFinite(Number(t.dir))?(Number(t.dir)%360+360)%360:null,M=null!=I&&Number.isFinite(I)?["N","NE","E","SE","S","SW","W","NW"][Math.round(I/45)%8]:null,A=t.vid?`/networks/${t.agency}/trains/${t.vid}/`:null,L="via"===String(t.agency).toLowerCase()&&"84"===String(t.vid),T=String(t.agency).toLowerCase(),z=t=>(t=P(t),"ttc"===T)?U(t):"go"===T||"go-transit"===T?t.replace(/\s+GO\s*$/i,""):t,R=z(l.stops[0]?.stop_name||t.org||"Unknown origin"),E=z(l.stops.at(-1)?.stop_name||t.dst||"Unknown de
1stination"),F=l.progress?.progressAlongTotalRoute?.percent,D="wmta"!==String(t?.agency).toLowerCase()?null:"NR"===String(t.name||"").trim().toUpperCase()?"Not in passenger service":String(t.name||"").trim()||t.gtfs?.trip_id||tb(t.org)||tb(t.dst)?null:"No trip assigned";return(0,i.jsxs)("div",{className:"flex min-h-0 flex-1 flex-col",children:[(0,i.jsxs)("div",{className:"flex shrink-0 items-start gap-3 px-5 pt-4",children:[(0,i.jsx)("div",{role:"img","aria-label":M?`Heading ${M}, ${Math.round(I)} degrees`:"Direction unavailable",className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-full border-2 text-white shadow-sm",style:{backgroundColor:e?.color||"#1e40af",borderColor:e?.darkerColor||"#1e3a8a"},children:null!=I?(0,i.jsx)(u.A,{className:"h-6 w-6",strokeWidth:2.5,style:{transform:`rotate(${I}deg)`},"aria-hidden":"true"}):(0,i.jsx)(p.A,{className:"h-5 w-5 opacity-60","aria-hidden":"true"})}),(0,i.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,i.jsx)("h2",{className:"break-words text-lg font-bold leading-tight text-gray-900",children:function(t,e=[],a,i){let n=t?.name||"Train",s=String(t?.agency).toLowerCase();if(["go","go-transit"].includes(s)){let e=a?.route_long_name||t.gtfs?.route_long_name||a?.route_short_name||t.gtfs?.route_short_name;if(!e)return n;if(!/^\d+:[0-5]\d(?::[0-5]\d)?$/.test(i||""))return e;let{time:s,dayLabel:r}=(0,ty.Pq)(i);return`${e} - ${s}${r?` ${r}`:""}`}if(!["via","via-rail"].includes(s))return n;let r=tb(t.org)||(e.length>1?tb(e[0]?.stop_name):null),o=tb(t.dst)||(e.length>1?tb(e.at(-1)?.stop_name):null);if(!r||!o)return n;let l=String(t.train_number||n).replace(/^train\s+/i,"").trim();return`${l} - ${r} to ${o}`}(t,l.stops,l.route,l.originDeparture)}),(0,i.jsx)("p",{className:"mt-0.5 text-xs text-gray-500",children:(0,i.jsx)(x(),{href:`/networks/${encodeURIComponent(t.agency)}/`,className:"hover:underline underline-offset-2 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800",children:e?.name||t.agency})}),(N||w||C)&&(0,i.jsxs)("div",{className:"mt-2 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs",children:[N&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(tr,{label:N,scheduleFallback:!0===t.schedule_fallback}),(w||C)&&(0,i.jsx)("span",{className:"text-gray-300","aria-hidden":"true",children:"\xb7"})]}),w&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)("span",{className:"inline-flex items-center gap-1 font-medium text-gray-700",children:[(0,i.jsx)(d.C_t,{className:"h-3 w-3 shrink-0 text-gray-500","aria-hidden":"true"}),w]}),C&&(0,i.jsx)("span",{className:"text-gray-300","aria-hidden":"true",children:"\xb7"})]}),C&&(0,i.jsxs)("span",{className:`inline-flex items-center gap-1 font-medium capitalize ${j}`,children:[(0,i.jsx)(S,{className:"h-3 w-3 shrink-0 text-gray-500","aria-hidden":"true"}),C]})]}),l.movement&&(0,i.jsxs)("p",{className:"-mr-8 mt-1 flex min-w-0 items-center gap-2 text-xs leading-relaxed text-gray-500",title:l.movement,children:[(0,i.jsxs)("span",{"aria-hidden":"true",className:"relative flex h-1.5 w-1.5 shrink-0",children:[(0,i.jsx)("span",{className:`absolute inline-flex h-full w-full animate-ping rounded-full opacity-60 motion-reduce:animate-none ${"delayed"===_?"bg-amber-500":"bg-emerald-500"}`}),(0,i.jsx)("span",{className:`relative inline-flex h-1.5 w-1.5 rounded-full ${"delayed"===_?"bg-amber-500":"bg-emerald-500"}`})]}),(0,i.jsx)("span",{className:"min-w-0 truncate",children:l.movement})]}),!l.movement&&l.progressLoading&&(0,i.jsx)(k,{className:"mt-1 h-5 w-44"})]}),(0,i.jsx)("button",{type:"button",onClick:a,"aria-label":"Close train details",className:"-mr-2 -mt-1 shrink-0 rounded-full p-2 text-gray-400 hover:bg-gray-100 hover:text-gray-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800",children:(0,i.jsx)(y.A,{className:"h-5 w-5","aria-hidden":"true"})})]}),(0,i.jsxs)("div",{className:"min-h-0 flex-1 overflow-y-auto overscroll-contain px-5 pb-5",children:[L&&(0,i.jsxs)("div",{className:"mb-3 flex flex-col items-center gap-1 text-gray-800",children:[(0,i.jsx)("img",{src:Z.A.src,alt:"",className:"h-14 w-auto"}),(0,i.jsx)("span",{className:"text-xl font-bold tracking-tight",children:"trains.fyi"})]}),L&&(0,i.jsx)("div",{role:"alert",className:"mb-2 rounded-lg border border-red-300 bg-red-50 px-3 py-2.5 text-sm font-semibold leading-snug text-red-800",children:"Train crashed into a tractor - severely delayed - no fatalities reported"}),L&&(0,i.jsxs)("div",{role:"note",className:"mb-3 rounded-lg border border-amber-300 bg-amber-50 px-3 py-2.5 text-sm leading-snug text-amber-900",children:[(0,i.jsx)("p",{className:"font-semibold",children:"Commuting Note"}),(0,i.jsx)("p",{className:"mt-0.5",children:"Riders report some of the cops on scene are hot \uD83D\uDD25"})]}),(0,i.jsx)(tc,{train:t,route:l.route}),(0,i.jsxs)("section",{"aria-label":"Trip summary","aria-busy":l.tripLoading||l.progressLoading,className:"rounded-xl px-3 py-3 ring-1 ring-inset ring-slate-200/70 first:mt-4",children:[l.tripLoading?(0,i.jsx)(k,{className:"mb-3 h-4 w-32"}):l.route&&(0,i.jsx)("p",{className:"mb-3 text-[11px] font-semibold tracking-wide text-gray-500",children:[l.route.route_short_name,l.route.route_long_name].filter(
1Boolean).join(" \xb7 ")}),D?(0,i.jsx)("p",{className:"text-sm font-semibold text-gray-900",children:D}):(0,i.jsxs)("div",{className:"grid grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center gap-3",children:[(0,i.jsxs)("div",{className:"min-w-0",children:[(0,i.jsx)("p",{className:"mb-1 text-[10px] font-medium uppercase tracking-widest text-gray-400",children:"From"}),(0,i.jsx)("p",{className:"break-words text-sm font-semibold leading-snug text-gray-900",children:l.tripLoading?(0,i.jsx)(k,{className:"h-5 w-full"}):R})]}),(0,i.jsx)(b.A,{className:"h-3.5 w-3.5 shrink-0 text-gray-400","aria-hidden":"true"}),(0,i.jsxs)("div",{className:"min-w-0 text-right",children:[(0,i.jsx)("p",{className:"mb-1 text-[10px] font-medium uppercase tracking-widest text-gray-400",children:"To"}),(0,i.jsx)("p",{className:"break-words text-sm font-semibold leading-snug text-gray-900",children:l.tripLoading?(0,i.jsx)(k,{className:"h-5 w-full"}):E})]})]}),l.progressLoading&&!Number.isFinite(F)?(0,i.jsxs)("div",{role:"status","aria-label":"Loading journey progress",className:"mt-3",children:[(0,i.jsx)(k,{className:"h-1 w-full"}),(0,i.jsx)(k,{className:"mt-1.5 h-4 w-4/5"})]}):Number.isFinite(F)&&(0,i.jsxs)("div",{className:"mt-3",children:[(0,i.jsxs)("div",{role:"progressbar","aria-label":"Journey progress","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":Math.round(100*Math.max(0,Math.min(1,F))),className:"relative h-1 rounded-full bg-gray-200",children:[(0,i.jsx)("div",{className:"h-full rounded-full",style:{width:`${100*Math.max(0,Math.min(1,F))}%`,backgroundColor:e?.color||"#1e40af"}}),(0,i.jsx)("svg",{"aria-hidden":"true",viewBox:"0 0 52 48",className:"absolute top-1/2 h-3 w-3.5 -translate-x-1/2 -translate-y-1/2",style:{left:`${100*Math.max(0,Math.min(1,F))}%`},children:(0,i.jsx)("path",{d:"M48 24 8 40 8 8Z",fill:e?.color||"#1e40af",stroke:e?.darkerColor||"#1e3a8a",strokeWidth:"3",strokeLinejoin:"round"})})]}),(0,i.jsxs)("p",{className:"mt-1.5 text-[10px] leading-relaxed text-gray-500",children:[Math.round(100*Math.max(0,Math.min(1,F))),"% of route completed"]})]})]}),(0,i.jsx)(ta,{train:t,network:e}),(0,i.jsx)(B,{journey:l,train:t,onSelectStation:n,color:e?.color||"#1e40af"}),(0,i.jsxs)("details",{className:"border-t border-gray-100 pt-3",children:[(0,i.jsx)("summary",{className:"cursor-pointer text-xs font-semibold text-gray-500",children:"More train information"}),(0,i.jsxs)("dl",{className:"mt-2 divide-y divide-gray-100",children:[(0,i.jsx)(tw,{label:"Network",children:e?.name||t.agency}),(0,i.jsx)(tw,{label:"Vehicle",children:t.normalized?.vehicle?.type?.name}),(0,i.jsx)(tw,{label:"Speed",children:w}),(0,i.jsx)(tw,{label:"Heading",children:M?`${M} \xb7 ${Math.round(I)}\xb0`:null}),(0,i.jsx)(tw,{label:"Position",children:N}),(0,i.jsx)(tw,{label:"Updated",children:function(t){if(!t)return null;let e=new Date(t).getTime();if(!Number.isFinite(e))return null;let a=Math.max(0,Math.round((Date.now()-e)/1e3));if(a<5)return"just now";if(a<60)return`${a}s ago`;let i=Math.floor(a/60);if(i<60)return`${i}m ago`;let n=Math.floor(i/60);return`${n}h ${i%60}m ago`}(t.updated)}),(0,i.jsx)(tw,{label:"Vehicle ID",children:(0,i.jsx)("span",{className:"font-mono text-xs",children:t.vid})}),(0,i.jsx)(tw,{label:"Coordinates",children:(0,i.jsxs)("span",{className:"font-mono text-xs tabular-nums",children:[Number(t.lat).toFixed(4),", ",Number(t.lng).toFixed(4)]})})]})]})]}),A&&(0,i.jsx)("div",{className:"shrink-0 border-t border-gray-100 bg-white px-5 py-4 pb-[calc(1rem+env(safe-area-inset-bottom))]",children:(0,i.jsxs)("a",{href:A,className:"flex w-full items-center justify-center gap-2 rounded-lg bg-blue-800 px-4 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-blue-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-800",children:["View full train details",(0,i.jsx)(f.A,{className:"h-4 w-4","aria-hidden":"true"})]})})]})}function t_({train:t,network:e,onClose:a,onSelectStation:n,docked:s=!1}){let r=!!t;return((0,g.useEffect)(()=>{if(!r)return;let t=t=>{"Escape"!==t.key||t.defaultPrevented||document.querySelector('[role="dialog"][aria-modal="true"]')||a()};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[r,a]),r)?(0,i.jsx)("aside",{"aria-label":"Train details",className:s?"relative z-20 h-full w-[380px] shrink-0 bg-white":"pointer-events-none absolute inset-x-0 bottom-0 z-20 max-h-full lg:inset-y-0 lg:left-auto lg:right-0 lg:w-[380px] lg:p-3",children:(0,i.jsxs)("div",{className:`pointer-events-auto flex max-h-full flex-col overflow-hidden bg-white ${s?"h-full":"h-[68dvh] rounded-t-2xl shadow-2xl ring-1 ring-black/5 lg:h-full lg:rounded-xl"}`,children:[(0,i.jsx)("div",{className:"flex shrink-0 justify-center pt-2.5 lg:hidden","aria-hidden":"true",children:(0,i.jsx)("span",{className:"h-1 w-9 rounded-full bg-gray-300"})}),t.freight?(0,i.jsx)(tm,{train:t,onClose:a}):(0,i.jsx)(tx,{train:t,network:e,onClose:a,onSelectStation:n},`${t.agency}:${t.vid}:${t.gtfs?.trip_id||""}`)]})}):null}var tv=a(77250),tj=a(50417),tk=a(62665),tS=a(61016);let tC=async t=>{let e=await fetch(t);if(!e.ok)throw Error("Station unavailable");return e.json()},tN=JSON.parse('{"30th street":[{"city":"Philadelphia","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/221_30th_Street_Station.jpg"}],"34th street hudson yards":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/431_34th_Street-Hudson_Yards_Station.jpg"}],"7th street metro center":[{"city":"Los Angeles","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/353_7th_StreetMetro_Center_Station.jpg"}],"addis ababa legehar":[{"city":"Addis Ababa","country":"Ethiopia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/391_Addis_Ababa_Railway_Station_Legehar.jpg"}],"adelaide":[{"city":"Adelaide","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/279_Adelaide_Railway_Station.jpg"}],"agra cantt":[{"city":"Agra","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/322_Agra_Cantt.jpg"}],"aguas calientes machu picchu":[{"city":"Aguas Calientes","country":"Peru","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/386_Aguas_Calientes_Machu_Picchu_Station.jpg"}],"ahmedabad":[{"city":"Ahmedabad","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/94_Ahmedabad_Junction.jpg"}],"akihabara":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/23_Akihabara_Station.jpg"}],"albany rensselaer":[{"city":"Rensselaer","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/226_Albany-Rensselaer_Station.jpg"}],"alger agha":[{"city":"Algiers","country":"Algeria","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/395_Alger_Agha_Station.jpg"}],"aluva":[{"city":"Kochi","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/419_Aluva_Station.jpg"}],"ameerpet":[{"city":"Hyderabad","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/418_Ameerpet_Station.jpg"}],"amritsar":[{"city":"Amritsar","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/318_Amritsar_Junction.jpg"}],"amsterdam centraal":[{"city":"Amsterdam","country":"Netherlands","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/192_Amsterdam_Centraal.jpg"}],"andheri":[{"city":"Mumbai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/323_Andheri_Station.jpg"}],"andheri metro":[{"city":"Mumbai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/415_Andheri_Metro_Station.jpg"}],"antwerp centraal":[{"city":"Antwerp","country":"Belgium","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/195_Antwerp_Centraal.jpg"}],"astana nurly zhol":[{"city":"Astana","country":"Kazakhstan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/451_Astana_Nurly_Zhol_Station.jpg"}
1],"athens larissa":[{"city":"Athens","country":"Greece","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/210_Athens_Larissa_Station.jpg"}],"atlantic":[{"city":"Brooklyn","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/248_Atlantic_Terminal.jpg"}],"atlantic avenue barclays center":[{"city":"Brooklyn","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/356_Atlantic_Avenue-Barclays_Center_Station.jpg"}],"back bay":[{"city":"Boston","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/228_Back_Bay_Station.jpg"}],"baltimore penn":[{"city":"Baltimore","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/224_Baltimore_Penn_Station.jpg"}],"bang sue grand":[{"city":"Bangkok","country":"Thailand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/118_Bang_Sue_Grand_Station.jpg"}],"banqiao":[{"city":"New Taipei","country":"Taiwan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/71_Banqiao_Station.jpg"}],"barcelona sants":[{"city":"Barcelona","country":"Spain","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/188_Barcelona_Sants.jpg"}],"beijing chaoyang":[{"city":"Beijing","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/39_Beijing_Chaoyang_Railway_Station.jpg"}],"beijing daxing airport":[{"city":"Beijing","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/481_Beijing_Daxing_Airport_Station.jpg"}],"beijing south":[{"city":"Beijing","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/37_Beijing_South_Railway_Station.jpg"}],"beijing west":[{"city":"Beijing","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/36_Beijing_West_Railway_Station.jpg"}],"belorussky rail":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/134_Belorussky_Rail_Terminal.jpg"}],"ben thanh":[{"city":"Ho Chi Minh City","country":"Vietnam","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/485_Bến_Th\xe0nh_Station.jpg"}],"bengaluru city":[{"city":"Bengaluru","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/92_Bengaluru_City_Railway_Station.jpg"}],"beograd centar":[{"city":"Belgrade","country":"Serbia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/442_Beograd_Centar.jpg"}],"bergen":[{"city":"Bergen","country":"Norway","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/471_Bergen_Station.jpg"}],"berlin hauptbahnhof":[{"city":"Berlin","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/170_Berlin_Hauptbahnhof.jpg"}],"bern hauptbahnhof":[{"city":"Bern","country":"Switzerland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/198_Bern_Hauptbahnhof.jpg"}],"bhopal":[{"city":"Bhopal","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/321_Bhopal_Junction.jpg"}],"bhubaneswar":[{"city":"Bhubaneswar","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/496_Bhubaneswar_Railway_Station.jpg"}],"bilbao abando":[{"city":"Bilbao","country":"Spain","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/294_Bilbao_Abando_Station.jpg"}],"birmingham new street":[{"city":"Birmingham","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/144_Birmingham_New_Street.jpg"}],"bloor yonge":[{"city":"Toronto","country":"Canada","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/259_Bloor-Yonge_Station.jpg"}],"bogor":[{"city":"Bogor","country":"Indonesia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/109_Bogor_Station.jpg"}],"bologna centrale":[{"city":"Bologna","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/185_Bologna_Centrale.jpg"}],"bond street":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/152_Bond_Street.jpg"}],"borivali":[{"city":"Mumbai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/324_Borivali_Station.jpg"}],"bras":[{"city":"S\xe3o Paulo","country":"Brazil","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/265_Br\xe1s_Station.jpg"}],"bremen hauptbahnhof":[{"city":"Bremen","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/369_Bremen_Hauptbahnhof.
1jpg"}],"bristol temple meads":[{"city":"Bristol","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/358_Bristol_Temple_Meads.jpg"}],"britomart":[{"city":"Auckland","country":"New Zealand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/281_Britomart_Station.jpg"}],"bruxelles midi":[{"city":"Brussels","country":"Belgium","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/196_Bruxelles-Midi.jpg"}],"budapest keleti":[{"city":"Budapest","country":"Hungary","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/204_Budapest_Keleti.jpg"}],"buenavista":[{"city":"Mexico City","country":"Mexico","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/261_Buenavista_Station.jpg"}],"busan":[{"city":"Busan","country":"South Korea","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/76_Busan_Station.jpg"}],"bwi thurgood marshall airport":[{"city":"Baltimore","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/227_BWI_Thurgood_Marshall_Airport_Station.jpg"}],"caltrain san francisco 4th and king":[{"city":"San Francisco","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/436_Caltrain_San_Francisco_Station_4th_and_King.jpg"}],"camden":[{"city":"Baltimore","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/437_Camden_Station.jpg"}],"canfranc international":[{"city":"Canfranc","country":"Spain","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/290_Canfranc_International_Railway_Station.jpg"}],"cape town":[{"city":"Cape Town","country":"South Africa","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/288_Cape_Town_Station.jpg"}],"capitolio":[{"city":"Caracas","country":"Venezuela","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/476_Capitolio_Station.jpg"}],"cardiff central":[{"city":"Cardiff","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/149_Cardiff_Central.jpg"}],"casa voyageurs":[{"city":"Casablanca","country":"Morocco","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/285_Casa-Voyageurs_Station.jpg"}],"cass scenic":[{"city":"Cass","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/467_Cass_Scenic_Railroad_Depot.jpg"}],"causeway bay":[{"city":"Hong Kong","country":"Hong Kong","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/67_Causeway_Bay_Station.jpg"}],"central":[{"city":"Hong Kong","country":"Hong Kong","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/65_Central_Station.jpg"},{"city":"Sydney","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/275_Central_Station.jpg"},{"city":"Ottawa","country":"Canada","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/383_Central_Station.jpg"}],"central do brasil":[{"city":"Rio de Janeiro","country":"Brazil","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/266_Central_do_Brasil.jpg"}],"century avenue":[{"city":"Shanghai","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/61_Century_Avenue_Station.jpg"}],"century park":[{"city":"Shanghai","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/316_Century_Park_Station.jpg"}],"changsha south":[{"city":"Changsha","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/56_Changsha_South_Railway_Station.jpg"}],"charlotte gateway":[{"city":"Charlotte","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/336_Charlotte_Gateway_Station.jpg"}],"chatelet les halles":[{"city":"Paris","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/161_Ch\xe2telet-Les_Halles.jpg"}],"chengdu east":[{"city":"Chengdu","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/45_Chengdu_East_Railway_Station.jpg"}
1],"chennai central":[{"city":"Chennai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/85_Chennai_Central.jpg"}],"chennai central metro":[{"city":"Chennai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/417_Chennai_Central_Metro_Station.jpg"}],"chennai egmore":[{"city":"Chennai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/317_Chennai_Egmore.jpg"}],"chhatrapati shivaji maharaj":[{"city":"Mumbai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/80_Chhatrapati_Shivaji_Maharaj_Terminus.jpg"}],"chiang mai":[{"city":"Chiang Mai","country":"Thailand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/406_Chiang_Mai_Railway_Station.jpg"}],"chiba":[{"city":"Chiba","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/301_Chiba_Station.jpg"}],"chicago ogilvie transportation center":[{"city":"Chicago","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/348_Chicago_Ogilvie_Transportation_Center.jpg"}],"chicago state lake":[{"city":"Chicago","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/246_Chicago_StateLake_Station.jpg"}],"chicago union":[{"city":"Chicago","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/222_Chicago_Union_Station.jpg"}],"chongqing north":[{"city":"Chongqing","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/51_Chongqing_North_Railway_Station.jpg"}],"chunxi road":[{"city":"Chengdu","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/420_Chunxi_Road_Station.jpg"}],"churchgate":[{"city":"Mumbai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/87_Churchgate_Railway_Station.jpg"}],"city hall mrt":[{"city":"Singapore","country":"Singapore","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/113_City_Hall_MRT_Station.jpg"}],"clapham":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/150_Clapham_Junction.jpg"}],"clark lake":[{"city":"Chicago","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/349_ClarkLake_Station.jpg"}],"coimbatore":[{"city":"Coimbatore","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/500_Coimbatore_Junction.jpg"}],"colombo fort":[{"city":"Colombo","country":"Sri Lanka","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/405_Colombo_Fort_Railway_Station.jpg"}],"constitucion":[{"city":"Buenos Aires","country":"Argentina","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/268_Constituci\xf3n_Station.jpg"}],"conwy valley betws y coed":[{"city":"Betws-y-Coed","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/461_Conwy_Valley_Betws-y-Coed_Station.jpg"}],"dadar":[{"city":"Mumbai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/86_Dadar_Railway_Station.jpg"}],"dakar regional express train":[{"city":"Dakar","country":"Senegal","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/456_Dakar_Regional_Express_Train_Station.jpg"}],"dalian":[{"city":"Dalian","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/491_Dalian_Railway_Station.jpg"}],"dallas union":[{"city":"Dallas","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/340_Dallas_Union_Station.jpg"}],"denver union":[{"city":"Denver","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/237_Denver_Union_Station.jpg"}],"dhaka kamalapur":[{"city":"Dhaka","country":"Bangladesh","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/408_Dhaka_Kamalapur_Railway_Station.jpg"}],"doha msheireb":[{"city":"Doha","country":"Qatar","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/398_Doha_Msheireb_Station.jpg"}],"dongdaegu":[{"city":"Daegu","country":"South Korea","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/79_Dongdaegu_Station.jpg"}],"dortmund hauptbahnhof":[{"city":"Dortmund","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/175_Dortmund_Hauptbahnhof.
1jpg"}],"dubai union burjuman":[{"city":"Dubai","country":"United Arab Emirates","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/215_Dubai_Union_Station_BurJuman.jpg"}],"dublin connolly":[{"city":"Dublin","country":"Ireland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/155_Dublin_Connolly.jpg"}],"dublin heuston":[{"city":"Dublin","country":"Ireland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/444_Dublin_Heuston.jpg"}],"dunedin":[{"city":"Dunedin","country":"New Zealand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/414_Dunedin_Railway_Station.jpg"}],"durango and silverton":[{"city":"Durango","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/466_Durango_and_Silverton_Depot.jpg"}],"dusseldorf hauptbahnhof":[{"city":"D\xfcsseldorf","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/174_D\xfcsseldorf_Hauptbahnhof.jpg"}],"edinburgh waverley":[{"city":"Edinburgh","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/148_Edinburgh_Waverley.jpg"}],"edmonton churchill":[{"city":"Edmonton","country":"Canada","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/438_Edmonton_Churchill_Station.jpg"}],"edsa":[{"city":"Manila","country":"Philippines","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/120_EDSA_Station.jpg"}],"elektrozavodskaya metro":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/447_Elektrozavodskaya_Metro_Station.jpg"}],"embarcadero":[{"city":"San Francisco","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/352_Embarcadero_Station.jpg"}],"esplanade metro":[{"city":"Kolkata","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/102_Esplanade_Metro_Station.jpg"}],"essen hauptbahnhof":[{"city":"Essen","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/176_Essen_Hauptbahnhof.jpg"}],"estacao ferroviaria de ouro preto":[{"city":"Ouro Preto","country":"Brazil","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/388_Esta\xe7\xe3o_Ferrovi\xe1ria_de_Ouro_Preto.jpg"}],"estacion central":[{"city":"Santiago","country":"Chile","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/269_Estaci\xf3n_Central.jpg"}],"estacion de la sabana":[{"city":"Bogot\xe1","country":"Colombia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/270_Estaci\xf3n_de_la_Sabana.jpg"}],"estacion desamparados":[{"city":"Lima","country":"Peru","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/271_Estaci\xf3n_Desamparados.jpg"}],"ffestiniog porthmadog":[{"city":"Porthmadog","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/460_Ffestiniog_Railway_Porthmadog_Station.jpg"}],"firenze santa maria novella":[{"city":"Florence","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/184_Firenze_Santa_Maria_Novella.jpg"}],"flam":[{"city":"Fl\xe5m","country":"Norway","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/382_Fl\xe5m_Station.jpg"}],"flinders street":[{"city":"Melbourne","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/272_Flinders_Street_Station.jpg"}],"flushing main street":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/354_Flushing-Main_Street_Station.jpg"}],"formosa boulevard":[{"city":"Kaohsiung","country":"Taiwan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/296_Formosa_Boulevard_Station.jpg"}],"fort worth central":[{"city":"Fort Worth","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/341_Fort_Worth_Central_Station.jpg"}],"foshan metro chancheng":[{"city":"Foshan","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/315_Foshan_Metro_Chancheng_Station.jpg"}],"frankfurt hauptbahnhof":[{"city":"Frankfurt","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/168_Frankfurt_Hauptbahnhof.
1jpg"}],"fremantle":[{"city":"Fremantle","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/411_Fremantle_Railway_Station.jpg"}],"fulton center":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/247_Fulton_Center.jpg"}],"fulton street":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/234_Fulton_Street_Station.jpg"}],"fuzhou":[{"city":"Fuzhou","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/490_Fuzhou_Railway_Station.jpg"}],"gallery place chinatown":[{"city":"Washington, D.C.","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/351_Gallery_Place-Chinatown_Station.jpg"}],"gambir":[{"city":"Jakarta","country":"Indonesia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/107_Gambir_Station.jpg"}],"gangnam":[{"city":"Seoul","country":"South Korea","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/73_Gangnam_Station.jpg"}],"gara de nord":[{"city":"Bucharest","country":"Romania","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/441_Gara_de_Nord.jpg"}],"gare centrale":[{"city":"Montreal","country":"Canada","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/256_Gare_Centrale.jpg"}],"gare centrale kinshasa":[{"city":"Kinshasa","country":"Democratic Republic of the Congo","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/457_Gare_Centrale_Kinshasa.jpg"}],"gare d austerlitz":[{"city":"Paris","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/365_Gare_dAusterlitz.jpg"}],"gare de bordeaux saint jean":[{"city":"Bordeaux","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/164_Gare_de_Bordeaux_Saint-Jean.jpg"}],"gare de l est":[{"city":"Paris","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/160_Gare_de_lEst.jpg"}],"gare de lille europe":[{"city":"Lille","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/166_Gare_de_Lille_Europe.jpg"}],"gare de lyon":[{"city":"Paris","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/158_Gare_de_Lyon.jpg"}],"gare de lyon part dieu":[{"city":"Lyon","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/162_Gare_de_Lyon-Part-Dieu.jpg"}],"gare de metz ville":[{"city":"Metz","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/293_Gare_de_Metz-Ville.jpg"}],"gare de nice ville":[{"city":"Nice","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/366_Gare_de_Nice-Ville.jpg"}],"gare de strasbourg":[{"city":"Strasbourg","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/165_Gare_de_Strasbourg.jpg"}],"gare du nord":[{"city":"Paris","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/156_Gare_du_Nord.jpg"}],"gare montparnasse":[{"city":"Paris","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/159_Gare_Montparnasse.jpg"}],"gare saint lazare":[{"city":"Paris","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/157_Gare_Saint-Lazare.jpg"}],"geneve cornavin":[{"city":"Geneva","country":"Switzerland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/199_Gen\xe8ve-Cornavin.jpg"}],"genova piazza principe":[{"city":"Genoa","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/371_Genova_Piazza_Principe.jpg"}],"ghatkopar":[{"city":"Mumbai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/47
17_Ghatkopar_Station.jpg"}],"ghaziabad":[{"city":"Ghaziabad","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/98_Ghaziabad_Junction.jpg"}],"ghum":[{"city":"Darjeeling","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/325_Ghum_Station.jpg"}],"ginza":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/24_Ginza_Station.jpg"}],"glacier express andermatt":[{"city":"Andermatt","country":"Switzerland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/458_Glacier_Express_Andermatt_Station.jpg"}],"glasgow central":[{"city":"Glasgow","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/147_Glasgow_Central.jpg"}],"gotanda":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/34_Gotanda_Station.jpg"}],"government center":[{"city":"Miami","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/434_Government_Center_Station.jpg"}],"grand central":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/219_Grand_Central_Terminal.jpg"}],"grand central 42nd street subway":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/231_Grand_Central-42nd_Street_Subway.jpg"}],"guangzhou":[{"city":"Guangzhou","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/42_Guangzhou_Railway_Station.jpg"}],"guangzhou east":[{"city":"Guangzhou","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/314_Guangzhou_East_Railway_Station.jpg"}],"guangzhou south":[{"city":"Guangzhou","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/43_Guangzhou_South_Railway_Station.jpg"}],"guomao":[{"city":"Beijing","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/60_Guomao_Station.jpg"}],"guwahati":[{"city":"Guwahati","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/495_Guwahati_Railway_Station.jpg"}],"hakata":[{"city":"Fukuoka","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/17_Hakata_Station.jpg"}],"hamburg hauptbahnhof":[{"city":"Hamburg","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/167_Hamburg_Hauptbahnhof.jpg"}],"hangzhou east":[{"city":"Hangzhou","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/50_Hangzhou_East_Railway_Station.jpg"}],"hannover hauptbahnhof":[{"city":"Hanover","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/177_Hannover_Hauptbahnhof.jpg"}],"hanoi":[{"city":"Hanoi","country":"Vietnam","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/122_Hanoi_Railway_Station.jpg"}],"harbin west":[{"city":"Harbin","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/310_Harbin_West_Railway_Station.jpg"}],"harrisburg transportation center":[{"city":"Harrisburg","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/333_Harrisburg_Transportation_Center.jpg"}],"haydarpasa":[{"city":"Istanbul","country":"Turkey","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/212_HaydarpaÅa_Terminal.jpg"}],"helsinki central":[{"city":"Helsinki","country":"Finland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/208_Helsinki_Central_Station.jpg"}],"hiroshima":[{"city":"Hiroshima","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/20_Hiroshima_Station.jpg"}],"hoboken":[{"city":"Hoboken","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/235_Hoboken_Terminal.jpg"}],"hong kong airport express":[{"city":"Hong Kong","country":"Hong Kong","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/482_Hong_Kong_Airport_Express_Station.jpg"}],"hong kong west kowloon":[{"city":"Hong Kong","country":"Hong Kong","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/64_Hong_Kong_West_Kowloon_Station.jpg"}],"hongik university":[{"city":"Seoul","country":"South Korea","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/75_Hongik_University_Station.jpg"}],"houston amtrak":[{"city":"Houston","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/342_Houston_Amtrak_Station.jpg"}],"howrah":[{"city":"Kolkata","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/81_Howrah_Junction.jpg"}],"hua lamphong":[{"city":"Bangkok","country":"Thailand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/117_Hua_Lamph
1ong_Station.jpg"}],"hung hom":[{"city":"Hong Kong","country":"Hong Kong","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/68_Hung_Hom_Station.jpg"}],"ikebukuro":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/3_Ikebukuro_Station.jpg"}],"incheon international airport":[{"city":"Incheon","country":"South Korea","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/428_Incheon_International_Airport_Station.jpg"}],"indios verdes":[{"city":"Mexico City","country":"Mexico","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/262_Indios_Verdes_Station.jpg"}],"interlaken ost":[{"city":"Interlaken","country":"Switzerland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/459_Interlaken_Ost_Station.jpg"}],"jackson heights roosevelt avenue":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/355_Jackson_Heights-Roosevelt_Avenue_Station.jpg"}],"jaipur":[{"city":"Jaipur","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/319_Jaipur_Junction.jpg"}],"jakarta kota":[{"city":"Jakarta","country":"Indonesia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/106_Jakarta_Kota_Station.jpg"}],"jamaica":[{"city":"Queens","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/236_Jamaica_Station.jpg"}],"jamsil":[{"city":"Seoul","country":"South Korea","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/74_Jamsil_Station.jpg"}],"jefferson":[{"city":"Philadelphia","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/478_Jefferson_Station.jpg"}
1],"jinan west":[{"city":"Jinan","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/489_Jinan_West_Railway_Station.jpg"}],"johannesburg park":[{"city":"Johannesburg","country":"South Africa","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/287_Johannesburg_Park_Station.jpg"}],"journal square":[{"city":"Jersey City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/432_Journal_Square_Station.jpg"}],"jungfraujoch":[{"city":"Jungfraujoch","country":"Switzerland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/378_Jungfraujoch_Railway_Station.jpg"}],"jurong east mrt":[{"city":"Singapore","country":"Singapore","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/114_Jurong_East_MRT_Station.jpg"}],"k benhavn h":[{"city":"Copenhagen","country":"Denmark","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/207_K\xf8benhavn_H.jpg"}],"kalka":[{"city":"Kalka","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/327_Kalka_Railway_Station.jpg"}],"kalyan":[{"city":"Mumbai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/84_Kalyan_Junction.jpg"}],"kamakura":[{"city":"Kamakura","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/425_Kamakura_Station.jpg"}],"kanazawa":[{"city":"Kanazawa","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/19_Kanazawa_Station.jpg"}],"kanchanaburi":[{"city":"Kanchanaburi","country":"Thailand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/407_Kanchanaburi_Railway_Station.jpg"}],"kandy":[{"city":"Kandy","country":"Sri Lanka","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/404_Kandy_Railway_Station.jpg"}],"kanpur central":[{"city":"Kanpur","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/89_Kanpur_Central.jpg"}],"kaohsiung main":[{"city":"Kaohsiung","country":"Taiwan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/70_Kaohsiung_Main_Station.jpg"}],"karachi cantonment":[{"city":"Karachi","country":"Pakistan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/409_Karachi_Cantonment_Station.jpg"}],"kashmere gate metro":[{"city":"Delhi","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/101_Kashmere_Gate_Metro_Station.jpg"}],"kawasaki":[{"city":"Kawasaki","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/30_Kawasaki_Station.jpg"}],"kazansky rail":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/129_Kazansky_Rail_Terminal.jpg"}],"kichijoji":[{"city":"Musashino","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/304_Kichijoji_Station.jpg"}],"kievskaya metro":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/125_Kievskaya_Metro_Station.jpg"}],"kita senju":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/9_Kita-Senju_Station.jpg"}],"kl sentral":[{"city":"Kuala Lumpur","country":"Malaysia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/111_KL_Sentral.jpg"}],"kobe":[{"city":"Kobe","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/426_Kobe_Station.jpg"}],"kobe sannomiya":[{"city":"Kobe","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/18_Kobe_Sannomiya_Station.jpg"}],"kokura":[{"city":"Kitakyushu","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/35_Kokura_Station.jpg"}],"kollam":[{"city":"Kollam","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/497_Kollam_Junction.jpg"}],"koln hauptbahnhof":[{"city":"Cologne","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/171_K\xf6ln_Hauptbahnhof.
1jpg"}],"komsomolskaya metro":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/124_Komsomolskaya_Metro_Station.jpg"}],"krakow g owny":[{"city":"Krak\xf3w","country":"Poland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/440_Krak\xf3w_GÅ\xf3wny.jpg"}],"kuala lumpur":[{"city":"Kuala Lumpur","country":"Malaysia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/110_Kuala_Lumpur_Railway_Station.jpg"}],"kuala lumpur international airport":[{"city":"Sepang","country":"Malaysia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/487_Kuala_Lumpur_International_Airport_Station.jpg"}],"kumamoto":[{"city":"Kumamoto","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/307_Kumamoto_Station.jpg"}],"kungstradgarden":[{"city":"Stockholm","country":"Sweden","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/298_Kungstr\xe4dg\xe5rden_Station.jpg"}],"kunming":[{"city":"Kunming","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/55_Kunming_Railway_Station.jpg"}],"kuranda":[{"city":"Kuranda","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/462_Kuranda_Railway_Station.jpg"}],"kursky rail":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/131_Kursky_Rail_Terminal.jpg"}],"kyiv passenger":[{"city":"Kyiv","country":"Ukraine","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/209_Kyiv_Passenger_Railway_Station.jpg"}],"kyoto":[{"city":"Kyoto","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/14_Kyoto_Station.jpg"}],"l enfant plaza":[{"city":"Washington, D.C.","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/350_LEnfant_Plaza_Station.jpg"}],"lahore":[{"city":"Lahore","country":"Pakistan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/410_Lahore_Railway_Station.jpg"}],"leeds":[{"city":"Leeds","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/146_Leeds_Railway_Station.jpg"}],"leipzig hauptbahnhof":[{"city":"Leipzig","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/173_Leipzig_Hauptbahnhof.jpg"}],"leningradsky rail":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/130_Leningradsky_Rail_Terminal.jpg"}],"liege guillemins":[{"city":"Li\xe8ge","country":"Belgium","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/291_Li\xe8ge-Guillemins_Station.jpg"}],"lisboa oriente":[{"city":"Lisbon","country":"Portugal","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/191_Lisboa_Oriente.jpg"}],"liverpool lime street":[{"city":"Liverpool","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/360_Liverpool_Lime_Street.jpg"}],"lokmanya tilak":[{"city":"Mumbai","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/88_Lokmanya_Tilak_Terminus.jpg"}],"london bridge":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/143_London_Bridge.jpg"}],"london euston":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/142_London_Euston.jpg"}],"london king s cross st pancras":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/139_London_Kings_Cross_St_Pancras.jpg"}],"london liverpool street":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/136_London_Liverpool_Street.jpg"}],"london paddington":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/138_London_Paddington.jpg"}],"london victoria":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/141_London_Victoria.jpg"}],"london waterloo":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/137_London_Waterloo.jpg"}],"los angeles union":[{"city":"Los Angeles","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/225_Los_Angeles_Union_Station.jpg"}],"lucknow charbagh":[{"city":"Lucknow","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/103_Lucknow_Charbagh_Railway_Station.jpg"}],"luxembourg":[{"city":"Luxembourg City","country":"Luxembourg","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/445_Luxembourg_Station.jpg"}],"luz":[{"city":"S\xe3o Paulo","country":"Brazil","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/264_Luz_Station.jpg"}],"machida":[{"city":"Machida","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/303_Machida_Station.jpg"}],"madrid atocha":[{"city":"Madrid","country":"Spain","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/186_Madrid_Atocha.jpg"}],"majestic kempegowda":[{"city":"Bengaluru","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/416_Majestic_Kempegowda_Station.jpg"}],"malaga maria zambrano":[{"city":"M\xe1laga","country":"Spain","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/374_M\xe1laga_Mar\xeda_Zambrano.jpg"}],"manchester piccadilly":[{"city":"Manchester","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/145_Manchester_Piccadilly.jpg"}],"manggarai":[{"city":"Jakarta","country":"Indonesia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/105_Manggarai_Station.jpg"}],"mannheim hauptbahnhof":[{"city":"Mannheim","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/370_Mannheim_Hauptbahnhof.
1jpg"}],"marseille saint charles":[{"city":"Marseille","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/163_Marseille_Saint-Charles.jpg"}],"mayakovskaya metro":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/127_Mayakovskaya_Metro_Station.jpg"}],"mecca haramain":[{"city":"Mecca","country":"Saudi Arabia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/399_Mecca_Haramain_Station.jpg"}],"medina haramain":[{"city":"Medina","country":"Saudi Arabia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/400_Medina_Haramain_Station.jpg"}],"meguro":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/33_Meguro_Station.jpg"}],"melbourne central":[{"city":"Melbourne","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/274_Melbourne_Central_Station.jpg"}],"metro center":[{"city":"Washington, D.C.","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/249_Metro_Center_Station.jpg"}],"miami central":[{"city":"Miami","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/250_Miami_Central_Station.jpg"}],"milano centrale":[{"city":"Milan","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/180_Milano_Centrale.jpg"}],"millennium":[{"city":"Boston","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/242_Millennium_Station.jpg"}],"mo chit bts":[{"city":"Bangkok","country":"Thailand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/119_Mo_Chit_BTS_Station.jpg"}],"mobolaji johnson":[{"city":"Lagos","country":"Nigeria","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/454_Mobolaji_Johnson_Station.jpg"}],"moskovsky rail":[{"city":"Saint Petersburg","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/132_Moskovsky_Rail_Terminal.jpg"}],"moynihan train hall":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/429_Moynihan_Train_Hall.jpg"}],"munich hauptbahnhof":[{"city":"Munich","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/169_Munich_Hauptbahnhof.jpg"}],"musashi kosugi":[{"city":"Kawasaki","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/27_Musashi-Kosugi_Station.jpg"}],"museum":[{"city":"Sydney","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/413_Museum_Station.jpg"}],"myrdal":[{"city":"Myrdal","country":"Norway","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/472_Myrdal_Station.jpg"}],"mysuru":[{"city":"Mysuru","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/499_Mysuru_Junction.jpg"}],"nagano":[{"city":"Nagano","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/21_Nagano_Station.jpg"}],"nagoya":[{"city":"Nagoya","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/6_Nagoya_Station.jpg"}],"nagpur":[{"city":"Nagpur","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/320_Nagpur_Junction.jpg"}],"naha airport":[{"city":"Naha","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/306_Naha_Airport_Station.jpg"}],"nairobi":[{"city":"Nairobi","country":"Kenya","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/389_Nairobi_Railway_Station.jpg"}],"nairobi sgr":[{"city":"Nairobi","country":"Kenya","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/390_Nairobi_Terminus_SGR.jpg"}],"nakameguro":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/26_Nakameguro_Station.jpg"}],"namba":[{"city":"Osaka","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/10_Namba_Station.jpg"}],"nanjing road":[{"city":"Shanghai","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/62_Nanjing_Road_Station.jpg"}],"nanjing south":[{"city":"Nanjing","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/48_Nanjing_South_Railway_Station.jpg"}],"nanjing xinjiekou":[{"city":"Nanjing","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/423_Nanjing_Xinjiekou_Station.jpg"}],"nantes":[{"city":"Nantes","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/368_Nantes_Station.jpg"}],"napoli centrale":[{"city":"Naples","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/182_Napoli_Centrale.jpg"}],"new delhi":[{"city":"Delhi","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/83_New_Delhi_Railway_Station.jpg"}],"new haven union":[{"city":"New Haven","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/330_New_Haven_Union_Station.jpg"}],"new orleans union passenger":[{"city":"New Orleans","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/344_New_Orleans_Union_Passenger_Terminal.jpg"}],"new york penn":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/218_New_York_Penn_Station.jpg"}],"newark penn":[{"city":"Newark","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/328_Newark_Penn_Station.jpg"}
1],"newcastle central":[{"city":"Newcastle upon Tyne","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/361_Newcastle_Central_Station.jpg"}],"nishi funabashi":[{"city":"Funabashi","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/28_Nishi-Funabashi_Station.jpg"}],"north":[{"city":"Boston","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/241_North_Station.jpg"}],"nottingham":[{"city":"Nottingham","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/363_Nottingham_Station.jpg"}],"novosibirsk glavny":[{"city":"Novosibirsk","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/135_Novosibirsk_Glavny.jpg"}],"novoslobodskaya metro":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/446_Novoslobodskaya_Metro_Station.jpg"}],"nuremberg hauptbahnhof":[{"city":"Nuremberg","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/178_Nuremberg_Hauptbahnhof.jpg"}],"oakland jack london square":[{"city":"Oakland","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/346_Oakland_Jack_London_Square_Station.jpg"}],"old delhi":[{"city":"Delhi","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/97_Old_Delhi_Railway_Station.jpg"}],"omiya":[{"city":"Saitama","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/11_Omiya_Station.jpg"}],"ooty":[{"city":"Udhagamandalam","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/326_Ooty_Railway_Station.jpg"}],"orlando health amtrak":[{"city":"Orlando","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/337_Orlando_HealthAmtrak_Station.jpg"}],"osaka umeda":[{"city":"Osaka","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/4_Osaka_Umeda_Station.jpg"}],"oslo sentralstasjon":[{"city":"Oslo","country":"Norway","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/205_Oslo_Sentralstasjon.jpg"}],"otemachi":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/22_Otemachi_Station.jpg"}],"pacific central":[{"city":"Vancouver","country":"Canada","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/257_Pacific_Central_Station.jpg"}],"palermo centrale":[{"city":"Palermo","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/372_Palermo_Centrale.jpg"}],"pantitlan":[{"city":"Mexico City","country":"Mexico","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/260_Pantitl\xe1n_Station.jpg"}],"park street":[{"city":"Boston","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/435_Park_Street_Station.jpg"}],"parramatta":[{"city":"Sydney","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/412_Parramatta_Station.jpg"}],"patna":[{"city":"Patna","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/95_Patna_Junction.jpg"}],"people s square":[{"city":"Shanghai","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/58_Peoples_Square_Station.jpg"}],"perth":[{"city":"Perth","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/278_Perth_Station.jpg"}],"phnom penh":[{"city":"Phnom Penh","country":"Cambodia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/402_Phnom_Penh_Railway_Station.jpg"}],"piccadilly circus":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/154_Piccadilly_Circus.jpg"}],"ploshchad revolyutsii metro":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/126_Ploshchad_Revolyutsii_Metro_Station.jpg"}],"ploshchad vosstaniya metro":[{"city":"Saint Petersburg","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/133_Ploshchad_Vosstaniya_Metro_Station.jpg"}],"portland union":[{"city":"Portland","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/253_Portland_Union_Station.jpg"}],"powell street":[{"city":"San Francisco","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/239_Powell_Street_Station.jpg"}
1],"praha hlavni nadrazi":[{"city":"Prague","country":"Czech Republic","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/203_Praha_hlavn\xed_n\xe1draž\xed.jpg"}],"preston":[{"city":"Preston","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/364_Preston_Station.jpg"}],"providence":[{"city":"Providence","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/331_Providence_Station.jpg"}],"puffing billy belgrave":[{"city":"Belgrave","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/468_Puffing_Billy_Belgrave_Station.jpg"}],"pune":[{"city":"Pune","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/91_Pune_Junction.jpg"}],"qingdao":[{"city":"Qingdao","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/57_Qingdao_Railway_Station.jpg"}],"rabat agdal":[{"city":"Rabat","country":"Morocco","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/286_Rabat-Agdal_Station.jpg"}],"raffles place mrt":[{"city":"Singapore","country":"Singapore","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/112_Raffles_Place_MRT_Station.jpg"}],"rajiv chowk metro":[{"city":"Delhi","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/100_Rajiv_Chowk_Metro_Station.jpg"}],"raleigh union":[{"city":"Raleigh","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/335_Raleigh_Union_Station.jpg"}],"ramses":[{"city":"Cairo","country":"Egypt","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/282_Ramses_Station.jpg"}],"reading":[{"city":"Reading","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/357_Reading_Station.jpg"}],"recto":[{"city":"Manila","country":"Philippines","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/121_Recto_Station.jpg"}],"retiro":[{"city":"Buenos Aires","country":"Argentina","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/267_Retiro_Station.jpg"}],"richmond main street":[{"city":"Richmond","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/334_Richmond_Main_Street_Station.jpg"}],"riyadh qasr al hokm":[{"city":"Riyadh","country":"Saudi Arabia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/216_Riyadh_Qasr_Al_Hokm_Station.jpg"}],"rocky mountaineer banff":[{"city":"Banff","country":"Canada","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/464_Rocky_Mountaineer_Banff_Station.jpg"}],"roma street":[{"city":"Brisbane","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/280_Roma_Street_Station.jpg"}],"roma termini":[{"city":"Rome","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/179_Roma_Termini.jpg"}],"roppongi":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/25_Roppongi_Station.jpg"}],"rotterdam centraal":[{"city":"Rotterdam","country":"Netherlands","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/194_Rotterdam_Centraal.jpg"}],"rovos rail capital park":[{"city":"Pretoria","country":"South Africa","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/397_Rovos_Rail_Capital_Park_Station.jpg"}],"sacramento valley":[{"city":"Sacramento","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/251_Sacramento_Valley_Station.jpg"}],"sadat":[{"city":"Cairo","country":"Egypt","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/283_Sadat_Station.jpg"}],"sagrado corazon":[{"city":"San Juan","country":"Puerto Rico","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/433_Sagrado_Coraz\xf3n_Station.jpg"}],"saigon":[{"city":"Ho Chi Minh City","country":"Vietnam","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/123_Saigon_Railway_Station.jpg"}
1],"salt lake city central":[{"city":"Salt Lake City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/345_Salt_Lake_City_Central_Station.jpg"}],"salzburg hauptbahnhof":[{"city":"Salzburg","country":"Austria","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/201_Salzburg_Hauptbahnhof.jpg"}],"salzkammergut hallstatt":[{"city":"Hallstatt","country":"Austria","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/473_Salzkammergut_Hallstatt_Station.jpg"}],"san antonio sunset":[{"city":"San Antonio","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/339_San_Antonio_Sunset_Station.jpg"}],"san diego santa fe":[{"city":"San Diego","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/254_San_Diego_Santa_Fe_Depot.jpg"}],"san francisco salesforce transit center":[{"city":"San Francisco","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/238_San_Francisco_Salesforce_Transit_Center.jpg"}],"san jose diridon":[{"city":"San Jose","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/347_San_Jose_Diridon_Station.jpg"}],"san pedro":[{"city":"Cusco","country":"Peru","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/387_San_Pedro_Station.jpg"}],"sandton":[{"city":"Johannesburg","country":"South Africa","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/289_Sandton_Station.jpg"}],"sanyuanli":[{"city":"Guangzhou","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/63_Sanyuanli_Station.jpg"}],"sao bento":[{"city":"Porto","country":"Portugal","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/190_S\xe3o_Bento_Station.jpg"}],"sapporo":[{"city":"Sapporo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/16_Sapporo_Station.jpg"}],"sealdah":[{"city":"Kolkata","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/82_Sealdah_Railway_Station.jpg"}],"seattle king street":[{"city":"Seattle","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/252_Seattle_King_Street_Station.jpg"}],"secunderabad":[{"city":"Hyderabad","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/93_Secunderabad_Junction.jpg"}],"semmering ghega":[{"city":"Semmering","country":"Austria","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/377_Semmering_Railway_Ghega_Station.jpg"}],"sendai":[{"city":"Sendai","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/15_Sendai_Station.jpg"}],"seoul":[{"city":"Seoul","country":"South Korea","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/72_Seoul_Station.jpg"}],"seoul express bus":[{"city":"Seoul","country":"South Korea","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/427_Seoul_Express_Bus_Terminal_Station.jpg"}],"sevilla santa justa":[{"city":"Seville","country":"Spain","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/373_Sevilla_Santa_Justa.jpg"}],"shanghai":[{"city":"Shanghai","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/40_Shanghai_Railway_Station.jpg"}],"shanghai hongqiao":[{"city":"Shanghai","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/41_Shanghai_Hongqiao_Railway_Station.jpg"}],"shanghai maglev longyang road":[{"city":"Shanghai","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/483_Shanghai_Maglev_Longyang_Road_Station.jpg"}],"shanghai south":[{"city":"Shanghai","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/53_Shanghai_South_Railway_Station.jpg"}],"sheffield":[{"city":"Sheffield","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/362_Sheffield_Station.jpg"}],"shenzhen convention center":[{"city":"Shenzhen","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/424_Shenzhen_Convention_Center_Station.jpg"}],"shenzhen north":[{"city":"Shenzhen","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/44_Shenzhen_North_Railway_Station.jpg"}],"shibuya":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/2_Shibuya_Station.jpg"}],"shijiazhuang":[{"city":"Shijiazhuang","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/312_Shijiazhuang_Railway_Station.jpg"}],"shin osaka":[{"city":"Osaka","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/32_Shin-Osaka_Station.jpg"}],"shin yokohama":[{"city":"Yokohama","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/299_Shin-Yokohama_Station.jpg"}],"shinagawa":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/8_Shinagawa_Station.jpg"}],"shinbashi":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/12_Shinbashi_Station.jpg"}],"shinjuku":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/1_Shinjuku_Station.jpg"}],"siam bts":[{"city":"Bangkok","country":"Thailand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/116_Siam_BTS_Station.jpg"}],"sindorim":[{"city":"Seoul","country":"South Korea","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/78_Sindorim_Station.jpg"}],"sirkeci":[{"city":"Istanbul","country":"Turkey","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/211_Sirkeci_Station.jpg"}],"sochi":[{"city":"Sochi","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/376_Sochi_Railway_Station.jpg"}],"south":[{"city":"Boston","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/223_South_Station.jpg"}],"southern cross":[{"city":"Melbourne","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/273_Southern_Cross_Station.jpg"}],"st moritz":[{"city":"St. Moritz","country":"Switzerland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/380_St_Moritz_Station.jpg"}],"st pancras international":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/140_St_Pancras_International.jpg"}],"stockholm centralstation":[{"city":"Stockholm","country":"Sweden","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/206_Stockholm_Centralstation.jpg"}],"stratford":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/153_Stratford_Station.jpg"},{"city":"Stratford","country":"Canada","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/501_Stratford_Ontario_Station.jpg"}],"stuttgart hauptbahnhof":[{"city":"Stuttgart","country":"Germany","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/172_Stuttgart_Hauptbahnhof.
1jpg"}],"surat":[{"city":"Surat","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/494_Surat_Railway_Station.jpg"}],"suvarnabhumi airport rail link":[{"city":"Bangkok","country":"Thailand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/488_Suvarnabhumi_Airport_Rail_Link_Station.jpg"}],"suzhou north":[{"city":"Suzhou","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/309_Suzhou_North_Railway_Station.jpg"}],"syntagma metro":[{"city":"Athens","country":"Greece","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/474_Syntagma_Metro_Station.jpg"}],"tachikawa":[{"city":"Tachikawa","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/300_Tachikawa_Station.jpg"}],"taieri gorge":[{"city":"Dunedin","country":"New Zealand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/469_Taieri_Gorge_Railway_Station.jpg"}],"taipei main":[{"city":"Taipei","country":"Taiwan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/69_Taipei_Main_Station.jpg"}],"takadanobaba":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/31_Takadanobaba_Station.jpg"}],"taksim square":[{"city":"Istanbul","country":"Turkey","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/213_Taksim_Square_Station.jpg"}],"tampa union":[{"city":"Tampa","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/338_Tampa_Union_Station.jpg"}],"tanah abang":[{"city":"Jakarta","country":"Indonesia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/108_Tanah_Abang_Station.jpg"}],"tashkent":[{"city":"Tashkent","country":"Uzbekistan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/452_Tashkent_Railway_Station.jpg"}],"tbilisi central":[{"city":"Tbilisi","country":"Georgia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/453_Tbilisi_Central_Station.jpg"}],"tehran":[{"city":"Tehran","country":"Iran","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/217_Tehran_Railway_Station.jpg"}],"tel aviv savidor central":[{"city":"Tel Aviv","country":"Israel","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/214_Tel_Aviv_Savidor_Central.jpg"}],"tenjin":[{"city":"Fukuoka","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/29_Tenjin_Station.jpg"}],"tianjin":[{"city":"Tianjin","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/54_Tianjin_Railway_Station.jpg"}],"times square 42nd street":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/230_Times_Square-42nd_Street.jpg"}],"tirano":[{"city":"Tirano","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/381_Tirano_Station.jpg"}],"tokyo":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/7_Tokyo_Station.jpg"}],"toledo naples metro":[{"city":"Naples","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/295_Toledo_Station_Naples_Metro.jpg"}],"torino porta nuova":[{"city":"Turin","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/181_Torino_Porta_Nuova.jpg"}],"tottenham court road":[{"city":"London","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/151_Tottenham_Court_Road.jpg"}],"toulouse matabiau":[{"city":"Toulouse","country":"France","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/367_Toulouse-Matabiau_Station.jpg"}],"town hall":[{"city":"Sydney","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/276_Town_Hall_Station.jpg"}],"toyama":[{"city":"Toyama","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/305_Toyama_Station.jpg"}],"tranzalpine arthur s pass":[{"city":"Arthur\'s Pass","country":"New Zealand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/463_TranzAlpine_Arthurs_Pass_Station.jpg"}
1],"trenton transit center":[{"city":"Trenton","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/329_Trenton_Transit_Center.jpg"}],"trivandrum central":[{"city":"Thiruvananthapuram","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/498_Trivandrum_Central.jpg"}],"tunis ville":[{"city":"Tunis","country":"Tunisia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/394_Tunis_Ville_Station.jpg"}],"ueno":[{"city":"Tokyo","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/13_Ueno_Station.jpg"}],"union":[{"city":"Washington, D.C.","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/240_Union_Station.jpg"},{"city":"Toronto","country":"Canada","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/255_Union_Station.jpg"}],"union nashville":[{"city":"Nashville","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/292_Union_Station_Nashville.jpg"}],"union square 14th street":[{"city":"New York City","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/233_Union_Square-14th_Street.jpg"}],"universidad de chile":[{"city":"Santiago","country":"Chile","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/475_Universidad_de_Chile_Station.jpg"}],"urawa":[{"city":"Saitama","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/302_Urawa_Station.jpg"}],"urumqi":[{"city":"Urumqi","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/311_Urumqi_Railway_Station.jpg"}],"uskudar":[{"city":"Istanbul","country":"Turkey","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/480_\xdcsk\xfcdar_Station.jpg"}],"utrecht centraal":[{"city":"Utrecht","country":"Netherlands","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/193_Utrecht_Centraal.jpg"}],"vadodara":[{"city":"Vadodara","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/96_Vadodara_Junction.jpg"}],"valencia estacio del nord":[{"city":"Valencia","country":"Spain","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/189_Valencia_Estaci\xf3_del_Nord.jpg"}],"varanasi":[{"city":"Varanasi","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/104_Varanasi_Junction.jpg"}],"venezia santa lucia":[{"city":"Venice","country":"Italy","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/183_Venezia_Santa_Lucia.jpg"}],"victoria falls":[{"city":"Victoria Falls","country":"Zimbabwe","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/396_Victoria_Falls_Station.jpg"}],"vientiane boten vientiane":[{"city":"Vientiane","country":"Laos","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/403_Vientiane_Boten-Vientiane_Railway_Station.jpg"}],"vijayawada":[{"city":"Vijayawada","country":"India","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/90_Vijayawada_Junction.jpg"}],"warszawa centralna":[{"city":"Warsaw","country":"Poland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/202_Warszawa_Centralna.jpg"}],"washington union":[{"city":"Washington, D.C.","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/220_Washington_Union_Station.jpg"}],"waterfront":[{"city":"Vancouver","country":"Canada","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/258_Waterfront_Station.jpg"}],"wellington":[{"city":"Wellington","country":"New Zealand","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/484_Wellington_Railway_Station.jpg"}],"white pass and yukon route skagway":[{"city":"Skagway","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/465_White_Pass_and_Yukon_Route_Skagway_Station.jpg"}],"wien hauptbahnhof":[{"city":"Vienna","country":"Austria","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/200_Wien_Hauptbahnhof.
1jpg"}],"wilmington":[{"city":"Wilmington","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/332_Wilmington_Station.jpg"}],"wilshire vermont":[{"city":"Los Angeles","country":"United States","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/245_WilshireVermont_Station.jpg"}],"windsor":[{"city":"Montreal","country":"Canada","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/384_Windsor_Station.jpg"}],"woodlands mrt checkpoint":[{"city":"Singapore","country":"Singapore","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/115_Woodlands_MRTCheckpoint_Station.jpg"}],"wuhan":[{"city":"Wuhan","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/49_Wuhan_Railway_Station.jpg"}],"wuhan hankou":[{"city":"Wuhan","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/313_Wuhan_Hankou_Railway_Station.jpg"}],"wuhan metro hongshan square":[{"city":"Wuhan","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/421_Wuhan_Metro_Hongshan_Square_Station.jpg"}],"wynyard":[{"city":"Sydney","country":"Australia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/277_Wynyard_Station.jpg"}],"xi an bell tower metro":[{"city":"Xi\'an","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/422_Xian_Bell_Tower_Metro_Station.jpg"}],"xi an north":[{"city":"Xi\'an","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/47_Xian_North_Railway_Station.jpg"}],"xizhimen":[{"city":"Beijing","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/59_Xizhimen_Station.jpg"}],"yangon central":[{"city":"Yangon","country":"Myanmar","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/401_Yangon_Central_Railway_Station.jpg"}],"yaroslavsky rail":[{"city":"Moscow","country":"Russia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/128_Yaroslavsky_Rail_Terminal.jpg"}],"yokohama":[{"city":"Yokohama","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/5_Yokohama_Station.jpg"}],"yokohama kannai":[{"city":"Yokohama","country":"Japan","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/493_Yokohama_Kannai_Station.jpg"}],"yongsan":[{"city":"Seoul","country":"South Korea","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/77_Yongsan_Station.jpg"}],"york":[{"city":"York","country":"United Kingdom","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/359_York_Railway_Station.jpg"}],"zagreb glavni kolodvor":[{"city":"Zagreb","country":"Croatia","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/443_Zagreb_Glavni_kolodvor.jpg"}],"zermatt":[{"city":"Zermatt","country":"Switzerland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/379_Zermatt_Station.jpg"}],"zhengzhou":[{"city":"Zhengzhou","country":"China","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/46_Zhengzhou_Railway_Station.jpg"}],"zurich hauptbahnhof":[{"city":"Zurich","country":"Switzerland","url":"https://storage.googleapis.com/trainsfyi-station-images/station-images/197_Z\xfcrich_Hauptbahnhof.jpg"}]}');var tI=a(99904);let tM=new Set(["station","railway","railroad","terminal","terminus","junction","depot"]);function tA(t){return t?t.normalize("NFKD").replace(/[Ì-ͯ]/g,"").toLowerCase().replace(/\./g,"").replace(/[^a-z0-9\s]/g," ").replace(/\s+/g," ").trim():""}function tL(t,e,a=new Date){if(!t)return null;let i=new Date(t),n={timeZone:e||void 0},s=new Intl.DateTimeFormat("en-CA",{...n,year:"numeric",month:"2-digit",day:"2-digit"}),r=Object.fromEntries(s.formatToParts(a).map(t=>[t.type,t.value])),o=new Date(Date.UTC(Number(r.year),Number(r.month)-1,Number(r.day)+1)),l=new Intl.DateTimeFormat("en-CA",{timeZone:"UTC",year:"numeric",month:"2-digit",day:"2-digit"}
1).format(o),c=s.format(i);return c===s.format(a)?"Today":c===l?"Tomorrow":i.toLocaleDateString([],{...n,weekday:"short",month:"short",day:"numeric"})}let tT=(t,e)=>JSON.stringify([t?.toLowerCase(),String(e)]),tz=t=>t?.replaceAll("-","");var tR=a(74880),tP=a(25620),tU=a(21081),tE=a(39126);function t$({onClose:t}){let{signInWithGoogle:e,signInWithApple:a,loading:n}=(0,tP.A)(),[s,r]=(0,g.useState)(null),[o,l]=(0,g.useState)(""),c=async(e,a)=>{r(e),l("");try{await a(),t()}catch(t){l((0,tE.C1)(t))}finally{r(null)}};return(0,i.jsxs)(V.lG,{open:!0,onClose:t,className:"fixed inset-0 z-[1000]",children:[(0,i.jsx)(V.Xi,{className:"fixed inset-0 bg-slate-950/40 backdrop-blur-sm"}),(0,i.jsx)("div",{className:"fixed inset-0 flex items-center justify-center overflow-y-auto p-4",children:(0,i.jsxs)(V.Lj,{className:"relative my-auto w-full max-w-sm rounded-2xl bg-white p-6 shadow-2xl sm:p-8",children:[(0,i.jsx)("button",{type:"button",onClick:t,"aria-label":"Close registration",className:"absolute right-3 top-3 rounded-full p-2 text-gray-500 hover:bg-gray-100",children:(0,i.jsx)(y.A,{className:"h-5 w-5","aria-hidden":"true"})}),(0,i.jsx)(V.L3,{className:"mt-5 text-2xl font-semibold text-slate-950",children:"Create your account"}),(0,i.jsx)(q.VY,{className:"mb-6 mt-3 text-sm leading-6 text-slate-500",children:"Register or sign in to your TrainsFYI account. Network filters and more departures and arrivals are included with Pro."}),o&&(0,i.jsx)("p",{role:"alert",className:"mb-4 rounded-lg bg-red-50 p-3 text-sm text-red-800",children:o}),(0,i.jsx)("div",{className:"space-y-3",children:[{name:"Google",Icon:Y.DSS,signIn:e},{name:"Apple",Icon:Y.eMv,signIn:a}].map(({name:t,Icon:e,signIn:a})=>(0,i.jsxs)("button",{type:"button",disabled:n||!!s,onClick:()=>c(t,a),className:"flex min-h-12 w-full items-center justify-center gap-3 rounded-lg border border-slate-200 px-4 py-3 text-sm font-semibold text-slate-800 hover:bg-slate-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 disabled:opacity-50",children:[(0,i.jsx)(e,{className:"h-5 w-5","aria-hidden":"true"}),s===t?"Signing inâ¦":`Continue with ${t}`]},t))})]})})]})}function tF({stopName:t,citySlugs:e,networkIds:a=[]}){let n=(0,g.useMemo)(()=>(e||"").split(",").map(t=>tI.L.getCity(t.trim())?.name).filter(Boolean),[e]),s=(0,g.useMemo)(()=>[...new Set(a.flatMap(t=>tR.Y.getNetwork(t)?.countries||[]))],[a]),r=(0,g.useMemo)(()=>(function(t,e=[],a=[]){let i=t?t.normalize("NFKD").replace(/[Ì-ͯ]/g,"").toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter(t=>t&&!tM.has(t)).join(" ").trim():"",n=i?tN[i]:void 0;if(!n||!n.length)return;let s=e.map(tA);if(s.length){let t=n.filter(t=>s.includes(tA(t.city)));return 1===t.length?t[0].url:void 0}let r=a.map(tA);if(r.length){let t=n.filter(t=>r.includes(tA(t.country)));return 1===t.length?t[0].url:void 0}return 1===n.length?n[0].url:void 0})(t,n,s),[t,n,s]),[o,l]=(0,g.useState)(!1);return!r||o?null:(0,i.jsx)("img",{src:r,alt:t?`Photo of ${t}`:"Station photo",className:"col-span-3 aspect-video max-h-40 w-full rounded-lg object-cover",loading:"lazy",onError:()=>l(!0)})}function tB({kind:t,header:e=!1,rows:a=5}){return(0,i.jsxs)("div",{role:"status","aria-label":`Loading ${t}`,children:[(0,i.jsxs)("span",{className:"sr-only",children:["Loading ",t,"â¦"]}),e&&(0,i.jsxs)("div",{className:"flex h-9 items-center justify-between",children:[(0,i.jsx)(k,{className:"h-3 w-12"}),(0,i.jsx)(k,{className:"h-4 w-14"})]}),(0,i.jsx)("div",{"aria-hidden":"true",className:"mt-1 divide-y divide-gray-100",children:Array.from({length:a},(t,e)=>(0,i.jsxs)("div",{className:"flex items-center justify-between gap-3 py-2",children:[(0,i.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,i.jsx)(k,{className:`h-5 ${e%2?"w-3/5":"w-4/5"}`}),(0,i.jsxs)("div",{className:"mt-1 flex items-center gap-1.5",children:[(0,i.jsx)(k,{className:"h-2 w-2 !rounded-full"}),(0,i.jsx)(k,{className:"h-3 w-28"})]})]}),(0,i.jsx)(k,{className:"h-5 w-14 shrink-0"})]},e))})]})}function tD({stationId:t,kind:e,trainForCall:a,onSelectTrain:n,networks:s,excludedNetworks:r,onNetworkChange:o}){let{user:l,loading:d}=(0,tP.A)(),{isPremium:h,entitlementLoading:m}=(0,tU.x)(),u=(0,c.useRouter)(),p=d||m,b=!!l&&!p&&h,[f,w]=(0,g.useState)(!1),[x,_]=(0,g.useState)(!1),v=()=>{w(!1),l?u.push("/pro/"):_(!0)},j=b?r:[],C=j.length>0,N=(0,g.useRef)(null),I=(0,g.useRef)(null);(0,g.useEffect)(()=>
1{if(!f)return;N.current?.querySelector('[role="dialog"] input, [role="dialog"] a, [role="dialog"] button')?.focus();let t=t=>{N.current?.contains(t.target)||w(!1)},e=t=>{"Escape"===t.key&&(t.stopPropagation(),w(!1),I.current?.focus())};return document.addEventListener("pointerdown",t),document.addEventListener("keydown",e,!0),()=>{document.removeEventListener("pointerdown",t),document.removeEventListener("keydown",e,!0)}},[f]);let{data:M,isLoading:A,error:L,isLoadingMore:T,hasMore:z,loadMore:R}=function(t,e,a=!1){let{data:i,error:n,isLoading:s,isValidating:r,size:o,setSize:l,mutate:c}=(0,tS.Ay)((i,n)=>{if(!t||i>0&&(!a||!n?.next_cursor))return null;let s=`${S.QU}/api/v5/stations/${encodeURIComponent(t)}/${e}/`;return 0===i?s:`${s}?cursor=${encodeURIComponent(n.next_cursor)}`},tC,{refreshInterval:3e4,revalidateAll:!0}),g=a?i:i?.slice(0,1),d=new Set,h=(g||[]).flatMap(t=>t[e]||[]).filter(t=>{let e=JSON.stringify([t.network,t.trip_id,t.service_date,t.stop_sequence]);return!d.has(e)&&(d.add(e),!0)});return{data:i?{...i[0],[e]:h,unavailable_networks:[...new Set(g.flatMap(t=>t.unavailable_networks||[]))]}:void 0,error:n,isLoading:s,isLoadingMore:!!i?.length&&r&&o>i.length,hasMore:!!g?.[g.length-1]?.next_cursor,loadMore:()=>n?c():a?l(o+1):void 0}}(t,e,b),U=(M?.[e]||[]).filter(t=>!j.includes(t.network)),E="arrivals"===e,$=E?"Arrivals":"Departures",F=!!L,B=U[0],D=B&&tL(E?B.arrival_at:B.departure_at,B.timezone);return(0,i.jsxs)("section",{"aria-label":$,children:[(0,i.jsxs)("div",{className:"flex items-center justify-between",children:[(0,i.jsx)("span",{className:"text-xs font-semibold text-gray-500",children:A?(0,i.jsx)(k,{className:"h-3 w-12"}):D}),(0,i.jsxs)("div",{ref:N,className:"relative",children:[(0,i.jsxs)("button",{ref:I,type:"button","aria-haspopup":"dialog","aria-label":"Filter by network","aria-expanded":f,"aria-controls":"station-network-filter",disabled:p,onClick:()=>{b?w(!f):v()},className:`inline-flex min-h-9 items-center gap-1.5 rounded-lg px-2 text-xs font-medium hover:bg-gray-100 disabled:opacity-50 ${C?"text-blue-800":"text-gray-600"}`,children:[(0,i.jsx)(tv.A,{className:"h-4 w-4","aria-hidden":"true"}),"Filter",C&&(0,i.jsx)("span",{className:"h-1.5 w-1.5 rounded-full bg-blue-700","aria-label":"Active filter"}),!b&&(0,i.jsx)(tj.A,{className:"h-3 w-3","aria-hidden":"true"})]}),f&&b&&(0,i.jsxs)("div",{id:"station-network-filter",role:"dialog","aria-label":"Filter by network",className:"absolute right-0 top-full z-30 mt-1 w-64 max-w-[calc(100vw-3rem)] rounded-xl bg-white p-3 shadow-xl ring-1 ring-black/10",children:[(0,i.jsxs)("div",{className:"mb-1 flex items-center justify-between gap-2",children:[(0,i.jsx)("h3",{className:"text-sm font-semibold text-gray-900",children:"Networks"}),(0,i.jsx)("button",{type:"button","aria-label":"Close network filter",onClick:()=>{w(!1),I.current?.focus()},className:"rounded p-1 text-gray-500 hover:bg-gray-100",children:(0,i.jsx)(y.A,{className:"h-4 w-4","aria-hidden":"true"})})]}),(0,i.jsx)("div",{className:"max-h-48 overflow-y-auto",children:s.map(t=>(0,i.jsxs)("label",{className:"flex min-h-11 cursor-pointer items-center justify-between gap-3 text-sm text-gray-700",children:[(0,i.jsx)("span",{children:t.name}),(0,i.jsx)("input",{type:"checkbox",checked:!j.includes(t.id),onChange:e=>o(e.target.checked?r.filter(e=>e!==t.id):[...r,t.id]),className:"h-5 w-5 shrink-0 rounded border-gray-300 text-blue-700"})]},t.id))})]})]})]}),x&&!l&&(0,i.jsx)(t$,{onClose:()=>_(!1)}),M?.unavailable_networks?.length>0&&(0,i.jsxs)("p",{className:"mt-2 text-xs text-amber-700",children:["Some ",e," are unavailable (",M.unavailable_networks.join(", "),")."]}),F&&!M?(0,i.jsxs)("p",{className:"mt-2 text-sm text-gray-500",children:[$," aren't available for this station yet."]}):A?(0,i.jsx)(tB,{kind:e}):U.length?(0,i.jsx)("ul",{className:"mt-1 divide-y divide-gray-100",children:U.map((t,e)=>{let r=E?t.arrival_at:t.departure_at,o=r?new Date(r).toLocaleTimeString([],{hour:"numeric",minute:"2-digit",timeZone:t.timezone||void 0}):function(t){if(!t)return null;let[e,a]=t.split(":").map(Number);if(!Number.isFinite(e)||!Number.isFinite(a))return null;let i=Math.floor(e/24),n=new Date(0,0,0,e%24,a).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"});return i>0?`${n} (+${i}d)`:n}(E?t.realtime_arrival||t.scheduled_arrival:t.realtime_departure||t.scheduled_departure),l=tL(r,t.timezone),c=U[e-1],d=c&&tL(E?c.arrival_at:c.departure_at,c.timezone),h=E?t.arrival_delay_seconds:t.delay_seconds,m=Number.isFinite(h)?Math.round(h/60):null,u=E?null==h?"scheduled":h>0?"delayed":"on_time":t.status,p=a?.(t),y=tR.Y.getNetwork(t.network),b=s.find(e=>e.id===t.network),f=y?.shortForms[0]||b?.name||y?.name||t.network,w=b?.color||y?.color||"#64748b";return(0,i.jsxs)(g.Fragment,{children:[e>0&&l&&l!==d&&(0,i.jsx)("li",{className:"pt-3 pb-1 text-xs font-semibold text-gray-500",children:l}),(0,i.jsx)("li",{children:(0,i.jsxs)(p?"button":"div",{type:p?"button":void 0,onClick:p?()=>n(p):void 0,className:`flex w-full items-center justify-between gap-3 py-2 text-left text-sm ${p?"rounded-lg hover:bg-blue-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800":""}`,children:[(0,i.jsxs)("div",{className:"min-w-0",children:[(0,i.jsxs)("p",{className:"truncate font-medium text-gray-900",children:[t.route_short_name&&(0,i.jsx)("span",{className:"mr-1.5 rounded px-1.5 py-0.5 text-xs font-semibold text-white",style:{backgroundColor:t.route_color?`#${t.route_color}`:"#334155"},children:t.route_short_name}),E?`From ${P(t.origin?.stop_name)||"unknown origin"}`:P(t.trip_headsign||t.final_destination?.stop_name||"Destination unknown")]}),(0,i.jsxs)("p",{className:"flex items-center gap-1.5 text-xs text-gray-500",children:[(0,i.jsx)("span",{"aria-hidden":"true",className:"h-2 w-2 shrink-0 rounded-full",style:{backgroundColor:w}}),(0,i.jsxs)("span",{className:"truncate",children:[f,t.platform_name&&(0,i.jsxs)(i.Fragment,{children:[" \xb7 ",t.platform_name]})]})]})]}),(0,i.jsxs)("div",{className:"shrink-0 text-right",children:[(0,i.jsx)("p",{className:"font-semibold tabular-nums text-gray-900",children:o||"â"}),"delayed"===u&&m?(0,i.jsxs)("p",{className:"text-xs text-amber-700",children:["+",m," min"]}):"on_time"===u?(0,i.jsx)("p",{className:"text-xs text-emerald-700",children:"On time"}):null]})]})})]},`${t.network}-${t.trip_id}-${t.service_date}-${t.stop_sequence}`)})}):(0,i.jsx)("p",{className:"mt-2 text-sm text-gray-500",children:s.length>0&&s.every(t=>j.includes(t.id))?"No networks selected.":C?z?`No ${e} for the selected networks in the loaded results. Load more to check later services.`:`No ${e} for the selected networks in the next 26 hours.`:`No ${e} in the next 26 hours.`}),T&&(0,i.jsx)(tB,{kind:e,rows:2}),M&&L&&(0,i.jsxs)("p",{role:"alert",className:"mt-2 text-xs text-amber-700",children:["Couldn't update ",e,". Showing the last loaded results."]}),M&&(z||L)&&(0,i.jsx)("button",{type:"button",onClick:()=>{L||b?R():v()},disabled:T||p,className:"mt-3 w-full rounded-lg border border-gray-200 px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50",children:T?"Loadingâ¦":L?"Try again":(0,i.jsxs)(i.Fragment,{children:["Load more",!b&&(0,i.jsx)("span",{className:"ml-1.5 rounded bg-amber-50 px-1 text-[10px] text-amber-800",children:"PRO"})]})})]})}function tG({data:t,error:e,isLoading:a}){let n=t?.alerts||[];return e?(0,i.jsx)("p",{className:"text-sm text-gray-500",children:"Alerts are temporarily unavailable."}):a?(0,i.jsx)("p",{className:"text-sm text-gray-500",children:"Loading alertsâ¦"}):n.length?(0,i.jsxs)("section",{"aria-label":"Alerts",children:[(0,i.jsx)("h3",{className:"text-xs font-semibold uppercase tracking-wide text-gray-500",children:"Alerts"}),(0,i.jsx)("ul",{className:"mt-2 space-y-2",children:n.map((t,e)=>(0,i.jsxs)("li",{className:"flex gap-2 rounded-lg bg-amber-50 px-3 py-2 text-sm text-amber-900",children:[(0,i.jsx)(tk.A,{className:"mt-0.5 h-4 w-4 shrink-0 text-amber-500","aria-hidden":"true"}),(0,i.jsx)("span",{children:t.header_text||t.description_text})]},`${t.network}:${t.id||e}`))})]}):(0,i.jsx)("p",{className:"text-sm text-gray-500",children:"No active alerts."})}function tO({station:t,network:e,onClose:a,onStopResolved:n,trainForCall:s,onSelectTrain:r}){var l;let{place:c,error:d}=function(t){let e=function(t){if(!t)return null;if(t.stationId)return`/api/v5/stations/${encodeURIComponent(t.stationId)}/`;let e=t.id?.startsWith("group:")?t.id.slice(6):null;return`/api/v5/stations/resolve/${encodeURIComponent(e?"group":t.network)}/${encodeURIComponent(e||t.stopId)}/`}(t),{data:a,error:i,isLoading:n}=(0,_.Ay)(e?`${S.QU}${e}`:null,tC);return{place:a?.station,error:i,isLoading:n}}(t),[h,m]=(0,g.useState)("departures"),[u,p]=(0,g.useState)([]),b=(l
1=c?.id,(0,_.Ay)(l?`${S.QU}/api/v5/stations/${encodeURIComponent(l)}/alerts/`:null,tC,{refreshInterval:3e4})),f=["departures","arrivals","alerts","info"],w=o(t);if((0,g.useEffect)(()=>{c&&n?.({selectionKey:w,place:c})},[c,w,n]),!t)return null;let x=P(c?.name||t.stopName),v=c?.city_slugs?.join(",")||t.citySlugs,j=c?.networks?.map(t=>t.id)||(t.network?[t.network]:[]),k=c?.sources||[];return(0,i.jsxs)("div",{className:"flex min-h-0 flex-1 flex-col",children:[(0,i.jsxs)("div",{className:"grid shrink-0 grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-3 px-5 py-4",children:[(0,i.jsx)("div",{"aria-hidden":"true",className:"mt-1.5 h-3 w-3 shrink-0 rounded-full ring-2 ring-white",style:{backgroundColor:e?.color||t.networkColor||"#64748b"}}),(0,i.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,i.jsx)("h2",{className:"break-words text-lg font-bold leading-tight text-gray-900",children:x||"Station"}),(0,i.jsx)("div",{className:"mt-0.5 text-xs text-gray-500",children:c?.networks?.length?(0,i.jsx)("nav",{"aria-label":"Network station pages",className:"flex items-center gap-x-1.5 overflow-x-auto whitespace-nowrap",children:c.networks.map((t,e)=>{let a=k.find(e=>e.network===t.id),n=tR.Y.getNetwork(t.id)?.shortForms[0]||t.name;return(0,i.jsxs)("span",{className:"shrink-0",title:t.name,children:[e>0&&(0,i.jsx)("span",{"aria-hidden":"true",className:"mr-1.5 text-gray-400",children:"\xb7"}),a?(0,i.jsx)("a",{href:`/networks/${encodeURIComponent(t.id)}/stations/${encodeURIComponent(a.stop_id)}/`,"aria-label":t.name,className:"underline-offset-2 hover:text-blue-800 hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800",children:n}):n]},t.id)})}):e?.name||t.networkName})]}),(0,i.jsx)("button",{type:"button",onClick:a,"aria-label":"Close station details",className:"-mr-2 -mt-1 shrink-0 rounded-full p-2 text-gray-400 hover:bg-gray-100 hover:text-gray-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800",children:(0,i.jsx)(y.A,{className:"h-5 w-5","aria-hidden":"true"})}),(0,i.jsx)(tF,{stopName:x,citySlugs:v,networkIds:j})]}),(0,i.jsx)("div",{role:"tablist","aria-label":"Station views",className:"flex shrink-0 border-b border-gray-100 px-3",children:f.map((t,e)=>(0,i.jsxs)("button",{type:"button",role:"tab",id:`station-tab-${t}`,"aria-controls":`station-panel-${t}`,"aria-selected":h===t,tabIndex:h===t?0:-1,onClick:()=>m(t),onKeyDown:t=>{let a="ArrowRight"===t.key?(e+1)%f.length:"ArrowLeft"===t.key?(e+f.length-1)%f.length:"Home"===t.key?0:"End"===t.key?f.length-1:null;null!==a&&(t.preventDefault(),m(f[a]),t.currentTarget.parentElement.querySelectorAll('[role="tab"]')[a].focus())},className:`flex-1 border-b-2 px-1 py-3 text-sm font-semibold focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-800 ${h===t?"border-blue-800 text-blue-800":"border-transparent text-gray-500 hover:text-gray-900"}`,children:[t[0].toUpperCase()+t.slice(1),"alerts"===t&&b.data?.alerts?.length>0&&(0,i.jsxs)(i.Fragment,{children:[" ",(0,i.jsx)("span",{className:"ml-1 rounded-full bg-amber-100 px-1.5 py-0.5 text-xs text-amber-900",children:b.data.alerts.length})]})]},t))}),(0,i.jsx)("div",{role:"tabpanel",id:`station-panel-${h}`,"aria-labelledby":`station-tab-${h}`,tabIndex:0,className:"min-h-0 flex-1 space-y-3 overflow-y-auto overscroll-contain px-5 pb-[calc(1.25rem+env(safe-area-inset-bottom))] pt-3",children:d?(0,i.jsx)("p",{role:"status",className:"text-sm text-gray-500",children:"Could not load station details. Please try again."}):c?"departures"===h||"arrivals"===h?(0,i.jsx)(tD,{stationId:c.id,kind:h,networks:c.networks||[],excludedNetworks:u,onNetworkChange:p,trainForCall:s,onSelectTrain:r},`${c.id}-${h}`):"alerts"===h?(0,i.jsx)(tG,{...b}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)("dl",{className:"space-y-3 text-sm",children:[(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"font-semibold text-gray-900",children:"Station"}),(0,i.jsx)("dd",{className:"text-gray-600",children:c.name})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"font-semibold text-gray-900",children:"Networks"}),(0,i.jsx)("dd",{className:"text-gray-600",children:c.networks?.map(t=>t.name).join(" \xb7 ")})]}),"complex"===c.kind&&(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"font-semibold text-gray-900",children:"Stations in this complex"}),(0,i.jsx)("dd",{className:"text-gray-600",children:c.members?.map(t=>t.name).join(" \xb7 ")})]}),"split"===c.status&&(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"font-semibold text-gray-900",children:"Status"}),(0,i.jsxs)("dd",{children:["This place has been split into ",c.successor_ids.length," stations."]})]})]}),(0,i.jsx)("h3",{className:"text-xs font-semibold uppercase tracking-wide text-gray-500",children:"Platforms"}),(0,i.jsx)("ul",{className:"space-y-2 text-sm text-gray-600",children:k.map(t=>(0,i.jsxs)("li",{children:[t.network," \xb7 ",t.name]},`${t.network}:${t.stop_id}`))})]}):"departures"===h||"arrivals"===h?(0,i.jsx)(tB,{kind:h,header:!0}):(0,i.jsx)("p",{role:"status",className:"text-sm text-gray-500",children:"Loading stationâ¦"})},h)]})}function tK({station:t,network:e,onClose:a,onStopResolved:n,trainForCall:s,onSelectTrain:r}){let l=!!t;return((0,g.useEffect)(()=>
1{if(!l)return;let t=t=>{"Escape"!==t.key||t.defaultPrevented||document.querySelector('[role="dialog"][aria-modal="true"]')||a()};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[l,a]),l)?(0,i.jsx)("aside",{"aria-label":"Station details",className:"pointer-events-none absolute inset-x-0 bottom-0 z-20 max-h-full lg:inset-y-0 lg:left-auto lg:right-0 lg:w-[380px] lg:p-3",children:(0,i.jsxs)("div",{className:"pointer-events-auto flex h-[68dvh] max-h-full flex-col overflow-hidden rounded-t-2xl bg-white shadow-2xl ring-1 ring-black/5 lg:h-full lg:rounded-xl",children:[(0,i.jsx)("div",{className:"flex shrink-0 justify-center pt-2.5 lg:hidden","aria-hidden":"true",children:(0,i.jsx)("span",{className:"h-1 w-9 rounded-full bg-gray-300"})}),(0,i.jsx)(tO,{station:t,network:e,onClose:a,onStopResolved:n,trainForCall:s,onSelectTrain:r},o(t))]})}):null}function tW({map:t,styleVersion:e,train:a,network:i,theme:n}){let{stops:s}=$(a),r=(0,g.useMemo)(()=>({type:"FeatureCollection",features:s.filter(t=>Number.isFinite(t.stop_lon)&&Number.isFinite(t.stop_lat)&&180>=Math.abs(t.stop_lon)&&90>=Math.abs(t.stop_lat)).map(t=>({type:"Feature",geometry:{type:"Point",coordinates:[t.stop_lon,t.stop_lat]},properties:{name:"ttc"===a.agency?U(t.stop_name):P(t.stop_name)}}))}),[s,a.agency]);return(0,g.useEffect)(()=>{if(!t?.getLayer("train-points"))return;t.addSource("selected-train-stops",{type:"geojson",data:{type:"FeatureCollection",features:[]}});let e=t.getSource("selected-train-stops");t.addLayer({id:"selected-train-stop-points",type:"circle",source:"selected-train-stops",paint:{"circle-radius":6,"circle-color":"#ffffff","circle-stroke-color":i?.color||"#1d4ed8","circle-stroke-width":3}},"train-points");let a=t.getStyle()?.glyphs;return a&&t.addLayer({id:"selected-train-stop-labels",type:"symbol",source:"selected-train-stops",layout:{"text-field":["get","name"],"text-font":a.startsWith("mapbox:")?["DIN Pro Medium","Arial Unicode MS Regular"]:["Noto Sans Regular"],"text-size":12,"text-variable-anchor":["top","bottom","left","right"],"text-radial-offset":1,"text-justify":"auto","text-max-width":14,"text-padding":4,"text-allow-overlap":!1,"text-ignore-placement":!1},paint:{"text-color":"dark"===n?"#ffffff":"#111827","text-halo-color":"dark"===n?"#111827":"#ffffff","text-halo-width":2}},"train-points"),()=>{try{if(t.getSource("selected-train-stops")!==e)return;for(let e of["selected-train-stop-labels","selected-train-stop-points"])t.getLayer(e)&&t.removeLayer(e);t.removeSource("selected-train-stops")}catch{}}},[t,e,i?.color,n]),(0,g.useEffect)(()=>{t?.getSource("selected-train-stops")?.setData(r)},[t,e,i?.color,n,r]),null}var tJ=a(37249),tH=a(17481),tV=a(48218),tq=a(67452),tY=a(59079),tZ=a(75105),tQ=a(60142),tX=a(72083),t0=a(30730),t1=a(56871),t2=a(73304);let t4={light:t0.A,dark:t1.A,satellite:t2.A,hybrid:t2.A,terrain:tV.A};function t3({theme:t,onChange:e,loading:a,error:n,signedIn:s,isPremium:r,accessLoading:o,returnUrl:l}){let c=(0,tH.RR)(s,l);return(0,i.jsxs)("fieldset",{children:[(0,i.jsx)("legend",{className:"mb-2 text-xs font-semibold uppercase tracking-wide text-gray-500",children:"Map style"}),(0,i.jsx)("div",{className:"grid grid-cols-2 gap-2",children:tH.u8.map(({id:n,label:s,description:l,premium:g})=>{let d=t4[n],h=!(0,tH.Vn)(n,r),m=a||g&&o,u=h&&!m?x():"button",p=h&&!m?{href:c.href,title:`${c.label} to use ${s}`}:{type:"button",disabled:m,"aria-pressed":t===n,onClick:()=>e(n)};return(0,i.jsxs)(u,{"aria-label":s,...p,className:`relative flex min-h-24 flex-col items-center justify-center gap-1 rounded-xl border-2 px-2 py-3 text-sm font-semibold focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 disabled:opacity-50 ${t===n?"border-blue-600 bg-blue-50 text-blue-800":"border-gray-100 hover:border-gray-300"}`,children:[g&&(0,i.jsxs)("span",{className:"absolute right-1 top-1 flex items-center gap-0.5 rounded bg-amber-50 px-1 text-[9px] text-amber-800",children:[h&&(0,i.jsx)(tj.A,{className:"h-3 w-3"}),"PRO"]}),(0,i.jsx)(d,{className:"h-6 w-6","aria-hidden":"true"}),s,(0,i.jsx)("span",{className:"text-[10px] font-normal text-gray-500",children:l})]},n)})}),(a||n)&&(0,i.jsx)("p",{role:"status",className:"mt-2 text-xs text-gray-500",children:a?"Loading map styleâ¦":n}),o&&(0,i.jsx)("p",{role:"status",className:"mt-3 text-xs text-gray-500",children:"Checking map accessâ¦"})]})}var t6=a(42644),t8=a(95389);let t5=[{id:"national",label:"National & intercity rail"},{id:"regional",label:"Regional & commuter rail"},{id:"metro",label:"Subways & metros"},{id:"streetcar",label:"Streetcars & trams"},{id:"light",label:"Light rail"},{id:"freight",label:"Freight trains"},{id:"other",label:"Other rail"}];function t7(t,e){let a=(e?.vehicleClassificationOverride||"").replace(/-/g,"_"),i=String(t.vt??"");if("freight"===i||["freight","freight_rail"].includes(a))return"freight";let n=t8.L[i]?.classification;return"sc"===i?"streetcar":"lr"===i?"light":n?.startsWith("subway")?"metro":"streetcar"===n||"tram"===n?"light_rail"
1===a?"light":"streetcar":"high_speed_rail"===n||"intercity_rail"===n?"national":"commuter_rail"===n?"regional":["intercity","intercity_rail","high_speed_rail"].includes(a)?"national":["regional_rail","commuter_rail"].includes(a)?"regional":["subway","subway_default","metro","light_metro","rapid_transit"].includes(a)?"metro":["streetcar","tram"].includes(a)?"streetcar":"light_rail"===a?"light":"other"}let t9="flex h-12 w-12 items-center justify-center rounded-xl bg-white text-gray-700 shadow-md ring-1 ring-black/10 hover:bg-gray-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600 disabled:opacity-50";function et({map:t,renderer:e,theme:a,onThemeChange:n,themeLoading:s,themeError:r,enabled:o,setEnabled:l,counts:c,showMajorStations:d,setShowMajorStations:h,showMinorStations:m,setShowMinorStations:u,railway:b,setRailway:f,trainRoutes:w,setTrainRoutes:_,trainRoutesError:v,slowdowns:j,setSlowdowns:k,panelOpen:S,signedIn:C,isPremium:N,accessLoading:I,returnUrl:M}){let A=(0,tH.RR)(C,M),[L,T]=(0,g.useState)(null),[z,R]=(0,g.useState)(""),[P,U]=(0,g.useState)(!1),[E,$]=(0,g.useState)(!1),F=(0,g.useRef)(null),B=(0,g.useRef)(null),D=(0,g.useRef)(null);(0,g.useEffect)(()=>{if(!t)return;let e=()=>$(t.getPitch()>0);return e(),t.on("pitchend",e),()=>t.off("pitchend",e)},[t]),(0,g.useEffect)(()=>{if(!t)return;class a extends e.GeolocateControl{onAdd(t){let e=super.onAdd(t);return e.style.display="none",e}}let i=new a({positionOptions:{enableHighAccuracy:!0,timeout:1e4},fitBoundsOptions:{maxZoom:12,duration:700},showUserLocation:!0,showAccuracyCircle:!0});return i.on("geolocate",()=>U(!1)),i.on("error",()=>{U(!1),R("Location unavailable. Check your browserâs location permission.")}),t.addControl(i),D.current=i,()=>{D.current=null,t.hasControl(i)&&t.removeControl(i)}},[t,e]),(0,g.useEffect)(()=>{if(!L)return;let t=t=>{F.current?.contains(t.target)||T(null)},e=t=>{"Escape"===t.key&&(t.stopPropagation(),T(null),B.current?.focus())};return document.addEventListener("pointerdown",t),document.addEventListener("keydown",e,!0),()=>{document.removeEventListener("pointerdown",t),document.removeEventListener("keydown",e,!0)}},[L]);let G=(t,e)=>{B.current=e.currentTarget,T(e=>e===t?null:t)},O=async()=>{try{document.fullscreenElement?await document.exitFullscreen():t?.getContainer().parentElement.requestFullscreen?await t.getContainer().parentElement.requestFullscreen():R("Full screen is unavailable in this browser.")}catch{R("Full screen is unavailable in this browser.")}};return(0,i.jsxs)("div",{ref:F,style:{"--map-tools-height":S?"calc(32dvh - 148px)":"calc(100dvh - 148px)"},className:"absolute left-3 top-[4.5rem] z-30 flex items-start gap-3 lg:top-14",children:[(0,i.jsxs)("div",{role:"toolbar","aria-label":"Map controls",className:"-m-1 flex max-h-[max(48px,var(--map-tools-height))] shrink-0 flex-col gap-2 overflow-y-auto p-1 [scrollbar-width:none] lg:max-h-[calc(100dvh-132px)] [&>button]:shrink-0 [&>div]:shrink-0",children:[(0,i.jsx)("button",{type:"button",title:"Map appearance","aria-label":"Map appearance","aria-expanded":"appearance"===L,"aria-controls":"world-map-options",onClick:t=>G("appearance",t),className:`${t9} ${"appearance"===L?"ring-2 ring-blue-600 text-blue-800":""}`,children:(0,i.jsx)(tV.A,{className:"h-6 w-6"})}),(0,i.jsxs)("button",{type:"button",title:"Train filters","aria-label":"Train filters","aria-expanded":"filters"===L,"aria-controls":"world-map-options",onClick:t=>G("filters",t),className:`${t9} relative ${"filters"===L?"ring-2 ring-blue-600 text-blue-800":""}`,children:[(0,i.jsx)(tq.A,{className:"h-6 w-6"}),(o.length<t5.length||!d||!m)&&(0,i.jsx)("span",{className:"absolute right-1 top-1 h-2 w-2 rounded-full bg-blue-700"})]}),(0,i.jsx)("button",{type:"button","aria-label":"Find my location",title:"Find my location",disabled:P,onClick:()=>{navigator.geolocation?(U(!0),R(""),D.current?.trigger()||(U(!1),R("The map is still loading. Try again in a moment."))):R("Location is unavailable in this browser.")},className:t9,children:(0,i.jsx)(tY.A,{className:`h-6 w-6 ${P?"animate-pulse":""}`})}),(0,i.jsx)("button",{type:"button","aria-label":"Report a problem or leave feedback",title:"Report a problem or leave feedback","aria-expanded":"feedback"===L,"aria-controls":"world-map-options",onClick:t=>G("feedback",t),className:`${t9} ${"feedback"===L?"ring-2 ring-blue-600 text-blue-800":""}`,children:(0,i.jsx)(tZ.A,{className:"h-6 w-6"})})]}),L&&(0,i.jsxs)("section",{id:"world-map-options","aria-label":"appearance"===L?"Map appearance options":"feedback"===L?"Feedback options":"Train filter options",className:"max-h-[calc(100dvh-140px)] w-72 max-w-[calc(100vw-88px)] overflow-y-auto overscroll-contain rounded-2xl bg-white p-4 text-gray-900 shadow-xl ring-1 ring-black/10",children:[(0,i.jsxs)("div",{className:"mb-4 flex items-center justify-between gap-3",children:[(0,i.jsx)("h2",{className:"text-base font-bold",children:"appearance"===L?"Map appearance":"feedback"===L?"Report or give feedback":"Train filters"}),(0,i.jsx)("button",{type:"button","aria-label":"Close map options",onClick:()=>{T(null),B.current?.focus()},className:"rounded-lg p-2 hover:bg-gray-100",children:(0,i.jsx)(y.A,{className:"h-5 w-5"})})]}),"appearance"===L?(0,i.jsxs)("div",{className:"space-y-4",children:[(0,i.jsxs)("details",{className:"group rounded-xl border border-gray-200",children:[(0,i.jsxs)("summary",{className:"flex min-h-12 cursor-pointer list-none items-center justify-between px-3 text-sm font-semibold [&::-webkit-details-marker]:hidden",children:["Map controls",(0,i.jsx)(K.A,{className:"h-4 w-4 transition-transform group-open:rotate-90"})]}),(0,i.jsxs)("div",{className:"space-y-2 border-t border-gray-100 p-3",children:[(0,i.jsxs)("div",{className:"grid grid-cols-2 gap-2",children:[(0,i.jsxs)("button",{type:"button","aria-label":"Zoom in",onClick:()=>t?.zoomIn(),className:"flex min-h-12 items-center justify-center gap-1 rounded-lg bg-gray-100 text-sm font-medium hover:bg-gray-200",children:[(0,i.jsx)(tQ.A,{className:"h-5 w-5"}),"Zoom in"]}),(0,i.jsxs)("button",{type:"button","aria-label":"Zoom out",onClick:()=>t?.zoomOut(),className:"flex min-h-12 items-center justify-center gap-1 rounded-lg bg-gray-100 text-sm font-medium hover:bg-gray-200",children:[(0,i.jsx)(p.A,{className:"h-5 w-5"}),"Zoom out"]})]}),(0,i.jsxs)("button",{type:"button","aria-label":"Toggle fullscreen",onClick:O,className:"flex min-h-12 w-full items-center justify-center gap-2 rounded-lg bg-gray-100 text-sm font-medium hover:bg-gray-200",children:[(0,i.jsx)(tX.A,{className:"h-5 w-5"}),"Toggle fullscreen"]}),(0,i.jsxs)("button",{type:"button","aria-label":"Reset bearing to north",onClick:()=>t?.easeTo({bearing:0,duration:400}),className:"flex min-h-12 w-full items-center justify-center gap-2 rounded-lg bg-gray-100 text-sm font-medium hover:bg-gray-200",children:[(0,i.jsx)("span",{"aria-hidden":"true",className:"font-bold",children:"N â"}),"Reset north"]})]})]}),(0,i.jsx)(t3,{theme:a,onChange:n,loading:s,error:r,signedIn:C,isPremium:N,accessLoading:I,returnUrl:M}),(0,i.jsx)(t6.A,{}),(0,i.jsxs)("fieldset",{children:[(0,i.jsx)("legend",{className:"mb-2 text-xs font-semibold uppercase tracking-wide text-gray-500",children:"Perspective"}),(0,i.jsx)("div",{className:"flex gap-2",children:[!1,!0].map(e=>(0,i.jsx)("button",{type:"button","aria-pressed":E===e,onClick:()=>{$(e),t?.easeTo({pitch:55*!!e,duration:500})},className:`min-h-11 flex-1 rounded-lg text-sm font-semibold ${E===e?"bg-blue-800 text-white":"bg-gray-100"}`,children:e?"3D":"2D"},String(e)))})]}),(0,i.jsxs)("div",{children:[N||I?(0,i.jsxs)("label",{className:"flex min-h-12 cursor-pointer items-center justify-between gap-3 text-sm font-medium",children:[(0,i.jsxs)("span",{children:["Slowdowns ",(0,i.jsx)("span",{className:"ml-1 rounded bg-amber-50 px-1 text-[9px] text-amber-800",children:"PRO"})]}),(0,i.jsx)("input",{type:"checkbox",checked:!!(N&&j),disabled:I,onChange:t=>k(t.target.checked),className:"h-5 w-5 rounded border-gray-300 text-blue-700"})]}):(0,i.jsxs)(x(),{href:A.href,"aria-label":"Slowdowns",className:"flex min-h-12 items-center justify-between gap-3 text-sm font-medium",children:[(0,i.jsxs)("span",{children:["Slowdowns ",(0,i.jsx)("span",{className:"ml-1 rounded bg-amber-50 px-1 text-[9px] text-amber-800",children:"PRO"})]}),(0,i.jsx)(tj.A,{className:"h-4 w-4 text-gray-400","aria-hidden":"true"})]}),(0,i.jsx)("p",{className:"text-xs text-gray-500",children:"Unusual travel times \xb7 GO, VIA and Caltrain pilot."})]}),(0,i.jsxs)("label",{className:"flex min-h-12 cursor-pointer items-center justify-between gap-3 border-t border-gray-100 pt-3 text-sm font-medium",children:["Railway tracks",(0,i.jsx)("input",{type:"checkbox",checked:b,onChange:t=>f(t.target.checked),className:"h-5 w-5 rounded border-gray-300 text-blue-700"})]}),(0,i.jsxs)("div",{children:[N||I?(0,i.jsxs)("label",{className:"flex min-h-12 cursor-pointer items-center justify-between gap-3 text-sm font-medium",children:[(0,i.jsxs)("span",{children:["Train routes ",(0,i.jsx)("span",{className:"ml-1 rounded bg-amber-50 px-1 text-[9px] text-amber-800",children:"PRO"})]}),(0,i.jsx)("input",{type:"checkbox",checked:N&&w,disabled:I,onChange:t=>_(t.target.checked),className:"h-5 w-5 rounded border-gray-300 text-blue-700 disabled:opacity-50"})]}):(0,i.jsxs)(x(),{href:A.href,"aria-label":"Train routes",title:`${A.label} to show train routes`,className:"flex min-h-12 items-center justify-between gap-3 rounded text-sm font-medium hover:text-blue-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600",children:[(0,i.jsxs)("span",{children:["Train routes ",(0,i.jsx)("span",{className:"ml-1 rounded bg-amber-50 px-1 text-[9px] text-amber-800",children:"PRO"})]}),(0,i.jsx)(tj.A,{className:"h-4 w-4 text-gray-400","aria-hidden":"true"})]}),(0,i.jsx)("p",{className:"text-xs text-gray-500",children:"Routes coloured by network."}),w&&v&&(0,i.jsx)("p",{role:"status",className:"mt-2 text-xs text-gray-500",children:v})]})]}):"feedback"===L?(0,i.jsx)(tJ.A,{}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)("div",{className:"mb-3 flex gap-3 text-xs font-semibold text-blue-800",children:[(0,i.jsx)("button",{type:"button",onClick:()=>l(t5.map(({id:t})=>t)),children:"Show all"}),(0,i.jsx)("button",{type:"button",onClick:()=>l([]),children:"Hide all"})]}),(0,i.jsx)("div",{className:"divide-y divide-gray-100",children:t5.map(({id:t,label:e})=>(0,i.jsxs)("label",{className:"flex min-h-14 cursor-pointer items-center gap-3 py-2 text-sm",children:[(0,i.jsx)("input",{type:"checkbox",checked:o.includes(t),onChange:e=>l(a=>e.target.checked?[...a,t]:a.filter(e=>e!==t)),className:"h-5 w-5 shrink-0 rounded border-gray-300 text-blue-700"}),(0,i.jsx)("span",{className:"flex-1",children:e}),(0,i.jsx)("span",{className:"text-xs tabular-nums text-gray-400",children:(c[t]||0).toLocaleStr
1ing()})]},t))}),(0,i.jsx)("p",{className:"mt-3 text-xs leading-relaxed text-gray-500",children:"Based on train type and network classification."}),(0,i.jsx)("div",{className:"mt-4 border-t border-gray-100 pt-3",children:[["Major Stations",d,h],["Minor Stations",m,u]].map(([t,e,a])=>(0,i.jsxs)("label",{className:"flex min-h-12 cursor-pointer items-center justify-between gap-3 text-sm font-medium",children:[t,(0,i.jsx)("input",{type:"checkbox",checked:e,onChange:t=>a(t.target.checked),className:"h-5 w-5 rounded border-gray-300 text-blue-700"})]},t))})]})]}),z&&(0,i.jsxs)("div",{role:"status",className:"absolute left-0 top-full mt-2 w-64 rounded-xl bg-white p-3 text-xs text-gray-700 shadow-md",children:[z,(0,i.jsx)("button",{type:"button",onClick:()=>R(""),"aria-label":"Dismiss map message",className:"ml-2 inline-flex",children:(0,i.jsx)(K.A,{className:"h-4 w-4"})})]})]})}let ee=()=>({type:"FeatureCollection",features:[]});function ea(t,e=Date.now()){return!t||Date.parse(t.expires_at)<=e||!Number.isFinite(Date.parse(t.expires_at))?ee():{type:"FeatureCollection",features:(t.features||[]).filter(t=>t.geometry?.type==="LineString"&&t.geometry.coordinates?.length>=2&&Number.isFinite(t.properties?.severity)&&Date.parse(t.properties.expires_at)>e)}}let ei=["interpolate",["linear"],["get","severity"],.25,"#eab308",.5,"#f97316",1,"#dc2626"];function en({map:t,renderer:e,enabled:a,styleVersion:n,panelOpen:s}){let[r,o]=(0,g.useState)("history"),[l,c]=(0,g.useState)([]),[d,h]=(0,g.useState)("Loading slowdown observationsâ¦");return((0,g.useEffect)(()=>{if(!a||!t)return;h("Loading slowdown observationsâ¦");let i="history"===r?["case",["==",["get","assessed_journeys"],0],"#94a3b8",["interpolate",["linear"],["get","severity"],0,"#60a5fa",.25,"#eab308",.5,"#f97316",1,"#dc2626"]]:ei,n=!1,s=null,o,l,g,d="",m=t.getLayer("train-halo")?"train-halo":void 0;t.addSource("slowdowns",{type:"geojson",data:ee()}),t.addLayer({id:"slowdown-glow",type:"line",source:"slowdowns",layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":i,"line-width":18,"line-blur":9,"line-opacity":.5}},m),t.addLayer({id:"slowdown-line",type:"line",source:"slowdowns",layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":i,"line-width":["interpolate",["linear"],["zoom"],2,2,10,5],"line-opacity":.9}},m);let u=()=>{if(n)return;let e=ea(s),a=JSON.stringify(e);a!==d&&(t.getSource("slowdowns")?.setData(e),d=a,g?.remove()),h(function(t,e=Date.now()){if(!t||!(Date.parse(t.expires_at)>e))return"Slowdown observations are unavailable.";let a=t.coverage||[];if("history"===t.mode){let i=ea(t,e).features;if(i.length){let t=i.filter(t=>t.properties.assessed_journeys>0).length;return`${i.length} measured section${1===i.length?"":"s"} in view; ${t} with slowdown comparisons. Historical coverage is limited.`}return a.some(t=>t.measured_sections>0)?"No measured sections in this view. History is available elsewhere in the pilot networks.":"No completed journeys available yet. Collection may be warming up or missing source data."}if(!a.filter(t=>"ready"===t.status).length)return a.some(t=>"collecting_baseline"===t.status)?"Collecting enough observations to identify unusual slowdowns.":"No recent observations in the pilot networks.";let i=ea(t,e).features.length;return i?`${i} confirmed slow section${1===i?"":"s"} in view.`:"No confirmed slowdowns in view. Coverage is limited."}(s)),c(s?.coverage||[])},p=async()=>{o?.abort();let e=(o=new AbortController).signal;try{var a;let i,o,l,c=await fetch(`${S.QU}/api/v5/slowdowns/?mode=${r}&bbox=${encodeURIComponent((i=(a=t.getBounds()).getWest(),o=a.getEast(),l=t=>((t+180)%360+360)%360-180,[o-i>=360?-180:l(i),Math.max(-90,a.getSouth()),o-i>=360?180:l(o),Math.min(90,a.getNorth())].join(",")))}`,{signal:e});if(!c.ok)throw Error("Slowdowns unavailable");let g=await c.json();if(n||e.aborted)return;s=g,u()}catch{if(n||e.aborted)return;s=null,u()}},y=()=>{clearTimeout(l),l=setTimeout(p,200)},b=a=>{let i=a.features?.[0]?.properties;if(!i||Date.parse(i.expires_at)<=Date.now())return;let n=document.createElement("div");n.className="text-sm text-gray-900";let s=document.createElement("strong");s.textContent=`${i.network.toUpperCase()} \xb7 ${Math.round(100*i.severity)}% longer than usual`;let r=document.createElement("p");r.textContent=`${Math.round(i.observed_seconds/60)} min observed; ${Math.round(i.expected_seconds/60)} min typical. Based on ${i.supporting_trains} recent trains and ${i.baseline_samples} baseline journeys.`;let o=document.createElement("p");o.textContent=`Observed ${new Date(i.observed_at).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}. Applies to this track section.`,"history"===i.kind&&(s.textContent=`${i.network.toUpperCase()} \xb7 Past 7 days`,r.textContent=i.assessed_journeys>0?`${i.slow_journeys} of ${i.assessed_journeys} comparable journeys were unusually slow (${Math.round(100*i.slow_fraction)}%). ${i.journeys} journeys measured in total.`:`${i.journeys} journeys measured. More comparable journeys are needed to assess slowdowns.`,o.textContent=`Median travel time: ${Math.round(i.median_seconds/60)}
1 min. Last measured ${new Date(i.observed_at).toLocaleString()}. Historical pattern, not a live incident.`),n.append(s,r,o),g?.remove(),g=new e.Popup({closeButton:!0}).setLngLat(a.lngLat).setDOMContent(n).addTo(t)};t.on("moveend",y),t.on("click","slowdown-line",b),p();let f=setInterval(p,3e4),w=setInterval(u,1e3);return()=>{if(n=!0,o?.abort(),clearTimeout(l),clearInterval(f),clearInterval(w),g?.remove(),t.off("moveend",y),t.off("click","slowdown-line",b),t.getStyle()){for(let e of["slowdown-line","slowdown-glow"])t.getLayer(e)&&t.removeLayer(e);t.getSource("slowdowns")&&t.removeSource("slowdowns")}}},[t,e,a,n,r]),a)?(0,i.jsxs)("aside",{"aria-label":"Slowdown legend",className:`absolute left-3 z-20 w-60 rounded-xl bg-white/95 p-3 text-xs text-gray-700 shadow-lg ${s?"bottom-[calc(68dvh+12px)] lg:bottom-20":"bottom-20"}`,children:[(0,i.jsx)("p",{className:"font-semibold text-gray-900",children:"Slowdown history \xb7 Pilot"}),(0,i.jsxs)("div",{className:"mt-2 flex gap-3",role:"group","aria-label":"Slowdown period",children:[(0,i.jsx)("button",{type:"button","aria-pressed":"history"===r,onClick:()=>o("history"),className:"history"===r?"font-bold underline":"",children:"Past 7 days"}),(0,i.jsx)("button",{type:"button","aria-pressed":"live"===r,onClick:()=>o("live"),className:"live"===r?"font-bold underline":"",children:"Live"})]}),(0,i.jsx)("div",{className:`my-2 h-2 rounded bg-gradient-to-r ${"history"===r?"from-blue-400":"from-yellow-500"} via-orange-500 to-red-600`}),(0,i.jsxs)("div",{className:"flex justify-between",children:[(0,i.jsx)("span",{children:"history"===r?"Fewer slow journeys":"25% longer"}),(0,i.jsx)("span",{children:"history"===r?"More":"100%+ longer"})]}),(0,i.jsx)("p",{role:"status",className:"mt-2",children:d}),(0,i.jsx)("p",{className:"mt-1 text-gray-500",children:l.map(t=>`${t.network.toUpperCase()}: ${"ready"===t.status?"comparisons available":"collecting_baseline"===t.status?"building baseline":"unavailable"===t.status?"unavailable":"no qualifying measurements"}`).join(" \xb7 ")}),(0,i.jsxs)("p",{className:"mt-1 text-gray-500",children:["GO, VIA and Caltrain \xb7 ","history"===r?"Past 7 days. Blue: no measured slowdowns. Gray: building baseline.":"Last 30 minutes."," Unshaded track may lack data."]})]}):null}function es(){let{user:t,loading:e}=(0,tP.A)(),[a,n]=(0,g.useState)(null);(0,g.useEffect)(()=>{let t="MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;n(/android/i.test(navigator.userAgent)?"android":/iPad|iPhone|iPod/i.test(navigator.userAgent)||t?"ios":"unknown")},[]);let s=!e&&!t&&a;return s?(0,i.jsx)("div",{role:"group","aria-label":"Apps and community",className:"pointer-events-none absolute inset-x-0 z-10 flex justify-center gap-2 px-3",style:{bottom:"calc(2rem + env(safe-area-inset-bottom, 0px))"},children:s&&[{platform:"ios",href:"/ios/",Icon:Y.eMv,caption:"Download on the",label:"App Store"},{platform:"android",href:"/android/",Icon:Y.N8X,caption:"Get it on",label:"Google Play"}].filter(t=>"unknown"===a||a===t.platform).map(({platform:t,href:e,Icon:a,caption:n,label:s})=>(0,i.jsxs)("a",{href:e,target:"_blank",rel:"noopener noreferrer","aria-label":`Download for ${"ios"===t?"iOS":"Android"}`,className:"pointer-events-auto flex min-h-11 items-center gap-1.5 rounded-2xl bg-gray-950/95 px-2 py-2.5 text-white shadow-lg ring-1 ring-white/20 backdrop-blur transition-colors hover:bg-gray-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-blue-500 lg:gap-2 lg:px-4",children:[(0,i.jsx)(a,{"aria-hidden":"true",className:"h-5 w-5 shrink-0 lg:h-6 lg:w-6"}),(0,i.jsxs)("span",{className:"whitespace-nowrap text-left",children:[(0,i.jsx)("span",{className:"hidden text-[10px] leading-tight text-gray-200 lg:block",children:n}),(0,i.jsx)("span",{className:"block text-xs font-semibold leading-tight lg:text-sm",children:s})]})]},t))}):null}var er=a(52850),eo=a(32020),el=a(67224),ec=a(64358);let eg=[{title:"Join the freight tracking network",description:"Live near a railroad? Host a tracker and help put more freight trains on the map.",Icon:er.A,background:"from-amber-700 via-orange-800 to-stone-900",links:[{label:"Host a tracker",href:"https://docs.google.com/forms/d/e/1FAIpQLSeAuP7Xec4ZIshbOE2ZIKuY8NdANA6j6RvlUimy-r7gtmPzoA/viewform?usp=publish-editor"}]},{title:"Follow along with trains.fyi",description:"Train spotting, new features, and updates from the network.",Icon:Y.ao$,background:"from-pink-700 via-fuchsia-800 to-indigo-950",links:[{label:"Twitter",href:"https://twitter.com/trainsfyi",Icon:Y.feZ},{label:"Instagram",href:"https://www.instagram.com/trains.fyi/",Icon:Y.ao$},{label:"TikTok",href:"https://www.tiktok.com/@trains.fyi",Icon:Y.kkU}]},{title:"Help shape trains.fyi",description:"Have an idea or spotted a problem? Weâd love to hear your feedback.",Icon:tZ.A,background:"from-emerald-700 via-teal-800 to-cyan-950",links:[{label:"Send us feedback",href:"/feedback/"}]},{title:"Your people. Your trains.",description:"Swap sightings, talk trains, and meet the trains.fyi community on Discord.",Icon:Y.O4U,background:"from-[#5865F2] via-indigo-700 to-purple-950",links:[{label:"Join the Discord",href:"https://discord.gg/TmHN7bamKX"}]}];function ed({onDismiss:t}){let e=(0,g.useRef)(null),a=(0,g.useRef)(null),[n,s]=(0,g.useState)(0),[r,o]=(0,g.useState)(!1),[l,c]=(0,g.useState)(!0);function d(t){e.current?.scrollTo({left:t*e.current.clientWidth,behavior:l?"instant":"smooth"})}(0,g.useEffect)(()=>{let t=window.matchMedia("(prefers-reduced-motion: reduce)"),e=()=>c(t.matches);return e(),t.addEventListener("change",e),()=>t.removeEventListener("change",e)},[]),(0,g.useEffect)(()=>
1{if(r||l)return;let t=window.setInterval(()=>{if(document.hidden||a.current?.matches(":hover")||a.current?.contains(document.activeElement))return;let t=e.current;t?.scrollTo({left:(n+1)%eg.length*t.clientWidth,behavior:"smooth"})},7e3);return()=>window.clearInterval(t)},[n,r,l]);let h="focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white";return(0,i.jsxs)("aside",{ref:a,"aria-label":"Attention card","aria-roledescription":"carousel",className:`absolute bottom-[calc(5.75rem+env(safe-area-inset-bottom,0px))] right-3 z-10 flex h-48 w-96 max-w-[calc(100%-1.5rem)] flex-col overflow-hidden rounded-2xl bg-gradient-to-br text-white shadow-xl ring-1 ring-white/20 lg:bottom-[calc(2rem+env(safe-area-inset-bottom,0px))] ${eg[n].background}`,children:[(0,i.jsx)("button",{type:"button","aria-label":"Dismiss attention card",onClick:t,className:`absolute right-1 top-1 z-10 flex h-11 w-11 items-center justify-center rounded-full bg-black/10 hover:bg-black/20 ${h}`,children:(0,i.jsx)(y.A,{"aria-hidden":"true",className:"h-5 w-5"})}),(0,i.jsx)("div",{ref:e,className:"flex min-h-0 flex-1 snap-x snap-mandatory overflow-x-auto overscroll-x-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",onScroll:t=>s(Math.max(0,Math.min(eg.length-1,Math.round(t.currentTarget.scrollLeft/t.currentTarget.clientWidth)))),children:eg.map(({title:t,description:e,Icon:a,links:s},r)=>(0,i.jsxs)("div",{role:"group","aria-roledescription":"slide","aria-label":`${r+1} of ${eg.length}: ${t}`,"aria-hidden":r!==n,inert:r!==n?"":void 0,className:"relative flex w-full shrink-0 snap-start flex-col px-4 pt-3",children:[(0,i.jsx)(a,{"aria-hidden":"true",className:"pointer-events-none absolute -right-3 top-6 h-24 w-24 -rotate-12 text-white/10"}),(0,i.jsxs)("div",{className:"relative flex items-center gap-2 pr-8",children:[(0,i.jsx)(a,{"aria-hidden":"true",className:"h-5 w-5 shrink-0"}),(0,i.jsx)("h2",{className:"text-sm font-bold leading-tight tracking-tight",children:t})]}),(0,i.jsx)("p",{className:"relative mt-1.5 text-xs leading-snug text-white/90",children:e}),(0,i.jsx)("div",{className:"relative mt-auto flex items-center gap-2 pt-1",children:s.map(({label:t,href:e,Icon:a})=>(0,i.jsxs)("a",{href:e,target:e.startsWith("https:")?"_blank":void 0,rel:e.startsWith("https:")?"noopener noreferrer":void 0,className:`inline-flex min-h-11 items-center justify-center gap-1 rounded-lg bg-white px-2.5 text-xs font-bold text-gray-900 shadow-sm hover:bg-white/90 ${h}`,children:[a&&(0,i.jsx)(a,{"aria-hidden":"true",className:"h-3.5 w-3.5"}),t,!a&&(0,i.jsx)(eo.A,{"aria-hidden":"true",className:"h-4 w-4"})]},t))})]},t))}),(0,i.jsxs)("div",{className:"flex h-11 shrink-0 items-center justify-between px-2",children:[(0,i.jsx)("button",{type:"button","aria-label":"Previous card",onClick:()=>d((n-1+eg.length)%eg.length),className:`flex h-11 w-11 items-center justify-center rounded-lg hover:bg-white/10 ${h}`,children:(0,i.jsx)(O.A,{"aria-hidden":"true",className:"h-4 w-4"})}),(0,i.jsx)("div",{className:"flex",role:"group","aria-label":"Choose a card",children:eg.map(({title:t},e)=>(0,i.jsx)("button",{type:"button","aria-label":`Show ${t}`,"aria-current":n===e?"true":void 0,onClick:()=>d(e),className:`flex h-11 w-7 items-center justify-center rounded-lg ${h}`,children:(0,i.jsx)("span",{className:`h-1.5 rounded-full bg-white transition-all motion-reduce:transition-none ${n===e?"w-5":"w-1.5 opacity-40"}`})},t))}),!l&&(0,i.jsx)("button",{type:"button","aria-label":r?"Resume card rotation":"Pause card rotation",onClick:()=>o(t=>!t),className:`flex h-11 w-11 items-center justify-center rounded-lg hover:bg-white/10 ${h}`,children:r?(0,i.jsx)(el.A,{"aria-hidden":"true",className:"h-4 w-4"}):(0,i.jsx)(ec.A,{"aria-hidden":"true",className:"h-4 w-4"})}),(0,i.jsx)("button",{type:"button","aria-label":"Next card",onClick:()=>d((n+1)%eg.length),className:`flex h-11 w-11 items-center justify-center rounded-lg hover:bg-white/10 ${h}`,children:(0,i.jsx)(K.A,{"aria-hidden":"true",className:"h-4 w-4"})})]})]})}var eh=a(18410);function em({floating:t=!1}){let{announcement:e,isLoading:a}=(0,S.bO)();if(a||!e)return null;let{text:n,link_url:s,link_label:r}=e;return(0,i.jsx)("div",{role:"status",className:t?"pointer-events-auto w-full rounded-2xl bg-blue-800/95 shadow-lg ring-1 ring-white/20 backdrop-blur":"bg-blue-800",children:(0,i.jsx)("div",{className:t?"px-4 py-3":"mx-auto max-w-7xl px-4 py-3 sm:px-6 lg:px-8",children:(0,i.jsxs)("div",{className:"flex items-start gap-3 text-left",children:[(0,i.jsx)(eh.A,{className:"h-5 w-5 shrink-0 text-blue-200","aria-hidden":"true"}),(0,i.jsxs)("div",{className:"min-w-0",children:[(0,i.jsx)("p",{className:"text-sm font-medium text-white",children:n}),s&&(0,i.jsx)("a",{href:s,className:"mt-1 inline-block text-sm font-semibold text-white underline underline-offset-2 hover:text-blue-100",children:r||"Learn more"})]})]})})})}var eu=a(21691);let ep=Math.PI/180,ey=t=>t*ep;function eb(t,e,a,i){let n=ey(i-e)*Math.cos(ey((t+a)/2)),s=ey(a-t);return 6378137*Math.sqrt(n*n+s*s)}var ef=a(14788),ew=a(48564);function ex(t,e,a,i=!0){let n=`train-${i?"triangle-balanced":"heading-unknown"}-${e}-${a}`;if(t.hasImage(n))return n;let s=document.createElement("canvas");s.width=48,s.height=52;let r=s.getContext("2d");return r.beginPath(),i?(r.moveTo(24,4),r.lineTo(40,44),r.lineTo(8,44)):r.arc(24,26,13,0,2*Math.PI),r.closePath(),r.fillStyle=e,r.fill(),r.lineWidth=3,r.lineJoin="round",r.strokeStyle=a,r.stroke(),t.addImage(n,r.getImageData(0,0,48,52),{pixelRatio:2}),n}var e_=a(19701),ev=a(19533);let ej=JSON.parse('[{"id":"toronto-union-station","name":"Union Station","latitude":43.6453,"longitude":-79.3806,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"UN","name":"Union Station GO"}
1,{"network":"up","stop_id":"UN","name":"UP Express Union Station"},{"network":"via","stop_id":"119","name":"Toronto"},{"network":"amtrak","stop_id":"TWO","name":"Toronto"},{"network":"ttc","stop_id":"10935","name":"Union Station"},{"network":"ttc","stop_id":"13815","name":"Union Station - Northbound Platform Towards Vaughan Metropolitan Centre"},{"network":"ttc","stop_id":"13816","name":"Union Station - Northbound Platform Towards Finch"},{"network":"ttc","stop_id":"1656","name":"Union Station Streetcar Platform"}]},{"id":"new-york-penn-station","name":"New York Penn Station","latitude":40.7503,"longitude":-73.9938,"timezone":"America/New_York","members":[{"network":"amtrak","stop_id":"NYP","name":"Moynihan Train Hall at Penn Station"},{"network":"njt","stop_id":"109","name":"Penn Station New York"},{"network":"lirr","stop_id":"237","name":"Penn Station"},{"network":"mta","stop_id":"128N","name":"34 St-Penn Station - 1/2/3 northbound"},{"network":"mta","stop_id":"128S","name":"34 St-Penn Station - 1/2/3 southbound"},{"network":"mta","stop_id":"A28N","name":"34 St-Penn Station - A/C/E northbound"},{"network":"mta","stop_id":"A28S","name":"34 St-Penn Station - A/C/E southbound"}]},{"id":"boston-south-station","name":"South Station","latitude":42.3523,"longitude":-71.0552,"timezone":"America/New_York","members":[{"network":"amtrak","stop_id":"BOS","name":"Boston South Station"},{"network":"mbta","stop_id":"NEC-2287","name":"South Station - Commuter Rail"},{"network":"mbta","stop_id":"70079","name":"South Station - Red Line southbound"},{"network":"mbta","stop_id":"70080","name":"South Station - Red Line northbound"}]},{"id":"boston-north-station","name":"North Station","latitude":42.3663,"longitude":-71.0612,"timezone":"America/New_York","members":[{"network":"amtrak","stop_id":"BON","name":"Boston North Station"},{"network":"mbta","stop_id":"BNT-0000","name":"North Station - Commuter Rail"},{"network":"mbta","stop_id":"70026","name":"North Station - Orange Line southbound"},{"network":"mbta","stop_id":"70027","name":"North Station - Orange Line northbound"},{"network":"mbta","stop_id":"70205","name":"North Station - Green Line westbound"},{"network":"mbta","stop_id":"70206","name":"North Station - Green Line eastbound"}]},{"id":"philadelphia-30th-street-station","name":"William H. Gray III 30th Street Station","latitude":39.9566,"longitude":-75.1818,"timezone":"America/New_York","members":[{"network":"amtrak","stop_id":"PHL","name":"Philadelphia"},{"network":"septa","stop_id":"90004","name":"Gray 30th St Station"},{"network":"njt","stop_id":"126","name":"Philadelphia 30th St."}]},{"id":"washington-union-station","name":"Washington Union Station","latitude":38.8974,"longitude":-77.0064,"timezone":"America/New_York","members":[{"network":"amtrak","stop_id":"WAS","name":"Washington Union Station"},{"network":"marc","stop_id":"11958","name":"Union Station MARC Washington"},{"network":"vre","stop_id":"00000000000000000000000000000001","name":"Union Station"},{"network":"wmta","stop_id":"PF_B03_C","name":"Union Station - Red Line"}]},{"id":"chicago-union-station","name":"Chicago Union Station","latitude":41.8788,"longitude":-87.6392,"timezone":"America/Chicago","members":[{"network":"amtrak","stop_id":"CHI","name":"Chicago Union Station"},{"network":"metra","stop_id":"CUS","name":"Chicago Union Station"}]},{"id":"los-angeles-union-station","name":"Los Angeles Union Station","latitude":34.056,"longitude":-118.235,"timezone":"America/Los_Angeles","members":[{"network":"amtrak","stop_id":"LAX","name":"Los Angeles"},{"network":"metrolink","stop_id":"107","name":"L.A. Union Station"},{"network":"lametro","stop_id":"80409","name":"Union Station - Metro A Line"},{"network":"lametro","stop_id":"80214","name":"Union Station - Metro B & D Lines"}]},{"id":"san-jose-diridon-station","name":"San Jose Diridon Station","latitude":37.3293,"longitude":-121.9032,"timezone":"America/Los_Angeles","members":[{"network":"amtrak","stop_id":"SJC","name":"San Jose"},{"network":"caltrain","stop_id":"70261","name":"San Jose Diridon Caltrain Northbound"},{"network":"caltrain","stop_id":"70262","name":"San Jose Diridon Caltrain Southbound"},{"network":"vta","stop_id":"65374","name":"Diridon Station"},{"network":"vta","stop_id":"65381","name":"Diridon Station"}]},{"id":"richmond-california-station","name":"Richmond Station","latitude":37.9368,"longitude":-122.3536,"timezone":"America/Los_Angeles","members":[{"network":"amtrak","stop_id":"RIC","name":"Richmond"},{"network":"bart","stop_id":"904601","name":"Richmond"},{"network":"bart","stop_id":"904602","name":"Richmond"}]},{"id":"millbrae-station","name":"Millbrae Station","latitude":37.5999,"longitude":-122.3868,"timezone":"America/Los_Angeles","members":[{"network":"caltrain","stop_id":"70061","name":"Millbrae Caltrain Northbound"},{"network":"caltrain","stop_id":"70062","name":"Millbrae Caltrain Southbound"},{"network":"bart","stop_id":"906403","name":"Millbrae - Caltrain Transfer Platform"}]},{"id":"montreal-central-station","name":"Montr\xe9al Gare Centrale","latitude":45.5,"longitude":-73.5665,"timezone":"America/Toronto","members":[{"network":"via","stop_id":"226","name":"Montr\xe9al"},{"network":"amtrak","stop_id":"MTR","name":"Montreal Central Station"},{"network":"exo","stop_id":"MTL5B","name":"Gare Centrale"},{"network":"exo","stop_id":"MTL5D","name":"Gare Centrale"},{"network":"rem","stop_id":"STA_ZCD_BT_QUAI_01_GCT","name":"Station Gare Centrale - Quai 1"},{"network":"rem","stop_id":"STA_ZCD_BT_QUAI_02_GCT","name":"Station Gare Centrale - Quai 2"}
1,{"network":"stm","stop_id":"15","name":"Station Bonaventure"}]},{"id":"newark-penn-station","name":"Newark Penn Station","latitude":40.7344,"longitude":-74.1642,"timezone":"America/New_York","members":[{"network":"amtrak","stop_id":"NWK","name":"Newark Penn Station"},{"network":"njt","stop_id":"112","name":"Newark Penn Station"},{"network":"path","stop_id":"781718","name":"Newark"},{"network":"path","stop_id":"781719","name":"Newark"}]},{"id":"baltimore-penn-station","name":"Baltimore Penn Station","latitude":39.3072,"longitude":-76.6157,"timezone":"America/New_York","members":[{"network":"amtrak","stop_id":"BAL","name":"Baltimore Penn Station"},{"network":"marc","stop_id":"11980","name":"Penn Station MARC southbound"},{"network":"marc","stop_id":"12002","name":"Penn Station MARC northbound"}]},{"id":"new-haven-union-station","name":"New Haven Union Station","latitude":41.2971,"longitude":-72.9275,"timezone":"America/New_York","members":[{"network":"amtrak","stop_id":"NHV","name":"New Haven"},{"network":"mnr","stop_id":"149","name":"New Haven"}]},{"id":"providence-station","name":"Providence Station","latitude":41.8294,"longitude":-71.4134,"timezone":"America/New_York","members":[{"network":"amtrak","stop_id":"PVD","name":"Providence"},{"network":"mbta","stop_id":"NEC-1851-03","name":"Providence"}]},{"id":"worcester-union-station","name":"Worcester Union Station","latitude":42.2613,"longitude":-71.7946,"timezone":"America/New_York","members":[{"network":"amtrak","stop_id":"WOR","name":"Worcester Union Station"},{"network":"mbta","stop_id":"WML-0442-CS","name":"Worcester"}]},{"id":"oceanside-transit-center","name":"Oceanside Transit Center","latitude":33.1915,"longitude":-117.3788,"timezone":"America/Los_Angeles","members":[{"network":"amtrak","stop_id":"OSD","name":"Oceanside"},{"network":"metrolink","stop_id":"144","name":"Oceanside"},{"network":"nctd","stop_id":"27000","name":"Oceanside Transit Center"},{"network":"nctd","stop_id":"28000","name":"Oceanside Transit Center Platform 3"},{"network":"nctd","stop_id":"28100","name":"Oceanside Transit Center"}]},{"id":"fullerton-transportation-center","name":"Fullerton Transportation Center","latitude":33.8688,"longitude":-117.9226,"timezone":"America/Los_Angeles","members":[{"network":"amtrak","stop_id":"FUL","name":"Fullerton Amtrak Station"},{"network":"metrolink","stop_id":"174","name":"Fullerton"}]},{"id":"anaheim-artic","name":"Anaheim Regional Transportation Intermodal Center","latitude":33.8032,"longitude":-117.8777,"timezone":"America/Los_Angeles","members":[{"network":"amtrak","stop_id":"ANA","name":"Anaheim"},{"network":"metrolink","stop_id":"128","name":"Anaheim - ARTIC"}]},{"id":"burbank-airport-south-station","name":"Burbank AirportâSouth Station","latitude":34.1929,"longitude":-118.3532,"timezone":"America/Los_Angeles","members":[{"network":"amtrak","stop_id":"BUR","name":"Burbank Amtrak"},{"network":"metrolink","stop_id":"170","name":"Burbank Airport - South"}]},{"id":"oakland-coliseum-station","name":"Oakland Coliseum Station","latitude":37.7529,"longitude":-122.1972,"timezone":"America/Los_Angeles","members":[{"network":"amtrak","stop_id":"OAC","name":"Oakland Coliseum/Airport"},{"network":"bart","stop_id":"902301","name":"Coliseum"},{"network":"bart","stop_id":"902302","name":"Coliseum"},{"network":"bart","stop_id":"902303","name":"Coliseum - OAC"}]},{"id":"denver-union-station","name":"Denver Union Station","latitude":39.7538,"longitude":-105.0012,"timezone":"America/Denver","members":[{"network":"amtrak","stop_id":"DEN","name":"Denver"},{"network":"rtddenver","stop_id":"34667","name":"Union Station Track 1"},{"network":"rtddenver","stop_id":"34668","name":"Union Station Track 2"},{"network":"rtddenver","stop_id":"34781","name":"Union Station Track 7"},{"network":"rtddenver","stop_id":"34782","name":"Union Station Track 8"},{"network":"rtddenver","stop_id":"25430","name":"Union Station Track 11"},{"network":"rtddenver","stop_id":"25434","name":"Union Station Track 12"}]},{"id":"dallas-union-station","name":"Dallas Union Station","latitude":32.7762,"longitude":-96.8077,"timezone":"America/Chicago","members":[{"network":"amtrak","stop_id":"DAL","name":"Dallas"},{"network":"dart","stop_id":"22748","name":"EBJ Union Station"}]},{"id":"fort-worth-central-station","name":"Fort Worth Central Station","latitude":32.7517,"longitude":-97.3256,"timezone":"America/Chicago","members":[{"network":"amtrak","stop_id":"FTW","name":"Fort Worth"},{"network":"dart","stop_id":"28251","name":"Fort Worth Central Station"}]}
1,{"id":"st-louis-gateway-station","name":"St. Louis Gateway Transportation Center","latitude":38.6246,"longitude":-90.2035,"timezone":"America/Chicago","members":[{"network":"amtrak","stop_id":"STL","name":"St. Louis"},{"network":"metrostlouis","stop_id":"10622","name":"Civic Center MetroLink Station"}]},{"id":"bloor-dundas-west-station-complex","name":"BloorâDundas West Station Complex","latitude":43.6569,"longitude":-79.4517,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"BL","name":"Bloor GO"},{"network":"up","stop_id":"BL","name":"Bloor GO/UP"},{"network":"ttc","stop_id":"13769","name":"Dundas West Station - Eastbound Platform"},{"network":"ttc","stop_id":"13770","name":"Dundas West Station - Westbound Platform"},{"network":"ttc","stop_id":"14665","name":"Dundas West Station"},{"network":"ttc","stop_id":"14666","name":"Dundas West Station"}]},{"id":"downsview-park-station","name":"Downsview Park Station","latitude":43.7535,"longitude":-79.4785,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"DW","name":"Downsview Park GO"},{"network":"ttc","stop_id":"15664","name":"Downsview Park Station - Northbound Platform"},{"network":"ttc","stop_id":"15665","name":"Downsview Park Station - Southbound Platform"}]},{"id":"kennedy-station-toronto","name":"Kennedy Station","latitude":43.7327,"longitude":-79.2637,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"KE","name":"Kennedy GO"},{"network":"ttc","stop_id":"13865","name":"Kennedy Station - Westbound Platform"},{"network":"ttc","stop_id":"14947","name":"Kennedy Station - Subway Platform"},{"network":"ttc","stop_id":"16081","name":"Kennedy Station LRT Platform"},{"network":"ttc","stop_id":"16082","name":"Kennedy Station LRT Platform"}]},{"id":"kipling-station-toronto","name":"Kipling Station","latitude":43.6373,"longitude":-79.536,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"KP","name":"Kipling GO"},{"network":"ttc","stop_id":"13785","name":"Kipling Station - Eastbound Platform"},{"network":"ttc","stop_id":"14948","name":"Kipling Station - Subway Platform"}]},{"id":"danforth-main-street-station-complex","name":"DanforthâMain Street Station Complex","latitude":43.6882,"longitude":-79.3015,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"DA","name":"Danforth GO"},{"network":"ttc","stop_id":"1262","name":"Main St at Danforth GO Station"},{"network":"ttc","stop_id":"1263","name":"Main St at Danforth GO Station"},{"network":"ttc","stop_id":"13735","name":"Main Street Station - Eastbound Platform"},{"network":"ttc","stop_id":"13736","name":"Main Street Station - Westbound Platform"},{"network":"ttc","stop_id":"14741","name":"Main Street Station"}]},{"id":"exhibition-station-complex","name":"Exhibition Station Complex","latitude":43.6358,"longitude":-79.4179,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"EX","name":"Exhibition GO"},{"network":"ttc","stop_id":"12584","name":"Exhibition Loop"},{"network":"ttc","stop_id":"15190","name":"Exhibition Loop"}
1,{"network":"ttc","stop_id":"13366","name":"Exhibition Loop at Manitoba Dr"}]},{"id":"oriole-leslie-station-complex","name":"OrioleâLeslie Station Complex","latitude":43.7683,"longitude":-79.3651,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"OR","name":"Oriole GO"},{"network":"ttc","stop_id":"13847","name":"Leslie Station - Westbound Platform"},{"network":"ttc","stop_id":"13848","name":"Leslie Station - Eastbound Platform"}]},{"id":"weston-station-toronto","name":"Weston Station","latitude":43.7003,"longitude":-79.5137,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"WE","name":"Weston GO"},{"network":"up","stop_id":"WE","name":"Weston GO/UP"}]},{"id":"mount-dennis-station-toronto","name":"Mount Dennis Station","latitude":43.6875,"longitude":-79.487,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"MD","name":"Mount Dennis GO"},{"network":"up","stop_id":"MD","name":"Mount Dennis GO/UP"},{"network":"ttc","stop_id":"16067","name":"Mount Dennis Station LRT Platform"},{"network":"ttc","stop_id":"16068","name":"Mount Dennis Station LRT Platform"}]},{"id":"vancouver-waterfront-station","name":"Waterfront Station","latitude":49.2858,"longitude":-123.1122,"timezone":"America/Vancouver","members":[{"network":"translink","stop_id":"8019","name":"Waterfront Station Eastbound"},{"network":"translink","stop_id":"8034","name":"Waterfront Station Unload Only"},{"network":"translink","stop_id":"8039","name":"Waterfront Station - Platform 2"},{"network":"translink","stop_id":"8078","name":"Waterfront Station - Platform 1"},{"network":"translink","stop_id":"11302","name":"Waterfront Station - Platform 4"},{"network":"translink","stop_id":"11303","name":"Waterfront Station - Platform 5"},{"network":"translink","stop_id":"12138","name":"Waterfront Station - West Coast Express"}]},{"id":"commercial-broadway-station","name":"CommercialâBroadway Station","latitude":49.2626,"longitude":-123.0688,"timezone":"America/Vancouver","members":[{"network":"translink","stop_id":"8754","name":"Commercial-Broadway Station - Platform 1"},{"network":"translink","stop_id":"8763","name":"Commercial-Broadway Station - Platform 2"},{"network":"translink","stop_id":"8073","name":"Commercial-Broadway Station - Platform 3"},{"network":"translink","stop_id":"8044","name":"Commercial-Broadway Station - Platform 4"}]},{"id":"moody-centre-station","name":"Moody Centre Station","latitude":49.278,"longitude":-122.8461,"timezone":"America/Vancouver","members":[{"network":"translink","stop_id":"8020","name":"Moody Centre Station Eastbound"},{"network":"translink","stop_id":"8033","name":"Moody Centre Station Westbound"},{"network":"translink","stop_id":"12230","name":"Moody Centre Station - Platform 1"},{"network":"translink","stop_id":"12231","name":"Moody Centre Station - Platform 2"},{"network":"translink","stop_id":"12319","name":"Moody Centre Station - West Coast Express"},{"network":"translink","stop_id":"12320","name":"Moody Centre Station - West Coast Express"}]},{"id":"coquitlam-central-station","name":"Coquitlam Central Station","latitude":49.2743,"longitude":-122.8003,"timezone":"America/Vancouver","members":[{"network":"translink","stop_id":"8021","name":"Coquitlam Central Station Eastbound"},{"network":"translink","stop_id":"8032","name":"Coquitlam Central Station Westbound"},{"network":"translink","stop_id":"12234","name":"Coquitlam Central Station - Platform 1"}
1,{"network":"translink","stop_id":"12235","name":"Coquitlam Central Station - Platform 2"},{"network":"translink","stop_id":"12321","name":"Coquitlam Central Station - West Coast Express"},{"network":"translink","stop_id":"12322","name":"Coquitlam Central Station - West Coast Express"}]},{"id":"stratford-station-complex","name":"Stratford","latitude":43.3643734,"longitude":-80.9757414,"timezone":"America/Toronto","members":[{"network":"via","stop_id":"7","name":"Stratford"},{"network":"go","stop_id":"SF","name":"Stratford GO"}]},{"id":"aldershot-station-complex","name":"Aldershot","latitude":43.313228,"longitude":-79.85546,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"AL","name":"Aldershot GO"},{"network":"amtrak","stop_id":"AST","name":"Aldershot"},{"network":"via","stop_id":"600","name":"Aldershot"}]},{"id":"niagara-falls-station-complex","name":"Niagara Falls","latitude":43.1088517,"longitude":-79.0633162,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"NI","name":"Niagara Falls GO"},{"network":"via","stop_id":"346","name":"Niagara Falls"},{"network":"amtrak","stop_id":"NFS","name":"Niagara Falls"}]},{"id":"kitchener-station-complex","name":"Kitchener","latitude":43.4557135,"longitude":-80.4931684,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"KI","name":"Kitchener GO"},{"network":"via","stop_id":"114","name":"Kitchener"}]},{"id":"georgetown-station-complex","name":"Georgetown","latitude":43.6554415,"longitude":-79.919087,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"GE","name":"Georgetown GO"},{"network":"via","stop_id":"6","name":"Georgetown"}]},{"id":"edouard-montpetit-station-complex","name":"\xc9douard-Montpetit","latitude":45.510038,"longitude":-73.612742,"timezone":"America/Toronto","members":[{"network":"stm","stop_id":"57","name":"Station \xc9douard-Montpetit"},{"network":"rem","stop_id":"STA_ZCD_BT_QUAI_02_EDM","name":"Station \xc9douard-Montpetit - Quai 2"},{"network":"rem","stop_id":"STA_ZCD_BT_QUAI_01_EDM","name":"Station \xc9douard-Montpetit - Quai 1"}]},{"id":"oakville-station-complex","name":"Oakville","latitude":43.4552943,"longitude":-79.6823653,"timezone":"America/Toronto","members":[{"network":"amtrak","stop_id":"OKL","name":"Oakville"},{"network":"go","stop_id":"OA","name":"Oakville GO"},{"network":"via","stop_id":"436","name":"Oakville"}]},{"id":"lucien-lallier-station-complex","name":"Lucien-LâAllier","latitude":45.4947557,"longitude":-73.5708843,"timezone":"America/Toronto","members":[{"network":"exo","stop_id":"MTL3C","name":"Gare Lucien-L\'Allier"},{"network":"stm","stop_id":"16","name":"Station Lucien-L\'Allier"},{"network":"exo","stop_id":"MTL3A","name":"Gare Lucien-L\'Allier"}]},{"id":"malton-station-complex","name":"Malton","latitude":43.705009,"longitude":-79.6381855,"timezone":"America/Toronto","members":[{"network":"via","stop_id":"34","name":"Malton"},{"network":"go","stop_id":"MA","name":"Malton GO"}]},{"id":"guildwood-station-complex","name":"Guildwood","latitude":43.7550478,"longitude":-79.1982576,"timezone":"America/Toronto","members":[{"network":"via","stop_id":"450","name":"Guildwood"},{"network":"go","stop_id":"GU","name":"Guildwood GO"}]},{"id":"vendome-station-complex","name":"Vend\xf4me","latitude":45.4738087,"longitude":-73.6033147,"timezone":"America/Toronto","members":[{"network":"exo","stop_id":"MTL2C","name":"Gare Vend\xf4me"},{"network":"stm","stop_id":"47","name":"Station Vend\xf4me"},{"network":"exo","stop_id":"MTL2A","name":"Gare Vend\xf4me"}]},{"id":"cote-de-liesse-station-complex","name":"C\xf4te-de-Liesse","latitude":45.5220385,"longitude":-73.6623467,"timezone":"America/Toronto","members":[{"network":"rem","stop_id":"STA_ZCD_BT_QUAI_01_A40","name":"Station C\xf4te-de-Liesse - Quai 1"},{"network":"exo","stop_id":"MTL60A","name":"Gare C\xf4te-de-Liesse"},{"network":"exo","stop_id":"MTL60C","name":"Gare C\xf4te-de-Liesse"},{"network":"rem","stop_id":"STA_ZCD_BT_QUAI_02_A40","name":"Station C\xf4te-de-Liesse - Quai 2"}]},{"id":"st-catharines-station-complex","name":"St. Catharines","latitude":43.1477023,"longitude":-79.2557667,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"SCTH","name":"St. Catharines GO"}
1,{"network":"via","stop_id":"185","name":"St. Catharines"},{"network":"amtrak","stop_id":"SCA","name":"St. Catherines"}]},{"id":"saint-lambert-station-complex","name":"Saint-Lambert","latitude":45.4993088,"longitude":-73.5065972,"timezone":"America/Toronto","members":[{"network":"via","stop_id":"343","name":"Saint-Lambert"},{"network":"exo","stop_id":"STL1D","name":"Gare Saint-Lambert"},{"network":"exo","stop_id":"STL1B","name":"Gare Saint-Lambert"},{"network":"amtrak","stop_id":"SLQ","name":"St-Lambert Amtrak Station"}]},{"id":"mcgill-station-complex","name":"McGill","latitude":45.5031473,"longitude":-73.5721487,"timezone":"America/Toronto","members":[{"network":"rem","stop_id":"STA_ZCD_BT_QUAI_01_MCG","name":"Station McGill - Quai 1"},{"network":"stm","stop_id":"32","name":"Station McGill"},{"network":"rem","stop_id":"STA_ZCD_BT_QUAI_02_MCG","name":"Station McGill - Quai 2"}]},{"id":"de-la-concorde-station-complex","name":"De la Concorde","latitude":45.560444,"longitude":-73.7097083,"timezone":"America/Toronto","members":[{"network":"exo","stop_id":"LVL24C","name":"Gare De la Concorde"},{"network":"stm","stop_id":"67","name":"Station De la Concorde -Zone B"},{"network":"exo","stop_id":"LVL24A","name":"Gare De la Concorde"}]},{"id":"guelph-station-complex","name":"Guelph","latitude":43.544802,"longitude":-80.2462595,"timezone":"America/Toronto","members":[{"network":"go","stop_id":"GL","name":"Guelph Central GO"},{"network":"via","stop_id":"70","name":"Guelph"}]},{"id":"oshawa-station-complex","name":"Oshawa","latitude":43.8709158,"longitude":-78.8847164,"timezone":"America/Toronto","members":[{"network":"via","stop_id":"367","name":"Oshawa"},{"network":"go","stop_id":"OS","name":"Durham College Oshawa GO"}]},{"id":"brampton-station-complex","name":"Brampton","latitude":43.6868793,"longitude":-79.7636716,"timezone":"America/Toronto","members":[{"network":"via","stop_id":"322","name":"Brampton"},{"network":"go","stop_id":"BR","name":"Brampton Innovation District GO"}]},{"id":"ottawatremblay-station-complex","name":"OttawaâTremblay","latitude":45.416372,"longitude":-75.6531837,"timezone":"America/Toronto","members":[{"network":"via","stop_id":"617","name":"Ottawa"},{"network":"octrans","stop_id":"AE995","name":"TREMBLAY O-TRAIN EAST / EST"},{"network":"octrans","stop_id":"AE990","name":"TREMBLAY O-TRAIN WEST / OUEST"}]}]'),ek=[10,30],eS=t=>`${t.agency}:${t.vid}`,eC=(t,e)=>`${encodeURIComponent(t)}:${encodeURIComponent(e)}`,eN=t=>{if("string"!=typeof t)return null;let e=t.indexOf(":");if(e<=0||e===t.length-1)return null;try{return[decodeURIComponent(t.slice(0,e)),decodeURIComponent(t.slice(e+1))]}catch{return null}};function eI(){let t=(0,ev._)(),e=(0,c.useRouter)(),h="1"===e.query.lateList,[m,u]=(0,g.useState)(!1),{user:p,loading:y}=(0,tP.A)(),{isPremium:b,entitlementLoading:f}=(0,tU.x)(),w=!!p&&!y&&!f&&b,x=(0,g.useRef)(!1);x.current=w;let[_,v]=(0,g.useState)({renderer:l.A,theme:"light",style:(0,tH.Zn)("light")}),j=(0,g.useRef)(_);j.current=_;let k=w?_.renderer:l.A,C=(0,g.useRef)(null),N=(0,g.useRef)(null),I=(0,g.useRef)(null),M=(0,g.useRef)(null),A=(0,g.useRef)(new Map),L=(0,g.useRef)(new Map),T=(0,g.useRef)({type:"FeatureCollection",features:[]}),z=(0,g.useRef)(null),R=(0,g.useRef)(null),P=(0,g.useRef)(new Set),U=(0,g.useRef)(!1),E=(0,g.useRef)(null),[$,F]=(0,g.useState)(null),[B,D]=(0,g.useState)(!1),G=B&&$?.renderer===k,[O,K]=(0,g.useState)(0),[W,J]=(0,g.useState)(!1),[H,V]=(0,g.useState)(!1),[q,Y]=(0,g.useState)(!1),[Q,X]=(0,g.useState)(""),[tt,te]=(0,g.useState)(!0),[ta,ti]=(0,g.useState)(!0),[tn,ts]=(0,g.useState)("light"),[tr,to]=(0,g.useState)(!1),[tl,tc]=(0,g.useState)(""),[tg,th]=(0,g.useState)(()=>t5.map(({id:t})=>t)),[tm,tu]=(0,g.useState)(!1);(0,g.useEffect)(()=>{let t=function(t){let e={railway:!1,trainRoutes:!1,showMajorStations:!0,showMinorStations:!0,enabled:t};try{let a=JSON.parse(localStorage.getItem(n));if(!a||"object"!=typeof a)return e;return{railway:"boolean"==typeof a.railway?a.railway:e.railway,trainRoutes:"boolean"==typeof a.trainRoutes?a.trainRoutes:e.trainRoutes,showMajorStations:"boolean"==typeof a.showMajorStations?a.showMajorStations:!1!==a.showStations,showMinorStations:"boolean"==typeof a.showMinorStations?a.showMinorStations:!1!==a.showStations,enabled:Array.isArray(a.enabled)?[...new Set(a.enabled.filter(e=>t.includes(e)))]:t}}catch{return e}}(t5.map(({id:t})=>t));J(t.railway),V(t.trainRoutes),te(t.showMajorStations),ti(t.showMinorStations),th(t.enabled),tu(!0)},[]),(0,g.useEffect)(()=>{tm&&function(t){try{localStorage.setItem(n,JSON.stringify(t))}catch{}}({railway:W,trainRoutes:H,showMajorStations:tt,showMinorStations:ta,enabled:tg})},[tm,W,H,tt,ta,tg]);let tp=(0,g.useRef)(null),ty=(0,g.useRef)(null);(0,g.useEffect)(()=>{tp.current?.abort(),to(!1)},[w]);let[tb,tf]=(0,g.useState)(null),[tw,tx]=(0,g.useState)(null),[tv,tj]=(0,g.useState)(null),[tk,tS]=(0,g.useState)(null),{trains:tC,isLoading:tN}=(0,S.e9)(!1,tk),tI=h&&"string"==typeof e.query.train?eN(e.query.train)?.[0]:null,{trains:tM}=(0,S._I)(tI),{networks:tA}=(0,S.xM)(),tL=(0,g.useMemo)(()=>tR.Y.getAllNetworks(),[]),tE=(0,g.useMemo)(()=>{let t=new Map(tL.map(t=>[t.slug?.toLowerCase(),t]));
1return tA.forEach(e=>{let a=e.slug?.toLowerCase();a&&!t.has(a)&&t.set(a,e)}),t.set("freight",ew.l4),t},[tL,tA]),t$=(0,g.useMemo)(()=>{let t=h&&tM.length?tM:tC?.trains??[];if(!h||"string"!=typeof e.query.train)return t;let a=eN(e.query.train);return a?t.filter(t=>t.agency===a[0]&&String(t.vid)===a[1]):[]},[h,tM,e.query.train,tC]),tF=(0,g.useMemo)(()=>{let t={};return t$.forEach(e=>{let a=t7(e,tE.get(e.agency?.toLowerCase()));t[a]=(t[a]||0)+1}),t},[t$,tE]),tB=(0,g.useMemo)(()=>h?t$:t$.filter(t=>tg.includes(t7(t,tE.get(t.agency?.toLowerCase())))),[t$,tg,h,tE]),tD=(0,g.useMemo)(()=>tB.filter(t=>eS(t)===tb||function(t,e){if(!e)return!0;let a=((t.lng+180)%360+360)%360-180;return e.some(([e,i,n,s])=>a>=e&&a<=n&&t.lat>=i&&t.lat<=s)}(t,tk)),[tB,tb,tk]),tG=(0,g.useMemo)(()=>(function(t,e=new Date){let a=new Map,i=new Map;for(let e of t)if(Number.isFinite(e.lat)&&Number.isFinite(e.lng))for(let[t,n]of[[a,e.gtfs?.trip_id],[i,e.vid]]){if(null==n||""===n)continue;let a=tT(e.agency,n);t.set(a,[...t.get(a)||[],e])}return t=>{let n=[...new Set([...t.trip_id&&a.get(tT(t.network,t.trip_id))||[],...t.vehicle_id&&i.get(tT(t.network,t.vehicle_id))||[]])].filter(a=>{if(a.gtfs?.trip_id&&String(a.gtfs.trip_id)!==String(t.trip_id))return!1;if(t.service_date){if(a.service_date)return tz(a.service_date)===tz(t.service_date);let i=new Intl.DateTimeFormat("en-CA",{timeZone:t.timezone||"UTC",year:"numeric",month:"2-digit",day:"2-digit"}).format(e);if(tz(t.service_date)!==tz(i))return!1}return!0});if(1===n.length)return n[0];let s=n.filter(e=>t.vehicle_id&&String(e.vid)===String(t.vehicle_id));return 1===s.length?s[0]:null}})(t$),[t$]),tO=(0,g.useCallback)(t=>{let e=eS(t),a=t7(t,tE.get(t.agency?.toLowerCase()));th(t=>t.includes(a)?t:[...t,a]),C.current=null,tj(null),tf(e)},[tE]),tJ=(0,g.useMemo)(()=>tb?tB.find(t=>eS(t)===tb)??null:h?t$[0]??null:null,[t$,h,tb,tB]);(0,g.useEffect)(()=>{h&&!tb&&t$[0]&&tf(eS(t$[0]))},[t$,h,tb]);let tV=tJ?eS(tJ):null,tq=!!(tJ&&tw===tb);(0,g.useEffect)(()=>{tx(t=>t===tb?t:null)},[tb]),(0,g.useEffect)(()=>{h&&tb&&tx(tb)},[h,tb]);let{data:tY}=(0,td.o)(tJ?.agency==="freight"?tJ.vid:null),tZ=tJ?tE.get(tJ.agency?.toLowerCase())??null:null,tQ=tv?tE.get(tv.network?.toLowerCase())??null:null;(0,g.useEffect)(()=>{z.current=tb},[tb]),(0,g.useEffect)(()=>{E.current=tv},[tv]);let tX=(0,g.useCallback)(()=>{C.current=null,tf(null)},[]),t0=(0,g.useCallback)(()=>{C.current=null,tj(null)},[]),t1=(0,g.useCallback)(t=>{C.current=null,tf(null),tj(t)},[]),t2=(0,g.useCallback)(({selectionKey:t,place:e})=>{tj(a=>{let i;if(!a||o(a)!==t)return a;let n=(i=e.sources?.[0],{stationId:e.id,id:e.marker_id||e.id,stopName:e.name,network:i?.network,stopId:i?.stop_id,lng:e.longitude,lat:e.latitude,citySlugs:e.city_slugs?.join(",")});return a.stationId===n.stationId&&a.id===n.id&&a.stopName===n.stopName&&a.lat===n.lat&&a.lng===n.lng&&a.citySlugs===n.citySlugs?a:{...a,...n}})},[]);(0,g.useEffect)(()=>{if(!e.isReady)return;let t=JSON.stringify([e.query.train,e.query.station,e.query.stationCities]);if(P.current.delete(t))return;U.current=!0;let a=e.query.train,i=e.query.station;if("string"==typeof a){let t=eN(a);if(t){let e=`${t[0]}:${t[1]}`;tf(t=>t===e?t:e),tj(t=>null===t?t:null)}}else if("string"==typeof i){let t=eN(i),e="string"==typeof i&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(i)?{stationId:i,id:i}:t?{network:t[0],stopId:t[1]}:{stationId:i};tj(t=>o(t)===o(e)?t:e),tf(null)}else tf(t=>null===t?t:null),tj(t=>null===t?t:null)},[e.isReady,e.query.train,e.query.station,e.query.stationCities]),(0,g.useEffect)(()=>{if(!e.isReady)return;if(U.current){U.current=!1;return}let t={...e.query};if(delete t.train,delete t.station,delete t.stationCities,tb){let[e,a]=tb.split(/:(.+)/);t.train=eC(e,a??"")}else tv&&(t.station=tv.stationId||eC(tv.network,tv.stopId));let a=e.query;if(a.train===t.train&&a.station===t.station&&a.stationCities===t.stationCities)return;let i=JSON.stringify([t.train,t.station,t.stationCities]);P.current.add(i),e.replace({pathname:e.pathname,query:t},void 0,{shallow:!0,scroll:!1}).catch(()=>P.current.delete(i))},[e.isReady,e.query.train,e.query.station,e.query.stationCities,tb,tv]),(0,g.useEffect)(()=>{let t,e,a;if(!N.current||I.current)return;D(!1);let i=j.current,n=(0,tH.Vn)(i.theme,x.current);ts(n?i.theme:"light"),to(!1),tc(""),t=new Map,e=null,a=null,M.current={sync:function(e,a=performance.now()){let i=new Set;for(let n of e){let e=`${n.agency}:${n.vid}`,s=Number(n.lat),r=Number(n.lng);if(!Number.isFinite(s)||!Number.isFinite(r))continue;i.add(e);let o=function(t){let e=Number(t);return!Number.isFinite(e)||e<=0?null:e/3.6}(n.normalized?.speed?.kph??n.spd),l=null==n.dir||""===String(n.dir).trim()?NaN:Number(n.dir),c=Number.isFinite(l)?l:null,g=Array.isArray(n.lookahead_path)&&n.lookahead_path.length>1?n.lookahead_path:null,d="sighting_prediction"===n.position_source||!!n.freight?.source,h=t.get(e),m=n.vehicle_timestamp??n.updated??null;if(!h){t.set(e,{fromLat:s,fromLng:r,toLat:s,toLng:r,renderLat:s,renderLng:r,startedAt:a,durationMs:3e4,bearingDeg:c,speedMps:o,fixTimestamp:m,railPath:g,railEstimate:d});continue}if(h.toLat===s&&h.toLng===r&&h.speedMps===o&&h.bearingDeg===c&&h.fixTimestamp===m)continue;let u=eb(h.toLat,h.toLng,s,r),p=a-h.startedAt,y=eb(h.renderLat,h.renderLng,s,r);u>2e3||y>2e3||p>=6e4?(h.renderLat=s,h.renderLng=r,h.fromLat=s,h.fromLng=r):(h.fromLat=h.renderLat,h.fromLng=h.renderLng),h.toLat=s,h.shapeMotion=void 0,h.toLng=r,h.startedAt=a,h.bearingDeg=c,h.speedMps=o,h.fixTimestamp=m,h.railPath=g,h.railEstimate=d,h.durationMs=u>1?Math.min(6e4,Math.max(5e3,p||3e4)):3e4}for(let e of t.keys())i.has(e)||t.delete(e)},step:function(i,n,s){let r=null!=a&&i-a>=5e3;a=i;let o=r?1:1-Math.exp(-Math.max(n,1)/450),l=0;for(let[a,n]of t){let t,c;r&&(n.fromLat=n.toLat,n.fromLng=n.toLng);let g=i-n.startedAt;if(n.railEstimate){let e=Math.max(0,Math.min(g,45e3))/1e3,a=n.railPath&&n.speedMps?function(t,e){for(let a=1;a<t.length;a+=1){let[i,n]=t[a-1],[s,r]=t[a],o=eb(n,i,r,s);if(o>0&&e<=o){let t=e/o;return{lat:n+(r-n)*t,lng:i+(s-i)*t}}e-=o}let[a,i]=t.at(-1);return{lat:i,lng:a}}(n.railPath,n.speedMps*e):{lat:n.toLat,lng:n.toLng};t=a.lat,c=a.lng}else if(n.speedMps&&null!=n.bearingDeg){let i=Math.min(g,45e3)/1e3;if(e?.id===a&&void 0===n.shapeMotion){let t=function(t,a){let i=null,n=Math.cos(ey(t));for(let s of e.segments){let e=(s.nextLng-s.lng)*n,r=s.nextLat-s.lat,o=Math.max(0,Math.min(1,((a-s.lng)*n*e+(t-s.lat)*r)/(e*e+r*r))),l=eb(t,a,s.lat+r*o,s.lng+(s.nextLng-s.lng)*o);(!i||l<i.distance)&&(i={distance:l,offset:s.start+s.size*o,bearing:Math.atan2(e,r)/ep})}return i}(n.toLat,n.toLng);n.shapeMotion=t.distance<=100?{origin:t.offset,rendered:null,direction:Math.cos(ey(n.bearingDeg-t.bearing))>=0?1:-1}:null}if(e?.id===a&&n.shapeMotion){let a=n.shapeMotion,s=Math.max(0,Math.min(e.length,a.origin+a.direction*n.speedMps*i));a.rendered=null==a.rendered?s:a.rendered+(s-a.rendered)*o;let r=function(t){let a=Math.max(0,Math.min(e.length,t)),i=e.segments.find(t=>t.start+t.size>=a)||e.segments.at(-1),n=(a-i.start)/i.size;return{lat:i.lat+(i.nextLat-i.lat)*n,lng:i.lng+(i.nextLng-i.lng)*n}}(a.rendered);t=r.lat,c=r.lng}
1else{let e=function(t,e,a,i){if(!i)return{lat:t,lng:e};let n=ey(a),s=i*Math.cos(n)/6378137/ep,r=Math.cos(ey(t));return{lat:t+s,lng:e+(1e-6>Math.abs(r)?0:i*Math.sin(n)/(6378137*r)/ep)}}(n.toLat,n.toLng,n.bearingDeg,n.speedMps*i);t=n.reanchorMotion?e.lat:n.renderLat+(e.lat-n.renderLat)*o,c=n.reanchorMotion?e.lng:n.renderLng+(e.lng-n.renderLng)*o}}else{let e=n.durationMs>0?Math.min(g/n.durationMs,1):1;t=n.fromLat+(n.toLat-n.fromLat)*e,c=n.fromLng+(n.toLng-n.fromLng)*e}n.reanchorMotion=!1,(Math.abs(t-n.renderLat)>1e-6||Math.abs(c-n.renderLng)>1e-6)&&(n.renderLat=t,n.renderLng=c,s(a,c,t),l+=1)}return l},positionOf:function(e){let a=t.get(e);return a?{lat:a.renderLat,lng:a.renderLng}:null},setSelectedShape:function(a,i){for(let a of(e=null,t.values()))a.shapeMotion&&(a.reanchorMotion=!0),a.shapeMotion=void 0;let n=i?.type==="LineString"?i.coordinates:null;if(!a||!Array.isArray(n)||n.length<2||!n.every(t=>Array.isArray(t)&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])))return;let s=0,r=[];for(let t=1;t<n.length;t+=1){let[e,a]=n[t-1],[i,o]=n[t],l=eb(a,e,o,i);l&&(r.push({lng:e,lat:a,nextLng:i,nextLat:o,size:l,start:s}),s+=l)}r.length&&(e={id:a,segments:r,length:s})},clear:function(){t.clear(),e=null,a=null}};let o=function(){try{let t=JSON.parse(localStorage.getItem(s)),{center:e,zoom:a,bearing:i,pitch:n}=t.camera;if(!Array.isArray(e)||2!==e.length||!e.every(Number.isFinite)||Math.abs(e[1])>85.051129||!Number.isFinite(a)||a<1.2||a>16||!Number.isFinite(i)||!Number.isFinite(n)||n<0||n>60)return null;let r={center:e,zoom:a,bearing:i,pitch:n};return t.width===window.innerWidth&&t.height===window.innerHeight&&t.camera.padding&&["top","bottom","left","right"].every(e=>Number.isFinite(t.camera.padding[e])&&t.camera.padding[e]>=0)&&(r.padding=t.camera.padding),{camera:r,selection:t.selection}}catch{return null}}(),c=r();C.current=o?.selection===c?c:null;let g=new k.Map({container:N.current,style:n?i.style:(0,tH.Zn)("light"),...k!==l.A?{accessToken:tH.Et}:{},center:ek,zoom:2.2,...o?.camera,minZoom:1.2,maxZoom:16,antialias:!0,attributionControl:!1,dragRotate:!1});I.current=g,F({instance:g,renderer:k});let d=()=>{let t=g.getBounds(),e=function(t,e){if(e<5)return null;let[a,i,n,s]=t,r=Math.max((n-a)/2,.05),o=Math.max((s-i)/2,.05),l=Math.max(-90,i-o),c=Math.min(90,s+o),g=n-a+2*r;if(g>=360)return[[-180,l,180,c]];let d=((a-r+180)%360+360)%360-180,h=d+g;return h<=180?[[d,l,h,c]]:[[d,l,180,c],[-180,l,h-360,c]]}([t.getWest(),t.getSouth(),t.getEast(),t.getNorth()],g.getZoom());tS(t=>JSON.stringify(t)===JSON.stringify(e)?t:e)};d(),g.on("moveend",d);let h=()=>(function(t){try{let e=t.getCenter();localStorage.setItem(s,JSON.stringify({camera:{center:[e.lng,e.lat],zoom:t.getZoom(),bearing:t.getBearing(),pitch:t.getPitch(),padding:t.getPadding()},selection:r(),width:window.innerWidth,height:window.innerHeight}))}catch{}})(g),m=()=>{"hidden"===document.visibilityState&&h()};g.on("moveend",h),window.addEventListener("pagehide",h),document.addEventListener("visibilitychange",m),g.addControl(new k.AttributionControl({compact:!0}),"bottom-left");let u=new ResizeObserver(()=>g.resize());u.observe(N.current);let p=()=>{T.current.features.forEach(({properties:t})=>ex(g,t.color,t.borderColor)),g.addSource("trains",{type:"geojson",data:T.current}),g.addSource("selected-route",{type:"geojson",data:{type:"FeatureCollection",features:[]}}),g.addLayer({id:"selected-route-casing",type:"line",source:"selected-route",layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":"#ffffff","line-width":6,"line-opacity":.9}}),g.addLayer({id:"selected-route-line",type:"line",source:"selected-route",layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":["get","color"],"line-width":3,"line-opacity":.95}}),g.addLayer({id:"train-halo",type:"circle",source:"trains",filter:["==",["get","id"],""],paint:{"circle-radius":["interpolate",["linear"],["zoom"],2,8,8,14,14,20],"circle-color":["get","color"],"circle-opacity":.25,"circle-stroke-color":["get","color"],"circle-stroke-width":1.5,"circle-stroke-opacity":.5}}),g.addLayer({id:"train-points",type:"symbol",source:"trains",layout:{"icon-image":["get","icon"],"icon-size":["interpolate",["linear"],["zoom"],2,["*",.45,["get","markerScale"]],6,["*",.65,["get","markerScale"]],10,["*",.85,["get","markerScale"]],16,["*",1.2,["get","markerScale"]]],"icon-rotate":["get","bearing"],"icon-rotation-alignment":"map","icon-pitch-alignment":"map","icon-allow-overlap":!0,"icon-ignore-placement":!0}}),(0,eu.MB)(g),K(t=>t+1),D(!0),to(!1)};return g.on("style.load",()=>{k===l.A||g.isStyleLoaded()?p():g.once("idle",p)}),g.on("click","train-points",t=>{let e=t.features?.[0]?.properties?.id;e&&(C.current=null,tj(null),tf(e))}),g.on("click",t=>{g.getLayer("train-points")&&!g.queryRenderedFeatures(t.point,{layers:["train-points"]}).length&&z.current&&tf(null);let e=["station-points","station-labels","major-stations-overview-points","major-stations-overview-labels"].filter(t=>g.getLayer(t));e.length?!g.queryRenderedFeatures(t.point,{layers:e}).length&&E.current&&tj(null):E.current&&tj(null)}),g.on("mouseenter","train-points",()=>{g.getCanvas().style.cursor="pointer"}),g.on("mouseleave","train-points",()=>{g.getCanvas().style.cursor=""}),()=>{tp.current?.abort(),h(),u.disconnect(),window.removeEventListener("pagehide",h),document.removeEventListener("visibilitychange",m),g.off("moveend",h),g.off("moveend",d),g.remove(),I.current=null,M.current?.clear(),A.current.clear(),L.current.clear(),T.current={type:"FeatureCollection",features:[]}}},[k]);let t4=(0,g.useCallback)(async t=>{if(t===tn||!(0,tH.Vn)(t,x.current))return;tp.current?.abort();let e=new AbortController;tp.current=e,to(!0),tc("");let i=!1,n=setTimeout(()=>{i=!0,e.abort()},15e3);try{let i=await (0,tH.E_)(t,e.signal);if(8!==i.version||!Array.isArray(i.layers)||!i.sources)throw Error("Invalid map style");if(e.signal.aborted||!I.current||!(0,tH.Vn)(t,x.current))return;let n=(0,tH.Vn)(t,!1)?l.A:(await Promise.all([a.e(3602),a.e(4595)]).then(a.bind(a,34595))).default;if(e.signal.aborted||!I.current||!(0,tH.Vn)(t,x.current))return;D(!1),v({renderer:n,theme:t,style:i}),$?.renderer===n&&I.current.setStyle(i,{diff:!1}),ts(t),(0,tH.w6)(t)}
1catch{(i||!e.signal.aborted)&&(tc("Could not load this style. Please try again."),to(!1))}finally{clearTimeout(n)}},[tn,$]);(0,g.useEffect)(()=>{let t=$?.instance;if(!G||!t||t!==I.current||y||f||ty.current?.instance===t&&ty.current?.premiumAccess===w)return;ty.current={instance:t,premiumAccess:w};let e=(0,tH.JX)();(0,tH.Vn)(e,w)&&t4(e)},[$,G,y,f,w,t4]),(0,g.useEffect)(()=>{let t=I.current;G&&t&&t.isStyleLoaded()&&(!W||tq||t.getSource("railway")?(!W||tq)&&(t.getLayer("railway-layer")&&t.removeLayer("railway-layer"),t.getSource("railway")&&t.removeSource("railway")):(t.addSource("railway",{type:"raster",tiles:["https://a.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png"],tileSize:256}),t.addLayer({id:"railway-layer",type:"raster",source:"railway",paint:{"raster-opacity":.6}},t.getLayer("station-points")?"station-points":"train-halo")))},[G,O,W,tq]),(0,g.useEffect)(()=>{if(G&&I.current&&!tq&&(tt||ta))return function(t,e,a,i,{showMajorStations:n=!0,showMinorStations:s=!0}={}){let r=["any",["==",["get","is_major"],!0],["==",["get","place_kind"],"complex"],["==",["slice",["to-string",["get","id"]],0,6],"group:"]],o=["all",["!",["any",["in",["get","id"],["literal",ej.map(t=>`group:${t.id}`)]],["in",["concat",["get","network"],":",["to-string",["get","stop_id"]]],["literal",ej.flatMap(t=>t.members.map(t=>`${t.network}:${t.stop_id}`))]]]],["any",["all",r,n],["all",["!",r],s,[">=",["zoom"],10]]]],l=new AbortController,c=["station-labels","station-points"],g=e=>{if(t.getLayer("train-points")&&t.queryRenderedFeatures(e.point,{layers:["train-points"]}).length)return;let i=e.features?.[0],{id:n,station_id:s,network:r,stop_id:o,stop_name:l,network_name:c,network_color:g,city_slugs:d}=i?.properties||{};if(!s&&(!r||!o))return;let h=i.geometry?.coordinates||[e.lngLat.lng,e.lngLat.lat];a?.({id:n,stationId:s,network:r,stopId:o,stopName:l,networkName:c,networkColor:g,citySlugs:d,lng:h[0],lat:h[1]})},d=()=>{t.getCanvas().style.cursor="pointer"},h=()=>{t.getCanvas().style.cursor=""},m=[];if(n){t.addSource("major-stations-overview",{type:"geojson",data:{type:"FeatureCollection",features:ej.map(t=>({type:"Feature",geometry:{type:"Point",coordinates:[t.longitude,t.latitude]},properties:{id:`group:${t.id}`,stop_name:t.name,network:t.members[0].network,stop_id:t.members[0].stop_id}}))}}),t.addLayer({id:"major-stations-overview-points",type:"circle",source:"major-stations-overview",minzoom:4,paint:{"circle-radius":5,"circle-color":"#4b5563","circle-stroke-color":"#000000","circle-stroke-width":2}},"train-halo"),m.push("major-stations-overview-points");let a=t.getStyle()?.glyphs;a&&(t.addLayer({id:"major-stations-overview-labels",type:"symbol",source:"major-stations-overview",minzoom:4,layout:{"text-field":["get","stop_name"],"text-font":a.startsWith("mapbox:")?["DIN Pro Medium","Arial Unicode MS Regular"]:["Noto Sans Regular"],"text-size":12,"text-anchor":"top","text-offset":[0,.9],"text-max-width":14},paint:{"text-color":"dark"===e?"#ffffff":"#111827","text-halo-color":"dark"===e?"#111827":"#ffffff","text-halo-width":2}},"train-halo"),m.push("major-stations-overview-labels")),t.on("click",m,g),t.on("mouseenter",m,d),t.on("mouseleave",m,h)}return fetch("https://storage.googleapis.com/trainsfyi-vector-tiles-central/_stations/manifest.json",{signal:l.signal}).then(t=>t.ok?t.json():null).then(a=>{!l.signal.aborted&&a?.tiles?.length&&(t.addSource("stations",{type:"vector",tiles:a.tiles,minzoom:a.minzoom,maxzoom:a.maxzoom,promoteId:"id"}),t.addLayer({id:"station-halo",type:"circle",source:"stations","source-layer":"stations",minzoom:a.minzoom,filter:["==",["get","id"],""],paint:{"circle-radius":["interpolate",["linear"],["zoom"],8,["case",r,9,6],14,["case",r,15,12]],"circle-color":["to-color",["get","network_color"],"#64748b"],"circle-opacity":["step",["zoom"],["case",["all",r,n],.25,0],10,["case",["any",["all",r,n],["all",["!",r],s]],.25,0]]}},"train-halo"),t.addLayer({id:"station-points",type:"circle",source:"stations",filter:o,"source-layer":"stations",minzoom:a.minzoom,paint:{"circle-radius":["interpolate",["linear"],["zoom"],8,["case",r,4,2],14,["case",r,7,4.5]],"circle-color":["case",r,"#4b5563","dar
1k"===e?"#0f172a":"#ffffff"],"circle-stroke-color":["case",r,"#000000",["to-color",["get","network_color"],"#64748b"]],"circle-stroke-width":2}},"train-halo"),t.getStyle()?.glyphs&&t.addLayer({id:"station-labels",type:"symbol",source:"stations","source-layer":"stations",minzoom:a.minzoom,filter:["all",o,["any",r,[">=",["zoom"],12]]],layout:{"text-field":["get","stop_name"],"text-font":t.getStyle().glyphs.startsWith("mapbox:")?["DIN Pro Medium","Arial Unicode MS Regular"]:["Noto Sans Regular"],"text-size":11,"text-anchor":"top","text-offset":["case",r,["literal",[0,1]],["literal",[0,.7]]],"text-max-width":12},paint:{"text-color":"dark"===e?"#e2e8f0":"#334155","text-halo-color":"dark"===e?"#0f172a":"#ffffff","text-halo-width":1.5}},"train-halo"),t.on("click",c,g),t.on("mouseenter",c,d),t.on("mouseleave",c,h),i?.())}).catch(t=>{"AbortError"!==t.name&&console.warn("Station tiles unavailable",t)}),()=>{l.abort(),t.off("click",c,g),t.off("mouseenter",c,d),t.off("mouseleave",c,h),m.length&&(t.off("click",m,g),t.off("mouseenter",m,d),t.off("mouseleave",m,h));try{if(!t.getStyle())return}catch{return}["station-labels","station-points","station-halo"].forEach(e=>{t.getLayer(e)&&t.removeLayer(e)}),m.slice().reverse().forEach(e=>{t.getLayer(e)&&t.removeLayer(e)}),t.getSource("major-stations-overview")&&t.removeSource("major-stations-overview"),t.getSource("stations")&&t.removeSource("stations")}}(I.current,tn,t1,()=>{let t=E.current,e=t?t.id||t.stationId||`${t.network}:${t.stopId}`:"";I.current?.getLayer("station-halo")&&I.current.setFilter("station-halo",["==",["get","id"],e])},{showMajorStations:tt,showMinorStations:ta})},[G,O,tn,t1,k,tt,ta,tq]),(0,g.useEffect)(()=>{let t=I.current;if(!G||!t||!H||!w||tq)return;let e=new AbortController;return X(""),fetch(tH.yq,{signal:e.signal}).then(t=>{if(!t.ok)throw Error("Train routes are unavailable. Please try again.");return t.json()}).then(a=>{if(e.signal.aborted)return;t.addSource("trainsfyi-networks",(0,tH.pV)(a));let i=t.getStyle().layers.find(t=>"symbol"===t.type)?.id||"train-halo";t.addLayer({id:"trainsfyi-networks",type:"raster",source:"trainsfyi-networks",paint:{"raster-opacity":1,"raster-fade-duration":0}},i)}).catch(t=>{e.signal.aborted||X(t.message||"Could not load train routes.")}),()=>{e.abort();try{t.getLayer("trainsfyi-networks")&&t.removeLayer("trainsfyi-networks"),t.getSource("trainsfyi-networks")&&t.removeSource("trainsfyi-networks")}catch{}}},[G,O,H,w,tq]),(0,g.useEffect)(()=>{if(G&&I.current){var t;let e,a,i,n,s;return t=I.current,e="trainsfyi-3d-buildings",(i="trainsfyi-buildings"==(a=t.getSource("openmaptiles")?"openmaptiles":"trainsfyi-buildings"))&&t.addSource(a,{type:"vector",url:"https://tiles.openfreemap.org/planet"}),n=t.getStyle().layers.find(t=>"symbol"===t.type)?.id||"train-halo",t.addLayer({id:e,type:"fill-extrusion",source:a,"source-layer":"building",minzoom:13,filter:["!=",["get","hide_3d"],!0],layout:{visibility:t.getPitch()>0?"visible":"none"},paint:{"fill-extrusion-color":"dark"===tn?"#64748b":"#cbd0d6","fill-extrusion-height":["coalesce",["get","render_height"],12],"fill-extrusion-base":["coalesce",["get","render_min_height"],0],"fill-extrusion-opacity":.85}},n),s=()=>{t.getLayer(e)&&t.setLayoutProperty(e,"visibility",t.getPitch()>0?"visible":"none")},t.on("pitch",s),()=>{t.off("pitch",s);try{t.getLayer(e)&&t.removeLayer(e),i&&t.getSource(a)&&t.removeSource(a)}catch{}}}},[G,O,tn]),(0,g.useEffect)(()=>{if(!G||!I.current)return;M.current?.sync(tD,performance.now());let e=new Map,a=new Map,i=tD.map(i=>{let n=eS(i),s=tE.get(i.agency?.toLowerCase()),r=(0,e_.IR)(i,s?.color||"#1f2937",t),o=s?.darkerColor||"#111827",l=function(t,e){if(null!=t.dir&&""!==String(t.dir).trim()&&Number.isFinite(Number(t.dir)))return(Number(t.dir)%360+360)%360;if(t.freight?.source)return null;if(e&&(t.lat!==e.lat||t.lng!==e.lng)){let a=Math.PI/180,i=e.lat*a,n=t.lat*a,s=(t.lng-e.lng)*a;return(Math.atan2(Math.sin(s)*Math.cos(n),Math.cos(i)*Math.sin(n)-Math.sin(i)*Math.cos(n)*Math.cos(s))/a+360)%360}return e?.bearing??null}(i,L.current.get(n)),c=M.current?.positionOf(n);a.set(n,{lat:i.lat,lng:i.lng,bearing:l});let g={type:"Feature",geometry:{type:"Point",coordinates:c?[c.lng,c.lat]:[i.lng,i.lat]},properties:{id:n,color:r,borderColor:o,bearing:l??0,heading_known:null!=l,markerScale:function(t,e){let a=t8.L[t.vt]?.classification;if(["monorail","funicular","cable_car","people_mover"].includes(a))return .65;let i=t7(t,e);if("national"===i||"regional"===i||"freight"===i)return 1;if("other"!==i)return .65;let n=(e?.vehicleClassificationOverride||"").replace(/-/g,"_");return"heavy_rail_default"===a||["rail","train","heavy_rail","freight","freight_rail"].includes(n)||"freight"===t.vt?1:.65}(i,s),icon:ex(I.current,r,o,null!=l)}};return e.set(n,g),g}),n=A.current.has(z.current);A.current=e,L.current=a,T.current={type:"FeatureCollection",features:i},I.current.getSource("trains")?.setData(T.current),(0,eu.pt)(i.map((t,e)=>({...t,geometry:{type:"Point",coordinates:[tD[e].lng,tD[e].lat]}}))),n&&!e.has(z.current)&&tf(null)},[G,O,tD,tE,t]),(0,g.useEffect)(()=>{let t;if(h||!G||!I.current)return;let e=performance.now(),a=0,i=!1,n=s=>{let r;if(i)return;t=requestAnimationFrame(n);let o=I.current;if(!o)return;if(o.isMoving()||document.hidden){e=s;return}let l=(r=o.getZoom())<5?500:r<9?100:50,c=s-e;if(c<l)return;let g=o.getSource("trains");if(!g)return;let d=0;M.current?.step(s,c,(t,e,a)=>{let i=A.current.get(t);i&&(i.geometry.coordinates[0]=e,i.geometry.coordinates[1]=a,d+=1)}),e=s,d>0&&g.setData(T.current);let h=R.current;if(h&&z.current===h.id&&s-a>=1e3){let t=A.current.get(h.id)?.geometry.coordinates,e=(0,ef.D)(h.detail,t);e&&I.current?.getSource("selected-route")?.setData({type:"FeatureCollection",features:[{type:"Feature",geometry:e,properties:{color:ew.l4.color}}]}),a=s}};return t=requestAnimationFrame(n),()=>{i=!0,cancelAnimationFrame(t)}},[h,G,O]),(0,g.useEffect)(()=>{G&&I.current?.getLayer("train-points")&&I.current.setFilter("train-points",tq?["==",["get","id"],tb]:null)},[G,O,tq,tb]),(0,g.useEffect)(()=>{G&&I.current&&I.current.getLayer("train-halo")&&I.current.setFilter("train-halo",["==",["get","id"],tb||""])},[G,O,tb]),(0,g.useEffect)(()=>
1{if(!G||!I.current)return;let t=tv?tv.id||tv.stationId||`${tv.network}:${tv.stopId}`:"";I.current.getLayer("station-halo")&&I.current.setFilter("station-halo",["==",["get","id"],t])},[G,O,tv]),(0,g.useEffect)(()=>{if(!G||!I.current)return;let e=I.current.getSource("selected-route");if(!e)return;for(let t of["selected-route-line","selected-route-casing"])I.current.setPaintProperty(t,"line-dasharray",tJ?.freight?.source?[2,2]:[1,0]);let a=()=>{R.current=null,M.current?.setSelectedShape(null,null),I.current?.getSource("selected-route")===e&&e.setData({type:"FeatureCollection",features:[]})};if(tJ?.agency==="freight")return a(),(tY?.predicted_route?.length||tY?.observed_route?.length)&&(R.current={id:eS(tJ),detail:tY},e.setData({type:"FeatureCollection",features:[{type:"Feature",geometry:(0,ef.D)(tY,A.current.get(eS(tJ))?.geometry.coordinates),properties:{color:ew.l4.color}}]})),a;let i=tJ?.gtfs?.shape_id;if(!tJ||!i)return void a();let n=!1,s=(0,e_.IR)(tJ,tZ?.color||"#1d4ed8",t);return fetch(`${S.QU}/api/v3/${tJ.agency}/shapes/${encodeURIComponent(i)}/`).then(t=>t.ok?t.json():null).then(t=>{!n&&t?.geojson&&(M.current?.setSelectedShape(eS(tJ),t.geojson),e.setData({type:"FeatureCollection",features:[{type:"Feature",geometry:t.geojson,properties:{color:s}}]}))}).catch(()=>{}),()=>{n=!0,a()}},[G,O,tJ,tZ,tY,t]),(0,g.useEffect)(()=>{if(!G||!I.current||!tJ||!h&&C.current===`train:${eC(tJ.agency,tJ.vid)}`)return;h&&I.current.resize();let t=window.matchMedia("(min-width: 1024px)").matches;I.current.easeTo({center:A.current.get(eS(tJ))?.geometry.coordinates||[tJ.lng,tJ.lat],zoom:Math.max(I.current.getZoom(),6),padding:h?{top:0,bottom:0,left:0,right:0}:t?{right:380,top:0,bottom:0,left:0}:{bottom:Math.max(0,Math.min(.68*window.innerHeight,I.current.getContainer().clientHeight-100)),top:0,left:0,right:0},duration:700})},[h,G,O,tV]),(0,g.useEffect)(()=>{if(!G||!I.current||!tv||C.current===`station:${o(tv)}`||!Number.isFinite(tv.lng)||!Number.isFinite(tv.lat))return;let t=window.matchMedia("(min-width: 1024px)").matches;I.current.easeTo({center:[tv.lng,tv.lat],padding:t?{right:380,top:0,bottom:0,left:0}:{bottom:Math.max(0,Math.min(.68*window.innerHeight,I.current.getContainer().clientHeight-100)),top:0,left:0,right:0},duration:700})},[G,O,tv]);let t3=tB.length,t6=(0,g.useMemo)(()=>new Set(tB.map(t=>t.agency)).size,[tB]);return(0,i.jsxs)("div",{"data-testid":h?"late-list-render":void 0,className:`relative flex h-full w-full overflow-hidden ${"dark"===tn?"bg-gray-950":"bg-[#eaeef2]"}`,children:[(0,i.jsx)("div",{ref:N,"data-testid":h?"late-list-map":void 0,className:h?"h-full min-w-0 flex-1":"h-full w-full"}),h&&(0,i.jsxs)("div",{className:"pointer-events-none absolute left-4 top-4 z-10 flex flex-col items-center rounded-xl bg-blue-800 px-3 py-2 shadow-lg",children:[(0,i.jsx)("img",{src:Z.A.src,alt:"trains.fyi logo",className:"h-8 w-auto"}),(0,i.jsx)("span",{className:"mt-0.5 text-base font-bold tracking-tight text-white",children:"trains.fyi"})]}),!h&&(0,i.jsx)(i.Fragment,{children:(0,i.jsx)("div",{className:"pointer-events-none absolute right-3 top-3 z-10 max-w-[calc(100%-180px)] lg:left-3 lg:right-auto lg:max-w-none",children:(0,i.jsxs)("div",{className:"pointer-events-auto inline-flex max-w-full items-center gap-2.5 rounded-full bg-white/95 py-1.5 pl-3 pr-4 shadow-lg ring-1 ring-black/5 backdrop-blur",children:[(0,i.jsxs)("span",{className:"relative flex h-2 w-2","aria-hidden":"true",children:[(0,i.jsx)("span",{className:"absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-400 opacity-75 motion-reduce:animate-none"}),(0,i.jsx)("span",{className:"relative inline-flex h-2 w-2 rounded-full bg-emerald-500"})]}),(0,i.jsx)("p",{className:"truncate text-xs font-semibold tabular-nums text-gray-900",children:tN&&!t3?"Loading live trainsâ¦":(0,i.jsxs)(i.Fragment,{children:[t3.toLocaleString(),tg.length<t5.length?` / ${t$.length.toLocaleString()} trains shown`:" trains live",(0,i.jsxs)("span",{className:"ml-1.5 hidden font-normal text-gray-500 min-[430px]:inline",children:["\xb7 ",t6," networks"]})]})})]})})}),!h&&(0,i.jsxs)("div",{className:"pointer-events-none absolute inset-x-0 top-3 z-10 flex flex-col items-start gap-3 px-3 lg:items-center lg:px-4",children:[(0,i.jsxs)("div",{className:`flex items-center gap-2 rounded-full py-2 pl-2.5 pr-4 shadow-lg ring-1 backdrop-blur ${"dark"===tn?"bg-gray-900/90 text-white ring-white/15":"bg-white/95 text-blue-900 ring-black/5"}`,children:[(0,i.jsx)("img",{src:Z.A.src,alt:"",className:"h-8 w-auto"}),(0,i.jsx)("span",{className:"text-base font-bold tracking-tight",children:"trains.fyi"})]}),(0,i.jsx)("div",{className:"ml-14 w-[calc(100%-3.5rem)] max-w-md lg:absolute lg:right-3 lg:top-0 lg:ml-0 lg:w-[calc(50%-7rem)]",children:(0,i.jsx)(em,{floating:!0})})]}),!h&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(en,{map:G?$?.instance:null,renderer:$?.renderer,enabled:q&&w&&!tq,styleVersion:O,panelOpen:!!tJ||!!tv}),(0,i.jsx)(et,{slowdowns:q&&w,setSlowdowns:Y,renderer:$?.renderer,signedIn:!!p,isPremium:w,accessLoading:y||f,returnUrl:e.asPath,map:$?.instance,theme:tn,onThemeChange:t4,themeLoading:tr||!G,themeError:tl,enabled:tg,setEnabled:th,counts:tF,showMajorStations:tt,setShowMajorStations:te,railway:W,setRailway:J,trainRoutes:H&&w,setTrainRoutes:V,trainRoutesError:Q,panelOpen:!!tJ||!!tv}),(0,i.jsx)(es,{})]}),!h&&(tJ||tv)&&(0,i.jsxs)("div",{className:"absolute bottom-[calc(68dvh+12px)] right-3 z-20 flex flex-col gap-2 lg:bottom-auto lg:right-[380px] lg:top-3",children:[(0,i.jsx)("button",{type:"button","aria-label":tJ?"Locate selected train":"Locate selected station",title:tJ?"Locate train":"Locate station",onClick:()=>{let t=I.current;if(!t||!G)return;let e=tJ?A.current.get(eS(tJ))?.geometry.coordinates||[tJ.lng,tJ.lat]:[tv?.lng,tv?.lat];if(!e.every(Number.isFinite))return;let a=window.matchMedia("(min-width: 1024px)").matches;t.easeTo({center:e,zoom:Math.max(t.getZoom(),tv?15:14),padding:a?{right:380,top:0,bottom:0,left:0}:{bottom:Math.max(0,Math.min(.68*window.innerHeight,t.getContainer().clientHeight-100)),top:0,left:0,right:0},duration:700*!window.matchMedia("(prefers-reduced-motion: reduce)").matches})},disabled:!G||!tJ&&(!Number.isFinite(tv?.lng)||!Number.isFinite(tv?.lat)),className:"flex h-11 w-11 items-center justify-center rounded-full bg-white text-gray-600 shadow-lg ring-1 ring-black/5 hover:bg-gray-50 hover:text-gray-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-800 disabled:opacity-40",children:(0,i.jsx)(d.jo6,{className:"h-5 w-5","aria-hidden":"true"})}),tJ&&(0,i.jsx)("button",{type:"button","aria-label":tq?"Show all trains":"Isolate selected train",title:tq?"Turn off journey isolation":"Isolate train and journey","aria-pressed":tq,onClick:()=>tx(tq?null:tb),disabled:!G,className:`flex h-11 w-11 items-center justify-center rounded-full shadow-lg ring-1 ring-black/5 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-800 disabled:opacity-40 ${tq?"bg-blue-800 text-white hover:bg-blue-900":"bg-white text-gray-600 hover:bg-gray-50 hover:text-gray-900"}`,children:(0,i.jsxs)("svg",{className:"h-5 w-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[(0,i.jsx)("path",{d:"m3 6 3-3 6 6-3 3Z"}
1),(0,i.jsx)("path",{d:"m12 9 9 4-8 8-4-9",fill:"currentColor",fillOpacity:"0.12"}),(0,i.jsx)("path",{d:"M6 10v10M3 20h6"})]})})]}),!h&&!tJ&&!tv&&!m&&(0,i.jsx)(ed,{onDismiss:()=>u(!0)}),tJ&&(0,i.jsx)(tW,{map:G?$?.instance:null,styleVersion:O,train:tJ,network:tZ,theme:tn},tb),(0,i.jsx)(t_,{train:tJ,network:tZ,onClose:tX,onSelectStation:t1,docked:h}),(0,i.jsx)(tK,{station:tv,network:tQ,onClose:t0,onStopResolved:t2,trainForCall:G?tG:void 0,onSelectTrain:tO})]})}},28168:(t,e,a)=>{"use strict";a.d(e,{A:()=>s});var i=a(31198),n=a.n(i);"unavailable"===n().getRTLTextPluginStatus()&&n().setRTLTextPlugin("/vendor/mapbox-gl-rtl-text/0.2.3.min.js",!0).catch(t=>console.error("Unable to initialize right-to-left map labels",t));let s=n()},35176:(t,e,a)=>{"use strict";a.d(e,{A:()=>n});var i=a(37876);function n({train:t}){let e="gps"===t.position_source;return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("p",{className:"mt-5 text-sm text-gray-600",children:e?"GPS position reported by the railway. The marker stays at the latest fix until a new report arrives.":"Last reported railway location. The train may have moved since this report; its position between reporting points is unknown."}),(0,i.jsxs)("dl",{className:"mt-5 space-y-4 text-sm",children:[(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Direction of travel"}),(0,i.jsx)("dd",{children:Number.isFinite(t.current_bearing)?`${Math.round(t.current_bearing)}\xb0 \xb7 estimated from ${e?"recent GPS fixes":"successive reporting locations"}`:"Unknown â waiting for movement between reports"})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Last reported"}),(0,i.jsx)("dd",{children:new Date(t.last_seen).toLocaleString()})]}),t.location_name&&(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Reporting location"}),(0,i.jsx)("dd",{children:t.location_name})]}),Number.isFinite(t.effective_speed_kmh)&&(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Reported speed"}),(0,i.jsxs)("dd",{children:[Math.round(t.effective_speed_kmh)," km/h"]})]}),t.operator&&(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Operator code"}),(0,i.jsx)("dd",{children:t.operator})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Report expires"}),(0,i.jsx)("dd",{children:new Date(t.valid_until).toLocaleTimeString()})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Position history"}),(0,i.jsxs)("dd",{children:[t.history_count||1," reports",t.history_since?` since ${new Date(t.history_since).toLocaleTimeString()}`:""]})]}),(0,i.jsxs)("div",{children:[(0,i.jsx)("dt",{className:"text-gray-500",children:"Source"}),(0,i.jsxs)("dd",{children:[(0,i.jsx)("a",{className:"text-blue-800 underline",href:t.source_url,target:"_blank",rel:"noreferrer",children:t.source_name}),"banenor"===t.source?(0,i.jsxs)(i.Fragment,{children:[" \xb7 ",(0,i.jsx)("a",{className:"underline",href:"https://data.norge.no/nlod/en/1.0",target:"_blank",rel:"noreferrer",children:"Norwegian Licence for Open Government Data (NLOD)"})]}):e?" \xb7 CC BY 4.0":" \xb7 Open Government Licence"]})]})]}),(0,i.jsx)("p",{className:"mt-4 text-xs text-gray-500",children:"The dashed trail joins recorded positions from the last three hours. It does not show the exact track between reports. Gaps mark missing data or location corrections."}),"banenor"===t.source&&(0,i.jsxs)("p",{className:"mt-4 text-xs text-gray-500",children:["Contains data under NLOD distributed by Bane NOR. Station coordinates are extracted from ",(0,i.jsx)("a",{className:"underline",href:"https://data.norge.no/en/datasets/e30d98a2-0edf-4fb3-b71d-dd8819410c9c/jernbane-banenettverk",target:"_blank",rel:"noreferrer",children:"Bane NORâs railway network dataset"}),"; headings and trails are calculated by trains.fyi. Reports may be sparse; unconfirmed schedules are omitted."]}),"networkrail"===t.source&&(0,i.jsxs)("p",{className:"mt-4 text-xs text-gray-500",children:["Reporting-point coordinates: ",(0,i.jsx)("a",{className:"underline",href:"https://github.com/davwheat/YATIPLOCL#data-sources",target:"_blank",rel:"noreferrer",children:"YATIPLOCL and its contributing sources"}),"."]})]})}},37249:(t,e,a)=>{"use strict";a.d(e,{A:()=>m});var i=a(37876),n=a(14232),s=a(372),r=a(25620),o=a(21081),l=a(45434),c=a(12921),g=a(1300);let d=function({getUser:t,writeFeedback:e,writeGuestFeedback:a,timestamp:i}){let n=!1;return async({message:s,isPremium:r=!1,pagePath:o="",email:l=""})=>
1{if(n)throw Error("A message is already being sent.");let c=t(),g=c?.email||("string"==typeof l?l.trim():"");if((!c?.uid||!c.email)&&(g.length>254||!/^[^\s@<>]+@[^\s@<>]+\.[^\s@<>]+$/.test(g)))throw Error("Enter a valid email address.");let d="string"==typeof s?s.trim():"";if(!d)throw Error("Write a message before sending.");if(Array.from(d).length>1e3)throw Error("Keep your message to 1,000 characters.");n=!0;try{if(!c?.uid)return void await a({message:d,email:g,pagePath:o});await e({userId:c.uid,email:g,displayName:c.displayName||null,message:d,isPremium:!0===r,appVersion:"web",platform:"web",createdAt:i(),pagePath:o})}finally{n=!1}}}({getUser:()=>g.j.currentUser,writeFeedback:t=>(0,l.gS)((0,l.rJ)(g.db,"feedback"),t),writeGuestFeedback:async t=>{await (0,c.Qg)((0,c.Uz)(g.A,"us-central1"),"submitGuestFeedback",{timeout:3e4})(t)},timestamp:l.O5}),h="trainsfyi-feedback-draft";function m(){let{user:t,loading:e}=(0,r.A)(),{isPremium:a}=(0,o.x)(),[l,c]=(0,n.useState)(""),[g,m]=(0,n.useState)(""),[u,p]=(0,n.useState)(!1),[y,b]=(0,n.useState)(!1),[f,w]=(0,n.useState)(!1),[x,_]=(0,n.use
1State)(""),v=(0,n.useRef)(!1),j=(0,n.useId)();async function k(t){if(t.preventDefault(),!v.current&&!e&&l.trim()){v.current=!0,b(!0),_("");try{await d({message:l,email:g,isPremium:a,pagePath:window.location.pathname});try{sessionStorage.removeItem(h)}catch{}c(""),w(!0)}catch(t){_(t?.code==="functions/resource-exhausted"?"Too many messages. Please try again in 15 minutes.":"Couldnât send your message. Please check your connection and try again. Your draft is still here.")}finally{v.current=!1,b(!1)}}}return(0,n.useEffect)(()=>{try{c(sessionStorage.getItem(h)||"")}catch{}p(!0)},[]),f?(0,i.jsxs)("div",{role:"status",className:"py-5 text-center",children:[(0,i.jsx)(s.A,{"aria-hidden":"true",className:"mx-auto h-12 w-12 text-emerald-600"}),(0,i.jsx)("h2",{className:"mt-4 text-lg font-semibold text-slate-950",children:"Thanks for the feedback!"}),(0,i.jsx)("p",{className:"mt-2 text-sm leading-6 text-slate-600",children:"Iâll take a look and get back to you if needed."}),(0,i.jsx)("button",{type:"button",onClick:()=>w(!1),className:"mt-5 rounded-lg px-3 py-2 text-sm font-semibold text-blue-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-600",children:"Send another message"})]}):(0,i.jsxs)("form",{onSubmit:k,className:"space-y-4","aria-busy":y,children:[(0,i.jsx)("p",{className:"text-sm leading-6 text-slate-600",children:"Got a bug, suggestion, or anything else? I read every message."}),(0,i.jsxs)("div",{children:[(0,i.jsx)("label",{htmlFor:`${j}-message`,className:"block text-sm font-semibold text-slate-900",children:"Your message"}),(0,i.jsx)("textarea",{id:`${j}-message`,required:!0,value:l,disabled:!u||y,onChange:t=>(function(t){let e=Array.from(t).slice(0,1e3).join("");c(e);try{sessionStorage.setItem(h,e)}catch{}})(t.target.value),rows:6,placeholder:"Whatâs on your mind?","aria-describedby":`${j}-count`,className:"mt-2 block w-full resize-y rounded-xl border-slate-300 text-base focus:border-blue-600 focus:ring-blue-600 disabled:opacity-60"}),(0,i.jsxs)("p",{id:`${j}-count`,className:"mt-2 text-right text-xs tabular-nums text-slate-500",children:[Array.from(l).length,"/",1e3]})]}),x&&(0,i.jsx)("p",{role:"alert",className:"rounded-lg bg-red-50 p-3 text-sm leading-6 text-red-800",children:x}),!e&&!t?.email&&(0,i.jsxs)("div",{children:[(0,i.jsx)("label",{htmlFor:`${j}-email`,className:"block text-sm font-semibold text-slate-900",children:"Your email"}),(0,i.jsx)("input",{id:`${j}-email`,type:"email",autoComplete:"email",required:!0,maxLength:254,value:g,disabled:y,onChange:t=>m(t.target.value),className:"mt-2 block w-full rounded-xl border-slate-300 text-base focus:border-blue-600 focus:ring-blue-600 disabled:opacity-60"}),(0,i.jsx)("p",{className:"mt-2 text-xs leading-5 text-slate-500",children:"So we can reply to your message."})]}),t?.email&&(0,i.jsxs)("p",{className:"text-xs leading-5 text-slate-500",children:["Reply to ",t.email]}),(0,i.jsx)("button",{type:"submit",disabled:!u||e||y||!l.trim(),className:"min-h-11 w-full rounded-xl bg-blue-800 px-4 py-3 text-sm font-semibold text-white hover:bg-blue-900 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 disabled:cursor-not-allowed disabled:opacity-50",children:y?"Sendingâ¦":"Send message"})]})}},42891:(t,e,a)=>{"use strict";a.d(e,{b:()=>h,o:()=>g});var i=a(75656),n=a(14232),s=a(57090),r=a(45434),o=a(22128),l=a(1300);async function c(t){let e=await fetch(t);if(!e.ok)throw Error("Freight details are unavailable");return e.json()}function g(t){return(0,i.Ay)(t?`/api/freight/trains/${encodeURIComponent(t)}`:null,c,{refreshInterval:3e4,revalidateOnFocus:!1,shouldRetryOnError:!1})}async function d([,t,e]){for(let a of t)try{if(a.startsWith("camera:")){let t=a.split(":")[1],e=await c(`/api/sightings/${encodeURIComponent(t)}`),i=e.file_urls?.frame||e.file_urls?.gif;if(i)return{url:i,caption:e.camera_name||"Camera sighting",href:`/sightings?id=${encodeURIComponent(t)}`}}else if(a.startsWith("user:")){if(!e||l.j.currentUser?.uid!==e)continue;let t=(await (0,r.x7)((0,r.H9)(l.db,"sightings",a.slice(5)))).data(),i=t?.photoStoragePaths?.[0]||t?.photoStoragePath;if(i&&"approved"===t.photoStatus)return{url:await (0,o.qk)((0,o.KR)((0,o.c7)(l.A),i)),caption:"Original sighting photo"}}}catch{}return null}
1function h(t){let[e,a]=(0,n.useState)(null);(0,n.useEffect)(()=>(0,s.hg)(l.j,t=>a(t?.uid||null)),[]);let r=[...new Set((t?.sightings||[]).map(t=>t.source_id||(t.description?.match(/trainspotter id=([a-zA-Z0-9_]+)/)?.[1]?`camera:${t.description.match(/trainspotter id=([a-zA-Z0-9_]+)/)[1]}`:null)).filter(Boolean))];return(0,i.Ay)(r.length?["freight-sighting-photo",r,e]:null,d,{revalidateOnFocus:!1,shouldRetryOnError:!1})}},71904:t=>{t.exports={shimmer:"loadingShimmer_shimmer__tXxCy"}},73093:(t,e,a)=>{"use strict";a.d(e,{K:()=>l,V:()=>c});let i=t=>t*Math.PI/180,n=t=>180*t/Math.PI,s=(t,e,a,n)=>{let s=i(t),r=i(a),o=i(a-t),l=i(n-e),c=Math.sin(o/2)*Math.sin(o/2)+Math.cos(s)*Math.cos(r)*Math.sin(l/2)*Math.sin(l/2);return 2*Math.atan2(Math.sqrt(c),Math.sqrt(1-c))*6371e3},r=(t,e,a,s)=>{let r=i(t),o=i(e),l=i(a),c=i(s);return(n(Math.atan2(Math.sin(c-o)*Math.cos(l),Math.cos(r)*Math.sin(l)-Math.sin(r)*Math.cos(l)*Math.cos(c-o)))+360)%360},o=(t,e,a,o,l,c)=>{let g=s(a,o,t,e),d=s(l,c,t,e),h=i(r(a,o,l,c)),m=i(r(a,o,t,e));if(0>Math.cos(m-h))return{lat:a,lon:o,distance:g};let u=i(r(l,c,a,o));if(0>Math.cos(i(r(l,c,t,e))-u))return{lat:l,lon:c,distance:d};let p=g/6371e3,y=Math.asin(Math.sin(p)*Math.sin(m-h)),b=Math.acos(Math.cos(p)/Math.cos(y)),f=i(a),w=i(o),x=Math.asin(Math.sin(f)*Math.cos(b)+Math.cos(f)*Math.sin(b)*Math.cos(h)),_=Math.atan2(Math.sin(h)*Math.sin(b)*Math.cos(f),Math.cos(b)-Math.sin(f)*Math.sin(x));return{lat:n(x),lon:n(w+_),distance:Math.abs(6371e3*y)}},l=async(t,e)=>{if(!t.shape_points||0===t.shape_points.length)throw Error("No shape data available for this trip");let a=t.shape_points.sort((t,e)=>t.shape_pt_sequence-e.shape_pt_sequence),i=1/0,n=null,r=-1;for(let t=0;t<a.length-1;t++){let s=o(e.position.lat,e.position.lon,a[t].shape_pt_lat,a[t].shape_pt_lon,a[t+1].shape_pt_lat,a[t+1].shape_pt_lon);s.distance<i&&(i=s.distance,n=s,r=t)}if(i>500)throw Error(`Train is significantly off the expected route (${i.toFixed(0)}m)`);let l=Array(a.length);l[0]=0;for(let t=1;t<a.length;t++)l[t]=l[t-1]+s(a[t-1].shape_pt_lat,a[t-1].shape_pt_lon,a[t].shape_pt_lat,a[t].shape_pt_lon);let c=l[a.length-1],g=l[r]+s(a[r].shape_pt_lat,a[r].shape_pt_lon,n.lat,n.lon),d=g/c,h=t.stop_times.map(t=>{let e=t.stop,i=1/0,n=0;for(let t=0;t<a.length-1;t++){let r=o(e.stop_lat,e.stop_lon,a[t].shape_pt_lat,a[t].shape_pt_lon,a[t+1].shape_pt_lat,a[t+1].shape_pt_lon);r.distance<i&&(i=r.distance,n=(l[t]+s(a[t].shape_pt_lat,a[t].shape_pt_lon,r.lat,r.lon))/c)}return{stop:e,progress:n,distanceToRoute:i}}).sort((t,e)=>t.progress-e.progress),m=h.find(({stop:t})=>100>=s(e.position.lat,e.position.lon,t.stop_lat,t.stop_lon)),u=-1;m?u=h.findIndex(t=>t.stop.stop_id===m.stop.stop_id):-1!==(u=h.slice().reverse().findIndex(t=>t.progress<d))&&(u=h.length-1-u);let p=h.slice(0,u+1).map(t=>t.stop),y=h.slice(u+1).map(t=>t.stop),b=null,f=u>-1?h[u]:null,w=u+1<h.length?h[u+1]:null;if(f&&w&&w.progress>f.progress){let t=d-f.progress,e=w.progress-f.progress;b={percent:e>0?t/e:0,distance:t*c/1e3,totalDistance:e*c/1e3}}return{previousStops:p,nextStops:y,trainIsAtStop:m?.stop||null,progressAlongTotalRoute:{percent:d,distance:g/1e3,totalDistance:c/1e3},progressBetweenStops:b}},c=async t=>{try{return t.stop_times.sort((t,e)=>t.stop_sequence-e.stop_sequence).map(t=>t.stop)}catch(t){throw console.error("Error fetching stops in order:",t),t}}}}]);
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.