1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[636],{250:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"useIntersection",{enumerable:!0,get:function(){return l}});let i=r(14232),n=r(41241),a="function"==typeof IntersectionObserver,s=new Map,o=[];function l({rootRef:e,rootMargin:t,disabled:r}){let u=r||!a,[c,h]=(0,i.useState)(!1),d=(0,i.useRef)(null),m=(0,i.useCallback)(e=>{d.current=e},[]);return(0,i.useEffect)(()=>{if(a){if(u||c)return;let r=d.current;if(r&&r.tagName)return function(e,t,r){let{id:i,observer:n,elements:a}=function(e){let t,r={root:e.root||null,margin:e.rootMargin||""},i=o.find(e=>e.root===r.root&&e.margin===r.margin);if(i&&(t=s.get(i)))return t;let n=new Map;return t={id:r,observer:new IntersectionObserver(e=>{e.forEach(e=>{let t=n.get(e.target),r=e.isIntersecting||e.intersectionRatio>0;t&&r&&t(r)})},e),elements:n},o.push(r),s.set(r,t),t}(r);return a.set(e,t),n.observe(e),function(){if(a.delete(e),n.unobserve(e),0===a.size){n.disconnect(),s.delete(i);let e=o.findIndex(e=>e.root===i.root&&e.margin===i.margin);e>-1&&o.splice(e,1)}}}(r,e=>e&&h(e),{root:e?.current,rootMargin:t})}else if(!c){let e=(0,n.requestIdleCallback)(()=>h(!0));return()=>(0,n.cancelIdleCallback)(e)}},[u,t,e,c,d.current]),[m,c,(0,i.useCallback)(()=>{h(!1)},[])]}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},1018:e=>{"use strict";e.exports=JSON.parse('{"id":"google-maps-embed","description":"Embed a Google Maps embed on your webpage","website":"https://developers.google.com/maps/documentation/embed/get-started","html":{"element":"iframe","attributes":{"loading":"lazy","src":{"url":"https://www.google.com/maps/embed/v1/place","slugParam":"mode","params":["key","q","center","zoom","maptype","language","region"]},"referrerpolicy":"no-referrer-when-downgrade","frameborder":"0","style":"border:0","allowfullscreen":true,"width":null,"height":null}}}')},1300:(e,t,r)=>{"use strict";r.d(t,{j:()=>l,db:()=>u,A:()=>c});var i=r(36672);(0,i.KO)("firebase","12.9.0","app");var n=r(57090),a=r(45434);let s=(0,i.Dk)(),o=0===s.length?(0,i.Wp)({apiKey:"AIzaSyBiCj3-MQis1dzH3TVgvnzHNDuNa6ZgUxY",authDomain:"trains-fyi.firebaseapp.com",projectId:"trains-fyi",storageBucket:"trains-fyi.firebasestorage.app",messagingSenderId:"1087330969693",appId:"1:1087330969693:web:29a26bf82597d8a17f85b4",measurementId:"G-NXT13DW1VJ"}):s[0],l=(0,n.xI)(o),u=(0,a.aU)(o),c=o},1825:(e,t,r)=>{"use strict";r.d(t,{P:()=>l,W:()=>u});var i=r(37876),n=r(14232),a=r(25620),s=r(21081);let o=(0,n.createContext)();function l({children:e}){let{user:t,loading:r}=(0,a.A)(),{isPremium:n,entitlementReadyForUser:u}=(0,s.x)();return(0,i.jsx)(o.Provider,{value:{showAds:!r&&(!t||u&&!n),updateShowAds:()=>{}},children:e})}function u(){return(0,n.useContext)(o)}},5625:function(e,t,r){"use strict";var i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){let{html:t,scripts:r,stylesheets:i}=(0,s.YouTubeEmbed)(e);return(0,n.jsx)(o.default,{height:e.height||null,width:e.width||null,html:t,dataNtpc:"YouTubeEmbed",children:null==r?void 0:r.map(e=>(0,n.jsx)(a.default,{src:e.url,strategy:l[e.strategy],stylesheets:i},e.url))})};let n=r(37876),a=i(r(45105)),s=r(86087),o=i(r(40125)),l={server:"beforeInteractive",client:"afterInteractive",idle:"lazyOnload",worker:"worker"}},8715:(e,t,r)=>{"use strict";r.d(t,{PC:()=>u,Je:()=>c,py:()=>o,ym:()=>s});var i=r(12921),n=r(1300),a=r(39126);let s=!0;async function o(){if(!n.j.currentUser)throw Error("Sign in to check your subscription.");let e=n.j.currentUser.uid,{data:t}=await (0,i.Qg)((0,i.Uz)(n.A,"us-central1"),"refreshPremium")();if(n.j.currentUser?.uid!==e)throw Error("Your account changed. Please try again.");return t}let l=function({apiKey:e,offeringId:t,getUid:r,getEmail:i,loadSdk:n,verifyPremium:s}){let o,l=Promise.resolve();function u(t,i){let a=l.catch(()=>{}).then(async()=>{let a=()=>
1{if(r()!==t)throw Error("Your account changed. Please try again.")};if(a(),!e)throw Error("Web subscriptions are not available yet. Please check back soon.");let{Purchases:s}=await n();a(),o||=s.generateRevenueCatAnonymousAppUserId();let l=t||o,u=s.isConfigured()?s.getSharedInstance():s.configure({apiKey:e,appUserId:l});u.getAppUserId()!==l&&await u.changeUser(l),a();let c=await i(u,a);return a(),c});return l=a.catch(()=>{}),a}async function c(e){let r=await e.getOfferings();return(0,a.Ap)(t?r.all[t]:r.current)}return{loadPlans:(e=null)=>u(e,c),async purchase(e,t){if(!e)throw Error("Sign in before subscribing.");if(r()!==e)throw Error("Your account changed. Please try again.");let a=await s();if(r()!==e)throw Error("Your account changed. Please try again.");return a.isPremium?{alreadyPremium:!0}:u(e,async(e,r)=>{if((await e.getCustomerInfo()).entitlements.active["TrainsFYI Pro"])return{alreadyPremium:!0};let a=(await c(e)).find(e=>e.id===t);if(!a)throw Error("This plan is currently unavailable. Please refresh and try again.");r();try{return await e.purchase({rcPackage:a.package,customerEmail:i()||void 0}),{purchased:!0}}catch(t){let{ErrorCode:e}=await n();if(t.errorCode===e.UserCancelledError)return{cancelled:!0};throw Error("Checkout could not be completed. Check your account status before trying again.")}})}}}({apiKey:"rcb_ajVaBySmXqOotTzYVdtVSNHGljDA",offeringId:"default",getUid:()=>n.j.currentUser?.uid||null,getEmail:()=>n.j.currentUser?.email,loadSdk:()=>r.e(3391).then(r.bind(r,60843)),verifyPremium:o}),u=l.loadPlans,c=l.purchase},12921:(e,t,r)=>{"use strict";r.d(t,{Uz:()=>F,Qg:()=>k});var i=r(36672),n=r(76653),a=r(21610);function s(e,t){let r={};for(let i in e)e.hasOwnProperty(i)&&(r[i]=t(e[i]));return r}function o(e){if(null==e)return null;if(e instanceof Number&&(e=e.valueOf()),"number"==typeof e&&isFinite(e)||!0===e||!1===e||"[object String]"===Object.prototype.toString.call(e))return e;if(e instanceof Date)return e.toISOString();if(Array.isArray(e))return e.map(e=>o(e));if("function"==typeof e||"object"==typeof e)return s(e,e=>o(e));throw Error("Data cannot be encoded in JSON: "+e)}function l(e){if(null==e)return e;if(e["@type"])switch(e["@type"]){case"type.googleapis.com/google.protobuf.Int64Value":case"type.googleapis.com/google.protobuf.UInt64Value":{let t=Number(e.value);if(isNaN(t))throw Error("Data cannot be decoded from JSON: "+e);return t}default:throw Error("Data cannot be decoded from JSON: "+e)}return Array.isArray(e)?e.map(e=>l(e)):"function"==typeof e||"object"==typeof e?s(e,e=>l(e)):e}let u="functions",c={OK:"ok",CANCELLED:"cancelled",UNKNOWN:"unknown",INVALID_ARGUMENT:"invalid-argument",DEADLINE_EXCEEDED:"deadline-exceeded",NOT_FOUND:"not-found",ALREADY_EXISTS:"already-exists",PERMISSION_DENIED:"permission-denied",UNAUTHENTICATED:"unauthenticated",RESOURCE_EXHAUSTED:"resource-exhausted",FAILED_PRECONDITION:"failed-precondition",ABORTED:"aborted",OUT_OF_RANGE:"out-of-range",UNIMPLEMENTED:"unimplemented",INTERNAL:"internal",UNAVAILABLE:"unavailable",DATA_LOSS:"data-loss"};class h extends n.g{constructor(e,t,r){super(`${u}/${e}`,t||""),this.details=r,Object.setPrototypeOf(this,h.prototype)}}function d(e,t){let r,i=function(e){if(e>=200&&e<300)return"ok";switch(e){case 0:case 500:return"internal";case 400:return"invalid-argument";case 401:return"unauthenticated";case 403:return"permission-denied";case 404:return"not-found";case 409:return"aborted";case 429:return"resource-exhausted";case 499:return"cancelled";case 501:return"unimplemented";case 503:return"unavailable";case 504:return"deadline-exceeded"}return"unknown"}(e),n=i;try{let e=t&&t.error;if(e){let t=e.status;if("string"==typeof t){if(!c[t])return new h("internal","internal");i=c[t],n=t}let a=e.message;"string"==typeof a&&(n=a),r=e.details,void 0!==r&&(r=l(r))}}catch(e){}return"ok"===i?null:new h(i,n,r)}class m{constructor(e,t,r,n){this.app=e,this.auth=null,this.messaging=null,this.appCheck=null,this.serverAppAppCheckToken=null,(0,i.xZ)(e)&&e.settings.appCheckToken&&(this.serverAppAppCheckToken=e.settings.appCheckToken),this.auth=t.getImmediate({optional:!0}),this.messaging=r.getImmediate({optional:!0}),this.auth||t.get().then(e=>this.auth=e,()=>{}),this.messaging||r.get().then(e=>this.messaging=e,()=>{}),this.appCheck||n?.get().then(e=>this.appCheck=e,()=>{})}async getAuthToken(){if(this.auth)try{let e=await this.auth.getToken();return e?.accessToken}catch(e){return}}
1async getMessagingToken(){if(this.messaging&&"Notification"in self&&"granted"===Notification.permission)try{return await this.messaging.getToken()}catch(e){return}}async getAppCheckToken(e){if(this.serverAppAppCheckToken)return this.serverAppAppCheckToken;if(this.appCheck){let t=e?await this.appCheck.getLimitedUseToken():await this.appCheck.getToken();return t.error?null:t.token}return null}async getContext(e){let t=await this.getAuthToken();return{authToken:t,messagingToken:await this.getMessagingToken(),appCheckToken:await this.getAppCheckToken(e)}}}let g="us-central1",p=/^data: (.*?)(?:\n|$)/;class f{constructor(e,t,r,i,n=g,a=(...e)=>fetch(...e)){this.app=e,this.fetchImpl=a,this.emulatorOrigin=null,this.contextProvider=new m(e,t,r,i),this.cancelAllRequests=new Promise(e=>{this.deleteService=()=>Promise.resolve(e())});try{const e=new URL(n);this.customDomain=e.origin+("/"===e.pathname?"":e.pathname),this.region=g}catch(e){this.customDomain=null,this.region=n}}_delete(){return this.deleteService()}_url(e){let t=this.app.options.projectId;if(null!==this.emulatorOrigin){let r=this.emulatorOrigin;return`${r}/${t}/${this.region}/${e}`}return null!==this.customDomain?`${this.customDomain}/${e}`:`https://${this.region}-${t}.cloudfunctions.net/${e}`}}function y(e){return e.emulatorOrigin&&(0,n.zJ)(e.emulatorOrigin)?"include":void 0}async function v(e,t,r,i,n){let a;r["Content-Type"]="application/json";try{a=await i(e,{method:"POST",body:JSON.stringify(t),headers:r,credentials:y(n)})}catch(e){return{status:0,json:null}}let s=null;try{s=await a.json()}catch(e){}return{status:a.status,json:s}}async function w(e,t){let r={},i=await e.contextProvider.getContext(t.limitedUseAppCheckTokens);return i.authToken&&(r.Authorization="Bearer "+i.authToken),i.messagingToken&&(r["Firebase-Instance-ID-Token"]=i.messagingToken),null!==i.appCheckToken&&(r["X-Firebase-AppCheck"]=i.appCheckToken),r}async function b(e,t,r,i){var n;let a,s={data:r=o(r)},u=await w(e,i),c=(n=i.timeout||7e4,a=null,{promise:new Promise((e,t)=>{a=setTimeout(()=>{t(new h("deadline-exceeded","deadline-exceeded"))},n)}),cancel:()=>{a&&clearTimeout(a)}}),m=await Promise.race([v(t,s,u,e.fetchImpl,e),c.promise,e.cancelAllRequests]);if(c.cancel(),!m)throw new h("cancelled","Firebase Functions instance was deleted.");let g=d(m.status,m.json);if(g)throw g;if(!m.json)throw new h("internal","Response is not valid JSON object.");let p=m.json.data;if(void 0===p&&(p=m.json.result),void 0===p)throw new h("internal","Response is missing data field.");return{data:l(p)}}async function C(e,t,r,i){var n,a,s,u;let c,m,g,f,v,b={data:r=o(r)},C=await w(e,i);C["Content-Type"]="application/json",C.Accept="text/event-stream";try{g=await e.fetchImpl(t,{method:"POST",body:JSON.stringify(b),headers:C,signal:i?.signal,credentials:y(e)})}catch(t){if(t instanceof Error&&"AbortError"===t.name){let e=new h("cancelled","Request was cancelled.");return{data:Promise.reject(e),stream:{[Symbol.asyncIterator]:()=>({next:()=>Promise.reject(e)})}}}let e=d(0,null);return{data:Promise.reject(e),stream:{[Symbol.asyncIterator]:()=>({next:()=>Promise.reject(e)})}}}let T=new Promise((e,t)=>{f=e,v=t});i?.signal?.addEventListener("abort",()=>{let e=new h("cancelled","Request was cancelled.");v(e)});let S=(n=g.body.getReader(),a=f,s=v,u=i?.signal,c=(e,t)=>{let r=e.match(p);if(!r)return;let i=r[1];try{let e=JSON.parse(i);if("result"in e)return void a(l(e.result));if("message"in e)return void t.enqueue(l(e.message));if("error"in e){let r=d(0,e);t.error(r),s(r);return}}catch(e){if(e instanceof h){t.error(e),s(e);return}}},m=new TextDecoder,new ReadableStream({start(e){let t="";return r();async function r(){if(u?.aborted){let t=new h("cancelled","Request was cancelled");return e.error(t),s(t),Promise.resolve()}try{let{value:i,done:a}=await n.read();if(a){t.trim()&&c(t.trim(),e),e.close();return}if(u?.aborted){let t=new h("cancelled","Request was cancelled");e.error(t),s(t),await n.cancel();return}let o=(t+=m.decode(i,{stream:!0})).split("\n");for(let r of(t=o.pop()||"",o))r.trim()&&c(r.trim(),e);return r()}catch(r){let t=r instanceof h?r:d(0,null);e.error(t),s(t)}}},cancel:()=>n.cancel()}));
1return{stream:{[Symbol.asyncIterator](){let e=S.getReader();return{async next(){let{value:t,done:r}=await e.read();return{value:t,done:r}},return:async()=>(await e.cancel(),{done:!0,value:void 0})}}},data:T}}let T="@firebase/functions",S="0.13.1";function F(e=(0,i.Sx)(),t=g){let r=(0,i.j6)((0,n.Ku)(e),u).getImmediate({identifier:t}),a=(0,n.yU)("functions");return a&&function(e,t,r){var i;let a;i=(0,n.Ku)(e),a=(0,n.zJ)(t),i.emulatorOrigin=`http${a?"s":""}://${t}:${r}`,a&&((0,n.gE)(i.emulatorOrigin+"/backends"),(0,n.P1)("Functions",!0))}(r,...a),r}function k(e,t,r){var i;let a;return i=(0,n.Ku)(e),(a=e=>{var n,a,s,o;let l;return n=i,a=t,s=e,o=r||{},l=n._url(a),b(n,l,s,o)}).stream=(e,r)=>{var n,a,s,o;let l;return n=i,a=t,s=e,o=r,l=n._url(a),C(n,l,s,o||{})},a}(0,i.om)(new a.uA(u,(e,{instanceIdentifier:t})=>new f(e.getProvider("app").getImmediate(),e.getProvider("auth-internal"),e.getProvider("messaging-internal"),e.getProvider("app-check-internal"),t),"PUBLIC").setMultipleInstances(!0)),(0,i.KO)(T,S,void 0),(0,i.KO)(T,S,"esm2020")},13949:(e,t)=>{"use strict";function r(e,t,i=!1){return t?Object.keys(e).filter(e=>i?!t.includes(e):t.includes(e)).reduce((t,r)=>(t[r]=e[r],t),{}):{}}function i(e,t,r,i){let n=i&&Object.keys(i).length>0?new URL(Object.values(i)[0],e):new URL(e);return t&&r&&t.forEach(e=>{r[e]&&n.searchParams.set(e,r[e])}),n.toString()}function n(e,t,r,n,a){var s;if(!t)return`<${e}></${e}>`;let o=(null==(s=t.src)?void 0:s.url)?Object.assign(Object.assign({},t),{src:i(t.src.url,t.src.params,n,a)}):t,l=Object.keys(Object.assign(Object.assign({},o),r)).reduce((e,t)=>{let i=null==r?void 0:r[t],n=o[t],a=null!=i?i:n,s=!0===a?t:`${t}="${a}"`;return a?e+` ${s}`:e},"");return`<${e}${l}></${e}>`}Object.defineProperty(t,"__esModule",{value:!0}),t.formatData=t.createHtml=t.formatUrl=void 0,t.formatUrl=i,t.createHtml=n,t.formatData=function(e,t){var a,s,o,l,u;let c=r(t,null==(a=e.scripts)?void 0:a.reduce((e,t)=>[...e,...Array.isArray(t.params)?t.params:[]],[])),h=r(t,null==(o=null==(s=e.html)?void 0:s.attributes.src)?void 0:o.params),d=r(t,[null==(u=null==(l=e.html)?void 0:l.attributes.src)?void 0:u.slugParam]),m=r(t,[...Object.keys(c),...Object.keys(h),...Object.keys(d)],!0);return Object.assign(Object.assign({},e),{html:e.html?n(e.html.element,e.html.attributes,m,h,d):null,scripts:e.scripts?e.scripts.map(e=>Object.assign(Object.assign({},e),{url:i(e.url,e.params,c)})):null})}},16110:function(e,t,r){"use strict";var i=this&&this.__rest||function(e,t){var r={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(r[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,i=Object.getOwnPropertySymbols(e);n<i.length;n++)0>t.indexOf(i[n])&&Object.prototype.propertyIsEnumerable.call(e,i[n])&&(r[i[n]]=e[i[n]]);return r},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.YouTubeEmbed=void 0;let a=n(r(36198)),s=r(13949);t.YouTubeEmbed=e=>{var t=i(e,[]);return(0,s.formatData)(a.default,t)}},18041:()=>{},19701:(e,t,r)=>{"use strict";r.d(t,{IR:()=>s,kr:()=>a,sM:()=>n});let i=new Map([["1","#D5C82B"],["2","#008000"],["3","#0099CC"],["4","#B300B3"],["5","#F58220"]]),n=[{id:"default",label:"Default",description:"Network colours with selected line colours, including TTC subway lines."},{id:"network",label:"Network colours",description:"One colour per network.",premium:!0},{id:"route",label:"Route colours",description:"Each routeâs colour, with network colours where unavailable.",premium:!0}];function a(e,t){return t&&n.some(t=>t.id===e)?e:"default"}function s(e,t,r="default"){if("network"===r)return t;if("route"===r){let r=e?.gtfs?.route_color;return"string"==typeof r&&/^#?[0-9a-f]{6}$/i.test(r.trim())?`#${r.trim().replace(/^#/,"")}`:t}return e?.agency?.toLowerCase()!=="ttc"?t:i.get(String(e.gtfs?.route_id??"").trim())||t}},21081:(e,t,r)=>{"use strict";r.d(t,{$:()=>c,x:()=>h});var i=r(37876),n=r(45434),a=r(14232),s=r(25620),o=r(1300),l=r(8715);let u=(0,a.createContext)(void 0);function c({children:e}){let{user:t}=(0,s.A)(),[r,h]=(0,a.useState)(null),[d,m]=(0,a.useState)(Date.now());(0,a.useEffect)(()=>
1{if(!t?.uid)return;let e=!0,r=(0,n.aQ)((0,n.H9)(o.db,"users",t.uid,"settings","profile"),r=>{e&&h({uid:t.uid,profile:r.data()||{}})},()=>{e&&h({uid:t.uid,profile:{}})}),i=()=>{"hidden"!==document.visibilityState&&(m(Date.now()),(0,l.py)().catch(()=>{}))};i(),window.addEventListener("focus",i);let a=setInterval(()=>m(Date.now()),3e4);return()=>{e=!1,r(),clearInterval(a),window.removeEventListener("focus",i)}},[t?.uid]);let g=!!t?.uid&&r?.uid===t.uid,p=g?r.profile:{},f=p.premiumExpiresAt&&Date.parse(p.premiumExpiresAt)<=d,y=!0===p.isPremium&&(!f||!0===p.adminPremium||"admin"===p.premiumSource);return(0,i.jsx)(u.Provider,{value:{isPremium:y,isDebugUser:!0===p.debugEnabled,entitlementLoading:!!t&&!g,entitlementReadyForUser:g,profile:p,refreshPremium:l.py},children:e})}function h(){let e=(0,a.useContext)(u);if(void 0===e)throw Error("useEntitlement must be used within an EntitlementProvider");return e}},21610:(e,t,r)=>{"use strict";r.d(t,{h1:()=>o,uA:()=>n});var i=r(76653);class n{constructor(e,t,r){this.name=e,this.instanceFactory=t,this.type=r,this.multipleInstances=!1,this.serviceProps={},this.instantiationMode="LAZY",this.onInstanceCreated=null}setInstantiationMode(e){return this.instantiationMode=e,this}setMultipleInstances(e){return this.multipleInstances=e,this}setServiceProps(e){return this.serviceProps=e,this}setInstanceCreatedCallback(e){return this.onInstanceCreated=e,this}}let a="[DEFAULT]";class s{constructor(e,t){this.name=e,this.container=t,this.component=null,this.instances=new Map,this.instancesDeferred=new Map,this.instancesOptions=new Map,this.onInitCallbacks=new Map}get(e){let t=this.normalizeInstanceIdentifier(e);if(!this.instancesDeferred.has(t)){let e=new i.cY;if(this.instancesDeferred.set(t,e),this.isInitialized(t)||this.shouldAutoInitialize())try{let r=this.getOrInitializeService({instanceIdentifier:t});r&&e.resolve(r)}catch(e){}}return this.instancesDeferred.get(t).promise}getImmediate(e){let t=this.normalizeInstanceIdentifier(e?.identifier),r=e?.optional??!1;if(this.isInitialized(t)||this.shouldAutoInitialize())try{return this.getOrInitializeService({instanceIdentifier:t})}catch(e){if(r)return null;throw e}if(r)return null;throw Error(`Service ${this.name} is not available`)}getComponent(){return this.component}setComponent(e){if(e.name!==this.name)throw Error(`Mismatching Component ${e.name} for Provider ${this.name}.`);if(this.component)throw Error(`Component for ${this.name} has already been provided`);if(this.component=e,this.shouldAutoInitialize()){if("EAGER"===e.instantiationMode)try{this.getOrInitializeService({instanceIdentifier:a})}catch(e){}for(let[e,t]of this.instancesDeferred.entries()){let r=this.normalizeInstanceIdentifier(e);try{let e=this.getOrInitializeService({instanceIdentifier:r});t.resolve(e)}catch(e){}}}}clearInstance(e=a){this.instancesDeferred.delete(e),this.instancesOptions.delete(e),this.instances.delete(e)}async delete(){let e=Array.from(this.instances.values());await Promise.all([...e.filter(e=>"INTERNAL"in e).map(e=>e.INTERNAL.delete()),...e.filter(e=>"_delete"in e).map(e=>e._delete())])}isComponentSet(){return null!=this.component}isInitialized(e=a){return this.instances.has(e)}getOptions(e=a){return this.instancesOptions.get(e)||{}}initialize(e={}){let{options:t={}}=e,r=this.normalizeInstanceIdentifier(e.instanceIdentifier);if(this.isInitialized(r))throw Error(`${this.name}(${r}) has already been initialized`);if(!this.isComponentSet())throw Error(`Component ${this.name} has not been registered yet`);let i=this.getOrInitializeService({instanceIdentifier:r,options:t});for(let[e,t]of this.instancesDeferred.entries())r===this.normalizeInstanceIdentifier(e)&&t.resolve(i);return i}onInit(e,t){let r=this.normalizeInstanceIdentifier(t),i=this.onInitCallbacks.get(r)??new Set;i.add(e),this.onInitCallbacks.set(r,i);let n=this.instances.get(r);return n&&e(n,r),()=>{i.delete(e)}}invokeOnInitCallbacks(e,t){let r=this.onInitCallbacks.get(t);if(r)for(let i of r)try{i(e,t)}catch{}}getOrInitializeService({instanceIdentifier:e,options:t={}}){var r;let i=this.instances.get(e);if(!i&&this.component&&(i=this.component.instanceFactory(this.container,{instanceIdentifier:(r=e)===a?void 0:r,options:t}),this.instances.set(e,i),this.instancesOptions.set(e,t),this.invokeOnInitCallbacks(i,e),this.component.onInstanceCreated))try{this.component.onInstanceCreated(this.container,e,i)}catch{}return i||null}normalizeInstanceIdentifier(e=a){return this.component?this.component.multipleInstances?e:a:e}shouldAutoInitialize(){return!!this.component&&"EXPLICIT"!==this.component.instantiationMode}}class o{constructor(e){this.name=e,this.providers=new Map}addComponent(e){let t=this.getProvider(e.name);if(t.isComponentSet())throw Error(`Component ${e.name} has already been registered with ${this.name}`);t.setComponent(e)}addOrOverwriteComponent(e){this.getProvider(e.name).isComponentSet()&&this.providers.delete(e.name),this.addComponent(e)}getProvider(e){if(this.providers.has(e))return this.providers.get(e);let t=new s(e,this);return this.providers.set(e,t),t}getProviders(){return Array.from(this.providers.values())}}},25620:(e,t,r)=>{"use strict";r.d(t,{O:()=>w,A:()=>b});var i=r(37876),n=r(57090),a=r(14232),s=r(45434),o=r(12921),l=r(77328),u=r.n(l),c=r(48230),h=r.n(c),d=r(89099),m=r(74880),g=r(39126),p=r(1300);
1let f=["Welcome","Your networks","Newsletter","Ready"];function y({user:e,onComplete:t}){let r=(0,d.useRouter)(),[n,l]=(0,a.useState)(0),[c,v]=(0,a.useState)([]),[w,b]=(0,a.useState)(""),[C,T]=(0,a.useState)(!1),[S,F]=(0,a.useState)(!1),[k,E]=(0,a.useState)(""),A=m.Y.getAllNetworks().filter(e=>e.name.toLowerCase().includes(w.toLowerCase()));async function _(){F(!0),E("");try{if(c.length){let t=await (0,s.GG)((0,s.P)((0,s.rJ)(p.db,"favorites"),(0,s._M)("userId","==",e.uid))),r=new Set(t.docs.map(e=>e.data().networkSlug));await Promise.all(c.filter(e=>!r.has(e)).map(t=>(0,s.BN)((0,s.H9)(p.db,"favorites",`${e.uid}_${t}`),{userId:e.uid,networkSlug:t,createdAt:(0,s.O5)()})))}let{data:i}=await (0,o.Qg)((0,o.Uz)(p.A),"registerResendSignup")({optIn:C,source:"web",consentVersion:"newsletter-v1"});if(!i.ok)throw Error("Could not save your newsletter choice. Please try again.");await r.replace((0,g.bk)(r.query.returnUrl)),t()}catch(e){E(e.message||"Could not save your choices. Please try again.")}finally{F(!1)}}return(0,i.jsxs)("main",{className:"flex min-h-screen items-center justify-center bg-blue-800 px-5 py-10 text-white",children:[(0,i.jsx)(u(),{children:(0,i.jsx)("title",{children:"Welcome to trains.fyi"})}),(0,i.jsxs)("section",{className:"w-full max-w-xl","aria-label":"Account setup",children:[(0,i.jsxs)("p",{className:"mb-3 text-sm text-blue-100",children:["Step ",n+1," of ",f.length," \xb7 ",f[n]]}),(0,i.jsx)("div",{className:"mb-10 flex gap-2","aria-hidden":"true",children:f.map((e,t)=>(0,i.jsx)("div",{className:`h-1 flex-1 rounded ${t<=n?"bg-white":"bg-white/30"}`},e))}),0===n&&(0,i.jsxs)("div",{className:"space-y-5",children:[(0,i.jsx)("img",{src:"/favicon.png",width:"90",height:"90",alt:""}),(0,i.jsx)("h1",{className:"text-4xl font-bold",children:"Welcome to trains.fyi"}),(0,i.jsx)("p",{className:"text-lg text-blue-100",children:"Track trains in real time around the world. Letâs make it yours."}),(0,i.jsx)("p",{className:"text-blue-100",children:"Pick your favorite networks and choose whether youâd like to hear from us."})]}),1===n&&(0,i.jsxs)("div",{className:"space-y-4",children:[(0,i.jsx)("h1",{className:"text-3xl font-bold",children:"Pick your networks"}),(0,i.jsx)("p",{className:"text-blue-100",children:"Your favorites sync with iOS and Android. You can also skip this step."}),(0,i.jsxs)("label",{className:"block",children:["Search networks",(0,i.jsx)("input",{value:w,onChange:e=>b(e.target.value),type:"search",className:"mt-2 w-full rounded-lg border border-white/30 bg-blue-900 p-3"})]}),(0,i.jsxs)("div",{className:"grid max-h-80 grid-cols-2 gap-3 overflow-y-auto p-1",children:[A.map(e=>(0,i.jsxs)("button",{type:"button","aria-pressed":c.includes(e.slug),onClick:()=>v(t=>t.includes(e.slug)?t.filter(t=>t!==e.slug):[...t,e.slug]),className:`rounded-lg border-2 p-4 text-left font-semibold ${c.includes(e.slug)?"border-white bg-white text-blue-800":"border-white/30 bg-blue-900"}`,children:[e.name,c.includes(e.slug)&&(0,i.jsx)("span",{"aria-hidden":"true",children:" â"})]},e.slug)),!A.length&&(0,i.jsx)("p",{children:"No matching networks."})]})]}),2===n&&(0,i.jsxs)("div",{className:"space-y-6",children:[(0,i.jsx)("h1",{className:"text-3xl font-bold",children:"Stay in the loop"}),(0,i.jsx)("p",{className:"text-blue-100",children:"Get product updates and rail news from trains.fyi."}),(0,i.jsxs)("label",{className:"flex cursor-pointer items-start gap-4 roun
1ded-xl border border-white/40 p-5",children:[(0,i.jsx)("input",{type:"checkbox",checked:C,onChange:e=>T(e.target.checked),className:"mt-1 h-5 w-5 shrink-0"}),(0,i.jsx)("span",{children:"Email me the trains.fyi newsletter with product updates and rail news. I can unsubscribe at any time."})]}),(0,i.jsxs)("p",{className:"text-sm text-blue-100",children:["Optional. Leave this off to continue without newsletter emails. If you opt in, weâll send emails to ",e.email,"."]}),(0,i.jsx)(h(),{href:"/privacy/",target:"_blank",rel:"noopener noreferrer",className:"inline-block underline",children:"Privacy policy"})]}),3===n&&(0,i.jsxs)("div",{className:"space-y-5",children:[(0,i.jsx)("h1",{className:"text-3xl font-bold",children:"Youâre all set!"}),(0,i.jsx)("p",{className:"text-blue-100",children:c.length?`${c.length} favorite networks selected.`:"Explore networks around the world."}),(0,i.jsx)("p",{children:C?"Youâve chosen to receive the newsletter.":"You wonât receive newsletter emails."}),(0,i.jsx)("p",{className:"text-blue-100",children:"Start exploring for free. You can discover Pro features any time from your account."})]}),k&&(0,i.jsx)("p",{role:"alert",className:"mt-5 rounded-lg bg-red-950 p-4",children:k}),(0,i.jsxs)("div",{className:"mt-10 flex items-center justify-between",children:[(0,i.jsx)("button",{type:"button",disabled:0===n||S,onClick:()=>l(n-1),className:"rounded px-4 py-3 disabled:opacity-30",children:"Back"}),(0,i.jsx)("button",{type:"button",disabled:S,onClick:()=>n===f.length-1?_():l(n+1),className:"rounded-full bg-white px-7 py-3 font-semibold text-blue-800 disabled:opacity-50",children:S?"Savingâ¦":0===n?"Get started":n===f.length-1?"Letâs go!":"Next"})]})]})]})}let v=(0,a.createContext)(void 0);function w({children:e}){let[t,r]=(0,a.useState)(null),[s,o]=(0,a.useState)(!0),[l,u]=(0,a.useState)(!1),c=(0,a.useRef)(!1),h=async e=>{c.current=!0,o(!0);try{let t=await e();if((0,n.B8)(t)?.isNewUser){try{localStorage.setItem(`onboarding:${t.user.uid}`,"pending")}catch{}u(!0)}return r(t.user),t}finally{c.current=!1,o(!1)}};(0,a.useEffect)(()=>(0,n.hg)(p.j,e=>{if(!c.current){r(e);try{u(!!e&&"pending"===localStorage.getItem(`onboarding:${e.uid}`))}catch{u(!1)}o(!1)}}),[]);let d=async(e,t)=>{await h(()=>(0,n.x9)(p.j,e,t))},m=async(e,t)=>{await h(()=>(0,n.eJ)(p.j,e,t))},g=async e=>{await (0,n.J1)(p.j,e)},f=async()=>{let e=new n.HF;await h(()=>(0,n.df)(p.j,e))},b=async()=>{let e=new n.LD("apple.com");await h(()=>(0,n.df)(p.j,e))},C=async()=>{await (0,n.CI)(p.j)},T=async e=>{if(!p.j.currentUser)throw Error("Sign in first.");if(!["google.com","apple.com"].includes(e))throw Error("Unsupported sign-in provider.");let t="google.com"===e?new n.HF:new n.LD("apple.com");await (0,n.x8)(p.j.currentUser,t),r(p.j.currentUser)};return(0,i.jsx)(v.Provider,{value:{user:t,loading:s,onboarding:l,signIn:d,signUp:m,resetPassword:g,signInWithGoogle:f,signInWithApple:b,logout:C,linkProvider:T},children:t&&l?(0,i.jsx)(y,{user:t,onComplete:()=>{try{localStorage.removeItem(`onboarding:${p.j.currentUser.uid}`)}catch{}u(!1)}}):e})}function b(){let e=(0,a.useContext)(v);if(void 0===e)throw Error("useAuth must be used within an AuthProvider");return e}},29979:(e,t,r)=>{"use strict";var i,n;r.d(t,{$b:()=>i,Vy:()=>c});let a=[];(n=i||(i={}))[n.DEBUG=0]="DEBUG",n[n.VERBOSE=1]="VERBOSE",n[n.INFO=2]="INFO",n[n.WARN=3]="WARN",n[n.ERROR=4]="ERROR",n[n.SILENT=5]="SILENT";let s={debug:i.DEBUG,verbose:i.VERBOSE,info:i.INFO,warn:i.WARN,error:i.ERROR,silent:i.SILENT},o=i.INFO,l={[i.DEBUG]:"log",[i.VERBOSE]:"log",[i.INFO]:"info",[i.WARN]:"warn",[i.ERROR]:"error"},u=(e,t,...r)=>{if(t<e.logLevel)return;let i=new Date().toISOString(),n=l[t];if(n)console[n](`[${i}] ${e.name}:`,...r);else throw Error(`Attempted to log a message with an invalid logType (value: ${t})`)};class c{constructor(e){this.name=e,this._logLevel=o,this._logHandler=u,this._userLogHandler=null,a.push(this)}get logLevel(){return this._logLevel}set logLevel(e){if(!(e in i))throw TypeError(`Invalid value "${e}" assigned to \`logLevel\``);this._logLevel=e}setLogLevel(e){this._logLevel="string"==typeof e?s[e]:e}get logHandler(){return this._logHandler}set logHandler(e){if("function"!=typeof e)throw TypeError("Value assigned to `logHandler` must be a function");this._logHandler=e}get userLogHandler(){return this._userLogHandler}set userLogHandler(e){this._userLogHandler=e}debug(...e){this._userLogHandler&&this._userLogHandler(this,i.DEBUG,...e),this._logHandler(this,i.DEBUG,...e)}log(...e){this._userLogHandler&&this._userLogHandler(this,i.VERBOSE,...e),this._logHandler(this,i.VERBOSE,...e)}info(...e){this._userLogHandler&&this._userLogHandler(this,i.INFO,...e),this._logHandler(this,i.INFO,...e)}warn(...e){this._userLogHandler&&this._userLogHandler(this,i.WARN,...e),this._logHandler(this,i.WARN,...e)}error(...e){this._userLogHandler&&this._userLogHandler(this,i.ERROR,...e),this._logHandler(this,i.ERROR,...e)}}},36198:e=>{"use strict";e.exports=JSON.parse('{"id":"youtube-embed","description":"Embed a YouTube embed on your webpage.","website":"https://github.com/paulirish/lite-youtube-embed","html":{"element":"lite-youtube","attributes":{"videoid":null,"playlabel":null}},"stylesheets":["https://cdn.jsdelivr.net/gh/paulirish/lite-youtube-embed@master/src/lite-yt-embed.css"],"scripts":[{"url":"https://cdn.jsdelivr.net/gh/paulirish/lite-youtube-embed@master/src/lite-yt-embed.js","strategy":"idle","location":"head","action":"append"}]}')},36672:(e,t,r)=>{"use strict";let i,n,a;r.d(t,{MF:()=>N,j6:()=>O,xZ:()=>M,om:()=>x,Sx:()=>z,Dk:()=>U,Wp:()=>D,KO:()=>B});var s=r(21610),o=r(29979),l=r(76653);let u=new WeakMap,c=new WeakMap,h=new WeakMap,d=new WeakMap,m=new WeakMap,g={get(e,t,r){if(e instanceof IDBTransaction){if("done"===t)return c.get(e);if("objectStoreNames"===t)return e.objectStoreNames||h.get(e);if("store"===t)return r.objectStoreNames[1]?void 0:r.objectStore(r.objectStoreNames[0])}return p(e[t])},set:(e,t,r)=>(e[t]=r,!0),has:(e,t)=>e instanceof IDBTransaction&&("done"===t||"store"===t)||t in e};function p(e){if(e instanceof IDBRequest){let t;return(t=new Promise((t,r)=>{let i=()=>{e.removeEventListener("success",n),e.removeEventListener("error",a)},n=()=>{t(p(e.result)),i()},a=()=>{r(e.error),i()};e.addEventListener("success",n),e.addEventListener("error",a)})).then(t=>{t instanceof IDBCursor&&u.set(t,e)}).catch(()=>{}),m.set(t,e),t}if(d.has(e))return d.get(e);let t=function(e){if("function"==typeof e)return e!==IDBDatabase.prototype.transaction||"objectStoreNames"in IDBTransaction.prototype?(n||(n=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])).includes(e)?function(...t){return e.apply(f(this),t),p(u.get(this))}:function(...t){return p(e.apply(f(this),t))}:function(t,...r){let i=e.call(f(this),t,...r);return h.set(i,t.sort?t.sort():[t]),p(i)};return e instanceof IDBTransaction&&function(e){if(c.has(e))return;let t=new Promise((t,r)=>{let i=()=>{e.removeEventListener("complete",n),e.removeEventListener("error",a),e.removeEventListener("abort",a)},n=()=>{t(),i()},a=()=>{r(e.error||new DOMException("AbortError","AbortError")),i()};e.addEventListener("complete",n),e.addEventListener("error",a),e.addEventListener("abort",a)});c.set(e,t)}(e),(i||(i=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])).some(t=>e instanceof t)?new Proxy(e,g):e}(e);return t!==e&&(d.set(e,t),m.set(t,e)),t}let f=e=>m.get(e),y=["get","getKey","getAll","getAllKeys","count"],v=["put","add","delete","clear"],w=new Map;function b(e,t){if(!(e instanceof IDBDatabase&&!(t in e)&&"string"==typeof t))return;if(w.get(t))return w.get(t);let r=t.replace(/FromIndex$/,""),i=t!==r,n=v.includes(r);if(!(r in(i?IDBIndex:IDBObjectStore).prototype)||!(n||y.includes(r)))return;let a=async function(e,...t){let a=this.transaction(e,n?"readwrite":"readonly"),s=a.store;
1return i&&(s=s.index(t.shift())),(await Promise.all([s[r](...t),n&&a.done]))[0]};return w.set(t,a),a}g={...a=g,get:(e,t,r)=>b(e,t)||a.get(e,t,r),has:(e,t)=>!!b(e,t)||a.has(e,t)};class C{constructor(e){this.container=e}getPlatformInfoString(){return this.container.getProviders().map(e=>{let t;if(t=e.getComponent(),t?.type!=="VERSION")return null;{let t=e.getImmediate();return`${t.library}/${t.version}`}}).filter(e=>e).join(" ")}}let T="@firebase/app",S="0.14.8",F=new o.Vy("@firebase/app"),k="[DEFAULT]",E={[T]:"fire-core","@firebase/app-compat":"fire-core-compat","@firebase/analytics":"fire-analytics","@firebase/analytics-compat":"fire-analytics-compat","@firebase/app-check":"fire-app-check","@firebase/app-check-compat":"fire-app-check-compat","@firebase/auth":"fire-auth","@firebase/auth-compat":"fire-auth-compat","@firebase/database":"fire-rtdb","@firebase/data-connect":"fire-data-connect","@firebase/database-compat":"fire-rtdb-compat","@firebase/functions":"fire-fn","@firebase/functions-compat":"fire-fn-compat","@firebase/installations":"fire-iid","@firebase/installations-compat":"fire-iid-compat","@firebase/messaging":"fire-fcm","@firebase/messaging-compat":"fire-fcm-compat","@firebase/performance":"fire-perf","@firebase/performance-compat":"fire-perf-compat","@firebase/remote-config":"fire-rc","@firebase/remote-config-compat":"fire-rc-compat","@firebase/storage":"fire-gcs","@firebase/storage-compat":"fire-gcs-compat","@firebase/firestore":"fire-fst","@firebase/firestore-compat":"fire-fst-compat","@firebase/ai":"fire-vertex","fire-js":"fire-js",firebase:"fire-js-all"},A=new Map,_=new Map,R=new Map;function I(e,t){try{e.container.addComponent(t)}catch(r){F.debug(`Component ${t.name} failed to register with FirebaseApp ${e.name}`,r)}}function x(e){let t=e.name;if(R.has(t))return F.debug(`There were multiple attempts to register component ${t}.`),!1;
1for(let r of(R.set(t,e),A.values()))I(r,e);for(let t of _.values())I(t,e);return!0}function O(e,t){let r=e.container.getProvider("heartbeat").getImmediate({optional:!0});return r&&r.triggerHeartbeat(),e.container.getProvider(t)}function M(e){return null!=e&&void 0!==e.settings}let P=new l.FA("app","Firebase",{"no-app":"No Firebase App '{$appName}' has been created - call initializeApp() first","bad-app-name":"Illegal App name: '{$appName}'","duplicate-app":"Firebase App named '{$appName}' already exists with different options or config","app-deleted":"Firebase App named '{$appName}' already deleted","server-app-deleted":"Firebase Server App has been deleted","no-options":"Need to provide options, when not being deployed to hosting via source.","invalid-app-argument":"firebase.{$appName}() takes either no argument or a Firebase App instance.","invalid-log-argument":"First argument to `onLog` must be null or a function.","idb-open":"Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.","idb-get":"Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.","idb-set":"Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.","idb-delete":"Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.","finalization-registry-not-supported":"FirebaseServerApp deleteOnDeref field defined but the JS runtime does not support FinalizationRegistry.","invalid-server-app-environment":"FirebaseServerApp is not for use in browser environments."});class L{constructor(e,t,r){this._isDeleted=!1,this._options={...e},this._config={...t},this._name=t.name,this._automaticDataCollectionEnabled=t.automaticDataCollectionEnabled,this._container=r,this.container.addComponent(new s.uA("app",()=>this,"PUBLIC"))}get automaticDataCollectionEnabled(){return this.checkDestroyed(),this._automaticDataCollectionEnabled}set automaticDataCollectionEnabled(e){this.checkDestroyed(),this._automaticDataCollectionEnabled=e}get name(){return this.checkDestroyed(),this._name}get options(){return this.checkDestroyed(),this._options}get config(){return this.checkDestroyed(),this._config}get container(){return this._container}get isDeleted(){return this._isDeleted}set isDeleted(e){this._isDeleted=e}checkDestroyed(){if(this.isDeleted)throw P.create("app-deleted",{appName:this._name})}}let N="12.9.0";function D(e,t={}){let r=e;"object"!=typeof t&&(t={name:t});let i={name:k,automaticDataCollectionEnabled:!0,...t},n=i.name;if("string"!=typeof n||!n)throw P.create("bad-app-name",{appName:String(n)});if(r||(r=(0,l.T9)()),!r)throw P.create("no-options");let a=A.get(n);if(a)if((0,l.bD)(r,a.options)&&(0,l.bD)(i,a.config))return a;else throw P.create("duplicate-app",{appName:n});let o=new s.h1(n);for(let e of R.values())o.addComponent(e);let u=new L(r,i,o);return A.set(n,u),u}function z(e=k){let t=A.get(e);if(!t&&e===k&&(0,l.T9)())return D();if(!t)throw P.create("no-app",{appName:e});return t}function U(){return Array.from(A.values())}function B(e,t,r){let i=E[e]??e;r&&(i+=`-${r}`);let n=i.match(/\s|\//),a=t.match(/\s|\//);if(n||a){let e=[`Unable to register library "${i}" with version "${t}":`];n&&e.push(`library name "${i}" contains illegal characters (whitespace or "/")`),n&&a&&e.push("and"),a&&e.push(`version name "${t}" contains illegal characters (whitespace or "/")`),F.warn(e.join(" "));return}x(new s.uA(`${i}-version`,()=>({library:i,version:t}),"VERSION"))}let V="firebase-heartbeat-store",j=null;function G(){return j||(j=(function(e,{blocked:t,upgrade:r,blocking:i,terminated:n}={}){let a=indexedDB.open(e,1),s=p(a);return r&&a.addEventListener("upgradeneeded",e=>{r(p(a.result),e.oldVersion,e.newVersion,p(a.transaction),e)}),t&&a.addEventListener("blocked",e=>t(e.oldVersion,e.newVersion,e)),s.then(e=>{n&&e.addEventListener("close",()=>n()),i&&e.addEventListener("versionchange",e=>i(e.oldVersion,e.newVersion,e))}).catch(()=>{}),s})("firebase-heartbeat-database",{upgrade:(e,t)=>{if(0===t)try{e.createObjectStore(V)}catch(e){console.warn(e)}}}).catch(e=>{throw P.create("idb-open",{originalErrorMessage:e.message})})),j}async function K(e){try{let t=(await G()).transaction(V),r=await t.objectStore(V).get(q(e));return await t.done,r}catch(e){if(e instanceof l.g)F.warn(e.message);else{let t=P.create("idb-get",{originalErrorMessage:e?.message});F.warn(t.message)}}}async function H(e,t){try{let r=(await G()).transaction(V,"readwrite"),i=r.objectStore(V);await i.put(t,q(e)),await r.done}catch(e){if(e instanceof l.g)F.warn(e.message);else{let t=P.create("idb-set",{originalErrorMessage:e?.message});F.warn(t.message)}}}function q(e){return`${e.name}!${e.options.appId}`}class W{constructor(e){this.container=e,this._heartbeatsCache=null;const t=this.container.getProvider("app").getImmediate();this._storage=new Y(t),this._heartbeatsCachePromise=this._storage.read().then(e=>(this._heartbeatsCache=e,e))}async triggerHeartbeat(){try{let e=this.container.getProvider("platform-logger").getImmediate().getPlatformInfoString(),t=$();if(this._heartbeatsCache?.heartbeats==null&&(this._heartbeatsCache=await this._heartbeatsCachePromise,this._heartbeatsCache?.heartbeats==null)||this._heartbeatsCache.lastSentHeartbeatDate===t||this._heartbeatsCache.heartbeats.some(e=>e.date===t))return;if(this._heartbeatsCache.heartbeats.push({date:t,agent:e}),this._heartbeatsCache.heartbeats.length>30){let e=function(e){if(0===e.length)return -1;let t=0,r=e[0].date;for(let i=1;i<e.length;i++)e[i].date<r&&(r=e[i].date,t=i);return t}(this._heartbeatsCache.heartbeats);this._heartbeatsCache.heartbeats.splice(e,1)}return this._storage.overwrite(this._heartbeatsCache)}catch(e){F.warn(e)}}async getHeartbeatsHeader(){try{if(null===this._heartbeatsCache&&await this._heartbeatsCachePromise,this._heartbeatsCache?.heartbeats==null||0===this._heartbeatsCache.heartbeats.length)return"";let e=$(),{heartbeatsToSend:t,unsentEntries:r}=function(e,t=1024){let r=[],i=e.slice();for(let n of e){let e=r.find(e=>e.agent===n.agent);if(e){if(e.dates.push(n.date),J(r)>t){e.dates.pop();break}}else if(r.push({agent:n.agent,dates:[n.date]}),J(r)>t){r.pop();break}i=i.slice(1)}return{heartbeatsToSend:r,unsentEntries:i}}(this._heartbeatsCache.heartbeats),i=(0,l.Uj)(JSON.stringify({version:2,heartbeats:t}));return this._heartbeatsCache.lastSentHeartbeatDate=e,r.length>0?(this._heartbeatsCache.heartbeats=r,await this._storage.overwrite(this._heartbeatsCache)):(this._heartbeatsCache.heartbeats=[],this._storage.overwrite(this._heartbeatsCache)),i}catch(e){return F.warn(e),""}}}function $(){return new Date().toISOString().substring(0,10)}class Y{constructor(e){this.app=e,this._canUseIndexedDBPromise=this.runIndexedDBEnvironmentCheck()}async runIndexedDBEnvironmentCheck(){return!!(0,l.zW)()&&(0,l.eX)().then(()=>!0).catch(()=>!1)}async read(){if(!await this._canUseIndexedDBPromise)return{heartbeats:[]};{let e=await K(this.app);return e?.heartbeats?e:{heartbeats:[]}}}async overwrite(e){if(await this._canUseIndexedDBPromise){let t=await this.read();return H(this.app,{lastSentHeartbeatDate:e.lastSentHeartbeatDate??t.lastSentHeartbeatDate,heartbeats:e.heartbeats})}}async add(e){if(await this._canUseIndexedDBPromise){let t=await this.read();return H(this.app,{lastSentHeartbeatDate:e.lastSentHeartbeatDate??t.lastSentHeartbeatDate,heartbeats:[...t.heartbeats,...e.heartbeats]})}}}function J(e){return(0,l.Uj)(JSON.stringify({version:2,heartbeats:e})).length}x(new s.uA("platform-logger",e=>new C(e),"PRIVATE")),x(new s.uA("heartbeat",e=>new W(e),"PRIVATE")),B(T,S,""),B(T,S,"esm2020"),B("fire-js","")},38377:(e,t,r)=>{"use strict";
1Object.defineProperty(t,"__esModule",{value:!0});var i={default:function(){return F},useLinkStatus:function(){return S}};for(var n in i)Object.defineProperty(t,n,{enumerable:!0,get:i[n]});let a=r(63732),s=r(37876),o=a._(r(14232)),l=r(87943),u=r(71175),c=r(91226),h=r(98608),d=r(58285),m=r(76194),g=r(250),p=r(69543),f=r(88246),y=r(58499),v=new Set;function w(e,t,r,i){if((0,u.isLocalURL)(t)){if(!i.bypassPrefetchedCheck){let n=t+"%"+r+"%"+(void 0!==i.locale?i.locale:"locale"in e?e.locale:void 0);if(v.has(n))return;v.add(n)}e.prefetch(t,r,i).catch(e=>{})}}function b(e){return"string"==typeof e?e:(0,c.formatUrl)(e)}let C=o.default.forwardRef(function(e,t){let r,i,{href:n,as:a,children:c,prefetch:v=null,passHref:C,replace:T,shallow:S,scroll:F,locale:k,onClick:E,onNavigate:A,onMouseEnter:_,onTouchStart:R,legacyBehavior:I=!1,transitionTypes:x,...O}=e;r=c,I&&("string"==typeof r||"number"==typeof r)&&(r=(0,s.jsx)("a",{children:r}));let M=o.default.useContext(m.RouterContext),P=!1!==v,{href:L,as:N}=o.default.useMemo(()=>{if(!M){let e=b(n);return{href:e,as:a?b(a):e}}let[e,t]=(0,l.resolveHref)(M,n,!0);return{href:e,as:a?(0,l.resolveHref)(M,a):t||e}},[M,n,a]),D=o.default.useRef(L),z=o.default.useRef(N);I&&(i=o.default.Children.only(r));let U=I?i&&"object"==typeof i&&i.ref:t,[B,V,j]=(0,g.useIntersection)({rootMargin:"200px"}),G=o.default.useCallback(e=>{(z.current!==N||D.current!==L)&&(j(),z.current=N,D.current=L),B(e)},[N,L,j,B]),K=(0,y.useMergedRef)(G,U);o.default.useEffect(()=>{!M||V&&P&&w(M,L,N,{bypassPrefetchedCheck:!1,locale:k})},[N,L,V,k,P,M?.locale,M]);let H={ref:K,onClick(e){I||"function"!=typeof E||E(e),I&&i.props&&"function"==typeof i.props.onClick&&i.props.onClick(e),!M||e.defaultPrevented||function(e,t,r,i,n,a,s,o,l){let c,{nodeName:h}=e.currentTarget;if(!("A"===h.toUpperCase()&&((c=e.currentTarget.getAttribute("target"))&&"_self"!==c||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||e.nativeEvent&&2===e.nativeEvent.which)||e.currentTarget.hasAttribute("download"))){if(!(0,u.isLocalURL)(r)){n&&(e.preventDefault(),location.replace(r));return}e.preventDefault(),(()=>{if(l){let e=!1;if(l({preventDefault:()=>{e=!0}}),e)return}let e=s??!0;"beforePopState"in t?t[n?"replace":"push"](r,i,{shallow:a,locale:o,scroll:e}):t[n?"replace":"push"](i||r,{scroll:e})})()}}(e,M,L,N,T,S,F,k,A)},onMouseEnter(e){I||"function"!=typeof _||_(e),I&&i.props&&"function"==typeof i.props.onMouseEnter&&i.props.onMouseEnter(e),M&&w(M,L,N,{locale:k,priority:!0,bypassPrefetchedCheck:!0})},onTouchStart:function(e){I||"function"!=typeof R||R(e),I&&i.props&&"function"==typeof i.props.onTouchStart&&i.props.onTouchStart(e),M&&w(M,L,N,{locale:k,priority:!0,bypassPrefetchedCheck:!0})}};if((0,h.isAbsoluteUrl)(N))H.href=N;else if(!I||C||"a"===i.type&&!("href"in i.props)){let e=void 0!==k?k:M?.locale;H.href=M?.isLocaleDomain&&(0,p.getDomainLocale)(N,e,M?.locales,M?.domainLocales)||(0,f.addBasePath)((0,d.addLocale)(N,e,M?.defaultLocale))}return I?o.default.cloneElement(i,H):(0,s.jsx)("a",{...O,...H,children:r})}),T=(0,o.createContext)({pending:!1}),S=()=>(0,o.useContext)(T),F=C;("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},38972:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>C});var i=r(37876),n=r(76988),a=r(77328),s=r.n(a),o=r(89099),l=r(14232);class u extends l.Component{static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e,t){console.error("Unhandled render error caught by ErrorBoundary:",e,t)}render(){return this.state.hasError?(0,i.jsxs)("div",{className:"flex min-h-screen flex-col items-center justify-center gap-4 bg-white px-4 text-center",children:[(0,i.jsx)("p",{className:"text-lg font-semibold text-gray-900",children:"Something went wrong."}),(0,i.jsx)("p",{className:"max-w-sm text-sm text-gray-500",children:"This page hit an unexpected error. Reloading usually fixes it."}),(0,i.jsx)("button",{onClick:()=>window.location.reload(),className:"rounded-md bg-blue-800 px-4 py-2 text-sm font-medium text-white hover:bg-blue-900",children:"Reload"})]}):this.props.children}constructor(...e){super(...e),this.state={hasError:!1}}}var c=r(48166),h=r(99904);let d=(0,l.createContext)(),m=({children:e})=>{let t=h.L.getAllCities();return(0,i.jsx)(c.Z,{children:(0,i.jsx)(d.Provider,{value:{cities:t},children:e})})};var g=r(1825),p=r(25620),f=r(21081);r(18041);let y="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4708941721149314",v=new Set(["/","/feedback","/apps","/social","/merch","/merch/[handle]","/
1pro","/account","/login","/login/email","/login/forgot-password"]);function w(){let{showAds:e}=(0,g.W)(),t=(0,o.useRouter)(),r=(0,l.useRef)(!1),i=v.has(t.pathname)||t.pathname.startsWith("/internal/late-list/");return(0,l.useEffect)(()=>{if(i||!e||r.current||"u"<typeof document||document.querySelector(`script[src="${y}"]`))return;r.current=!0;let t=document.createElement("script");t.src=y,t.async=!0,t.crossOrigin="anonymous",document.head.appendChild(t)},[e,i]),null}function b({Component:e,pageProps:t}){let r=(0,o.useRouter)();return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(s(),{children:[(0,i.jsx)("link",{rel:"icon",href:"/favicon.png"}),(0,i.jsx)("meta",{name:"theme-color",content:"#1e40af"}),(0,i.jsx)("meta",{name:"apple-itunes-app",content:"app-id=6741248139"}),(0,i.jsx)("style",{children:` 2 html { 3 background-color: #1e40af; 4 } 5 `})]}),(0,i.jsx)(w,{}),(0,i.jsx)(n.GoogleAnalytics,{gaId:"G-3TDXEXC8DS"}),(0,i.jsx)("div",{className:"bg-white",children:(0,i.jsx)(u,{children:(0,i.jsx)(e,{...t})},r.asPath.split(/[?#]/)[0])})]})}let C=function({Component:e,pageProps:t}){return(0,i.jsx)(m,{children:(0,i.jsx)(p.O,{children:(0,i.jsx)(f.$,{children:(0,i.jsx)(g.P,{children:(0,i.jsx)(b,{Component:e,pageProps:t})})})})})}},39126:(e,t,r)=>{"use strict";function i(e,t="/account/"){return"string"!=typeof e||!e.startsWith("/")||e.startsWith("//")||/[\\\x00-\x20]/.test(e)?t:e}function n(e){switch(e?.code){case"auth/popup-closed-by-user":case"auth/cancelled-popup-request":return"Sign-in was cancelled. You can try again when youâre ready.";case"auth/popup-blocked":return"Your browser blocked the sign-in window. Allow pop-ups for this site and try again.";case"auth/account-exists-with-different-credential":case"auth/credential-already-in-use":return"This sign-in belongs to an existing account. Sign in with the method you used before. You can link another sign-in method from your account.";case"auth/network-request-failed":return"Unable to connect. Check your connection and try again.";default:return"Unable to sign in. Please try again."}}function a(e){return[{id:"annual",label:"Annual",period:"year",duration:"P1Y",package:e?.annual},{id:"monthly",label:"Monthly",period:"month",duration:"P1M",package:e?.monthly}].filter(e=>e.package?.webBillingProduct?.normalPeriodDuration===e.duration)}r.d(t,{Ap:()=>a,C1:()=>n,bk:()=>i})},40125:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function({html:e,height:t=null,width:r=null,children:a,dataNtpc:s=""}){return(0,n.useEffect)(()=>{s&&performance.mark("mark_feature_usage",{detail:{feature:`next-third-parties-${s}`}})},[s]),(0,i.jsxs)(i.Fragment,{children:[a,e?(0,i.jsx)("div",{style:{height:null!=t?`${t}px`:"auto",width:null!=r?`${r}px`:"auto"},"data-ntpc":s,dangerouslySetInnerHTML:{__html:e}}):null]})};let i=r(37876),n=r(14232)},45105:(e,t,r)=>{e.exports=r(2470)},45434:(e,t,r)=>{"use strict";r.d(t,{gS:()=>sh,rJ:()=>ay,H9:()=>av,x7:()=>sl,GG:()=>su,aU:()=>aS,AB:()=>a7,aQ:()=>sd,My:()=>a6,P:()=>a2,O5:()=>aW,BN:()=>sc,_M:()=>a4});var i,n,a,s,o,l,u,c,h,d,m,g,p,f,y=r(36672),v=r(21610),w=r(76653),b="u">typeof globalThis?globalThis:"u">typeof window?window:"u">typeof global?global:"u">typeof self?self:{},C={};(function(){function e(){this.blockSize=-1,this.blockSize=64,this.g=[,,,,],this.C=Array(this.blockSize),this.o=this.h=0,this.u()}var t=function(){this.blockSize=-1};function r(){}function a(e,t,r){r||(r=0);let i=Array(16);if("string"==typeof t)for(var n=0;n<16;++n)i[n]=t.charCodeAt(r++)|t.charCodeAt(r++)<<8|t.charCodeAt(r++)<<16|t.charCodeAt(r++)<<24;else for(n=0;n<16;++n)i[n]=t[r++]|t[r++]<<8|t[r++]<<16|t[r++]<<24;t=e.g[0],r=e.g[1],n=e.g[2];let a=e.g[3],s;s=t+(a^r&(n^a))+i[0]+0xd76aa478|0,s=a+(n^(t=r+(s<<7|s>>>25))&(r^n))+i[1]+0xe8c7b756|0,s=n+(r^(a=t+(s<<12|s>>>20))&(t^r))+i[2]+0x242070db|0,s=r+(t^(n=a+(s<<17|s>>>15))&(a^t))+i[3]+0xc1bdceee|0,s=t+(a^(r=n+(s<<22|s>>>10))&(n^a))+i[4]+0xf57c0faf|0,s=a+(n^(t=r+(s<<7|s>>>25))&(r^n))+i[5]+0x4787c62a|0,s=n+(r^(a=t+(s<<12|s>>>20))&(t^r))+i[6]+0xa8304613|0,s=r+(t^(n=a+(s<<17|s>>>
515))&(a^t))+i[7]+0xfd469501|0,s=t+(a^(r=n+(s<<22|s>>>10))&(n^a))+i[8]+0x698098d8|0,s=a+(n^(t=r+(s<<7|s>>>25))&(r^n))+i[9]+0x8b44f7af|0,s=n+(r^(a=t+(s<<12|s>>>20))&(t^r))+i[10]+0xffff5bb1|0,s=r+(t^(n=a+(s<<17|s>>>15))&(a^t))+i[11]+0x895cd7be|0,s=t+(a^(r=n+(s<<22|s>>>10))&(n^a))+i[12]+0x6b901122|0,s=a+(n^(t=r+(s<<7|s>>>25))&(r^n))+i[13]+0xfd987193|0,s=n+(r^(a=t+(s<<12|s>>>20))&(t^r))+i[14]+0xa679438e|0,s=r+(t^(n=a+(s<<17|s>>>15))&(a^t))+i[15]+0x49b40821|0,r=n+(s<<22|s>>>10),s=t+(n^a&(r^n))+i[1]+0xf61e2562|0,t=r+(s<<5|s>>>27),s=a+(r^n&(t^r))+i[6]+0xc040b340|0,a=t+(s<<9|s>>>23),s=n+(t^r&(a^t))+i[11]+0x265e5a51|0,n=a+(s<<14|s>>>18),s=r+(a^t&(n^a))+i[0]+0xe9b6c7aa|0,r=n+(s<<20|s>>>12),s=t+(n^a&(r^n))+i[5]+0xd62f105d|0,t=r+(s<<5|s>>>27),s=a+(r^n&(t^r))+i[10]+0x2441453|0,a=t+(s<<9|s>>>23),s=n+(t^r&(a^t))+i[15]+0xd8a1e681|0,n=a+(s<<14|s>>>18),s=r+(a^t&(n^a))+i[4]+0xe7d3fbc8|0,r=n+(s<<20|s>>>12),s=t+(n^a&(r^n))+i[9]+0x21e1cde6|0,t=r+(s<<5|s>>>27),s=a+(r^n&(t^r))+i[14]+0xc33707d6|0,a=t+(s<<9|s>>>23),s=n+(t^r&(a^t))+i[3]+0xf4d50d87|0,n=a+(s<<14|s>>>18),s=r+(a^t&(n^a))+i[8]+0x455a14ed|0,r=n+(s<<20|s>>>12),s=t+(n^a&(r^n))+i[13]+0xa9e3e905|0,t=r+(s<<5|s>>>27),s=a+(r^n&(t^r))+i[2]+0xfcefa3f8|0,a=t+(s<<9|s>>>23),s=n+(t^r&(a^t))+i[7]+0x676f02d9|0,n=a+(s<<14|s>>>18),s=r+(a^t&(n^a))+i[12]+0x8d2a4c8a|0,s=t+((r=n+(s<<20|s>>>12))^n^a)+i[5]+0xfffa3942|0,s=a+((t=r+(s<<4|s>>>28))^r^n)+i[8]+0x8771f681|0,s=n+((a=t+(s<<11|s>>>21))^t^r)+i[11]+0x6d9d6122|0,s=r+((n=a+(s<<16|s>>>16))^a^t)+i[14]+0xfde5380c|0,s=t+((r=n+(s<<23|s>>>9))^n^a)+i[1]+0xa4beea44|0,s=a+((t=r+(s<<4|s>>>28))^r^n)+i[4]+0x4bdecfa9|0,s=n+((a=t+(s<<11|s>>>21))^t^r)+i[7]+0xf6bb4b60|0,s=r+((n=a+(s<<16|s>>>16))^a^t)+i[10]+0xbebfbc70|0,s=t+((r=n+(s<<23|s>>>9))^n^a)+i[13]+0x289b7ec6|0,s=a+((t=r+(s<<4|s>>>28))^r^n)+i[0]+0xeaa127fa|0,s=n+((a=t+(s<<11|s>>>21))^t^r)+i[3]+0xd4ef3085|0,s=r+((n=a+(s<<16|s>>>16))^a^t)+i[6]+0x4881d05|0,s=t+((r=n+(s<<23|s>>>9))^n^a)+i[9]+0xd9d4d039|0,s=a+((t=r+(s<<4|s>>>28))^r^n)+i[12]+0xe6db99e5|0,s=n+((a=t+(s<<11|s>>>21))^t^r)+i[15]+0x1fa27cf8|0,s=r+((n=a+(s<<16|s>>>16))^a^t)+i[2]+0xc4ac5665|0,r=n+(s<<23|s>>>9),s=t+(n^(r|~a))+i[0]+0xf4292244|0,t=r+(s<<6|s>>>26),s=a+(r^(t|~n))+i[7]+0x432aff97|0,a=t+(s<<10|s>>>22),s=n+(t^(a|~r))+i[14]+0xab9423a7|0,n=a+(s<<15|s>>>17),s=r+(a^(n|~t))+i[5]+0xfc93a039|0,r=n+(s<<21|s>>>11),s=t+(n^(r|~a))+i[12]+0x655b59c3|0,t=r+(s<<6|s>>>26),s=a+(r^(t|~n))+i[3]+0x8f0ccc92|0,a=t+(s<<10|s>>>22),s=n+(t^(a|~r))+i[10]+0xffeff47d|0,n=a+(s<<15|s>>>17),s=r+(a^(n|~t))+i[1]+0x85845dd1|0,r=n+(s<<21|s>>>11),s=t+(n^(r|~a))+i[8]+0x6fa87e4f|0,t=r+(s<<6|s>>>26),s=a+(r^(t|~n))+i[15]+0xfe2ce6e0|0,a=t+(s<<10|s>>>22),s=n+(t^(a|~r))+i[6]+0xa3014314|0,n=a+(s<<15|s>>>17),s=r+(a^(n|~t))+i[13]+0x4e0811a1|0,r=n+(s<<21|s>>>11),s=t+(n^(r|~a))+i[4]+0xf7537e82|0,t=r+(s<<6|s>>>26),s=a+(r^(t|~n))+i[11]+0xbd3af235|0,a=t+(s<<10|s>>>22),s=n+(t^(a|~r))+i[2]+0x2ad7d2bb|0,n=a+(s<<15|s>>>17),s=r+(a^(n|~t))+i[9]+0xeb86d391|0,e.g[0]=e.g[0]+t|0,e.g[1]=e.g[1]+(n+(s<<21|s>>>11))|0,e.g[2]=e.g[2]+n|0,e.g[3]=e.g[3]+a|0}function s(e,t){this.h=t;let r=[],i=!0;for(let n=e.length-1;n>=0;n--){let a=0|e[n];i&&a==t||(r[n]=a,i=!1)}this.g=r}r.prototype=t.prototype,e.F=t.prototype,e.prototype=new r,e.prototype.constructor=e,e.D=function(e,r,i){for(var n=Array(arguments.length-2),a=2;a<arguments.length;a++)n[a-2]=arguments[a];return t.prototype[r].apply(e,n)},e.prototype.u=function(){this.g[0]=0x67452301,this.g[1]=0xefcdab89,this.g[2]=0x98badcfe,this.g[3]=0x10325476,this.o=this.h=0},e.prototype.v=function(e,t){void 0===t&&(t=e.length);let r=t-this.blockSize,i=this.C,n=this.h,s=0;for(;s<t;){if(0==n)for(;s<=r;)a(this,e,s),s+=this.blockSize;if("string"==typeof e){for(;s<t;)if(i[n++]=e.charCodeAt(s++),n==this.blockSize){a(this,i),n=0;break}}else for(;s<t;)if(i[n++]=e[s++],n==this.blockSize){a(this,i),n=0;break}}this.h=n,this.o+=t},e.prototype.A=function(){var e=Array((this.h<56?this.blockSize:2*this.blockSize)-this.h);e[0]=128;for(var t=1;t<e.length-8;++t)e[t]=0;t=8*this.o;for(var r=e.length-8;r<e.length;++r)e[r]=255&t,t/=256;for(this.v(e),e=Array(16),t=0,r=0;r<4;++r)for(let i=0;i<32;i+=8)e[t++]=this.g[r]>>>i&255;return e};var o,l={};function u(e){var t;return -128<=e&&e<128?(t=function(e){return new s([0|e],e<0?-1:0)},Object.prototype.hasOwnProperty.call(l,e)?l[e]:l[e]=t(e)):new s([0|e],e<0?-1:0)}function c(e){if(isNaN(e)||!isFinite(e))return h;if(e<0)return f(c(-e));let t=[],r=1;for(let i=0;e>=r;i++)t[i]=e/r|0,r*=0x100000000;return new s(t,0)}var h=u(0),d=u(1),m=u(0x1000000);function g(e){if(0!=e.h)return!1;for(let t=0;t<e.g.length;t++)if(0!=e.g[t])return!1;return!0}function p(e){return -1==e.h}function f(e){let t=e.g.length,r=[];for(let i=0;i<t;i++)r[i]=~e.g[i];return new s(r,~e.h).add(d)}function y(e,t){return e.add(f(t))}function v(e,t){for(;(65535&e[t])!=e[t];)e[t+1]+=e[t]>>>16,e[t]&=65535,t++}function w(e,t){this.g=e,this.h=t}function b(e,t){if(g(t))throw Error("division by zero");
5if(g(e))return new w(h,h);if(p(e))return t=b(f(e),t),new w(f(t.g),f(t.h));if(p(t))return t=b(e,f(t)),new w(f(t.g),t.h);if(e.g.length>30){if(p(e)||p(t))throw Error("slowDivide_ only works with positive integers.");for(var r=d,i=t;0>=i.l(e);)r=T(r),i=T(i);var n=S(r,1),a=S(i,1);for(i=S(i,2),r=S(r,2);!g(i);){var s=a.add(i);0>=s.l(e)&&(n=n.add(r),a=s),i=S(i,1),r=S(r,1)}return t=y(e,n.j(t)),new w(n,t)}for(n=h;e.l(t)>=0;){for(i=(i=Math.ceil(Math.log(r=Math.max(1,Math.floor(e.m()/t.m())))/Math.LN2))<=48?1:Math.pow(2,i-48),s=(a=c(r)).j(t);p(s)||s.l(e)>0;)r-=i,s=(a=c(r)).j(t);g(a)&&(a=d),n=n.add(a),e=y(e,s)}return new w(n,e)}function T(e){let t=e.g.length+1,r=[];for(let i=0;i<t;i++)r[i]=e.i(i)<<1|e.i(i-1)>>>31;return new s(r,e.h)}function S(e,t){let r=t>>5;t%=32;let i=e.g.length-r,n=[];for(let a=0;a<i;a++)n[a]=t>0?e.i(a+r)>>>t|e.i(a+r+1)<<32-t:e.i(a+r);return new s(n,e.h)}(o=s.prototype).m=function(){if(p(this))return-f(this).m();let e=0,t=1;for(let r=0;r<this.g.length;r++){let i=this.i(r);e+=(i>=0?i:0x100000000+i)*t,t*=0x100000000}return e},o.toString=function(e){if((e=e||10)<2||36<e)throw Error("radix out of range: "+e);if(g(this))return"0";if(p(this))return"-"+f(this).toString(e);let t=c(Math.pow(e,6));var r=this;let i="";for(;;){let n=b(r,t).g,a=(((r=y(r,n.j(t))).g.length>0?r.g[0]:r.h)>>>0).toString(e);if(g(r=n))return a+i;for(;a.length<6;)a="0"+a;i=a+i}},o.i=function(e){return e<0?0:e<this.g.length?this.g[e]:this.h},o.l=function(e){return p(e=y(this,e))?-1:+!g(e)},o.abs=function(){return p(this)?f(this):this},o.add=function(e){let t=Math.max(this.g.length,e.g.length),r=[],i=0;for(let n=0;n<=t;n++){let t=i+(65535&this.i(n))+(65535&e.i(n)),a=(t>>>16)+(this.i(n)>>>16)+(e.i(n)>>>16);i=a>>>16,t&=65535,a&=65535,r[n]=a<<16|t}return new s(r,-0x80000000&r[r.length-1]?-1:0)},o.j=function(e){if(g(this)||g(e))return h;if(p(this))return p(e)?f(this).j(f(e)):f(f(this).j(e));if(p(e))return f(this.j(f(e)));if(0>this.l(m)&&0>e.l(m))return c(this.m()*e.m());let t=this.g.length+e.g.length,r=[];for(var i=0;i<2*t;i++)r[i]=0;for(i=0;i<this.g.length;i++)for(let t=0;t<e.g.length;t++){let n=this.i(i)>>>16,a=65535&this.i(i),s=e.i(t)>>>16,o=65535&e.i(t);r[2*i+2*t]+=a*o,v(r,2*i+2*t),r[2*i+2*t+1]+=n*o,v(r,2*i+2*t+1),r[2*i+2*t+1]+=a*s,v(r,2*i+2*t+1),r[2*i+2*t+2]+=n*s,v(r,2*i+2*t+2)}for(e=0;e<t;e++)r[e]=r[2*e+1]<<16|r[2*e];for(e=t;e<2*t;e++)r[e]=0;return new s(r,0)},o.B=function(e){return b(this,e).h},o.and=function(e){let t=Math.max(this.g.length,e.g.length),r=[];for(let i=0;i<t;i++)r[i]=this.i(i)&e.i(i);return new s(r,this.h&e.h)},o.or=function(e){let t=Math.max(this.g.length,e.g.length),r=[];for(let i=0;i<t;i++)r[i]=this.i(i)|e.i(i);return new s(r,this.h|e.h)},o.xor=function(e){let t=Math.max(this.g.length,e.g.length),r=[];for(let i=0;i<t;i++)r[i]=this.i(i)^e.i(i);return new s(r,this.h^e.h)},e.prototype.digest=e.prototype.A,e.prototype.reset=e.prototype.u,e.prototype.update=e.prototype.v,n=C.Md5=e,s.prototype.add=s.prototype.add,s.prototype.multiply=s.prototype.j,s.prototype.modulo=s.prototype.B,s.prototype.compare=s.prototype.l,s.prototype.toNumber=s.prototype.m,s.prototype.toString=s.prototype.toString,s.prototype.getBits=s.prototype.i,s.fromNumber=c,s.fromString=function e(t,r){if(0==t.length)throw Error("number format error: empty string");if((r=r||10)<2||36<r)throw Error("radix out of range: "+r);if("-"==t.charAt(0))return f(e(t.substring(1),r));if(t.indexOf("-")>=0)throw Error('number format error: interior "-" character');let i=c(Math.pow(r,8)),n=h;for(let e=0;e<t.length;e+=8){var a=Math.min(8,t.length-e);let s=parseInt(t.substring(e,e+a),r);a<8?(a=c(Math.pow(r,a)),n=n.j(a).add(c(s))):n=(n=n.j(i)).add(c(s))}return n},i=C.Integer=s}).apply(void 0!==b?b:"u">typeof self?self:"u">typeof window?window:{});var T=r(29979),S="u">typeof globalThis?globalThis:"u">typeof window?window:"u">typeof global?global:"u">typeof self?self:{},F={};(function(){var e,t,r=Object.defineProperty,i=function(e){e=["object"==typeof globalThis&&globalThis,e,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof S&&S];for(var t=0;t<e.length;++t){var r=e[t];if(r&&r.Math==Math)return r}throw Error("Cannot find global object")}(this);function n(e,t){if(t)e:{var n=i;e=e.split(".");for(var a=0;a<e.length-1;a++){var s=e[a];if(!(s in n))break e;n=n[s]}(t=t(a=n[e=e[e.length-1]]))!=a&&null!=t&&r(n,e,{configurable:!0,writable:!0,value:t})}}n("Symbol.dispose",function(e){return e||Symbol("Symbol.dispose")}),n("Array.prototype.values",function(e){return e||function(){return this[Symbol.iterator]()}}),n("Object.entries",function(e){return e||function(e){var t,r=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&r.push([t,e[t]]);return r}});var m=m||{},g=this||self;function p(e){var t=typeof e;return"object"==t&&null!=e||"function"==t}function f(e,t,r){return e.call.apply(e.bind,arguments)}function y(e,t,r){return(y=f).apply(null,arguments)}
5function v(e,t){var r=Array.prototype.slice.call(arguments,1);return function(){var t=r.slice();return t.push.apply(t,arguments),e.apply(this,t)}}function w(e,t){function r(){}r.prototype=t.prototype,e.Z=t.prototype,e.prototype=new r,e.prototype.constructor=e,e.Ob=function(e,r,i){for(var n=Array(arguments.length-2),a=2;a<arguments.length;a++)n[a-2]=arguments[a];return t.prototype[r].apply(e,n)}}var b="u">typeof AsyncContext&&"function"==typeof AsyncContext.Snapshot?e=>e&&AsyncContext.Snapshot.wrap(e):e=>e;function C(e){let t=e.length;if(t>0){let r=Array(t);for(let i=0;i<t;i++)r[i]=e[i];return r}return[]}function T(e,t){for(let t=1;t<arguments.length;t++){let i=arguments[t];var r=typeof i;if("array"==(r="object"!=r?r:i?Array.isArray(i)?"array":r:"null")||"object"==r&&"number"==typeof i.length){r=e.length||0;let t=i.length||0;e.length=r+t;for(let n=0;n<t;n++)e[r+n]=i[n]}else e.push(i)}}class k{constructor(e,t){this.i=e,this.j=t,this.h=0,this.g=null}get(){let e;return this.h>0?(this.h--,e=this.g,this.g=e.next,e.next=null):e=this.i(),e}}class E{constructor(){this.h=this.g=null}add(e,t){let r=A.get();r.set(e,t),this.h?this.h.next=r:this.g=r,this.h=r}}var A=new k(()=>new _,e=>e.reset());class _{constructor(){this.next=this.g=this.h=null}set(e,t){this.h=e,this.g=t,this.next=null}reset(){this.next=this.g=this.h=null}}let R,I=!1,x=new E,O=()=>{let e=Promise.resolve(void 0);R=()=>{e.then(M)}};function M(){let e;for(var t;e=null,x.g&&(e=x.g,x.g=x.g.next,x.g||(x.h=null),e.next=null),t=e;){try{t.h.call(t.g)}catch(e){!function(e){g.setTimeout(()=>{throw e},0)}(e)}A.j(t),A.h<100&&(A.h++,t.next=A.g,A.g=t)}I=!1}function P(){this.u=this.u,this.C=this.C}function L(e,t){this.type=e,this.g=this.target=t,this.defaultPrevented=!1}P.prototype.u=!1,P.prototype.dispose=function(){this.u||(this.u=!0,this.N())},P.prototype[Symbol.dispose]=function(){this.dispose()},P.prototype.N=function(){if(this.C)for(;this.C.length;)this.C.shift()()},L.prototype.h=function(){this.defaultPrevented=!0};var N=function(){if(!g.addEventListener||!Object.defineProperty)return!1;var e=!1,t=Object.defineProperty({},"passive",{get:function(){e=!0}});try{let e=()=>{};g.addEventListener("test",e,t),g.removeEventListener("test",e,t)}catch(e){}return e}();function D(e){return/^[\s\xa0]*$/.test(e)}function z(e,t){L.call(this,e?e.type:""),this.relatedTarget=this.g=this.target=null,this.button=this.screenY=this.screenX=this.clientY=this.clientX=0,this.key="",this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1,this.state=null,this.pointerId=0,this.pointerType="",this.i=null,e&&this.init(e,t)}w(z,L),z.prototype.init=function(e,t){let r=this.type=e.type,i=e.changedTouches&&e.changedTouches.length?e.changedTouches[0]:null;this.target=e.target||e.srcElement,this.g=t,(t=e.relatedTarget)||("mouseover"==r?t=e.fromElement:"mouseout"==r&&(t=e.toElement)),this.relatedTarget=t,i?(this.clientX=void 0!==i.clientX?i.clientX:i.pageX,this.clientY=void 0!==i.clientY?i.clientY:i.pageY,this.screenX=i.screenX||0,this.screenY=i.screenY||0):(this.clientX=void 0!==e.clientX?e.clientX:e.pageX,this.clientY=void 0!==e.clientY?e.clientY:e.pageY,this.screenX=e.screenX||0,this.screenY=e.screenY||0),this.button=e.button,this.key=e.key||"",this.ctrlKey=e.ctrlKey,this.altKey=e.altKey,this.shiftKey=e.shiftKey,this.metaKey=e.metaKey,this.pointerId=e.pointerId||0,this.pointerType=e.pointerType,this.state=e.state,this.i=e,e.defaultPrevented&&z.Z.h.call(this)},z.prototype.h=function(){z.Z.h.call(this);let e=this.i;e.preventDefault?e.preventDefault():e.returnValue=!1};var U="closure_listenable_"+(1e6*Math.random()|0),B=0;function V(e,t,r,i,n){this.listener=e,this.proxy=null,this.src=t,this.type=r,this.capture=!!i,this.ha=n,this.key=++B,this.da=this.fa=!1}function j(e){e.da=!0,e.listener=null,e.proxy=null,e.src=null,e.ha=null}function G(e,t,r){for(let i in e)t.call(r,e[i],i,e)}function K(e){let t={};for(let r in e)t[r]=e[r];return t}let H="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");function q(e,t){let r,i;for(let t=1;t<arguments.length;t++){for(r in i=arguments[t])e[r]=i[r];for(let t=0;t<H.length;t++)r=H[t],Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r])}}function W(e){this.src=e,this.g={},this.h=0}function $(e,t){let r=t.type;if(r in e.g){var i,n=e.g[r],a=Array.prototype.indexOf.call(n,t,void 0);(i=a>=0)&&Array.prototype.splice.call(n,a,1),i&&(j(t),0==e.g[r].length&&(delete e.g[r],e.h--))}}
5function Y(e,t,r,i){for(let n=0;n<e.length;++n){let a=e[n];if(!a.da&&a.listener==t&&!!r==a.capture&&a.ha==i)return n}return -1}W.prototype.add=function(e,t,r,i,n){let a=e.toString();(e=this.g[a])||(e=this.g[a]=[],this.h++);let s=Y(e,t,i,n);return s>-1?(t=e[s],r||(t.fa=!1)):((t=new V(t,this.src,a,!!i,n)).fa=r,e.push(t)),t};var J="closure_lm_"+(1e6*Math.random()|0),Q={};function X(e,t,r,i,n,a){if(!t)throw Error("Invalid event type");let s=p(n)?!!n.capture:!!n,o=er(e);if(o||(e[J]=o=new W(e)),(r=o.add(t,r,i,s,a)).proxy)return r;if(i=function e(t){return et.call(e.src,e.listener,t)},r.proxy=i,i.src=e,i.listener=r,e.addEventListener)N||(n=s),void 0===n&&(n=!1),e.addEventListener(t.toString(),i,n);else if(e.attachEvent)e.attachEvent(ee(t.toString()),i);else if(e.addListener&&e.removeListener)e.addListener(i);else throw Error("addEventListener and attachEvent are unavailable.");return r}function Z(e){if("number"!=typeof e&&e&&!e.da){var t=e.src;if(t&&t[U])$(t.i,e);else{var r=e.type,i=e.proxy;t.removeEventListener?t.removeEventListener(r,i,e.capture):t.detachEvent?t.detachEvent(ee(r),i):t.addListener&&t.removeListener&&t.removeListener(i),(r=er(t))?($(r,e),0==r.h&&(r.src=null,t[J]=null)):j(e)}}}function ee(e){return e in Q?Q[e]:Q[e]="on"+e}function et(e,t){if(e.da)e=!0;else{t=new z(t,this);let r=e.listener,i=e.ha||e.src;e.fa&&Z(e),e=r.call(i,t)}return e}function er(e){return(e=e[J])instanceof W?e:null}var ei="__closure_events_fn_"+(1e9*Math.random()>>>0);function en(e){return"function"==typeof e?e:(e[ei]||(e[ei]=function(t){return e.handleEvent(t)}),e[ei])}function ea(){P.call(this),this.i=new W(this),this.M=this,this.G=null}function es(e,t){let r,i;var n,a=e.G;if(a)for(n=[];a;a=a.G)n.push(a);if(e=e.M,a=t.type||t,"string"==typeof t)t=new L(t,e);else if(t instanceof L)t.target=t.target||e;else{var s=t;q(t=new L(a,e),s)}if(s=!0,n)for(i=n.length-1;i>=0;i--)s=eo(r=t.g=n[i],a,!0,t)&&s;if(s=eo(r=t.g=e,a,!0,t)&&s,s=eo(r,a,!1,t)&&s,n)for(i=0;i<n.length;i++)s=eo(r=t.g=n[i],a,!1,t)&&s}function eo(e,t,r,i){if(!(t=e.i.g[String(t)]))return!0;t=t.concat();let n=!0;for(let a=0;a<t.length;++a){let s=t[a];if(s&&!s.da&&s.capture==r){let t=s.listener,r=s.ha||s.src;s.fa&&$(e.i,s),n=!1!==t.call(r,i)&&n}}return n&&!i.defaultPrevented}w(ea,P),ea.prototype[U]=!0,ea.prototype.removeEventListener=function(e,t,r,i){!function e(t,r,i,n,a){if(Array.isArray(r))for(var s=0;s<r.length;s++)e(t,r[s],i,n,a);else(n=p(n)?!!n.capture:!!n,i=en(i),t&&t[U])?(t=t.i,(s=String(r).toString())in t.g&&(i=Y(r=t.g[s],i,n,a))>-1&&(j(r[i]),Array.prototype.splice.call(r,i,1),0==r.length&&(delete t.g[s],t.h--))):t&&(t=er(t))&&(r=t.g[r.toString()],t=-1,r&&(t=Y(r,i,n,a)),(i=t>-1?r[t]:null)&&Z(i))}(this,e,t,r,i)},ea.prototype.N=function(){if(ea.Z.N.call(this),this.i){var e=this.i;for(let t in e.g){let r=e.g[t];for(let e=0;e<r.length;e++)j(r[e]);delete e.g[t],e.h--}}this.G=null},ea.prototype.J=function(e,t,r,i){return this.i.add(String(e),t,!1,r,i)},ea.prototype.K=function(e,t,r,i){return this.i.add(String(e),t,!0,r,i)};class el extends P{constructor(e,t){super(),this.m=e,this.l=t,this.h=null,this.i=!1,this.g=null}j(e){this.h=arguments,this.g?this.i=!0:function e(t){t.g=function(e,t){if("function"!=typeof e)if(e&&"function"==typeof e.handleEvent)e=y(e.handleEvent,e);else throw Error("Invalid listener argument");return Number(t)>0x7fffffff?-1:g.setTimeout(e,t||0)}(()=>{t.g=null,t.i&&(t.i=!1,e(t))},t.l);let r=t.h;t.h=null,t.m.apply(null,r)}(this)}N(){super.N(),this.g&&(g.clearTimeout(this.g),this.g=null,this.i=!1,this.h=null)}}function eu(e){P.call(this),this.h=e,this.g={}}w(eu,P);var ec=[];function eh(e){G(e.g,function(e,t){this.g.hasOwnProperty(t)&&Z(e)},e),e.g={}}eu.prototype.N=function(){eu.Z.N.call(this),eh(this)},eu.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented")};var ed=g.JSON.stringify,em=g.JSON.parse,eg=class{stringify(e){return g.JSON.stringify(e,void 0)}parse(e){return g.JSON.parse(e,void 0)}};function ep(){}function ef(){}var ey={OPEN:"a",hb:"b",ERROR:"c",tb:"d"};function ev(){L.call(this,"d")}function ew(){L.call(this,"c")}w(ev,L),w(ew,L);var eb={},eC=null;function eT(){return eC=eC||new ea}function eS(e){L.call(this,eb.Ia,e)}function eF(e){let t=eT();es(t,new eS(t))}function ek(e,t){L.call(this,eb.STAT_EVENT,e),this.stat=t}function eE(e){let t=eT();es(t,new ek(t,e))}function eA(e,t){L.call(this,eb.Ja,e),this.size=t}function e_(e,t){if("function"!=typeof e)throw Error("Fn must not be null and must be a function");return g.setTimeout(function(){e()},t)}function eR(){this.g=!0}function eI(e,t,r,i){e.info(function(){return"XMLHTTP TEXT ("+t+"): "+function(e,t){if(!e.g)return t;if(!t)return null;try{let a=JSON.parse(t);if(a){for(e=0;e<a.length;e++)if(Array.isArray(a[e])){var r=a[e];if(!(r.length<2)){var i=r[1];if(Array.isArray(i)&&!(i.length<1)){var n=i[0];if("noop"!=n&&"stop"!=n&&"close"!=n)for(let e=1;e<i.length;e++)i[e]=""}}}}return ed(a)}catch(e){return t}}(e,r)+(i?" "+i:"")})}eb.Ia="serverreachability",w(eS,L),eb.STAT_EVENT="statevent",w(ek,L),eb.Ja="timingevent",w(eA,L),eR.prototype.ua=function(){this.g=!1},eR.prototype.info=function(){};var ex={NO_ERROR:0,cb:1,qb:2,pb:3,kb:4,ob:5,rb:6,Ga:7,TIMEOUT:8,ub:9},eO={ib:"complete",Fb:"success",ERROR:"error",Ga:"abort",xb:"ready",yb:"readystatechange",TIMEOUT:"timeout",sb:"incrementaldata",wb:"progress",lb:"downloadprogress",Nb:"uploadprogress"};function eM(){}function eP(e){return encodeURIComponent(String(e))}function eL(e,t,r,i){this.j=e,this.i=t,this.l=r,this.S=i||1,this.V=new eu(this),this.H=45e3,this.J=null,this.o=!1,this.u=this.B=this.A=this.M=this.F=this.T=this.D=null,this.G=[],this.g=null,this.C=0,this.m=this.v=null,this.X=-1,this.K=!1,this.P=0,this.O=null,this.W=this.L=this.U=this.R=!1,this.h=new eN}function eN(){this.i=null,this.g="",this.h=!1}w(eM,ep),eM.prototype.g=function(){return new XMLHttpRequest},e=new eM;var eD={},ez={};function eU(e,t,r){e.M=1,e.A=e7(e4(t)),e.u=r,e.R=!0,eB(e,null)}function eB(e,t){e.F=Date.now(),ej(e),e.B=e4(e.A);var r,i,n,a,s,o,l=e.B,u=e.S;Array.isArray(u)||(u=[String(u)]),tm(l.i,"t",u),e.C=0,l=e.j.L,e.h=new eN,e.g=tZ(e.j,l?t:null,!e.u),e.P>0&&(e.O=new el(y(e.Y,e,e.g),e.P)),t=e.V,l=e.g,u=e.ba;var c="readystatechange";Array.isArray(c)||(c&&(ec[0]=c.toString()),c=ec);for(let e=0;e<c.length;e++){let r=function e(t,r,i,n,a){if(n&&n.once)return function e(t,r,i,n,a){if(Array.isArray(r)){for(let s=0;s<r.length;s++)e(t,r[s],i,n,a);return null}return i=en(i),t&&t[U]?t.K(r,i,p(n)?!!n.capture:!!n,a):X(t,r,i,!0,n,a)}(t,r,i,n,a);if(Array.isArray(r)){for(let s=0;s<r.length;s++)e(t,r[s],i,n,a);return null}return i=en(i),t&&t[U]?t.J(r,i,p(n)?!!n.capture:!!n,a):X(t,r,i,!1,n,a)}(l,c[e],u||t.handleEvent,!1,t.h||t);if(!r)break;t.g[r.key]=r}t=e.J?K(e.J):{},e.u?(e.v||(e.v="POST"),t["Content-Type"]="application/x-www-form-urlencoded",e.g.ea(e.B,e.v,e.u,t)):(e.v="GET",e.g.ea(e.B,e.v,null,t)),eF(),r=e.i,i=e.v,n=e.B,a=e.l,s=e.S,o=e.u,r.info(function(){if(r.g)if(o){var e="",t=o.split("&");for(let r=0;r<t.length;r++){var l=t[r].split("=");if(l.length>1){let t=l[0];l=l[1];let r=t.split("_");e=r.length>=2&&"type"==r[1]?e+(t+"=")+l+"&":e+(t+"=redacted&")}}}else e=null;else e=o;return"XMLHTTP REQ ("+a+") [attempt "+s+"]: "+i+"\n"+n+"\n"+e})}function eV(e){return!!e.g&&"GET"==e.v&&2!=e.M&&e.j.Aa}function ej(e){e.T=Date.now()+e.H,eG(e,e.H)}function eG(e,t){if(null!=e.D)throw Error("WatchDog timer not null");e.D=e_(y(e.aa,e),t)}function eK(e){e.D&&(g.clearTimeout(e.D),e.D=null)}function eH(e){0==e.j.I||e.K||t$(e.j,e)}function eq(e){eK(e);var t=e.O;t&&"function"==typeof t.dispose&&t.dispose(),e.O=null,eh(e.V),e.g&&(t=e.g,e.g=null,t.abort(),t.dis
5pose())}function eW(e,t){try{var r=e.j;if(0!=r.I&&(r.g==e||eX(r.h,e))){if(!e.L&&eX(r.h,e)&&3==r.I){try{var i=r.Ba.g.parse(t)}catch(e){i=null}if(Array.isArray(i)&&3==i.length){var n=i;if(0==n[0]){e:if(!r.v){if(r.g)if(r.g.F+3e3<e.F)tW(r),tD(r);else break e;tK(r),eE(18)}}else r.xa=n[1],0<r.xa-r.K&&n[2]<37500&&r.F&&0==r.A&&!r.C&&(r.C=e_(y(r.Va,r),6e3));1>=eQ(r.h)&&r.ta&&(r.ta=void 0)}else tJ(r,11)}else if((e.L||r.g==e)&&tW(r),!D(t))for(n=r.Ba.g.parse(t),t=0;t<n.length;t++){let o=n[t],l=o[0];if(!(l<=r.K))if(r.K=l,o=o[1],2==r.I)if("c"==o[0]){r.M=o[1],r.ba=o[2];let t=o[3];null!=t&&(r.ka=t,r.j.info("VER="+r.ka));let n=o[4];null!=n&&(r.za=n,r.j.info("SVER="+r.za));let l=o[5];null!=l&&"number"==typeof l&&l>0&&(r.O=i=1.5*l,r.j.info("backChannelRequestTimeoutMs_="+i)),i=r;let u=e.g;if(u){let e=u.g?u.g.getResponseHeader("X-Client-Wire-Protocol"):null;if(e){var a=i.h;a.g||-1==e.indexOf("spdy")&&-1==e.indexOf("quic")&&-1==e.indexOf("h2")||(a.j=a.l,a.g=new Set,a.h&&(eZ(a,a.h),a.h=null))}if(i.G){let e=u.g?u.g.getResponseHeader("X-HTTP-Session-Id"):null;e&&(i.wa=e,e8(i.J,i.G,e))}}if(r.I=3,r.l&&r.l.ra(),r.aa&&(r.T=Date.now()-e.F,r.j.info("Handshake RTT: "+r.T+"ms")),(i=r).na=tX(i,i.L?i.ba:null,i.W),e.L){e0(i.h,e);var s=i.O;s&&(e.H=s),e.D&&(eK(e),ej(e)),i.g=e}else tG(i);r.i.length>0&&tU(r)}else"stop"!=o[0]&&"close"!=o[0]||tJ(r,7);else 3==r.I&&("stop"==o[0]||"close"==o[0]?"stop"==o[0]?tJ(r,7):tN(r):"noop"!=o[0]&&r.l&&r.l.qa(o),r.A=0)}}eF(4)}catch(e){}}eL.prototype.ba=function(e){e=e.target;let t=this.O;t&&3==tO(e)?t.j():this.Y(e)},eL.prototype.Y=function(e){try{if(e==this.g)e:{let d=tO(this.g),m=this.g.ya(),p=this.g.ca();if(!(d<3)&&(3!=d||this.g&&(this.h.h||this.g.la()||tM(this.g)))){this.K||4!=d||7==m||(8==m||p<=0?eF(3):eF(2)),eK(this);var t=this.g.ca();this.X=t;var r=function(e){if(!eV(e))return e.g.la();let t=tM(e.g);if(""===t)return"";let r="",i=t.length,n=4==tO(e.g);if(!e.h.i){if("u"<typeof TextDecoder)return eq(e),eH(e),"";e.h.i=new g.TextDecoder}for(let a=0;a<i;a++)e.h.h=!0,r+=e.h.i.decode(t[a],{stream:!(n&&a==i-1)});return t.length=0,e.h.g+=r,e.C=0,e.h.g}(this);if(this.o=200==t,i=this.i,n=this.v,a=this.B,s=this.l,o=this.S,i.info(function(){return"XMLHTTP RESP ("+s+") [ attempt "+o+"]: "+n+"\n"+a+"\n"+d+" "+t}),this.o){if(this.U&&!this.L){t:{if(this.g){var i,n,a,s,o,l,u=this.g;if((l=u.g?u.g.getResponseHeader("X-HTTP-Initial-Response"):null)&&!D(l)){var c=l;break t}}c=null}if(e=c)eI(this.i,this.l,e,"Initial handshake response via X-HTTP-Initial-Response"),this.L=!0,eW(this,e);else{this.o=!1,this.m=3,eE(12),eq(this),eH(this);break e}}if(this.R){let t;for(e=!0;!this.K&&this.C<r.length;)if((t=function(e,t){var r=e.C,i=t.indexOf("\n",r);return -1==i?ez:isNaN(r=Number(t.substring(r,i)))?eD:(i+=1)+r>t.length?ez:(t=t.slice(i,i+r),e.C=i+r,t)}(this,r))==ez){4==d&&(this.m=4,eE(14),e=!1),eI(this.i,this.l,null,"[Incomplete Response]");break}else if(t==eD){this.m=4,eE(15),eI(this.i,this.l,r,"[Invalid Chunk]"),e=!1;break}else eI(this.i,this.l,t,null),eW(this,t);if(eV(this)&&0!=this.C&&(this.h.g=this.h.g.slice(this.C),this.C=0),4!=d||0!=r.length||this.h.h||(this.m=1,eE(16),e=!1),this.o=this.o&&e,e){if(r.length>0&&!this.W){this.W=!0;var h=this.j;h.g==this&&h.aa&&!h.P&&(h.j.info("Great, no buffering proxy detected. Bytes received: "+r.length),tH(h),h.P=!0,eE(11))}}else eI(this.i,this.l,r,"[Invalid Chunked Response]"),eq(this),eH(this)}else eI(this.i,this.l,r,null),eW(this,r);4==d&&eq(this),this.o&&!this.K&&(4==d?t$(this.j,this):(this.o=!1,ej(this)))}else(function(e){let t={};e=(e.g&&tO(e)>=2&&e.g.getAllResponseHeaders()||"").split("\r\n");for(let i=0;i<e.length;i++){if(D(e[i]))continue;var r=function(e){var t=1;e=e.split(":");let r=[];for(;t>0&&e.length;)r.push(e.shift()),t--;return e.length&&r.push(e.join(":")),r}(e[i]);let n=r[0];if("string"!=typeof(r=r[1]))continue;r=r.trim();let a=t[n]||[];t[n]=a,a.push(r)}var i=function(e){return e.join(", ")};for(let e in t)i.call(void 0,t[e],e,t)})(this.g),400==t&&r.indexOf("Unknown SID")>0?(this.m=3,eE(12)):(this.m=0,eE(13)),eq(this),eH(this)}}}catch(e){}finally{}},eL.prototype.cancel=function(){this.K=!0,eq(this)},eL.prototype.aa=function(){var e,t;this.D=null;let r=Date.now();r-this.T>=0?(e=this.i,t=this.B,e.info(function(){return"TIMEOUT: "+t}),2!=this.M&&(eF(),eE(17)),eq(this),this.m=2,eH(this)):eG(this,this.T-r)};var e$=class{constructor(e,t){this.g=e,this.map=t}};function eY(e){this.l=e||10,e=g.PerformanceNavigationTiming?(e=g.performance.getEntriesByType("navigation")).length>0&&("hq"==e[0].nextHopProtocol||"h2"==e[0].nextHopProtocol):!!(g.chrome&&g.chrome.loadTimes&&g.chrome.loadTimes()&&g.chrome.loadTimes().wasFetchedViaSpdy),this.j=e?this.l:1,this.g=null,this.j>1&&(this.g=new Set),this.h=null,this.i=[]}function eJ(e){return!!e.h||!!e.g&&e.g.size>=e.j}function eQ(e){return e.h?1:e.g?e.g.size:0}function eX(e,t){return e.h?e.h==t:!!e.g&&e.g.has(t)}function eZ(e,t){e.g?e.g.add(t):e.h=t}function e0(e,t){e.h&&e.h==t?e.h=null:e.g&&e.g.has(t)&&e.g.delete(t)}function e1(e){if(null!=e.h)return e.i.concat(e.h.G);if(null!=e.g&&0!==e.g.size){let t=e.i;for(let r of e.g.values())t=t.concat(r.G);return t}return C(e.i)}eY.prototype.cancel=function(){if(this.i=e1(this),this.h)this.h.cancel(),this.h=null;else if(this.g&&0!==this.g.size){for(let e of this.g.values())e.cancel();this.g.clear()}};var e2=RegExp("^(?:([^:/?#.]+):)?(?://(?:([^\\\\/?#]*)@)?([^\\\\/?#]*?)(?::([0-9]+))?(?=[\\\\/?#]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#([\\s\\S]*))?$");function e3(e){let t;this.g=this.o=this.j="",this.u=null,this.m=this.h="",this.l=!1,e instanceof e3?(this.l=e.l,e5(this,e.j),this.o=e.o,this.g=e.g,e9(this,e.u),this.h=e.h,e6(this,tg(e.i)),this.m=e.m):e&&(t=String(e).match(e2))?(this.l=!1,e5(this,t[1]||"",!0),this.o=te(t[2]||""),this.g=te(t[3]||"",!0),e9(this,t[4]),this.h=te(t[5]||"",!0),e6(this,t[6]||"",!0),this.m=te(t[7]||"")):(this.l=!1,this.i=new tl(null,this.l))}function e4(e){return new e3(e)}function e5(e,t,r){e.j=r?te(t,!0):t,e.j&&(e.j=e.j.replace(/:$/,""))}function e9(e,t){if(t){if(isNaN(t=Number(t))||t<0)throw Error("Bad port number "+t);e.u=t}else e.u=null}function e6(e,t,r){var i,n;t instanceof tl?(e.i=t,i=e.i,(n=e.l)&&!i.j&&(tu(i),i.i=null,i.g.forEach(function(e,t){let r=t.toLowerCase();t!=r&&(tc(this,t),tm(this,r,e))},i)),i.j=n):(r||(t=tt(t,ts)),e.i=new tl(t,e.l))}function e8(e,t,r){e.i.set(t,r)}function e7(e){return e8(e,"zx",Math.floor(0x80000000*Math.random()).toString(36)+Math.abs(Math.floor(0x80000000*Math.random())^Date.now()).toString(36)),e}function te(e,t){return e?t?decodeURI(e.replace(/%25/g,"%2525")):decodeURIComponent(e):""}function tt(e,t,r){return"string"==typeof e?(e=encodeURI(e).replace(t,tr),r&&(e=e.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),e):null}function tr(e){return"%"+((e=e.charCodeAt(0))>>4&15).toString(16)+(15&e).toString(16)}e3.prototype.toString=function(){let e=[];var t=this.j;t&&e.push(tt(t,ti,!0),":");var r=this.g;return(r||"file"==t)&&(e.push("//"),(t=this.o)&&e.push(tt(t,ti,!0),"@"),e.push(eP(r).replace(/%25([0-9a-fA-F]{2})/g,"%$1")),null!=(r=this.u)&&e.push(":",String(r))),(r=this.h)&&(this.g&&"/"!=r.charAt(0)&&e.push("/"),e.push(tt(r,"/"==r.charAt(0)?ta:tn,!0))),(r=this.i.toString())&&e.push("?",r),(r=this.m)&&e.push("#",tt(r,to)),e.join("")},e3.prototype.resolve=function(e){let t=e4(this),r=!!e.j;r?e5(t,e.j):r=!!e.o,r?t.o=e.o:r=!!e.g,r?t.g=e.g:r=null!=e.u;var i=e.h;if(r)e9(t,e.u);else if(r=!!e.h){if("/"!=i.charAt(0))if(this.g&&!this.h)i="/"+i;else{var n=t.h.lastIndexOf("/");-1!=n&&(i=t.h.slice(0,n+1)+i)}if(".."==(n=i)||"."==n)i="";else if(-1!=n.indexOf("./")||-1!=n.indexOf("/.")){i=0==n.lastIndexOf("/",0),n=n.split("/");let e=[];for(let t=0;t<n.length;){let r=n[t++];"."==r?i&&t==n.length&&e.push(""):".."==r?((e.length>1||1==e.length&&""!=e[0])&&e.pop(),i&&t==n.length&&e.push("")):(e.push(r),i=!0)}
vendor: 6,443 bytes, line 5
5i=e.join("/")}else i=n}return r?t.h=i:r=""!==e.i.toString(),r?e6(t,tg(e.i)):r=!!e.m,r&&(t.m=e.m),t};var ti=/[#\/\?@]/g,tn=/[#\?:]/g,ta=/[#\?]/g,ts=/[#\?@]/g,to=/#/g;function tl(e,t){this.h=this.g=null,this.i=e||null,this.j=!!t}function tu(e){e.g||(e.g=new Map,e.h=0,e.i&&function(e,t){if(e){e=e.split("&");for(let r=0;r<e.length;r++){let i=e[r].indexOf("="),n,a=null;i>=0?(n=e[r].substring(0,i),a=e[r].substring(i+1)):n=e[r],t(n,a?decodeURIComponent(a.replace(/\+/g," ")):"")}}}(e.i,function(t,r){e.add(decodeURIComponent(t.replace(/\+/g," ")),r)}))}function tc(e,t){tu(e),t=tp(e,t),e.g.has(t)&&(e.i=null,e.h-=e.g.get(t).length,e.g.delete(t))}function th(e,t){return tu(e),t=tp(e,t),e.g.has(t)}function td(e,t){tu(e);let r=[];if("string"==typeof t)th(e,t)&&(r=r.concat(e.g.get(tp(e,t))));else for(e=Array.from(e.g.values()),t=0;t<e.length;t++)r=r.concat(e[t]);return r}function tm(e,t,r){tc(e,t),r.length>0&&(e.i=null,e.g.set(tp(e,t),C(r)),e.h+=r.length)}function tg(e){let t=new tl;return t.i=e.i,e.g&&(t.g=new Map(e.g),t.h=e.h),t}function tp(e,t){return t=String(t),e.j&&(t=t.toLowerCase()),t}function tf(e,t,r,i,n){try{n&&(n.onload=null,n.onerror=null,n.onabort=null,n.ontimeout=null),i(r)}catch(e){}}function ty(){this.g=new eg}function tv(e){this.i=e.Sb||null,this.h=e.ab||!1}function tw(e,t){ea.call(this),this.H=e,this.o=t,this.m=void 0,this.status=this.readyState=0,this.responseType=this.responseText=this.response=this.statusText="",this.onreadystatechange=null,this.A=new Headers,this.h=null,this.F="GET",this.D="",this.g=!1,this.B=this.j=this.l=null,this.v=new AbortController}function tb(e){e.j.read().then(e.Ma.bind(e)).catch(e.ga.bind(e))}function tC(e){e.readyState=4,e.l=null,e.j=null,e.B=null,tT(e)}function tT(e){e.onreadystatechange&&e.onreadystatechange.call(e)}function tS(e){let t="";return G(e,function(e,r){t+=r,t+=":",t+=e,t+="\r\n"}),t}function tF(e,t,r){e:{for(i in r){var i=!1;break e}i=!0}i||(r=tS(r),"string"==typeof e?null!=r&&eP(r):e8(e,t,r))}function tk(e){ea.call(this),this.headers=new Map,this.L=e||null,this.h=!1,this.g=null,this.D="",this.o=0,this.l="",this.j=this.B=this.v=this.A=!1,this.m=null,this.F="",this.H=!1}(t=tl.prototype).add=function(e,t){tu(this),this.i=null,e=tp(this,e);let r=this.g.get(e);return r||this.g.set(e,r=[]),r.push(t),this.h+=1,this},t.forEach=function(e,t){tu(this),this.g.forEach(function(r,i){r.forEach(function(r){e.call(t,r,i,this)},this)},this)},t.set=function(e,t){return tu(this),this.i=null,th(this,e=tp(this,e))&&(this.h-=this.g.get(e).length),this.g.set(e,[t]),this.h+=1,this},t.get=function(e,t){return e&&(e=td(this,e)).length>0?String(e[0]):t},t.toString=function(){if(this.i)return this.i;if(!this.g)return"";let e=[],t=Array.from(this.g.keys());for(let i=0;i<t.length;i++){var r=t[i];let n=eP(r);r=td(this,r);for(let t=0;t<r.length;t++){let i=n;""!==r[t]&&(i+="="+eP(r[t])),e.push(i)}}return this.i=e.join("&")},w(tv,ep),tv.prototype.g=function(){return new tw(this.i,this.h)},w(tw,ea),(t=tw.prototype).open=function(e,t){if(0!=this.readyState)throw this.abort(),Error("Error reopening a connection");this.F=e,this.D=t,this.readyState=1,tT(this)},t.send=function(e){if(1!=this.readyState)throw this.abort(),Error("need to call open() first. ");if(this.v.signal.aborted)throw this.abort(),Error("Request was aborted.");this.g=!0;let t={headers:this.A,method:this.F,credentials:this.m,cache:void 0,signal:this.v.signal};e&&(t.body=e),(this.H||g).fetch(new Request(this.D,t)).then(this.Pa.bind(this),this.ga.bind(this))},t.abort=function(){this.response=this.responseText="",this.A=new Headers,this.status=0,this.v.abort(),this.j&&this.j.cancel("Request was aborted.").catch(()=>{}),this.readyState>=1&&this.g&&4!=this.readyState&&(this.g=!1,tC(this)),this.readyState=0},t.Pa=function(e){if(this.g&&(this.l=e,this.h||(this.status=this.l.status,this.statusText=this.l.statusText,this.h=e.headers,this.readyState=2,tT(this)),this.g&&(this.readyState=3,tT(this),this.g)))if("arraybuffer"===this.responseType)e.arrayBuffer().then(this.Na.bind(this),this.ga.bind(this));else if(void 0!==g.ReadableStream&&"body"in e){if(this.j=e.body.getReader(),this.o){if(this.responseType)throw Error('responseType must be empty for "streamBinaryChunks" mode responses.');this.response=[]}else this.response=this.responseText="",this.B=new TextDecoder;tb(this)}else e.text().then(this.Oa.bind(this),this.ga.bind(this))},t.Ma=function(e){if(this.g){if(this.o&&e.value)this.response.push(e.value);else if(!this.o){var t=e.value?e.value:new Uint8Array(0);(t=this.B.decode(t,{stream:!e.done}))&&(this.response=this.responseText+=t)}e.done?tC(this):tT(this),3==this.readyState&&tb(this)}},t.Oa=function(e){this.g&&(this.response=this.responseText=e,tC(this))},t.Na=function(e){this.g&&(this.response=e,tC(this))},t.ga=function(){this.g&&tC(this)},t.setRequestHeader=function(e,t){this.A.append(e,t)},t.getResponseHeader=function(e){return this.h&&this.h.get(e.toLowerCase())||""},t.getAllResponseHeaders=function(){if(!this.h)return"";let e=[],t=this.h.entries();for(var r=t.next();!r.done;)e.push((r=r.value)[0]+": "+r[1]),r=t.next();return e.join("\r\n")},Object.defineProperty(tw.prototype,"withCredentials",{get:function(){return"include"===this.m},set:function(e){this.m=e?"include":"same-origin"}}),w(tk,ea);var tE=/^https?$/i,tA=["POST","PUT"];function t_(e,t){e.h=!1,e.g&&(e.j=!0,e.g.abort(),e.j=!1),e.l=t,e.o=5,tR(e),tx(e)}function tR(e){e.A||(e.A=!0,es(e,"complete"),es(e,"error"))}function tI(e){if(e.h&&void 0!==m){if(e.v&&4==tO(e))setTimeout(e.Ca.bind(e),0);else if(es(e,"readystatechange"),4==tO(e)){e.h=!1;try{let a=e.ca();switch(a){case 200:case 201:case 202:case 204:case 206:case 304:case 1223:var t,r,i=!0;break;default:i=!1}if(!(t=i)){if(r=0===a){let t=String(e.D).match(e2)[1]||null;!t&&g.self&&g.self.location&&(t=g.self.location.protocol.slice(0,-1)),r=!tE.test(t?t.toLowerCase():"")}t=r}if(t)es(e,"complete"),es(e,"success");else{e.o=6;try{var n=tO(e)>2?e.g.statusText:""}catch(e){n=""}e.l=n+" ["+e.ca()+"]",tR(e)}}finally{tx(e)}}}}function tx(e,t){if(e.g){e.m&&(clearTimeout(e.m),e.m=null);let r=e.g;e.g=null,t||es(e,"ready");try{r.onreadystatechange=null}catch(e){}}}function tO(e){return e.g?e.g.readyState:0}function tM(e){try{if(!e.g)return null;if("response"in e.g)return e.g.response;switch(e.F){case"":case"text":return e.g.responseText;case"arraybuffer":if("mozResponseArrayBuffer"in e.g)return e.g.mozResponseArrayBuffer}return null}catch(e){return null}}
5function tP(e,t,r){return r&&r.internalChannelParams&&r.internalChannelParams[e]||t}function tL(e){this.za=0,this.i=[],this.j=new eR,this.ba=this.na=this.J=this.W=this.g=this.wa=this.G=this.H=this.u=this.U=this.o=null,this.Ya=this.V=0,this.Sa=tP("failFast",!1,e),this.F=this.C=this.v=this.m=this.l=null,this.X=!0,this.xa=this.K=-1,this.Y=this.A=this.D=0,this.Qa=tP("baseRetryDelayMs",5e3,e),this.Za=tP("retryDelaySeedMs",1e4,e),this.Ta=tP("forwardChannelMaxRetries",2,e),this.va=tP("forwardChannelRequestTimeoutMs",2e4,e),this.ma=e&&e.xmlHttpFactory||void 0,this.Ua=e&&e.Rb||void 0,this.Aa=e&&e.useFetchStreams||!1,this.O=void 0,this.L=e&&e.supportsCrossDomainXhr||!1,this.M="",this.h=new eY(e&&e.concurrentRequestLimit),this.Ba=new ty,this.S=e&&e.fastHandshake||!1,this.R=e&&e.encodeInitMessageHeaders||!1,this.S&&this.R&&(this.R=!1),this.Ra=e&&e.Pb||!1,e&&e.ua&&this.j.ua(),e&&e.forceLongPolling&&(this.X=!1),this.aa=!this.S&&this.X&&e&&e.detectBufferingProxy||!1,this.ia=void 0,e&&e.longPollingTimeout&&e.longPollingTimeout>0&&(this.ia=e.longPollingTimeout),this.ta=void 0,this.T=0,this.P=!1,this.ja=this.B=null}function tN(e){if(tz(e),3==e.I){var t=e.V++,r=e4(e.J);if(e8(r,"SID",e.M),e8(r,"RID",t),e8(r,"TYPE","terminate"),tV(e,r),(t=new eL(e,e.j,t)).M=2,t.A=e7(e4(r)),r=!1,g.navigator&&g.navigator.sendBeacon)try{r=g.navigator.sendBeacon(t.A.toString(),"")}catch(e){}!r&&g.Image&&((new Image).src=t.A,r=!0),r||(t.g=tZ(t.j,null),t.g.ea(t.A)),t.F=Date.now(),ej(t)}tQ(e)}function tD(e){e.g&&(tH(e),e.g.cancel(),e.g=null)}function tz(e){tD(e),e.v&&(g.clearTimeout(e.v),e.v=null),tW(e),e.h.cancel(),e.m&&("number"==typeof e.m&&g.clearTimeout(e.m),e.m=null)}function tU(e){if(!eJ(e.h)&&!e.m){e.m=!0;var t=e.Ea;R||O(),I||(R(),I=!0),x.add(t,e),e.D=0}}function tB(e,t){var r;r=t?t.l:e.V++;let i=e4(e.J);e8(i,"SID",e.M),e8(i,"RID",r),e8(i,"AID",e.K),tV(e,i),e.u&&e.o&&tF(i,e.u,e.o),r=new eL(e,e.j,r,e.D+1),null===e.u&&(r.J=e.o),t&&(e.i=t.G.concat(e.i)),t=tj(e,r,1e3),r.H=Math.round(.5*e.va)+Math.round(.5*e.va*Math.random()),eZ(e.h,r),eU(r,i,t)}function tV(e,t){e.H&&G(e.H,function(e,r){e8(t,r,e)}),e.l&&G({},function(e,r){e8(t,r,e)})}function tj(e,t,r){r=Math.min(e.i.length,r);let i=e.l?y(e.l.Ka,e.l,e):null;e:{var n=e.i;let t=-1;for(;;){let e=["count="+r];-1==t?r>0?(t=n[0].g,e.push("ofs="+t)):t=0:e.push("ofs="+t);let o=!0;for(let l=0;l<r;l++){var a=n[l].g;let r=n[l].map;if((a-=t)<0)t=Math.max(0,n[l].g-100),o=!1;else try{a="req"+a+"_";try{var s=r instanceof Map?r:Object.entries(r);for(let[t,r]of s){let i=r;p(r)&&(i=ed(r)),e.push(a+t+"="+encodeURIComponent(i))}}catch(t){throw e.push(a+"type="+encodeURIComponent("_badmap")),t}}catch(e){i&&i(r)}}if(o){s=e.join("&");break e}}s=void 0}return t.G=e=e.i.splice(0,r),s}function tG(e){if(!e.g&&!e.v){e.Y=1;var t=e.Da;R||O(),I||(R(),I=!0),x.add(t,e),e.A=0}}function tK(e){return!e.g&&!e.v&&!(e.A>=3)&&(e.Y++,e.v=e_(y(e.Da,e),tY(e,e.A)),e.A++,!0)}function tH(e){null!=e.B&&(g.clearTimeout(e.B),e.B=null)}function tq(e){e.g=new eL(e,e.j,"rpc",e.Y),null===e.u&&(e.g.J=e.o),e.g.P=0;var t=e4(e.na);e8(t,"RID","rpc"),e8(t,"SID",e.M),e8(t,"AID",e.K),e8(t,"CI",e.F?"0":"1"),!e.F&&e.ia&&e8(t,"TO",e.ia),e8(t,"TYPE","xmlhttp"),tV(e,t),e.u&&e.o&&tF(t,e.u,e.o),e.O&&(e.g.H=e.O);var r=e.g;e=e.ba,r.M=1,r.A=e7(e4(t)),r.u=null,r.R=!0,eB(r,e)}function tW(e){null!=e.C&&(g.clearTimeout(e.C),e.C=null)}function t$(e,t){var r,i=null;if(e.g==t){tW(e),tH(e),e.g=null;var n=2}else{if(!eX(e.h,t))return;i=t.G,e0(e.h,t),n=1}if(0!=e.I){if(t.o)if(1==n){i=t.u?t.u.length:0,t=Date.now()-t.F;var a=e.D;es(n=eT(),new eA(n,i)),tU(e)}else tG(e);else if(3==(a=t.m)||0==a&&t.X>0||!(1==n&&(r=t,!(eQ(e.h)>=e.h.j-!!e.m)&&(e.m?(e.i=r.G.concat(e.i),!0):1!=e.I&&2!=e.I&&!(e.D>=(e.Sa?0:e.Ta))&&(e.m=e_(y(e.Ea,e,r),tY(e,e.D)),e.D++,!0)))||2==n&&tK(e)))switch(i&&i.length>0&&((t=e.h).i=t.i.concat(i)),a){case 1:tJ(e,5);break;case 4:tJ(e,10);break;case 3:tJ(e,6);break;default:tJ(e,2)}}}function tY(e,t){let r=e.Qa+Math.floor(Math.random()*e.Za);return e.isActive()||(r*=2),r*t}function tJ(e,t){if(e.j.info("Error code "+t),2==t){let t,a,s;var r,i=y(e.bb,e),n=e.Ua;let o=!n;n=new e3(n||"//www.google.com/images/cleardot.gif"),g.location&&"http"==g.location.protocol||e5(n,"https"),e7(n),o?function(e,t){let r=new eR;if(g.Image){let i=new Image;i.onload=v(tf,r,"TestLoadImage: loaded",!0,t,i),i.onerror=v(tf,r,"TestLoadImage: error",!1,t,i),i.onabort=v(tf,r,"TestLoadImage: abort",!1,t,i),i.ontimeout=v(tf,r,"TestLoadImage: timeout",!1,t,i),g.setTimeout(function(){i.ontimeout&&i.ontimeout()},1e4),i.src=e}else t(!1)}(n.toString(),i):(r=n.toString(),t=new eR,a=new AbortController,s=setTimeout(()=>{a.abort(),tf(t,"TestPingServer: timeout",!1,i)},1e4),fetch(r,{signal:a.signal}).then(e=>{clearTimeout(s),e.ok?tf(t,"TestPingServer: ok",!0,i):tf(t,"TestPingServer: server error",!1,i)}).catch(()=>{clearTimeout(s),tf(t,"TestPingServer: error",!1,i)}))}else eE(2);e.I=0,e.l&&e.l.pa(t),tQ(e),tz(e)}function tQ(e){if(e.I=0,e.ja=[],e.l){let t=e1(e.h);
5(0!=t.length||0!=e.i.length)&&(T(e.ja,t),T(e.ja,e.i),e.h.i.length=0,C(e.i),e.i.length=0),e.l.oa()}}function tX(e,t,r){var i=r instanceof e3?e4(r):new e3(r);if(""!=i.g)t&&(i.g=t+"."+i.g),e9(i,i.u);else{var n=g.location;i=n.protocol,t=t?t+"."+n.hostname:n.hostname,n=+n.port;let e=new e3(null);i&&e5(e,i),t&&(e.g=t),n&&e9(e,n),r&&(e.h=r),i=e}return r=e.G,t=e.wa,r&&t&&e8(i,r,t),e8(i,"VER",e.ka),tV(e,i),i}function tZ(e,t,r){if(t&&!e.L)throw Error("Can't create secondary domain capable XhrIo object.");return(t=new tk(e.Aa&&!e.ma?new tv({ab:r}):e.ma)).Fa(e.L),t}function t0(){}function t1(){}function t2(e,t){ea.call(this),this.g=new tL(t),this.l=e,this.h=t&&t.messageUrlParams||null,e=t&&t.messageHeaders||null,t&&t.clientProtocolHeaderRequired&&(e?e["X-Client-Protocol"]="webchannel":e={"X-Client-Protocol":"webchannel"}),this.g.o=e,e=t&&t.initMessageHeaders||null,t&&t.messageContentType&&(e?e["X-WebChannel-Content-Type"]=t.messageContentType:e={"X-WebChannel-Content-Type":t.messageContentType}),t&&t.sa&&(e?e["X-WebChannel-Client-Profile"]=t.sa:e={"X-WebChannel-Client-Profile":t.sa}),this.g.U=e,(e=t&&t.Qb)&&!D(e)&&(this.g.u=e),this.A=t&&t.supportsCrossDomainXhr||!1,this.v=t&&t.sendRawJson||!1,(t=t&&t.httpSessionIdParam)&&!D(t)&&(this.g.G=t,null!==(e=this.h)&&t in e&&t in(e=this.h)&&delete e[t]),this.j=new t5(this)}function t3(e){ev.call(this),e.__headers__&&(this.headers=e.__headers__,this.statusCode=e.__status__,delete e.__headers__,delete e.__status__);var t=e.__sm__;if(t){e:{for(let r in t){e=r;break e}e=void 0}(this.i=e)&&(e=this.i,t=null!==t&&e in t?t[e]:void 0),this.data=t}else this.data=e}function t4(){ew.call(this),this.status=1}function t5(e){this.g=e}(t=tk.prototype).Fa=function(e){this.H=e},t.ea=function(t,r,i,n){if(this.g)throw Error("[goog.net.XhrIo] Object is active with another request="+this.D+"; newUri="+t);r=r?r.toUpperCase():"GET",this.D=t,this.l="",this.o=0,this.A=!1,this.h=!0,this.g=this.L?this.L.g():e.g(),this.g.onreadystatechange=b(y(this.Ca,this));try{this.B=!0,this.g.open(r,String(t),!0),this.B=!1}catch(e){t_(this,e);return}if(t=i||"",i=new Map(this.headers),n)if(Object.getPrototypeOf(n)===Object.prototype)for(var a in n)i.set(a,n[a]);else if("function"==typeof n.keys&&"function"==typeof n.get)for(let e of n.keys())i.set(e,n.get(e));else throw Error("Unknown input type for opt_headers: "+String(n));for(let[e,s]of(n=Array.from(i.keys()).find(e=>"content-type"==e.toLowerCase()),a=g.FormData&&t instanceof g.FormData,!(Array.prototype.indexOf.call(tA,r,void 0)>=0)||n||a||i.set("Content-Type","application/x-www-form-urlencoded;charset=utf-8"),i))this.g.setRequestHeader(e,s);this.F&&(this.g.responseType=this.F),"withCredentials"in this.g&&this.g.withCredentials!==this.H&&(this.g.withCredentials=this.H);try{this.m&&(clearTimeout(this.m),this.m=null),this.v=!0,this.g.send(t),this.v=!1}catch(e){t_(this,e)}},t.abort=function(e){this.g&&this.h&&(this.h=!1,this.j=!0,this.g.abort(),this.j=!1,this.o=e||7,es(this,"complete"),es(this,"abort"),tx(this))},t.N=function(){this.g&&(this.h&&(this.h=!1,this.j=!0,this.g.abort(),this.j=!1),tx(this,!0)),tk.Z.N.call(this)},t.Ca=function(){this.u||(this.B||this.v||this.j?tI(this):this.Xa())},t.Xa=function(){tI(this)},t.isActive=function(){return!!this.g},t.ca=function(){try{return tO(this)>2?this.g.status:-1}catch(e){return -1}},t.la=function(){try{return this.g?this.g.responseText:""}catch(e){return""}},t.La=function(e){if(this.g){var t=this.g.responseText;return e&&0==t.indexOf(e)&&(t=t.substring(e.length)),em(t)}},t.ya=function(){return this.o},t.Ha=function(){return"string"==typeof this.l?this.l:String(this.l)},(t=tL.prototype).ka=8,t.I=1,t.connect=function(e,t,r,i){eE(0),this.W=e,this.H=t||{},r&&void 0!==i&&(this.H.OSID=r,this.H.OAID=i),this.F=this.X,this.J=tX(this,null,this.W),tU(this)},t.Ea=function(e){if(this.m)if(this.m=null,1==this.I){if(!e){this.V=Math.floor(1e5*Math.random()),e=this.V++;let n=new eL(this,this.j,e),a=this.o;if(this.U&&(a?q(a=K(a),this.U):a=this.U),null!==this.u||this.R||(n.J=a,a=null),this.S)e:{for(var t=0,r=0;r<this.i.length;r++){t:{var i=this.i[r];if("__data__"in i.map&&"string"==typeof(i=i.map.__data__)){i=i.length;break t}i=void 0}if(void 0===i)break;if((t+=i)>4096){t=r;break e}if(4096===t||r===this.i.length-1){t=r+1;break e}}t=1e3}else t=1e3;t=tj(this,n,t),e8(r=e4(this.J),"RID",e),e8(r,"CVER",22),this.G&&e8(r,"X-HTTP-Session-Id",this.G),tV(this,r),a&&(this.R?t="headers="+eP(tS(a)
5)+"&"+t:this.u&&tF(r,this.u,a)),eZ(this.h,n),this.Ra&&e8(r,"TYPE","init"),this.S?(e8(r,"$req",t),e8(r,"SID","null"),n.U=!0,eU(n,r,null)):eU(n,r,t),this.I=2}}else 3==this.I&&(e?tB(this,e):0==this.i.length||eJ(this.h)||tB(this))},t.Da=function(){if(this.v=null,tq(this),this.aa&&!(this.P||null==this.g||this.T<=0)){var e=4*this.T;this.j.info("BP detection timer enabled: "+e),this.B=e_(y(this.Wa,this),e)}},t.Wa=function(){this.B&&(this.B=null,this.j.info("BP detection timeout reached."),this.j.info("Buffering proxy detected and switch to long-polling!"),this.F=!1,this.P=!0,eE(10),tD(this),tq(this))},t.Va=function(){null!=this.C&&(this.C=null,tD(this),tK(this),eE(19))},t.bb=function(e){e?(this.j.info("Successfully pinged google.com"),eE(2)):(this.j.info("Failed to ping google.com"),eE(1))},t.isActive=function(){return!!this.l&&this.l.isActive(this)},(t=t0.prototype).ra=function(){},t.qa=function(){},t.pa=function(){},t.oa=function(){},t.isActive=function(){return!0},t.Ka=function(){},t1.prototype.g=function(e,t){return new t2(e,t)},w(t2,ea),t2.prototype.m=function(){this.g.l=this.j,this.A&&(this.g.L=!0),this.g.connect(this.l,this.h||void 0)},t2.prototype.close=function(){tN(this.g)},t2.prototype.o=function(e){var t=this.g;if("string"==typeof e){var r={};r.__data__=e,e=r}else this.v&&((r={}).__data__=ed(e),e=r);t.i.push(new e$(t.Ya++,e)),3==t.I&&tU(t)},t2.prototype.N=function(){this.g.l=null,delete this.j,tN(this.g),delete this.g,t2.Z.N.call(this)},w(t3,ev),w(t4,ew),w(t5,t0),t5.prototype.ra=function(){es(this.g,"a")},t5.prototype.qa=function(e){es(this.g,new t3(e))},t5.prototype.pa=function(e){es(this.g,new t4)},t5.prototype.oa=function(){es(this.g,"b")},t1.prototype.createWebChannel=t1.prototype.g,t2.prototype.send=t2.prototype.o,t2.prototype.open=t2.prototype.m,t2.prototype.close=t2.prototype.close,d=F.createWebChannelTransport=function(){return new t1},h=F.getStatEventTarget=function(){return eT()},c=F.Event=eb,u=F.Stat={jb:0,mb:1,nb:2,Hb:3,Mb:4,Jb:5,Kb:6,Ib:7,Gb:8,Lb:9,PROXY:10,NOPROXY:11,Eb:12,Ab:13,Bb:14,zb:15,Cb:16,Db:17,fb:18,eb:19,gb:20},ex.NO_ERROR=0,ex.TIMEOUT=8,ex.HTTP_ERROR=6,l=F.ErrorCode=ex,eO.COMPLETE="complete",o=F.EventType=eO,ef.EventType=ey,ey.OPEN="a",ey.CLOSE="b",ey.ERROR="c",ey.MESSAGE="d",ea.prototype.listen=ea.prototype.J,s=F.WebChannel=ef,F.FetchXmlHttpFactory=tv,tk.prototype.listenOnce=tk.prototype.K,tk.prototype.getLastError=tk.prototype.Ha,tk.prototype.getLastErrorCode=tk.prototype.ya,tk.prototype.getStatus=tk.prototype.ca,tk.prototype.getResponseJson=tk.prototype.La,tk.prototype.getResponseText=tk.prototype.la,tk.prototype.send=tk.prototype.ea,tk.prototype.setWithCredentials=tk.prototype.Fa,a=F.XhrIo=tk}).apply(void 0!==S?S:"u">typeof self?self:"u">typeof window?window:{}),r(65364);var k=r(88220).Buffer;class E{constructor(e){this.uid=e}isAuthenticated(){return null!=this.uid}toKey(){return this.isAuthenticated()?"uid:"+this.uid:"anonymous-user"}isEqual(e){return e.uid===this.uid}}E.UNAUTHENTICATED=new E(null),E.GOOGLE_CREDENTIALS=new E("google-credentials-uid"),E.FIRST_PARTY=new E("first-party-uid"),E.MOCK_USER=new E("mock-user");let A="12.9.0",_=new T.Vy("@firebase/firestore");function R(){return _.logLevel}function I(e,...t){if(_.logLevel<=T.$b.DEBUG){let r=t.map(M);_.debug(`Firestore (${A}): ${e}`,...r)}}function x(e,...t){if(_.logLevel<=T.$b.ERROR){let r=t.map(M);_.error(`Firestore (${A}): ${e}`,...r)}}function O(e,...t){if(_.logLevel<=T.$b.WARN){let r=t.map(M);_.warn(`Firestore (${A}): ${e}`,...r)}}function M(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch(t){return e}}function P(e,t,r){let i="Unexpected state";"string"==typeof t?i=t:r=t,L(e,i,r)}function L(e,t,r){let i=`FIRESTORE (${A}) INTERNAL ASSERTION FAILED: ${t} (ID: ${e.toString(16)})`;if(void 0!==r)try{i+=" CONTEXT: "+JSON.stringify(r)}catch(e){i+=" CONTEXT: "+r}throw x(i),Error(i)}function N(e,t,r,i){let n="Unexpected state";"string"==typeof r?n=r:i=r,e||L(t,n,i)}let D={OK:"ok",CANCELLED:"cancelled",UNKNOWN:"unknown",INVALID_ARGUMENT:"invalid-argument",DEADLINE_EXCEEDED:"deadline-exceeded",NOT_FOUND:"not-found",ALREADY_EXISTS:"already-exists",PERMISSION_DENIED:"permission-denied",UNAUTHENTICATED:"unauthenticated",RESOURCE_EXHAUSTED:"resource-exhausted",FAILED_PRECONDITION:"failed-precondition",ABORTED:"aborted",OUT_OF_RANGE:"out-of-range",UNIMPLEMENT
5ED:"unimplemented",INTERNAL:"internal",UNAVAILABLE:"unavailable",DATA_LOSS:"data-loss"};class z extends w.g{constructor(e,t){super(e,t),this.code=e,this.message=t,this.toString=()=>`${this.name}: [code=${this.code}]: ${this.message}`}}class U{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}}class B{constructor(e,t){this.user=t,this.type="OAuth",this.headers=new Map,this.headers.set("Authorization",`Bearer ${e}`)}}class V{getToken(){return Promise.resolve(null)}invalidateToken(){}start(e,t){e.enqueueRetryable(()=>t(E.UNAUTHENTICATED))}shutdown(){}}class j{constructor(e){this.token=e,this.changeListener=null}getToken(){return Promise.resolve(this.token)}invalidateToken(){}start(e,t){this.changeListener=t,e.enqueueRetryable(()=>t(this.token.user))}shutdown(){this.changeListener=null}}class G{constructor(e){this.t=e,this.currentUser=E.UNAUTHENTICATED,this.i=0,this.forceRefresh=!1,this.auth=null}start(e,t){N(void 0===this.o,42304);let r=this.i,i=e=>this.i!==r?(r=this.i,t(e)):Promise.resolve(),n=new U;this.o=()=>{this.i++,this.currentUser=this.u(),n.resolve(),n=new U,e.enqueueRetryable(()=>i(this.currentUser))};let a=()=>{let t=n;e.enqueueRetryable(async()=>{await t.promise,await i(this.currentUser)})},s=e=>{I("FirebaseAuthCredentialsProvider","Auth detected"),this.auth=e,this.o&&(this.auth.addAuthTokenListener(this.o),a())};this.t.onInit(e=>s(e)),setTimeout(()=>{if(!this.auth){let e=this.t.getImmediate({optional:!0});e?s(e):(I("FirebaseAuthCredentialsProvider","Auth not yet detected"),n.resolve(),n=new U)}},0),a()}getToken(){let e=this.i,t=this.forceRefresh;return this.forceRefresh=!1,this.auth?this.auth.getToken(t).then(t=>this.i!==e?(I("FirebaseAuthCredentialsProvider","getToken aborted due to token change."),this.getToken()):t?(N("string"==typeof t.accessToken,31837,{l:t}),new B(t.accessToken,this.currentUser)):null):Promise.resolve(null)}invalidateToken(){this.forceRefresh=!0}shutdown(){this.auth&&this.o&&this.auth.removeAuthTokenListener(this.o),this.o=void 0}u(){let e=this.auth&&this.auth.getUid();return N(null===e||"string"==typeof e,2055,{h:e}),new E(e)}}class K{constructor(e,t,r){this.P=e,this.T=t,this.I=r,this.type="FirstParty",this.user=E.FIRST_PARTY,this.R=new Map}A(){return this.I?this.I():null}get headers(){this.R.set("X-Goog-AuthUser",this.P);let e=this.A();return e&&this.R.set("Authorization",e),this.T&&this.R.set("X-Goog-Iam-Authorization-Token",this.T),this.R}}class H{constructor(e,t,r){this.P=e,this.T=t,this.I=r}getToken(){return Promise.resolve(new K(this.P,this.T,this.I))}start(e,t){e.enqueueRetryable(()=>t(E.FIRST_PARTY))}shutdown(){}invalidateToken(){}}class q{constructor(e){this.value=e,this.type="AppCheck",this.headers=new Map,e&&e.length>0&&this.headers.set("x-firebase-appcheck",this.value)}}class W{constructor(e,t){this.V=t,this.forceRefresh=!1,this.appCheck=null,this.m=null,this.p=null,(0,y.xZ)(e)&&e.settings.appCheckToken&&(this.p=e.settings.appCheckToken)}start(e,t){N(void 0===this.o,3512);let r=e=>{null!=e.error&&I("FirebaseAppCheckTokenProvider",`Error getting App Check token; using placeholder token instead. Error: ${e.error.message}`);let r=e.token!==this.m;return this.m=e.token,I("FirebaseAppCheckTokenProvider",`Received ${r?"new":"existing"} token.`),r?t(e.token):Promise.resolve()};this.o=t=>{e.enqueueRetryable(()=>r(t))};let i=e=>{I("FirebaseAppCheckTokenProvider","AppCheck detected"),this.appCheck=e,this.o&&this.appCheck.addTokenListener(this.o)};this.V.onInit(e=>i(e)),setTimeout(()=>{if(!this.appCheck){let e=this.V.getImmediate({optional:!0});e?i(e):I("FirebaseAppCheckTokenProvider","AppCheck not yet detected")}},0)}getToken(){if(this.p)return Promise.resolve(new q(this.p));let e=this.forceRefresh;return this.forceRefresh=!1,this.appCheck?this.appCheck.getToken(e).then(e=>e?(N("string"==typeof e.token,44558,{tokenResult:e}),this.m=e.token,new q(e.token)):null):Promise.resolve(null)}invalidateToken(){this.forceRefresh=!0}shutdown(){this.appCheck&&this.o&&this.appCheck.removeTokenListener(this.o),this.o=void 0}}class ${static newId(){let e=62*Math.floor(256/62),t="";for(;t.length<20;){let r=function(){let e="u">typeof self&&(self.crypto||self.msCrypto),t=new Uint8Array(40);if(e&&"function"==typeof e.getRandomValues)e.getRandomValues(t);else for(let e=0;e<40;
5e++)t[e]=Math.floor(256*Math.random());return t}();for(let i=0;i<r.length;++i)t.length<20&&r[i]<e&&(t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(r[i]%62))}return t}}function Y(e,t){return e<t?-1:+(e>t)}function J(e,t){let r=Math.min(e.length,t.length);for(let i=0;i<r;i++){let r=e.charAt(i),n=t.charAt(i);if(r!==n)return Q(r)===Q(n)?Y(r,n):Q(r)?1:-1}return Y(e.length,t.length)}function Q(e){let t=e.charCodeAt(0);return t>=55296&&t<=57343}function X(e,t,r){return e.length===t.length&&e.every((e,i)=>r(e,t[i]))}let Z="__name__";class ee{constructor(e,t,r){void 0===t?t=0:t>e.length&&P(637,{offset:t,range:e.length}),void 0===r?r=e.length-t:r>e.length-t&&P(1746,{length:r,range:e.length-t}),this.segments=e,this.offset=t,this.len=r}get length(){return this.len}isEqual(e){return 0===ee.comparator(this,e)}child(e){let t=this.segments.slice(this.offset,this.limit());return e instanceof ee?e.forEach(e=>{t.push(e)}):t.push(e),this.construct(t)}limit(){return this.offset+this.length}popFirst(e){return e=void 0===e?1:e,this.construct(this.segments,this.offset+e,this.length-e)}popLast(){return this.construct(this.segments,this.offset,this.length-1)}firstSegment(){return this.segments[this.offset]}lastSegment(){return this.get(this.length-1)}get(e){return this.segments[this.offset+e]}isEmpty(){return 0===this.length}isPrefixOf(e){if(e.length<this.length)return!1;for(let t=0;t<this.length;t++)if(this.get(t)!==e.get(t))return!1;return!0}isImmediateParentOf(e){if(this.length+1!==e.length)return!1;for(let t=0;t<this.length;t++)if(this.get(t)!==e.get(t))return!1;return!0}forEach(e){for(let t=this.offset,r=this.limit();t<r;t++)e(this.segments[t])}toArray(){return this.segments.slice(this.offset,this.limit())}static comparator(e,t){let r=Math.min(e.length,t.length);for(let i=0;i<r;i++){let r=ee.compareSegments(e.get(i),t.get(i));if(0!==r)return r}return Y(e.length,t.length)}static compareSegments(e,t){let r=ee.isNumericId(e),i=ee.isNumericId(t);return r&&!i?-1:!r&&i?1:r&&i?ee.extractNumericId(e).compare(ee.extractNumericId(t)):J(e,t)}static isNumericId(e){return e.startsWith("__id")&&e.endsWith("__")}static extractNumericId(e){return i.fromString(e.substring(4,e.length-2))}}class et extends ee{construct(e,t,r){return new et(e,t,r)}canonicalString(){return this.toArray().join("/")}toString(){return this.canonicalString()}toUriEncodedString(){return this.toArray().map(encodeURIComponent).join("/")}static fromString(...e){let t=[];for(let r of e){if(r.indexOf("//")>=0)throw new z(D.INVALID_ARGUMENT,`Invalid segment (${r}). Paths must not contain // in them.`);t.push(...r.split("/").filter(e=>e.length>0))}return new et(t)}static emptyPath(){return new et([])}}let er=/^[_a-zA-Z][_a-zA-Z0-9]*$/;class ei extends ee{construct(e,t,r){return new ei(e,t,r)}static isValidIdentifier(e){return er.test(e)}canonicalString(){return this.toArray().map(e=>(e=e.replace(/\\/g,"\\\\").replace(/`/g,"\\`"),ei.isValidIdentifier(e)||(e="`"+e+"`"),e)).join(".")}toString(){return this.canonicalString()}isKeyField(){return 1===this.length&&this.get(0)===Z}static keyField(){return new ei([Z])}static fromServerFormat(e){let t=[],r="",i=0,n=()=>{if(0===r.length)throw new z(D.INVALID_ARGUMENT,`Invalid field path (${e}). Paths must not be empty, begin with '.', end with '.', or contain '..'`);t.push(r),r=""},a=!1;for(;i<e.length;){let t=e[i];if("\\"===t){if(i+1===e.length)throw new z(D.INVALID_ARGUMENT,"Path has trailing escape character: "+e);let t=e[i+1];if("\\"!==t&&"."!==t&&"`"!==t)throw new z(D.INVALID_ARGUMENT,"Path has invalid escape sequence: "+e);r+=t,i+=2}else"`"===t?a=!a:"."!==t||a?r+=t:n(),i++}if(n(),a)throw new z(D.INVALID_ARGUMENT,"Unterminated ` in path: "+e);return new ei(t)}static emptyPath(){return new ei([])}}class en{constructor(e){this.path=e}static fromPath(e){return new en(et.fromString(e))}static fromName(e){return new en(et.fromString(e).popFirst(5))}static empty(){return new en(et.emptyPath())}get collectionGroup(){return this.path.popLast().lastSegment()}hasCollectionId(e){return this.path.length>=2&&this.path.get(this.path.length-2)===e}getCollectionGroup(){return this.path.get(this.path.length-2)}getCollectionPath(){return this.path.popLast()}isEqual(e){return null!==e&&0===et.comparator(this.path,e.path)}toString(){return this.path.toString()}static comparator(e,t){return et.comparator(e.path,t.path)}static isDocumentKey(e){return e.length%2==0}static fromSegments(e){return new en(new et(e.slice()))}}function ea(e,t,r){if(!r)throw new z(D.INVALID_ARGUMENT,`Function ${e}() cannot be called with an empty ${t}.`)}function es(e){if(!en.isDocumentKey(e))throw new z(D.INVALID_ARGUMENT,`Invalid document reference. Document references must have an even number of segments, but ${e} has ${e.length}.`)}function eo(e){if(en.isDocumentKey(e))throw new z(D.INVALID_ARGUMENT,`Invalid collection reference. Collection references must have an odd number of segments, but ${e} has ${e.length}.`)}function el(e){return"object"==typeof e&&null!==e&&(Object.getPrototypeOf(e)===Object.prototype||null===Object.getPrototypeOf(e))}function eu(e){if(void 0===e)return"undefined";if(null===e)return"null";if("string"==typeof e)return e.length>20&&(e=`${e.substring(0,20)}...`),JSON.stringify(e);if("number"==typeof e||"boolean"==typeof e)return""+e;if("object"==typeof e){if(e instanceof Array)return"an array";{var t;let r=(t=e).constructor?t.constructor.name:null;return r?`a custom ${r} object`:"an object"}}return"function"==typeof e?"a function":P(12329,{type:typeof e})}function ec(e,t){if("_delegate"in e&&(e=e._delegate),!(e instanceof t)){if(t.name===e.constructor.name)throw new z(D.INVALID_ARGUMENT,"Type does not match the expected instance. Did you pass a reference from a different Firestore SDK?");{let r=eu(e);throw new z(D.INVALID_ARGUMENT,`Expected type '${t.name}', but it was: ${r}`)}}return e}function eh(e,t){let r={typeString:e};return t&&(r.value=t),r}function ed(e,t){let r;if(!el(e))throw new z(D.INVALID_ARGUMENT,"JSON must be an object");for(let i in t)if(t[i]){let n=t[i].typeString,a="value"in t[i]?{value:t[i].value}:void 0;if(!(i in e)){r=`JSON missing required field: '${i}'`;break}let s=e[i];if(n&&typeof s!==n){r=`JSON field '${i}' must be a ${n}.`;break}if(void 0!==a&&s!==a.value){r=`Expected '${i}' field to equal '${a.value}'`;break}}if(r)throw new z(D.INVALID_ARGUMENT,r);return!0}class em{static now(){return em.fromMillis(Date.now())}static fromDate(e){return em.fromMillis(e.getTime())}static fromMillis(e){let t=Math.floor(e/1e3),r=Math.floor((e-1e3*t)*1e6);return new em(t,r)}constructor(e,t){if(this.seconds=e,this.nanoseconds=t,t<0||t>=1e9)throw new z(D.INVALID_ARGUMENT,"Timestamp nanoseconds out of range: "+t);if(e<-0xe7791f700||e>=0x3afff44180)throw new z(D.INVALID_ARGUMENT,"Timestamp seconds out of range: "+e)}toDate(){return new Date(this.toMillis())}toMillis(){return 1e3*this.seconds+this.nanoseconds/1e6}_compareTo(e){return this.seconds===e.seconds?Y(this.nanoseconds,e.nanoseconds):Y(this.seconds,e.seconds)}isEqual(e){return e.seconds===this.seconds&&e.nanoseconds===this.nanoseconds}toString(){return"Timestamp(seconds="+this.seconds+", nanoseconds="+this.nanoseconds+")"}toJSON(){return{type:em._jsonSchemaVersion,seconds:this.seconds,nanoseconds:this.nanoseconds}}static fromJSON(e){if(ed(e,em._jsonSchema))return new em(e.seconds,e.nanoseconds)}valueOf(){return String(this.seconds- -0xe7791f700).padStart(12,"0")+"."+String(this.nanoseconds).padStart(9,"0")}
5}em._jsonSchemaVersion="firestore/timestamp/1.0",em._jsonSchema={type:eh("string",em._jsonSchemaVersion),seconds:eh("number"),nanoseconds:eh("number")};class eg{static fromTimestamp(e){return new eg(e)}static min(){return new eg(new em(0,0))}static max(){return new eg(new em(0x3afff4417f,0x3b9ac9ff))}constructor(e){this.timestamp=e}compareTo(e){return this.timestamp._compareTo(e.timestamp)}isEqual(e){return this.timestamp.isEqual(e.timestamp)}toMicroseconds(){return 1e6*this.timestamp.seconds+this.timestamp.nanoseconds/1e3}toString(){return"SnapshotVersion("+this.timestamp.toString()+")"}toTimestamp(){return this.timestamp}}class ep{constructor(e,t,r,i){this.indexId=e,this.collectionGroup=t,this.fields=r,this.indexState=i}}ep.UNKNOWN_ID=-1;class ef{constructor(e,t,r){this.readTime=e,this.documentKey=t,this.largestBatchId=r}static min(){return new ef(eg.min(),en.empty(),-1)}static max(){return new ef(eg.max(),en.empty(),-1)}}class ey{constructor(){this.onCommittedListeners=[]}addOnCommittedListener(e){this.onCommittedListeners.push(e)}raiseOnCommittedEvent(){this.onCommittedListeners.forEach(e=>e())}}async function ev(e){if(e.code!==D.FAILED_PRECONDITION||"The current tab is not in the required state to perform this operation. It might be necessary to refresh the browser tab."!==e.message)throw e;I("LocalStore","Unexpectedly lost primary lease")}class ew{constructor(e){this.nextCallback=null,this.catchCallback=null,this.result=void 0,this.error=void 0,this.isDone=!1,this.callbackAttached=!1,e(e=>{this.isDone=!0,this.result=e,this.nextCallback&&this.nextCallback(e)},e=>{this.isDone=!0,this.error=e,this.catchCallback&&this.catchCallback(e)})}catch(e){return this.next(void 0,e)}next(e,t){return this.callbackAttached&&P(59440),this.callbackAttached=!0,this.isDone?this.error?this.wrapFailure(t,this.error):this.wrapSuccess(e,this.result):new ew((r,i)=>{this.nextCallback=t=>{this.wrapSuccess(e,t).next(r,i)},this.catchCallback=e=>{this.wrapFailure(t,e).next(r,i)}})}toPromise(){return new Promise((e,t)=>{this.next(e,t)})}wrapUserFunction(e){try{let t=e();return t instanceof ew?t:ew.resolve(t)}catch(e){return ew.reject(e)}}wrapSuccess(e,t){return e?this.wrapUserFunction(()=>e(t)):ew.resolve(t)}wrapFailure(e,t){return e?this.wrapUserFunction(()=>e(t)):ew.reject(t)}static resolve(e){return new ew((t,r)=>{t(e)})}static reject(e){return new ew((t,r)=>{r(e)})}static waitFor(e){return new ew((t,r)=>{let i=0,n=0,a=!1;e.forEach(e=>{++i,e.next(()=>{++n,a&&n===i&&t()},e=>r(e))}),a=!0,n===i&&t()})}static or(e){let t=ew.resolve(!1);for(let r of e)t=t.next(e=>e?ew.resolve(e):r());return t}static forEach(e,t){let r=[];return e.forEach((e,i)=>{r.push(t.call(this,e,i))}),this.waitFor(r)}static mapArray(e,t){return new ew((r,i)=>{let n=e.length,a=Array(n),s=0;for(let o=0;o<n;o++){let l=o;t(e[l]).next(e=>{a[l]=e,++s===n&&r(a)},e=>i(e))}})}static doWhile(e,t){return new ew((r,i)=>{let n=()=>{!0===e()?t().next(()=>{n()},i):r()};n()})}}function eb(e){return"IndexedDbTransactionError"===e.name}class eC{constructor(e,t){this.previousValue=e,t&&(t.sequenceNumberHandler=e=>this.ae(e),this.ue=e=>t.writeSequenceNumber(e))}ae(e){return this.previousValue=Math.max(e,this.previousValue),this.previousValue}next(){let e=++this.previousValue;return this.ue&&this.ue(e),e}}eC.ce=-1;function eT(e){return 0===e&&1/e==-1/0}function eS(e){let t=0;for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&t++;return t}function eF(e,t){for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&t(r,e[r])}function ek(e){for(let t in e)if(Object.prototype.hasOwnProperty.call(e,t))return!1;return!0}class eE{constructor(e,t){this.comparator=e,this.root=t||e_.EMPTY}insert(e,t){return new eE(this.comparator,this.root.insert(e,t,this.comparator).copy(null,null,e_.BLACK,null,null))}remove(e){return new eE(this.comparator,this.root.remove(e,this.comparator).copy(null,null,e_.BLACK,null,null))}get(e){let t=this.root;for(;!t.isEmpty();){let r=this.comparator(e,t.key);if(0===r)return t.value;r<0?t=t.left:r>0&&(t=t.right)}return null}indexOf(e){let t=0,r=this.root;for(;!r.isEmpty();){let i=this.comparator(e,r.key);if(0===i)return t+r.left.size;i<0?r=r.left:(t+=r.left.size+1,r=r.right)}return -1}isEmpty(){return this.root.isEmpty()}get size(){return this.root.size}minKey(){return this.root.minKey()}maxKey(){return this.root.maxKey()}inorderTraversal(e){return this.root.inorderTraversal(e)}forEach(e){this.inorderTraversal((t,r)=>(e(t,r),!1))}toString(){let e=[];return this.inorderTraversal((t,r)=>(e.push(`${t}:${r}`),!1)),`{${e.join(", ")}}`}reverseTraversal(e){return this.root.reverseTraversal(e)}getIterator(){return new eA(this.root,null,this.comparator,!1)}getIteratorFrom(e){return new eA(this.root,e,this.comparator,!1)}getReverseIterator(){return new eA(this.root,null,this.comparator,!0)}getReverseIteratorFrom(e){return new eA(this.root,e,this.comparator,!0)}}
5class eA{constructor(e,t,r,i){this.isReverse=i,this.nodeStack=[];let n=1;for(;!e.isEmpty();)if(n=t?r(e.key,t):1,t&&i&&(n*=-1),n<0)e=this.isReverse?e.left:e.right;else{if(0===n){this.nodeStack.push(e);break}this.nodeStack.push(e),e=this.isReverse?e.right:e.left}}getNext(){let e=this.nodeStack.pop(),t={key:e.key,value:e.value};if(this.isReverse)for(e=e.left;!e.isEmpty();)this.nodeStack.push(e),e=e.right;else for(e=e.right;!e.isEmpty();)this.nodeStack.push(e),e=e.left;return t}hasNext(){return this.nodeStack.length>0}peek(){if(0===this.nodeStack.length)return null;let e=this.nodeStack[this.nodeStack.length-1];return{key:e.key,value:e.value}}}class e_{constructor(e,t,r,i,n){this.key=e,this.value=t,this.color=null!=r?r:e_.RED,this.left=null!=i?i:e_.EMPTY,this.right=null!=n?n:e_.EMPTY,this.size=this.left.size+1+this.right.size}copy(e,t,r,i,n){return new e_(null!=e?e:this.key,null!=t?t:this.value,null!=r?r:this.color,null!=i?i:this.left,null!=n?n:this.right)}isEmpty(){return!1}inorderTraversal(e){return this.left.inorderTraversal(e)||e(this.key,this.value)||this.right.inorderTraversal(e)}reverseTraversal(e){return this.right.reverseTraversal(e)||e(this.key,this.value)||this.left.reverseTraversal(e)}min(){return this.left.isEmpty()?this:this.left.min()}minKey(){return this.min().key}maxKey(){return this.right.isEmpty()?this.key:this.right.maxKey()}insert(e,t,r){let i=this,n=r(e,i.key);return(i=n<0?i.copy(null,null,null,i.left.insert(e,t,r),null):0===n?i.copy(null,t,null,null,null):i.copy(null,null,null,null,i.right.insert(e,t,r))).fixUp()}removeMin(){if(this.left.isEmpty())return e_.EMPTY;let e=this;return e.left.isRed()||e.left.left.isRed()||(e=e.moveRedLeft()),(e=e.copy(null,null,null,e.left.removeMin(),null)).fixUp()}remove(e,t){let r,i=this;if(0>t(e,i.key))i.left.isEmpty()||i.left.isRed()||i.left.left.isRed()||(i=i.moveRedLeft()),i=i.copy(null,null,null,i.left.remove(e,t),null);else{if(i.left.isRed()&&(i=i.rotateRight()),i.right.isEmpty()||i.right.isRed()||i.right.left.isRed()||(i=i.moveRedRight()),0===t(e,i.key)){if(i.right.isEmpty())return e_.EMPTY;r=i.right.min(),i=i.copy(r.key,r.value,null,null,i.right.removeMin())}i=i.copy(null,null,null,null,i.right.remove(e,t))}return i.fixUp()}isRed(){return this.color}fixUp(){let e=this;return e.right.isRed()&&!e.left.isRed()&&(e=e.rotateLeft()),e.left.isRed()&&e.left.left.isRed()&&(e=e.rotateRight()),e.left.isRed()&&e.right.isRed()&&(e=e.colorFlip()),e}moveRedLeft(){let e=this.colorFlip();return e.right.left.isRed()&&(e=(e=(e=e.copy(null,null,null,null,e.right.rotateRight())).rotateLeft()).colorFlip()),e}moveRedRight(){let e=this.colorFlip();return e.left.left.isRed()&&(e=(e=e.rotateRight()).colorFlip()),e}rotateLeft(){let e=this.copy(null,null,e_.RED,null,this.right.left);return this.right.copy(null,null,this.color,e,null)}rotateRight(){let e=this.copy(null,null,e_.RED,this.left.right,null);return this.left.copy(null,null,this.color,null,e)}colorFlip(){let e=this.left.copy(null,null,!this.left.color,null,null),t=this.right.copy(null,null,!this.right.color,null,null);return this.copy(null,null,!this.color,e,t)}checkMaxDepth(){return Math.pow(2,this.check())<=this.size+1}check(){if(this.isRed()&&this.left.isRed())throw P(43730,{key:this.key,value:this.value});if(this.right.isRed())throw P(14113,{key:this.key,value:this.value});let e=this.left.check();if(e!==this.right.check())throw P(27949);return e+ +!this.isRed()}}e_.EMPTY=null,e_.RED=!0,e_.BLACK=!1,e_.EMPTY=new class{constructor(){this.size=0}get key(){throw P(57766)}get value(){throw P(16141)}get color(){throw P(16727)}get left(){throw P(29726)}get right(){throw P(36894)}copy(e,t,r,i,n){return this}insert(e,t,r){return new e_(e,t)}remove(e,t){return this}isEmpty(){return!0}inorderTraversal(e){return!1}reverseTraversal(e){return!1}minKey(){return null}maxKey(){return null}isRed(){return!1}checkMaxDepth(){return!0}check(){return 0}};class eR{constructor(e){this.comparator=e,this.data=new eE(this.comparator)}has(e){return null!==this.data.get(e)}first(){return this.data.minKey()}last(){return this.data.maxKey()}get size(){return this.data.size}indexOf(e){return this.data.indexOf(e)}forEach(e){this.data.inorderTraversal((t,r)=>(e(t),!1))}forEachInRange(e,t){let r=this.data.getIteratorFrom(e[0]);for(;r.hasNext();){let i=r.getNext();if(this.comparator(i.key,e[1])>=0)return;t(i.key)}}forEachWhile(e,t){let r;for(r=void 0!==t?this.data.getIteratorFrom(t):this.data.getIterator();r.hasNext();)if(!e(r.getNext().key))return}firstAfterOrEqual(e){let t=this.data.getIteratorFrom(e);return t.hasNext()?t.getNext().key:null}getIterator(){return new eI(this.data.getIterator())}getIteratorFrom(e){return new eI(this.data.getIteratorFrom(e))}add(e){return this.copy(this.data.remove(e).insert(e,!0))}delete(e){return this.has(e)?this.copy(this.data.remove(e)):this}isEmpty(){return this.data.isEmpty()}unionWith(e){let t=this;
5return t.size<e.size&&(t=e,e=this),e.forEach(e=>{t=t.add(e)}),t}isEqual(e){if(!(e instanceof eR)||this.size!==e.size)return!1;let t=this.data.getIterator(),r=e.data.getIterator();for(;t.hasNext();){let e=t.getNext().key,i=r.getNext().key;if(0!==this.comparator(e,i))return!1}return!0}toArray(){let e=[];return this.forEach(t=>{e.push(t)}),e}toString(){let e=[];return this.forEach(t=>e.push(t)),"SortedSet("+e.toString()+")"}copy(e){let t=new eR(this.comparator);return t.data=e,t}}class eI{constructor(e){this.iter=e}getNext(){return this.iter.getNext().key}hasNext(){return this.iter.hasNext()}}class ex{constructor(e){this.fields=e,e.sort(ei.comparator)}static empty(){return new ex([])}unionWith(e){let t=new eR(ei.comparator);for(let e of this.fields)t=t.add(e);for(let r of e)t=t.add(r);return new ex(t.toArray())}covers(e){for(let t of this.fields)if(t.isPrefixOf(e))return!0;return!1}isEqual(e){return X(this.fields,e.fields,(e,t)=>e.isEqual(t))}}class eO extends Error{constructor(){super(...arguments),this.name="Base64DecodeError"}}class eM{constructor(e){this.binaryString=e}static fromBase64String(e){return new eM(function(e){try{return atob(e)}catch(e){throw"u">typeof DOMException&&e instanceof DOMException?new eO("Invalid base64 string: "+e):e}}(e))}static fromUint8Array(e){return new eM(function(e){let t="";for(let r=0;r<e.length;++r)t+=String.fromCharCode(e[r]);return t}(e))}[Symbol.iterator](){let e=0;return{next:()=>e<this.binaryString.length?{value:this.binaryString.charCodeAt(e++),done:!1}:{value:void 0,done:!0}}}toBase64(){return btoa(this.binaryString)}toUint8Array(){var e=this.binaryString;let t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}approximateByteSize(){return 2*this.binaryString.length}compareTo(e){return Y(this.binaryString,e.binaryString)}isEqual(e){return this.binaryString===e.binaryString}}eM.EMPTY_BYTE_STRING=new eM("");let eP=new RegExp(/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.(\d+))?Z$/);function eL(e){if(N(!!e,39018),"string"==typeof e){let t=0,r=eP.exec(e);if(N(!!r,46558,{timestamp:e}),r[1]){let e=r[1];t=Number(e=(e+"000000000").substr(0,9))}return{seconds:Math.floor(new Date(e).getTime()/1e3),nanos:t}}return{seconds:eN(e.seconds),nanos:eN(e.nanos)}}function eN(e){return"number"==typeof e?e:"string"==typeof e?Number(e):0}function eD(e){return"string"==typeof e?eM.fromBase64String(e):eM.fromUint8Array(e)}let ez="server_timestamp",eU="__type__",eB="__previous_value__",eV="__local_write_time__";function ej(e){return(e?.mapValue?.fields||{})[eU]?.stringValue===ez}function eG(e){let t=e.mapValue.fields[eB];return ej(t)?eG(t):t}function eK(e){let t=eL(e.mapValue.fields[eV].timestampValue);return new em(t.seconds,t.nanos)}class eH{constructor(e,t,r,i,n,a,s,o,l,u,c){this.databaseId=e,this.appId=t,this.persistenceKey=r,this.host=i,this.ssl=n,this.forceLongPolling=a,this.autoDetectLongPolling=s,this.longPollingOptions=o,this.useFetchStreams=l,this.isUsingEmulator=u,this.apiKey=c}}
5let eq="(default)";class eW{constructor(e,t){this.projectId=e,this.database=t||eq}static empty(){return new eW("","")}get isDefaultDatabase(){return this.database===eq}isEqual(e){return e instanceof eW&&e.projectId===this.projectId&&e.database===this.database}}let e$="__type__",eY="__max__",eJ={fields:{__type__:{stringValue:eY}}},eQ="__vector__",eX="value";function eZ(e){return"nullValue"in e?0:"booleanValue"in e?1:"integerValue"in e||"doubleValue"in e?2:"timestampValue"in e?3:"stringValue"in e?5:"bytesValue"in e?6:"referenceValue"in e?7:"geoPointValue"in e?8:"arrayValue"in e?9:"mapValue"in e?ej(e)?4:tn(e)?0x1fffffffffffff:tr(e)?10:11:P(28295,{value:e})}function e0(e,t){if(e===t)return!0;let r=eZ(e);if(r!==eZ(t))return!1;switch(r){case 0:case 0x1fffffffffffff:return!0;case 1:return e.booleanValue===t.booleanValue;case 4:return eK(e).isEqual(eK(t));case 3:if("string"==typeof e.timestampValue&&"string"==typeof t.timestampValue&&e.timestampValue.length===t.timestampValue.length)return e.timestampValue===t.timestampValue;let i=eL(e.timestampValue),n=eL(t.timestampValue);return i.seconds===n.seconds&&i.nanos===n.nanos;case 5:return e.stringValue===t.stringValue;case 6:return eD(e.bytesValue).isEqual(eD(t.bytesValue));case 7:return e.referenceValue===t.referenceValue;case 8:return eN(e.geoPointValue.latitude)===eN(t.geoPointValue.latitude)&&eN(e.geoPointValue.longitude)===eN(t.geoPointValue.longitude);case 2:if("integerValue"in e&&"integerValue"in t)return eN(e.integerValue)===eN(t.integerValue);if("doubleValue"in e&&"doubleValue"in t){let r=eN(e.doubleValue),i=eN(t.doubleValue);return r===i?eT(r)===eT(i):isNaN(r)&&isNaN(i)}return!1;case 9:return X(e.arrayValue.values||[],t.arrayValue.values||[],e0);case 10:case 11:let a=e.mapValue.fields||{},s=t.mapValue.fields||{};if(eS(a)!==eS(s))return!1;for(let e in a)if(a.hasOwnProperty(e)&&(void 0===s[e]||!e0(a[e],s[e])))return!1;return!0;default:return P(52216,{left:e})}}function e1(e,t){return void 0!==(e.values||[]).find(e=>e0(e,t))}function e2(e,t){var r,i,n,a,s,o;if(e===t)return 0;let l=eZ(e),u=eZ(t);if(l!==u)return Y(l,u);switch(l){case 0:case 0x1fffffffffffff:return 0;case 1:return Y(e.booleanValue,t.booleanValue);case 2:let c,h;return c=eN(e.integerValue||e.doubleValue),c<(h=eN(t.integerValue||t.doubleValue))?-1:c>h?1:c===h?0:isNaN(c)?isNaN(h)?0:-1:1;case 3:return e3(e.timestampValue,t.timestampValue);case 4:return e3(eK(e),eK(t));case 5:return J(e.stringValue,t.stringValue);case 6:let d,m;return r=e.bytesValue,i=t.bytesValue,d=eD(r),m=eD(i),d.compareTo(m);case 7:return function(e,t){let r=e.split("/"),i=t.split("/");for(let e=0;e<r.length&&e<i.length;e++){let t=Y(r[e],i[e]);if(0!==t)return t}return Y(r.length,i.length)}(e.referenceValue,t.referenceValue);case 8:let g;return n=e.geoPointValue,a=t.geoPointValue,0!==(g=Y(eN(n.latitude),eN(a.latitude)))?g:Y(eN(n.longitude),eN(a.longitude));case 9:return e4(e.arrayValue,t.arrayValue);case 10:let p,f,y,v,w;return s=e.mapValue,o=t.mapValue,p=s.fields||{},f=o.fields||{},y=p[eX]?.arrayValue,v=f[eX]?.arrayValue,0!==(w=Y(y?.values?.length||0,v?.values?.length||0))?w:e4(y,v);case 11:return function(e,t){if(e===eJ&&t===eJ)return 0;if(e===eJ)return 1;if(t===eJ)return -1;let r=e.fields||{},i=Object.keys(r),n=t.fields||{},a=Object.keys(n);i.sort(),a.sort();for(let e=0;e<i.length&&e<a.length;++e){let t=J(i[e],a[e]);if(0!==t)return t;let s=e2(r[i[e]],n[a[e]]);if(0!==s)return s}return Y(i.length,a.length)}(e.mapValue,t.mapValue);default:throw P(23264,{he:l})}}function e3(e,t){if("string"==typeof e&&"string"==typeof t&&e.length===t.length)return Y(e,t);let r=eL(e),i=eL(t),n=Y(r.seconds,i.seconds);return 0!==n?n:Y(r.nanos,i.nanos)}function e4(e,t){let r=e.values||[],i=t.values||[];for(let e=0;e<r.length&&e<i.length;++e){let t=e2(r[e],i[e]);if(t)return t}return Y(r.length,i.length)}function e5(e){var t,r;let i;return"nullValue"in e?"null":"booleanValue"in e?""+e.booleanValue:"integerValue"in e?""+e.integerValue:"doubleValue"in e?""+e.doubleValue:"timestampValue"in e?(i=eL(e.timestampValue),`time(${i.seconds},${i.nanos})`):"stringValue"in e?e.stringValue:"bytesValue"in e?eD(e.bytesValue).toBase64():"referenceValue"in e?(t=e.referenceValue,en.fromName(t).toString()):"geoPointValue"in e?(r=e.geoPointValue,`geo(${r.latitude},${r.longitude})`):"arrayValue"in e?function(e){let t="[",r=!0;for(let i of e.values||[])r?r=!1:t+=",",t+=e5(i);return t+"]"}(e.arrayValue):"mapValue"in e?function(e){let t=Object.keys(e.fields||{}).sort(),r="{",i=!0;for(let n of t)i?i=!1:r+=",",r+=`${n}:${e5(e.fields[n])}`;return r+"}"}(e.mapValue):P(61005,{value:e})}function e9(e,t){return{referenceValue:`projects/${e.projectId}/databases/${e.database}/documents/${t.path.canonicalString()}`}}function e6(e){return!!e&&"integerValue"in e}function e8(e){return!!e&&"arrayValue"in e}function e7(e){return!!e&&"nullValue"in e}function te(e){return!!e&&"doubleValue"in e&&isNaN(Number(e.doubleValue))}function tt(e){return!!e&&"mapValue"in e}function tr(e){return(e?.mapValue?.fields||{})[e$]?.stringValue===eQ}function ti(e){if(e.geoPointValue)return{geoPointValue:{...e.geoPointValue}};if(e.timestampValue&&"object"==typeof e.timestampValue)return{timestampValue:{...e.timestampValue}};if(e.mapValue){let t={mapValue:{fields:{}}};return eF(e.mapValue.fields,(e,r)=>t.mapValue.fields[e]=ti(r)),t}if(e.arrayValue){let t={arrayValue:{values:[]}};for(let r=0;r<(e.arrayValue.values||[]).length;++r)t.arrayValue.values[r]=ti(e.arrayValue.values[r]);return t}return{...e}}function tn(e){return(((e.mapValue||{}).fields||{}).__type__||{}).stringValue===eY}class ta{constructor(e){this.value=e}static empty(){return new ta({mapValue:{}})}field(e){if(e.isEmpty())return this.value;{let t=this.value;for(let r=0;r<e.length-1;++r)if(!tt(t=(t.mapValue.fields||{})[e.get(r)]))return null;return(t=(t.mapValue.fields||{})[e.lastSegment()])||null}}set(e,t){this.getFieldsMap(e.popLast())[e.lastSegment()]=ti(t)}setAll(e){let t=ei.emptyPath(),r={},i=[];e.forEach((e,n)=>{if(!t.isImmediateParentOf(n)){let e=this.getFieldsMap(t);this.applyChanges(e,r,i),r={},i=[],t=n.popLast()}e?r[n.lastSegment()]=ti(e):i.push(n.lastSegment())});let n=this.getFieldsMap(t);this.applyChanges(n,r,i)}delete(e){let t=this.field(e.popLast());tt(t)&&t.mapValue.fields&&delete t.mapValue.fields[e.lastSegment()]}isEqual(e){return e0(this.value,e.value)}getFieldsMap(e){let t=this.value;t.mapValue.fields||(t.mapValue={fields:{}});for(let r=0;r<e.length;++r){let i=t.mapValue.fields[e.get(r)];tt(i)&&i.mapValue.fields||(i={mapValue:{fields:{}}},t.mapValue.fields[e.get(r)]=i),t=i}return t.mapValue.fields}
5applyChanges(e,t,r){for(let i of(eF(t,(t,r)=>e[t]=r),r))delete e[i]}clone(){return new ta(ti(this.value))}}class ts{constructor(e,t,r,i,n,a,s){this.key=e,this.documentType=t,this.version=r,this.readTime=i,this.createTime=n,this.data=a,this.documentState=s}static newInvalidDocument(e){return new ts(e,0,eg.min(),eg.min(),eg.min(),ta.empty(),0)}static newFoundDocument(e,t,r,i){return new ts(e,1,t,eg.min(),r,i,0)}static newNoDocument(e,t){return new ts(e,2,t,eg.min(),eg.min(),ta.empty(),0)}static newUnknownDocument(e,t){return new ts(e,3,t,eg.min(),eg.min(),ta.empty(),2)}convertToFoundDocument(e,t){return this.createTime.isEqual(eg.min())&&(2===this.documentType||0===this.documentType)&&(this.createTime=e),this.version=e,this.documentType=1,this.data=t,this.documentState=0,this}convertToNoDocument(e){return this.version=e,this.documentType=2,this.data=ta.empty(),this.documentState=0,this}convertToUnknownDocument(e){return this.version=e,this.documentType=3,this.data=ta.empty(),this.documentState=2,this}setHasCommittedMutations(){return this.documentState=2,this}setHasLocalMutations(){return this.documentState=1,this.version=eg.min(),this}setReadTime(e){return this.readTime=e,this}get hasLocalMutations(){return 1===this.documentState}get hasCommittedMutations(){return 2===this.documentState}get hasPendingWrites(){return this.hasLocalMutations||this.hasCommittedMutations}isValidDocument(){return 0!==this.documentType}isFoundDocument(){return 1===this.documentType}isNoDocument(){return 2===this.documentType}isUnknownDocument(){return 3===this.documentType}isEqual(e){return e instanceof ts&&this.key.isEqual(e.key)&&this.version.isEqual(e.version)&&this.documentType===e.documentType&&this.documentState===e.documentState&&this.data.isEqual(e.data)}mutableCopy(){return new ts(this.key,this.documentType,this.version,this.readTime,this.createTime,this.data.clone(),this.documentState)}toString(){return`Document(${this.key}, ${this.version}, ${JSON.stringify(this.data.value)}, {createTime: ${this.createTime}}), {documentType: ${this.documentType}}), {documentState: ${this.documentState}})`}}class to{constructor(e,t){this.position=e,this.inclusive=t}}function tl(e,t,r){let i=0;for(let n=0;n<e.position.length;n++){let a=t[n],s=e.position[n];if(i=a.field.isKeyField()?en.comparator(en.fromName(s.referenceValue),r.key):e2(s,r.data.field(a.field)),"desc"===a.dir&&(i*=-1),0!==i)break}return i}function tu(e,t){if(null===e)return null===t;if(null===t||e.inclusive!==t.inclusive||e.position.length!==t.position.length)return!1;for(let r=0;r<e.position.length;r++)if(!e0(e.position[r],t.position[r]))return!1;return!0}class tc{constructor(e,t="asc"){this.field=e,this.dir=t}}class th{}class td extends th{constructor(e,t,r){super(),this.field=e,this.op=t,this.value=r}static create(e,t,r){return e.isKeyField()?"in"===t||"not-in"===t?this.createKeyFieldInFilter(e,t,r):new tf(e,t,r):"array-contains"===t?new tb(e,r):"in"===t?new tC(e,r):"not-in"===t?new tT(e,r):"array-contains-any"===t?new tS(e,r):new td(e,t,r)}static createKeyFieldInFilter(e,t,r){return"in"===t?new ty(e,r):new tv(e,r)}matches(e){let t=e.data.field(this.field);return"!="===this.op?null!==t&&void 0===t.nullValue&&this.matchesComparison(e2(t,this.value)):null!==t&&eZ(this.value)===eZ(t)&&this.matchesComparison(e2(t,this.value))}matchesComparison(e){switch(this.op){case"<":return e<0;case"<=":return e<=0;case"==":return 0===e;case"!=":return 0!==e;case">":return e>0;case">=":return e>=0;default:return P(47266,{operator:this.op})}}isInequality(){return["<","<=",">",">=","!=","not-in"].indexOf(this.op)>=0}getFlattenedFilters(){return[this]}getFilters(){return[this]}}class tm extends th{constructor(e,t){super(),this.filters=e,this.op=t,this.Pe=null}static create(e,t){return new tm(e,t)}matches(e){return tg(this)?void 0===this.filters.find(t=>!t.matches(e)):void 0!==this.filters.find(t=>t.matches(e))}getFlattenedFilters(){return null!==this.Pe||(this.Pe=this.filters.reduce((e,t)=>e.concat(t.getFlattenedFilters()),[])),this.Pe}getFilters(){return Object.assign([],this.filters)}}function tg(e){return"and"===e.op}function tp(e){for(let t of e.filters)if(t instanceof tm)return!1;return!0}class tf extends td{constructor(e,t,r){super(e,t,r),this.key=en.fromName(r.referenceValue)}matches(e){let t=en.comparator(e.key,this.key);return this.matchesComparison(t)}}class ty extends td{constructor(e,t){super(e,"in",t),this.keys=tw("in",t)}matches(e){return this.keys.some(t=>t.isEqual(e.key))}}class tv extends td{constructor(e,t){super(e,"not-in",t),this.keys=tw("not-in",t)}matches(e){return!this.keys.some(t=>t.isEqual(e.key))}}function tw(e,t){return(t.arrayValue?.values||[]).map(e=>en.fromName(e.referenceValue))}class tb extends td{constructor(e,t){super(e,"array-contains",t)}matches(e){let t=e.data.field(this.field);return e8(t)&&e1(t.arrayValue,this.value)}}class tC extends td{constructor(e,t){super(e,"in",t)}matches(e){let t=e.data.field(this.field);return null!==t&&e1(this.value.arrayValue,t)}}class tT extends td{constructor(e,t){super(e,"not-in",t)}matches(e){if(e1(this.value.arrayValue,{nullValue:"NULL_VALUE"}))return!1;let t=e.data.field(this.field);return null!==t&&void 0===t.nullValue&&!e1(this.value.arrayValue,t)}}class tS extends td{constructor(e,t){super(e,"array-contains-any",t)}matches(e){let t=e.data.field(this.field);return!(!e8(t)||!t.arrayValue.values)&&t.arrayValue.values.some(e=>e1(this.value.arrayValue,e))}}class tF{constructor(e,t=null,r=[],i=[],n=null,a=null,s=null){this.path=e,this.collectionGroup=t,this.orderBy=r,this.filters=i,this.limit=n,this.startAt=a,this.endAt=s,this.Te=null}}function tk(e,t=null,r=[],i=[],n=null,a=null,s=null){return new tF(e,t,r,i,n,a,s)}function tE(e){if(null===e.Te){let t=e.path.canonicalString();null!==e.collectionGroup&&(t+="|cg:"+e.collectionGroup),t+="|f:",t+=e.filters.map(e=>(function e(t){if(t instanceof td)return t.field.canonicalString()+t.op.toString()+e5(t.value);if(tp(t)&&tg(t))return t.filters.map(t=>e(t)).join(",");{let r=t.filters.map(t=>e(t)).join(",");return`${t.op}(${r})`}})(e)).join(","),t+="|ob:",t+=e.orderBy.map(e=>e.field.canonicalString()+e.dir).join(","),null==e.limit||(t+="|l:",t+=e.limit),e.startAt&&(t+="|lb:",t+=e.startAt.inclusive?"b:":"a:",t+=e.startAt.position.map(e=>e5(e)).join(",")),e.endAt&&(t+="|ub:",t+=e.endAt.inclusive?"a:":"b:",t+=e.endAt.position.map(e=>e5(e)).join(",")),e.Te=t}return e.Te}function tA(e,t){if(e.limit!==t.limit||e.orderBy.length!==t.orderBy.length)return!1;for(let n=0;n<e.orderBy.length;n++){var r,i;if(r=e.orderBy[n],i=t.orderBy[n],!(r.dir===i.dir&&r.field.isEqual(i.field)))return!1}if(e.filters.length!==t.filters.length)return!1;for(let r=0;r<e.filters.length;r++)if(!function e(t,r){return t instanceof td?r instanceof td&&t.op===r.op&&t.field.isEqual(r.field)&&e0(t.value,r.value):t instanceof tm?r instanceof tm&&t.op===r.op&&t.filters.length===r.filters.length&&t.filters.reduce((t,i,n)=>
5t&&e(i,r.filters[n]),!0):void P(19439)}(e.filters[r],t.filters[r]))return!1;return e.collectionGroup===t.collectionGroup&&!!e.path.isEqual(t.path)&&!!tu(e.startAt,t.startAt)&&tu(e.endAt,t.endAt)}function t_(e){return en.isDocumentKey(e.path)&&null===e.collectionGroup&&0===e.filters.length}class tR{constructor(e,t=null,r=[],i=[],n=null,a="F",s=null,o=null){this.path=e,this.collectionGroup=t,this.explicitOrderBy=r,this.filters=i,this.limit=n,this.limitType=a,this.startAt=s,this.endAt=o,this.Ie=null,this.Ee=null,this.Re=null,this.startAt,this.endAt}}function tI(e){return new tR(e)}function tx(e){return 0===e.filters.length&&null===e.limit&&null==e.startAt&&null==e.endAt&&(0===e.explicitOrderBy.length||1===e.explicitOrderBy.length&&e.explicitOrderBy[0].field.isKeyField())}function tO(e){return null!==e.collectionGroup}function tM(e){if(null===e.Ie){let t;e.Ie=[];let r=new Set;for(let t of e.explicitOrderBy)e.Ie.push(t),r.add(t.field.canonicalString());let i=e.explicitOrderBy.length>0?e.explicitOrderBy[e.explicitOrderBy.length-1].dir:"asc";(t=new eR(ei.comparator),e.filters.forEach(e=>{e.getFlattenedFilters().forEach(e=>{e.isInequality()&&(t=t.add(e.field))})}),t).forEach(t=>{r.has(t.canonicalString())||t.isKeyField()||e.Ie.push(new tc(t,i))}),r.has(ei.keyField().canonicalString())||e.Ie.push(new tc(ei.keyField(),i))}return e.Ie}function tP(e){return e.Ee||(e.Ee=function(e,t){if("F"===e.limitType)return tk(e.path,e.collectionGroup,t,e.filters,e.limit,e.startAt,e.endAt);{t=t.map(e=>{let t="desc"===e.dir?"asc":"desc";return new tc(e.field,t)});let r=e.endAt?new to(e.endAt.position,e.endAt.inclusive):null,i=e.startAt?new to(e.startAt.position,e.startAt.inclusive):null;return tk(e.path,e.collectionGroup,t,e.filters,e.limit,r,i)}}(e,tM(e))),e.Ee}function tL(e,t){let r=e.filters.concat([t]);return new tR(e.path,e.collectionGroup,e.explicitOrderBy.slice(),r,e.limit,e.limitType,e.startAt,e.endAt)}function tN(e,t,r){return new tR(e.path,e.collectionGroup,e.explicitOrderBy.slice(),e.filters.slice(),t,r,e.startAt,e.endAt)}function tD(e,t){return tA(tP(e),tP(t))&&e.limitType===t.limitType}function tz(e){return`${tE(tP(e))}|lt:${e.limitType}`}function tU(e){var t;let r;return`Query(target=${r=(t=tP(e)).path.canonicalString(),null!==t.collectionGroup&&(r+=" collectionGroup="+t.collectionGroup),t.filters.length>0&&(r+=`, filters: [${t.filters.map(e=>(function e(t){return t instanceof td?`${t.field.canonicalString()} ${t.op} ${e5(t.value)}`:t instanceof tm?t.op.toString()+" {"+t.getFilters().map(e).join(" ,")+"}":"Filter"})(e)).join(", ")}]`),null==t.limit||(r+=", limit: "+t.limit),t.orderBy.length>0&&(r+=`, orderBy: [${t.orderBy.map(e=>`${e.field.canonicalString()} (${e.dir})`).join(", ")}]`),t.startAt&&(r+=", startAt: ",r+=t.startAt.inclusive?"b:":"a:",r+=t.startAt.position.map(e=>e5(e)).join(",")),t.endAt&&(r+=", endAt: ",r+=t.endAt.inclusive?"a:":"b:",r+=t.endAt.position.map(e=>e5(e)).join(",")),`Target(${r})`}; limitType=${e.limitType})`}function tB(e,t){var r,i,n,a;let s,o,l;return t.isFoundDocument()&&(s=t.key.path,null!==e.collectionGroup?t.key.hasCollectionId(e.collectionGroup)&&e.path.isPrefixOf(s):en.isDocumentKey(e.path)?e.path.isEqual(s):e.path.isImmediateParentOf(s))&&function(e,t){for(let r of tM(e))if(!r.field.isKeyField()&&null===t.data.field(r.field))return!1;return!0}(e,t)&&function(e,t){for(let r of e.filters)if(!r.matches(t))return!1;return!0}(e,t)&&(r=e,i=t,(!r.startAt||(n=r.startAt,o=tl(n,tM(r),i),n.inclusive?!!(o<=0):!!(o<0)))&&(!r.endAt||(a=r.endAt,l=tl(a,tM(r),i),a.inclusive?!!(l>=0):!!(l>0))))}function tV(e){return(t,r)=>{let i=!1;for(let n of tM(e)){let e=function(e,t,r){var i;let n,a,s=e.field.isKeyField()?en.comparator(t.key,r.key):(i=e.field,n=t.data.field(i),a=r.data.field(i),null!==n&&null!==a?e2(n,a):P(42886));switch(e.dir){case"asc":return s;case"desc":return -1*s;default:return P(19790,{direction:e.dir})}}(n,t,r);if(0!==e)return e;i=i||n.field.isKeyField()}return 0}}class tj{constructor(e,t){this.mapKeyFn=e,this.equalsFn=t,this.inner={},this.innerSize=0}get(e){let t=this.mapKeyFn(e),r=this.inner[t];if(void 0!==r){for(let[t,i]of r)if(this.equalsFn(t,e))return i}}has(e){return void 0!==this.get(e)}set(e,t){let r=this.mapKeyFn(e),i=this.inner[r];if(void 0===i)return this.inner[r]=[[e,t]],void this.innerSize++;for(let r=0;r<i.length;r++)if(this.equalsFn(i[r][0],e))return void(i[r]=[e,t]);i.push([e,t]),this.innerSize++}delete(e){let t=this.mapKeyFn(e),r=this.inner[t];if(void 0===r)return!1;for(let i=0;i<r.length;i++)if(this.equalsFn(r[i][0],e))return 1===r.length?delete this.inner[t]:r.splice(i,1),this.innerSize--,!0;return!1}forEach(e){eF(this.inner,(t,r)=>{for(let[t,i]of r)e(t,i)})}isEmpty(){return ek(this.inner)}size(){return this.innerSize}}let tG=new eE(en.comparator),tK=new eE(en.comparator);function tH(...e){let t=tK;for(let r of e)t=t.insert(r.key,r);return t}function tq(e){let t=tK;return e.forEach((e,r)=>t=t.insert(e,r.overlayedDocument)),t}function tW(){return new tj(e=>e.toString(),(e,t)=>e.isEqual(t))}
5let t$=new eE(en.comparator),tY=new eR(en.comparator);function tJ(...e){let t=tY;for(let r of e)t=t.add(r);return t}let tQ=new eR(Y);function tX(e,t){if(e.useProto3Json){if(isNaN(t))return{doubleValue:"NaN"};if(t===1/0)return{doubleValue:"Infinity"};if(t===-1/0)return{doubleValue:"-Infinity"}}return{doubleValue:eT(t)?"-0":t}}function tZ(e){return{integerValue:""+e}}class t0{constructor(){this._=void 0}}function t1(e,t){return e instanceof t6?e6(t)||t&&"doubleValue"in t?t:{integerValue:0}:null}class t2 extends t0{}class t3 extends t0{constructor(e){super(),this.elements=e}}function t4(e,t){let r=t7(t);for(let t of e.elements)r.some(e=>e0(e,t))||r.push(t);return{arrayValue:{values:r}}}class t5 extends t0{constructor(e){super(),this.elements=e}}function t9(e,t){let r=t7(t);for(let t of e.elements)r=r.filter(e=>!e0(e,t));return{arrayValue:{values:r}}}class t6 extends t0{constructor(e,t){super(),this.serializer=e,this.Ae=t}}function t8(e){return eN(e.integerValue||e.doubleValue)}function t7(e){return e8(e)&&e.arrayValue.values?e.arrayValue.values.slice():[]}class re{constructor(e,t){this.field=e,this.transform=t}}class rt{constructor(e,t){this.version=e,this.transformResults=t}}class rr{constructor(e,t){this.updateTime=e,this.exists=t}static none(){return new rr}static exists(e){return new rr(void 0,e)}static updateTime(e){return new rr(e)}get isNone(){return void 0===this.updateTime&&void 0===this.exists}isEqual(e){return this.exists===e.exists&&(this.updateTime?!!e.updateTime&&this.updateTime.isEqual(e.updateTime):!e.updateTime)}}function ri(e,t){return void 0!==e.updateTime?t.isFoundDocument()&&t.version.isEqual(e.updateTime):void 0===e.exists||e.exists===t.isFoundDocument()}class rn{}function ra(e,t){if(!e.hasLocalMutations||t&&0===t.fields.length)return null;if(null===t)return e.isNoDocument()?new rm(e.key,rr.none()):new rl(e.key,e.data,rr.none());{let r=e.data,i=ta.empty(),n=new eR(ei.comparator);for(let e of t.fields)if(!n.has(e)){let t=r.field(e);null===t&&e.length>1&&(e=e.popLast(),t=r.field(e)),null===t?i.delete(e):i.set(e,t),n=n.add(e)}return new ru(e.key,i,new ex(n.toArray()),rr.none())}}function rs(e,t,r,i){return e instanceof rl?function(e,t,r,i){if(!ri(e.precondition,t))return r;let n=e.value.clone(),a=rd(e.fieldTransforms,i,t);return n.setAll(a),t.convertToFoundDocument(t.version,n).setHasLocalMutations(),null}(e,t,r,i):e instanceof ru?function(e,t,r,i){if(!ri(e.precondition,t))return r;let n=rd(e.fieldTransforms,i,t),a=t.data;return(a.setAll(rc(e)),a.setAll(n),t.convertToFoundDocument(t.version,a).setHasLocalMutations(),null===r)?null:r.unionWith(e.fieldMask.fields).unionWith(e.fieldTransforms.map(e=>e.field))}(e,t,r,i):ri(e.precondition,t)?(t.convertToNoDocument(t.version).setHasLocalMutations(),null):r}function ro(e,t){var r,i;return e.type===t.type&&!!e.key.isEqual(t.key)&&!!e.precondition.isEqual(t.precondition)&&(r=e.fieldTransforms,i=t.fieldTransforms,!!(void 0===r&&void 0===i||!(!r||!i)&&X(r,i,(e,t)=>{var r,i;return e.field.isEqual(t.field)&&(r=e.transform,i=t.transform,r instanceof t3&&i instanceof t3||r instanceof t5&&i instanceof t5?X(r.elements,i.elements,e0):r instanceof t6&&i instanceof t6?e0(r.Ae,i.Ae):r instanceof t2&&i instanceof t2)})))&&(0===e.type?e.value.isEqual(t.value):1!==e.type||e.data.isEqual(t.data)&&e.fieldMask.isEqual(t.fieldMask))}class rl extends rn{constructor(e,t,r,i=[]){super(),this.key=e,this.value=t,this.precondition=r,this.fieldTransforms=i,this.type=0}getFieldMask(){return null}}class ru extends rn{constructor(e,t,r,i,n=[]){super(),this.key=e,this.data=t,this.fieldMask=r,this.precondition=i,this.fieldTransforms=n,this.type=1}getFieldMask(){return this.fieldMask}}function rc(e){let t=new Map;return e.fieldMask.fields.forEach(r=>{if(!r.isEmpty()){let i=e.data.field(r);t.set(r,i)}}),t}function rh(e,t,r){let i=new Map;N(e.length===r.length,32656,{Ve:r.length,de:e.length});for(let a=0;a<r.length;a++){var n;let s=e[a],o=s.transform,l=t.data.field(s.field);i.set(s.field,(n=r[a],o instanceof t3?t4(o,l):o instanceof t5?t9(o,l):n))}return i}function rd(e,t,r){let i=new Map;for(let n of e){let e=n.transform,a=r.data.field(n.field);i.set(n.field,function(e,t,r){var i;let n,a,s;return e instanceof t2?(i=t,n={fields:{[eU]:{stringValue:ez},[eV]:{timestampValue:{seconds:r.seconds,nanos:r.nanoseconds}}}},i&&ej(i)&&(i=eG(i)),i&&(n.fields[eB]=i),{mapValue:n}):e instanceof t3?t4(e,t):e instanceof t5?t9(e,t):(s=t8(a=t1(e,t))+t8(e.Ae),e6(a)&&e6(e.Ae)?tZ(s):tX(e.serializer,s))}(e,a,t))}return i}class rm extends rn{constructor(e,t){super(),this.key=e,this.prec
5ondition=t,this.type=2,this.fieldTransforms=[]}getFieldMask(){return null}}class rg extends rn{constructor(e,t){super(),this.key=e,this.precondition=t,this.type=3,this.fieldTransforms=[]}getFieldMask(){return null}}class rp{constructor(e,t,r,i){this.batchId=e,this.localWriteTime=t,this.baseMutations=r,this.mutations=i}applyToRemoteDocument(e,t){let r=t.mutationResults;for(let t=0;t<this.mutations.length;t++){let i=this.mutations[t];i.key.isEqual(e.key)&&function(e,t,r){let i,n;e instanceof rl?(i=e.value.clone(),n=rh(e.fieldTransforms,t,r.transformResults),i.setAll(n),t.convertToFoundDocument(r.version,i).setHasCommittedMutations()):e instanceof ru?function(e,t,r){if(!ri(e.precondition,t))return t.convertToUnknownDocument(r.version);let i=rh(e.fieldTransforms,t,r.transformResults),n=t.data;n.setAll(rc(e)),n.setAll(i),t.convertToFoundDocument(r.version,n).setHasCommittedMutations()}(e,t,r):t.convertToNoDocument(r.version).setHasCommittedMutations()}(i,e,r[t])}}applyToLocalView(e,t){for(let r of this.baseMutations)r.key.isEqual(e.key)&&(t=rs(r,e,t,this.localWriteTime));for(let r of this.mutations)r.key.isEqual(e.key)&&(t=rs(r,e,t,this.localWriteTime));return t}applyToLocalDocumentSet(e,t){let r=tW();return this.mutations.forEach(i=>{let n=e.get(i.key),a=n.overlayedDocument,s=this.applyToLocalView(a,n.mutatedFields),o=ra(a,s=t.has(i.key)?null:s);null!==o&&r.set(i.key,o),a.isValidDocument()||a.convertToNoDocument(eg.min())}),r}keys(){return this.mutations.reduce((e,t)=>e.add(t.key),tJ())}isEqual(e){return this.batchId===e.batchId&&X(this.mutations,e.mutations,(e,t)=>ro(e,t))&&X(this.baseMutations,e.baseMutations,(e,t)=>ro(e,t))}}
5class rf{constructor(e,t,r,i){this.batch=e,this.commitVersion=t,this.mutationResults=r,this.docVersions=i}static from(e,t,r){N(e.mutations.length===r.length,58842,{me:e.mutations.length,fe:r.length});let i=t$,n=e.mutations;for(let e=0;e<n.length;e++)i=i.insert(n[e].key,r[e].version);return new rf(e,t,r,i)}}class ry{constructor(e,t){this.largestBatchId=e,this.mutation=t}getKey(){return this.mutation.key}isEqual(e){return null!==e&&this.mutation===e.mutation}toString(){return`Overlay{ 6 largestBatchId: ${this.largestBatchId}, 7 mutation: ${this.mutation.toString()} 8 }`}}class rv{constructor(e,t){this.count=e,this.unchangedNames=t}}function rw(e){if(void 0===e)return x("GRPC error has no .code"),D.UNKNOWN;switch(e){case m.OK:return D.OK;case m.CANCELLED:return D.CANCELLED;case m.UNKNOWN:return D.UNKNOWN;case m.DEADLINE_EXCEEDED:return D.DEADLINE_EXCEEDED;case m.RESOURCE_EXHAUSTED:return D.RESOURCE_EXHAUSTED;case m.INTERNAL:return D.INTERNAL;case m.UNAVAILABLE:return D.UNAVAILABLE;case m.UNAUTHENTICATED:return D.UNAUTHENTICATED;case m.INVALID_ARGUMENT:return D.INVALID_ARGUMENT;case m.NOT_FOUND:return D.NOT_FOUND;case m.ALREADY_EXISTS:return D.ALREADY_EXISTS;case m.PERMISSION_DENIED:return D.PERMISSION_DENIED;case m.FAILED_PRECONDITION:return D.FAILED_PRECONDITION;case m.ABORTED:return D.ABORTED;case m.OUT_OF_RANGE:return D.OUT_OF_RANGE;case m.UNIMPLEMENTED:return D.UNIMPLEMENTED;case m.DATA_LOSS:return D.DATA_LOSS;default:return P(39323,{code:e})}}(g=m||(m={}))[g.OK=0]="OK",g[g.CANCELLED=1]="CANCELLED",g[g.UNKNOWN=2]="UNKNOWN",g[g.INVALID_ARGUMENT=3]="INVALID_ARGUMENT",g[g.DEADLINE_EXCEEDED=4]="DEADLINE_EXCEEDED",g[g.NOT_FOUND=5]="NOT_FOUND",g[g.ALREADY_EXISTS=6]="ALREADY_EXISTS",g[g.PERMISSION_DENIED=7]="PERMISSION_DENIED",g[g.UNAUTHENTICATED=16]="UNAUTHENTICATED",g[g.RESOURCE_EXHAUSTED=8]="RESOURCE_EXHAUSTED",g[g.FAILED_PRECONDITION=9]="FAILED_PRECONDITION",g[g.ABORTED=10]="ABORTED",g[g.OUT_OF_RANGE=11]="OUT_OF_RANGE",g[g.UNIMPLEMENTED=12]="UNIMPLEMENTED",g[g.INTERNAL=13]="INTERNAL",g[g.UNAVAILABLE=14]="UNAVAILABLE",g[g.DATA_LOSS=15]="DATA_LOSS";let rb=new i([0xffffffff,0xffffffff],0);function rC(e){let t=(new TextEncoder).encode(e),r=new n;return r.update(t),new Uint8Array(r.digest())}function rT(e){let t=new DataView(e.buffer),r=t.getUint32(0,!0),n=t.getUint32(4,!0),a=t.getUint32(8,!0),s=t.getUint32(12,!0);return[new i([r,n],0),new i([a,s],0)]}class rS{constructor(e,t,r){if(this.bitmap=e,this.padding=t,this.hashCount=r,t<0||t>=8)throw new rF(`Invalid padding: ${t}`);if(r<0||e.length>0&&0===this.hashCount)throw new rF(`Invalid hash count: ${r}`);if(0===e.length&&0!==t)throw new rF(`Invalid padding when bitmap length is 0: ${t}`);this.ge=8*e.length-t,this.pe=i.fromNumber(this.ge)}ye(e,t,r){let n=e.add(t.multiply(i.fromNumber(r)));return 1===n.compare(rb)&&(n=new i([n.getBits(0),n.getBits(1)],0)),n.modulo(this.pe).toNumber()}we(e){return!!(this.bitmap[Math.floor(e/8)]&1<<e%8)}mightContain(e){if(0===this.ge)return!1;let[t,r]=rT(rC(e));for(let e=0;e<this.hashCount;e++){let i=this.ye(t,r,e);if(!this.we(i))return!1}return!0}static create(e,t,r){let i=new rS(new Uint8Array(Math.ceil(e/8)),e%8==0?0:8-e%8,t);return r.forEach(e=>i.insert(e)),i}insert(e){if(0===this.ge)return;let[t,r]=rT(rC(e));for(let e=0;e<this.hashCount;e++){let i=this.ye(t,r,e);this.be(i)}}be(e){let t=Math.floor(e/8);this.bitmap[t]|=1<<e%8}}
8class rF extends Error{constructor(){super(...arguments),this.name="BloomFilterError"}}class rk{constructor(e,t,r,i,n){this.snapshotVersion=e,this.targetChanges=t,this.targetMismatches=r,this.documentUpdates=i,this.resolvedLimboDocuments=n}static createSynthesizedRemoteEventForCurrentChange(e,t,r){let i=new Map;return i.set(e,rE.createSynthesizedTargetChangeForCurrentChange(e,t,r)),new rk(eg.min(),i,new eE(Y),tG,tJ())}}class rE{constructor(e,t,r,i,n){this.resumeToken=e,this.current=t,this.addedDocuments=r,this.modifiedDocuments=i,this.removedDocuments=n}static createSynthesizedTargetChangeForCurrentChange(e,t,r){return new rE(r,t,tJ(),tJ(),tJ())}}class rA{constructor(e,t,r,i){this.Se=e,this.removedTargetIds=t,this.key=r,this.De=i}}class r_{constructor(e,t){this.targetId=e,this.Ce=t}}class rR{constructor(e,t,r=eM.EMPTY_BYTE_STRING,i=null){this.state=e,this.targetIds=t,this.resumeToken=r,this.cause=i}}class rI{constructor(){this.ve=0,this.Fe=rM(),this.Me=eM.EMPTY_BYTE_STRING,this.xe=!1,this.Oe=!0}get current(){return this.xe}get resumeToken(){return this.Me}get Ne(){return 0!==this.ve}get Be(){return this.Oe}Le(e){e.approximateByteSize()>0&&(this.Oe=!0,this.Me=e)}ke(){let e=tJ(),t=tJ(),r=tJ();return this.Fe.forEach((i,n)=>{switch(n){case 0:e=e.add(i);break;case 2:t=t.add(i);break;case 1:r=r.add(i);break;default:P(38017,{changeType:n})}}),new rE(this.Me,this.xe,e,t,r)}Ke(){this.Oe=!1,this.Fe=rM()}qe(e,t){this.Oe=!0,this.Fe=this.Fe.insert(e,t)}Ue(e){this.Oe=!0,this.Fe=this.Fe.remove(e)}$e(){this.ve+=1}We(){this.ve-=1,N(this.ve>=0,3241,{ve:this.ve})}Qe(){this.Oe=!0,this.xe=!0}}class rx{constructor(e){this.Ge=e,this.ze=new Map,this.je=tG,this.He=rO(),this.Je=rO(),this.Ze=new eE(Y)}Xe(e){for(let t of e.Se)e.De&&e.De.isFoundDocument()?this.Ye(t,e.De):this.et(t,e.key,e.De);for(let t of e.removedTargetIds)this.et(t,e.key,e.De)}tt(e){this.forEachTarget(e,t=>{let r=this.nt(t);switch(e.state){case 0:this.rt(t)&&r.Le(e.resumeToken);break;case 1:r.We(),r.Ne||r.Ke(),r.Le(e.resumeToken);break;case 2:r.We(),r.Ne||this.removeTarget(t);break;case 3:this.rt(t)&&(r.Qe(),r.Le(e.resumeToken));break;case 4:this.rt(t)&&(this.it(t),r.Le(e.resumeToken));break;default:P(56790,{state:e.state})}})}forEachTarget(e,t){e.targetIds.length>0?e.targetIds.forEach(t):this.ze.forEach((e,r)=>{this.rt(r)&&t(r)})}st(e){let t=e.targetId,r=e.Ce.count,i=this.ot(t);if(i){let n=i.target;if(t_(n))if(0===r){let e=new en(n.path);this.et(t,e,ts.newNoDocument(e,eg.min()))}else N(1===r,20013,{expectedCount:r});else{let i=this._t(t);if(i!==r){let r=this.ut(e),n=r?this.ct(r,e,i):1;0!==n&&(this.it(t),this.Ze=this.Ze.insert(t,2===n?"TargetPurposeExistenceFilterMismatchBloom":"TargetPurposeExistenceFilterMismatch"))}}}}ut(e){let t,r,i=e.Ce.unchangedNames;if(!i||!i.bits)return null;let{bits:{bitmap:n="",padding:a=0},hashCount:s=0}=i;try{t=eD(n).toUint8Array()}catch(e){if(e instanceof eO)return O("Decoding the base64 bloom filter in existence filter failed ("+e.message+"); ignoring the bloom filter and falling back to full re-query."),null;throw e}try{r=new rS(t,a,s)}catch(e){return O(e instanceof rF?"BloomFilter error: ":"Applying bloom filter failed: ",e),null}return 0===r.ge?null:r}ct(e,t,r){return 2*(t.Ce.count!==r-this.Pt(e,t.targetId))}Pt(e,t){let r=this.Ge.getRemoteKeysForTarget(t),i=0;return r.forEach(r=>{let n=this.Ge.ht(),a=`projects/${n.projectId}/databases/${n.database}/documents/${r.path.canonicalString()}`;e.mightContain(a)||(this.et(t,r,null),i++)}),i}Tt(e){let t=new Map;this.ze.forEach((r,i)=>{let n=this.ot(i);if(n){if(r.current&&t_(n.target)){let t=new en(n.target.path);this.It(t).has(i)||this.Et(i,t)||this.et(i,t,ts.newNoDocument(t,e))}r.Be&&(t.set(i,r.ke()),r.Ke())}});let r=tJ();this.Je.forEach((e,t)=>{let i=!0;t.forEachWhile(e=>{let t=this.ot(e);return!t||"TargetPurposeLimboResolution"===t.purpose||(i=!1,!1)}),i&&(r=r.add(e))}),this.je.forEach((t,r)=>r.setReadTime(e));let i=new rk(e,t,this.Ze,this.je,r);return this.je=tG,this.He=rO(),this.Je=rO(),this.Ze=new eE(Y),i}Ye(e,t){if(!this.rt(e))return;let r=2*!!this.Et(e,t.key);this.nt(e).qe(t.key,r),this.je=this.je.insert(t.key,t),this.He=this.He.insert(t.key,this.It(t.key).add(e)),this.Je=this.Je.insert(t.key,this.Rt(t.key).add(e))}et(e,t,r){if(!this.rt(e))return;let i=this.nt(e);this.Et(e,t)?i.qe(t,1):i.Ue(t),this.Je=this.Je.insert(t,this.Rt(t).delete(e)),this.Je=this.Je.insert(t,this.Rt(t).add(e)),r&&(this.je=this.je.insert(t,r))}removeTarget(e){this.ze.delete(e)}_t(e){let t=this.nt(e).ke();return this.Ge.getRemoteKeysForTarget(e).size+t.addedDocuments.size-t.removedDocuments.size}$e(e){this.nt(e).$e()}nt(e){let t=this.ze.get(e);return t||(t=new rI,this.ze.set(e,t)),t}Rt(e){let t=this.Je.get(e);return t||(t=new eR(Y),this.Je=this.Je.insert(e,t)),t}It(e){let t=this.He.get(e);return t||(t=new eR(Y),this.He=this.He.insert(e,t)),t}rt(e){let t=null!==this.ot(e);return t||I("WatchChangeAggregator","Detected inactive target",e),t}ot(e){let t=this.ze.get(e);return t&&t.Ne?null:this.Ge.At(e)}it(e){this.ze.set(e,new rI),this.Ge.getRemoteKeysForTarget(e).forEach(t=>{this.et(e,t,null)})}Et(e,t){return this.Ge.getRemoteKeysForTarget(e).has(t)}}function rO(){return new eE(en.comparator)}function rM(){return new eE(en.comparator)}let rP={asc:"ASCENDING",desc:"DESCENDING"},rL={"<":"LESS_THAN","<=":"LESS_THAN_OR_EQUAL",">":"GREATER_THAN",">=":"GREATER_THAN_OR_EQUAL","==":"EQUAL","!=":"NOT_EQUAL","array-contains":"ARRAY_CONTAINS",in:"IN","not-in":"NOT_IN","array-contains-any":"ARRAY_CONTAINS_ANY"},rN={and:"AND",or:"OR"};class rD{constructor(e,t){this.databaseId=e,this.useProto3Json=t}}function rz(e,t){return e.useProto3Json||null==t?t:{value:t}}function rU(e,t){return e.useProto3Json?`${new Date(1e3*t.seconds).toISOString().replace(/\.\d*/,"").replace("Z","")}.${("000000000"+t.nanoseconds).slice(-9)}Z`:{seconds:""+t.seconds,nanos:t.nanoseconds}}function rB(e,t){return e.useProto3Json?t.toBase64():t.toUint8Array()}function rV(e){let t;return N(!!e,49232),eg.fromTimestamp(new em((t=eL(e)).seconds,t.nanos))}function rj(e,t){return rG(e,t).canonicalString()}function rG(e,t){let r=new et(["projects",e.projectId,"databases",e.database]).child("documents");return void 0===t?r:r.child(t)}function rK(e){let t=et.fromString(e);return N(rZ(t),10190,{key:t.toString()}),t}function rH(e,t){return rj(e.databaseId,t.path)}function rq(e,t){let r=rK(t);if(r.get(1)!==e.databaseId.projectId)throw new z(D.INVALID_ARGUMENT,"Tried to deserialize key from different project: "+r.get(1)+" vs "+e.databaseId.projectId);if(r.get(3)!==e.databaseId.database)throw new z(D.INVALID_ARGUMENT,"Tried to deserialize key from different database: "+r.get(3)+" vs "+e.databaseId.database);return new en(rY(r))}function rW(e,t){return rj(e.databaseId,t)}function r$(e){return new et(["projects",e.databaseId.projectId,"databases",e.databaseId.database]).canonicalString()}function rY(e){return N(e.length>4&&"documents"===e.get(4),29091,{key:e.toString()}),e.popFirst(5)}function rJ(e,t,r){return{name:rH(e,t),fields:r.value.mapValue.fields}}function rQ(e){return{fieldPath:e.canonicalString()}}function rX(e){return ei.fromServerFormat(e.fieldPath)}function rZ(e){return e.length>=4&&"projects"===e.get(0)&&"databases"===e.get(2)}function r0(e){return!!e&&"function"==typeof e._toProto&&"ProtoValue"===e._protoValueType}class r1{constructor(e,t,r,i,n=eg.min(),a=eg.min(),s=eM.EMPTY_BYTE_STRING,o=null){this.target=e,this.targetId=t,this.purpose=r,this.sequenceNumber=i,this.snapshotVersion=n,this.lastLimboFreeSnapshotVersion=a,this.resumeToken=s,this.expectedCount=o}withSequenceNumber(e){return new r1(this.target,this.targetId,this.purpose,e,this.snapshotVersion,this.lastLimboFreeSnapshotVersion,this.resumeToken,this.expectedCount)}withResumeToken(e,t){return new r1(this.target,this.targetId,this.purpose,this.sequenceNumber,t,this.lastLimboFreeSnapshotVersion,e,null)}withExpectedCount(e){return new r1(this.target,this.targetId,this.purpose,this.sequenceNumber,this.snapshotVersion,this.lastLimboFreeSnapshotVersion,this.resumeToken,e)}withLastLimboFreeSnapshotVersion(e){return new r1(this.target,this.targetId,this.purpose,this.sequenceNumber,this.snapshotVersion,e,this.resumeToken,this.expectedCount)}}class r2{constructor(e){this.yt=e}}class r3{Dt(e,t){this.Ct(e,t),t.vt()}Ct(e,t){if("nullValue"in e)this.Ft(t,5);else if("booleanValue"in e)this.Ft(t,10),t.Mt(+!!e.booleanValue);else if("integerValue"in e)this.Ft(t,15),t.Mt(eN(e.integerValue));else if("doubleValue"in e){let r=eN(e.doubleValue);isNaN(r)?this.Ft(t,13):(this.Ft(t,15),eT(r)?t.Mt(0):t.Mt(r))}else if("timestampValue"in e){let r=e.timestampValue;this.Ft(t,20),"string"==typeof r&&(r=eL(r)),t.xt(`${r.seconds||""}`),t.Mt(r.nanos||0)}else if("stringValue"in e)this.Ot(e.stringValue,t),this.Nt(t);else if("bytesValue"in e)this.Ft(t,30),t.Bt(eD(e.bytesValue)),this.Nt(t);else if("referenceValue"in e)this.Lt(e.referenceValue,t);else if("geoPointValue"in e){let r=e.geoPointValue;this.Ft(t,45),t.Mt(r.latitude||0),t.Mt(r.longitude||0)}else"mapValue"in e?tn(e)?this.Ft(t,Number.MAX_SAFE_INTEGER):tr(e)?this.kt(e.mapValue,t):(this.Kt(e.mapValue,t),this.Nt(t)):"arrayValue"in e?(this.qt(e.arrayValue,t),this.Nt(t)):P(19022,{Ut:e})}Ot(e,t){this.Ft(t,25),this.$t(e,t)}$t(e,t){t.xt(e)}Kt(e,t){let r=e.fields||{};for(let e of(this.Ft(t,55),Object.keys(r)))this.Ot(e,t),this.Ct(r[e],t)}kt(e,t){let r=e.fields||{};this.Ft(t,53);let i=r[eX].arrayValue?.values?.length||0;this.Ft(t,15),t.Mt(eN(i)),this.Ot(eX,t),this.Ct(r[eX],t)}qt(e,t){let r=e.values||[];for(let e of(this.Ft(t,50),r))this.Ct(e,t)}
vendor: 4,118 bytes, line 8
8Lt(e,t){this.Ft(t,37),en.fromName(e).path.forEach(e=>{this.Ft(t,60),this.$t(e,t)})}Ft(e,t){e.Mt(t)}Nt(e){e.Mt(2)}}r3.Wt=new r3;class r4{constructor(){this.Sn=new r5}addToCollectionParentIndex(e,t){return this.Sn.add(t),ew.resolve()}getCollectionParents(e,t){return ew.resolve(this.Sn.getEntries(t))}addFieldIndex(e,t){return ew.resolve()}deleteFieldIndex(e,t){return ew.resolve()}deleteAllFieldIndexes(e){return ew.resolve()}createTargetIndexes(e,t){return ew.resolve()}getDocumentsMatchingTarget(e,t){return ew.resolve(null)}getIndexType(e,t){return ew.resolve(0)}getFieldIndexes(e,t){return ew.resolve([])}getNextCollectionGroupToUpdate(e){return ew.resolve(null)}getMinOffset(e,t){return ew.resolve(ef.min())}getMinOffsetFromCollectionGroup(e,t){return ew.resolve(ef.min())}updateCollectionGroup(e,t,r){return ew.resolve()}updateIndexEntries(e,t){return ew.resolve()}}class r5{constructor(){this.index={}}add(e){let t=e.lastSegment(),r=e.popLast(),i=this.index[t]||new eR(et.comparator),n=!i.has(r);return this.index[t]=i.add(r),n}has(e){let t=e.lastSegment(),r=e.popLast(),i=this.index[t];return i&&i.has(r)}getEntries(e){return(this.index[e]||new eR(et.comparator)).toArray()}}new Uint8Array(0);let r9={didRun:!1,sequenceNumbersCollected:0,targetsRemoved:0,documentsRemoved:0};class r6{static withCacheSize(e){return new r6(e,r6.DEFAULT_COLLECTION_PERCENTILE,r6.DEFAULT_MAX_SEQUENCE_NUMBERS_TO_COLLECT)}constructor(e,t,r){this.cacheSizeCollectionThreshold=e,this.percentileToCollect=t,this.maximumSequenceNumbersToCollect=r}}r6.DEFAULT_COLLECTION_PERCENTILE=10,r6.DEFAULT_MAX_SEQUENCE_NUMBERS_TO_COLLECT=1e3,r6.DEFAULT=new r6(0x2800000,r6.DEFAULT_COLLECTION_PERCENTILE,r6.DEFAULT_MAX_SEQUENCE_NUMBERS_TO_COLLECT),r6.DISABLED=new r6(-1,0,0);class r8{constructor(e){this.sr=e}next(){return this.sr+=2,this.sr}static _r(){return new r8(0)}static ar(){return new r8(-1)}}let r7="LruGarbageCollector";function ie([e,t],[r,i]){let n=Y(e,r);return 0===n?Y(t,i):n}class it{constructor(e){this.Pr=e,this.buffer=new eR(ie),this.Tr=0}Ir(){return++this.Tr}Er(e){let t=[e,this.Ir()];if(this.buffer.size<this.Pr)this.buffer=this.buffer.add(t);else{let e=this.buffer.last();0>ie(t,e)&&(this.buffer=this.buffer.delete(e).add(t))}}get maxValue(){return this.buffer.last()[0]}}class ir{constructor(e,t,r){this.garbageCollector=e,this.asyncQueue=t,this.localStore=r,this.Rr=null}start(){-1!==this.garbageCollector.params.cacheSizeCollectionThreshold&&this.Ar(6e4)}stop(){this.Rr&&(this.Rr.cancel(),this.Rr=null)}get started(){return null!==this.Rr}Ar(e){I(r7,`Garbage collection scheduled in ${e}ms`),this.Rr=this.asyncQueue.enqueueAfterDelay("lru_garbage_collection",e,async()=>{this.Rr=null;try{await this.localStore.collectGarbage(this.garbageCollector)}catch(e){eb(e)?I(r7,"Ignoring IndexedDB error during garbage collection: ",e):await ev(e)}await this.Ar(3e5)})}}class ii{constructor(e,t){this.Vr=e,this.params=t}calculateTargetCount(e,t){return this.Vr.dr(e).next(e=>Math.floor(t/100*e))}nthSequenceNumber(e,t){if(0===t)return ew.resolve(eC.ce);let r=new it(t);return this.Vr.forEachTarget(e,e=>r.Er(e.sequenceNumber)).next(()=>this.Vr.mr(e,e=>r.Er(e))).next(()=>r.maxValue)}removeTargets(e,t,r){return this.Vr.removeTargets(e,t,r)}removeOrphanedDocuments(e,t){return this.Vr.removeOrphanedDocuments(e,t)}collect(e,t){return -1===this.params.cacheSizeCollectionThreshold?(I("LruGarbageCollector","Garbage collection skipped; disabled"),ew.resolve(r9)):this.getCacheSize(e).next(r=>r<this.params.cacheSizeCollectionThreshold?(I("LruGarbageCollector",`Garbage collection skipped; Cache size ${r} is lower than threshold ${this.params.cacheSizeCollectionThreshold}`),r9):this.gr(e,t))}getCacheSize(e){return this.Vr.getCacheSize(e)}gr(e,t){let r,i,n,a,s,o,l,u=Date.now();return this.calculateTargetCount(e,this.params.percentileToCollect).next(t=>(t>this.params.maximumSequenceNumbersToCollect?(I("LruGarbageCollector",`Capping sequence numbers to collect down to the maximum of ${this.params.maximumSequenceNumbersToCollect} from ${t}`),i=this.params.maximumSequenceNumbersToCollect):i=t,a=Date.now(),this.nthSequenceNumber(e,i
8))).next(i=>(r=i,s=Date.now(),this.removeTargets(e,r,t))).next(t=>(n=t,o=Date.now(),this.removeOrphanedDocuments(e,r))).next(e=>(l=Date.now(),R()<=T.$b.DEBUG&&I("LruGarbageCollector",`LRU Garbage Collection 9 Counted targets in ${a-u}ms 10 Determined least recently used ${i} in `+(s-a)+"ms\n"+` Removed ${n} targets in `+(o-s)+"ms\n"+` Removed ${e} documents in `+(l-o)+"ms\n"+`Total Duration: ${l-u}ms`),ew.resolve({didRun:!0,sequenceNumbersCollected:i,targetsRemoved:n,documentsRemoved:e})))}}class ia{constructor(){this.changes=new tj(e=>e.toString(),(e,t)=>e.isEqual(t)),this.changesApplied=!1}addEntry(e){this.assertNotApplied(),this.changes.set(e.key,e)}removeEntry(e,t){this.assertNotApplied(),this.changes.set(e,ts.newInvalidDocument(e).setReadTime(t))}getEntry(e,t){this.assertNotApplied();let r=this.changes.get(t);return void 0!==r?ew.resolve(r):this.getFromCache(e,t)}getEntries(e,t){return this.getAllFromCache(e,t)}apply(e){return this.assertNotApplied(),this.changesApplied=!0,this.applyChanges(e)}assertNotApplied(){}}class is{constructor(e,t){this.overlayedDocument=e,this.mutatedFields=t}}
10class io{constructor(e,t,r,i){this.remoteDocumentCache=e,this.mutationQueue=t,this.documentOverlayCache=r,this.indexManager=i}getDocument(e,t){let r=null;return this.documentOverlayCache.getOverlay(e,t).next(i=>(r=i,this.remoteDocumentCache.getEntry(e,t))).next(e=>(null!==r&&rs(r.mutation,e,ex.empty(),em.now()),e))}getDocuments(e,t){return this.remoteDocumentCache.getEntries(e,t).next(t=>this.getLocalViewOfDocuments(e,t,tJ()).next(()=>t))}getLocalViewOfDocuments(e,t,r=tJ()){let i=tW();return this.populateOverlays(e,i,t).next(()=>this.computeViews(e,t,i,r).next(e=>{let t=tH();return e.forEach((e,r)=>{t=t.insert(e,r.overlayedDocument)}),t}))}getOverlayedDocuments(e,t){let r=tW();return this.populateOverlays(e,r,t).next(()=>this.computeViews(e,t,r,tJ()))}populateOverlays(e,t,r){let i=[];return r.forEach(e=>{t.has(e)||i.push(e)}),this.documentOverlayCache.getOverlays(e,i).next(e=>{e.forEach((e,r)=>{t.set(e,r)})})}computeViews(e,t,r,i){let n=tG,a=tW(),s=tW();return t.forEach((e,t)=>{let s=r.get(t.key);i.has(t.key)&&(void 0===s||s.mutation instanceof ru)?n=n.insert(t.key,t):void 0!==s?(a.set(t.key,s.mutation.getFieldMask()),rs(s.mutation,t,s.mutation.getFieldMask(),em.now())):a.set(t.key,ex.empty())}),this.recalculateAndSaveOverlays(e,n).next(e=>(e.forEach((e,t)=>a.set(e,t)),t.forEach((e,t)=>s.set(e,new is(t,a.get(e)??null))),s))}recalculateAndSaveOverlays(e,t){let r=tW(),i=new eE((e,t)=>e-t),n=tJ();return this.mutationQueue.getAllMutationBatchesAffectingDocumentKeys(e,t).next(e=>{for(let n of e)n.keys().forEach(e=>{let a=t.get(e);if(null===a)return;let s=r.get(e)||ex.empty();s=n.applyToLocalView(a,s),r.set(e,s);let o=(i.get(n.batchId)||tJ()).add(e);i=i.insert(n.batchId,o)})}).next(()=>{let a=[],s=i.getReverseIterator();for(;s.hasNext();){let i=s.getNext(),o=i.key,l=i.value,u=tW();l.forEach(e=>{if(!n.has(e)){let i=ra(t.get(e),r.get(e));null!==i&&u.set(e,i),n=n.add(e)}}),a.push(this.documentOverlayCache.saveOverlays(e,o,u))}return ew.waitFor(a)}).next(()=>r)}recalculateAndSaveOverlaysForDocumentKeys(e,t){return this.remoteDocumentCache.getEntries(e,t).next(t=>this.recalculateAndSaveOverlays(e,t))}getDocumentsMatchingQuery(e,t,r,i){return en.isDocumentKey(t.path)&&null===t.collectionGroup&&0===t.filters.length?this.getDocumentsMatchingDocumentQuery(e,t.path):tO(t)?this.getDocumentsMatchingCollectionGroupQuery(e,t,r,i):this.getDocumentsMatchingCollectionQuery(e,t,r,i)}getNextDocuments(e,t,r,i){return this.remoteDocumentCache.getAllFromCollectionGroup(e,t,r,i).next(n=>{let a=i-n.size>0?this.documentOverlayCache.getOverlaysForCollectionGroup(e,t,r.largestBatchId,i-n.size):ew.resolve(tW()),s=-1,o=n;return a.next(t=>ew.forEach(t,(t,r)=>(s<r.largestBatchId&&(s=r.largestBatchId),n.get(t)?ew.resolve():this.remoteDocumentCache.getEntry(e,t).next(e=>{o=o.insert(t,e)}))).next(()=>this.populateOverlays(e,t,n)).next(()=>this.computeViews(e,o,t,tJ())).next(e=>({batchId:s,changes:tq(e)})))})}getDocumentsMatchingDocumentQuery(e,t){return this.getDocument(e,new en(t)).next(e=>{let t=tH();return e.isFoundDocument()&&(t=t.insert(e.key,e)),t})}getDocumentsMatchingCollectionGroupQuery(e,t,r,i){let n=t.collectionGroup,a=tH();return this.indexManager.getCollectionParents(e,n).next(s=>ew.forEach(s,s=>{let o=new tR(s.child(n),null,t.explicitOrderBy.slice(),t.filters.slice(),t.limit,t.limitType,t.startAt,t.endAt);return this.getDocumentsMatchingCollectionQuery(e,o,r,i).next(e=>{e.forEach((e,t)=>{a=a.insert(e,t)})})}).next(()=>a))}getDocumentsMatchingCollectionQuery(e,t,r,i){let n;return this.documentOverlayCache.getOverlaysForCollection(e,t.path,r.largestBatchId).next(a=>(n=a,this.remoteDocumentCache.getDocumentsMatchingQuery(e,t,r,n,i))).next(e=>{n.forEach((t,r)=>{let i=r.getKey();null===e.get(i)&&(e=e.insert(i,ts.newInvalidDocument(i)))});let r=tH();return e.forEach((e,i)=>{let a=n.get(e);void 0!==a&&rs(a.mutation,i,ex.empty(),em.now()),tB(t,i)&&(r=r.insert(e,i))}),r})}}class il{constructor(e){this.serializer=e,this.Nr=new Map,this.Br=new Map}getBundleMetadata(e,t){return ew.resolve(this.Nr.get(t))}saveBundleMetadata(e,t){return this.Nr.set(t.id,{id:t.id,version:t.version,createTime:rV(t.createTime)}),ew.resolve()}getNamedQuery(e,t){return ew.resolve(this.Br.get(t))}saveNamedQuery(e,t){var r;let i;return this.Br.set(t.name,{name:t.name,query:(i=function(e){var t,r,i,n;let a,s,o,l,u,c=4===(a=rK(e.parent)).length?et.emptyPath():rY(a),h=e.structuredQuery,d=h.from?h.from.length:0,m=null;if(d>0){N(1===d,65062);let e=h.from[0];e.allDescendants?m=e.collectionId:c=c.child(e.collectionId)}let g=[];h.where&&(g=(s=function e(t){return void 0!==t.unaryFilter?function(e){switch(e.unaryFilter.op){case"IS_NAN":let t=rX(e.unaryFilter.field);return td.create(t,"==",{doubleValue:NaN});case"IS_NULL":let r=rX(e.unaryFilter.field);return td.create(r,"==",{nullValue:"NULL_VALUE"});
10case"IS_NOT_NAN":let i=rX(e.unaryFilter.field);return td.create(i,"!=",{doubleValue:NaN});case"IS_NOT_NULL":let n=rX(e.unaryFilter.field);return td.create(n,"!=",{nullValue:"NULL_VALUE"});case"OPERATOR_UNSPECIFIED":return P(61313);default:return P(60726)}}(t):void 0!==t.fieldFilter?td.create(rX(t.fieldFilter.field),function(e){switch(e){case"EQUAL":return"==";case"NOT_EQUAL":return"!=";case"GREATER_THAN":return">";case"GREATER_THAN_OR_EQUAL":return">=";case"LESS_THAN":return"<";case"LESS_THAN_OR_EQUAL":return"<=";case"ARRAY_CONTAINS":return"array-contains";case"IN":return"in";case"NOT_IN":return"not-in";case"ARRAY_CONTAINS_ANY":return"array-contains-any";case"OPERATOR_UNSPECIFIED":return P(58110);default:return P(50506)}}(t.fieldFilter.op),t.fieldFilter.value):void 0!==t.compositeFilter?tm.create(t.compositeFilter.filters.map(t=>e(t)),function(e){switch(e){case"AND":return"and";case"OR":return"or";default:return P(1026)}}(t.compositeFilter.op)):P(30097,{filter:t})}(h.where))instanceof tm&&tp(t=s)&&tg(t)?s.getFilters():[s]);let p=[];h.orderBy&&(p=h.orderBy.map(e=>new tc(rX(e.field),function(e){switch(e){case"ASCENDING":return"asc";case"DESCENDING":return"desc";default:return}}(e.direction))));let f=null;h.limit&&(f=null==(o="object"==typeof(r=h.limit)?r.value:r)?null:o);let y=null;h.startAt&&(l=!!(i=h.startAt).before,y=new to(i.values||[],l));let v=null;return h.endAt&&(u=!(n=h.endAt).before,v=new to(n.values||[],u)),new tR(c,m,p,g,f,"F",y,v)}({parent:(r=t.bundledQuery).parent,structuredQuery:r.structuredQuery}),"LAST"===r.limitType?tN(i,i.limit,"L"):i),readTime:rV(t.readTime)}),ew.resolve()}}class iu{constructor(){this.overlays=new eE(en.comparator),this.Lr=new Map}getOverlay(e,t){return ew.resolve(this.overlays.get(t))}getOverlays(e,t){let r=tW();return ew.forEach(t,t=>this.getOverlay(e,t).next(e=>{null!==e&&r.set(t,e)})).next(()=>r)}saveOverlays(e,t,r){return r.forEach((r,i)=>{this.bt(e,t,i)}),ew.resolve()}removeOverlaysForBatchId(e,t,r){let i=this.Lr.get(r);return void 0!==i&&(i.forEach(e=>this.overlays=this.overlays.remove(e)),this.Lr.delete(r)),ew.resolve()}getOverlaysForCollection(e,t,r){let i=tW(),n=t.length+1,a=new en(t.child("")),s=this.overlays.getIteratorFrom(a);for(;s.hasNext();){let e=s.getNext().value,a=e.getKey();if(!t.isPrefixOf(a.path))break;a.path.length===n&&e.largestBatchId>r&&i.set(e.getKey(),e)}return ew.resolve(i)}getOverlaysForCollectionGroup(e,t,r,i){let n=new eE((e,t)=>e-t),a=this.overlays.getIterator();for(;a.hasNext();){let e=a.getNext().value;if(e.getKey().getCollectionGroup()===t&&e.largestBatchId>r){let t=n.get(e.largestBatchId);null===t&&(t=tW(),n=n.insert(e.largestBatchId,t)),t.set(e.getKey(),e)}}let s=tW(),o=n.getIterator();for(;o.hasNext()&&(o.getNext().value.forEach((e,t)=>s.set(e,t)),!(s.size()>=i)););return ew.resolve(s)}bt(e,t,r){let i=this.overlays.get(r.key);if(null!==i){let e=this.Lr.get(i.largestBatchId).delete(r.key);this.Lr.set(i.largestBatchId,e)}this.overlays=this.overlays.insert(r.key,new ry(t,r));let n=this.Lr.get(t);void 0===n&&(n=tJ(),this.Lr.set(t,n)),this.Lr.set(t,n.add(r.key))}}class ic{constructor(){this.sessionToken=eM.EMPTY_BYTE_STRING}getSessionToken(e){return ew.resolve(this.sessionToken)}setSessionToken(e,t){return this.sessionToken=t,ew.resolve()}}class ih{constructor(){this.kr=new eR(id.Kr),this.qr=new eR(id.Ur)}isEmpty(){return this.kr.isEmpty()}addReference(e,t){let r=new id(e,t);this.kr=this.kr.add(r),this.qr=this.qr.add(r)}$r(e,t){e.forEach(e=>this.addReference(e,t))}removeReference(e,t){this.Wr(new id(e,t))}Qr(e,t){e.forEach(e=>this.removeReference(e,t))}Gr(e){let t=new en(new et([])),r=new id(t,e),i=new id(t,e+1),n=[];return this.qr.forEachInRange([r,i],e=>{this.Wr(e),n.push(e.key)}),n}zr(){this.kr.forEach(e=>this.Wr(e))}Wr(e){this.kr=this.kr.delete(e),this.qr=this.qr.delete(e)}jr(e){let t=new en(new et([])),r=new id(t,e),i=new id(t,e+1),n=tJ();return this.qr.forEachInRange([r,i],e=>{n=n.add(e.key)}),n}containsKey(e){let t=new id(e,0),r=this.kr.firstAfterOrEqual(t);return null!==r&&e.isEqual(r.key)}}class id{constructor(e,t){this.key=e,this.Hr=t}
10static Kr(e,t){return en.comparator(e.key,t.key)||Y(e.Hr,t.Hr)}static Ur(e,t){return Y(e.Hr,t.Hr)||en.comparator(e.key,t.key)}}class im{constructor(e,t){this.indexManager=e,this.referenceDelegate=t,this.mutationQueue=[],this.Yn=1,this.Jr=new eR(id.Kr)}checkEmpty(e){return ew.resolve(0===this.mutationQueue.length)}addMutationBatch(e,t,r,i){let n=this.Yn;this.Yn++,this.mutationQueue.length>0&&this.mutationQueue[this.mutationQueue.length-1];let a=new rp(n,t,r,i);for(let t of(this.mutationQueue.push(a),i))this.Jr=this.Jr.add(new id(t.key,n)),this.indexManager.addToCollectionParentIndex(e,t.key.path.popLast());return ew.resolve(a)}lookupMutationBatch(e,t){return ew.resolve(this.Zr(t))}getNextMutationBatchAfterBatchId(e,t){let r=this.Xr(t+1),i=r<0?0:r;return ew.resolve(this.mutationQueue.length>i?this.mutationQueue[i]:null)}getHighestUnacknowledgedBatchId(){return ew.resolve(0===this.mutationQueue.length?-1:this.Yn-1)}getAllMutationBatches(e){return ew.resolve(this.mutationQueue.slice())}getAllMutationBatchesAffectingDocumentKey(e,t){let r=new id(t,0),i=new id(t,1/0),n=[];return this.Jr.forEachInRange([r,i],e=>{let t=this.Zr(e.Hr);n.push(t)}),ew.resolve(n)}getAllMutationBatchesAffectingDocumentKeys(e,t){let r=new eR(Y);return t.forEach(e=>{let t=new id(e,0),i=new id(e,1/0);this.Jr.forEachInRange([t,i],e=>{r=r.add(e.Hr)})}),ew.resolve(this.Yr(r))}getAllMutationBatchesAffectingQuery(e,t){let r=t.path,i=r.length+1,n=r;en.isDocumentKey(n)||(n=n.child(""));let a=new id(new en(n),0),s=new eR(Y);return this.Jr.forEachWhile(e=>{let t=e.key.path;return!!r.isPrefixOf(t)&&(t.length===i&&(s=s.add(e.Hr)),!0)},a),ew.resolve(this.Yr(s))}Yr(e){let t=[];return e.forEach(e=>{let r=this.Zr(e);null!==r&&t.push(r)}),t}removeMutationBatch(e,t){N(0===this.ei(t.batchId,"removed"),55003),this.mutationQueue.shift();let r=this.Jr;return ew.forEach(t.mutations,i=>{let n=new id(i.key,t.batchId);return r=r.delete(n),this.referenceDelegate.markPotentiallyOrphaned(e,i.key)}).next(()=>{this.Jr=r})}nr(e){}containsKey(e,t){let r=new id(t,0),i=this.Jr.firstAfterOrEqual(r);return ew.resolve(t.isEqual(i&&i.key))}performConsistencyCheck(e){return this.mutationQueue.length,ew.resolve()}ei(e,t){return this.Xr(e)}Xr(e){return 0===this.mutationQueue.length?0:e-this.mutationQueue[0].batchId}Zr(e){let t=this.Xr(e);return t<0||t>=this.mutationQueue.length?null:this.mutationQueue[t]}}class ig{constructor(e){this.ti=e,this.docs=new eE(en.comparator),this.size=0}setIndexManager(e){this.indexManager=e}addEntry(e,t){let r=t.key,i=this.docs.get(r),n=i?i.size:0,a=this.ti(t);return this.docs=this.docs.insert(r,{document:t.mutableCopy(),size:a}),this.size+=a-n,this.indexManager.addToCollectionParentIndex(e,r.path.popLast())}removeEntry(e){let t=this.docs.get(e);t&&(this.docs=this.docs.remove(e),this.size-=t.size)}getEntry(e,t){let r=this.docs.get(t);return ew.resolve(r?r.document.mutableCopy():ts.newInvalidDocument(t))}getEntries(e,t){let r=tG;return t.forEach(e=>{let t=this.docs.get(e);r=r.insert(e,t?t.document.mutableCopy():ts.newInvalidDocument(e))}),ew.resolve(r)}getDocumentsMatchingQuery(e,t,r,i){let n=tG,a=t.path,s=new en(a.child("__id-9223372036854775808__")),o=this.docs.getIteratorFrom(s);for(;o.hasNext();){let{key:e,value:{document:s}}=o.getNext();if(!a.isPrefixOf(e.path))break;e.path.length>a.length+1||0>=function(e,t){let r=e.readTime.compareTo(t.readTime);return 0!==r||0!==(r=en.comparator(e.documentKey,t.documentKey))?r:Y(e.largestBatchId,t.largestBatchId)}(new ef(s.readTime,s.key,-1),r)||(i.has(s.key)||tB(t,s))&&(n=n.insert(s.key,s.mutableCopy()))}return ew.resolve(n)}getAllFromCollectionGroup(e,t,r,i){P(9500)}ni(e,t){return ew.forEach(this.docs,e=>t(e))}newChangeBuffer(e){return new ip(this)}getSize(e){return ew.resolve(this.size)}}class ip extends ia{constructor(e){super(),this.Mr=e}applyChanges(e){let t=[];
vendor: 6,500 bytes, line 10
10return this.changes.forEach((r,i)=>{i.isValidDocument()?t.push(this.Mr.addEntry(e,i)):this.Mr.removeEntry(r)}),ew.waitFor(t)}getFromCache(e,t){return this.Mr.getEntry(e,t)}getAllFromCache(e,t){return this.Mr.getEntries(e,t)}}class iy{constructor(e){this.persistence=e,this.ri=new tj(e=>tE(e),tA),this.lastRemoteSnapshotVersion=eg.min(),this.highestTargetId=0,this.ii=0,this.si=new ih,this.targetCount=0,this.oi=r8._r()}forEachTarget(e,t){return this.ri.forEach((e,r)=>t(r)),ew.resolve()}getLastRemoteSnapshotVersion(e){return ew.resolve(this.lastRemoteSnapshotVersion)}getHighestSequenceNumber(e){return ew.resolve(this.ii)}allocateTargetId(e){return this.highestTargetId=this.oi.next(),ew.resolve(this.highestTargetId)}setTargetsMetadata(e,t,r){return r&&(this.lastRemoteSnapshotVersion=r),t>this.ii&&(this.ii=t),ew.resolve()}lr(e){this.ri.set(e.target,e);let t=e.targetId;t>this.highestTargetId&&(this.oi=new r8(t),this.highestTargetId=t),e.sequenceNumber>this.ii&&(this.ii=e.sequenceNumber)}addTargetData(e,t){return this.lr(t),this.targetCount+=1,ew.resolve()}updateTargetData(e,t){return this.lr(t),ew.resolve()}removeTargetData(e,t){return this.ri.delete(t.target),this.si.Gr(t.targetId),this.targetCount-=1,ew.resolve()}removeTargets(e,t,r){let i=0,n=[];return this.ri.forEach((a,s)=>{s.sequenceNumber<=t&&null===r.get(s.targetId)&&(this.ri.delete(a),n.push(this.removeMatchingKeysForTargetId(e,s.targetId)),i++)}),ew.waitFor(n).next(()=>i)}getTargetCount(e){return ew.resolve(this.targetCount)}getTargetData(e,t){let r=this.ri.get(t)||null;return ew.resolve(r)}addMatchingKeys(e,t,r){return this.si.$r(t,r),ew.resolve()}removeMatchingKeys(e,t,r){this.si.Qr(t,r);let i=this.persistence.referenceDelegate,n=[];return i&&t.forEach(t=>{n.push(i.markPotentiallyOrphaned(e,t))}),ew.waitFor(n)}removeMatchingKeysForTargetId(e,t){return this.si.Gr(t),ew.resolve()}getMatchingKeysForTargetId(e,t){let r=this.si.jr(t);return ew.resolve(r)}containsKey(e,t){return ew.resolve(this.si.containsKey(t))}}class iv{constructor(e,t){this._i={},this.overlays={},this.ai=new eC(0),this.ui=!1,this.ui=!0,this.ci=new ic,this.referenceDelegate=e(this),this.li=new iy(this),this.indexManager=new r4,this.remoteDocumentCache=function(e){return new ig(e)}(e=>this.referenceDelegate.hi(e)),this.serializer=new r2(t),this.Pi=new il(this.serializer)}start(){return Promise.resolve()}shutdown(){return this.ui=!1,Promise.resolve()}get started(){return this.ui}setDatabaseDeletedListener(){}setNetworkEnabled(){}getIndexManager(e){return this.indexManager}getDocumentOverlayCache(e){let t=this.overlays[e.toKey()];return t||(t=new iu,this.overlays[e.toKey()]=t),t}getMutationQueue(e,t){let r=this._i[e.toKey()];return r||(r=new im(t,this.referenceDelegate),this._i[e.toKey()]=r),r}getGlobalsCache(){return this.ci}getTargetCache(){return this.li}getRemoteDocumentCache(){return this.remoteDocumentCache}getBundleCache(){return this.Pi}runTransaction(e,t,r){I("MemoryPersistence","Starting transaction:",e);let i=new iw(this.ai.next());return this.referenceDelegate.Ti(),r(i).next(e=>this.referenceDelegate.Ii(i).next(()=>e)).toPromise().then(e=>(i.raiseOnCommittedEvent(),e))}Ei(e,t){return ew.or(Object.values(this._i).map(r=>()=>r.containsKey(e,t)))}}class iw extends ey{constructor(e){super(),this.currentSequenceNumber=e}}class ib{constructor(e){this.persistence=e,this.Ri=new ih,this.Ai=null}static Vi(e){return new ib(e)}get di(){if(this.Ai)return this.Ai;throw P(60996)}addReference(e,t,r){return this.Ri.addReference(r,t),this.di.delete(r.toString()),ew.resolve()}removeReference(e,t,r){return this.Ri.removeReference(r,t),this.di.add(r.toString()),ew.resolve()}markPotentiallyOrphaned(e,t){return this.di.add(t.toString()),ew.resolve()}removeTarget(e,t){this.Ri.Gr(t.targetId).forEach(e=>this.di.add(e.toString()));let r=this.persistence.getTargetCache();return r.getMatchingKeysForTargetId(e,t.targetId).next(e=>{e.forEach(e=>this.di.add(e.toString()))}).next(()=>r.removeTargetData(e,t))}Ti(){this.Ai=new Set}Ii(e){let t=this.persistence.getRemoteDocumentCache().newChangeBuffer();return ew.forEach(this.di,r=>{let i=en.fromPath(r);return this.mi(e,i).next(e=>{e||t.removeEntry(i,eg.min())})}).next(()=>(this.Ai=null,t.apply(e)))}updateLimboDocument(e,t){return this.mi(e,t).next(e=>{e?this.di.delete(t.toString()):this.di.add(t.toString())})}hi(e){return 0}mi(e,t){return ew.or([()=>ew.resolve(this.Ri.containsKey(t)),()=>this.persistence.getTargetCache().containsKey(e,t),()=>this.persistence.Ei(e,t)])}}class iC{constructor(e,t){this.persistence=e,this.fi=new tj(e=>(function(e){let t="";for(let r=0;r<e.length;r++)t.length>0&&(t+="\x01\x01"),t=function(e,t){let r=t,i=e.length;for(let t=0;t<i;t++){let i=e.charAt(t);switch(i){case"\0":r+="\x01\x10";break;case"\x01":r+="\x01\x11";break;default:r+=i}}return r}(e.get(r),t);return t+"\x01\x01"})(e.path),(e,t)=>e.isEqual(t)),this.garbageCollector=function(e,t){return new ii(e,t)}(this,t)}static Vi(e,t){return new iC(e,t)}Ti(){}Ii(e){return ew.resolve()}forEachTarget(e,t){return this.persistence.getTargetCache().forEachTarget(e,t)}dr(e){let t=this.pr(e);return this.persistence.getTargetCache().getTargetCount(e).next(e=>t.next(t=>e+t))}pr(e){let t=0;return this.mr(e,e=>{t++}).next(()=>t)}mr(e,t){return ew.forEach(this.fi,(r,i)=>this.wr(e,r,i).next(e=>e?ew.resolve():t(i)))}removeTargets(e,t,r){return this.persistence.getTargetCache().removeTargets(e,t,r)}removeOrphanedDocuments(e,t){let r=0,i=this.persistence.getRemoteDocumentCache(),n=i.newChangeBuffer();return i.ni(e,i=>this.wr(e,i,t).next(e=>{e||(r++,n.removeEntry(i,eg.min()))})).next(()=>n.apply(e)).next(()=>r)}markPotentiallyOrphaned(e,t){return this.fi.set(t,e.currentSequenceNumber),ew.resolve()}removeTarget(e,t){let r=t.withSequenceNumber(e.currentSequenceNumber);return this.persistence.getTargetCache().updateTargetData(e,r)}addReference(e,t,r){return this.fi.set(r,e.currentSequenceNumber),ew.resolve()}removeReference(e,t,r){return this.fi.set(r,e.currentSequenceNumber),ew.resolve()}updateLimboDocument(e,t){return this.fi.set(t,e.currentSequenceNumber),ew.resolve()}hi(e){let t=e.key.toString().length;return e.isFoundDocument()&&(t+=function e(t){switch(eZ(t)){case 0:case 1:return 4;case 2:return 8;case 3:case 8:return 16;case 4:let r=eG(t);return r?16+e(r):16;case 5:return 2*t.stringValue.length;case 6:return eD(t.bytesValue).approximateByteSize();case 7:return t.referenceValue.length;case 9:return(t.arrayValue.values||[]).reduce((t,r)=>t+e(r),0);case 10:case 11:var i;let n;
10return i=t.mapValue,n=0,eF(i.fields,(t,r)=>{n+=t.length+e(r)}),n;default:throw P(13486,{value:t})}}(e.data.value)),t}wr(e,t,r){return ew.or([()=>this.persistence.Ei(e,t),()=>this.persistence.getTargetCache().containsKey(e,t),()=>{let e=this.fi.get(t);return ew.resolve(void 0!==e&&e>r)}])}getCacheSize(e){return this.persistence.getRemoteDocumentCache().getSize(e)}}class iT{constructor(e,t,r,i){this.targetId=e,this.fromCache=t,this.Ts=r,this.Is=i}static Es(e,t){let r=tJ(),i=tJ();for(let e of t.docChanges)switch(e.type){case 0:r=r.add(e.doc.key);break;case 1:i=i.add(e.doc.key)}return new iT(e,t.fromCache,r,i)}}class iS{constructor(){this._documentReadCount=0}get documentReadCount(){return this._documentReadCount}incrementDocumentReadCount(e){this._documentReadCount+=e}}class iF{constructor(){this.Rs=!1,this.As=!1,this.Vs=100,this.ds=function(){let e;return(0,w.nr)()?8:Number((e=(0,w.ZQ)().match(/Android ([\d.]+)/i))?e[1].split(".").slice(0,2).join("."):"-1")>0?6:4}()}initialize(e,t){this.fs=e,this.indexManager=t,this.Rs=!0}getDocumentsMatchingQuery(e,t,r,i){let n={result:null};return this.gs(e,t).next(e=>{n.result=e}).next(()=>{if(!n.result)return this.ps(e,t,i,r).next(e=>{n.result=e})}).next(()=>{if(n.result)return;let r=new iS;return this.ys(e,t,r).next(i=>{if(n.result=i,this.As)return this.ws(e,t,r,i.size)})}).next(()=>n.result)}ws(e,t,r,i){return r.documentReadCount<this.Vs?(R()<=T.$b.DEBUG&&I("QueryEngine","SDK will not create cache indexes for query:",tU(t),"since it only creates cache indexes for collection contains","more than or equal to",this.Vs,"documents"),ew.resolve()):(R()<=T.$b.DEBUG&&I("QueryEngine","Query:",tU(t),"scans",r.documentReadCount,"local documents and returns",i,"documents as results."),r.documentReadCount>this.ds*i?(R()<=T.$b.DEBUG&&I("QueryEngine","The SDK decides to create cache indexes for query:",tU(t),"as using cache indexes may help improve performance."),this.indexManager.createTargetIndexes(e,tP(t))):ew.resolve())}gs(e,t){if(tx(t))return ew.resolve(null);let r=tP(t);return this.indexManager.getIndexType(e,r).next(i=>0===i?null:(null!==t.limit&&1===i&&(r=tP(t=tN(t,null,"F"))),this.indexManager.getDocumentsMatchingTarget(e,r).next(i=>{let n=tJ(...i);return this.fs.getDocuments(e,n).next(i=>this.indexManager.getMinOffset(e,r).next(r=>{let a=this.bs(t,i);return this.Ss(t,a,n,r.readTime)?this.gs(e,tN(t,null,"F")):this.Ds(e,a,t,r)}))})))}ps(e,t,r,i){return tx(t)||i.isEqual(eg.min())?ew.resolve(null):this.fs.getDocuments(e,r).next(n=>{let a,s,o=this.bs(t,n);return this.Ss(t,o,r,i)?ew.resolve(null):(R()<=T.$b.DEBUG&&I("QueryEngine","Re-using previous result from %s to execute query: %s",i.toString(),tU(t)),this.Ds(e,o,t,(a=i.toTimestamp().seconds,s=i.toTimestamp().nanoseconds+1,new ef(eg.fromTimestamp(1e9===s?new em(a+1,0):new em(a,s)),en.empty(),-1))).next(e=>e))})}bs(e,t){let r=new eR(tV(e));return t.forEach((t,i)=>{tB(e,i)&&(r=r.add(i))}),r}Ss(e,t,r,i){if(null===e.limit)return!1;if(r.size!==t.size)return!0;let n="F"===e.limitType?t.last():t.first();return!!n&&(n.hasPendingWrites||n.version.compareTo(i)>0)}ys(e,t,r){return R()<=T.$b.DEBUG&&I("QueryEngine","Using full collection scan to execute query:",tU(t)),this.fs.getDocumentsMatchingQuery(e,t,ef.min(),r)}Ds(e,t,r,i){return this.fs.getDocumentsMatchingQuery(e,r,i).next(e=>(t.forEach(t=>{e=e.insert(t.key,t)}),e))}}let ik="LocalStore";
10class iE{constructor(e,t,r,i){this.persistence=e,this.Cs=t,this.serializer=i,this.vs=new eE(Y),this.Fs=new tj(e=>tE(e),tA),this.Ms=new Map,this.xs=e.getRemoteDocumentCache(),this.li=e.getTargetCache(),this.Pi=e.getBundleCache(),this.Os(r)}Os(e){this.documentOverlayCache=this.persistence.getDocumentOverlayCache(e),this.indexManager=this.persistence.getIndexManager(e),this.mutationQueue=this.persistence.getMutationQueue(e,this.indexManager),this.localDocuments=new io(this.xs,this.mutationQueue,this.documentOverlayCache,this.indexManager),this.xs.setIndexManager(this.indexManager),this.Cs.initialize(this.localDocuments,this.indexManager)}collectGarbage(e){return this.persistence.runTransaction("Collect garbage","readwrite-primary",t=>e.collect(t,this.vs))}}async function iA(e,t){return await e.persistence.runTransaction("Handle user change","readonly",r=>{let i;return e.mutationQueue.getAllMutationBatches(r).next(n=>(i=n,e.Os(t),e.mutationQueue.getAllMutationBatches(r))).next(t=>{let n=[],a=[],s=tJ();for(let e of i)for(let t of(n.push(e.batchId),e.mutations))s=s.add(t.key);for(let e of t)for(let t of(a.push(e.batchId),e.mutations))s=s.add(t.key);return e.localDocuments.getDocuments(r,s).next(e=>({Ns:e,removedBatchIds:n,addedBatchIds:a}))})})}function i_(e){return e.persistence.runTransaction("Get last remote snapshot version","readonly",t=>e.li.getLastRemoteSnapshotVersion(t))}async function iR(e,t,r){let i=e.vs.get(t);try{r||await e.persistence.runTransaction("Release target",r?"readwrite":"readwrite-primary",t=>e.persistence.referenceDelegate.removeTarget(t,i))}catch(e){if(!eb(e))throw e;I(ik,`Failed to update sequence numbers for target ${t}: ${e}`)}e.vs=e.vs.remove(t),e.Fs.delete(i.target)}function iI(e,t,r){let i=eg.min(),n=tJ();return e.persistence.runTransaction("Execute query","readwrite",a=>{var s;let o;return(s=tP(t),void 0!==(o=e.Fs.get(s))?ew.resolve(e.vs.get(o)):e.li.getTargetData(a,s)).next(t=>{if(t)return i=t.lastLimboFreeSnapshotVersion,e.li.getMatchingKeysForTargetId(a,t.targetId).next(e=>{n=e})}).next(()=>e.Cs.getDocumentsMatchingQuery(a,t,r?i:eg.min(),r?n:tJ())).next(r=>{var i,a,s;let o;return i=e,a=t.collectionGroup||(t.path.length%2==1?t.path.lastSegment():t.path.get(t.path.length-2)),s=r,o=i.Ms.get(a)||eg.min(),s.forEach((e,t)=>{t.readTime.compareTo(o)>0&&(o=t.readTime)}),i.Ms.set(a,o),{documents:r,ks:n}})})}class ix{constructor(){this.activeTargetIds=tQ}Qs(e){this.activeTargetIds=this.activeTargetIds.add(e)}Gs(e){this.activeTargetIds=this.activeTargetIds.delete(e)}Ws(){return JSON.stringify({activeTargetIds:this.activeTargetIds.toArray(),updateTimeMs:Date.now()})}}class iO{constructor(){this.vo=new ix,this.Fo={},this.onlineStateHandler=null,this.sequenceNumberHandler=null}addPendingMutation(e){}updateMutationState(e,t,r){}addLocalQueryTarget(e,t=!0){return t&&this.vo.Qs(e),this.Fo[e]||"not-current"}updateQueryState(e,t,r){this.Fo[e]=t}removeLocalQueryTarget(e){this.vo.Gs(e)}isLocalQueryTarget(e){return this.vo.activeTargetIds.has(e)}clearQueryState(e){delete this.Fo[e]}getAllActiveQueryTargets(){return this.vo.activeTargetIds}isActiveQueryTarget(e){return this.vo.activeTargetIds.has(e)}start(){return this.vo=new ix,Promise.resolve()}handleUserChange(e,t,r){}setOnlineState(e){}shutdown(){}writeSequenceNumber(e){}notifyBundleLoaded(e){}}class iM{Mo(e){}shutdown(){}}let iP="ConnectivityMonitor";class iL{constructor(){this.xo=()=>this.Oo(),this.No=()=>this.Bo(),this.Lo=[],this.ko()}Mo(e){this.Lo.push(e)}shutdown(){window.removeEventListener("online",this.xo),window.removeEventListener("offline",this.No)}ko(){window.addEventListener("online",this.xo),window.addEventListener("offline",this.No)}Oo(){for(let e of(I(iP,"Network connectivity changed: AVAILABLE"),this.Lo))e(0)}Bo(){for(let e of(I(iP,"Network connectivity changed: UNAVAILABLE"),this.Lo))e(1)}static v(){return"u">typeof window&&void 0!==window.addEventListener&&void 0!==window.removeEventListener}}let iN=null;function iD(){return null===iN?iN=0x10000000+Math.round(0x80000000*Math.random()):iN++,"0x"+iN.toString(16)}let iz="RestConnection",iU={BatchGetDocuments:"batchGet",Commit:"commit",RunQuery:"runQuery",RunAggregation
10Query:"runAggregationQuery",ExecutePipeline:"executePipeline"};class iB{get Ko(){return!1}constructor(e){this.databaseInfo=e,this.databaseId=e.databaseId;const t=e.ssl?"https":"http",r=encodeURIComponent(this.databaseId.projectId),i=encodeURIComponent(this.databaseId.database);this.qo=t+"://"+e.host,this.Uo=`projects/${r}/databases/${i}`,this.$o=this.databaseId.database===eq?`project_id=${r}`:`project_id=${r}&database_id=${i}`}Wo(e,t,r,i,n){let a=iD(),s=this.Qo(e,t.toUriEncodedString());I(iz,`Sending RPC '${e}' ${a}:`,s,r);let o={"google-cloud-resource-prefix":this.Uo,"x-goog-request-params":this.$o};this.Go(o,i,n);let{host:l}=new URL(s),u=(0,w.zJ)(l);return this.zo(e,s,o,r,u).then(t=>(I(iz,`Received RPC '${e}' ${a}: `,t),t),t=>{throw O(iz,`RPC '${e}' ${a} failed with error: `,t,"url: ",s,"request:",r),t})}jo(e,t,r,i,n,a){return this.Wo(e,t,r,i,n)}Go(e,t,r){e["X-Goog-Api-Client"]="gl-js/ fire/"+A,e["Content-Type"]="text/plain",this.databaseInfo.appId&&(e["X-Firebase-GMPID"]=this.databaseInfo.appId),t&&t.headers.forEach((t,r)=>e[r]=t),r&&r.headers.forEach((t,r)=>e[r]=t)}Qo(e,t){let r=iU[e],i=`${this.qo}/v1/${t}:${r}`;return this.databaseInfo.apiKey&&(i=`${i}?key=${encodeURIComponent(this.databaseInfo.apiKey)}`),i}terminate(){}}class iV{constructor(e){this.Ho=e.Ho,this.Jo=e.Jo}Zo(e){this.Xo=e}Yo(e){this.e_=e}t_(e){this.n_=e}onMessage(e){this.r_=e}close(){this.Jo()}send(e){this.Ho(e)}i_(){this.Xo()}s_(){this.e_()}o_(e){this.n_(e)}__(e){this.r_(e)}}let ij="WebChannelConnection",iG=(e,t,r)=>{e.listen(t,e=>{try{r(e)}catch(e){setTimeout(()=>{throw e},0)}})};class iK extends iB{constructor(e){super(e),this.a_=[],this.forceLongPolling=e.forceLongPolling,this.autoDetectLongPolling=e.autoDetectLongPolling,this.useFetchStreams=e.useFetchStreams,this.longPollingOptions=e.longPollingOptions}static u_(){iK.c_||(iG(h(),c.STAT_EVENT,e=>{e.stat===u.PROXY?I(ij,"STAT_EVENT: detected buffering proxy"):e.stat===u.NOPROXY&&I(ij,"STAT_EVENT: detected no buffering proxy")}),iK.c_=!0)}zo(e,t,r,i,n){let s=iD();return new Promise((n,u)=>{let c=new a;c.setWithCredentials(!0),c.listenOnce(o.COMPLETE,()=>{try{switch(c.getLastErrorCode()){case l.NO_ERROR:let t=c.getResponseJson();I(ij,`XHR for RPC '${e}' ${s} received:`,JSON.stringify(t)),n(t);break;case l.TIMEOUT:I(ij,`RPC '${e}' ${s} timed out`),u(new z(D.DEADLINE_EXCEEDED,"Request time out"));break;case l.HTTP_ERROR:let r=c.getStatus();if(I(ij,`RPC '${e}' ${s} failed with status:`,r,"response text:",c.getResponseText()),r>0){let e=c.getResponseJson();Array.isArray(e)&&(e=e[0]);let t=e?.error;if(t&&t.status&&t.message){let e,r=(e=t.status.toLowerCase().replace(/_/g,"-"),Object.values(D).indexOf(e)>=0?e:D.UNKNOWN);u(new z(r,t.message))}else u(new z(D.UNKNOWN,"Server responded with status "+c.getStatus()))}else u(new z(D.UNAVAILABLE,"Connection failed."));break;default:P(9055,{l_:e,streamId:s,h_:c.getLastErrorCode(),P_:c.getLastError()})}}finally{I(ij,`RPC '${e}' ${s} completed.`)}});let h=JSON.stringify(i);I(ij,`RPC '${e}' ${s} sending request:`,i),c.send(t,"POST",h,r,15)})}T_(e,t,r){let i=iD(),n=[this.qo,"/","google.firestore.v1.Firestore","/",e,"/channel"],a=this.createWebChannelTransport(),o={httpSessionIdParam:"gsessionid",initMessageHeaders:{},messageUrlParams:{database:`projects/${this.databaseId.projectId}/databases/${this.databaseId.database}`},sendRawJson:!0,supportsCrossDomainXhr:!0,internalChannelParams:{forwardChannelRequestTimeoutMs:6e5},forceLongPolling:this.forceLongPolling,detectBufferingProxy:this.autoDetectLongPolling},l=this.longPollingOptions.timeoutSeconds;void 0!==l&&(o.longPollingTimeout=Math.round(1e3*l)),this.useFetchStreams&&(o.useFetchStreams=!0),this.Go(o.initMessageHeaders,t,r),o.encodeInitMessageHeaders=!0;let u=n.join("");I(ij,`Creating RPC '${e}' stream ${i}: ${u}`,o);let c=a.createWebChannel(u,o);this.I_(c);let h=!1,d=!1,g=new iV({Ho:t=>{d?I(ij,`Not sending because RPC '${e}' stream ${i} is closed:`,t):(h||(I(ij,`Opening RPC '${e}' stream ${i} transport.`),c.open(),h=!0),I(ij,`RPC '${e}' stream ${i} sending:`,t),c.send(t))},Jo:()=>c.close()});return iG(c,s.EventType.OPEN,()=>{d||(I(ij,`RPC '${e}' stream ${i} transport opened.`),g.i_())}),iG(c,s.EventType.CLOSE,()=>{d||(d=!0,I(ij,`RPC '${e}' stream ${i} transport closed`),g.o_(),this.E_(c))}
10),iG(c,s.EventType.ERROR,t=>{d||(d=!0,O(ij,`RPC '${e}' stream ${i} transport errored. Name:`,t.name,"Message:",t.message),g.o_(new z(D.UNAVAILABLE,"The operation could not be completed")))}),iG(c,s.EventType.MESSAGE,t=>{if(!d){let r=t.data[0];N(!!r,16349);let n=r?.error||r[0]?.error;if(n){I(ij,`RPC '${e}' stream ${i} received error:`,n);let t=n.status,r=function(e){let t=m[e];if(void 0!==t)return rw(t)}(t),a=n.message;"NOT_FOUND"===t&&a.includes("database")&&a.includes("does not exist")&&a.includes(this.databaseId.database)&&O(`Database '${this.databaseId.database}' not found. Please check your project configuration.`),void 0===r&&(r=D.INTERNAL,a="Unknown error status: "+t+" with message "+n.message),d=!0,g.o_(new z(r,a)),c.close()}else I(ij,`RPC '${e}' stream ${i} received:`,r),g.__(r)}}),iK.u_(),setTimeout(()=>{g.s_()},0),g}terminate(){this.a_.forEach(e=>e.close()),this.a_=[]}I_(e){this.a_.push(e)}E_(e){this.a_=this.a_.filter(t=>t===e)}Go(e,t,r){super.Go(e,t,r),this.databaseInfo.apiKey&&(e["x-goog-api-key"]=this.databaseInfo.apiKey)}createWebChannelTransport(){return d()}}function iH(){return"u">typeof document?document:null}function iq(e){return new rD(e,!0)}iK.c_=!1;class iW{constructor(e,t,r=1e3,i=1.5,n=6e4){this.Ci=e,this.timerId=t,this.R_=r,this.A_=i,this.V_=n,this.d_=0,this.m_=null,this.f_=Date.now(),this.reset()}reset(){this.d_=0}g_(){this.d_=this.V_}p_(e){this.cancel();let t=Math.floor(this.d_+this.y_()),r=Math.max(0,Date.now()-this.f_),i=Math.max(0,t-r);i>0&&I("ExponentialBackoff",`Backing off for ${i} ms (base delay: ${this.d_} ms, delay with jitter: ${t} ms, last attempt: ${r} ms ago)`),this.m_=this.Ci.enqueueAfterDelay(this.timerId,i,()=>(this.f_=Date.now(),e())),this.d_*=this.A_,this.d_<this.R_&&(this.d_=this.R_),this.d_>this.V_&&(this.d_=this.V_)}w_(){null!==this.m_&&(this.m_.skipDelay(),this.m_=null)}cancel(){null!==this.m_&&(this.m_.cancel(),this.m_=null)}y_(){return(Math.random()-.5)*this.d_}}let i$="PersistentStream";class iY{constructor(e,t,r,i,n,a,s,o){this.Ci=e,this.b_=r,this.S_=i,this.connection=n,this.authCredentialsProvider=a,this.appCheckCredentialsProvider=s,this.listener=o,this.state=0,this.D_=0,this.C_=null,this.v_=null,this.stream=null,this.F_=0,this.M_=new iW(e,t)}x_(){return 1===this.state||5===this.state||this.O_()}O_(){return 2===this.state||3===this.state}start(){this.F_=0,4!==this.state?this.auth():this.N_()}async stop(){this.x_()&&await this.close(0)}B_(){this.state=0,this.M_.reset()}L_(){this.O_()&&null===this.C_&&(this.C_=this.Ci.enqueueAfterDelay(this.b_,6e4,()=>this.k_()))}K_(e){this.q_(),this.stream.send(e)}async k_(){if(this.O_())return this.close(0)}q_(){this.C_&&(this.C_.cancel(),this.C_=null)}U_(){this.v_&&(this.v_.cancel(),this.v_=null)}async close(e,t){this.q_(),this.U_(),this.M_.cancel(),this.D_++,4!==e?this.M_.reset():t&&t.code===D.RESOURCE_EXHAUSTED?(x(t.toString()),x("Using maximum backoff delay to prevent overloading the backend."),this.M_.g_()):t&&t.code===D.UNAUTHENTICATED&&3!==this.state&&(this.authCredentialsProvider.invalidateToken(),this.appCheckCredentialsProvider.invalidateToken()),null!==this.stream&&(this.W_(),this.stream.close(),this.stream=null),this.state=e,await this.listener.t_(t)}W_(){}auth(){this.state=1;let e=this.Q_(this.D_),t=this.D_;Promise.all([this.authCredentialsProvider.getToken(),this.appCheckCredentialsProvider.getToken()]).then(([e,r])=>{this.D_===t&&this.G_(e,r)},t=>{e(()=>{let e=new z(D.UNKNOWN,"Fetching auth token failed: "+t.message);return this.z_(e)})})}G_(e,t){let r=this.Q_(this.D_);this.stream=this.j_(e,t),this.stream.Zo(()=>{r(()=>this.listener.Zo())}),this.stream.Yo(()=>{r(()=>(this.state=2,this.v_=this.Ci.enqueueAfterDelay(this.S_,1e4,()=>(this.O_()&&(this.state=3),Promise.resolve())),this.listener.Yo()))}),this.stream.t_(e=>{r(()=>this.z_(e))}),this.stream.onMessage(e=>{r(()=>1==++this.F_?this.H_(e):this.onNext(e))})}N_(){this.state=5,this.M_.p_(async()=>{this.state=0,this.start()})}z_(e){return I(i$,`close with error: ${e}`),this.stream=null,this.close(4,e)}Q_(e){return t=>{this.Ci.enqueueAndForget(()=>this.D_===e?t():(I(i$,"stream callback skipped by getCloseGuardedDispatcher."),Promise.resolve()))}}}class iJ extends iY{constructor(e,t,r,i,n,a){super(e,"listen_stream_connection_backoff","listen_stream_idle","health_check_timeout",t,r,i,a),this.serializer
10=n}j_(e,t){return this.connection.T_("Listen",e,t)}H_(e){return this.onNext(e)}onNext(e){this.M_.reset();let t=function(e,t){let r;if("targetChange"in t){var i,n;t.targetChange;let a="NO_CHANGE"===(i=t.targetChange.targetChangeType||"NO_CHANGE")?0:"ADD"===i?1:"REMOVE"===i?2:"CURRENT"===i?3:"RESET"===i?4:P(39313,{state:i}),s=t.targetChange.targetIds||[],o=(n=t.targetChange.resumeToken,e.useProto3Json?(N(void 0===n||"string"==typeof n,58123),eM.fromBase64String(n||"")):(N(void 0===n||n instanceof k||n instanceof Uint8Array,16193),eM.fromUint8Array(n||new Uint8Array))),l=t.targetChange.cause;r=new rR(a,s,o,l&&new z(void 0===l.code?D.UNKNOWN:rw(l.code),l.message||"")||null)}else if("documentChange"in t){t.documentChange;let i=t.documentChange;i.document,i.document.name,i.document.updateTime;let n=rq(e,i.document.name),a=rV(i.document.updateTime),s=i.document.createTime?rV(i.document.createTime):eg.min(),o=new ta({mapValue:{fields:i.document.fields}}),l=ts.newFoundDocument(n,a,s,o);r=new rA(i.targetIds||[],i.removedTargetIds||[],l.key,l)}else if("documentDelete"in t){t.documentDelete;let i=t.documentDelete;i.document;let n=rq(e,i.document),a=i.readTime?rV(i.readTime):eg.min(),s=ts.newNoDocument(n,a);r=new rA([],i.removedTargetIds||[],s.key,s)}else if("documentRemove"in t){t.documentRemove;let i=t.documentRemove;i.document;let n=rq(e,i.document);r=new rA([],i.removedTargetIds||[],n,null)}else{if(!("filter"in t))return P(11601,{Vt:t});{t.filter;let e=t.filter;e.targetId;let{count:i=0,unchangedNames:n}=e,a=new rv(i,n);r=new r_(e.targetId,a)}}return r}(this.serializer,e),r=function(e){if(!("targetChange"in e))return eg.min();let t=e.targetChange;return t.targetIds&&t.targetIds.length?eg.min():t.readTime?rV(t.readTime):eg.min()}(e);return this.listener.J_(t,r)}Z_(e){let t,r={};r.database=r$(this.serializer),r.addTarget=function(e,t){var r,i;let n,a,s,o,l,u,c,h=t.target;if((n=t_(h)?{documents:{documents:[rW(e,h.path)]}}:{query:(s={structuredQuery:{}},o=h.path,null!==h.collectionGroup?(a=o,s.structuredQuery.from=[{collectionId:h.collectionGroup,allDescendants:!0}]):(a=o.popLast(),s.structuredQuery.from=[{collectionId:o.lastSegment()}]),s.parent=rW(e,a),(l=function(e){if(0!==e.length)return function e(t){var r;let i;return t instanceof td?function(e){if("=="===e.op){if(te(e.value))return{unaryFilter:{field:rQ(e.field),op:"IS_NAN"}};if(e7(e.value))return{unaryFilter:{field:rQ(e.field),op:"IS_NULL"}}}else if("!="===e.op){if(te(e.value))return{unaryFilter:{field:rQ(e.field),op:"IS_NOT_NAN"}};if(e7(e.value))return{unaryFilter:{field:rQ(e.field),op:"IS_NOT_NULL"}}}return{fieldFilter:{field:rQ(e.field),op:rL[e.op],value:e.value}}}(t):t instanceof tm?1===(i=(r=t).getFilters().map(t=>e(t))).length?i[0]:{compositeFilter:{op:rN[r.op],filters:i}}:P(54877,{filter:t})}(tm.create(e,"and"))}(h.filters))&&(s.structuredQuery.where=l),(u=function(e){if(0!==e.length)return e.map(e=>({field:rQ(e.field),direction:rP[e.dir]}))}(h.orderBy))&&(s.structuredQuery.orderBy=u),null!==(c=rz(e,h.limit))&&(s.structuredQuery.limit=c),h.startAt&&(s.structuredQuery.startAt={before:(r=h.startAt).inclusive,values:r.position}),h.endAt&&(s.structuredQuery.endAt={before:!(i=h.endAt).inclusive,values:i.position}),{ft:s,parent:a}).ft}).targetId=t.targetId,t.resumeToken.approximateByteSize()>0){n.resumeToken=rB(e,t.resumeToken);let r=rz(e,t.expectedCount);null!==r&&(n.expectedCount=r)}else if(t.snapshotVersion.compareTo(eg.min())>0){n.readTime=rU(e,t.snapshotVersion.toTimestamp());let r=rz(e,t.expectedCount);null!==r&&(n.expectedCount=r)}return n}(this.serializer,e);let i=(this.serializer,null==(t=function(e){switch(e){case"TargetPurposeListen":return null;case"TargetPurposeExistenceFilterMismatch":return"existence-filter-mismatch";case"TargetPurposeExistenceFilterMismatchBloom":return"existence-filter-mismatch-bloom";case"TargetPurposeLimboResolution":return"limbo-document";default:return P(28987,{purpose:e})}}(e.purpose))?null:{"goog-listen-tags":t});i&&(r.labels=i),this.K_(r)}X_(e){let t={};t.database=r$(this.serializer),t.removeTarget=e,this.K_(t)}}class iQ extends iY{constructor(e,t,r,i,n,a){super(e,"write_stream_connection_backoff","write_stream_idle","health_check_timeout",t,r,i,a),this.serializer
10=n}get Y_(){return this.F_>0}start(){this.lastStreamToken=void 0,super.start()}W_(){this.Y_&&this.ea([])}j_(e,t){return this.connection.T_("Write",e,t)}H_(e){return N(!!e.streamToken,31322),this.lastStreamToken=e.streamToken,N(!e.writeResults||0===e.writeResults.length,55816),this.listener.ta()}onNext(e){var t,r;N(!!e.streamToken,12678),this.lastStreamToken=e.streamToken,this.M_.reset();let i=(t=e.writeResults,r=e.commitTime,t&&t.length>0?(N(void 0!==r,14353),t.map(e=>{let t;return(t=e.updateTime?rV(e.updateTime):rV(r)).isEqual(eg.min())&&(t=rV(r)),new rt(t,e.transformResults||[])})):[]),n=rV(e.commitTime);return this.listener.na(n,i)}ra(){let e={};e.database=r$(this.serializer),this.K_(e)}ea(e){let t={streamToken:this.lastStreamToken,writes:e.map(e=>(function(e,t){var r,i;let n;if(t instanceof rl)n={update:rJ(e,t.key,t.value)};else if(t instanceof rm)n={delete:rH(e,t.key)};else if(t instanceof ru){let r;n={update:rJ(e,t.key,t.data),updateMask:(i=t.fieldMask,r=[],i.fields.forEach(e=>r.push(e.canonicalString())),{fieldPaths:r})}}else{if(!(t instanceof rg))return P(16599,{dt:t.type});n={verify:rH(e,t.key)}}return t.fieldTransforms.length>0&&(n.updateTransforms=t.fieldTransforms.map(e=>(function(e){let t=e.transform;if(t instanceof t2)return{fieldPath:e.field.canonicalString(),setToServerValue:"REQUEST_TIME"};if(t instanceof t3)return{fieldPath:e.field.canonicalString(),appendMissingElements:{values:t.elements}};if(t instanceof t5)return{fieldPath:e.field.canonicalString(),removeAllFromArray:{values:t.elements}};if(t instanceof t6)return{fieldPath:e.field.canonicalString(),increment:t.Ae};throw P(20930,{transform:e.transform})})(e))),t.precondition.isNone||(n.currentDocument=void 0!==(r=t.precondition).updateTime?{updateTime:rU(e,r.updateTime.toTimestamp())}:void 0!==r.exists?{exists:r.exists}:P(27497)),n})(this.serializer,e))};this.K_(t)}}class iX{}
10class iZ extends iX{constructor(e,t,r,i){super(),this.authCredentials=e,this.appCheckCredentials=t,this.connection=r,this.serializer=i,this.ia=!1}sa(){if(this.ia)throw new z(D.FAILED_PRECONDITION,"The client has already been terminated.")}Wo(e,t,r,i){return this.sa(),Promise.all([this.authCredentials.getToken(),this.appCheckCredentials.getToken()]).then(([n,a])=>this.connection.Wo(e,rG(t,r),i,n,a)).catch(e=>{throw"FirebaseError"===e.name?(e.code===D.UNAUTHENTICATED&&(this.authCredentials.invalidateToken(),this.appCheckCredentials.invalidateToken()),e):new z(D.UNKNOWN,e.toString())})}jo(e,t,r,i,n){return this.sa(),Promise.all([this.authCredentials.getToken(),this.appCheckCredentials.getToken()]).then(([a,s])=>this.connection.jo(e,rG(t,r),i,a,s,n)).catch(e=>{throw"FirebaseError"===e.name?(e.code===D.UNAUTHENTICATED&&(this.authCredentials.invalidateToken(),this.appCheckCredentials.invalidateToken()),e):new z(D.UNKNOWN,e.toString())})}terminate(){this.ia=!0,this.connection.terminate()}}class i0{constructor(e,t){this.asyncQueue=e,this.onlineStateHandler=t,this.state="Unknown",this.oa=0,this._a=null,this.aa=!0}ua(){0===this.oa&&(this.ca("Unknown"),this._a=this.asyncQueue.enqueueAfterDelay("online_state_timeout",1e4,()=>(this._a=null,this.la("Backend didn't respond within 10 seconds."),this.ca("Offline"),Promise.resolve())))}ha(e){"Online"===this.state?this.ca("Unknown"):(this.oa++,this.oa>=1&&(this.Pa(),this.la(`Connection failed 1 times. Most recent error: ${e.toString()}`),this.ca("Offline")))}set(e){this.Pa(),this.oa=0,"Online"===e&&(this.aa=!1),this.ca(e)}ca(e){e!==this.state&&(this.state=e,this.onlineStateHandler(e))}la(e){let t=`Could not reach Cloud Firestore backend. ${e} 11This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.`;this.aa?(x(t),this.aa=!1):I("OnlineStateTracker",t)}Pa(){null!==this._a&&(this._a.cancel(),this._a=null)}}let i1="RemoteStore";class i2{constructor(e,t,r,i,n){this.localStore=e,this.datastore=t,this.asyncQueue=r,this.remoteSyncer={},this.Ta=[],this.Ia=new Map,this.Ea=new Set,this.Ra=[],this.Aa=n,this.Aa.Mo(e=>{r.enqueueAndForget(async()=>{nt(this)&&(I(i1,"Restarting streams for network reachability change."),await async function(e){e.Ea.add(4),await i4(e),e.Va.set("Unknown"),e.Ea.delete(4),await i3(e)}(this))})}),this.Va=new i0(r,i)}}async function i3(e){if(nt(e))for(let t of e.Ra)await t(!0)}async function i4(e){for(let t of e.Ra)await t(!1)}function i5(e,t){e.Ia.has(t.targetId)||(e.Ia.set(t.targetId,t),ne(e)?i7(e):ny(e).O_()&&i6(e,t))}function i9(e,t){let r=ny(e);e.Ia.delete(t),r.O_()&&i8(e,t),0===e.Ia.size&&(r.O_()?r.L_():nt(e)&&e.Va.set("Unknown"))}function i6(e,t){if(e.da.$e(t.targetId),t.resumeToken.approximateByteSize()>0||t.snapshotVersion.compareTo(eg.min())>0){let r=e.remoteSyncer.getRemoteKeysForTarget(t.targetId).size;t=t.withExpectedCount(r)}ny(e).Z_(t)}function i8(e,t){e.da.$e(t),ny(e).X_(t)}function i7(e){e.da=new rx({getRemoteKeysForTarget:t=>e.remoteSyncer.getRemoteKeysForTarget(t),At:t=>e.Ia.get(t)||null,ht:()=>e.datastore.serializer.databaseId}),ny(e).start(),e.Va.ua()}function ne(e){return nt(e)&&!ny(e).x_()&&e.Ia.size>0}function nt(e){return 0===e.Ea.size}async function nr(e){e.Va.set("Online")}async function ni(e){e.Ia.forEach((t,r)=>{i6(e,t)})}async function nn(e,t){e.da=void 0,ne(e)?(e.Va.ha(t),i7(e)):e.Va.set("Unknown")}async function na(e,t,r){if(e.Va.set("Online"),t instanceof rR&&2===t.state&&t.cause)try{await async function(e,t){let r=t.cause;for(let i of t.targetIds)e.Ia.has(i)&&(await e.remoteSyncer.rejectListen(i,r),e.Ia.delete(i),e.da.removeTarget(i))}(e,t)}catch(r){I(i1,"Failed to remove targets %s: %s ",t.targetIds.join(","),r),await ns(e,r)}else if(t instanceof rA?e.da.Xe(t):t instanceof r_?e.da.st(t):e.da.tt(t),!r.isEqual(eg.min()))try{let t,i=await i_(e.localStore);r.compareTo(i)>
11=0&&await ((t=e.da.Tt(r)).targetChanges.forEach((t,i)=>{if(t.resumeToken.approximateByteSize()>0){let n=e.Ia.get(i);n&&e.Ia.set(i,n.withResumeToken(t.resumeToken,r))}}),t.targetMismatches.forEach((t,r)=>{let i=e.Ia.get(t);if(!i)return;e.Ia.set(t,i.withResumeToken(eM.EMPTY_BYTE_STRING,i.snapshotVersion)),i8(e,t);let n=new r1(i.target,t,r,i.sequenceNumber);i6(e,n)}),e.remoteSyncer.applyRemoteEvent(t))}catch(t){I(i1,"Failed to raise snapshot:",t),await ns(e,t)}}async function ns(e,t,r){if(!eb(t))throw t;e.Ea.add(1),await i4(e),e.Va.set("Offline"),r||(r=()=>i_(e.localStore)),e.asyncQueue.enqueueRetryable(async()=>{I(i1,"Retrying IndexedDB access"),await r(),e.Ea.delete(1),await i3(e)})}function no(e,t){return t().catch(r=>ns(e,r,t))}async function nl(e){var t;let r=nv(e),i=e.Ta.length>0?e.Ta[e.Ta.length-1].batchId:-1;for(;nt(t=e)&&t.Ta.length<10;)try{let t=await function(e,t){return e.persistence.runTransaction("Get next mutation batch","readonly",r=>(void 0===t&&(t=-1),e.mutationQueue.getNextMutationBatchAfterBatchId(r,t)))}(e.localStore,i);if(null===t){0===e.Ta.length&&r.L_();break}i=t.batchId,function(e,t){e.Ta.push(t);let r=nv(e);r.O_()&&r.Y_&&r.ea(t.mutations)}(e,t)}catch(t){await ns(e,t)}nu(e)&&nc(e)}function nu(e){return nt(e)&&!nv(e).x_()&&e.Ta.length>0}function nc(e){nv(e).start()}async function nh(e){nv(e).ra()}async function nd(e){let t=nv(e);for(let r of e.Ta)t.ea(r.mutations)}async function nm(e,t,r){let i=e.Ta.shift(),n=rf.from(i,t,r);await no(e,()=>e.remoteSyncer.applySuccessfulWrite(n)),await nl(e)}async function ng(e,t){t&&nv(e).Y_&&await async function(e,t){var r;if(function(e){switch(e){case D.OK:return P(64938);case D.CANCELLED:case D.UNKNOWN:case D.DEADLINE_EXCEEDED:case D.RESOURCE_EXHAUSTED:case D.INTERNAL:case D.UNAVAILABLE:case D.UNAUTHENTICATED:return!1;case D.INVALID_ARGUMENT:case D.NOT_FOUND:case D.ALREADY_EXISTS:case D.PERMISSION_DENIED:case D.FAILED_PRECONDITION:case D.ABORTED:case D.OUT_OF_RANGE:case D.UNIMPLEMENTED:case D.DATA_LOSS:return!0;default:return P(15467,{code:e})}}(r=t.code)&&r!==D.ABORTED){let r=e.Ta.shift();nv(e).B_(),await no(e,()=>e.remoteSyncer.rejectFailedWrite(r.batchId,t)),await nl(e)}}(e,t),nu(e)&&nc(e)}async function np(e,t){e.asyncQueue.verifyOperationInProgress(),I(i1,"RemoteStore received new credentials");let r=nt(e);e.Ea.add(3),await i4(e),r&&e.Va.set("Unknown"),await e.remoteSyncer.handleCredentialChange(t),e.Ea.delete(3),await i3(e)}async function nf(e,t){t?(e.Ea.delete(2),await i3(e)):t||(e.Ea.add(2),await i4(e),e.Va.set("Unknown"))}function ny(e){var t,r,i;return e.ma||(t=e.datastore,r=e.asyncQueue,i={Zo:nr.bind(null,e),Yo:ni.bind(null,e),t_:nn.bind(null,e),J_:na.bind(null,e)},t.sa(),e.ma=new iJ(r,t.connection,t.authCredentials,t.appCheckCredentials,t.serializer,i),e.Ra.push(async t=>{t?(e.ma.B_(),ne(e)?i7(e):e.Va.set("Unknown")):(await e.ma.stop(),e.da=void 0)})),e.ma}function nv(e){var t,r,i;return e.fa||(t=e.datastore,r=e.asyncQueue,i={Zo:()=>Promise.resolve(),Yo:nh.bind(null,e),t_:ng.bind(null,e),ta:nd.bind(null,e),na:nm.bind(null,e)},t.sa(),e.fa=new iQ(r,t.connection,t.authCredentials,t.appCheckCredentials,t.serializer,i),e.Ra.push(async t=>{t?(e.fa.B_(),await nl(e)):(await e.fa.stop(),e.Ta.length>0&&(I(i1,`Stopping write stream with ${e.Ta.length} pending writes`),e.Ta=[]))})),e.fa}class nw{constructor(e,t,r,i,n){this.asyncQueue=e,this.timerId=t,this.targetTimeMs=r,this.op=i,this.removalCallback=n,this.deferred=new U,this.then=this.deferred.promise.then.bind(this.deferred.promise),this.deferred.promise.catch(e=>{})}get promise(){return this.deferred.promise}static createAndSchedule(e,t,r,i,n){let a=new nw(e,t,Date.now()+r,i,n);return a.start(r),a}start(e){this.timerHandle=setTimeout(()=>this.handleDelayElapsed(),e)}skipDelay(){return this.handleDelayElapsed()}cancel(e){null!==this.timerHandle&&(this.clearTimeout(),this.deferred.reject(new z(D.CANCELLED,"Operation cancelled"+(e?": "+e:""))))}handleDelayElapsed(){this.asyncQueue.enqueueAndForget(()=>null!==this.timerHandle?(this.clearTimeout(),this.op().then(e=>this.deferred.resolve(e))):Promise.resolve())}clearTimeout(){null!==this.timerHandle&&(this.removalCallback(this),clearTimeout(this.timerHandle),this.timerHandle=null)}}function nb(e,t){if(x("AsyncQueue",`${t}: ${e}`),eb(e))return new z(D.UNAVAILABLE,`${t}: ${e}`);throw e}class nC{static emptySet(e){return new nC(e.comparator)}constructor(e){this.comparator=e?(t,r)=>e(t,r)||en.comparator(t.key,r.key):(e,t)=>en.comparator(e.key,t.key),this.keyedMap=tH(),this.sortedSet=new eE(this.comparator)}has(e){return null!=this.keyedMap.get(e)}get(e){return this.keyedMap.get(e)}first(){return this.sortedSet.minKey()}last(){return this.sortedSet.maxKey()}isEmpty(){return this.sortedSet.isEmpty()}indexOf(e){let t=this.keyedMap.get(e);return t?this.sortedSet.indexOf(t):-1}get size(){return this.sortedSet.size}forEach(e){this.sortedSet.inorderTraversal((t,r)=>(e(t),!1))}add(e){let t=this.delete(e.key);return t.copy(t.keyedMap.insert(e.key,e),t.sortedSet.insert(e,null))}delete(e){let t=this.get(e);return t?this.copy(this.keyedMap.remove(e),this.sortedSet.remove(t)):this}isEqual(e){if(!(e instanceof nC)||this.size!==e.size)return!1;let t=this.sortedSet.getIterator(),r=e.sortedSet.getIterator();for(;t.hasNext();){let e=t.getNext().key,i=r.getNext().key;if(!e.isEqual(i))return!1}return!0}toString(){let e=[];return this.forEach(t=>{e.push(t.toString())}),0===e.length?"DocumentSet ()":"DocumentSet (\n "+e.join(" \n")+"\n)"}copy(e,t){let r=new nC;return r.comparator=this.comparator,r.keyedMap=e,r.sortedSet=t,r}}class nT{constructor(){this.ga=new eE(en.comparator)}track(e){let t=e.doc.key,r=this.ga.get(t);r?0!==e.type&&3===r.type?this.ga=this.ga.insert(t,e):3===e.type&&1!==r.type?this.ga=this.ga.insert(t,{type:r.type,doc:e.doc}):2===e.type&&2===r.type?this.ga=this.ga.insert(t,{type:2,doc:e.doc}):2===e.type&&0===r.type?this.ga=this.ga.insert(t,{type:0,doc:e.doc}):1===e.type&&0===r.type?this.ga=this.ga.remove(t):1===e.type&&2===r.type?this.ga=this.ga.insert(t,{type:1,doc:r.doc}):0===e.type&&1===r.type?this.ga=this.ga.insert(t,{type:2,doc:e.doc}):P(63341,{Vt:e,pa:r}):this.ga=this.ga.insert(t,e)}ya(){let e=[];return this.ga.inorderTraversal((t,r)=>{e.push(r)}),e}}class nS{constructor(e,t,r,i,n,a,s,o,l){this.query=e,this.docs=t,this.oldDocs=r,this.docChanges=i,this.mutatedKeys=n,this.fromCache=a,this.syncStateChanged=s,this.excludesMetadataChanges=o,this.hasCachedResults=l}static fromInitialDocuments(e,t,r,i,n){let a=[];
11return t.forEach(e=>{a.push({type:0,doc:e})}),new nS(e,t,nC.emptySet(t),a,r,i,!0,!1,n)}get hasPendingWrites(){return!this.mutatedKeys.isEmpty()}isEqual(e){if(!(this.fromCache===e.fromCache&&this.hasCachedResults===e.hasCachedResults&&this.syncStateChanged===e.syncStateChanged&&this.mutatedKeys.isEqual(e.mutatedKeys)&&tD(this.query,e.query)&&this.docs.isEqual(e.docs)&&this.oldDocs.isEqual(e.oldDocs)))return!1;let t=this.docChanges,r=e.docChanges;if(t.length!==r.length)return!1;for(let e=0;e<t.length;e++)if(t[e].type!==r[e].type||!t[e].doc.isEqual(r[e].doc))return!1;return!0}}class nF{constructor(){this.wa=void 0,this.ba=[]}Sa(){return this.ba.some(e=>e.Da())}}class nk{constructor(){this.queries=nE(),this.onlineState="Unknown",this.Ca=new Set}terminate(){var e;let t;e=new z(D.ABORTED,"Firestore shutting down"),t=this.queries,this.queries=nE(),t.forEach((t,r)=>{for(let t of r.ba)t.onError(e)})}}function nE(){return new tj(e=>tz(e),tD)}async function nA(e,t){let r=3,i=t.query,n=e.queries.get(i);n?!n.Sa()&&t.Da()&&(r=2):(n=new nF,r=+!t.Da());try{switch(r){case 0:n.wa=await e.onListen(i,!0);break;case 1:n.wa=await e.onListen(i,!1);break;case 2:await e.onFirstRemoteStoreListen(i)}}catch(r){let e=nb(r,`Initialization of query '${tU(t.query)}' failed`);return void t.onError(e)}e.queries.set(i,n),n.ba.push(t),t.va(e.onlineState),n.wa&&t.Fa(n.wa)&&nx(e)}async function n_(e,t){let r=t.query,i=3,n=e.queries.get(r);if(n){let e=n.ba.indexOf(t);e>=0&&(n.ba.splice(e,1),0===n.ba.length?i=+!t.Da():!n.Sa()&&t.Da()&&(i=2))}switch(i){case 0:return e.queries.delete(r),e.onUnlisten(r,!0);case 1:return e.queries.delete(r),e.onUnlisten(r,!1);case 2:return e.onLastRemoteStoreUnlisten(r);default:return}}function nR(e,t){let r=!1;for(let i of t){let t=i.query,n=e.queries.get(t);if(n){for(let e of n.ba)e.Fa(i)&&(r=!0);n.wa=i}}r&&nx(e)}function nI(e,t,r){let i=e.queries.get(t);if(i)for(let e of i.ba)e.onError(r);e.queries.delete(t)}function nx(e){e.Ca.forEach(e=>{e.next()})}(f=p||(p={})).Ma="default",f.Cache="cache";class nO{constructor(e,t,r){this.query=e,this.xa=t,this.Oa=!1,this.Na=null,this.onlineState="Unknown",this.options=r||{}}Fa(e){if(!this.options.includeMetadataChanges){let t=[];for(let r of e.docChanges)3!==r.type&&t.push(r);e=new nS(e.query,e.docs,e.oldDocs,t,e.mutatedKeys,e.fromCache,e.syncStateChanged,!0,e.hasCachedResults)}let t=!1;return this.Oa?this.Ba(e)&&(this.xa.next(e),t=!0):this.La(e,this.onlineState)&&(this.ka(e),t=!0),this.Na=e,t}onError(e){this.xa.error(e)}va(e){this.onlineState=e;let t=!1;return this.Na&&!this.Oa&&this.La(this.Na,e)&&(this.ka(this.Na),t=!0),t}La(e,t){return!(e.fromCache&&this.Da())||(!this.options.Ka||"Offline"===t)&&(!e.docs.isEmpty()||e.hasCachedResults||"Offline"===t)}Ba(e){if(e.docChanges.length>0)return!0;let t=this.Na&&this.Na.hasPendingWrites!==e.hasPendingWrites;return!(!e.syncStateChanged&&!t)&&!0===this.options.includeMetadataChanges}ka(e){e=nS.fromInitialDocuments(e.query,e.docs,e.mutatedKeys,e.fromCache,e.hasCachedResults),this.Oa=!0,this.xa.next(e)}Da(){return this.options.source!==p.Cache}}class nM{constructor(e){this.key=e}}class nP{constructor(e){this.key=e}}class nL{constructor(e,t){this.query=e,this.Za=t,this.Xa=null,this.hasCachedResults=!1,this.current=!1,this.Ya=tJ(),this.mutatedKeys=tJ(),this.eu=tV(e),this.tu=new nC(this.eu)}get nu(){return this.Za}ru(e,t){let r=t?t.iu:new nT,i=t?t.tu:this.tu,n=t?t.mutatedKeys:this.mutatedKeys,a=i,s=!1,o="F"===this.query.limitType&&i.size===this.query.limit?i.last():null,l="L"===this.query.limitType&&i.size===this.query.limit?i.first():null;if(e.inorderTraversal((e,t)=>{let u=i.get(e),c=tB(this.query,t)?t:null,h=!!u&&this.mutatedKeys.has(u.key),d=!!c&&(c.hasLocalMutations||this.mutatedKeys.has(c.key)&&c.hasCommittedMutations),m=!1;u&&c?u.data.isEqual(c.data)?h!==d&&(r.track({type:3,doc:c}),m=!0):this.su(u,c)||(r.track({type:2,doc:c}),m=!0,(o&&this.eu(c,o)>0||l&&0>this.eu(c,l))&&(s=!0)):!u&&c?(r.track({type:0,doc:c}),m=!0):u&&!c&&(r.track({type:1,doc:u}),m=!0,(o||l)&&(s=!0)),m&&(c?(a=a.add(c),n=d?n.add(e):n.delete(e)):(a=a.delete(e),n=n.delete(e)))}),null!==this.query.limit)for(;a.size>this.query.limit;){let e="F"===this.query.limitType?a.last():a.first();a=a.delete(e.key),n=n.delete(e.key),r.track({type:1,doc:e})}return{tu:a,iu:r,Ss:s,mutatedKeys:n}}su(e,t){return e.hasLocalMutations&&t.hasCommittedMutations&&!t.hasLocalMutations}
11applyChanges(e,t,r,i){let n=this.tu;this.tu=e.tu,this.mutatedKeys=e.mutatedKeys;let a=e.iu.ya();a.sort((e,t)=>{var r,i;let n;return r=e.type,i=t.type,(n=e=>{switch(e){case 0:return 1;case 2:case 3:return 2;case 1:return 0;default:return P(20277,{Vt:e})}})(r)-n(i)||this.eu(e.doc,t.doc)}),this.ou(r),i=i??!1;let s=t&&!i?this._u():[],o=0===this.Ya.size&&this.current&&!i?1:0,l=o!==this.Xa;return(this.Xa=o,0!==a.length||l)?{snapshot:new nS(this.query,e.tu,n,a,e.mutatedKeys,0===o,l,!1,!!r&&r.resumeToken.approximateByteSize()>0),au:s}:{au:s}}va(e){return this.current&&"Offline"===e?(this.current=!1,this.applyChanges({tu:this.tu,iu:new nT,mutatedKeys:this.mutatedKeys,Ss:!1},!1)):{au:[]}}uu(e){return!this.Za.has(e)&&!!this.tu.has(e)&&!this.tu.get(e).hasLocalMutations}ou(e){e&&(e.addedDocuments.forEach(e=>this.Za=this.Za.add(e)),e.modifiedDocuments.forEach(e=>{}),e.removedDocuments.forEach(e=>this.Za=this.Za.delete(e)),this.current=e.current)}_u(){if(!this.current)return[];let e=this.Ya;this.Ya=tJ(),this.tu.forEach(e=>{this.uu(e.key)&&(this.Ya=this.Ya.add(e.key))});let t=[];return e.forEach(e=>{this.Ya.has(e)||t.push(new nP(e))}),this.Ya.forEach(r=>{e.has(r)||t.push(new nM(r))}),t}cu(e){this.Za=e.ks,this.Ya=tJ();let t=this.ru(e.documents);return this.applyChanges(t,!0)}lu(){return nS.fromInitialDocuments(this.query,this.tu,this.mutatedKeys,0===this.Xa,this.hasCachedResults)}}let nN="SyncEngine";class nD{constructor(e,t,r){this.query=e,this.targetId=t,this.view=r}}class nz{constructor(e){this.key=e,this.hu=!1}}class nU{constructor(e,t,r,i,n,a){this.localStore=e,this.remoteStore=t,this.eventManager=r,this.sharedClientState=i,this.currentUser=n,this.maxConcurrentLimboResolutions=a,this.Pu={},this.Tu=new tj(e=>tz(e),tD),this.Iu=new Map,this.Eu=new Set,this.Ru=new eE(en.comparator),this.Au=new Map,this.Vu=new ih,this.du={},this.mu=new Map,this.fu=r8.ar(),this.onlineState="Unknown",this.gu=void 0}get isPrimaryClient(){return!0===this.gu}}async function nB(e,t,r=!0){let i,n=n6(e),a=n.Tu.get(t);return a?(n.sharedClientState.addLocalQueryTarget(a.targetId),i=a.view.lu()):i=await nj(n,t,r,!0),i}async function nV(e,t){let r=n6(e);await nj(r,t,!0,!1)}async function nj(e,t,r,i){var n,a;let s,o=await (n=e.localStore,a=tP(t),n.persistence.runTransaction("Allocate target","readwrite",e=>{let t;return n.li.getTargetData(e,a).next(r=>r?(t=r,ew.resolve(t)):n.li.allocateTargetId(e).next(r=>(t=new r1(a,r,"TargetPurposeListen",e.currentSequenceNumber),n.li.addTargetData(e,t).next(()=>t))))}).then(e=>{let t=n.vs.get(e.targetId);return(null===t||e.snapshotVersion.compareTo(t.snapshotVersion)>0)&&(n.vs=n.vs.insert(e.targetId,e),n.Fs.set(a,e.targetId)),e})),l=o.targetId,u=e.sharedClientState.addLocalQueryTarget(l,r);return i&&(s=await nG(e,t,l,"current"===u,o.resumeToken)),e.isPrimaryClient&&r&&i5(e.remoteStore,o),s}async function nG(e,t,r,i,n){e.pu=(t,r,i)=>(async function(e,t,r,i){let n=t.view.ru(r);n.Ss&&(n=await iI(e.localStore,t.query,!1).then(({documents:e})=>t.view.ru(e,n)));let a=i&&i.targetChanges.get(t.targetId),s=i&&null!=i.targetMismatches.get(t.targetId),o=t.view.applyChanges(n,e.isPrimaryClient,a,s);return n2(e,t.targetId,o.au),o.snapshot})(e,t,r,i);let a=await iI(e.localStore,t,!0),s=new nL(t,a.ks),o=s.ru(a.documents),l=rE.createSynthesizedTargetChangeForCurrentChange(r,i&&"Offline"!==e.onlineState,n),u=s.applyChanges(o,e.isPrimaryClient,l);n2(e,r,u.au);let c=new nD(t,r,s);return e.Tu.set(t,c),e.Iu.has(r)?e.Iu.get(r).push(t):e.Iu.set(r,[t]),u.snapshot}async function nK(e,t,r){let i=e.Tu.get(t),n=e.Iu.get(i.targetId);n.length>1?(e.Iu.set(i.targetId,n.filter(e=>!tD(e,t))),e.Tu.delete(t)):e.isPrimaryClient?(e.sharedClientState.removeLocalQueryTarget(i.targetId),e.sharedClientState.isActiveQueryTarget(i.targetId)||await iR(e.localStore,i.targetId,!1).then(()=>{e.sharedClientState.clearQueryState(i.targetId),r&&i9(e.remoteStore,i.targetId),n0(e,i.targetId)}).catch(ev)):(n0(e,i.targetId),await iR(e.localStore,i.targetId,!0))}async function nH(e,t){let r=e.Tu.get(t),i=e.Iu.get(r.targetId);e.isPrimaryClient&&1===i.length&&(e.sharedClientState.removeLocalQueryTarget(r.targetId),i9(e.remoteStore,r.targetId))}async function nq(e,t,r){var i,n,a;let s=((i=e).remoteStore.remoteSyncer.applySuccessfulWrite=nJ.bind(null,i),i.remoteStore.remoteSyncer.rejectFailedWrite=nQ.bind(null,i),i);try{let e,i,o,l,u,c=await (n=s.localStore,o=em.now(),l=t.reduce((e,t)=>
11e.add(t.key),tJ()),n.persistence.runTransaction("Locally write mutations","readwrite",r=>{let a=tG,s=tJ();return n.xs.getEntries(r,l).next(e=>{(a=e).forEach((e,t)=>{t.isValidDocument()||(s=s.add(e))})}).next(()=>n.localDocuments.getOverlayedDocuments(r,a)).next(i=>{e=i;let a=[];for(let r of t){let t=function(e,t){let r=null;for(let i of e.fieldTransforms){let e=t.data.field(i.field),n=t1(i.transform,e||null);null!=n&&(null===r&&(r=ta.empty()),r.set(i.field,n))}return r||null}(r,e.get(r.key).overlayedDocument);null!=t&&a.push(new ru(r.key,t,function e(t){let r=[];return eF(t.fields,(t,i)=>{let n=new ei([t]);if(tt(i)){let t=e(i.mapValue).fields;if(0===t.length)r.push(n);else for(let e of t)r.push(n.child(e))}else r.push(n)}),new ex(r)}(t.value.mapValue),rr.exists(!0)))}return n.mutationQueue.addMutationBatch(r,o,a,t)}).next(t=>{i=t;let a=t.applyToLocalDocumentSet(e,s);return n.documentOverlayCache.saveOverlays(r,t.batchId,a)})}).then(()=>({batchId:i.batchId,changes:tq(e)})));s.sharedClientState.addPendingMutation(c.batchId),a=c.batchId,(u=s.du[s.currentUser.toKey()])||(u=new eE(Y)),u=u.insert(a,r),s.du[s.currentUser.toKey()]=u,await n4(s,c.changes),await nl(s.remoteStore)}catch(t){let e=nb(t,"Failed to persist write");r.reject(e)}}async function nW(e,t){try{var r,i;let n,a,s=await (r=e.localStore,n=(i=t).snapshotVersion,a=r.vs,r.persistence.runTransaction("Apply remote event","readwrite-primary",e=>{var t,s,o;let l,u,c=r.xs.newChangeBuffer({trackRemovals:!0});a=r.vs;let h=[];
11i.targetChanges.forEach((t,s)=>{var o;let l=a.get(s);if(!l)return;h.push(r.li.removeMatchingKeys(e,t.removedDocuments,s).next(()=>r.li.addMatchingKeys(e,t.addedDocuments,s)));let u=l.withSequenceNumber(e.currentSequenceNumber);null!==i.targetMismatches.get(s)?u=u.withResumeToken(eM.EMPTY_BYTE_STRING,eg.min()).withLastLimboFreeSnapshotVersion(eg.min()):t.resumeToken.approximateByteSize()>0&&(u=u.withResumeToken(t.resumeToken,n)),a=a.insert(s,u),o=u,(0===l.resumeToken.approximateByteSize()||o.snapshotVersion.toMicroseconds()-l.snapshotVersion.toMicroseconds()>=3e8||t.addedDocuments.size+t.modifiedDocuments.size+t.removedDocuments.size>0)&&h.push(r.li.updateTargetData(e,u))});let d=tG,m=tJ();if(i.documentUpdates.forEach(t=>{i.resolvedLimboDocuments.has(t)&&h.push(r.persistence.referenceDelegate.updateLimboDocument(e,t))}),h.push((t=e,s=c,o=i.documentUpdates,l=tJ(),u=tJ(),o.forEach(e=>l=l.add(e)),s.getEntries(t,l).next(e=>{let t=tG;return o.forEach((r,i)=>{let n=e.get(r);i.isFoundDocument()!==n.isFoundDocument()&&(u=u.add(r)),i.isNoDocument()&&i.version.isEqual(eg.min())?(s.removeEntry(r,i.readTime),t=t.insert(r,i)):!n.isValidDocument()||i.version.compareTo(n.version)>0||0===i.version.compareTo(n.version)&&n.hasPendingWrites?(s.addEntry(i),t=t.insert(r,i)):I(ik,"Ignoring outdated watch update for ",r,". Current version:",n.version," Watch version:",i.version)}),{Bs:t,Ls:u}})).next(e=>{d=e.Bs,m=e.Ls})),!n.isEqual(eg.min())){let t=r.li.getLastRemoteSnapshotVersion(e).next(t=>r.li.setTargetsMetadata(e,e.currentSequenceNumber,n));h.push(t)}return ew.waitFor(h).next(()=>c.apply(e)).next(()=>r.localDocuments.getLocalViewOfDocuments(e,d,m)).next(()=>d)}).then(e=>(r.vs=a,e)));
11t.targetChanges.forEach((t,r)=>{let i=e.Au.get(r);i&&(N(t.addedDocuments.size+t.modifiedDocuments.size+t.removedDocuments.size<=1,22616),t.addedDocuments.size>0?i.hu=!0:t.modifiedDocuments.size>0?N(i.hu,14607):t.removedDocuments.size>0&&(N(i.hu,42227),i.hu=!1))}),await n4(e,s,t)}catch(e){await ev(e)}}function n$(e,t,r){if(e.isPrimaryClient&&0===r||!e.isPrimaryClient&&1===r){var i;let r,n=[];e.Tu.forEach((e,r)=>{let i=r.view.va(t);i.snapshot&&n.push(i.snapshot)}),(i=e.eventManager).onlineState=t,r=!1,i.queries.forEach((e,i)=>{for(let e of i.ba)e.va(t)&&(r=!0)}),r&&nx(i),n.length&&e.Pu.J_(n),e.onlineState=t,e.isPrimaryClient&&e.sharedClientState.setOnlineState(t)}}async function nY(e,t,r){e.sharedClientState.updateQueryState(t,"rejected",r);let i=e.Au.get(t),n=i&&i.key;if(n){let r=new eE(en.comparator);r=r.insert(n,ts.newNoDocument(n,eg.min()));let i=tJ().add(n),a=new rk(eg.min(),new Map,new eE(Y),r,i);await nW(e,a),e.Ru=e.Ru.remove(n),e.Au.delete(t),n3(e)}else await iR(e.localStore,t,!1).then(()=>n0(e,t,r)).catch(ev)}async function nJ(e,t){let r=t.batch.batchId;try{var i,n;let a=await (i=e.localStore,n=t,i.persistence.runTransaction("Acknowledge batch","readwrite-primary",e=>{let t,r,a,s=n.batch.keys(),o=i.xs.newChangeBuffer({trackRemovals:!0});
11return(r=(t=n.batch).keys(),a=ew.resolve(),r.forEach(r=>{a=a.next(()=>o.getEntry(e,r)).next(e=>{let i=n.docVersions.get(r);N(null!==i,48541),0>e.version.compareTo(i)&&(t.applyToRemoteDocument(e,n),e.isValidDocument()&&(e.setReadTime(n.commitVersion),o.addEntry(e)))})}),a.next(()=>i.mutationQueue.removeMutationBatch(e,t))).next(()=>o.apply(e)).next(()=>i.mutationQueue.performConsistencyCheck(e)).next(()=>i.documentOverlayCache.removeOverlaysForBatchId(e,s,n.batch.batchId)).next(()=>i.localDocuments.recalculateAndSaveOverlaysForDocumentKeys(e,function(e){let t=tJ();for(let r=0;r<e.mutationResults.length;++r)e.mutationResults[r].transformResults.length>0&&(t=t.add(e.batch.mutations[r].key));return t}(n))).next(()=>i.localDocuments.getDocuments(e,s))}));nZ(e,r,null),nX(e,r),e.sharedClientState.updateMutationState(r,"acknowledged"),await n4(e,a)}catch(e){await ev(e)}}async function nQ(e,t,r){try{var i;let n=await (i=e.localStore,i.persistence.runTransaction("Reject batch","readwrite-primary",e=>{let r;return i.mutationQueue.lookupMutationBatch(e,t).next(t=>(N(null!==t,37113),r=t.keys(),i.mutationQueue.removeMutationBatch(e,t))).next(()=>i.mutationQueue.performConsistencyCheck(e)).next(()=>i.documentOverlayCache.removeOverlaysForBatchId(e,r,t)).next(()=>i.localDocuments.recalculateAndSaveOverlaysForDocumentKeys(e,r)).next(()=>i.localDocuments.getDocuments(e,r))}));nZ(e,t,r),nX(e,t),e.sharedClientState.updateMutationState(t,"rejected",r),await n4(e,n)}catch(e){await ev(e)}}function nX(e,t){(e.mu.get(t)||[]).forEach(e=>{e.resolve()}),e.mu.delete(t)}function nZ(e,t,r){let i=e.du[e.currentUser.toKey()];if(i){let n=i.get(t);n&&(r?n.reject(r):n.resolve(),i=i.remove(t)),e.du[e.currentUser.toKey()]=i}}function n0(e,t,r=null){for(let i of(e.sharedClientState.removeLocalQueryTarget(t),e.Iu.get(t)))e.Tu.delete(i),r&&e.Pu.yu(i,r);e.Iu.delete(t),e.isPrimaryClient&&e.Vu.Gr(t).forEach(t=>{e.Vu.containsKey(t)||n1(e,t)})}function n1(e,t){e.Eu.delete(t.path.canonicalString());let r=e.Ru.get(t);null!==r&&(i9(e.remoteStore,r),e.Ru=e.Ru.remove(t),e.Au.delete(r),n3(e))}function n2(e,t,r){for(let i of r)i instanceof nM?(e.Vu.addReference(i.key,t),function(e,t){let r=t.key,i=r.path.canonicalString();e.Ru.get(r)||e.Eu.has(i)||(I(nN,"New document in limbo: "+r),e.Eu.add(i),n3(e))}(e,i)):i instanceof nP?(I(nN,"Document no longer in limbo: "+i.key),e.Vu.removeReference(i.key,t),e.Vu.containsKey(i.key)||n1(e,i.key)):P(19791,{wu:i})}function n3(e){for(;e.Eu.size>0&&e.Ru.size<e.maxConcurrentLimboResolutions;){let t=e.Eu.values().next().value;e.Eu.delete(t);let r=new en(et.fromString(t)),i=e.fu.next();e.Au.set(i,new nz(r)),e.Ru=e.Ru.insert(r,i),i5(e.remoteStore,new r1(tP(tI(r.path)),i,"TargetPurposeLimboResolution",eC.ce))}}async function n4(e,t,r){let i=[],n=[],a=[];e.Tu.isEmpty()||(e.Tu.forEach((s,o)=>{a.push(e.pu(o,t,r).then(t=>{if((t||r)&&e.isPrimaryClient){let i=t?!t.fromCache:r?.targetChanges.get(o.targetId)?.current;e.sharedClientState.updateQueryState(o.targetId,i?"current":"not-current")}if(t){i.push(t);let e=iT.Es(o.targetId,t);n.push(e)}}))}),await Promise.all(a),e.Pu.J_(i),await async function(e,t){try{await e.persistence.runTransaction("notifyLocalViewChanges","readwrite",r=>ew.forEach(t,t=>ew.forEach(t.Ts,i=>e.persistence.referenceDelegate.addReference(r,t.targetId,i)).next(()=>ew.forEach(t.Is,i=>e.persistence.referenceDelegate.removeReference(r,t.targetId,i)))))}catch(e){if(!eb(e))throw e;I(ik,"Failed to update sequence numbers: "+e)}for(let r of t){let t=r.targetId;if(!r.fromCache){let r=e.vs.get(t),i=r.snapshotVersion,n=r.withLastLimboFreeSnapshotVersion(i);e.vs=e.vs.insert(t,n)}}}(e.localStore,n))}async function n5(e,t){if(!e.currentUser.isEqual(t)){I(nN,"User change. New user:",t.toKey());let r=await iA(e.localStore,t);e.currentUser=t,e.mu.forEach(e=>{e.forEach(e=>{e.reject(new z(D.CANCELLED,"'waitForPendingWrites' promise is rejected due to a user change."))})}),e.mu.clear(),e.sharedClientState.handleUserChange(t,r.removedBatchIds,r.addedBatchIds),await n4(e,r.Ns)}}function n9(e,t){let r=e.Au.get(t);if(r&&r.hu)return tJ().add(r.key);{let r=tJ(),i=e.Iu.get(t);if(!i)return r;for(let t of i){let i=e.Tu.get(t);r=r.unionWith(i.view.nu)}return r}}function n6(e){return e.remoteStore.remoteSyncer.applyRemoteEvent=nW.bind(null,e),e.remoteStore.remoteSyncer.getRemoteKeysForTarget=n9.bind(null,e),e.remoteStore.remoteSyncer.rejectListen=nY.bind(null,e),e.Pu.J_=nR.bind(null,e.eventManager),e.Pu.yu=nI.bind(null,e.eventManager),e}class n8{constructor(){this.kind="memory",this.synchronizeTabs=!1}
11async initialize(e){this.serializer=iq(e.databaseInfo.databaseId),this.sharedClientState=this.Du(e),this.persistence=this.Cu(e),await this.persistence.start(),this.localStore=this.vu(e),this.gcScheduler=this.Fu(e,this.localStore),this.indexBackfillerScheduler=this.Mu(e,this.localStore)}Fu(e,t){return null}Mu(e,t){return null}vu(e){var t,r;return t=this.persistence,r=new iF,new iE(t,r,e.initialUser,this.serializer)}Cu(e){return new iv(ib.Vi,this.serializer)}Du(e){return new iO}async terminate(){this.gcScheduler?.stop(),this.indexBackfillerScheduler?.stop(),this.sharedClientState.shutdown(),await this.persistence.shutdown()}}n8.provider={build:()=>new n8};class n7 extends n8{constructor(e){super(),this.cacheSizeBytes=e}Fu(e,t){return N(this.persistence.referenceDelegate instanceof iC,46915),new ir(this.persistence.referenceDelegate.garbageCollector,e.asyncQueue,t)}Cu(e){let t=void 0!==this.cacheSizeBytes?r6.withCacheSize(this.cacheSizeBytes):r6.DEFAULT;return new iv(e=>iC.Vi(e,t),this.serializer)}}class ae{async initialize(e,t){this.localStore||(this.localStore=e.localStore,this.sharedClientState=e.sharedClientState,this.datastore=this.createDatastore(t),this.remoteStore=this.createRemoteStore(t),this.eventManager=this.createEventManager(t),this.syncEngine=this.createSyncEngine(t,!e.synchronizeTabs),this.sharedClientState.onlineStateHandler=e=>n$(this.syncEngine,e,1),this.remoteStore.remoteSyncer.handleCredentialChange=n5.bind(null,this.syncEngine),await nf(this.remoteStore,this.syncEngine.isPrimaryClient))}createEventManager(e){return new nk}createDatastore(e){var t;let r=iq(e.databaseInfo.databaseId),i=new iK(e.databaseInfo);return t=e.authCredentials,new iZ(t,e.appCheckCredentials,i,r)}createRemoteStore(e){var t,r;return t=this.localStore,r=this.datastore,new i2(t,r,e.asyncQueue,e=>n$(this.syncEngine,e,0),iL.v()?new iL:new iM)}createSyncEngine(e,t){var r,i,n,a,s,o;let l;return r=this.localStore,i=this.remoteStore,n=this.eventManager,a=this.sharedClientState,s=e.initialUser,o=e.maxConcurrentLimboResolutions,l=new nU(r,i,n,a,s,o),t&&(l.gu=!0),l}async terminate(){await async function(e){I(i1,"RemoteStore shutting down."),e.Ea.add(5),await i4(e),e.Aa.shutdown(),e.Va.set("Unknown")}(this.remoteStore),this.datastore?.terminate(),this.eventManager?.terminate()}}ae.provider={build:()=>new ae};class at{constructor(e){this.observer=e,this.muted=!1}next(e){this.muted||this.observer.next&&this.Ou(this.observer.next,e)}error(e){this.muted||(this.observer.error?this.Ou(this.observer.error,e):x("Uncaught Error in snapshot listener:",e.toString()))}Nu(){this.muted=!0}Ou(e,t){setTimeout(()=>{this.muted||e(t)},0)}}let ar="FirestoreClient";class ai{constructor(e,t,r,i,n){this.authCredentials=e,this.appCheckCredentials=t,this.asyncQueue=r,this._databaseInfo=i,this.user=E.UNAUTHENTICATED,this.clientId=$.newId(),this.authCredentialListener=()=>Promise.resolve(),this.appCheckCredentialListener=()=>Promise.resolve(),this._uninitializedComponentsProvider=n,this.authCredentials.start(r,async e=>{I(ar,"Received user=",e.uid),await this.authCredentialListener(e),this.user=e}),this.appCheckCredentials.start(r,e=>(I(ar,"Received new app check token=",e),this.appCheckCredentialListener(e,this.user)))}get configuration(){return{asyncQueue:this.asyncQueue,databaseInfo:this._databaseInfo,clientId:this.clientId,authCredentials:this.authCredentials,appCheckCredentials:this.appCheckCredentials,initialUser:this.user,maxConcurrentLimboResolutions:100}}setCredentialChangeListener(e){this.authCredentialListener=e}setAppCheckTokenChangeListener(e){this.appCheckCredentialListener=e}terminate(){this.asyncQueue.enterRestrictedMode();let e=new U;return this.asyncQueue.enqueueAndForgetEvenWhileRestricted(async()=>{try{this._onlineComponents&&await this._onlineComponents.terminate(),this._offlineComponents&&await this._offlineComponents.terminate(),this.authCredentials.shutdown(),this.appCheckCredentials.shutdown(),e.resolve()}catch(r){let t=nb(r,"Failed to shutdown persistence");e.reject(t)}}),e.promise}}async function an(e,t){e.asyncQueue.verifyOperationInProgress(),I(ar,"Initializing OfflineComponentProvider");let r=e.configuration;await t.initialize(r);let i=r.initialUser;e.setCredentialChangeListener(async e=>{i.isEqual(e)||(await iA(t.localStore,e),i=e)}),t.persistence.setDatabaseDeletedListener(()=>e.terminate()),e._offlineComponents=t}async function aa(e,t){e.asyncQueue.verifyOperationInProgress();let r=await as(e);I(ar,"Initializing OnlineComponentProvider"),await t.initialize(r,e.configuration),e.setCredentialChangeListener(e=>np(t.remoteStore,e)),e.setAppCheckTokenChangeListener((e,r)=>np(t.remoteStore,r)),e._onlineComponents=t}async function as(e){if(!e._offlineComponents)if(e._uninitializedComponentsProvider){I(ar,"Using user provided OfflineComponentProvider");try{await an(e,e._uninitializedComponentsProvider._offline)}catch(t){if(!("FirebaseError"===t.name?t.code===D.FAILED_PRECONDITION||t.code===D.UNIMPLEMENT
11ED:!("u">typeof DOMException&&t instanceof DOMException)||22===t.code||20===t.code||11===t.code))throw t;O("Error using user provided cache. Falling back to memory cache: "+t),await an(e,new n8)}}else I(ar,"Using default OfflineComponentProvider"),await an(e,new n7(void 0));return e._offlineComponents}async function ao(e){return e._onlineComponents||(e._uninitializedComponentsProvider?(I(ar,"Using user provided OnlineComponentProvider"),await aa(e,e._uninitializedComponentsProvider._online)):(I(ar,"Using default OnlineComponentProvider"),await aa(e,new ae))),e._onlineComponents}async function al(e){let t=await ao(e),r=t.eventManager;return r.onListen=nB.bind(null,t.syncEngine),r.onUnlisten=nK.bind(null,t.syncEngine),r.onFirstRemoteStoreListen=nV.bind(null,t.syncEngine),r.onLastRemoteStoreUnlisten=nH.bind(null,t.syncEngine),r}function au(e){let t={};return void 0!==e.timeoutSeconds&&(t.timeoutSeconds=e.timeoutSeconds),t}let ac=new Map,ah="firestore.googleapis.com";class ad{constructor(e){if(void 0===e.host){if(void 0!==e.ssl)throw new z(D.INVALID_ARGUMENT,"Can't provide ssl option if host option is not set");this.host=ah,this.ssl=!0}else this.host=e.host,this.ssl=e.ssl??!0;if(this.isUsingEmulator=void 0!==e.emulatorOptions,this.credentials=e.credentials,this.ignoreUndefinedProperties=!!e.ignoreUndefinedProperties,this.localCache=e.localCache,void 0===e.cacheSizeBytes)this.cacheSizeBytes=0x2800000;else{if(-1!==e.cacheSizeBytes&&e.cacheSizeBytes<1048576)throw new z(D.INVALID_ARGUMENT,"cacheSizeBytes must be at least 1048576");this.cacheSizeBytes=e.cacheSizeBytes}(function(e,t,r,i){if(!0===t&&!0===i)throw new z(D.INVALID_ARGUMENT,`${e} and ${r} cannot be used together.`)})("experimentalForceLongPolling",e.experimentalForceLongPolling,"experimentalAutoDetectLongPolling",e.experimentalAutoDetectLongPolling),this.experimentalForceLongPolling=!!e.experimentalForceLongPolling,this.experimentalForceLongPolling?this.experimentalAutoDetectLongPolling=!1:void 0===e.experimentalAutoDetectLongPolling?this.experimentalAutoDetectLongPolling=!0:this.experimentalAutoDetectLongPolling=!!e.experimentalAutoDetectLongPolling,this.experimentalLongPollingOptions=au(e.experimentalLongPollingOptions??{}),function(e){if(void 0!==e.timeoutSeconds){if(isNaN(e.timeoutSeconds))throw new z(D.INVALID_ARGUMENT,`invalid long polling timeout: ${e.timeoutSeconds} (must not be NaN)`);if(e.timeoutSeconds<5)throw new z(D.INVALID_ARGUMENT,`invalid long polling timeout: ${e.timeoutSeconds} (minimum allowed value is 5)`);if(e.timeoutSeconds>30)throw new z(D.INVALID_ARGUMENT,`invalid long polling timeout: ${e.timeoutSeconds} (maximum allowed value is 30)`)}}(this.experimentalLongPollingOptions),this.useFetchStreams=!!e.useFetchStreams}isEqual(e){var t,r;return this.host===e.host&&this.ssl===e.ssl&&this.credentials===e.credentials&&this.cacheSizeBytes===e.cacheSizeBytes&&this.experimentalForceLongPolling===e.experimentalForceLongPolling&&this.experimentalAutoDetectLongPolling===e.experimentalAutoDetectLongPolling&&(t=this.experimentalLongPollingOptions,r=e.experimentalLongPollingOptions,t.timeoutSeconds===r.timeoutSeconds)&&this.ignoreUndefinedProperties===e.ignoreUndefinedProperties&&this.useFetchStreams===e.useFetchStreams}}
11class am{constructor(e,t,r,i){this._authCredentials=e,this._appCheckCredentials=t,this._databaseId=r,this._app=i,this.type="firestore-lite",this._persistenceKey="(lite)",this._settings=new ad({}),this._settingsFrozen=!1,this._emulatorOptions={},this._terminateTask="notTerminated"}get app(){if(!this._app)throw new z(D.FAILED_PRECONDITION,"Firestore was not initialized using the Firebase SDK. 'app' is not available");return this._app}get _initialized(){return this._settingsFrozen}get _terminated(){return"notTerminated"!==this._terminateTask}_setSettings(e){if(this._settingsFrozen)throw new z(D.FAILED_PRECONDITION,"Firestore has already been started and its settings can no longer be changed. You can only modify settings before calling any other methods on a Firestore object.");this._settings=new ad(e),this._emulatorOptions=e.emulatorOptions||{},void 0!==e.credentials&&(this._authCredentials=function(e){if(!e)return new V;switch(e.type){case"firstParty":return new H(e.sessionIndex||"0",e.iamToken||null,e.authTokenFactory||null);case"provider":return e.client;default:throw new z(D.INVALID_ARGUMENT,"makeAuthCredentialsProvider failed due to invalid credential type")}}(e.credentials))}_getSettings(){return this._settings}_getEmulatorOptions(){return this._emulatorOptions}_freezeSettings(){return this._settingsFrozen=!0,this._settings}_delete(){return"notTerminated"===this._terminateTask&&(this._terminateTask=this._terminate()),this._terminateTask}async _restart(){"notTerminated"===this._terminateTask?await this._terminate():this._terminateTask="notTerminated"}toJSON(){return{app:this._app,databaseId:this._databaseId,settings:this._settings}}_terminate(){let e;return(e=ac.get(this))&&(I("ComponentProvider","Removing Datastore"),ac.delete(this),e.terminate()),Promise.resolve()}}class ag{constructor(e,t,r){this.converter=t,this._query=r,this.type="query",this.firestore=e}withConverter(e){return new ag(this.firestore,e,this._query)}}class ap{constructor(e,t,r){this.converter=t,this._key=r,this.type="document",this.firestore=e}get _path(){return this._key.path}get id(){return this._key.path.lastSegment()}get path(){return this._key.path.canonicalString()}get parent(){return new af(this.firestore,this.converter,this._key.path.popLast())}withConverter(e){return new ap(this.firestore,e,this._key)}toJSON(){return{type:ap._jsonSchemaVersion,referencePath:this._key.toString()}}static fromJSON(e,t,r){if(ed(t,ap._jsonSchema))return new ap(e,r||null,new en(et.fromString(t.referencePath)))}}ap._jsonSchemaVersion="firestore/documentReference/1.0",ap._jsonSchema={type:eh("string",ap._jsonSchemaVersion),referencePath:eh("string")};class af extends ag{constructor(e,t,r){super(e,t,tI(r)),this._path=r,this.type="collection"}get id(){return this._query.path.lastSegment()}get path(){return this._query.path.canonicalString()}get parent(){let e=this._path.popLast();return e.isEmpty()?null:new ap(this.firestore,null,new en(e))}withConverter(e){return new af(this.firestore,e,this._path)}}function ay(e,t,...r){if(e=(0,w.Ku)(e),ea("collection","path",t),e instanceof am){let i=et.fromString(t,...r);return eo(i),new af(e,null,i)}{if(!(e instanceof ap||e instanceof af))throw new z(D.INVALID_ARGUMENT,"Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore");let i=e._path.child(et.fromString(t,...r));return eo(i),new af(e.firestore,null,i)}}function av(e,t,...r){if(e=(0,w.Ku)(e),1==arguments.length&&(t=$.newId()),ea("doc","path",t),e instanceof am){let i=et.fromString(t,...r);return es(i),new ap(e,null,new en(i))}{if(!(e instanceof ap||e instanceof af))throw new z(D.INVALID_ARGUMENT,"Expected first argument to doc() to be a CollectionReference, a DocumentReference or FirebaseFirestore");let i=e._path.child(et.fromString(t,...r));return es(i),new ap(e.firestore,e instanceof af?e.converter:null,new en(i))}}let aw="AsyncQueue";class ab{constructor(e=Promise.resolve()){this.Yu=[],this.ec=!1,this.tc=[],this.nc=null,this.rc=!1,this.sc=!1,this.oc=[],this.M_=new iW(this,"async_queue_retry"),this._c=()=>{let e=iH();e&&I(aw,"Visibility state changed to "+e.visibilityState),this.M_.w_()},this.ac=e;const t=iH();t&&"function"==typeof t.addEventListener&&t.addEventListener("visibilitychange",this._c)}get isShuttingDown(){return this.ec}enqueueAndForget(e){this.enqueue(e)}enqueueAndForgetEvenWhileRestricted(e){this.uc(),this.cc(e)}enterRestrictedMode(e){if(!this.ec){this.ec=!0,this.sc=e||!1;let t=iH();t&&"function"==typeof t.removeEventListener&&t.removeEventListener("visibilitychange",this._c)}}enqueue(e){if(this.uc(),this.ec)return new Promise(()=>{});let t=new U;return this.cc(()=>this.ec&&this.sc?Promise.resolve():(e().then(t.resolve,t.reject),t.promise)).then(()=>t.promise)}enqueueRetryable(e){this.enqueueAndForget(()=>(this.Yu.push(e),this.lc()))}async lc(){if(0!==this.Yu.length){try{await this.Yu[0](),this.Yu.shift(),this.M_.reset()}catch(e){if(!eb(e))throw e;I(aw,"Operation failed with retryable error: "+e)}this.Yu.length>0&&this.M_.p_(()=>this.lc())}}cc(e){let t=this.ac.then(()=>(this.rc=!0,e().catch(e=>{throw this.nc=e,this.rc=!1,x("INTERNAL UNHANDLED ERROR: ",aC(e)),e}).then(e=>(this.rc=!1,e))));return this.ac=t,t}enqueueAfterDelay(e,t,r){this.uc(),this.oc.indexOf(e)>-1&&(t=0);let i=nw.createAndSchedule(this,e,t,r,e=>this.hc(e));return this.tc.push(i),i}uc(){this.nc&&P(47125,{Pc:aC(this.nc)})}verifyOperationInProgress(){}async Tc(){let e;do e=this.ac,await e;while(e!==this.ac)}Ic(e){for(let t of this.tc)if(t.timerId===e)return!0;return!1}Ec(e){return this.Tc().then(()=>{for(let t of(this.tc.sort((e,t)=>
11e.targetTimeMs-t.targetTimeMs),this.tc))if(t.skipDelay(),"all"!==e&&t.timerId===e)break;return this.Tc()})}Rc(e){this.oc.push(e)}hc(e){let t=this.tc.indexOf(e);this.tc.splice(t,1)}}function aC(e){let t=e.message||"";return e.stack&&(t=e.stack.includes(e.message)?e.stack:e.message+"\n"+e.stack),t}class aT extends am{constructor(e,t,r,i){super(e,t,r,i),this.type="firestore",this._queue=new ab,this._persistenceKey=i?.name||"[DEFAULT]"}async _terminate(){if(this._firestoreClient){let e=this._firestoreClient.terminate();this._queue=new ab(e),this._firestoreClient=void 0,await e}}}function aS(e,t){let r="object"==typeof e?e:(0,y.Sx)(),i=(0,y.j6)(r,"firestore").getImmediate({identifier:"string"==typeof e?e:t||eq});if(!i._initialized){let e=(0,w.yU)("firestore");e&&function(e,t,r,i={}){e=ec(e,am);let n=(0,w.zJ)(t),a=e._getSettings(),s={...a,emulatorOptions:e._getEmulatorOptions()},o=`${t}:${r}`;n&&((0,w.gE)(`https://${o}`),(0,w.P1)("Firestore",!0)),a.host!==ah&&a.host!==o&&O("Host has been set in both settings() and connectFirestoreEmulator(), emulator host will be used.");let l={...a,host:o,ssl:n,emulatorOptions:i};if(!(0,w.bD)(l,s)&&(e._setSettings(l),i.mockUserToken)){let t,r;if("string"==typeof i.mockUserToken)t=i.mockUserToken,r=E.MOCK_USER;else{t=(0,w.Fy)(i.mockUserToken,e._app?.options.projectId);let n=i.mockUserToken.sub||i.mockUserToken.user_id;if(!n)throw new z(D.INVALID_ARGUMENT,"mockUserToken must contain 'sub' or 'user_id' field!");r=new E(n)}e._authCredentials=new j(new B(t,r))}}(i,...e)}return i}function aF(e){if(e._terminated)throw new z(D.FAILED_PRECONDITION,"The client has already been terminated.");return e._firestoreClient||function(e){var t,r,i,n,a;let s,o=e._freezeSettings(),l=(t=e._databaseId,r=e._app?.options.appId||"",i=e._persistenceKey,n=e._app?.options.apiKey,new eH(t,r,i,o.host,o.ssl,o.experimentalForceLongPolling,o.experimentalAutoDetectLongPolling,au(o.experimentalLongPollingOptions),o.useFetchStreams,o.isUsingEmulator,n));e._componentsProvider||o.localCache?._offlineComponentProvider&&o.localCache?._onlineComponentProvider&&(e._componentsProvider={_offline:o.localCache._offlineComponentProvider,_online:o.localCache._onlineComponentProvider}),e._firestoreClient=new ai(e._authCredentials,e._appCheckCredentials,e._queue,l,e._componentsProvider&&(a=e._componentsProvider,s=a?._online.build(),{_offline:a?._offline.build(s),_online:s}))}(e),e._firestoreClient}class ak{constructor(e){this._byteString=e}static fromBase64String(e){try{return new ak(eM.fromBase64String(e))}catch(e){throw new z(D.INVALID_ARGUMENT,"Failed to construct data from Base64 string: "+e)}}static fromUint8Array(e){return new ak(eM.fromUint8Array(e))}toBase64(){return this._byteString.toBase64()}toUint8Array(){return this._byteString.toUint8Array()}toString(){return"Bytes(base64: "+this.toBase64()+")"}isEqual(e){return this._byteString.isEqual(e._byteString)}toJSON(){return{type:ak._jsonSchemaVersion,bytes:this.toBase64()}}static fromJSON(e){if(ed(e,ak._jsonSchema))return ak.fromBase64String(e.bytes)}}ak._jsonSchemaVersion="firestore/bytes/1.0",ak._jsonSchema={type:eh("string",ak._jsonSchemaVersion),bytes:eh("string")};class aE{constructor(...e){for(let t=0;t<e.length;++t)if(0===e[t].length)throw new z(D.INVALID_ARGUMENT,"Invalid field name at argument $(i + 1). Field names must not be empty.");this._internalPath=new ei(e)}isEqual(e){return this._internalPath.isEqual(e._internalPath)}}class aA{constructor(e){this._methodName=e}}class a_{constructor(e,t){if(!isFinite(e)||e<-90||e>90)throw new z(D.INVALID_ARGUMENT,"Latitude must be a number between -90 and 90, but was: "+e);if(!isFinite(t)||t<-180||t>180)throw new z(D.INVALID_ARGUMENT,"Longitude must be a number between -180 and 180, but was: "+t);this._lat=e,this._long=t}get latitude(){return this._lat}get longitude(){return this._long}isEqual(e){return this._lat===e._lat&&this._long===e._long}_compareTo(e){return Y(this._lat,e._lat)||Y(this._long,e._long)}toJSON(){return{latitude:this._lat,longitude:this._long,type:a_._jsonSchemaVersion}}static fromJSON(e){if(ed(e,a_._jsonSchema))return new a_(e.latitude,e.longitude)}}a_._jsonSchemaVersion="firestore/geoPoint/1.0",a_._jsonSchema={type:eh("string",a_._jsonSchemaVersion),latitude:eh("number"),longitude:eh("number")};class aR{constructor(e){this._values=(e||[]).map(e=>e)}toArray(){return this._values.map(e=>e)}isEqual(e){return function(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;++r)if(e[r]!==t[r])return!1;return!0}(this._values,e._values)}toJSON(){return{type:aR._jsonSchemaVersion,vectorValues:this._values}}
11static fromJSON(e){if(ed(e,aR._jsonSchema)){if(Array.isArray(e.vectorValues)&&e.vectorValues.every(e=>"number"==typeof e))return new aR(e.vectorValues);throw new z(D.INVALID_ARGUMENT,"Expected 'vectorValues' field to be a number array")}}}aR._jsonSchemaVersion="firestore/vectorValue/1.0",aR._jsonSchema={type:eh("string",aR._jsonSchemaVersion),vectorValues:eh("object")};let aI=/^__.*__$/;class ax{constructor(e,t,r){this.data=e,this.fieldMask=t,this.fieldTransforms=r}toMutation(e,t){return null!==this.fieldMask?new ru(e,this.data,this.fieldMask,t,this.fieldTransforms):new rl(e,this.data,t,this.fieldTransforms)}}function aO(e){switch(e){case 0:case 2:case 1:return!0;case 3:case 4:return!1;default:throw P(40011,{dataSource:e})}}class aM{constructor(e,t,r,i,n,a){this.settings=e,this.databaseId=t,this.serializer=r,this.ignoreUndefinedProperties=i,void 0===n&&this.validatePath(),this.fieldTransforms=n||[],this.fieldMask=a||[]}get path(){return this.settings.path}get dataSource(){return this.settings.dataSource}contextWith(e){return new aM({...this.settings,...e},this.databaseId,this.serializer,this.ignoreUndefinedProperties,this.fieldTransforms,this.fieldMask)}childContextForField(e){let t=this.path?.child(e),r=this.contextWith({path:t,arrayElement:!1});return r.validatePathSegment(e),r}childContextForFieldPath(e){let t=this.path?.child(e),r=this.contextWith({path:t,arrayElement:!1});return r.validatePath(),r}childContextForArray(e){return this.contextWith({path:void 0,arrayElement:!0})}createError(e){return aK(e,this.settings.methodName,this.settings.hasConverter||!1,this.path,this.settings.targetDoc)}contains(e){return void 0!==this.fieldMask.find(t=>e.isPrefixOf(t))||void 0!==this.fieldTransforms.find(t=>e.isPrefixOf(t.field))}validatePath(){if(this.path)for(let e=0;e<this.path.length;e++)this.validatePathSegment(this.path.get(e))}validatePathSegment(e){if(0===e.length)throw this.createError("Document fields must not be empty");if(aO(this.dataSource)&&aI.test(e))throw this.createError('Document fields cannot begin and end with "__"')}}class aP{constructor(e,t,r){this.databaseId=e,this.ignoreUndefinedProperties=t,this.serializer=r||iq(e)}createContext(e,t,r,i=!1){return new aM({dataSource:e,methodName:t,targetDoc:r,path:ei.emptyPath(),arrayElement:!1,hasConverter:i},this.databaseId,this.serializer,this.ignoreUndefinedProperties)}}function aL(e){let t=e._freezeSettings(),r=iq(e._databaseId);return new aP(e._databaseId,!!t.ignoreUndefinedProperties,r)}function aN(e,t,r,i,n,a={}){let s,o,l=e.createContext(a.merge||a.mergeFields?2:0,t,r,n);aV("Data must be an object, but it was:",l,i);let u=aU(i,l);if(a.merge)s=new ex(l.fieldMask),o=l.fieldTransforms;else if(a.mergeFields){let e=[];for(let i of a.mergeFields){let n=aj(t,i,r);if(!l.contains(n))throw new z(D.INVALID_ARGUMENT,`Field '${n}' is specified in your field mask but missing from your input data.`);(function(e,t){return e.some(e=>e.isEqual(t))})(e,n)||e.push(n)}s=new ex(e),o=l.fieldTransforms.filter(e=>s.covers(e.field))}else s=null,o=l.fieldTransforms;return new ax(new ta(u),s,o)}class aD extends aA{_toFieldTransform(e){return new re(e.path,new t2)}isEqual(e){return e instanceof aD}}function az(e,t){if(aB(e=(0,w.Ku)(e)))return aV("Unsupported field value:",t,e),aU(e,t);if(e instanceof aA)return function(e,t){if(!aO(t.dataSource))throw t.createError(`${e._methodName}() can only be used with update() and set()`);if(!t.path)throw t.createError(`${e._methodName}() is not currently supported inside arrays`);let r=e._toFieldTransform(t);r&&t.fieldTransforms.push(r)}(e,t),null;if(void 0===e&&t.ignoreUndefinedProperties)return null;if(t.path&&t.fieldMask.push(t.path),e instanceof Array){if(t.settings.arrayElement&&4!==t.dataSource)throw t.createError("Nested arrays are not supported");let r=[],i=0;for(let n of e){let e=az(n,t.childContextForArray(i));null==e&&(e={nullValue:"NULL_VALUE"}),r.push(e),i++}return{arrayValue:{values:r}}}return function(e,t){var r,i,n,a;if(null===(e=(0,w.Ku)(e)))return{nullValue:"NULL_VALUE"};if("number"==typeof e)return r=t.serializer,"number"==typeof(n=i=e)&&Number.isInteger(n)&&!eT(n)&&n<=Number.MAX_SAFE_INTEGER&&n>=Number.MIN_SAFE_INTEGER?tZ(i):tX(r,i);if("boolean"==typeof e)return{booleanValue:e};if("string"==typeof e)return{stringValue:e};if(e instanceof Date){let r=em.fromDate(e);return{timestampValue:rU(t.serializer,r)}}if(e instanceof em){let r=new em(e.seconds,1e3*Math.floor(e.nanoseconds/1e3));return{timestampValue:rU(t.serializer,r)}}if(e instanceof a_)return{geoPointValue:{latitude:e.latitude,longitude:e.longitude}};if(e instanceof ak)return{bytesValue:rB(t.serializer,e._byteString)};if(e instanceof ap){let r=t.databaseId,i=e.firestore._databaseId;if(!i.isEqual(r))throw t.createError(`Document reference is for database ${i.projectId}/${i.database} but should be for database ${r.projectId}/${r.database}`);return{referenceValue:rj(e.firestore._databaseId||t.databaseId,e._key.path)}}if(e instanceof aR)return{mapValue:{fields:{[e$]:{stringValue:eQ},[eX]:{arrayValue:{values:((a=e)instanceof aR?a.toArray():a).map(e=>{if("number"!=typeof e)throw t.createError("VectorValues must only contain numeric values.");return tX(t.serializer,e)})}}}}};if(r0(e))return e._toProto(t.serializer);throw t.createError(`Unsupported field value: ${eu(e)}`)}(e,t)}function aU(e,t){let r={};return ek(e)?t.path&&t.path.length>0&&t.fieldMask.push(t.path):eF(e,(e,i)=>{let n=az(i,t.childContextForField(e));null!=n&&(r[e]=n)}),{mapValue:{fields:r}}}function aB(e){return!("object"!=typeof e||null===e||e instanceof Array||e instanceof Date||e instanceof em||e instanceof a_||e instanceof ak||e instanceof ap||e instanceof aA||e instanceof aR||r0(e))}function aV(e,t,r){if(!aB(r)||!el(r)){let i=eu(r);throw"an object"===i?t.createError(e+" a custom object"):t.createError(e+" "+i)}}function aj(e,t,r){if((t=(0,w.Ku)(t))instanceof aE)return t._internalPath;if("string"==typeof t){var i=e,n=t;if(n.search(aG)>=0)throw aK(`Invalid field path (${n}). Paths must not contain '~', '*', '/', '[', or ']'`,i,!1,void 0,void 0);try{return new aE(...n.split("."))._internalPath}catch(e){throw aK(`Invalid field path (${n}). Paths must not be empty, begin with '.', end with '.', or contain '..'`,i,!1,void 0,void 0)}}throw aK("Field path arguments must be of type string or ",e,!1,void 0,r)}let aG=RegExp("[~\\*/\\[\\]]");function aK(e,t,r,i,n){let a=i&&!i.isEmpty(),s=void 0!==n,o=`Function ${t}
11() called with invalid data`;r&&(o+=" (via `toFirestore()`)"),o+=". ";let l="";return(a||s)&&(l+=" (found",a&&(l+=` in field ${i}`),s&&(l+=` in document ${n}`),l+=")"),new z(D.INVALID_ARGUMENT,o+e+l)}class aH{convertValue(e,t="none"){switch(eZ(e)){case 0:return null;case 1:return e.booleanValue;case 2:return eN(e.integerValue||e.doubleValue);case 3:return this.convertTimestamp(e.timestampValue);case 4:return this.convertServerTimestamp(e,t);case 5:return e.stringValue;case 6:return this.convertBytes(eD(e.bytesValue));case 7:return this.convertReference(e.referenceValue);case 8:return this.convertGeoPoint(e.geoPointValue);case 9:return this.convertArray(e.arrayValue,t);case 11:return this.convertObject(e.mapValue,t);case 10:return this.convertVectorValue(e.mapValue);default:throw P(62114,{value:e})}}convertObject(e,t){return this.convertObjectMap(e.fields,t)}convertObjectMap(e,t="none"){let r={};return eF(e,(e,i)=>{r[e]=this.convertValue(i,t)}),r}convertVectorValue(e){return new aR(e.fields?.[eX].arrayValue?.values?.map(e=>eN(e.doubleValue)))}convertGeoPoint(e){return new a_(eN(e.latitude),eN(e.longitude))}convertArray(e,t){return(e.values||[]).map(e=>this.convertValue(e,t))}convertServerTimestamp(e,t){switch(t){case"previous":let r=eG(e);return null==r?null:this.convertValue(r,t);case"estimate":return this.convertTimestamp(eK(e));default:return null}}convertTimestamp(e){let t=eL(e);return new em(t.seconds,t.nanos)}convertDocumentKey(e,t){let r=et.fromString(e);N(rZ(r),9688,{name:e});let i=new eW(r.get(1),r.get(3)),n=new en(r.popFirst(5));return i.isEqual(t)||x(`Document ${n} contains a document reference within a different database (${i.projectId}/${i.database}) which is not supported. It will be treated as a reference in the current database (${t.projectId}/${t.database}) instead.`),n}}class aq extends aH{constructor(e){super(),this.firestore=e}convertBytes(e){return new ak(e)}convertReference(e){let t=this.convertDocumentKey(e,this.firestore._databaseId);return new ap(this.firestore,null,t)}}function aW(){return new aD("serverTimestamp")}let a$="@firebase/firestore",aY="4.11.0";function aJ(e){if("object"!=typeof e||null===e)return!1;for(let t of["next","error","complete"])if(t in e&&"function"==typeof e[t])return!0;return!1}class aQ{constructor(e,t,r,i,n){this._firestore=e,this._userDataWriter=t,this._key=r,this._document=i,this._converter=n}get id(){return this._key.path.lastSegment()}get ref(){return new ap(this._firestore,this._converter,this._key)}exists(){return null!==this._document}data(){if(this._document){if(this._converter){let e=new aX(this._firestore,this._userDataWriter,this._key,this._document,null);return this._converter.fromFirestore(e)}return this._userDataWriter.convertValue(this._document.data.value)}}_fieldsProto(){return this._document?.data.clone().value.mapValue.fields??void 0}get(e){if(this._document){let t=this._document.data.field(aj("DocumentSnapshot.get",e));if(null!==t)return this._userDataWriter.convertValue(t)}}}class aX extends aQ{data(){return super.data()}}function aZ(e){if("L"===e.limitType&&0===e.explicitOrderBy.length)throw new z(D.UNIMPLEMENTED,"limitToLast() queries require specifying at least one orderBy() clause")}class a0{}class a1 extends a0{}function a2(e,t,...r){let i=[];for(let n of(t instanceof a0&&i.push(t),function(e){let t=e.filter(e=>e instanceof a5).length,r=e.filter(e=>e instanceof a3).length;if(t>1||t>0&&r>0)throw new z(D.INVALID_ARGUMENT,"InvalidQuery. When using composite filters, you cannot use more than one filter at the top level. Consider nesting the multiple filters within an `and(...)` statement. For example: change `query(query, where(...), or(...))` to `query(query, and(where(...), or(...)))`.")}(i=i.concat(r)),i))e=n._apply(e);return e}class a3 extends a1{constructor(e,t,r){super(),this._field=e,this._op=t,this._value=r,this.type="where"}static _create(e,t,r){return new a3(e,t,r)}_apply(e){let t=this._parse(e);return sr(e._query,t),new ag(e.firestore,e.converter,tL(e._query,t))}_parse(e){let t=aL(e.firestore);return function(e,t,r,i,n,a,s){let o;
11if(n.isKeyField()){if("array-contains"===a||"array-contains-any"===a)throw new z(D.INVALID_ARGUMENT,`Invalid Query. You can't perform '${a}' queries on documentId().`);if("in"===a||"not-in"===a){st(s,a);let t=[];for(let r of s)t.push(se(i,e,r));o={arrayValue:{values:t}}}else o=se(i,e,s)}else"in"!==a&&"not-in"!==a&&"array-contains-any"!==a||st(s,a),o=function(e,t,r,i=!1){return az(r,e.createContext(i?4:3,t))}(r,t,s,"in"===a||"not-in"===a);return td.create(n,a,o)}(e._query,"where",t,e.firestore._databaseId,this._field,this._op,this._value)}}function a4(e,t,r){let i=aj("where",e);return a3._create(i,t,r)}class a5 extends a0{constructor(e,t){super(),this.type=e,this._queryConstraints=t}static _create(e,t){return new a5(e,t)}_parse(e){let t=this._queryConstraints.map(t=>t._parse(e)).filter(e=>e.getFilters().length>0);return 1===t.length?t[0]:tm.create(t,this._getOperator())}_apply(e){let t=this._parse(e);return 0===t.getFilters().length?e:(function(e,t){let r=e;for(let e of t.getFlattenedFilters())sr(r,e),r=tL(r,e)}(e._query,t),new ag(e.firestore,e.converter,tL(e._query,t)))}_getQueryConstraints(){return this._queryConstraints}_getOperator(){return"and"===this.type?"and":"or"}}class a9 extends a1{constructor(e,t){super(),this._field=e,this._direction=t,this.type="orderBy"}static _create(e,t){return new a9(e,t)}_apply(e){var t;let r,i=function(e,t,r){if(null!==e.startAt)throw new z(D.INVALID_ARGUMENT,"Invalid query. You must not call startAt() or startAfter() before calling orderBy().");if(null!==e.endAt)throw new z(D.INVALID_ARGUMENT,"Invalid query. You must not call endAt() or endBefore() before calling orderBy().");return new tc(t,r)}(e._query,this._field,this._direction);return new ag(e.firestore,e.converter,(t=e._query,r=t.explicitOrderBy.concat([i]),new tR(t.path,t.collectionGroup,r,t.filters.slice(),t.limit,t.limitType,t.startAt,t.endAt)))}}function a6(e,t="asc"){let r=aj("orderBy",e);return a9._create(r,t)}class a8 extends a1{constructor(e,t,r){super(),this.type=e,this._limit=t,this._limitType=r}static _create(e,t,r){return new a8(e,t,r)}_apply(e){return new ag(e.firestore,e.converter,tN(e._query,this._limit,this._limitType))}}function a7(e){return function(e,t){if(t<=0)throw new z(D.INVALID_ARGUMENT,`Function ${e}() requires a positive number, but it was: ${t}.`)}("limit",e),a8._create("limit",e,"F")}function se(e,t,r){if("string"==typeof(r=(0,w.Ku)(r))){if(""===r)throw new z(D.INVALID_ARGUMENT,"Invalid query. When querying with documentId(), you must provide a valid document ID, but it was an empty string.");if(!tO(t)&&-1!==r.indexOf("/"))throw new z(D.INVALID_ARGUMENT,`Invalid query. When querying a collection by documentId(), you must provide a plain document ID, but '${r}' contains a '/' character.`);let i=t.path.child(et.fromString(r));if(!en.isDocumentKey(i))throw new z(D.INVALID_ARGUMENT,`Invalid query. When querying a collection group by documentId(), the value provided must result in a valid document path, but '${i}' is not because it has an odd number of segments (${i.length}).`);return e9(e,new en(i))}if(r instanceof ap)return e9(e,r._key);throw new z(D.INVALID_ARGUMENT,`Invalid query. When querying with documentId(), you must provide a valid string or a DocumentReference, but it was: ${eu(r)}.`)}function st(e,t){if(!Array.isArray(e)||0===e.length)throw new z(D.INVALID_ARGUMENT,`Invalid Query. A non-empty array is required for '${t.toString()}' filters.`)}function sr(e,t){let r=function(e,t){for(let r of e)for(let e of r.getFlattenedFilters())if(t.indexOf(e.op)>=0)return e.op;return null}(e.filters,function(e){switch(e){case"!=":return["!=","not-in"];case"array-contains-any":case"in":return["not-in"];case"not-in":return["array-contains-any","in","not-in","!="];default:return[]}}(t.op));if(null!==r)throw r===t.op?new z(D.INVALID_ARGUMENT,`Invalid query. You cannot use more than one '${t.op.toString()}' filter.`):new z(D.INVALID_ARGUMENT,`Invalid query. You cannot use '${t.op.toString()}' filters with '${r.toString()}' filters.`)}function si(e,t,r){return e?r&&(r.merge||r.mergeFields)?e.toFirestore(t,r):e.toFirestore(t):t}class sn{constructor(e,t){this.hasPendingWrites=e,this.fromCache=t}isEqual(e){return this.hasPendingWrites===e.hasPendingWrites&&this.fromCache===e.fromCache}}class sa extends aQ{constructor(e,t,r,i,n,a){super(e,t,r,i,a),this._firestore=e,this._firestoreImpl=e,this.metadata=n}exists(){return super.exists()}data(e={}){if(this._document){if(this._converter){let t=new ss(this._firestore,this._userDataWriter,this._key,this._document,this.metadata,null);return this._converter.fromFirestore(t,e)}return this._userDataWriter.convertValue(this._document.data.value,e.serverTimestamps)}}get(e,t={}){if(this._document){let r=this._document.data.field(aj("DocumentSnapshot.get",e));if(null!==r)return this._userDataWriter.convertValue(r,t.serverTimestamps)}}toJSON(){if(this.metadata.hasPendingWrites)throw new z(D.FAILED_PRECONDITION,"DocumentSnapshot.toJSON() attempted to serialize a document with pending writes. Await waitForPendingWrites() before invoking toJSON().");let e=this._document,t={};return t.type=sa._jsonSchemaVersion,t.bundle="",t.bundleSource="DocumentSnapshot",t.bundleName=this._key.toString(),e&&e.isValidDocument()&&e.isFoundDocument()&&
11(this._userDataWriter.convertObjectMap(e.data.value.mapValue.fields,"previous"),this._firestore,this.ref.path,t.bundle="NOT SUPPORTED"),t}}sa._jsonSchemaVersion="firestore/documentSnapshot/1.0",sa._jsonSchema={type:eh("string",sa._jsonSchemaVersion),bundleSource:eh("string","DocumentSnapshot"),bundleName:eh("string"),bundle:eh("string")};class ss extends sa{data(e={}){return super.data(e)}}class so{constructor(e,t,r,i){this._firestore=e,this._userDataWriter=t,this._snapshot=i,this.metadata=new sn(i.hasPendingWrites,i.fromCache),this.query=r}get docs(){let e=[];return this.forEach(t=>e.push(t)),e}get size(){return this._snapshot.docs.size}get empty(){return 0===this.size}forEach(e,t){this._snapshot.docs.forEach(r=>{e.call(t,new ss(this._firestore,this._userDataWriter,r.key,r,new sn(this._snapshot.mutatedKeys.has(r.key),this._snapshot.fromCache),this.query.converter))})}docChanges(e={}){let t=!!e.includeMetadataChanges;if(t&&this._snapshot.excludesMetadataChanges)throw new z(D.INVALID_ARGUMENT,"To include metadata changes with your document changes, you must also pass { includeMetadataChanges:true } to onSnapshot().");return this._cachedChanges&&this._cachedChangesIncludeMetadataChanges===t||(this._cachedChanges=function(e,t){if(e._snapshot.oldDocs.isEmpty()){let t=0;return e._snapshot.docChanges.map(r=>{let i=new ss(e._firestore,e._userDataWriter,r.doc.key,r.doc,new sn(e._snapshot.mutatedKeys.has(r.doc.key),e._snapshot.fromCache),e.query.converter);return r.doc,{type:"added",doc:i,oldIndex:-1,newIndex:t++}})}{let r=e._snapshot.oldDocs;return e._snapshot.docChanges.filter(e=>t||3!==e.type).map(t=>{let i=new ss(e._firestore,e._userDataWriter,t.doc.key,t.doc,new sn(e._snapshot.mutatedKeys.has(t.doc.key),e._snapshot.fromCache),e.query.converter),n=-1,a=-1;return 0!==t.type&&(n=r.indexOf(t.doc.key),r=r.delete(t.doc.key)),1!==t.type&&(a=(r=r.add(t.doc)).indexOf(t.doc.key)),{type:function(e){switch(e){case 0:return"added";case 2:case 3:return"modified";case 1:return"removed";default:return P(61501,{type:e})}}(t.type),doc:i,oldIndex:n,newIndex:a}})}}(this,t),this._cachedChangesIncludeMetadataChanges=t),this._cachedChanges}toJSON(){if(this.metadata.hasPendingWrites)throw new z(D.FAILED_PRECONDITION,"QuerySnapshot.toJSON() attempted to serialize a document with pending writes. Await waitForPendingWrites() before invoking toJSON().");let e={};e.type=so._jsonSchemaVersion,e.bundleSource="QuerySnapshot",e.bundleName=$.newId(),this._firestore._databaseId.database,this._firestore._databaseId.projectId;let t=[],r=[],i=[];return this.docs.forEach(e=>{null!==e._document&&(t.push(e._document),r.push(this._userDataWriter.convertObjectMap(e._document.data.value.mapValue.fields,"previous")),i.push(e.ref.path))}),this._firestore,this.query._query,e.bundleName,e.bundle="NOT SUPPORTED",e}}function sl(e){e=ec(e,ap);let t=ec(e.firestore,aT);return(function(e,t,r={}){let i=new U;return e.asyncQueue.enqueueAndForget(async()=>{var n,a;let s,o;return n=await al(e),a=e.asyncQueue,s=new at({next:e=>{s.Nu(),a.enqueueAndForget(()=>n_(n,o));let l=e.docs.has(t);!l&&e.fromCache?i.reject(new z(D.UNAVAILABLE,"Failed to get document because the client is offline.")):l&&e.fromCache&&r&&"server"===r.source?i.reject(new z(D.UNAVAILABLE,'Failed to get document from server. (However, this document does exist in the local cache. Run again without setting source to "server" to retrieve the cached document.)')):i.resolve(e)},error:e=>i.reject(e)}),nA(n,o=new nO(tI(t.path),s,{includeMetadataChanges:!0,Ka:!0}))}),i.promise})(aF(t),e._key).then(r=>sg(t,e,r))}function su(e){e=ec(e,ag);let t=ec(e.firestore,aT),r=aF(t),i=new aq(t);return aZ(e._query),(function(e,t,r={}){let i=new U;return e.asyncQueue.enqueueAndForget(async()=>{var n,a;let s,o;return n=await al(e),a=e.asyncQueue,o=new nO(t,s=new at({next:e=>{s.Nu(),a.enqueueAndForget(()=>n_(n,o)),e.fromCache&&"server"===r.source?i.reject(new z(D.UNAVAILABLE,'Failed to get documents from server. (However, these documents may exist in the local cache. Run again without setting source to "server" to retrieve the cached documents.)')):i.resolve(e)},error:e=>i.reject(e)}),{includeMetadataChanges:!0,Ka:!0}),nA(n,o)}),i.promise})(r,e._query).then(r=>new so(t,i,e,r))}function sc(e,t,r){e=ec(e,ap);let i=ec(e.firestore,aT),n=si(e.converter,t,r),a=aL(i);return sm(i,[aN(a,"setDoc",e._key,n,null!==e.converter,r).toMutation(e._key,rr.none())])}function sh(e,t){let r=ec(e.firestore,aT),i=av(e),n=si(e.converter,t);
11return sm(r,[aN(aL(e.firestore),"addDoc",i._key,n,null!==e.converter,{}).toMutation(i._key,rr.exists(!1))]).then(()=>i)}function sd(e,...t){var r;let i,n,a,s,o;e=(0,w.Ku)(e);let l={includeMetadataChanges:!1,source:"default"},u=0;"object"!=typeof t[0]||aJ(t[u])||(l=t[u++]);let c={includeMetadataChanges:l.includeMetadataChanges,source:l.source};if(aJ(t[u])){let e=t[u];t[u]=e.next?.bind(e),t[u+1]=e.error?.bind(e),t[u+2]=e.complete?.bind(e)}if(e instanceof ap)n=ec(e.firestore,aT),a=tI(e._key.path),i={next:r=>{t[u]&&t[u](sg(n,e,r))},error:t[u+1],complete:t[u+2]};else{let r=ec(e,ag);n=ec(r.firestore,aT),a=r._query;let s=new aq(n);i={next:e=>{t[u]&&t[u](new so(n,s,r,e))},error:t[u+1],complete:t[u+2]},aZ(e._query)}return r=aF(n),o=new nO(a,s=new at(i),c),r.asyncQueue.enqueueAndForget(async()=>nA(await al(r),o)),()=>{s.Nu(),r.asyncQueue.enqueueAndForget(async()=>n_(await al(r),o))}}function sm(e,t){var r;let i;return r=aF(e),i=new U,r.asyncQueue.enqueueAndForget(async()=>nq(await ao(r).then(e=>e.syncEngine),t,i)),i.promise}function sg(e,t,r){let i=r.docs.get(t._key),n=new aq(e);return new sa(e,n,t._key,i,new sn(r.hasPendingWrites,r.fromCache),t.converter)}so._jsonSchemaVersion="firestore/querySnapshot/1.0",so._jsonSchema={type:eh("string",so._jsonSchemaVersion),bundleSource:eh("string","QuerySnapshot"),bundleName:eh("string"),bundle:eh("string")},new WeakMap,function(e=!0){A=y.MF,(0,y.om)(new v.uA("firestore",(t,{instanceIdentifier:r,options:i})=>{let n=t.getProvider("app").getImmediate(),a=new aT(new G(t.getProvider("auth-internal")),new W(n,t.getProvider("app-check-internal")),function(e,t){if(!Object.prototype.hasOwnProperty.apply(e.options,["projectId"]))throw new z(D.INVALID_ARGUMENT,'"projectId" not provided in firebase.initializeApp.');return new eW(e.options.projectId,t)}(n,r),n);return i={useFetchStreams:e,...i},a._setSettings(i),a},"PUBLIC").setMultipleInstances(!0)),(0,y.KO)(a$,aY,void 0),(0,y.KO)(a$,aY,"esm2020")}()},48166:(e,t,r)=>{"use strict";r.d(t,{Z:()=>h,t:()=>d});var i=r(37876),n=r(14232),a=r(19701);let s=(0,n.createContext)(),o="trains_fyi_settings",l={units:"kph",language:"en",trainColorMode:"default",version:"1.0"},u=(e,t,r)=>{if(!e||t===r)return e;let i=e;return("mph"===t&&(i=1.60934*e),"mph"===r)?Math.round(.621371*i):Math.round(i)},c=(e,t)=>null==e?"N/A":`${Math.round(e)} ${t}`,h=({children:e})=>{let[t,r]=(0,n.useState)(l);(0,n.useEffect)(()=>{try{let e=localStorage.getItem(o);if(e){let t=JSON.parse(e);r({...l,...t})}}catch(e){console.error("Error loading settings from localStorage:",e)}},[]),(0,n.useEffect)(()=>{try{localStorage.setItem(o,JSON.stringify(t))}catch(e){console.error("Error saving settings to localStorage:",e)}},[t]);let h=(e,r)=>u(e,r,t.units),d={...t,setUnits:e=>{r(t=>({...t,units:e}))},setLanguage:e=>{r(t=>({...t,language:e}))},setTrainColorMode:e=>{a.sM.some(t=>t.id===e)&&r(t=>({...t,trainColorMode:e}))},convertSpeed:h,formatSpeed:(e,r)=>c(h(e,r),t.units),convertSpeedRaw:u,formatSpeedRaw:c};return(0,i.jsx)(s.Provider,{value:d,children:e})},d=()=>{let e=(0,n.useContext)(s);if(!e)throw Error("useSettings must be used within a SettingsProvider");return e}},48230:(e,t,r)=>{e.exports=r(38377)},48477:function(e,t,r){"use strict";var i=this&&this.__rest||function(e,t){var r={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(r[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,i=Object.getOwnPropertySymbols(e);n<i.length;n++)0>t.indexOf(i[n])&&Object.prototype.propertyIsEnumerable.call(e,i[n])&&(r[i[n]]=e[i[n]]);return r},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.GoogleAnalytics=void 0;let a=n(r(73513)),s=r(13949);t.GoogleAnalytics=e=>{var t=i(e,[]);return(0,s.formatData)(a.default,t)}},56556:(e,t,r)=>{(window.__NEXT_P=window.__NEXT_P||[]).push(["/_app",function(){return r(38972)}])},57090:(e,t,r)=>{"use strict";r.d(t,{HF:()=>e3,LD:()=>e1,eJ:()=>to,B8:()=>tp,xI:()=>rI,x8:()=>t1,hg:()=>tf,J1:()=>ts,x9:()=>tl,df:()=>t0,CI:()=>ty});var i,n=r(36672),a=r(76653),s=r(29979),o=r(21610);function l(){return{"dependent-sdk-initialized-before-auth":"Another Firebase SDK was initialized and is trying to use Auth before Auth is initialized. Please be sure to call `initializeAuth` or `getAuth` before starting any other Firebase SDK."}}let u=new a.FA("auth","Firebase",l()),c=new s.Vy("@firebase/auth");function h(e,...t){c.logLevel<=s.$b.ERROR&&c.error(`Auth (${n.MF}): ${e}`,...t)}function d(e,...t){throw y(e,...t)}function m(e,...t){return y(e,...t)}function g(e,t,r){let i={...l(),[t]:r};
11return new a.FA("auth","Firebase",i).create(t,{appName:e.name})}function p(e){return g(e,"operation-not-supported-in-this-environment","Operations that alter the current user are not supported in conjunction with FirebaseServerApp")}function f(e,t,r){if(!(t instanceof r))throw r.name!==t.constructor.name&&d(e,"argument-error"),g(e,"argument-error",`Type of ${t.constructor.name} does not match expected instance.Did you pass a reference from a different Auth SDK?`)}function y(e,...t){if("string"!=typeof e){let r=t[0],i=[...t.slice(1)];return i[0]&&(i[0].appName=e.name),e._errorFactory.create(r,...i)}return u.create(e,...t)}function v(e,t,...r){if(!e)throw y(t,...r)}function w(e){let t="INTERNAL ASSERTION FAILED: "+e;throw h(t),Error(t)}function b(){return"u">typeof self&&self.location?.href||""}function C(){return"u">typeof self&&self.location?.protocol||null}class T{constructor(e,t){this.shortDelay=e,this.longDelay=t,function(e,t){e||w(t)}(t>e,"Short delay should be less than long delay!"),this.isMobile=(0,a.jZ)()||(0,a.lV)()}get(){return!("u">typeof navigator&&navigator&&"onLine"in navigator&&"boolean"==typeof navigator.onLine&&("http:"===C()||"https:"===C()||(0,a.sr)()||"connection"in navigator))||navigator.onLine?this.isMobile?this.longDelay:this.shortDelay:Math.min(5e3,this.shortDelay)}}function S(e,t){var r,i;r=e.emulator,i="Emulator should always be set here",r||w(i);let{url:n}=e.emulator;return t?`${n}${t.startsWith("/")?t.slice(1):t}`:n}class F{static initialize(e,t,r){this.fetchImpl=e,t&&(this.headersImpl=t),r&&(this.responseImpl=r)}static fetch(){return this.fetchImpl?this.fetchImpl:"u">typeof self&&"fetch"in self?self.fetch:"u">typeof globalThis&&globalThis.fetch?globalThis.fetch:"u">typeof fetch?fetch:void w("Could not find fetch implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill")}static headers(){return this.headersImpl?this.headersImpl:"u">typeof self&&"Headers"in self?self.Headers:"u">typeof globalThis&&globalThis.Headers?globalThis.Headers:"u">typeof Headers?Headers:void w("Could not find Headers implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill")}static response(){return this.responseImpl?this.responseImpl:"u">typeof self&&"Response"in self?self.Response:"u">typeof globalThis&&globalThis.Response?globalThis.Response:"u">typeof Response?Response:void w("Could not find Response implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill")}}let k={CREDENTIAL_MISMATCH:"custom-token-mismatch",MISSING_CUSTOM_TOKEN:"internal-error",INVALID_IDENTIFIER:"invalid-email",MISSING_CONTINUE_URI:"internal-error",INVALID_PASSWORD:"wrong-password",MISSING_PASSWORD:"missing-password",INVALID_LOGIN_CREDENTIALS:"invalid-credential",EMAIL_EXISTS:"email-already-in-use",PASSWORD_LOGIN_DISABLED:"operation-not-allowed",INVALID_IDP_RESPONSE:"invalid-credential",INVALID_PENDING_TOKEN:"invalid-credential",FEDERATED_USER_ID_ALREADY_LINKED:"credential-already-in-use",MISSING_REQ_TYPE:"internal-error",EMAIL_NOT_FOUND:"user-not-found",RESET_PASSWORD_EXCEED_LIMIT:"too-many-requests",EXPIRED_OOB_CODE:"expired-action-code",INVALID_OOB_CODE:"invalid-action-code",MISSING_OOB_CODE:"internal-error",CREDENTIAL_TOO_OLD_LOGIN_AGAIN:"requires-recent-login",INVALID_ID_TOKEN:"invalid-user-token",TOKEN_EXPIRED:"user-token-expired",USER_NOT_FOUND:"user-token-expired",TOO_MANY_ATTEMPTS_TRY_LATER:"too-many-requests",PASSWORD_DOES_NOT_MEET_REQUIREMENTS:"password-does-not-meet-requirements",INVALID_CODE:"invalid-verification-code",INVALID_SESSION_INFO:"invalid-verification-id",INVALID_TEMPORARY_PROOF:"invalid-credential",MISSING_SESSION_INFO:"missing-verification-id",SESSION_EXPIRED:"code-expired",MISSING_ANDROID_PACKAGE_NAME:"missing-android-pkg-name",UNAUTHORIZED_DOMAIN:"unauthorized-continue-uri",INVALID_OAUTH_CLIENT_ID:"invalid-oauth-client-id",ADMIN_ONLY_OPERATION:"admin-restricted-operation",INVALID_MFA_PENDING_CREDENTIAL:"invalid-multi-factor-session",MFA_ENROLLMENT_NOT_FOUND:"multi-factor-info-not-found",MISSING_MFA_ENROLLMENT_ID:"missing-multi-factor-info",MISSING_MFA_PENDING_CREDENTIAL:"missing-multi-factor-session",SECOND_FACTOR_EXISTS:"second-factor-already-in-use",SECOND_FACTOR_LIMIT_EXCEEDED:"maximum-second-factor-count-exceeded",BLOCKING_FUNCTION_ERROR_RESPONSE:"internal-error",RECAPTCHA_NOT_ENABLED:"recaptcha-not-enabled",MISSING_RECAPTCHA_TOKEN:"missing-rec
11aptcha-token",INVALID_RECAPTCHA_TOKEN:"invalid-recaptcha-token",INVALID_RECAPTCHA_ACTION:"invalid-recaptcha-action",MISSING_CLIENT_TYPE:"missing-client-type",MISSING_RECAPTCHA_VERSION:"missing-recaptcha-version",INVALID_RECAPTCHA_VERSION:"invalid-recaptcha-version",INVALID_REQ_TYPE:"invalid-req-type"},E=["/v1/accounts:signInWithCustomToken","/v1/accounts:signInWithEmailLink","/v1/accounts:signInWithIdp","/v1/accounts:signInWithPassword","/v1/accounts:signInWithPhoneNumber","/v1/token"],A=new T(3e4,6e4);function _(e,t){return e.tenantId&&!t.tenantId?{...t,tenantId:e.tenantId}:t}async function R(e,t,r,i,n={}){return I(e,n,async()=>{let n={},s={};i&&("GET"===t?s=i:n={body:JSON.stringify(i)});let o=(0,a.Am)({key:e.config.apiKey,...s}).slice(1),l=await e._getAdditionalHeaders();l["Content-Type"]="application/json",e.languageCode&&(l["X-Firebase-Locale"]=e.languageCode);let u={method:t,headers:l,...n};return(0,a.c1)()||(u.referrerPolicy="no-referrer"),e.emulatorConfig&&(0,a.zJ)(e.emulatorConfig.host)&&(u.credentials="include"),F.fetch()(await O(e,e.config.apiHost,r,o),u)})}async function I(e,t,r){e._canInitEmulator=!1;let i={...k,...t};try{let t=new M(e),n=await Promise.race([r(),t.promise]);t.clearNetworkTimeout();let a=await n.json();if("needConfirmation"in a)throw P(e,"account-exists-with-different-credential",a);if(n.ok&&!("errorMessage"in a))return a;{let[t,r]=(n.ok?a.errorMessage:a.error.message).split(" : ");if("FEDERATED_USER_ID_ALREADY_LINKED"===t)throw P(e,"credential-already-in-use",a);if("EMAIL_EXISTS"===t)throw P(e,"email-already-in-use",a);if("USER_DISABLED"===t)throw P(e,"user-disabled",a);let s=i[t]||t.toLowerCase().replace(/[_\s]+/g,"-");if(r)throw g(e,s,r);d(e,s)}}catch(t){if(t instanceof a.g)throw t;d(e,"network-request-failed",{message:String(t)})}}async function x(e,t,r,i,n={}){let a=await R(e,t,r,i,n);return"mfaPendingCredential"in a&&d(e,"multi-factor-auth-required",{_serverResponse:a}),a}async function O(e,t,r,i){let n=`${t}${r}?${i}`,a=e.config.emulator?S(e.config,n):`${e.config.apiScheme}://${n}`;return E.includes(r)&&(await e._persistenceManagerAvailable,"COOKIE"===e._getPersistenceType())?e._getPersistence()._getFinalTarget(a).toString():a}class M{clearNetworkTimeout(){clearTimeout(this.timer)}constructor(e){this.auth=e,this.timer=null,this.promise=new Promise((e,t)=>{this.timer=setTimeout(()=>t(m(this.auth,"network-request-failed")),A.get())})}}function P(e,t,r){let i={appName:e.name};r.email&&(i.email=r.email),r.phoneNumber&&(i.phoneNumber=r.phoneNumber);let n=m(e,t,i);return n.customData._tokenResponse=r,n}function L(e){return void 0!==e&&void 0!==e.enterprise}class N{constructor(e){if(this.siteKey="",this.recaptchaEnforcementState=[],void 0===e.recaptchaKey)throw Error("recaptchaKey undefined");this.siteKey=e.recaptchaKey.split("/")[3],this.recaptchaEnforcementState=e.recaptchaEnforcementState}getProviderEnforcementState(e){if(!this.recaptchaEnforcementState||0===this.recaptchaEnforcementState.length)return null;for(let t of this.recaptchaEnforcementState)if(t.provider&&t.provider===e)switch(t.enforcementState){case"ENFORCE":return"ENFORCE";case"AUDIT":return"AUDIT";case"OFF":return"OFF";default:return"ENFORCEMENT_STATE_UNSPECIFIED"}return null}isProviderEnabled(e){return"ENFORCE"===this.getProviderEnforcementState(e)||"AUDIT"===this.getProviderEnforcementState(e)}isAnyProviderEnabled(){return this.isProviderEnabled("EMAIL_PASSWORD_PROVIDER")||this.isProviderEnabled("PHONE_PROVIDER")}}async function D(e,t){return R(e,"GET","/v2/recaptchaConfig",_(e,t))}async function z(e,t){return R(e,"POST","/v1/accounts:delete",t)}async function U(e,t){return R(e,"POST","/v1/accounts:lookup",t)}function B(e){if(e)try{let t=new Date(Number(e));if(!isNaN(t.getTime()))return t.toUTCString()}catch(e){}}async function V(e,t=!1){let r=(0,a.Ku)(e),i=await r.getIdToken(t),n=G(i);v(n&&n.exp&&n.auth_time&&n.iat,r.auth,"internal-error");let s="object"==typeof n.firebase?n.firebase:void 0,o=s?.sign_in_provider;return{claims:n,token:i,authTime:B(j(n.auth_time)),issuedAtTime:B(j(n.iat)),expirationTime:B(j(n.exp)),signInProvider:o||null,signInSecondFactor:s?.sign_in_second_factor||null}}function j(e){return 1e3*Number(e)}function G(e){let[t,r,i]=e.split(".");if(void 0===t||void 0===r||void 0===i)return h("JWT malformed, contained fewer than 3 sections"),null;try{let e=(0,a.u)(r);if(!e)return h("Failed to decode base64 JWT payload"),null;return JSON.parse(e)}catch(e){return h("Caught error parsing JWT payload as JSON",e?.toString()),null}}function K(e){let t=G(e);return v(t,"internal-error"),v(void 0!==t.exp,"internal-error"),v(void 0!==t.iat,"internal-error"),Number(t.exp)-Number(t.iat)}async function H(e,t,r=!1){if(r)return t;try{return await t}catch(t){throw t instanceof a.g&&function({code:e}){return"auth/user-disabled"===e||"auth/user-token-expired"===e}(t)&&e.auth.currentUser===e&&await e.auth.signOut(),t}}class q{constructor(e){this.user=e,this.isRunning=!1,this.timerId=null,this.errorBackoff=3e4}_start(){this.isRunning||(this.isRunning=!0,this.schedule())}_stop(){this.isRunning&&(this.isRunning=!1,null!==this.timerId&&clearTimeout(this.timerId))}getInterval(e){if(!e)return this.errorBackoff=3e4,Math.max(0,(this.user.stsTokenManager.expirationTime??0)-Date.now()-3e5);{let e=this.errorBackoff;return this.errorBackoff=Math.min(2*this.errorBackoff,96e4),e}}schedule(e=!1){if(!this.isRunning)return;let t=this.getInterval(e);this.timerId=setTimeout(async()=>{await this.iteration()},t)}async iteration(){try{await this.user.getIdToken(!0)}catch(e){e?.code==="auth/network-request-failed"&&this.schedule(!0);return}this.schedule()}}class W{constructor(e,t){this.createdAt=e,this.lastLoginAt=t,this._initializeTime()}_initializeTime(){this.lastSignInTime=B(this.lastLoginAt),this.creationTime=B(this.createdAt)}_copy(e){this.createdAt=e.createdAt,this.lastLoginAt=e.lastLoginAt,this._initializeTime()}toJSON(){return{createdAt:this.createdAt,lastLoginAt:this.lastLoginAt}}}async function $(e){var t,r;let i=e.auth,n=await e.getIdToken(),a=await H(e,U(i,{idToken:n}));v(a?.users.length,i,"internal-error");let s=a.users[0];e._notifyReloadListener(s);let o=s.providerUserInfo?.length?J(s.providerUserInfo):[],l=(t=e.providerData,r=o,[...t.filter(e=>!r.some(t=>t.providerId===e.providerId)),...r]),u=e.isAnonymous,c=!(e.email&&s.passwordHash)&&!l?.length;Object.assign(e,{uid:s.localId,displayName:s.displayName||null,photoURL:s.photoUrl||null,email:s.email||null,emailVerified:s.emailVerified||!1,phoneNumber:s.phoneNumber||null,tenantId:s.tenantId||null,providerData:l,metadata:new W(s.createdAt,s.lastLoginAt),isAnonymous:!!u&&c})}async function Y(e){let t=(0,a.Ku)(e);await $(t),await t.auth._persistUserIfCurrent(t),t.auth._notifyListenersIfCurrent(t)}function J(e){return e.map(({providerId:e,...t})=>
11({providerId:e,uid:t.rawId||"",displayName:t.displayName||null,email:t.email||null,phoneNumber:t.phoneNumber||null,photoURL:t.photoUrl||null}))}async function Q(e,t){let r=await I(e,{},async()=>{let r=(0,a.Am)({grant_type:"refresh_token",refresh_token:t}).slice(1),{tokenApiHost:i,apiKey:n}=e.config,s=await O(e,i,"/v1/token",`key=${n}`),o=await e._getAdditionalHeaders();o["Content-Type"]="application/x-www-form-urlencoded";let l={method:"POST",headers:o,body:r};return e.emulatorConfig&&(0,a.zJ)(e.emulatorConfig.host)&&(l.credentials="include"),F.fetch()(s,l)});return{accessToken:r.access_token,expiresIn:r.expires_in,refreshToken:r.refresh_token}}async function X(e,t){return R(e,"POST","/v2/accounts:revokeToken",_(e,t))}class Z{constructor(){this.refreshToken=null,this.accessToken=null,this.expirationTime=null}get isExpired(){return!this.expirationTime||Date.now()>this.expirationTime-3e4}updateFromServerResponse(e){v(e.idToken,"internal-error"),v(void 0!==e.idToken,"internal-error"),v(void 0!==e.refreshToken,"internal-error");let t="expiresIn"in e&&void 0!==e.expiresIn?Number(e.expiresIn):K(e.idToken);this.updateTokensAndExpiration(e.idToken,e.refreshToken,t)}updateFromIdToken(e){v(0!==e.length,"internal-error");let t=K(e);this.updateTokensAndExpiration(e,null,t)}async getToken(e,t=!1){return t||!this.accessToken||this.isExpired?(v(this.refreshToken,e,"user-token-expired"),this.refreshToken)?(await this.refresh(e,this.refreshToken),this.accessToken):null:this.accessToken}clearRefreshToken(){this.refreshToken=null}async refresh(e,t){let{accessToken:r,refreshToken:i,expiresIn:n}=await Q(e,t);this.updateTokensAndExpiration(r,i,Number(n))}updateTokensAndExpiration(e,t,r){this.refreshToken=t||null,this.accessToken=e||null,this.expirationTime=Date.now()+1e3*r}static fromJSON(e,t){let{refreshToken:r,accessToken:i,expirationTime:n}=t,a=new Z;return r&&(v("string"==typeof r,"internal-error",{appName:e}),a.refreshToken=r),i&&(v("string"==typeof i,"internal-error",{appName:e}),a.accessToken=i),n&&(v("number"==typeof n,"internal-error",{appName:e}),a.expirationTime=n),a}toJSON(){return{refreshToken:this.refreshToken,accessToken:this.accessToken,expirationTime:this.expirationTime}}_assign(e){this.accessToken=e.accessToken,this.refreshToken=e.refreshToken,this.expirationTime=e.expirationTime}_clone(){return Object.assign(new Z,this.toJSON())}_performRefresh(){return w("not implemented")}}function ee(e,t){v("string"==typeof e||void 0===e,"internal-error",{appName:t})}class et{constructor({uid:e,auth:t,stsTokenManager:r,...i}){this.providerId="firebase",this.proactiveRefresh=new q(this),this.reloadUserInfo=null,this.reloadListener=null,this.uid=e,this.auth=t,this.stsTokenManager=r,this.accessToken=r.accessToken,this.displayName=i.displayName||null,this.email=i.email||null,this.emailVerified=i.emailVerified||!1,this.phoneNumber=i.phoneNumber||null,this.photoURL=i.photoURL||null,this.isAnonymous=i.isAnonymous||!1,this.tenantId=i.tenantId||null,this.providerData=i.providerData?[...i.providerData]:[],this.metadata=new W(i.createdAt||void 0,i.lastLoginAt||void 0)}async getIdToken(e){let t=await H(this,this.stsTokenManager.getToken(this.auth,e));return v(t,this.auth,"internal-error"),this.accessToken!==t&&(this.accessToken=t,await this.auth._persistUserIfCurrent(this),this.auth._notifyListenersIfCurrent(this)),t}getIdTokenResult(e){return V(this,e)}reload(){return Y(this)}_assign(e){this!==e&&(v(this.uid===e.uid,this.auth,"internal-error"),this.displayName=e.displayName,this.photoURL=e.photoURL,this.email=e.email,this.emailVerified=e.emailVerified,this.phoneNumber=e.phoneNumber,this.isAnonymous=e.isAnonymous,this.tenantId=e.tenantId,this.providerData=e.providerData.map(e=>({...e})),this.metadata._copy(e.metadata),this.stsTokenManager._assign(e.stsTokenManager))}_clone(e){let t=new et({...this,auth:e,stsTokenManager:this.stsTokenManager._clone()});return t.metadata._copy(this.metadata),t}_onReload(e){v(!this.reloadListener,this.auth,"internal-error"),this.reloadListener=e,this.reloadUserInfo&&(this._notifyReloadListener(this.reloadUserInfo),this.reloadUserInfo=null)}_notifyReloadListener(e){this.reloadListener?this.reloadListener(e):this.reloadUserInfo=e}_startProactiveRefresh(){this.proactiveRefresh._start()}_stopProactiveRefresh(){this.proactiveRefresh._stop()}async _updateTokensIfNecessary(e,t=!1){let r=!1;e.idToken&&e.idToken!==this.stsTokenManager.accessToken&&(this.stsTokenManager.updateFromServerResponse(e),r=!0),t&&await $(this),await this.auth._persistUserIfCurrent(this),r&&this.auth._notifyListenersIfCurrent(this)}async delete(){if((0,n.xZ)(this.auth.app))return Promise.reject(p(this.auth));let e=await this.getIdToken();return await H(this,z(this.auth,{idToken:e})),this.stsTokenManager.clearRefreshToken(),this.auth.signOut()}toJSON(){return{uid:this.uid,email:this.email||void 0,emailVerified:this.emailVerified,displayName:this.displayName||void 0,isA
11nonymous:this.isAnonymous,photoURL:this.photoURL||void 0,phoneNumber:this.phoneNumber||void 0,tenantId:this.tenantId||void 0,providerData:this.providerData.map(e=>({...e})),stsTokenManager:this.stsTokenManager.toJSON(),_redirectEventId:this._redirectEventId,...this.metadata.toJSON(),apiKey:this.auth.config.apiKey,appName:this.auth.name}}get refreshToken(){return this.stsTokenManager.refreshToken||""}static _fromJSON(e,t){let r=t.displayName??void 0,i=t.email??void 0,n=t.phoneNumber??void 0,a=t.photoURL??void 0,s=t.tenantId??void 0,o=t._redirectEventId??void 0,l=t.createdAt??void 0,u=t.lastLoginAt??void 0,{uid:c,emailVerified:h,isAnonymous:d,providerData:m,stsTokenManager:g}=t;v(c&&g,e,"internal-error");let p=Z.fromJSON(this.name,g);v("string"==typeof c,e,"internal-error"),ee(r,e.name),ee(i,e.name),v("boolean"==typeof h,e,"internal-error"),v("boolean"==typeof d,e,"internal-error"),ee(n,e.name),ee(a,e.name),ee(s,e.name),ee(o,e.name),ee(l,e.name),ee(u,e.name);let f=new et({uid:c,auth:e,email:i,emailVerified:h,displayName:r,isAnonymous:d,photoURL:a,phoneNumber:n,tenantId:s,stsTokenManager:p,createdAt:l,lastLoginAt:u});return m&&Array.isArray(m)&&(f.providerData=m.map(e=>({...e}))),o&&(f._redirectEventId=o),f}static async _fromIdTokenResponse(e,t,r=!1){let i=new Z;i.updateFromServerResponse(t);let n=new et({uid:t.localId,auth:e,stsTokenManager:i,isAnonymous:r});return await $(n),n}static async _fromGetAccountInfoResponse(e,t,r){let i=t.users[0];v(void 0!==i.localId,"internal-error");let n=void 0!==i.providerUserInfo?J(i.providerUserInfo):[],a=!(i.email&&i.passwordHash)&&!n?.length,s=new Z;s.updateFromIdToken(r);let o=new et({uid:i.localId,auth:e,stsTokenManager:s,isAnonymous:a});return Object.assign(o,{uid:i.localId,displayName:i.displayName||null,photoURL:i.photoUrl||null,email:i.email||null,emailVerified:i.emailVerified||!1,phoneNumber:i.phoneNumber||null,tenantId:i.tenantId||null,providerData:n,metadata:new W(i.createdAt,i.lastLoginAt),isAnonymous:!(i.email&&i.passwordHash)&&!n?.length}),o}}let er=new Map;function ei(e){var t,r;t="Expected a class definition",e instanceof Function||w(t);let i=er.get(e);return i?(r="Instance stored in cache mismatched with class",i instanceof e||w(r)):(i=new e,er.set(e,i)),i}class en{constructor(){this.type="NONE",this.storage={}}async _isAvailable(){return!0}async _set(e,t){this.storage[e]=t}async _get(e){let t=this.storage[e];return void 0===t?null:t}async _remove(e){delete this.storage[e]}_addListener(e,t){}_removeListener(e,t){}}function ea(e,t,r){return`firebase:${e}:${t}:${r}`}en.type="NONE";class es{constructor(e,t,r){this.persistence=e,this.auth=t,this.userKey=r;const{config:i,name:n}=this.auth;this.fullUserKey=ea(this.userKey,i.apiKey,n),this.fullPersistenceKey=ea("persistence",i.apiKey,n),this.boundEventHandler=t._onStorageEvent.bind(t),this.persistence._addListener(this.fullUserKey,this.boundEventHandler)}setCurrentUser(e){return this.persistence._set(this.fullUserKey,e.toJSON())}async getCurrentUser(){let e=await this.persistence._get(this.fullUserKey);if(!e)return null;if("string"==typeof e){let t=await U(this.auth,{idToken:e}).catch(()=>void 0);return t?et._fromGetAccountInfoResponse(this.auth,t,e):null}return et._fromJSON(this.auth,e)}removeCurrentUser(){return this.persistence._remove(this.fullUserKey)}savePersistenceForRedirect(){return this.persistence._set(this.fullPersistenceKey,this.persistence.type)}async setPersistence(e){if(this.persistence===e)return;let t=await this.getCurrentUser();if(await this.removeCurrentUser(),this.persistence=e,t)return this.setCurrentUser(t)}delete(){this.persistence._removeListener(this.fullUserKey,this.boundEventHandler)}static async create(e,t,r="authUser"){if(!t.length)return new es(ei(en),e,r);let i=(await Promise.all(t.map(async e=>{if(await e._isAvailable())return e}))).filter(e=>e),n=i[0]||ei(en),a=ea(r,e.config.apiKey,e.name),s=null;for(let r of t)try{let t=await r._get(a);if(t){let i;if("string"==typeof t){let r=await U(e,{idToken:t}).catch(()=>void 0);if(!r)break;i=await et._fromGetAccountInfoResponse(e,r,t)}else i=et._fromJSON(e,t);r!==n&&(s=i),n=r;break}}catch{}let o=i.filter(e=>e._shouldAllowMigration);return n._shouldAllowMigration&&o.length&&(n=o[0],s&&await n._set(a,s.toJSON()),await Promise.all(t.map(async e=>{if(e!==n)try{await e._remove(a)}catch{}}))),new es(n,e,r)}}function eo(e){let t=e.toLowerCase();if(t.includes("opera/")||t.includes("opr/")||t.includes("opios/"))return"Opera";{if(eh(t))return"IEMobile";if(t.includes("msie")||t.includes("trident/"))return"IE";if(t.includes("edge/"))return"Edge";if(el(t))return"Firefox";if(t.includes("silk/"))return"Silk";if(em(t))return"Blackberry";if(eg(t))return"Webos";if(eu(t))return"Safari";if((t.includes("chrome/")||ec(t))&&!t.includes("edge/"))return"Chrome";if(ed(t))return"Android";let r=e.match(/([a-zA-Z\d\.]+)\/[a-zA-Z\d\.]*$/);if(r?.length===2)return r[1]}return"Other"}function el(e=(0,a.ZQ)()){return/firefox\//i.test(e)}function eu(e=(0,a.ZQ)()){let t=e.toLowerCase();return t.includes("safari/")&&!t.includes("chrome/")&&!t.includes("crios/")&&!t.includes("android")}function ec(e=(0,a.ZQ)()){return/crios\//i.test(e)}function eh(e=(0,a.ZQ)()){return/iemobile/i.test(e)}function ed(e=(0,a.ZQ)()){return/android/i.test(e)}function em(e=(0,a.ZQ)()){return/blackberry/i.test(e)}function eg(e=(0,a.ZQ)()){return/webos/i.test(e)}function ep(e=(0,a.ZQ)()){return/iphone|ipad|ipod/i.test(e)||/macintosh/i.test(e)&&/mobile/i.test(e)}function ef(e=(0,a.ZQ)()){return ep(e)||ed(e)||eg(e)||em(e)||/windows phone/i.test(e)||eh(e)}function ey(e,t=[]){let r;switch(e){case"Browser":r=eo((0,a.ZQ)());break;case"Worker":r=`${eo((0,a.ZQ)())}-${e}`;break;default:r=e}let i=t.length?t.join(","):"FirebaseCore-web";return`${r}/JsCore/${n.MF}/${i}`}class ev{constructor(e){this.auth=e,this.queue=[]}pushCallback(e,t){let r=t=>new Promise((r,i)=>{try{let i=e(t);r(i)}catch(e){i(e)}});r.onAbort=t,this.queue.push(r);let i=this.queue.length-1;return()=>{this.queue[i]=()=>Promise.resolve()}}async runMiddleware(e){if(this.auth.currentUser===e)return;let t=[];try{for(let r of this.queue)await r(e),r.onAbort&&t.push(r.onAbort)}catch(e){for(let e of(t.reverse(),t))try{e()}catch(e){}throw this.auth._errorFactory.create("login-blocked",{originalMessage:e?.message})}}}async function ew(e,t={}){return R(e,"GET","/v2/passwordPolicy",_(e,t))}class eb{constructor(e){const t=e.customStrengthOptions;this.customStrengthOptions={},this.customStrengthOptions.minPasswordLength=t.minPasswordLength??6,t.maxPasswordLength&&(this.customStrengthOptions.maxPasswordLength=t.maxPasswordLength),void 0!==t.containsLowercaseCharacter&&(this.customStrengthOptions.containsLowercaseLetter=t.containsLowercaseCharacter),void 0!==t.containsUppercaseCharacter&&(this.customStrengthOptions.containsUppercaseLetter=t.containsUppercaseCharacter),void 0!==t.containsNumericCharacter&&(this.customStrengthOptions.containsNumericCharacter=t.containsNumericCharacter),void 0!==t.containsNonAlphanumericCharacter&&(this.customStrengthOptions.containsNonAlphanumericCharacter=t.containsNonAlphanumericCharacter),this.enforcementState=e.enforcementState,"ENFORCEMENT_STATE_UNSPECIFIED"===this.enforcementState&&(this.enforcementState="OFF"),this.allowedNonAlphanumericCharacters=e.allowedNonAlphanumericCharacters?.join("")??"",this.forceUpgradeOnSignin=e.forceUpgradeOnSignin??!1,this.schemaVersion=e.schemaVersion}validatePassword(e){let t={isValid:!0,passwordPolicy:this};return this.validatePasswordLengthOptions(e,t),this.validatePasswordCharacterOptions(e,t),t.isValid&&
vendor: 1,345 bytes, line 11
11(t.isValid=t.meetsMinPasswordLength??!0),t.isValid&&(t.isValid=t.meetsMaxPasswordLength??!0),t.isValid&&(t.isValid=t.containsLowercaseLetter??!0),t.isValid&&(t.isValid=t.containsUppercaseLetter??!0),t.isValid&&(t.isValid=t.containsNumericCharacter??!0),t.isValid&&(t.isValid=t.containsNonAlphanumericCharacter??!0),t}validatePasswordLengthOptions(e,t){let r=this.customStrengthOptions.minPasswordLength,i=this.customStrengthOptions.maxPasswordLength;r&&(t.meetsMinPasswordLength=e.length>=r),i&&(t.meetsMaxPasswordLength=e.length<=i)}validatePasswordCharacterOptions(e,t){let r;this.updatePasswordCharacterOptionsStatuses(t,!1,!1,!1,!1);for(let i=0;i<e.length;i++)r=e.charAt(i),this.updatePasswordCharacterOptionsStatuses(t,r>="a"&&r<="z",r>="A"&&r<="Z",r>="0"&&r<="9",this.allowedNonAlphanumericCharacters.includes(r))}updatePasswordCharacterOptionsStatuses(e,t,r,i,n){this.customStrengthOptions.containsLowercaseLetter&&(e.containsLowercaseLetter||(e.containsLowercaseLetter=t)),this.customStrengthOptions.containsUppercaseLetter&&(e.containsUppercaseLetter||(e.containsUppercaseLetter=r)),this.customStrengthOptions.containsNumericCharacter&&(e.containsNumericCharacter||(e.containsNumericCharacter=i)),this.customStrengthOptions.containsNonAlphanumericCharacter&&(e.containsNonAlphanumericCharacter||(e.containsNonAlphanumericCharacter=n))}}
11class eC{constructor(e,t,r,i){this.app=e,this.heartbeatServiceProvider=t,this.appCheckServiceProvider=r,this.config=i,this.currentUser=null,this.emulatorConfig=null,this.operations=Promise.resolve(),this.authStateSubscription=new eS(this),this.idTokenSubscription=new eS(this),this.beforeStateQueue=new ev(this),this.redirectUser=null,this.isProactiveRefreshEnabled=!1,this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION=1,this._canInitEmulator=!0,this._isInitialized=!1,this._deleted=!1,this._initializationPromise=null,this._popupRedirectResolver=null,this._errorFactory=u,this._agentRecaptchaConfig=null,this._tenantRecaptchaConfigs={},this._projectPasswordPolicy=null,this._tenantPasswordPolicies={},this._resolvePersistenceManagerAvailable=void 0,this.lastNotifiedUid=void 0,this.languageCode=null,this.tenantId=null,this.settings={appVerificationDisabledForTesting:!1},this.frameworks=[],this.name=e.name,this.clientVersion=i.sdkClientVersion,this._persistenceManagerAvailable=new Promise(e=>this._resolvePersistenceManagerAvailable=e)}_initializeWithPersistence(e,t){return t&&(this._popupRedirectResolver=ei(t)),this._initializationPromise=this.queue(async()=>{if(!this._deleted){if(this.persistenceManager=await es.create(this,e),this._resolvePersistenceManagerAvailable?.(),!this._deleted){if(this._popupRedirectResolver?._shouldInitProactively)try{await this._popupRedirectResolver._initialize(this)}catch(e){}await this.initializeCurrentUser(t),this.lastNotifiedUid=this.currentUser?.uid||null,this._deleted||(this._isInitialized=!0)}}}),this._initializationPromise}async _onStorageEvent(){if(this._deleted)return;let e=await this.assertedPersistence.getCurrentUser();if(this.currentUser||e){if(this.currentUser&&e&&this.currentUser.uid===e.uid){this._currentUser._assign(e),await this.currentUser.getIdToken();return}await this._updateCurrentUser(e,!0)}}async initializeCurrentUserFromIdToken(e){try{let t=await U(this,{idToken:e}),r=await et._fromGetAccountInfoResponse(this,t,e);await this.directlySetCurrentUser(r)}catch(e){console.warn("FirebaseServerApp could not login user with provided authIdToken: ",e),await this.directlySetCurrentUser(null)}}async initializeCurrentUser(e){if((0,n.xZ)(this.app)){let e=this.app.settings.authIdToken;return e?new Promise(t=>{setTimeout(()=>this.initializeCurrentUserFromIdToken(e).then(t,t))}):this.directlySetCurrentUser(null)}let t=await this.assertedPersistence.getCurrentUser(),r=t,i=!1;if(e&&this.config.authDomain){await this.getOrInitRedirectPersistenceManager();let t=this.redirectUser?._redirectEventId,n=r?._redirectEventId,a=await this.tryRedirectSignIn(e);(!t||t===n)&&a?.user&&(r=a.user,i=!0)}if(!r)return this.directlySetCurrentUser(null);if(!r._redirectEventId){if(i)try{await this.beforeStateQueue.runMiddleware(r)}catch(e){r=t,this._popupRedirectResolver._overrideRedirectResult(this,()=>Promise.reject(e))}return r?this.reloadAndSetCurrentUserOrClear(r):this.directlySetCurrentUser(null)}return(v(this._popupRedirectResolver,this,"argument-error"),await this.getOrInitRedirectPersistenceManager(),this.redirectUser&&this.redirectUser._redirectEventId===r._redirectEventId)?this.directlySetCurrentUser(r):this.reloadAndSetCurrentUserOrClear(r)}async tryRedirectSignIn(e){let t=null;try{t=await this._popupRedirectResolver._completeRedirectFn(this,e,!0)}catch(e){await this._setRedirectUser(null)}return t}async reloadAndSetCurrentUserOrClear(e){try{await $(e)}catch(e){if(e?.code!=="auth/network-request-failed")return this.directlySetCurrentUser(null)}return this.directlySetCurrentUser(e)}useDeviceLanguage(){this.languageCode=function(){if("u"<typeof navigator)return null;let e=navigator;return e.languages&&e.languages[0]||e.language||null}()}async _delete(){this._deleted=!0}async updateCurrentUser(e){if((0,n.xZ)(this.app))return Promise.reject(p(this));let t=e?(0,a.Ku)(e):null;return t&&v(t.auth.config.apiKey===this.config.apiKey,this,"invalid-user-token"),this._updateCurrentUser(t&&t._clone(this))}async _updateCurrentUser(e,t=!1){if(!this._deleted)return e&&v(this.tenantId===e.tenantId,this,"tenant-id-mismatch"),t||await this.beforeStateQueue.runMiddleware(e),this.queue(async()=>{await this.directlySetCurrentUser(e),this.notifyAuthListeners()})}async signOut(){return(0,n.xZ)(this.app)?Promise.reject(p(this)):(await this.beforeStateQueue.runMiddleware(null),(this.redirectPersistenceManager||this._popupRedirectResolver)&&await this._setRedirectUser(null),this._updateCurrentUser(null,!0))}setPersistence(e){return(0,n.xZ)(this.app)?Promise.reject(p(this)):this.queue(async()=>{await this.assertedPersistence.setPersistence(ei(e))})}_getRecaptchaConfig(){return null==this.tenantId?this._agentRecaptchaConfig:this._tenantRecaptchaConfigs[this.tenantId]}async validatePassword(e){this._getPasswordPolicyInternal()||await this._updatePasswordPolicy();let t=this._getPasswordPolicyInternal();return t.schemaVersion!==this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION?Promise.reject(this._errorFactory.create("unsupported-password-policy-schema-version",{})):t.validatePassword(e)}_getPasswordPolicyInternal(){return null===this.tenantId?this._projectPasswordPolicy:this._tenantPasswordPolicies[this.tenantId]}async _updatePasswordPolicy(){let e=new eb(await ew(this));null===this.tenantId?this._projectPasswordPolicy=e:this._tenantPasswordPolicies[this.tenantId]=e}_getPersistenceType(){return this.assertedPersistence.persistence.type}_getPersistence(){return this.assertedPersistence.persistence}_updateErrorMap(e){this._errorFactory=new a.FA("auth","Firebase",e())}onAuthStateChanged(e,t,r){return this.registerStateListener(this.authStateSubscription,e,t,r)}beforeAuthStateChanged(e,t){return this.beforeStateQueue.pushCallback(e,t)}onIdTokenChanged(e,t,r){return this.registerStateListener(this.idTokenSubscription,e,t,r)}authStateReady(){return new Promise((e,t)=>
11{if(this.currentUser)e();else{let r=this.onAuthStateChanged(()=>{r(),e()},t)}})}async revokeAccessToken(e){if(this.currentUser){let t={providerId:"apple.com",tokenType:"ACCESS_TOKEN",token:e,idToken:await this.currentUser.getIdToken()};null!=this.tenantId&&(t.tenantId=this.tenantId),await X(this,t)}}toJSON(){return{apiKey:this.config.apiKey,authDomain:this.config.authDomain,appName:this.name,currentUser:this._currentUser?.toJSON()}}async _setRedirectUser(e,t){let r=await this.getOrInitRedirectPersistenceManager(t);return null===e?r.removeCurrentUser():r.setCurrentUser(e)}async getOrInitRedirectPersistenceManager(e){if(!this.redirectPersistenceManager){let t=e&&ei(e)||this._popupRedirectResolver;v(t,this,"argument-error"),this.redirectPersistenceManager=await es.create(this,[ei(t._redirectPersistence)],"redirectUser"),this.redirectUser=await this.redirectPersistenceManager.getCurrentUser()}return this.redirectPersistenceManager}async _redirectUserForId(e){return(this._isInitialized&&await this.queue(async()=>{}),this._currentUser?._redirectEventId===e)?this._currentUser:this.redirectUser?._redirectEventId===e?this.redirectUser:null}async _persistUserIfCurrent(e){if(e===this.currentUser)return this.queue(async()=>this.directlySetCurrentUser(e))}_notifyListenersIfCurrent(e){e===this.currentUser&&this.notifyAuthListeners()}_key(){return`${this.config.authDomain}:${this.config.apiKey}:${this.name}`}_startProactiveRefresh(){this.isProactiveRefreshEnabled=!0,this.currentUser&&this._currentUser._startProactiveRefresh()}_stopProactiveRefresh(){this.isProactiveRefreshEnabled=!1,this.currentUser&&this._currentUser._stopProactiveRefresh()}get _currentUser(){return this.currentUser}notifyAuthListeners(){if(!this._isInitialized)return;this.idTokenSubscription.next(this.currentUser);let e=this.currentUser?.uid??null;this.lastNotifiedUid!==e&&(this.lastNotifiedUid=e,this.authStateSubscription.next(this.currentUser))}registerStateListener(e,t,r,i){if(this._deleted)return()=>{};let n="function"==typeof t?t:t.next.bind(t),a=!1,s=this._isInitialized?Promise.resolve():this._initializationPromise;if(v(s,this,"internal-error"),s.then(()=>{a||n(this.currentUser)}),"function"==typeof t){let n=e.addObserver(t,r,i);return()=>{a=!0,n()}}{let r=e.addObserver(t);return()=>{a=!0,r()}}}async directlySetCurrentUser(e){this.currentUser&&this.currentUser!==e&&this._currentUser._stopProactiveRefresh(),e&&this.isProactiveRefreshEnabled&&e._startProactiveRefresh(),this.currentUser=e,e?await this.assertedPersistence.setCurrentUser(e):await this.assertedPersistence.removeCurrentUser()}queue(e){return this.operations=this.operations.then(e,e),this.operations}get assertedPersistence(){return v(this.persistenceManager,this,"internal-error"),this.persistenceManager}_logFramework(e){!e||this.frameworks.includes(e)||(this.frameworks.push(e),this.frameworks.sort(),this.clientVersion=ey(this.config.clientPlatform,this._getFrameworks()))}_getFrameworks(){return this.frameworks}async _getAdditionalHeaders(){let e={"X-Client-Version":this.clientVersion};this.app.options.appId&&(e["X-Firebase-gmpid"]=this.app.options.appId);let t=await this.heartbeatServiceProvider.getImmediate({optional:!0})?.getHeartbeatsHeader();t&&(e["X-Firebase-Client"]=t);let r=await this._getAppCheckToken();return r&&(e["X-Firebase-AppCheck"]=r),e}async _getAppCheckToken(){if((0,n.xZ)(this.app)&&this.app.settings.appCheckToken)return this.app.settings.appCheckToken;let e=await this.appCheckServiceProvider.getImmediate({optional:!0})?.getToken();return e?.error&&function(e,...t){c.logLevel<=s.$b.WARN&&c.warn(`Auth (${n.MF}): ${e}`,...t)}(`Error while retrieving App Check token: ${e.error}`),e?.token}}function eT(e){return(0,a.Ku)(e)}class eS{constructor(e){this.auth=e,this.observer=null,this.addObserver=(0,a.tD)(e=>this.observer=e)}get next(){return v(this.observer,this.auth,"internal-error"),this.observer.next.bind(this.observer)}}let eF={async loadJS(){throw Error("Unable to load external scripts")},recaptchaV2Script:"",recaptchaEnterpriseScript:"",gapiScript:""};function ek(e){return`__${e}${Math.floor(1e6*Math.random())}`}class eE{constructor(){this.enterprise=new eA}ready(e){e()}execute(e,t){return Promise.resolve("token")}render(e,t){return""}}class eA{ready(e){e()}execute(e,t){return Promise.resolve("token")}render(e,t){return""}}let e_="NO_RECAPTCHA";class eR{constructor(e){this.type="recaptcha-enterprise",this.auth=eT(e)}async verify(e="verify",t=!1){async function r(e){if(!t){if(null==e.tenantId&&null!=e._agentRecaptchaConfig)return e._agentRecaptchaConfig.siteKey;if(null!=e.tenantId&&void 0!==e._tenantRecaptchaConfigs[e.tenantId])return e._tenantRecaptchaConfigs[e.tenantId].siteKey}return new Promise(async(t,r)=>
11{D(e,{clientType:"CLIENT_TYPE_WEB",version:"RECAPTCHA_ENTERPRISE"}).then(i=>{if(void 0===i.recaptchaKey)r(Error("recaptcha Enterprise site key undefined"));else{let r=new N(i);return null==e.tenantId?e._agentRecaptchaConfig=r:e._tenantRecaptchaConfigs[e.tenantId]=r,t(r.siteKey)}}).catch(e=>{r(e)})})}function i(t,r,i){let n=window.grecaptcha;L(n)?n.enterprise.ready(()=>{n.enterprise.execute(t,{action:e}).then(e=>{r(e)}).catch(()=>{r(e_)})}):i(Error("No reCAPTCHA enterprise script loaded."))}return this.auth.settings.appVerificationDisabledForTesting?new eE().execute("siteKey",{action:"verify"}):new Promise((e,n)=>{r(this.auth).then(r=>{if(!t&&L(window.grecaptcha))i(r,e,n);else{var a;if("u"<typeof window)return void n(Error("RecaptchaVerifier is only supported in browser"));let t=eF.recaptchaEnterpriseScript;0!==t.length&&(t+=r),(a=t,eF.loadJS(a)).then(()=>{i(r,e,n)}).catch(e=>{n(e)})}}).catch(e=>{n(e)})})}}async function eI(e,t,r,i=!1,n=!1){let a,s=new eR(e);if(n)a=e_;else try{a=await s.verify(r)}catch(e){a=await s.verify(r,!0)}let o={...t};if("mfaSmsEnrollment"===r||"mfaSmsSignIn"===r){if("phoneEnrollmentInfo"in o){let e=o.phoneEnrollmentInfo.phoneNumber,t=o.phoneEnrollmentInfo.recaptchaToken;Object.assign(o,{phoneEnrollmentInfo:{phoneNumber:e,recaptchaToken:t,captchaResponse:a,clientType:"CLIENT_TYPE_WEB",recaptchaVersion:"RECAPTCHA_ENTERPRISE"}})}else if("phoneSignInInfo"in o){let e=o.phoneSignInInfo.recaptchaToken;Object.assign(o,{phoneSignInInfo:{recaptchaToken:e,captchaResponse:a,clientType:"CLIENT_TYPE_WEB",recaptchaVersion:"RECAPTCHA_ENTERPRISE"}})}return o}return i?Object.assign(o,{captchaResp:a}):Object.assign(o,{captchaResponse:a}),Object.assign(o,{clientType:"CLIENT_TYPE_WEB"}),Object.assign(o,{recaptchaVersion:"RECAPTCHA_ENTERPRISE"}),o}async function ex(e,t,r,i,n){if("EMAIL_PASSWORD_PROVIDER"===n)if(!e._getRecaptchaConfig()?.isProviderEnabled("EMAIL_PASSWORD_PROVIDER"))return i(e,t).catch(async n=>{if("auth/missing-recaptcha-token"!==n.code)return Promise.reject(n);{console.log(`${r} is protected by reCAPTCHA Enterprise for this project. Automatically triggering the reCAPTCHA flow and restarting the flow.`);let n=await eI(e,t,r,"getOobCode"===r);return i(e,n)}});else{let n=await eI(e,t,r,"getOobCode"===r);return i(e,n)}if("PHONE_PROVIDER"!==n)return Promise.reject(n+" provider is not supported.");if(e._getRecaptchaConfig()?.isProviderEnabled("PHONE_PROVIDER")){let n=await eI(e,t,r);return i(e,n).catch(async n=>{if(e._getRecaptchaConfig()?.getProviderEnforcementState("PHONE_PROVIDER")==="AUDIT"&&("auth/missing-recaptcha-token"===n.code||"auth/invalid-app-credential"===n.code)){console.log(`Failed to verify with reCAPTCHA Enterprise. Automatically triggering the reCAPTCHA v2 flow to complete the ${r} flow.`);let n=await eI(e,t,r,!1,!0);return i(e,n)}return Promise.reject(n)})}{let n=await eI(e,t,r,!1,!0);return i(e,n)}}async function eO(e){let t=eT(e),r=new N(await D(t,{clientType:"CLIENT_TYPE_WEB",version:"RECAPTCHA_ENTERPRISE"}));null==t.tenantId?t._agentRecaptchaConfig=r:t._tenantRecaptchaConfigs[t.tenantId]=r,r.isAnyProviderEnabled()&&new eR(t).verify()}function eM(e){let t=e.indexOf(":");return t<0?"":e.substr(0,t+1)}function eP(e){if(!e)return null;let t=Number(e);return isNaN(t)?null:t}class eL{constructor(e,t){this.providerId=e,this.signInMethod=t}toJSON(){return w("not implemented")}_getIdTokenResponse(e){return w("not implemented")}_linkToIdToken(e,t){return w("not implemented")}_getReauthenticationResolver(e){return w("not implemented")}}async function eN(e,t){return R(e,"POST","/v1/accounts:signUp",t)}async function eD(e,t){return x(e,"POST","/v1/accounts:signInWithPassword",_(e,t))}async function ez(e,t){return R(e,"POST","/v1/accounts:sendOobCode",_(e,t))}async function eU(e,t){return ez(e,t)}async function eB(e,t){return x(e,"POST","/v1/accounts:signInWithEmailLink",_(e,t))}async function eV(e,t){return x(e,"POST","/v1/accounts:signInWithEmailLink",_(e,t))}class ej extends eL{constructor(e,t,r,i=null){super("password",r),this._email=e,this._password=t,this._tenantId=i}static _fromEmailAndPassword(e,t){return new ej(e,t,"password")}static _fromEmailAndCode(e,t,r=null){return new ej(e,t,"emailLink",r)}toJSON(){return{email:this._email,password:this._password,signInMethod:this.signInMethod,tenantId:this._tenantId}}static fromJSON(e){let t="string"==typeof e?JSON.parse(e):e;if(t?.email&&t?.password){if("password"===t.signInMethod)return this._fromEmailAndPassword(t.email,t.password);else if("emailLink"===t.signInMethod)return this._fromEmailAndCode(t.email,t.password,t.tenantId)}return null}async _getIdTokenResponse(e){switch(this.signInMethod){case"password":return ex(e,{returnSecureToken:!0,email:this._email,password:this._password,clientType:"CLIENT_TYPE_WEB"},"signInWithPassword",eD,"EMAIL_PASSWORD_PROVIDER");case"emailLink":return eB(e,{email:this._email,oobCode:this._password});default:d(e,"internal-error")}}async _linkToIdToken(e,t){switch(this.signInMethod){case"password":return ex(e,{idToken:t,returnSecureToken:!0,email:this._email,password:this._password,clientType:"CLIENT_TYPE_WEB"},"signUpPassword",eN,"EMAIL_PASSWORD_PROVIDER");case"emailLink":return eV(e,{idToken:t,email:this._email,oobCode:this._password});default:d(e,"internal-error")}}_getReauthenticationResolver(e){return this._getIdTokenResponse(e)}}async function eG(e,t){return x(e,"POST","/v1/accounts:signInWithIdp",_(e,t))}class eK extends eL{constructor(){super(...arguments),this.pendingToken=null}static _fromParams(e){let t=new eK(e.providerId,e.signInMethod);return e.idToken||e.accessToken?(e.idToken&&(t.idToken=e.idToken),e.accessToken&&(t.accessToken=e.accessToken),e.nonce&&!e.pendingToken&&
11(t.nonce=e.nonce),e.pendingToken&&(t.pendingToken=e.pendingToken)):e.oauthToken&&e.oauthTokenSecret?(t.accessToken=e.oauthToken,t.secret=e.oauthTokenSecret):d("argument-error"),t}toJSON(){return{idToken:this.idToken,accessToken:this.accessToken,secret:this.secret,nonce:this.nonce,pendingToken:this.pendingToken,providerId:this.providerId,signInMethod:this.signInMethod}}static fromJSON(e){let{providerId:t,signInMethod:r,...i}="string"==typeof e?JSON.parse(e):e;if(!t||!r)return null;let n=new eK(t,r);return n.idToken=i.idToken||void 0,n.accessToken=i.accessToken||void 0,n.secret=i.secret,n.nonce=i.nonce,n.pendingToken=i.pendingToken||null,n}_getIdTokenResponse(e){return eG(e,this.buildRequest())}_linkToIdToken(e,t){let r=this.buildRequest();return r.idToken=t,eG(e,r)}_getReauthenticationResolver(e){let t=this.buildRequest();return t.autoCreate=!1,eG(e,t)}buildRequest(){let e={requestUri:"http://localhost",returnSecureToken:!0};if(this.pendingToken)e.pendingToken=this.pendingToken;else{let t={};this.idToken&&(t.id_token=this.idToken),this.accessToken&&(t.access_token=this.accessToken),this.secret&&(t.oauth_token_secret=this.secret),t.providerId=this.providerId,this.nonce&&!this.pendingToken&&(t.nonce=this.nonce),e.postBody=(0,a.Am)(t)}return e}}async function eH(e,t){return R(e,"POST","/v1/accounts:sendVerificationCode",_(e,t))}async function eq(e,t){return x(e,"POST","/v1/accounts:signInWithPhoneNumber",_(e,t))}async function eW(e,t){let r=await x(e,"POST","/v1/accounts:signInWithPhoneNumber",_(e,t));if(r.temporaryProof)throw P(e,"account-exists-with-different-credential",r);return r}let e$={USER_NOT_FOUND:"user-not-found"};async function eY(e,t){return x(e,"POST","/v1/accounts:signInWithPhoneNumber",_(e,{...t,operation:"REAUTH"}),e$)}class eJ extends eL{constructor(e){super("phone","phone"),this.params=e}static _fromVerification(e,t){return new eJ({verificationId:e,verificationCode:t})}static _fromTokenResponse(e,t){return new eJ({phoneNumber:e,temporaryProof:t})}_getIdTokenResponse(e){return eq(e,this._makeVerificationRequest())}_linkToIdToken(e,t){return eW(e,{idToken:t,...this._makeVerificationRequest()})}_getReauthenticationResolver(e){return eY(e,this._makeVerificationRequest())}_makeVerificationRequest(){let{temporaryProof:e,phoneNumber:t,verificationId:r,verificationCode:i}=this.params;return e&&t?{temporaryProof:e,phoneNumber:t}:{sessionInfo:r,code:i}}toJSON(){let e={providerId:this.providerId};return this.params.phoneNumber&&(e.phoneNumber=this.params.phoneNumber),this.params.temporaryProof&&(e.temporaryProof=this.params.temporaryProof),this.params.verificationCode&&(e.verificationCode=this.params.verificationCode),this.params.verificationId&&(e.verificationId=this.params.verificationId),e}static fromJSON(e){"string"==typeof e&&(e=JSON.parse(e));let{verificationId:t,verificationCode:r,phoneNumber:i,temporaryProof:n}=e;return r||t||i||n?new eJ({verificationId:t,verificationCode:r,phoneNumber:i,temporaryProof:n}):null}}class eQ{constructor(e){const t=(0,a.I9)((0,a.hp)(e)),r=t.apiKey??null,i=t.oobCode??null,n=function(e){switch(e){case"recoverEmail":return"RECOVER_EMAIL";case"resetPassword":return"PASSWORD_RESET";case"signIn":return"EMAIL_SIGNIN";case"verifyEmail":return"VERIFY_EMAIL";case"verifyAndChangeEmail":return"VERIFY_AND_CHANGE_EMAIL";case"revertSecondFactorAddition":return"REVERT_SECOND_FACTOR_ADDITION";default:return null}}(t.mode??null);v(r&&i&&n,"argument-error"),this.apiKey=r,this.operation=n,this.code=i,this.continueUrl=t.continueUrl??null,this.languageCode=t.lang??null,this.tenantId=t.tenantId??null}static parseLink(e){let t,r,i,n=(r=(t=(0,a.I9)((0,a.hp)(e)).link)?(0,a.I9)((0,a.hp)(t)).deep_link_id:null,((i=(0,a.I9)((0,a.hp)(e)).deep_link_id)?(0,a.I9)((0,a.hp)(i)).link:null)||i||r||t||e);try{return new eQ(n)}catch{return null}}}class eX{constructor(){this.providerId=eX.PROVIDER_ID}static credential(e,t){return ej._fromEmailAndPassword(e,t)}static credentialWithLink(e,t){let r=eQ.parseLink(t);return v(r,"argument-error"),ej._fromEmailAndCode(e,r.code,r.tenantId)}}eX.PROVIDER_ID="password",eX.EMAIL_PASSWORD_SIGN_IN_METHOD="password",eX.EMAIL_LINK_SIGN_IN_METHOD="emailLink";class eZ{constructor(e){this.providerId=e,this.defaultLanguageCode=null,this.customParameters={}}setDefaultLanguage(e){this.defaultLanguageCode=e}setCustomParameters(e){return this.customParameters=e,this}getCustomParameters(){return this.customParameters}}class e0 extends eZ{constructor(){super(...arguments),this.scopes=[]}addScope(e){return this.scopes.includes(e)||this.scopes.push(e),this}getScopes(){return[...this.scopes]}}class e1 extends e0{static credentialFromJSON(e){let t="string"==typeof e?JSON.parse(e):e;return v("providerId"in t&&"signInMethod"in t,"argument-error"),eK._fromParams(t)}credential(e){return this._credential({...e,nonce:e.rawNonce})}_credential(e){return v(e.idToken||e.accessToken,"argument-error"),eK._fromParams({...e,providerId:this.providerId,sign
11InMethod:this.providerId})}static credentialFromResult(e){return e1.oauthCredentialFromTaggedObject(e)}static credentialFromError(e){return e1.oauthCredentialFromTaggedObject(e.customData||{})}static oauthCredentialFromTaggedObject({_tokenResponse:e}){if(!e)return null;let{oauthIdToken:t,oauthAccessToken:r,oauthTokenSecret:i,pendingToken:n,nonce:a,providerId:s}=e;if(!r&&!i&&!t&&!n||!s)return null;try{return new e1(s)._credential({idToken:t,accessToken:r,nonce:a,pendingToken:n})}catch(e){return null}}}class e2 extends e0{constructor(){super("facebook.com")}static credential(e){return eK._fromParams({providerId:e2.PROVIDER_ID,signInMethod:e2.FACEBOOK_SIGN_IN_METHOD,accessToken:e})}static credentialFromResult(e){return e2.credentialFromTaggedObject(e)}static credentialFromError(e){return e2.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e||!("oauthAccessToken"in e)||!e.oauthAccessToken)return null;try{return e2.credential(e.oauthAccessToken)}catch{return null}}}e2.FACEBOOK_SIGN_IN_METHOD="facebook.com",e2.PROVIDER_ID="facebook.com";class e3 extends e0{constructor(){super("google.com"),this.addScope("profile")}static credential(e,t){return eK._fromParams({providerId:e3.PROVIDER_ID,signInMethod:e3.GOOGLE_SIGN_IN_METHOD,idToken:e,accessToken:t})}static credentialFromResult(e){return e3.credentialFromTaggedObject(e)}static credentialFromError(e){return e3.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e)return null;let{oauthIdToken:t,oauthAccessToken:r}=e;if(!t&&!r)return null;try{return e3.credential(t,r)}catch{return null}}}e3.GOOGLE_SIGN_IN_METHOD="google.com",e3.PROVIDER_ID="google.com";class e4 extends e0{constructor(){super("github.com")}static credential(e){return eK._fromParams({providerId:e4.PROVIDER_ID,signInMethod:e4.GITHUB_SIGN_IN_METHOD,accessToken:e})}static credentialFromResult(e){return e4.credentialFromTaggedObject(e)}static credentialFromError(e){return e4.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e||!("oauthAccessToken"in e)||!e.oauthAccessToken)return null;try{return e4.credential(e.oauthAccessToken)}catch{return null}}}e4.GITHUB_SIGN_IN_METHOD="github.com",e4.PROVIDER_ID="github.com";class e5 extends e0{constructor(){super("twitter.com")}static credential(e,t){return eK._fromParams({providerId:e5.PROVIDER_ID,signInMethod:e5.TWITTER_SIGN_IN_METHOD,oauthToken:e,oauthTokenSecret:t})}static credentialFromResult(e){return e5.credentialFromTaggedObject(e)}static credentialFromError(e){return e5.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e)return null;let{oauthAccessToken:t,oauthTokenSecret:r}=e;if(!t||!r)return null;try{return e5.credential(t,r)}catch{return null}}}async function e9(e,t){return x(e,"POST","/v1/accounts:signUp",_(e,t))}e5.TWITTER_SIGN_IN_METHOD="twitter.com",e5.PROVIDER_ID="twitter.com";class e6{constructor(e){this.user=e.user,this.providerId=e.providerId,this._tokenResponse=e._tokenResponse,this.operationType=e.operationType}static async _fromIdTokenResponse(e,t,r,i=!1){return new e6({user:await et._fromIdTokenResponse(e,r,i),providerId:e8(r),_tokenResponse:r,operationType:t})}static async _forOperation(e,t,r){return await e._updateTokensIfNecessary(r,!0),new e6({user:e,providerId:e8(r),_tokenResponse:r,operationType:t})}}function e8(e){return e.providerId?e.providerId:"phoneNumber"in e?"phone":null}
11class e7 extends a.g{constructor(e,t,r,i){super(t.code,t.message),this.operationType=r,this.user=i,Object.setPrototypeOf(this,e7.prototype),this.customData={appName:e.name,tenantId:e.tenantId??void 0,_serverResponse:t.customData._serverResponse,operationType:r}}static _fromErrorAndOperation(e,t,r,i){return new e7(e,t,r,i)}}function te(e,t,r,i){return("reauthenticate"===t?r._getReauthenticationResolver(e):r._getIdTokenResponse(e)).catch(r=>{if("auth/multi-factor-auth-required"===r.code)throw e7._fromErrorAndOperation(e,r,t,i);throw r})}async function tt(e,t,r=!1){let i=await H(e,t._linkToIdToken(e.auth,await e.getIdToken()),r);return e6._forOperation(e,"link",i)}async function tr(e,t,r=!1){let{auth:i}=e;if((0,n.xZ)(i.app))return Promise.reject(p(i));let a="reauthenticate";try{let n=await H(e,te(i,a,t,e),r);v(n.idToken,i,"internal-error");let s=G(n.idToken);v(s,i,"internal-error");let{sub:o}=s;return v(e.uid===o,i,"user-mismatch"),e6._forOperation(e,a,n)}catch(e){throw e?.code==="auth/user-not-found"&&d(i,"user-mismatch"),e}}async function ti(e,t,r=!1){if((0,n.xZ)(e.app))return Promise.reject(p(e));let i="signIn",a=await te(e,i,t),s=await e6._fromIdTokenResponse(e,i,a);return r||await e._updateCurrentUser(s.user),s}async function tn(e,t){return ti(eT(e),t)}async function ta(e){let t=eT(e);t._getPasswordPolicyInternal()&&await t._updatePasswordPolicy()}async function ts(e,t,r){let i=eT(e),n={requestType:"PASSWORD_RESET",email:t,clientType:"CLIENT_TYPE_WEB"};r&&(v(r.url?.length>0,i,"invalid-continue-uri"),v(void 0===r.dynamicLinkDomain||r.dynamicLinkDomain.length>0,i,"invalid-dynamic-link-domain"),v(void 0===r.linkDomain||r.linkDomain.length>0,i,"invalid-hosting-link-domain"),n.continueUrl=r.url,n.dynamicLinkDomain=r.dynamicLinkDomain,n.linkDomain=r.linkDomain,n.canHandleCodeInApp=r.handleCodeInApp,r.iOS&&(v(r.iOS.bundleId.length>0,i,"missing-ios-bundle-id"),n.iOSBundleId=r.iOS.bundleId),r.android&&(v(r.android.packageName.length>0,i,"missing-android-pkg-name"),n.androidInstallApp=r.android.installApp,n.androidMinimumVersionCode=r.android.minimumVersion,n.androidPackageName=r.android.packageName)),await ex(i,n,"getOobCode",eU,"EMAIL_PASSWORD_PROVIDER")}async function to(e,t,r){if((0,n.xZ)(e.app))return Promise.reject(p(e));let i=eT(e),a=ex(i,{returnSecureToken:!0,email:t,password:r,clientType:"CLIENT_TYPE_WEB"},"signUpPassword",e9,"EMAIL_PASSWORD_PROVIDER"),s=await a.catch(t=>{throw"auth/password-does-not-meet-requirements"===t.code&&ta(e),t}),o=await e6._fromIdTokenResponse(i,"signIn",s);return await i._updateCurrentUser(o.user),o}function tl(e,t,r){return(0,n.xZ)(e.app)?Promise.reject(p(e)):tn((0,a.Ku)(e),eX.credential(t,r)).catch(async t=>{throw"auth/password-does-not-meet-requirements"===t.code&&ta(e),t})}class tu{constructor(e,t,r={}){this.isNewUser=e,this.providerId=t,this.profile=r}}
11class tc extends tu{constructor(e,t,r,i){super(e,t,r),this.username=i}}class th extends tu{constructor(e,t){super(e,"facebook.com",t)}}class td extends tc{constructor(e,t){super(e,"github.com",t,"string"==typeof t?.login?t?.login:null)}}class tm extends tu{constructor(e,t){super(e,"google.com",t)}}class tg extends tc{constructor(e,t,r){super(e,"twitter.com",t,r)}}function tp(e){let{user:t,_tokenResponse:r}=e;return t.isAnonymous&&!r?{providerId:null,isNewUser:!1,profile:null}:function(e){if(!e)return null;let{providerId:t}=e,r=e.rawUserInfo?JSON.parse(e.rawUserInfo):{},i=e.isNewUser||"identitytoolkit#SignupNewUserResponse"===e.kind;if(!t&&e?.idToken){let t=G(e.idToken)?.firebase?.sign_in_provider;if(t)return new tu(i,"anonymous"!==t&&"custom"!==t?t:null)}if(!t)return null;switch(t){case"facebook.com":return new th(i,r);case"github.com":return new td(i,r);case"google.com":return new tm(i,r);case"twitter.com":return new tg(i,r,e.screenName||null);case"custom":case"anonymous":return new tu(i,null);default:return new tu(i,t,r)}}(r)}function tf(e,t,r,i){return(0,a.Ku)(e).onAuthStateChanged(t,r,i)}function ty(e){return(0,a.Ku)(e).signOut()}function tv(e,t){return R(e,"POST","/v2/accounts/mfaEnrollment:start",_(e,t))}new WeakMap;let tw="__sak";class tb{constructor(e,t){this.storageRetriever=e,this.type=t}_isAvailable(){try{if(!this.storage)return Promise.resolve(!1);return this.storage.setItem(tw,"1"),this.storage.removeItem(tw),Promise.resolve(!0)}catch{return Promise.resolve(!1)}}_set(e,t){return this.storage.setItem(e,JSON.stringify(t)),Promise.resolve()}_get(e){let t=this.storage.getItem(e);return Promise.resolve(t?JSON.parse(t):null)}_remove(e){return this.storage.removeItem(e),Promise.resolve()}get storage(){return this.storageRetriever()}}class tC extends tb{constructor(){super(()=>window.localStorage,"LOCAL"),this.boundEventHandler=(e,t)=>this.onStorageEvent(e,t),this.listeners={},this.localCache={},this.pollTimer=null,this.fallbackToPolling=ef(),this._shouldAllowMigration=!0}forAllChangedKeys(e){for(let t of Object.keys(this.listeners)){let r=this.storage.getItem(t),i=this.localCache[t];r!==i&&e(t,i,r)}}onStorageEvent(e,t=!1){if(!e.key)return void this.forAllChangedKeys((e,t,r)=>{this.notifyListeners(e,r)});let r=e.key;t?this.detachListener():this.stopPolling();let i=()=>{let e=this.storage.getItem(r);(t||this.localCache[r]!==e)&&this.notifyListeners(r,e)},n=this.storage.getItem(r);(0,a.lT)()&&10===document.documentMode&&n!==e.newValue&&e.newValue!==e.oldValue?setTimeout(i,10):i()}notifyListeners(e,t){this.localCache[e]=t;let r=this.listeners[e];if(r)for(let e of Array.from(r))e(t?JSON.parse(t):t)}startPolling(){this.stopPolling(),this.pollTimer=setInterval(()=>{this.forAllChangedKeys((e,t,r)=>{this.onStorageEvent(new StorageEvent("storage",{key:e,oldValue:t,newValue:r}),!0)})},1e3)}stopPolling(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null)}attachListener(){window.addEventListener("storage",this.boundEventHandler)}detachListener(){window.removeEventListener("storage",this.boundEventHandler)}_addListener(e,t){0===Object.keys(this.listeners).length&&(this.fallbackToPolling?this.startPolling():this.attachListener()),this.listeners[e]||(this.listeners[e]=new Set,this.localCache[e]=this.storage.getItem(e)),this.listeners[e].add(t)}_removeListener(e,t){this.listeners[e]&&(this.listeners[e].delete(t),0===this.listeners[e].size&&delete this.listeners[e]),0===Object.keys(this.listeners).length&&(this.detachListener(),this.stopPolling())}async _set(e,t){await super._set(e,t),this.localCache[e]=JSON.stringify(t)}async _get(e){let t=await super._get(e);return this.localCache[e]=JSON.stringify(t),t}async _remove(e){await super._remove(e),delete this.localCache[e]}}function tT(e){let t=e.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),r=RegExp(`${t}=([^;]+)`);return document.cookie.match(r)?.[1]??null}function tS(e){let t="http:"===window.location.protocol;return`${t?"__dev_":"__HOST-"}FIREBASE_${e.split(":")[3]}`}tC.type="LOCAL";class tF{constructor(){this.type="COOKIE",this.listenerUnsubscribes=new Map}_getFinalTarget(e){let t=new URL(`${window.location.origin}/__cookies__`);return t.searchParams.set("finalTarget",e),t}async _isAvailable(){return!("boolean"==typeof isSecureContext&&!isSecureContext||"u"<typeof navigator||"u"<typeof document)&&(navigator.cookieEnabled??!0)}async _set(e,t){}async _get(e){if(!this._isAvailable())return null;let t=tS(e);if(window.cookieStore){let e=await window.cookieStore.get(t);return e?.value}return tT(t)}async _remove(e){if(!this._isAvailable()||!await this._get(e))return;let t=tS(e);document.cookie=`${t}=;Max-Age=34560000;Partitioned;Secure;SameSite=Strict;Path=/;
11Priority=High`,await fetch("/__cookies__",{method:"DELETE"}).catch(()=>void 0)}_addListener(e,t){if(!this._isAvailable())return;let r=tS(e);if(window.cookieStore){let e=e=>{let i=e.changed.find(e=>e.name===r);i&&t(i.value),e.deleted.find(e=>e.name===r)&&t(null)};return this.listenerUnsubscribes.set(t,()=>window.cookieStore.removeEventListener("change",e)),window.cookieStore.addEventListener("change",e)}let i=tT(r),n=setInterval(()=>{let e=tT(r);e!==i&&(t(e),i=e)},1e3);this.listenerUnsubscribes.set(t,()=>clearInterval(n))}_removeListener(e,t){let r=this.listenerUnsubscribes.get(t);r&&(r(),this.listenerUnsubscribes.delete(t))}}tF.type="COOKIE";class tk extends tb{constructor(){super(()=>window.sessionStorage,"SESSION")}_addListener(e,t){}_removeListener(e,t){}}tk.type="SESSION";class tE{constructor(e){this.eventTarget=e,this.handlersMap={},this.boundEventHandler=this.handleEvent.bind(this)}static _getInstance(e){let t=this.receivers.find(t=>t.isListeningto(e));if(t)return t;let r=new tE(e);return this.receivers.push(r),r}isListeningto(e){return this.eventTarget===e}async handleEvent(e){let{eventId:t,eventType:r,data:i}=e.data,n=this.handlersMap[r];if(!n?.size)return;e.ports[0].postMessage({status:"ack",eventId:t,eventType:r});let a=Array.from(n).map(async t=>t(e.origin,i)),s=await Promise.all(a.map(async e=>{try{let t=await e;return{fulfilled:!0,value:t}}catch(e){return{fulfilled:!1,reason:e}}}));e.ports[0].postMessage({status:"done",eventId:t,eventType:r,response:s})}_subscribe(e,t){0===Object.keys(this.handlersMap).length&&this.eventTarget.addEventListener("message",this.boundEventHandler),this.handlersMap[e]||(this.handlersMap[e]=new Set),this.handlersMap[e].add(t)}_unsubscribe(e,t){this.handlersMap[e]&&t&&this.handlersMap[e].delete(t),t&&0!==this.handlersMap[e].size||delete this.handlersMap[e],0===Object.keys(this.handlersMap).length&&this.eventTarget.removeEventListener("message",this.boundEventHandler)}}function tA(e="",t=10){let r="";for(let e=0;e<t;e++)r+=Math.floor(10*Math.random());return e+r}tE.receivers=[];class t_{constructor(e){this.target=e,this.handlers=new Set}removeMessageHandler(e){e.messageChannel&&(e.messageChannel.port1.removeEventListener("message",e.onMessage),e.messageChannel.port1.close()),this.handlers.delete(e)}async _send(e,t,r=50){let i,n,a="u">typeof MessageChannel?new MessageChannel:null;if(!a)throw Error("connection_unavailable");return new Promise((s,o)=>{let l=tA("",20);a.port1.start();let u=setTimeout(()=>{o(Error("unsupported_event"))},r);n={messageChannel:a,onMessage(e){if(e.data.eventId===l)switch(e.data.status){case"ack":clearTimeout(u),i=setTimeout(()=>{o(Error("timeout"))},3e3);break;case"done":clearTimeout(i),s(e.data.response);break;default:clearTimeout(u),clearTimeout(i),o(Error("invalid_response"))}}},this.handlers.add(n),a.port1.addEventListener("message",n.onMessage),this.target.postMessage({eventType:e,eventId:l,data:t},[a.port2])}).finally(()=>{n&&this.removeMessageHandler(n)})}}function tR(){return window}function tI(){return void 0!==tR().WorkerGlobalScope&&"function"==typeof tR().importScripts}async function tx(){if(!navigator?.serviceWorker)return null;try{return(await navigator.serviceWorker.ready).active}catch{return null}}let tO="firebaseLocalStorageDb",tM="firebaseLocalStorage",tP="fbase_key";class tL{constructor(e){this.request=e}toPromise(){return new Promise((e,t)=>{this.request.addEventListener("success",()=>{e(this.request.result)}),this.request.addEventListener("error",()=>{t(this.request.error)})})}}function tN(e,t){return e.transaction([tM],t?"readwrite":"readonly").objectStore(tM)}function tD(){let e=indexedDB.open(tO,1);return new Promise((t,r)=>{e.addEventListener("error",()=>{r(e.error)}),e.addEventListener("upgradeneeded",()=>{let t=e.result;try{t.createObjectStore(tM,{keyPath:tP})}catch(e){r(e)}}),e.addEventListener("success",async()=>{let r=e.result;r.objectStoreNames.contains(tM)?t(r):(r.close(),await new tL(indexedDB.deleteDatabase(tO)).toPromise(),t(await tD()))})})}async function tz(e,t,r){return new tL(tN(e,!0).put({[tP]:t,value:r})).toPromise()}async function tU(e,t){let r=tN(e,!1).get(t),i=await new tL(r).toProm
11ise();return void 0===i?null:i.value}function tB(e,t){return new tL(tN(e,!0).delete(t)).toPromise()}class tV{constructor(){this.type="LOCAL",this._shouldAllowMigration=!0,this.listeners={},this.localCache={},this.pollTimer=null,this.pendingWrites=0,this.receiver=null,this.sender=null,this.serviceWorkerReceiverAvailable=!1,this.activeServiceWorker=null,this._workerInitializationPromise=this.initializeServiceWorkerMessaging().then(()=>{},()=>{})}async _openDb(){return this.db||(this.db=await tD()),this.db}async _withRetries(e){let t=0;for(;;)try{let t=await this._openDb();return await e(t)}catch(e){if(t++>3)throw e;this.db&&(this.db.close(),this.db=void 0)}}async initializeServiceWorkerMessaging(){return tI()?this.initializeReceiver():this.initializeSender()}async initializeReceiver(){this.receiver=tE._getInstance(tI()?self:null),this.receiver._subscribe("keyChanged",async(e,t)=>({keyProcessed:(await this._poll()).includes(t.key)})),this.receiver._subscribe("ping",async(e,t)=>["keyChanged"])}async initializeSender(){if(this.activeServiceWorker=await tx(),!this.activeServiceWorker)return;this.sender=new t_(this.activeServiceWorker);let e=await this.sender._send("ping",{},800);e&&e[0]?.fulfilled&&e[0]?.value.includes("keyChanged")&&(this.serviceWorkerReceiverAvailable=!0)}async notifyServiceWorker(e){if(this.sender&&this.activeServiceWorker&&(navigator?.serviceWorker?.controller||null)===this.activeServiceWorker)try{await this.sender._send("keyChanged",{key:e},this.serviceWorkerReceiverAvailable?800:50)}catch{}}async _isAvailable(){try{if(!indexedDB)return!1;let e=await tD();return await tz(e,tw,"1"),await tB(e,tw),!0}catch{}return!1}async _withPendingWrite(e){this.pendingWrites++;try{await e()}finally{this.pendingWrites--}}async _set(e,t){return this._withPendingWrite(async()=>(await this._withRetries(r=>tz(r,e,t)),this.localCache[e]=t,this.notifyServiceWorker(e)))}async _get(e){let t=await this._withRetries(t=>tU(t,e));return this.localCache[e]=t,t}async _remove(e){return this._withPendingWrite(async()=>(await this._withRetries(t=>tB(t,e)),delete this.localCache[e],this.notifyServiceWorker(e)))}async _poll(){let e=await this._withRetries(e=>new tL(tN(e,!1).getAll()).toPromise());if(!e||0!==this.pendingWrites)return[];let t=[],r=new Set;if(0!==e.length)for(let{fbase_key:i,value:n}of e)r.add(i),JSON.stringify(this.localCache[i])!==JSON.stringify(n)&&(this.notifyListeners(i,n),t.push(i));for(let e of Object.keys(this.localCache))this.localCache[e]&&!r.has(e)&&(this.notifyListeners(e,null),t.push(e));return t}notifyListeners(e,t){this.localCache[e]=t;let r=this.listeners[e];if(r)for(let e of Array.from(r))e(t)}startPolling(){this.stopPolling(),this.pollTimer=setInterval(async()=>this._poll(),800)}stopPolling(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null)}_addListener(e,t){0===Object.keys(this.listeners).length&&this.startPolling(),this.listeners[e]||(this.listeners[e]=new Set,this._get(e)),this.listeners[e].add(t)}_removeListener(e,t){this.listeners[e]&&(this.listeners[e].delete(t),0===this.listeners[e].size&&delete this.listeners[e]),0===Object.keys(this.listeners).length&&this.stopPolling()}}function tj(e,t){return R(e,"POST","/v2/accounts/mfaSignIn:start",_(e,t))}tV.type="LOCAL",ek("rcb"),new T(3e4,6e4);let tG="recaptcha";async function tK(e,t,r){if(!e._getRecaptchaConfig())try{await eO(e)}catch(e){console.log("Failed to initialize reCAPTCHA Enterprise config. Triggering the reCAPTCHA v2 verification.")}try{let i;if(i="string"==typeof t?{phoneNumber:t}:t,"session"in i){let t=i.session;if("phoneNumber"in i){v("enroll"===t.type,e,"internal-error");let n={idToken:t.credential,phoneEnrollmentInfo:{phoneNumber:i.phoneNumber,clientType:"CLIENT_TYPE_WEB"}},a=async(e,t)=>{if(t.phoneEnrollmentInfo.captchaResponse===e_){v(r?.type===tG,e,"argument-error");let i=await tH(e,t,r);return tv(e,i)}return tv(e,t)},s=ex(e,n,"mfaSmsEnrollment",a,"PHONE_PROVIDER");return(await s.catch(e=>Promise.reject(e))).phoneSessionInfo.sessionInfo}{v("signin"===t.type,e,"internal-error");let n=i.multiFactorHint?.uid||i.multiFactorUid;v(n,e,"missing-multi-factor-info");let a={mfaPendingCredential:t.credential,mfaEnrollmentId:n,phoneSignInInfo:{clientType:"CLIENT_TYPE_WEB"}},s=async(e,t)=>{if(t.phoneSignInInfo.captchaResponse===e_){v(r?.type===tG,e,"argument-error");let i=await tH(e,t,r);return tj(e,i)}return tj(e,t)}
11,o=ex(e,a,"mfaSmsSignIn",s,"PHONE_PROVIDER");return(await o.catch(e=>Promise.reject(e))).phoneResponseInfo.sessionInfo}}{let t={phoneNumber:i.phoneNumber,clientType:"CLIENT_TYPE_WEB"},n=async(e,t)=>{if(t.captchaResponse===e_){v(r?.type===tG,e,"argument-error");let i=await tH(e,t,r);return eH(e,i)}return eH(e,t)},a=ex(e,t,"sendVerificationCode",n,"PHONE_PROVIDER");return(await a.catch(e=>Promise.reject(e))).sessionInfo}}finally{r?._reset()}}async function tH(e,t,r){v(r.type===tG,e,"argument-error");let i=await r.verify();v("string"==typeof i,e,"argument-error");let n={...t};if("phoneEnrollmentInfo"in n){let e=n.phoneEnrollmentInfo.phoneNumber,t=n.phoneEnrollmentInfo.captchaResponse,r=n.phoneEnrollmentInfo.clientType,a=n.phoneEnrollmentInfo.recaptchaVersion;return Object.assign(n,{phoneEnrollmentInfo:{phoneNumber:e,recaptchaToken:i,captchaResponse:t,clientType:r,recaptchaVersion:a}}),n}if(!("phoneSignInInfo"in n))return Object.assign(n,{recaptchaToken:i}),n;{let e=n.phoneSignInInfo.captchaResponse,t=n.phoneSignInInfo.clientType,r=n.phoneSignInInfo.recaptchaVersion;return Object.assign(n,{phoneSignInInfo:{recaptchaToken:i,captchaResponse:e,clientType:t,recaptchaVersion:r}}),n}}class tq{constructor(e){this.providerId=tq.PROVIDER_ID,this.auth=eT(e)}verifyPhoneNumber(e,t){return tK(this.auth,e,(0,a.Ku)(t))}static credential(e,t){return eJ._fromVerification(e,t)}static credentialFromResult(e){return tq.credentialFromTaggedObject(e)}static credentialFromError(e){return tq.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e)return null;let{phoneNumber:t,temporaryProof:r}=e;return t&&r?eJ._fromTokenResponse(t,r):null}}function tW(e,t){return t?ei(t):(v(e._popupRedirectResolver,e,"argument-error"),e._popupRedirectResolver)}tq.PROVIDER_ID="phone",tq.PHONE_SIGN_IN_METHOD="phone";class t$ extends eL{constructor(e){super("custom","custom"),this.params=e}_getIdTokenResponse(e){return eG(e,this._buildIdpRequest())}_linkToIdToken(e,t){return eG(e,this._buildIdpRequest(t))}_getReauthenticationResolver(e){return eG(e,this._buildIdpRequest())}_buildIdpRequest(e){let t={requestUri:this.params.requestUri,sessionId:this.params.sessionId,postBody:this.params.postBody,tenantId:this.params.tenantId,pendingToken:this.params.pendingToken,returnSecureToken:!0,returnIdpCredential:!0};return e&&(t.idToken=e),t}}function tY(e){return ti(e.auth,new t$(e),e.bypassAuthState)}function tJ(e){let{auth:t,user:r}=e;return v(r,t,"internal-error"),tr(r,new t$(e),e.bypassAuthState)}async function tQ(e){let{auth:t,user:r}=e;return v(r,t,"internal-error"),tt(r,new t$(e),e.bypassAuthState)}class tX{constructor(e,t,r,i,n=!1){this.auth=e,this.resolver=r,this.user=i,this.bypassAuthState=n,this.pendingPromise=null,this.eventManager=null,this.filter=Array.isArray(t)?t:[t]}execute(){return new Promise(async(e,t)=>{this.pendingPromise={resolve:e,reject:t};try{this.eventManager=await this.resolver._initialize(this.auth),await this.onExecution(),this.eventManager.registerConsumer(this)}catch(e){this.reject(e)}})}async onAuthEvent(e){let{urlResponse:t,sessionId:r,postBody:i,tenantId:n,error:a,type:s}=e;if(a)return void this.reject(a);let o={auth:this.auth,requestUri:t,sessionId:r,tenantId:n||void 0,postBody:i||void 0,user:this.user,bypassAuthState:this.bypassAuthState};try{this.resolve(await this.getIdpTask(s)(o))}catch(e){this.reject(e)}}onError(e){this.reject(e)}getIdpTask(e){switch(e){case"signInViaPopup":case"signInViaRedirect":return tY;case"linkViaPopup":case"linkViaRedirect":return tQ;case"reauthViaPopup":case"reauthViaRedirect":return tJ;default:d(this.auth,"internal-error")}}resolve(e){var t,r;t=this.pendingPromise,r="Pending promise was never set",t||w(r),this.pendingPromise.resolve(e),this.unregisterAndCleanUp()}reject(e){var t,r;t=this.pendingPromise,r="Pending promise was never set",t||w(r),this.pendingPromise.reject(e),this.unregisterAndCleanUp()}unregisterAndCleanUp(){this.eventManager&&this.eventManager.unregisterConsumer(this),this.pendingPromise=null,this.cleanUp()}}let tZ=new T(2e3,1e4);async function t0(e,t,r){if((0,n.xZ)(e.app))return Promise.reject(m(e,"o
11peration-not-supported-in-this-environment"));let i=eT(e);f(e,t,eZ);let a=tW(i,r);return new t2(i,"signInViaPopup",t,a).executeNotNull()}async function t1(e,t,r){let i=(0,a.Ku)(e);f(i.auth,t,eZ);let n=tW(i.auth,r);return new t2(i.auth,"linkViaPopup",t,n,i).executeNotNull()}class t2 extends tX{constructor(e,t,r,i,n){super(e,t,i,n),this.provider=r,this.authWindow=null,this.pollId=null,t2.currentPopupAction&&t2.currentPopupAction.cancel(),t2.currentPopupAction=this}async executeNotNull(){let e=await this.execute();return v(e,this.auth,"internal-error"),e}async onExecution(){var e,t;e=1===this.filter.length,t="Popup operations only handle one event",e||w(t);let r=tA();this.authWindow=await this.resolver._openPopup(this.auth,this.provider,this.filter[0],r),this.authWindow.associatedEvent=r,this.resolver._originValidation(this.auth).catch(e=>{this.reject(e)}),this.resolver._isIframeWebStorageSupported(this.auth,e=>{e||this.reject(m(this.auth,"web-storage-unsupported"))}),this.pollUserCancellation()}get eventId(){return this.authWindow?.associatedEvent||null}cancel(){this.reject(m(this.auth,"cancelled-popup-request"))}cleanUp(){this.authWindow&&this.authWindow.close(),this.pollId&&window.clearTimeout(this.pollId),this.authWindow=null,this.pollId=null,t2.currentPopupAction=null}pollUserCancellation(){let e=()=>{if(this.authWindow?.window?.closed){this.pollId=window.setTimeout(()=>{this.pollId=null,this.reject(m(this.auth,"popup-closed-by-user"))},8e3);return}this.pollId=window.setTimeout(e,tZ.get())};e()}}t2.currentPopupAction=null;let t3=new Map;class t4 extends tX{constructor(e,t,r=!1){super(e,["signInViaRedirect","linkViaRedirect","reauthViaRedirect","unknown"],t,void 0,r),this.eventId=null}async execute(){let e=t3.get(this.auth._key());if(!e){try{let t=await t5(this.resolver,this.auth)?await super.execute():null;e=()=>Promise.resolve(t)}catch(t){e=()=>Promise.reject(t)}t3.set(this.auth._key(),e)}return this.bypassAuthState||t3.set(this.auth._key(),()=>Promise.resolve(null)),e()}async onAuthEvent(e){if("signInViaRedirect"===e.type)return super.onAuthEvent(e);if("unknown"===e.type)return void this.resolve(null);if(e.eventId){let t=await this.auth._redirectUserForId(e.eventId);if(t)return this.user=t,super.onAuthEvent(e);this.resolve(null)}}async onExecution(){}cleanUp(){}}async function t5(e,t){var r;let i=ea("pendingRedirect",(r=t).config.apiKey,r.name),n=ei(e._redirectPersistence);if(!await n._isAvailable())return!1;let a=await n._get(i)==="true";return await n._remove(i),a}function t9(e,t){t3.set(e._key(),t)}async function t6(e,t,r=!1){if((0,n.xZ)(e.app))return Promise.reject(p(e));let i=eT(e),a=tW(i,t),s=new t4(i,a,r),o=await s.execute();return o&&!r&&(delete o.user._redirectEventId,await i._persistUserIfCurrent(o.user),await i._setRedirectUser(null,t)),o}class t8{constructor(e){this.auth=e,this.cachedEventUids=new Set,this.consumers=new Set,this.queuedRedirectEvent=null,this.hasHandledPotentialRedirect=!1,this.lastProcessedEventTime=Date.now()}registerConsumer(e){this.consumers.add(e),this.queuedRedirectEvent&&this.isEventForConsumer(this.queuedRedirectEvent,e)&&(this.sendToConsumer(this.queuedRedirectEvent,e),this.saveEventToCache(this.queuedRedirectEvent),this.queuedRedirectEvent=null)}unregisterConsumer(e){this.consumers.delete(e)}onEvent(e){if(this.hasEventBeenHandled(e))return!1;let t=!1;return this.consumers.forEach(r=>{this.isEventForConsumer(e,r)&&(t=!0,this.sendToConsumer(e,r),this.saveEventToCache(e))}),this.hasHandledPotentialRedirect||!function(e){switch(e.type){case"signInViaRedirect":case"linkViaRedirect":case"reauthViaRedirect":return!0;case"unknown":return re(e);default:return!1}}(e)||(this.hasHandledPotentialRedirect=!0,t||(this.queuedRedirectEvent=e,t=!0)),t}sendToConsumer(e,t){if(e.error&&!re(e)){let r=e.error.code?.split("auth/")[1]||"internal-error";t.onError(m(this.auth,r))}else t.onAuthEvent(e)}isEventForConsumer(e,t){let r=null===t.eventId||!!e.eventId&&e.eventId===t.eventId;return t.filter.includes(e.type)&&r}hasEventBeenHandled(e){return Date.now()-this.lastProcessedEventTime>=6e5&&this.cachedEventUids.clear(),this.cachedEventUids.has(t7(e))}saveEventToCache(e){this.cachedEventUids.add(t7(e)),this.lastProcessedEventTime=
11Date.now()}}function t7(e){return[e.type,e.eventId,e.sessionId,e.tenantId].filter(e=>e).join("-")}function re({type:e,error:t}){return"unknown"===e&&t?.code==="auth/no-auth-event"}async function rt(e,t={}){return R(e,"GET","/v1/projects",t)}let rr=/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,ri=/^https?/;async function rn(e){if(e.config.emulator)return;let{authorizedDomains:t}=await rt(e);for(let e of t)try{if(function(e){let t=b(),{protocol:r,hostname:i}=new URL(t);if(e.startsWith("chrome-extension://")){let n=new URL(e);return""===n.hostname&&""===i?"chrome-extension:"===r&&e.replace("chrome-extension://","")===t.replace("chrome-extension://",""):"chrome-extension:"===r&&n.hostname===i}if(!ri.test(r))return!1;if(rr.test(e))return i===e;let n=e.replace(/\./g,"\\.");return RegExp("^(.+\\."+n+"|"+n+")$","i").test(i)}(e))return}catch{}d(e,"unauthorized-domain")}let ra=new T(3e4,6e4);function rs(){let e=tR().___jsl;if(e?.H){for(let t of Object.keys(e.H))if(e.H[t].r=e.H[t].r||[],e.H[t].L=e.H[t].L||[],e.H[t].r=[...e.H[t].L],e.CP)for(let t=0;t<e.CP.length;t++)e.CP[t]=null}}let ro=null,rl=new T(5e3,15e3),ru={style:{position:"absolute",top:"-100px",width:"1px",height:"1px"},"aria-hidden":"true",tabindex:"-1"},rc=new Map([["identitytoolkit.googleapis.com","p"],["staging-identitytoolkit.sandbox.googleapis.com","s"],["test-identitytoolkit.sandbox.googleapis.com","t"]]);async function rh(e){let t,r,i,s,o,l=await (ro=ro||new Promise((t,r)=>{function i(){rs(),gapi.load("gapi.iframes",{callback:()=>{t(gapi.iframes.getContext())},ontimeout:()=>{rs(),r(m(e,"network-request-failed"))},timeout:ra.get()})}if(tR().gapi?.iframes?.Iframe)t(gapi.iframes.getContext());else if(tR().gapi?.load)i();else{var n;let t=ek("iframefcb");return tR()[t]=()=>{gapi.load?i():r(m(e,"network-request-failed"))},(n=`${eF.gapiScript}?onload=${t}`,eF.loadJS(n)).catch(e=>r(e))}}).catch(e=>{throw ro=null,e})),u=tR().gapi;return v(u,e,"internal-error"),l.open({where:document.body,url:(v((t=e.config).authDomain,e,"auth-domain-config-required"),r=t.emulator?S(t,"emulator/auth/iframe"):`https://${e.config.authDomain}/__/auth/iframe`,i={apiKey:t.apiKey,appName:e.name,v:n.MF},(s=rc.get(e.config.apiHost))&&(i.eid=s),(o=e._getFrameworks()).length&&(i.fw=o.join(",")),`${r}?${(0,a.Am)(i).slice(1)}`),messageHandlersFilter:u.iframes.CROSS_ORIGIN_IFRAMES_FILTER,attributes:ru,dontclear:!0},t=>new Promise(async(r,i)=>{await t.restyle({setHideOnLeave:!1});let n=m(e,"network-request-failed"),a=tR().setTimeout(()=>{i(n)},rl.get());function s(){tR().clearTimeout(a),r(t)}t.ping(s).then(s,()=>{i(n)})}))}let rd={location:"yes",resizable:"yes",statusbar:"yes",toolbar:"no"};class rm{constructor(e){this.window=e,this.associatedEvent=null}close(){if(this.window)try{this.window.close()}catch(e){}}}let rg=encodeURIComponent("fac");async function rp(e,t,r,i,s,o){v(e.config.authDomain,e,"auth-domain-config-required"),v(e.config.apiKey,e,"invalid-api-key");let l={apiKey:e.config.apiKey,appName:e.name,authType:r,redirectUrl:i,v:n.MF,eventId:s};if(t instanceof eZ)for(let[r,i]of(t.setDefaultLanguage(e.languageCode),l.providerId=t.providerId||"",(0,a.Im)(t.getCustomParameters())||(l.customParameters=JSON.stringify(t.getCustomParameters())),Object.entries(o||{})))l[r]=i;if(t instanceof e0){let e=t.getScopes().filter(e=>""!==e);e.length>0&&(l.scopes=e.join(","))}for(let t of(e.tenantId&&(l.tid=e.tenantId),Object.keys(l)))void 0===l[t]&&delete l[t];let u=await e._getAppCheckToken(),c=u?`#${rg}=${encodeURIComponent(u)}`:"";return`${function({config:e}){return e.emulator?S(e,"emulator/auth/handler"):`https://${e.authDomain}/__/auth/handler`}(e)}?${(0,a.Am)(l).slice(1)}${c}`}let rf="webStorageSupport";class ry{constructor(){this.eventManagers={},this.iframes={},this.originValidationPromises={},this._redirectPersistence=tk,this._completeRedirectFn=t6,this._overrideRedirectResult=t9}async _openPopup(e,t,r,i){var n,s;n=this.eventManagers[e._key()]?.manager,s="_initialize() not called before _openPopup()",n||w(s);let o=await rp(e,t,r,b(),i);return function(e,t,r,i=500,n=600){let s=Math.max((window.screen.availHeight-n)/2,0).toString(),o=Math.max((window.screen.availWi
11dth-i)/2,0).toString(),l="",u={...rd,width:i.toString(),height:n.toString(),top:s,left:o},c=(0,a.ZQ)().toLowerCase();r&&(l=ec(c)?"_blank":r),el(c)&&(t=t||"http://localhost",u.scrollbars="yes");let h=Object.entries(u).reduce((e,[t,r])=>`${e}${t}=${r},`,"");if(function(e=(0,a.ZQ)()){return ep(e)&&!!window.navigator?.standalone}(c)&&"_self"!==l){var d,m;let e,r;return d=t||"",m=l,(e=document.createElement("a")).href=d,e.target=m,(r=document.createEvent("MouseEvent")).initMouseEvent("click",!0,!0,window,1,0,0,0,0,!1,!1,!1,!1,1,null),e.dispatchEvent(r),new rm(null)}let g=window.open(t||"",l,h);v(g,e,"popup-blocked");try{g.focus()}catch(e){}return new rm(g)}(e,o,tA())}async _openRedirect(e,t,r,i){var n;return await this._originValidation(e),n=await rp(e,t,r,b(),i),tR().location.href=n,new Promise(()=>{})}_initialize(e){let t=e._key();if(this.eventManagers[t]){var r;let{manager:e,promise:i}=this.eventManagers[t];return e?Promise.resolve(e):(r="If manager is not set, promise should be",i||w(r),i)}let i=this.initAndGetManager(e);return this.eventManagers[t]={promise:i},i.catch(()=>{delete this.eventManagers[t]}),i}async initAndGetManager(e){let t=await rh(e),r=new t8(e);return t.register("authEvent",t=>(v(t?.authEvent,e,"invalid-auth-event"),{status:r.onEvent(t.authEvent)?"ACK":"ERROR"}),gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER),this.eventManagers[e._key()]={manager:r},this.iframes[e._key()]=t,r}_isIframeWebStorageSupported(e,t){this.iframes[e._key()].send(rf,{type:rf},r=>{let i=r?.[0]?.[rf];void 0!==i&&t(!!i),d(e,"internal-error")},gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER)}_originValidation(e){let t=e._key();return this.originValidationPromises[t]||(this.originValidationPromises[t]=rn(e)),this.originValidationPromises[t]}get _shouldInitProactively(){return ef()||eu()||ep()}}class rv{constructor(e){this.factorId=e}_process(e,t,r){switch(t.type){case"enroll":return this._finalizeEnroll(e,t.credential,r);case"signin":return this._finalizeSignIn(e,t.credential);default:return w("unexpected MultiFactorSessionType")}}}class rw extends rv{constructor(e){super("phone"),this.credential=e}static _fromCredential(e){return new rw(e)}_finalizeEnroll(e,t,r){return R(e,"POST","/v2/accounts/mfaEnrollment:finalize",_(e,{idToken:t,displayName:r,phoneVerificationInfo:this.credential._makeVerificationRequest()}))}_finalizeSignIn(e,t){return R(e,"POST","/v2/accounts/mfaSignIn:finalize",_(e,{mfaPendingCredential:t,phoneVerificationInfo:this.credential._makeVerificationRequest()}))}}class rb{static assertion(e){return rw._fromCredential(e)}}rb.FACTOR_ID="phone";class rC{static assertionForEnrollment(e,t){return rT._fromSecret(e,t)}static assertionForSignIn(e,t){return rT._fromEnrollmentId(e,t)}static async generateSecret(e){var t;v(void 0!==e.user?.auth,"internal-error");let r=await R(t=e.user.auth,"POST","/v2/accounts/mfaEnrollment:start",_(t,{idToken:e.credential,totpEnrollmentInfo:{}}));return rS._fromStartTotpMfaEnrollmentResponse(r,e.user.auth)}}rC.FACTOR_ID="totp";class rT extends rv{constructor(e,t,r){super("totp"),this.otp=e,this.enrollmentId=t,this.secret=r}static _fromSecret(e,t){return new rT(t,void 0,e)}static _fromEnrollmentId(e,t){return new rT(t,e)}async _finalizeEnroll(e,t,r){return v(void 0!==this.secret,e,"argument-error"),R(e,"POST","/v2/accounts/mfaEnrollment:finalize",_(e,{idToken:t,displayName:r,totpVerificationInfo:this.secret._makeTotpVerificationInfo(this.otp)}))}async _finalizeSignIn(e,t){v(void 0!==this.enrollmentId&&void 0!==this.otp,e,"argument-error");let r={verificationCode:this.otp};return R(e,"POST","/v2/accounts/mfaSignIn:finalize",_(e,{mfaPendingCredential:t,mfaEnrollmentId:this.enrollmentId,totpVerificationInfo:r}))}}class rS{constructor(e,t,r,i,n,a,s){this.sessionInfo=a,this.auth=s,this.secretKey=e,this.hashingAlgorithm=t,this.codeLength=r,this.codeIntervalSeconds=i,this.enrollmentCompletionDeadline=n}static _fromStartTotpMfaEnrollmentResponse(e,t){return new rS(e.totpSessionInfo.sharedSecretKey,e.totpSessionInfo.hashingAlgorithm,e.totpSessionInfo.verificationCodeLength,e.totpSessionInfo.periodSec,new Date(e.totpSessionInfo.finalizeEnrollmentTime).toUTCString(),e.totpSessionInfo.sessionInfo,t)}_makeTotpVerificationInfo(e){return{sessionInfo:this.sessionInfo,verificationCode:e}}generateQrCodeUrl(e,t){let r=!1;return(rF(e)||rF(t))&&(r=!0),r&&(rF(e)&&(e=this.auth.currentUser?.email||"unknownuser"),rF(t)&&(t=this.auth.name)),`otpauth://totp/${t}:${e}?secret=${this.secretKey}&issuer=${t}&algorithm=${this.hashingAlgorithm}&digits=${this.codeLength}`}}function rF(e){return void 0===e||e?.length===0}
11var rk="@firebase/auth",rE="1.12.0";class rA{constructor(e){this.auth=e,this.internalListeners=new Map}getUid(){return this.assertAuthConfigured(),this.auth.currentUser?.uid||null}async getToken(e){return(this.assertAuthConfigured(),await this.auth._initializationPromise,this.auth.currentUser)?{accessToken:await this.auth.currentUser.getIdToken(e)}:null}addAuthTokenListener(e){if(this.assertAuthConfigured(),this.internalListeners.has(e))return;let t=this.auth.onIdTokenChanged(t=>{e(t?.stsTokenManager.accessToken||null)});this.internalListeners.set(e,t),this.updateProactiveRefresh()}removeAuthTokenListener(e){this.assertAuthConfigured();let t=this.internalListeners.get(e);t&&(this.internalListeners.delete(e),t(),this.updateProactiveRefresh())}assertAuthConfigured(){v(this.auth._initializationPromise,"dependent-sdk-initialized-before-auth")}updateProactiveRefresh(){this.internalListeners.size>0?this.auth._startProactiveRefresh():this.auth._stopProactiveRefresh()}}let r_=(0,a.XA)("authIdTokenMaxAge")||300,rR=null;function rI(e=(0,n.Sx)()){let t=(0,n.j6)(e,"auth");if(t.isInitialized())return t.getImmediate();let r=function(e,t){let r=(0,n.j6)(e,"auth");if(r.isInitialized()){let e=r.getImmediate(),i=r.getOptions();if((0,a.bD)(i,t??{}))return e;d(e,"already-initialized")}return r.initialize({options:t})}(e,{popupRedirectResolver:ry,persistence:[tV,tC,tk]}),i=(0,a.XA)("authTokenSyncURL");if(i&&"boolean"==typeof isSecureContext&&isSecureContext){let e=new URL(i,location.origin);if(location.origin===e.origin){let t,i=(t=e.toString(),async e=>{let r=e&&await e.getIdTokenResult(),i=r&&(new Date().getTime()-Date.parse(r.issuedAtTime))/1e3;if(i&&i>r_)return;let n=r?.token;rR!==n&&(rR=n,await fetch(t,{method:n?"POST":"DELETE",headers:n?{Authorization:`Bearer ${n}`}:{}}))});(0,a.Ku)(r).beforeAuthStateChanged(i,()=>i(r.currentUser)),(0,a.Ku)(r).onIdTokenChanged(e=>i(e),void 0,void 0)}}let s=(0,a.Tj)("auth");return s&&function(e,t){let r=eT(e);v(/^https?:\/\//.test(t),r,"invalid-emulator-scheme");let i=eM(t),{host:n,port:s}=function(e){let t=eM(e),r=/(\/\/)?([^?#/]+)/.exec(e.substr(t.length));if(!r)return{host:"",port:null};let i=r[2].split("@").pop()||"",n=/^(\[[^\]]+\])(:|$)/.exec(i);if(n){let e=n[1];return{host:e,port:eP(i.substr(e.length+1))}}{let[e,t]=i.split(":");return{host:e,port:eP(t)}}}(t),o=null===s?"":`:${s}`,l={url:`${i}//${n}${o}/`},u=Object.freeze({host:n,port:s,protocol:i.replace(":",""),options:Object.freeze({disableWarnings:!1})});if(!r._canInitEmulator){v(r.config.emulator&&r.emulatorConfig,r,"emulator-config-failed"),v((0,a.bD)(l,r.config.emulator)&&(0,a.bD)(u,r.emulatorConfig),r,"emulator-config-failed");return}r.config.emulator=l,r.emulatorConfig=u,r.settings.appVerificationDisabledForTesting=!0,(0,a.zJ)(n)?((0,a.gE)(`${i}//${n}${o}`),(0,a.P1)("Auth",!0)):function(){function e(){let e=document.createElement("p"),t=e.style;e.innerText="Running in emulator mode. Do not use with production credentials.",t.position="fixed",t.width="100%",t.backgroundColor="#ffffff",t.border=".1em solid #000000",t.color="#b50000",t.bottom="0px",t.left="0px",t.margin="0px",t.zIndex="10000",t.textAlign="center",e.classList.add("firebase-emulator-warning"),document.body.appendChild(e)}"u">typeof console&&"function"==typeof console.info&&console.info("WARNING: You are using the Auth Emulator, which is intended for local testing only. Do not use with production credentials."),"u">typeof window&&"u">typeof document&&("loading"===document.readyState?window.addEventListener("DOMContentLoaded",e):e())}()}(r,`http://${s}`),r}eF={loadJS:e=>new Promise((t,r)=>{let i=document.createElement("script");i.setAttribute("src",e),i.onload=t,i.onerror=e=>{let t=m("internal-error");t.customData=e,r(t)},i.type="text/javascript",i.charset="UTF-8",(document.getElementsByTagName("head")?.[0]??document).appendChild(i)}),gapiScript:"https://apis.google.com/js/api.js",recaptchaV2Script:"https://www.google.com/recaptcha/api.js",recaptchaEnterpriseScript:"https://www.google.com/recaptcha/enterprise.js?render="},i="Browser",(0,n.om)(new o.uA("auth",(e,{options:t})=>{let r,n,a=e.getProvider("app").getImmediate(),s=e.getProvider("heartbeat"),o=e.getProvider("app-check-internal"),{apiKey:l,authDomain:u}=a.options;v(l&&!l.includes(":"),"invalid-api-key",{appName:a.name});let c=new eC(a,s,o,{apiKey:l,authDomain:u,clientPlatform:i,apiHost:"identitytoolkit.googleapis.com",tokenApiHost:"securetoken.googleapis.com",apiScheme:"https",sdkClientVersion:ey(i)});return n=(Array.isArray(r=t?.persistence||[])?r:[r]).map(ei),t?.errorMap&&c._updateErrorMap(t.errorMap),c._initializeWithPersistence(n,t?.popupRedirectResolver),c},"PUBLIC").setInstantiationMode("EXPLICIT").setInstanceCreatedCallback((e,t,r)=>{e.getProvider("auth-internal").initialize()})),(0,n.om)(new o.uA("auth-internal",e=>new rA(eT(e.getProvider("auth").getImmediate())),"PRIVATE").setInstantiationMode("EXPLICIT")),(0,n.KO)(rk,rE,function(e){switch(e){case"Node":return"node";case"ReactNative":return"rn";case"Worker":return"webworker";case"Cordova":return"cordova";case"WebExtension":return"web-extension";default:return}}(i)),(0,n.KO)(rk,rE,"esm2020")},58499:(e,t,r)=>{"use strict";
11Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"useMergedRef",{enumerable:!0,get:function(){return n}});let i=r(14232);function n(e,t){let r=(0,i.useRef)(null),n=(0,i.useRef)(null);return(0,i.useCallback)(i=>{if(null===i){let e=r.current;e&&(r.current=null,e());let t=n.current;t&&(n.current=null,t())}else e&&(r.current=a(e,i)),t&&(n.current=a(t,i))},[e,t])}function a(e,t){if("function"!=typeof e)return e.current=t,()=>{e.current=null};{let r=e(t);return"function"==typeof r?r:()=>e(null)}}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},62818:function(e,t,r){"use strict";var i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.sendGTMEvent=void 0,t.GoogleTagManager=function(e){let{gtmId:t,gtmScriptUrl:r,dataLayerName:i="dataLayer",auth:l,preview:u,dataLayer:c,nonce:h}=e;o=i;let d=new URL(r||"https://www.googletagmanager.com/gtm.js");return t&&d.searchParams.set("id",t),"dataLayer"!==i&&d.searchParams.set("l",i),l&&d.searchParams.set("gtm_auth",l),u&&(d.searchParams.set("gtm_preview",u),d.searchParams.set("gtm_cookies_win","x")),(0,a.useEffect)(()=>{performance.mark("mark_feature_usage",{detail:{feature:"next-third-parties-gtm"}})},[]),(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.default,{id:"_next-gtm-init",dangerouslySetInnerHTML:{__html:` 12 (function(w,l){ 13 w[l]=w[l]||[]; 14 w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'}); 15 ${c?`w[l].push(${JSON.stringify(c)})`:""} 16 })(window,'${i}');`},nonce:h}),(0,n.jsx)(s.default,{id:"_next-gtm","data-ntpc":"GTM",src:d.href,nonce:h})]})};let n=r(37876),a=r(14232),s=i(r(45105)),o="dataLayer";t.sendGTMEvent=(e,t)=>{let r=t||o;window[r]=window[r]||[],window[r].push(e)}},69543:(e,t,r)=>{"use strict";function i(e,t,r,i){return!1}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getDomainLocale",{enumerable:!0,get:function(){return i}}),r(81623),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},73513:e=>{"use strict";e.exports=JSON.parse('{"id":"google-analytics","description":"Install a Google Analytics tag on your website","website":"https://analytics.google.com/analytics/web/","scripts":[{"url":"https://www.googletagmanager.com/gtag/js","params":["id"],"strategy":"worker","location":"head","action":"append"},{"code":"window.dataLayer=window.dataLayer||[];window.gtag=function gtag(){window.dataLayer.push(arguments);};gtag(\'js\',new Date());gtag(\'config\',\'${args.id}\')","strategy":"worker","location":"head","action":"append"}]}')},74880:(e,t,r)=>{"use strict";r.d(t,{Y:()=>s});let i=JSON.parse('[{"name":"Amtrak","slug":"amtrak","metric":false,"cities":[],"countries":["United States"],"color":"#18567d","darkerColor":"#002e55","textColor":"#FFFFFF","shortForms":["Amtrak"],"summary":"Amtrak is the national passenger railroad service of the United States.","history":"Amtrak, a combination of the words \'America\' and \'track\', was established in 1971 to take over most of the country\'s intercity passenger rail services. It was created in response to the decline of private passenger rail services, as many railroads were facing bankruptcy. Amtrak has since become an essential part of the U.S. transportation system, operating a nationwide rail network that serves over 500 destinations across 46 states. Despite facing financial challenges and competition from other modes of transport, Amtrak has continued to modernize its fleet and expand its services, including the introduction of high-speed Acela trains in the Northeast Corridor.","stats":[{"label":"Route Miles","value":"21,400"},{"label":"Annual Ridership","value":"32m"},{"label":"Year Founded","value":"1971"},{"label":"Stations Served","value":"500+"}],"websiteUrl":"https://www.amtrak.com","map":{"lat":39.8283,"lng":-98.5795,"zoom":4},"vehicleClassificationOverride":"intercity_rail"},{"name":"Alaska Railroad","slug":"alaska-railroad","metric":false,"cities":[],"countries":["United States"],"color":"#00563F","darkerColor":"#003B2B","textColor":"#FFFFFF","shortForms":["Alaska Railroad","ARR"],"summary":"The Alaska Railroad operates year-round and seasonal passenger trains between Seward, Anchorage, Denali and Fairbanks, including the Coastal Classic, Denali Star, Glacier Discovery, Hurricane Turn and Aurora Winter trains.","history":"Completed in 1923, the Alaska Railroad connects nearly 500 miles of Southcentral and Interior Alaska. It is owned by the State of Alaska and carries both passengers and freight through remote communities, national park country and areas accessible only by rail.","stats":[{"label":"Completed","value":"1923"},{"label":"Main Line","value":"470 mi"},{"label":"Passenger Routes","value":"5"}],"websiteUrl":"https://www.alaskarailroad.com","gtfsEnabled":true,"map":{"lat":62.7,"lng":-149.2,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"VIA Rail","slug":"via","metric":true,"cities":[],"countries":["Canada"],"color":"#FFCC00","darkerColor":"#d7a400","textColor":"#000000","shortForms":["VIA","VIA Rail"],"summary":"VIA Rail Canada is the national passenger rail service of Canada.","history":"VIA Rail Canada was established in 1977 as an independent crown corporation to provide intercity passenger rail services in Canada. It was created to take over the passenger services previously operated by Canadian National (CN) and Canadian Pacific (CP) railways. Since its inception, VIA Rail has played a crucial role in connecting Canadian communities, operating on a network that spans from the Atlantic to the Pacific coasts. Despite facing challenges such as budget cuts and route reductions over the years, VIA Rail has continued to modernize its services and fleet, including plans for new corridors and high-frequency rail projects to improve passenger rail transportation in Canada.","stats":[{"label":"Route Kilometers","value":"12,500"},{"label":"Annual Ridership","value":"5m"},{"label":"Year Founded","value":"1977"},{"label":"Stations Served","value":"400+"}],"websiteUrl":"https://www.viarail.ca","gtfsEnabled":true,"map":{"lat":56.1304,"lng":-95.3468,"zoom":3},"vehicleClassificationOverride":"intercity_rail"},{"name":"SunRail","slug":"sunrail","metric":false,"cities":["orlando"],"color":"#FFBF00","darkerColor":"#d79700","textColor":"#000000","shortForms":["SunRail"],"summary":"SunRail is a commuter rail system serving the Greater Orlando, Florida area.","history":"SunRail was conceived to improve transportation in Central Florida and reduce car dependency. After overcoming various challenges including funding and liability issues, the project was approved with federal, state, and local funding. The first phase,
16covering 31 miles with 12 stations, launched in 2014. A southern extension in 2018 added 17.2 miles and four stations to the system.","stats":[{"label":"Route Miles","value":"61.5"},{"label":"Stations","value":"16"},{"label":"Year Founded","value":"2014"},{"label":"Counties Served","value":"4"}],"websiteUrl":"https://sunrail.com","map":{"lat":28.5383,"lng":-81.3792,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Massachusetts Bay Transportation Authority","slug":"mbta","metric":false,"cities":["boston"],"color":"#3A89C9","darkerColor":"#1261a1","textColor":"#FFFFFF","shortForms":["MBTA","The T"],"summary":"The Massachusetts Bay Transportation Authority (MBTA) is the principal public transportation operator in the Greater Boston area, providing subway, bus, commuter rail, and ferry services.","history":"The MBTA\'s roots trace back to the 19th century, evolving from private commuter rail and horsecar lines to an electrified system. It succeeded the Metropolitan Transit Authority in 1964, expanding to serve a broader region. The MBTA became part of the Massachusetts Department of Transportation in 2009, reflecting its integral role in the state\'s transportation network.","stats":[{"label":"Subway Lines","value":"4"},{"label":"Annual Ridership","value":"380m"},{"label":"Year Founded","value":"1964"},{"label":"Area Square Miles","value":"3244"}],"websiteUrl":"https://www.mbta.com","map":{"lat":42.3601,"lng":-71.0589,"zoom":11},"vehicleClassificationOverride":"subway_default"},{"name":"Chicago Transit Authority","slug":"cta","metric":false,"cities":["chicago"],"color":"#ff0000","darkerColor":"#d70000","textColor":"#FFFFFF","shortForms":["CTA"],"summary":"The Chicago Transit Authority (CTA) operates the \'L\' train network, Chicago\'s rapid transit system and one of the largest in the United States.","history":"The origins of Chicago\'s \'L\' train system date back to 1892, making it the second-oldest rapid transit system in the Americas. The system has been managed by the Chicago Transit Authority since its inception and has evolved into an extensive network with multiple lines and stations, connecting various parts of the city and suburbs. The \'L\' has been recognized for its role in shaping the city\'s dense core and is considered one of the \'seven wonders of Chicago\'.","stats":[{"label":"Route Miles","value":"102.8"},{"label":"Stations","value":"145"},{"label":"Annual Ridership","value":"230m"}],"websiteUrl":"https://www.transitchicago.com","map":{"lat":41.8781,"lng":-87.6298,"zoom":11},"vehicleClassificationOverride":"subway_default"},{"name":"Metra Metropolitan Rail","slug":"metra","metric":false,"cities":["chicago"],"color":"#005195","darkerColor":"#00296d","textColor":"#FFFFFF","shortForms":["Metra"],"summary":"Metra operates in the Chicago metropolitan area, providing commuter rail services between the city of Chicago and its surrounding suburbs.","history":"Metra was established in 1984 as a public transportation provider in Chicago. Since its inception, it has evolved to become a key component of the region\'s transportation network, expanding its services and infrastructure to meet the growing needs of the metropolitan area. Metra\'s development over the years reflects the changing dynamics of urban transportation and the increasing reliance on efficient commuter rail services.","stats":[{"label":"Rail Lines","value":"11"},{"label":"Year Founded","value":"1984"},{"label":"Route Miles","value":"487.5"},{"label":"Annual Ridership","value":"62.4m"}],"websiteUrl":"https://metra.com","map":{"lat":41.8781,"lng":-87.6298,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"South Shore Line","slug":"southshore","metric":false,"cities":["chicago"],"color":"#000000","darkerColor":"#000000","textColor":"#FFFFFF","shortForms":["SSL","South Shore"],"summary":"The South Shore Line, operated by the Northern Indiana Commuter Transportation District (NICTD), is a notable commuter rail line running between downtown Chicago and South Bend, Indiana. It\'s one of the last surviving interurban trains in the United States.","history":"The South Shore Line\'
16s history dates back to the early 20th century, initially constructed between 1901 and 1908 as the Chicago and Indiana Air Line Railway. It was reorganized in 1904 as the Chicago, Lake Shore and South Bend Railway. In 1989, passenger operation was assumed by the NICTD. Today, it remains a key component of the region\'s transportation infrastructure, blending historical significance with modern commuter services.","stats":[{"label":"Route Length","value":"90"},{"label":"Year Founded","value":"1901"},{"label":"Stations","value":"33"},{"label":"Annual Ridership","value":"3.4m"}],"websiteUrl":"https://www.mysouthshoreline.com","map":{"lat":41.8781,"lng":-87.6298,"zoom":8},"vehicleClassificationOverride":"commuter_rail"},{"name":"Metrolink","slug":"metrolink","metric":false,"cities":["los-angeles"],"color":"#0075de","darkerColor":"#004db6","textColor":"#FFFFFF","shortForms":["Metrolink"],"summary":"Metrolink is a commuter rail system serving Southern California, primarily the Los Angeles metropolitan area and neighboring counties.","history":"Founded in 1991 as the Southern California Regional Rail Authority (SCRRA), Metrolink began operations in 1992. It was established to provide regional commuter rail service and reduce traffic congestion across Southern California. Over the years, it has expanded and upgraded to enhance service efficiency and safety, becoming an integral part of the region\'s public transportation network.","stats":[{"label":"Lines","value":"8"},{"label":"Stations","value":"69"},{"label":"Track miles","value":"545.6"},{"label":"Year Founded","value":"1991"}],"websiteUrl":"https://metrolinktrains.com","map":{"lat":34.0522,"lng":-118.2437,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"Metro Transit","slug":"metrotransit","metric":false,"cities":["minneapolis"],"color":"#0047AB","darkerColor":"#001f83","textColor":"#FFFFFF","shortForms":["Metro Transit"],"summary":"Metro Transit operates two light rail lines (Blue and Green) in the Twin Cities region of Minnesota, primarily serving Minneapolis and St. Paul. These lines connect key locations including the Minneapolis-St. Paul International Airport.","history":"Metro Transit\'s history began in 1970 with the acquisition of the Twin City Lines bus system. The 1990s saw renewed interest in light rail transit, leading to the Blue Line in 2004 and the Green Line in 2014. Initially under the Metropolitan Council Transit Operations, it was rebranded as Metro Transit in 1997. The network continues to evolve with ongoing expansion plans and upgrades to existing lines.","stats":[{"label":"Light Rail Lines","value":"2"},{"label":"Year Founded","value":"1970"}],"websiteUrl":"https://www.metrotransit.org","map":{"lat":44.9778,"lng":-93.265,"zoom":11},"vehicleClassificationOverride":"streetcar"},{"name":"Exo","slug":"exo","metric":true,"cities":["montreal"],"color":"#000000","darkerColor":"#000000","textColor":"#FFFFFF","shortForms":["exo"],"summary":"EXO operates a comprehensive public transit system that includes both train and bus services in the Greater Montreal area, including the Island of Montreal, Laval, and communities along the North Shore of the Mille-\xceles River and the South Shore of the St. Lawrence River.","history":"EXO, formerly known as R\xe9seau de transport m\xe9tropolitain (RTM), has historical roots dating back to the late 19th century. In 2017, operations transitioned from CN and CP to Bombardier Transportation. The network comprises five train lines, each with its own rich history: VaudreuilâHudson (est. 1887), Saint-J\xe9r\xf4me (1882), Mont-Saint-Hilaire (1859), Candiac (1887), and Mascouche (2014).","stats":[{"label":"Train Lines","value":"5"},{"label":"Stations","value":"52"},{"label":"Founded (Exo)","value":"2017"}],"websiteUrl":"https://exo.quebec/en","map":{"lat":45.5017,"lng":-73.5673,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Long Island Railroad","slug":"lirr","metric":false,"cities":["new-york"],"color":"#FFBF00","darkerColor":"#d79700","textColor":"#000000","shortForms":["LIRR"],"summary":"LIRR: NYC to Long Island commuter rail","history":"Chartered in 1834 as the Brooklyn and Jamaica Rail Road, the LIRR initially aimed to provide a faster route between New York and Boston. The first section opened in 1836, extending to Greenport by 1844. After facing challenges in the mid-1800s, it refocused on local services. The Pennsylvania Railroad\'s acquisition in the late 19th century led to extensive modernization. Despite bankruptcy in 1949 due to increased automobile competition, the MTA\'s acquisition in 1965 brought a resurgence. Today, after over 185 years, it remains the busiest commuter railroad in the United States.","stats":[{"label":"Stations","value":"124"},{"label":"Track miles","value":"700+"},{"label":"Annual Ridership","value":"81m"},{"label":"Year Founded","value":"1834"}],"websiteUrl":"https://new.mta.info/agency/long-island-rail-road","map":{"lat":40.7128,"lng":-73.5951,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"Metro-North Railroad","slug":"mnr","metric":false,"cities":["new-york"],"color":"#0039A6","darkerColor":"#00117e","textColor":"#FFFFFF","shortForms":["Metro-North","MNR"],"summary":"Metro North Railroad: MTA-operated commuter rail serving NYC and suburbs, 412 miles, 120 stations.","history":"The origins of Metro North Railroad date back to the early 19th century, evolving from the services of legendary railroads like the New York Central, New Haven, and Erie Railroads. These lines were consolidated under Conrail following several mergers. The commuter operations were divested by Conrail in 1982, leading to the establishment of the Metro North Commuter Railroad on January 1, 1983. This transition marked a new era in the New York metropolitan area\'s public transportation, with the Metro North Railroad becoming a critical component of the MTA. Over the years, the system has seen significant investments and upgrades, including extended services, modernized rolling stock, and improved facilities, especially at Grand Central Terminal. The railroad\'s evolution reflects the changing demands of commuter transportation in one of the world\'s busiest metropolitan areas.","stats":[{"label":"Route Miles","value":"412"},{"label":"Stations","value":"120"},{"label":"Daily Ridership","value":"+240k"},{"label":"Year Founded","value":"1983"}],"websiteUrl":"https://new.mta.info/agency/metro-north-railroad","map":{"lat":41.034,"lng":-73.7629,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"Southeastern Pennsylvania Transportation Authority","slug":"septa","metric":false,"cities":["philadelphia"],"color":"#F14728","darkerColor":"#c91f00","textColor":"#FFFFFF","shortForms":["SEPTA"],"summary":"SEPTA: Major transit provider for Philadelphia and surrounding counties, operating diverse transit modes.","history":"SEPTA was established by the Pennsylvania legislature on August 17, 1963, and commenced operations on February 18, 1964. It was created to coordinate government funding for various transit and railroad companies in southeastern Pennsylvania. Over time, SEPTA expanded by acquiring various transportation companies and lines, including the Philadelphia Transportation Company (PTC) in 1968 and the Philadelphia Suburban Transportation Company in 1970. In 1983, SEPTA took over the direct operation of the region\'s commuter rail lines, marking a significant expansion of its services.","stats":[{"label":"Annual Ridership","value":"302m"},{"label":"Active Stations","value":"290"},{"label":"Track Miles","value":"450+"},{"label":"Routes","value":"196"}],"websiteUrl":"http://www.septa.org","map":{"lat":39.9526,"lng":-75.1652,"zoom":11},"vehicleClassificationOverride":"subway_default"},{"name":"Utah Transit Authority","slug":"uta","metric":false,"cities":["salt-lake-city"],"color":"#EC1C24","dar
16kerColor":"#c40000","textColor":"#FFFFFF","shortForms":["UTA"],"summary":"The Utah Transit Authority (UTA) operates a comprehensive public transportation system in the Wasatch Front of Utah, including major metropolitan areas like Ogden, Park City, Provo, Salt Lake City, and Tooele. UTA\'s services include an extensive bus network, the TRAX light rail system, and the FrontRunner commuter rail.","history":"UTA began in the 1970s by expanding and streamlining bus services in the Salt Lake Valley. The first TRAX light rail line opened in 1999, connecting downtown Salt Lake City to Sandy. This was followed by additional lines and extensions, including the FrontRunner commuter rail service in 2008. Over the years, UTA has continuously expanded its network to include more areas and introduced services like express buses and seasonal ski buses, adapting to meet the growing transportation needs of Utah\'s urban and suburban populations.","stats":[{"label":"Light Rail Lines","value":"3"},{"label":"Commuter Rail","value":"1"},{"label":"Year Founded","value":"1970"}],"websiteUrl":"https://www.rideuta.com","map":{"lat":40.7608,"lng":-111.891,"zoom":11},"vehicleClassificationOverride":"streetcar"},{"name":"Caltrain","slug":"caltrain","metric":false,"cities":["san-francisco"],"color":"#d0343e","darkerColor":"#a80c16","textColor":"#FFFFFF","shortForms":["Caltrain"],"summary":"Caltrain: SF Peninsula-Santa Clara Valley commuter rail, SF to San Jose/Gilroy.","history":"Caltrain\'s history dates back to 1863 when the San Francisco & San Jose Railroad built the original commuter line. Southern Pacific (SP) purchased it in 1870 and made improvements, including double-tracking in 1904. After a post-1945 ridership decline, Caltrans intervened in 1980 to preserve the service. In 1987, the Peninsula Corridor Joint Powers Board was formed to manage the line, purchasing it from SP in 1991. The following year, PCJPB took over Caltrain operations, selecting Amtrak as the contract operator, and extended service to Gilroy.","stats":[{"label":"Route Miles","value":"77"},{"label":"Regular Stops","value":"28"},{"label":"Year Founded","value":"1863"},{"label":"Ridership","value":"+65k"}],"websiteUrl":"https://www.caltrain.com","map":{"lat":37.7749,"lng":-122.4194,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"GO Transit","slug":"go","metric":true,"cities":["toronto","hamilton-ontario","kitchener-ontario","burlington-ontario","niagara-falls-ontario"],"color":"#3CB371","darkerColor":"#148b49","textColor":"#FFFFFF","shortForms":["GO"],"summary":"GO Transit is the regional public transit service for the Greater Toronto and Hamilton Area in Ontario, Canada.","history":"GO Transit was established in 1967 as a single train line along Lake Ontario\'s shoreline. It has since expanded to become an extensive network of trains and buses serving a population of more than seven million across more than 11,000 square kilometers (4,200 sq mi) stretching from Hamilton and Kitchener-Waterloo in the west to Newcastle and Peterborough in the east, and from Orangeville, Barrie, and Beaverton in the north to Niagara Falls in the south. GO Transit has played a crucial role in connecting communities and reducing traffic congestion in the Greater Toronto Area.","stats":[{"label":"Annual Ridership","value":"57m"},{"label":"Year Founded","value":"1967"},{"label":"Train Lines","value":"7"},{"label":"Bus Routes","value":"46"}],"websiteUrl":"https://www.gotransit.com","map":{"lat":43.6532,"lng":-79.3832,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"Toronto Transit Commission","slug":"ttc","metric":true,"cities":["toronto"],"color":"#DA251D","darkerColor":"#b20000","textColor":"#FFFFFF","shortForms":["TTC"],"summary":"The Toronto Transit Commission (TTC) is the public transport agency that operates transit bus, streetcar, paratransit, and rapid transit services in Toronto, Ontario, Canada.","history":"The TTC was established in 1921 to consolidate and operate the various privately owned and municipal transit systems in Toronto. Over the years, it has grown to become North America\'s third-largest transit system b
16y ridership, after New York City and Mexico City. The TTC has played a crucial role in Toronto\'s development, with its subway system opening in 1954 and continually expanding. Despite challenges such as funding issues and aging infrastructure, the TTC remains an integral part of Toronto\'s urban fabric, constantly working to improve service and adopt new technologies to enhance the passenger experience.","stats":[{"label":"Annual Ridership","value":"527m"},{"label":"Year Founded","value":"1921"},{"label":"Subway Lines","value":"4"},{"label":"Streetcar Routes","value":"11"}],"websiteUrl":"https://www.ttc.ca","map":{"lat":43.6532,"lng":-79.3832,"zoom":11},"vehicleClassificationOverride":"streetcar"},{"name":"UP Express","slug":"up","metric":true,"cities":["toronto"],"color":"#000000","darkerColor":"#000000","textColor":"#FFFFFF","shortForms":["UP Express","UPX"],"summary":"UP Express: Fast rail service between downtown Toronto and Pearson Airport.","history":"The concept of improved transit to Pearson Airport originated in the late 1980s. After various studies and proposals, Metrolinx took over the project in 2010. Construction began in 2011 as part of the Georgetown South Project. The UP Express service launched on June 6, 2015. Initially criticized for high fares, the service underwent a fare reduction in 2016 to increase accessibility.","stats":[{"label":"Year Launched","value":"2015"},{"label":"Travel Time","value":"25 mins"},{"label":"Stations","value":"4"}],"websiteUrl":"https://www.upexpress.com","map":{"lat":43.6532,"lng":-79.3832,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"Maryland Area Rail Commuter","slug":"marc","metric":false,"cities":["washington-dc","baltimore"],"color":"#a5272d","darkerColor":"#7d0005","textColor":"#FFFFFF","shortForms":["MARC"],"summary":"MARC: Commuter rail connecting DC, Baltimore, and Maryland areas.","history":"MARC, descending from older rail services like the Baltimore and Ohio Railroad, began operations under its current name in the early 1980s. It has evolved from its origins in historic commuter routes in the region. Over time, it has expanded to include three main lines, with the Penn Line being a prominent part of the Northeast Corridor, demonstrating significant growth and modernization in its operations and services.","stats":[{"label":"Year Founded","value":"1980s"},{"label":"Lines","value":"3"},{"label":"Max Speed","value":"125 mph"}],"websiteUrl":"https://www.mta.maryland.gov/marc-train","map":{"lat":38.9072,"lng":-77.0369,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"Virginia Railway Express","slug":"vre","metric":false,"cities":["washington-dc"],"color":"#C60034","darkerColor":"#9e000c","textColor":"#FFFFFF","shortForms":["VRE"],"summary":"VRE: Commuter rail serving Northern Virginia and D.C. with two lines.","history":"VRE was formed in 1989 as a joint creation of the Northern Virginia Transportation Commission and the Potomac and Rappahannock Transportation Commission. Its initial service to Manassas began on June 22, 1992, followed by service to Fredericksburg on July 20, 1992. The service was initiated to address the commuting needs of the growing suburban population in Northern Virginia. VRE faced early challenges including legal negotiations over trackage rights and manufacturing delays of the train coaches.","stats":[{"label":"Year Founded","value":"1989"},{"label":"System Miles","value":"83"},{"label":"Stations","value":"18"},{"label":"Lines","value":"2"}],"websiteUrl":"https://www.vre.org","map":{"lat":38.9072,"lng":-77.0369,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"Washington Metropolitan Area Transit Authority","slug":"wmta","metric":false,"cities":["washington-dc"],"color":"#222222","darkerColor":"#000000","textColor":"#FFFFFF","shortForms":["WMATA","Metro"],"summary":"WMATA operates Metrorail, serving DC, MD, and VA with color-coded lines.","history":"WMATA\'s Metrorail system originated in the mid-20th century to address growing transportation needs. Construction began in 1969, with the first segment opening in 1976. The system expanded significantly through the 1980s and 1990s, spurring economic growth and urban renew
16al. The 21st century saw further innovations, including the Silver Line extension to Dulles International Airport. Despite challenges, Metrorail remains crucial to the region\'s transportation infrastructure, continually adapting to serve its diverse ridership.","stats":[{"label":"Year Opened","value":"1976"},{"label":"System Miles","value":"117"},{"label":"Stations","value":"91"},{"label":"Lines","value":"6"}],"websiteUrl":"https://www.wmata.com","map":{"lat":38.9072,"lng":-77.0369,"zoom":11},"vehicleClassificationOverride":"subway_default"},{"name":"New Jersey Transit","slug":"njt","metric":false,"cities":["new-york"],"color":"#1a2b57","darkerColor":"#142143","textColor":"#ffffff","shortForms":["NJT","NJ Transit"],"summary":"NJ Transit operates extensive commuter rail connecting New Jersey to NYC and Philadelphia.","history":"New Jersey Transit was established in 1979 as a state-owned public transportation system, consolidating several previous transit operators. Rail operations began in 1983 when it acquired commuter rail operations from Conrail. Through the 1980s and 1990s, NJ Transit expanded and modernized its network, including major projects like the Secaucus Junction transfer station and direct service to New York Penn Station. Today, it operates one of the largest statewide public transit systems in the United States.","stats":[{"label":"Year Founded","value":"1979"},{"label":"System Miles","value":"535"},{"label":"Stations","value":"166"},{"label":"Lines","value":"11"}],"websiteUrl":"https://www.njtransit.com","map":{"lat":40.7128,"lng":-74.006,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"OC Transpo","slug":"octrans","metric":true,"cities":["ottawa"],"color":"#e71324","darkerColor":"#b80f1d","textColor":"#FFFFFF","shortForms":["OCT","OC"],"summary":"OC Transpo operates Ottawa\'s O-Train light rail and bus rapid transit system.","history":"OC Transpo was founded in 1972 by merging several municipal transportation systems. The organization introduced the Transitway bus rapid transit system in 1983, pioneering BRT in North America. In 2001, OC Transpo launched its first light rail service, the O-Train Trillium Line. The system underwent major expansion with the opening of the Confederation Line in 2019, marking Ottawa\'s transition to a modern light rail network. This transformation represents one of the largest infrastru
16cture projects in the city\'s history.","stats":[{"label":"Year Founded","value":"1972"},{"label":"System KM","value":"20.5"},{"label":"Stations","value":"24"},{"label":"Lines","value":"2"}],"websiteUrl":"https://www.octranspo.com","map":{"lat":45.4215,"lng":-75.6972,"zoom":11},"vehicleClassificationOverride":"light_rail"},{"name":"MTA (New York City Subway)","slug":"mta","metric":false,"cities":["new-york"],"color":"#0f61a9","darkerColor":"#0B467A","textColor":"#FFFFFF","shortForms":["NYCT","Subway"],"summary":"The New York City Subway is the largest rapid transit system in the United States, serving the city\'s five boroughs.","history":"The New York City Subway opened in 1904 with the Interborough Rapid Transit Company (IRT). The system expanded through the early 20th century with the Brooklyn-Manhattan Transit Corporation (BMT) and Independent Subway System (IND). In 1953, these were unified under the New York City Transit Authority, now part of the MTA. The subway has shaped New York\'s development for over a century, operating 24/7 and carrying over 5 million daily riders pre-pandemic. Its extensive network includes express and local services, making it one of the world\'s most complex transit systems.","stats":[{"label":"Year Founded","value":"1904"},{"label":"System Miles","value":"850"},{"label":"Stations","value":"472"},{"label":"Lines","value":"28"}],"websiteUrl":"https://new.mta.info/agency/new-york-city-transit","map":{"lat":40.7128,"lng":-74.006,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"STM (Soci\xe9t\xe9 de transport de Montr\xe9al)","slug":"stm","metric":true,"cities":["montreal"],"color":"#0072ce","darkerColor":"#005ba3","textColor":"#FFFFFF","shortForms":["STM","M\xe9tro"],"summary":"The STM operates Montreal\'s Metro rapid transit system and bus network, serving Canada\'s second-largest city.","history":"The Montreal Metro opened in 1966 as part of the city\'s preparations for Expo 67. The system was notable for its distinctive rubber-tired trains and award-winning station architecture. The initial network consisted of 26 stations on three lines. Major expansions occurred in the 1970s and 1980s, including the addition of the Blue Line. The STM has continued modernizing its fleet and infrastructure while maintaining the system\'s unique architectural heritage. The Metro is recognized for its public art program, with each station featuring original works by Quebec artists.","stats":[{"label":"Year Founded","value":"1966"},{"label":"System KM","value":"71"},{"label":"Stations","value":"68"},{"label":"Lines","value":"4"}],"websiteUrl":"https://www.stm.info/","map":{"lat":45.5017,"lng":-73.5673,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"Maryland Metro","slug":"marylandmetro","metric":false,"cities":["baltimore"],"color":"#6F2C91","darkerColor":"#4F1F67","textColor":"#FFFFFF","shortForms":["MTA","Metro SubwayLink"],"summary":"The Baltimore Metro SubwayLink is a rapid transit line serving Baltimore and its suburbs, operated by the Maryland Transit Administration.","history":"Baltimore\'s Metro SubwayLink opened in 1983 as the Baltimore Metro, connecting downtown Baltimore to Reisterstown Plaza. The system was extended to Owings Mills in 1987 and to Johns Hopkins Hospital in 1995. As Baltimore\'s only rapid transit line, it serves as a crucial north-south transportation corridor, connecting the suburbs to downtown Baltimore and major institutions like Johns Hopkins Hospital. The system is part of the Maryland Transit Administration\'s integrated transit network, which includes light rail, buses, and commuter rail services.","stats":[{"label":"Year Founded","value":"1983"},{"label":"System Miles","value":"15.5"},{"label":"Stations","value":"14"},{"label":"Lines","value":"1"}],"websiteUrl":"https://www.mta.maryland.gov/metro-subway","map":{"lat":39.2904,"lng":-76.6122,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"Maryland Light Rail","slug":"marylandlightrail","metric":false,"cities":["baltimore"],"color":"#00A4E4","darkerColor":"#0082B4","textColor":"#FFFFFF","shortForms":["MTA","Light RailLink"],"summary":"The Baltimore Light RailLink is a light rail system serving Baltimore and its suburbs, operated by the Maryland Transit Administration.","history":"The Baltimore Light Rail began operations in 1992, providing north-south service between Hunt V
16alley and Glen Burnie. The system was expanded in 1997 with branches to Penn Station and BWI Airport. Built largely on existing rail rights-of-way, the Light Rail has played an important role in Baltimore\'s transit network, connecting suburban areas with downtown Baltimore, Camden Yards, Penn Station, and BWI Marshall Airport. The system operates primarily at street level and features both dedicated rights-of-way and street-running segments.","stats":[{"label":"Year Founded","value":"1992"},{"label":"System Miles","value":"30"},{"label":"Stations","value":"33"},{"label":"Lines","value":"3"}],"websiteUrl":"https://www.mta.maryland.gov/light-rail","map":{"lat":39.2904,"lng":-76.6122,"zoom":11},"vehicleClassificationOverride":"light-rail"},{"name":"MARTA","slug":"marta","metric":false,"cities":["atlanta"],"color":"#F7931D","darkerColor":"#D67B16","textColor":"#000000","shortForms":["MARTA"],"summary":"The Metropolitan Atlanta Rapid Transit Authority (MARTA) operates Atlanta\'s rapid transit system, consisting of heavy rail and bus services.","history":"MARTA began operations in 1979, making it one of the newer major transit systems in the United States. The system was built following a 1971 referendum where Atlanta, Fulton County, and DeKalb County voters approved a 1% sales tax to fund MARTA. The first rail line opened between Avondale and Five Points, and the system gradually expanded to form a cross-shaped network with north-south and east-west lines. MARTA serves as the backbone of Atlanta\'s public transportation system, connecting major destinations including Hartsfield-Jackson Atlanta International Airport, Downtown Atlanta, Midtown, Buckhead, and Decatur.","stats":[{"label":"Year Founded","value":"1979"},{"label":"System Miles","value":"48"},{"label":"Stations","value":"38"},{"label":"Lines","value":"4"}],"websiteUrl":"https://www.itsmarta.com","map":{"lat":33.749,"lng":-84.388,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"Edmonton Transit Service","slug":"edmonton","metric":true,"cities":["edmonton"],"color":"#004B8D","darkerColor":"#003A6E","textColor":"#FFFFFF","shortForms":["ETS","LRT"],"summary":"The Edmonton Transit Service (ETS) operates Edmonton\'s light rail transit system, connecting key areas of Alberta\'s capital city.","history":"Edmonton\'s LRT system opened in 1978, becoming Canada\'s first modern light rail system. The initial line was built to serve the 1978 Commonwealth Games, running from Belvedere to Central Station. The system has since expanded significantly, with the Capital Line running from Clareview to Century Park and the Metro Line branching northwest to NAIT. The Valley Line Southeast, a low-floor urban style LRT line, began operations in 2023, adding new connectivity to Mill Woods and downtown Edmonton.","stats":[{"label":"Year Founded","value":"1978"},{"label":"System Miles","value":"24.3"},{"label":"Stations","value":"26"},{"label":"Lines","value":"3"}],"websiteUrl":"https://www.edmonton.ca/ets","map":{"lat":53.5461,"lng":-113.4937,"zoom":11},"vehicleClassificationOverride":"light-rail"},{"name":"Sistema de Transporte Colectivo","slug":"cdmx","metric":true,"cities":["mexico-city"],"color":"#FF6319","darkerColor":"#D94F11","textColor":"#FFFFFF","shortForms":["Metro CDMX","Metro"],"summary":"The Mexico City Metro (Sistema de Transporte Colectivo) is one of the largest and busiest metro systems in the world, serving Mexico\'s capital city.","history":"The Mexico City Metro began operations in 1969 with Line 1, designed to help modernize the city\'s transportation system. The system has grown extensively since then, now comprising 12 lines covering most of Mexico City. The network was built using a combination of underground tunnels, surface-level tracks, and elevated sections. Notable for its use of icons to identify stations (implemented due to high illiteracy rates when the system opened), the Metro has become an essential part of daily life in Mexico City, carrying over 4.6 million passengers daily.","stats":[{"label":"Year Founded","value":"1969"},{"label":"System Miles","value":"140.7"},{"label":"Stations","value":"195"},{"label":"Lines","value":"12"}
16],"websiteUrl":"https://www.metro.cdmx.gob.mx","map":{"lat":19.4326,"lng":-99.1332,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"Metro de Medell\xedn","slug":"metromedellin","metric":true,"cities":["medellin"],"color":"#0054A4","darkerColor":"#003d7a","textColor":"#FFFFFF","shortForms":["Metro Medell\xedn","Metro"],"summary":"Metro de Medell\xedn operates the metro (Lines A and B), Metrocable, Ayacucho Tram, and integrated bus services in the Aburr\xe1 Valley, Colombia.","history":"The Medell\xedn Metro opened in 1995 with Line A (Niqu\xedaâLa Estrella), the first and only metro in Colombia. Line B opened in 1996. The system later added Metrocable gondola lines (from 2004), the Ayacucho Tram (2016), and integrates with MetroPlus BRT. All services use the Civica card for unified fares.","stats":[{"label":"Year Founded","value":"1995"},{"label":"Metro km","value":"31.3"},{"label":"Stations (metro)","value":"27"},{"label":"Lines (metro + tram)","value":"3"}],"websiteUrl":"https://www.metrodemedellin.gov.co","gtfsEnabled":true,"map":{"lat":6.2442,"lng":-75.5812,"zoom":11},"vehicleClassificationOverride":"subway","countries":["Colombia"]},{"name":"Dallas Area Rapid Transit","slug":"dart","metric":false,"cities":["dallas"],"color":"#0099DC","darkerColor":"#007AB0","textColor":"#FFFFFF","shortForms":["DART"],"summary":"Dallas Area Rapid Transit (DART) operates light rail, commuter rail, and bus services throughout the Dallas metropolitan area.","history":"DART began light rail operations in 1996 with the opening of the Red Line from Westmoreland to Pearl Station. The system has since expanded to become the longest light rail system in the United States, with four lines serving Dallas and its suburbs. The network includes the Red Line, Blue Line, Green Line, and Orange Line, connecting major destinations including downtown Dallas, D
16FW Airport, and various suburban communities. DART has played a crucial role in shaping transit-oriented development throughout the region.","stats":[{"label":"Year Founded","value":"1996"},{"label":"System Miles","value":"93"},{"label":"Stations","value":"65"},{"label":"Lines","value":"4"}],"websiteUrl":"https://www.dart.org","map":{"lat":32.7767,"lng":-96.797,"zoom":11},"vehicleClassificationOverride":"light-rail"},{"name":"Denton County Transportation Authority","slug":"dcta","metric":false,"cities":["denton"],"color":"#005636","darkerColor":"#003D26","textColor":"#FFFFFF","shortForms":["DCTA","A-train"],"summary":"Denton County Transportation Authority (DCTA) operates the A-train commuter rail line connecting Denton and Carrollton, Texas, along with local bus service in Denton County.","history":"DCTA was created in 2002 after Denton County voters approved its formation under Texas House Bill 3323. The A-train commuter rail line opened on June 20, 2011, running 21 miles between Denton and Carrollton, where it connects to DART\'s Green Line at Trinity Mills Station. The line serves six stations across Denton, Lewisville, and Carrollton, providing a regional rail link into the Dallas-Fort Worth area.","stats":[{"label":"Year Founded","value":"2002"},{"label":"A-train Opened","value":"2011"},{"label":"Route Miles","value":"21"},{"label":"Stations","value":"6"}],"websiteUrl":"https://www.dcta.net","map":{"lat":33.1032,"lng":-96.9486,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Calgary Transit CTrain","slug":"calgary","metric":true,"cities":["calgary"],"color":"#FF0000","darkerColor":"#CC0000","textColor":"#FFFFFF","shortForms":["CTrain"],"summary":"The CTrain is Calgary\'s light rail transit system, serving the city with two lines that connect the downtown core to the suburbs.","history":"The CTrain began operations in 1981 with the South Line (now part of the Red Line). The system was built as part of Calgary\'s preparation for the 1988 Winter Olympics and has since expanded to become one of North America\'s most successful light rail systems. Notable for being one of the first systems in North America to be fully powered by renewable energy, the CTrain carries over 300,000 passengers on a typical weekday. The system features a free fare zone in downtown Calgary and has been instrumental in promoting transit-oriented development throughout the city.","stats":[{"label":"Year Founded","value":"1981"},{"label":"System Miles","value":"37.2"},{"label":"Stations","value":"45"},{"label":"Lines","value":"2"}],"websiteUrl":"https://www.calgarytransit.com","map":{"lat":51.0447,"lng":-114.0719,"zoom":11},"vehicleClassificationOverride":"light-rail"},{"name":"Brightline","slug":"brightline","metric":false,"cities":["miami","orlando"],"color":"#F7B500","darkerColor":"#C69100","textColor":"#000000","shortForms":["Brightline"],"summary":"Brightline is the first privately owned and operated intercity passenger railroad in the United States in decades, connecting major cities in Florida with modern high-speed rail service.","history":"Brightline began operations in 2018 between Miami and West Palm Beach. In 2023, the service expanded to Orlando, marking a significant milestone in American passenger rail by connecting Central and South Florida with speeds up to 125 mph. The system represents the first successful private passenger rail service in the United States since the 1980s, offering a premium travel experience and modern amenities. Future plans include expansion to Tampa and potential service to other regions.","stats":[{"label":"Year Founded","value":"2018"},{"label":"System Miles","value":"235"},{"label":"Stations","value":"5"},{"label":"Top Speed (mph)","value":"125"}],"websiteUrl":"https://www.gobrightline.com","map":{"lat":27.3644,"lng":-80.83,"zoom":7},"vehicleClassificationOverride":"intercity"},{"name":"ION Light Rail","slug":"ionwaterloo","metric":true,"cities":["kitchener-ontario"],"color":"#0097A9","darkerColor":"#007A89","textColor":"#FFFFFF","shortForms":["ION"],"summary":"ION is a light rail transit system serving the Regional Municipality of Waterloo, connecting the cities of Kitchener and Waterloo.","history":"The ION light rail system began operations in 2019 after years of planning and construction. The system was designed to support the region\'s growth and development while connecting major destinations including universities, hospitals, and commercial centers. Phase 1 of the project connects Waterloo to Kitchener with modern electric light rail vehicles. The system represents a major investment in sustainable transportation for the region and has already sparked significant transit-oriented development along its corridor.","stats":[{"label":"Year Founded","value":"2019"},{"label":"System Miles","value":"11.8"},{"label":"Stations","value":"19"},{"label":"Lines","value":"1"}],"websiteUrl":"https://www.grt.ca/en/ion-light-rail.aspx","map":{"lat":43.4516,"lng":-80.4925,"zoom":12},"vehicleClassificationOverride":"light-rail"}
16,{"name":"MetroLink","slug":"metrostlouis","metric":false,"cities":["st-louis"],"color":"#ED1B2E","darkerColor":"#BE1624","textColor":"#FFFFFF","shortForms":["MetroLink"],"summary":"MetroLink is a light rail system serving the St. Louis metropolitan area, connecting Missouri and Illinois with two lines.","history":"MetroLink began operations in 1993 with its initial line between East St. Louis and Lambert International Airport. The system expanded in 2001 with the addition of the Blue Line (originally called Cross County Extension) serving Clayton and Shrewsbury. The system was one of the first modern light rail systems in the Midwest and has played an important role in connecting major destinations including downtown St. Louis, the Gateway Arch, universities, hospitals, and both sports stadiums.","stats":[{"label":"Year Founded","value":"1993"},{"label":"System Miles","value":"46"},{"label":"Stations","value":"38"},{"label":"Lines","value":"2"}],"websiteUrl":"https://www.metrostlouis.org/metrolink/","map":{"lat":38.627,"lng":-90.1994,"zoom":11},"vehicleClassificationOverride":"light-rail"},{"name":"San Diego MTS","slug":"mtssandiego","metric":false,"cities":["san-diego"],"color":"#C41E3A","darkerColor":"#9D1830","textColor":"#FFFFFF","shortForms":["MTS"],"summary":"The San Diego Metropolitan Transit System operates light rail service known as the San Diego Trolley, serving the greater San Diego metropolitan area.","history":"The San Diego Trolley began service in 1981 with the Blue Line, making it the first modern light rail system in the United States. The system has since expanded to include three lines serving major destinations throughout San Diego County. The Trolley connects downtown San Diego with Mission Valley, East County communities, and the Mexican border at San Ysidro. The system is known for its distinctive red trolley cars and has been instrumental in providing sustainable transit options for the region.","stats":[{"label":"Year Founded","value":"1981"},{"label":"System Miles","value":"54"},{"label":"Stations","value":"53"},{"label":"Lines","value":"3"}],"websiteUrl":"https://www.sdmts.com/","map":{"lat":32.7157,"lng":-117.1611,"zoom":11},"vehicleClassificationOverride":"light-rail"},{"name":"R\xe9seau Express M\xe9tropolitain","slug":"rem","metric":true,"cities":["montreal"],"color":"#00B0B9","darkerColor":"#008C93","textColor":"#FFFFFF","shortForms":["REM"],"summary":"The R\xe9seau express m\xe9tropolitain (REM) is a new automated light metro system serving Greater Montreal, connecting downtown with the South Shore, West Island, North Shore and Montreal Airport.","history":"The REM project was announced in 2016 as one of the largest public transit projects in Montreal\'s history. Construction began in 2018, and the first segment between Central Station and Brossard opened in July 2023. When fully completed, the REM will be one of the world\'s largest automated transit networks, integrating with existing metro and commuter rail services to form a comprehensive regional transit system.","stats":[{"label":"Year Founded","value":"2023"},{"label":"System Kilometers","value":"67"},{"label":"Stations","value":"26"},{"label":"Lines","value":"1"}],"websiteUrl":"https://rem.info/en","map":{"lat":45.5017,"lng":-73.5673,"zoom":11},"vehicleClassificationOverride":"light-metro"},{"name":"RTD Light Rail","slug":"rtddenver","metric":false,"cities":["denver"],"color":"#007DB8","darkerColor":"#006494","textColor":"#FFFFFF","shortForms":["RTD"],"summary":"The Regional Transportation District (RTD) operates a comprehensive light rail system serving the Denver metropolitan area, connecting downtown Denver with surrounding suburbs.","history":"RTD\'s light rail system began operations in 1994 with the opening of the Central Corridor. The system has since undergone several major expansions, including the Southeast Corridor in 2006 and the W Line to Golden in 2013. The transit system has played a crucial role in Denver\'s growth, providing sustainable transportation options and spurring transit-oriented development throughout the region.","stats":[{"label":"Year Founded","value":"1994"},{"label":"System Miles","value":"60"},{"label":"Stations","value":"54"},{"label":"Lines","value":"8"}],"websiteUrl":"https://www.rtd-denver.com/","map":{"lat":39.7392,"lng":-104.9903,"zoom":11},"vehicleClassificationOverride":"light-rail"},{"name":"TransLink SkyTrain","slug":"translink","metric":true,"cities":["vancouver"],"color":"#0057B8","darkerColor":"#004593","textColor":"#FFFFFF","shortForms":["TransLink"],"summary":"TransLink\'s SkyTrain is Vancouver\'s automated rapid transit system, consisting of three lines: the Expo Line, Millennium Line, and Canada Line. It is one of the longest fully-automated driverless metro systems in the world.","history":"The SkyTrain system began operations in 1985 with the Expo Line, built for the 1986 World\'s Fair (Expo 86). The system expanded with the Millennium Line in 2002 and the Canada Line in 2009, built for the 2010 Winter Olympics. The network continues to grow with the Broadway Extension of the Millennium Line under construction.","stats":[{"label":"Year Founded","value":"1985"},{"label":"System Kilometers","value":"79.6"},{"label":"Stations","value":"53"},{"label":"Lines","value":"3"}],"websiteUrl":"https://www.translink.ca/","map":{"lat":49.2827,"lng":-123.1207,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"Tri-Rail","slug":"trirail","metric":false,"cities":["miami","orlando"],"color":"#00A0DF","darkerColor":"#0080B2","textColor":"#FFFFFF","shortForms":["Tri-Rail"],"summary":"Tri-Rail is a commuter rail system serving South Florida, running along the South Florida Rail Corri
16dor between Miami, Fort Lauderdale, and West Palm Beach.","history":"Tri-Rail began operations in 1989 as a temporary service during construction on I-95. The service proved popular and became permanent, expanding to serve three major South Florida counties. The system has since modernized its fleet and stations while playing a vital role in regional transportation.","stats":[{"label":"Year Founded","value":"1989"},{"label":"System Miles","value":"72"},{"label":"Stations","value":"18"},{"label":"Lines","value":"1"}],"websiteUrl":"https://www.tri-rail.com/","map":{"lat":26.1224,"lng":-80.1373,"zoom":9},"vehicleClassificationOverride":"commuter-rail"},{"name":"Valley Metro Rail","slug":"valleymetrorail","metric":false,"cities":["phoenix"],"color":"#00A1DE","darkerColor":"#0081B1","textColor":"#FFFFFF","shortForms":["Valley Metro"],"summary":"Valley Metro Rail is a light rail system serving the Phoenix metropolitan area, connecting Phoenix, Tempe, and Mesa along a single line.","history":"Valley Metro Rail began operations in 2008, marking Phoenix\'s first modern rail transit system. The 20-mile initial segment has since been extended multiple times, most recently in 2019. The system has exceeded ridership expectations and spurred transit-oriented development throughout the corridor.","stats":[{"label":"Year Founded","value":"2008"},{"label":"System Miles","value":"28"},{"label":"Stations","value":"38"},{"label":"Lines","value":"1"}],"websiteUrl":"https://www.valleymetro.org/","map":{"lat":33.4484,"lng":-112.074,"zoom":11},"vehicleClassificationOverride":"light-rail"},{"name":"Sound Transit","slug":"soundtransit","metric":false,"cities":["seattle"],"color":"#00B5E2","darkerColor":"#008DB0","textColor":"#FFFFFF","shortForms":["Sound Transit","Link"],"summary":"Sound Transit operates Link light rail, Sounder commuter rail, and regional express buses in the Seattle metropolitan area.","history":"Sound Transit was created in 1996 to build and operate high-capacity public transportation in the Central Puget Sound region. Link light rail began service in 2009 with a line between downtown Seattle and Sea-Tac Airport. The system has since expanded northward to the University of Washington and beyond, with major extensions planned to reach Lynnwood, Federal Way, and the East Side. Sounder commuter rail service began in 2000 and serves the north and south corridors.","stats":[{"label":"Year Founded","value":"1996"},{"label":"System Miles","value":"24"},{"label":"Light Rail Stations","value":"19"},{"label":"Daily Ridership","value":"80k+"}],"websiteUrl":"https://www.soundtransit.org/","map":{"lat":47.6062,"lng":-122.3321,"zoom":11},"vehicleClassificationOverride":"light-rail"},{"name":"TriMet","slug":"trimet","metric":false,"cities":["portland"],"color":"#E82E22","darkerColor":"#B82218","textColor":"#FFFFFF","shortForms":["TriMet","MAX"],"summary":"TriMet operates the MAX Light Rail system, along with buses and commuter rail in the Portland metropolitan area.","history":"TriMet (Tri-County Metropolitan Transportation District of Oregon) was founded in 1969. The MAX (Metropolitan Area Express) Light Rail system began service in 1986 with the Blue Line between Portland and Gresham. The system has since expanded to five lines covering 60 miles, serving Portland and its suburbs. MAX was one of the first modern light rail systems in North America and has been influential in Portland\'s transit-oriented development and environmental sustainability efforts.","stats":[{"label":"Year Founded","value":"1969"},{"label":"System Miles","value":"60"},{"label":"Light Rail Lines","value":"5"},{"label":"Daily Ridership","value":"120k+"}],"websiteUrl":"https://trimet.org/","map":{"lat":45.5155,"lng":-122.6789,"zoom":11},"vehicleClassificationOverride":"light-rail"},{"name":"Portland Streetcar","slug":"portlandstreetcar","metric":false,"cities":["portland"],"color":"#72A130","darkerColor":"#537723","textColor":"#000000","shortForms":["Portland Streetcar"],"summary":"Portland Streetcar operates the NS Line, A Loop, and B Loop connecting downtown Portland, the Pearl District, and surrounding neighborhoods.","history":"Portland Streetcar began service in 2001 as the first modern streetcar line built in the United States in decades, initially connecting Northwest Portland to Portland State University. It has since expanded into the NS Line and the Central Loop (split into the A and B Loops), extending service across the Willamette River to the Central Eastside. The system is owned by the City of Portland and operated by Portland Streetcar, Inc. under contract, separately from TriMet\'
16s bus and MAX light rail network.","stats":[{"label":"Year Opened","value":"2001"},{"label":"Lines","value":"3"},{"label":"System Miles","value":"7.9"}],"websiteUrl":"https://portlandstreetcar.org/","map":{"lat":45.5222,"lng":-122.679,"zoom":13},"vehicleClassificationOverride":"streetcar"},{"name":"KCATA","slug":"kcata","metric":false,"cities":["kansas-city"],"color":"#0066B3","darkerColor":"#004C85","textColor":"#FFFFFF","shortForms":["KCATA","RideKC"],"summary":"The Kansas City Area Transportation Authority (KCATA) operates the RideKC bus system and KC Streetcar in the Kansas City metropolitan area.","history":"The Kansas City Area Transportation Authority was established in 1965 to provide public transportation services in the Kansas City metropolitan area. In 2016, the KC Streetcar began operation in downtown Kansas City, marking the return of rail transit to the city after a 59-year absence. The 2.2-mile starter line connects the River Market to Union Station, with plans for expansion north to the riverfront and south to UMKC.","stats":[{"label":"Year Founded","value":"1965"},{"label":"Streetcar Miles","value":"2.2"},{"label":"Streetcar Stops","value":"16"},{"label":"Daily Ridership","value":"6k+"}],"websiteUrl":"https://www.kcata.org/","map":{"lat":39.0997,"lng":-94.5786,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"TECO Line Streetcar","slug":"tampa","metric":false,"cities":["tampa"],"color":"#00563F","darkerColor":"#003D2B","textColor":"#FFFFFF","shortForms":["TECO Streetcar","HART"],"summary":"The TECO Line Streetcar is a heritage trolley system connecting downtown Tampa, the Channelside District, and Ybor City, operated by the Hillsborough Area Regional Transit Authority (HART).","history":"The TECO Line Streetcar opened in October 2002, reviving streetcar service along a route once served by Tampa\'s original electric trolley network, which ran from 1892 until 1946. Sponsored by and named for Tampa Electric Company (TECO), the line uses replica heritage trolley cars to connect Ybor City, the Channelside District, and downtown Tampa. It is operated by the Hillsborough Area Regional Transit Authority (HART).","stats":[{"label":"Year Opened","value":"2002"},{"label":"System Miles","value":"2.7"},{"label":"Streetcar Stops","value":"11"}],"websiteUrl":"https://www.gohart.org/getting-around/streetcar","map":{"lat":27.9478,"lng":-82.4419,"zoom":14},"vehicleClassificationOverride":"streetcar","gtfsEnabled":true},{"name":"EMBARK","slug":"okcstreetcar","metric":false,"cities":["oklahoma-city"],"color":"#0072CE","darkerColor":"#005598","textColor":"#FFFFFF","shortForms":["EMBARK","OKC Streetcar"],"summary":"EMBARK operates the Oklahoma City Streetcar system, along with buses and other transit services in the Oklahoma City metropolitan area.","history":"The Oklahoma City Streetcar began service in December 2018 as part of the MAPS 3 capital improvement program. The system features two routes - the Downtown Loop and Bricktown Loop - covering 4.8 miles of track. The streetcar system connects major destinations in downtown Oklahoma City, including Bricktown, Midtown, Automobile Alley, and the Central Business District. The project represents a significant investment in Oklahoma City\'s public transit infrastructure and urban development.","stats":[{"label":"Year Opened","value":"2018"},{"label":"System Miles","value":"4.8"},{"label":"Streetcar Stops","value":"22"},{"label":"Daily Ridership","value":"1k+"}],"websiteUrl":"https://embarkok.com/","map":{"lat":35.4676,"lng":-97.5164,"zoom":13},"vehicleClassificationOverride":"streetcar","gtfsEnabled":true},{"name":"Cincinnati Connector","slug":"cincinnati","metric":false,"cities":["cincinnati"],"color":"#68C9F2","darkerColor":"#4CA3C7","textColor":"#000000","shortForms":["Connector","SORTA"],"summary":"The Cincinnati Bell Connector is a free streetcar system operated by SORTA (Metro), connecting the Over-the-Rhine and Banks neighborhoods via downtown Cincinnati.","history":"The Connector opened in September 2016 as Cincinnati\'s first modern streetcar line, running a 3.6-mile loop through the Central Bu
16siness District, Over-the-Rhine, and The Banks riverfront district. It is operated by the Southwest Ohio Regional Transit Authority (SORTA), which also runs Cincinnati Metro\'s bus network, and is free to ride.","stats":[{"label":"Year Opened","value":"2016"},{"label":"System Length","value":"3.6 miles"},{"label":"Operator","value":"SORTA (Metro)"}],"websiteUrl":"https://www.cincinnati-oh.gov/streetcar/","map":{"lat":39.1031,"lng":-84.512,"zoom":13},"vehicleClassificationOverride":"streetcar"},{"name":"Detroit People Mover","slug":"detroitpeoplemover","metric":false,"cities":["detroit"],"color":"#00274C","darkerColor":"#001A33","textColor":"#FFFFFF","shortForms":["DPM"],"summary":"The Detroit People Mover is a single-line automated elevated monorail circling downtown Detroit.","history":"The Detroit People Mover opened in 1987 as a 2.9-mile elevated automated guideway system looping through downtown Detroit with 13 stations. It was built as part of a broader downtown revitalization effort and remains one of only a handful of fully automated driverless transit systems in the United States.","stats":[{"label":"Year Opened","value":"1987"},{"label":"System Length","value":"2.9 miles"},{"label":"Stations","value":"13"}],"websiteUrl":"http://www.thepeoplemover.com/","map":{"lat":42.3314,"lng":-83.0458,"zoom":14},"vehicleClassificationOverride":"metro"},{"name":"The Tide","slug":"tidelrt","metric":false,"cities":["norfolk"],"color":"#00A9E0","darkerColor":"#0080AA","textColor":"#FFFFFF","shortForms":["The Tide","HRT"],"summary":"The Tide is Hampton Roads Transit\'s light rail line connecting downtown Norfolk with Newtown Road via Eastern Virginia Medical Center.","history":"The Tide opened in August 2011 as Virginia\'s first light rail system, running a 7.4-mile single line with 11 stations through downtown Norfolk. It is operated by Hampton Roads Transit (HRT), which also runs the region\'s bus network.","stats":[{"label":"Year Opened","value":"2011"},{"label":"System Length","value":"7.4 miles"},{"label":"Stations","value":"11"}],"websiteUrl":"https://gohrt.com/modes/","map":{"lat":36.8508,"lng":-76.2859,"zoom":13},"vehicleClassificationOverride":"light_rail"},{"name":"ACE","slug":"acerail","metric":false,"cities":["san-francisco","san-jose"],"color":"#00A0DC","darkerColor":"#0076A3","textColor":"#FFFFFF","shortForms":["ACE","Altamont Corridor Express"],"summary":"The Altamont Corridor Express (ACE) is a commuter rail service connecting the Central Valley with Silicon Valley in California.","history":"The Altamont Corridor Express began operations in 1998 with two daily round trips between Stockton and San Jose through the Altamont Pass. Originally known as the Altamont Commuter Express, it was renamed in 2012 to reflect its broader role in regional transportation. The service has expanded over the years, now offering four daily round trips and serving communities along its 86-mile route. ACE provides a crucial transportation link for commuters between California\'s Central Valley and the Bay Area\'s tech employment centers.","stats":[{"label":"Route Miles","value":"86"},{"label":"Year Founded","value":"1998"},{"label":"Daily Trips","value":"8"},{"label":"Stations","value":"10"}],"websiteUrl":"https://www.acerail.com/","map":{"lat":37.5485,"lng":-121.9886,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"BART","slug":"bart","metric":false,"cities":["san-francisco","oakland"],"color":"#0099DC","darkerColor":"#007ab0","textColor":"#FFFFFF","shortForms":["BART","Bay Area Rapid Transit"],"summary":"Bay Area Rapid Transit (BART) is a rapid transit system serving the San Francisco Bay Area.","history":"BART began service in 1972 as one of the first modern rapid transit systems in America. The system was designed to provide a high-speed regional alternative to freeway congestion in the rapidly growing San Francisco Bay Area. BART was groundbreaking in many ways, featuring automated trains, wide-gauge tracks for stability at high speeds, and transbay tube construction. The system has expanded significantly since its initial opening, now serving five counties with over 130 miles of track. Major expansions have included the SFO Airport extension (2003), Oakland Airport Connector (2014), and Silicon Valley extension (2020).","stats":[{"label":"System Miles","value":"131"},{"label":"Year Opened","value":"1972"},{"label":"Daily Ridership","value":"405k"},{"label":"Stations","value":"50"}],"websiteUrl":"https://www.bart.gov","gtfsEnabled":true,"map":{"lat":37.7749,"lng":-122.4194,"zoom":9},"vehicleClassificationOverride":"rapid_transit"},{"name":"Parramatta Light Rail","slug":"parramatta","metric":true,"cities":["sydney"],"color":"#E31837","darkerColor":"#B31329","textColor":"#FFFFFF","shortForms":["PLR","L4"],"summary":"The Parramatta Light Rail is a light rail system in Sydney, with Stage 1 connecting Westmead to Carlingford via the Parramatta CBD. Stage 2 is under construction, extending the network to Sydney Olympic Park.","history":"Announced in 2015, the Parramatta Light Rail project aims to enhance connectivity in Western Sydney. Stage 1 construction began in 2019 and opened to passengers on 20 December 2024. Stage 2, approved in 2024 with a $2.1 billion commitment, commenced early works in late 2024, with major construction starting in 2025. This stage includes a new bridge over the Parramatta River and is expected to be operational by 2031.","stats":[{"label":"Route Length","value":"12 km (Stage 1), 10 km (Stage 2)"},{"label":"Operational Since","value":"20 December 2024 (Stage 1)"},{"label":"Planned Stops","value":"16 (Stage 1), 14 (Stage 2)"},{"label":"Vehicle Type","value":"CAF Urbos 100"},{"label":"Operator","value":"Great River City Light Rail (Transdev & CAF JV)"}],"websiteUrl":"https://www.parramattalightrail.nsw.gov.au/","map":{"lat":-33.8148,"lng":151.0017,"zoom":13},"vehicleClassificationOverride":"light_rail"},{"name":"Sydney Light Rail","slug":"sydneylightrail","metric":true,"cities":["sydney"],"color":"#D71920","darkerColor":"#A3161A","textColor":"#FFFFFF","shortForms":["SLR","L1","L2","L3"],"summary":"Sydney Light Rail is a multi-line tram system serving central and inner Sydney, comprising the L1 Dulwich Hill, L2 Randwick, and L3 Kingsford lines.","history":"Sydney\'s original tram network was dismantled in 1961. Light rail returned in 1997 with the L1 Dulwich Hill Line, extended in 2000 and 2014. The L2 Randwick Line opened in December 2019, followed by the L3 Kingsford Line in April 2020, forming the CBD and South East Light Rail.","stats":[{"label":"System Length","value":"36.7 km"},{"label":"Total Stops","value":"58"},{"label":"Annual Ridership","value":"40.59 million (2023/24)"},{"label":"Vehicle Types","value":"Alstom Citadis 305, CAF Urbos 3"},{"label":"Operator","value":"Transdev Sydney"}],"websiteUrl":"https://transportnsw.info/travel-info/ways-to-get-around/light-rail","map":{"lat":-33.8688,"lng":151.2093,"zoom":13},"vehicleClassificationOverride":"light_rail"},{"name":"Sydney Metro","slug":"sydneymetro","metric":true,"cities":["sydney"],"color":"#00A9D8","dar
16kerColor":"#007A9B","textColor":"#FFFFFF","shortForms":["SM","M1","M2","M3"],"summary":"Sydney Metro is Australia\'s first fully automated rapid transit system, featuring driverless trains and modern stations. It currently operates the M1 line from Tallawong to Sydenham, with extensions and new lines under construction.","history":"Sydney Metro began operations on 26 May 2019 with the M1 North West Line from Tallawong to Chatswood. The line was extended to Sydenham on 19 August 2024 as part of the City & Southwest project. Further extensions to Bankstown are underway, with completion expected in 2026. Two additional lines, Metro West (M2) and Western Sydney Airport (M3), are under construction, aiming to expand the network to 113 km with 46 stations upon completion.","stats":[{"label":"System Length","value":"113 km (upon completion)"},{"label":"Operational Since","value":"26 May 2019"},{"label":"Current Stations","value":"21 (M1), expanding to 46"},{"label":"Train Type","value":"Alstom Metropolis (M1), Siemens Inspiro (M3)"},{"label":"Operator","value":"Metro Trains Sydney"},{"label":"Top Speed","value":"100 km/h"},{"label":"Headway","value":"4 minutes (peak)"},{"label":"Annual Ridership","value":"23.3 million (2023/24)"}],"websiteUrl":"https://www.sydneymetro.info/","map":{"lat":-33.8688,"lng":151.2093,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"Sydney Trains","slug":"sydneytrains","metric":true,"cities":["sydney"],"color":"#F58220","darkerColor":"#C75B12","textColor":"#FFFFFF","shortForms":["T1","T2","T3","T4","T5","T6","T7","T8","T9"],"summary":"Sydney Trains operates the suburban rail network across Greater Sydney, serving 168 stations over 355.5 km with nine lines, forming the backbone of the city\'s public transport system.","history":"Established in 2013, Sydney Trains took over suburban rail operations from CityRail. The network encompasses nine lines, with services extending to various parts of Greater Sydney. It is managed by Transport for NSW and utilizes the Opal card ticketing system.","stats":[{"label":"System Length","value":"355.5 km"},{"label":"Stations","value":"168"},{"label":"Lines","value":"9"},{"label":"Annual Ridership","value":"302 million (2023â24)"},{"label":"Train Types","value":"Double-deck electric multiple units (A, B, C, K, T, V sets)"},{"label":"Operator","value":"Sydney Trains (Transport for NSW)"},{"label":"Top Speed","value":"130 km/h"},{"label":"Headway","value":"5â10 minutes (peak), 15 minutes (off-peak)"}],"websiteUrl":"https://transportnsw.info/routes/train","map":{"lat":-33.8688,"lng":151.2093,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"NSW TrainLink","slug":"nswtrainlink","metric":true,"cities":[],"color":"#00594C","darkerColor":"#003D34","textColor":"#FFFFFF","shortForms":["TL","XPT"],"summary":"NSW TrainLink operates regional and intercity rail services across New South Wales, connecting Sydney with regional centres and interstate destinations.","history":"NSW TrainLink was established in 2013, taking over regional and intercity rail and coach services previously run as CountryLink. It operates seven regional rail lines radiating from Sydney â Hunter, North Coast, North Western, Central Western, South Western, and Southern â using Xplorer and XPT diesel railcars, alongside a connecting regional coach network.","stats":[{"label":"Lines","value":"7 regional rail lines"},{"label":"Train Types","value":"XPT, Xplorer, Endeavour diesel railcars"},{"label":"Operator","value":"NSW TrainLink (Transport for NSW)"}],"websiteUrl":"https://transportnsw.info/travel-info/ways-to-get-around/nsw-trainlink-regional","map":{"lat":-33.8688,"lng":151.2093,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"Newcastle Light Rail","slug":"newcastlelightrail","metric":true,"cities":["newcastle-nsw"],"color":"#EE343F","darkerColor":"#B8242C","textColor":"#FFFFFF","shortForms":["NLR"],"summary":"Newcastle Light Rail is a single-line tram system connecting Newcastle Interchange to Pacific Park along the city\'s revitalised harbourside.","history":"Newcastle Light Rail opened in February 2019, replacing the final stretch of the former heavy rail line into central Newcastle as part of the city\'s urban renew
16al project. It runs along Hunter and Scott Streets, linking the Newcastle Interchange with the East End and Newcastle Beach precinct.","stats":[{"label":"System Length","value":"2.7 km"},{"label":"Stops","value":"6"},{"label":"Vehicle Type","value":"Alstom Citadis X05"},{"label":"Year Opened","value":"2019"}],"websiteUrl":"https://transportnsw.info/routes/details/newcastle-light-rail/nlr/78NLR","map":{"lat":-32.9243,"lng":151.7739,"zoom":14},"vehicleClassificationOverride":"light_rail"},{"name":"Yarra Trams","slug":"yarratram","metric":true,"cities":["melbourne"],"color":"#0066CC","darkerColor":"#004C99","textColor":"#FFFFFF","shortForms":["yarra"],"summary":"Yarra Trams operates the world\'s largest operational tram network, serving Melbourne with 24 routes across 250 km of track, providing essential public transport services throughout the city.","history":"Melbourne\'s tram network began in 1885 with horse-drawn trams, transitioning to electric operation in 1906. The network has been continuously operated since then, surviving the tram removal programs that affected other Australian cities. Today, it\'s operated by Yarra Trams under contract to Public Transport Victoria.","stats":[{"label":"System Length","value":"250 km"},{"label":"Annual Ridership","value":"206m"},{"label":"Fleet Size","value":"475 trams"},{"label":"Top Speed","value":"70 km/h"}],"websiteUrl":"https://www.yarratrams.com.au/","map":{"lat":-37.8136,"lng":144.9631,"zoom":12},"vehicleClassificationOverride":"tram"},{"name":"Melbourne Metro","slug":"melbournemetro","metric":true,"cities":["melbourne"],"color":"#00A0DE","darkerColor":"#0077A3","textColor":"#FFFFFF","shortForms":["melbournemetro"],"summary":"Melbourne Metro operates the suburban rail network serving Greater Melbourne, with 16 electrified lines covering 998 km of track and serving 222 stations, forming the backbone of the city\'s public transport system.","history":"The Melbourne rail network began in 1854 with the first steam train service. Electrification began in 1919 and was completed by 1923. The network has undergone significant expansion and modernization, including the recent Metro Tunnel project and ongoing level crossing removal program.","stats":[{"label":"System Length","value":"998 km"},{"label":"Ridership","value":"246.8m"},{"label":"Train Types","value":"Comeng, Siemens Nexas, X\'Trapolis, HCMT"},{"label":"Top Speed","value":"115 km/h"}],"websiteUrl":"https://www.metrotrains.com.au/","map":{"lat":-37.8136,"lng":144.9631,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"V/Line","slug":"vline","metric":true,"cities":[],"color":"#8F1A95","darkerColor":"#651269","textColor":"#FFFFFF","shortForms":["V/Line"],"summary":"V/Line operates regional and intercity rail services across Victoria, connecting Melbourne with regional centres including Geelong, Ballarat, Bendigo, and Traralgon.","history":"V/Line was established in 1983 as the brand for Victoria\'s country rail and coach services, taking over from Victorian Railways. It was privatised in the late 1990s before returning to public ownership in 2003. The network today operates 13 lines radiating from Melbourne\'s Southern Cross Station, using VLocity diesel multiple units alongside classic N-class locomotive-hauled services.","stats":[{"label":"Lines","value":"13 regional rail lines"},{"label":"Train Types","value":"VLocity DMU, N-class locomotive-hauled carriages"},{"label":"Operator","value":"V/Line (Department of Transport and Planning)"}],"websiteUrl":"https://www.vline.com.au/","map":{"lat":-37.8136,"lng":144.9631,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"KTMB","slug":"ktmb","metric":true,"cities":["kuala-lumpur"],"color":"#1B4F72","darkerColor":"#0D2B4A","textColor":"#FFFFFF","shortForms":["ktmb"],"summary":"Keretapi Tanah Melayu Berhad (KTMB) operates Malaysia\'s main railway network, providing commuter, intercity, and freight services across the country, with a focus on the Klang Valley region.","history":"KTMB traces its origins to 1885 when the first railway line was built in Malaya. The network expanded significantly during British colonial rule and has continued to modernize, including the introduction of electric commuter services in the Klang Valley.","stats":[{"label":"System Length","value":"1,833 km"},{"label":"Stations","value":"191"},{"label":"Train Types","value":"KTM Class 81, Class 83, Class 92"},{"label":"Top Speed","value":"140 km/h"}],"websiteUrl":"https://www.ktmb.com.my/","map":{"lat":3.139,"lng":101.6869,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"Translink SEQ","slug":"translinkseq","metric":true,"cities":["brisbane"],"color":"#00A0DE","darkerColor":"#0077A3","textColor":"#FFFFFF","shortForms":["translink","seq","g:link","glink"],"summary":"Translink operates South East Queensland\'s integrated public transport network, including bus, train, ferry, and tram services, serving the greater Brisbane metropolitan area and surrounding regions.","history":"The network has evolved from Brisbane\'s first horse-drawn trams in 1885 to today\'s modern integrated system. The rail network began in 1879, while the current light rail (G:link) opened in 2014, marking a return of trams to the Gold Coast.","stats":[{"label":"Rail Lines","value":"13"},{"label":"Stations","value":"152"},{"label":"Annual Ridership","value":"70m+"},{"label":"Train Types","value":"NGR, SMU260, IMU100"}],"websiteUrl":"https://translink.com.au/","map":{"lat":-27.4698,"lng":153.0251,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"Auckland Transport","slug":"aucklandtransport","metric":true,"cities":["auckland"],"color":"#0064AF","darkerColor":"#004B82","textColor":"#FFFFFF","shortForms":["at","auckland","atc","atcl"],"summary":"Auckland Transport operates the public transport network in Auckland, New Zealand, including trains, buses, and ferries. The rail network consists of four lines serving the greater Auckland region.","history":"Auckland\'s rail history dates back to 1873 with the opening of the first railway line. The network underwent significant modernization in the 2000s, including electrification completed in 2015 and the introduction of modern EMU trains.","stats":[{"label":"Rail Lines","value":"4"},{"label":"Stations","value":"42"},{"label":"Train Types","value":"AM Class EMU"},{"label":"Top Speed","value":"110 km/h"}],"websiteUrl":"https://at.govt.nz/","map":{"lat":-36.8509,"lng":174.7645,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"Metlink Wellington","slug":"metlinkwellington","metric":true,"cities":["wellington"],"color":"#002C6C","darkerColor":"#001F4D","textColor":"#FFFFFF","shortForms":["metlink","wellington","wrl"],"summary":"Metlink operates Wellington\'s integrated public transport network, including trains, buses, and harbour ferries. The rail network consists of five lines serving the greater Wellington region.","history":"Wellington\'s rail history began in 1874 with the Wellington-Lower Hutt railway. The network has since evolved significantly, with major modernization including the introduction of Matangi electric multiple units in 2010-2016 to replace older rolling stock.","stats":[{"label":"Rail Lines","value":"5"},{"label":"Stations","value":"49"},{"label":"Train Types","value":"Matangi EMU"},{"label":"Top Speed","value":"110 km/h"}],"websiteUrl":"https://www.metlink.org.nz/","map":{"lat":-41.2866,"lng":174.7756,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"Pittsburgh Regional Transit","slug":"pittsburgh","metric":false,"cities":["pittsburgh"],"color":"#003d4c","darkerColor":"#002933","textColor":"#FFFFFF","shortForms":["PRT","Port Authority"],"summary":"Pittsburgh Regional Transit operates public transportation in Pittsburgh and Allegheny County, including light rail transit, bus, and incline services. The light rail system, known locally as \'The T\', serves downtown Pittsburgh and southern communities.","history":"Pittsburgh\'s rail transit history dates back to the 19th century with streetcars. The modern light rail system evolved from these streetcar lines, with major renovations in the 1980s creating the current \'T\' system. In 2022, the Port Authority was rebranded as Pittsburgh Regional Transit. The system includes notable infrastru
16cture like the Mount Washington Transit Tunnel and serves as a vital link between downtown Pittsburgh and its southern communities.","stats":[{"label":"Rail Lines","value":"2"},{"label":"Stations","value":"53"},{"label":"System Length","value":"26.2 miles"},{"label":"Year Founded","value":"1964"}],"websiteUrl":"https://www.rideprt.org/","gtfsEnabled":true,"map":{"lat":40.4406,"lng":-79.9959,"zoom":11},"vehicleClassificationOverride":"light_rail"},{"name":"LA Metro","slug":"lametro","metric":false,"cities":["los-angeles"],"color":"#111111","darkerColor":"#000000","textColor":"#FFFFFF","shortForms":["LA Metro","Metro Los Angeles","LACMTA"],"summary":"The Los Angeles County Metropolitan Transportation Authority operates an extensive rail network serving Los Angeles County, including heavy rail subway and light rail lines. The system connects major destinations like Downtown LA, Hollywood, Santa Monica, and Long Beach.","history":"LA Metro\'s modern rail system began with the Blue Line (now A Line) in 1990, marking the return of rail transit to Los Angeles after decades without service. The system has since expanded significantly, with the Red Line subway opening in 1993 and multiple extensions and new lines added through the 2010s and 2020s.","stats":[{"label":"Rail Lines","value":"6"},{"label":"Stations","value":"93"},{"label":"System Length","value":"98 miles"},{"label":"Year Founded","value":"1990"}],"websiteUrl":"https://www.metro.net/","gtfsEnabled":true,"map":{"lat":34.0522,"lng":-118.2437,"zoom":10},"vehicleClassificationOverride":"light_rail"},{"name":"San Francisco Muni","slug":"sfmuni","metric":false,"cities":["san-francisco"],"color":"#f58426","darkerColor":"#c25d00","textColor":"#FFFFFF","shortForms":["Muni","SF Muni"],"summary":"San Francisco Muni operates the Muni Metro light rail and historic streetcar lines throughout San Francisco.","history":"San Francisco Municipal Railway (Muni) began operations in 1912 as one of the first publicly owned transit agencies in the U.S. The Muni Metro light rail system was developed in the late 1970s, utilizing the Market Street Subway. Muni also operates historic streetcars, including the F Market & Wharves line, and the iconic cable cars. The system is a vital part of San Francisco\'s public transportation network, connecting neighborhoods across the city.","stats":[{"label":"Rail Lines","value":"6"},{"label":"Stations","value":"24 subway, 87 surface stops"},{"label":"System Length","value":"35 miles"},{"label":"Year Founded","value":"1912"}],"websiteUrl":"https://www.sfmta.com/","gtfsEnabled":true,"map":{"lat":37.7749,"lng":-122.4194,"zoom":12},"vehicleClassificationOverride":"light_rail"},{"name":"VTA Light Rail","slug":"vta","metric":false,"cities":["san-jose","santa-clara"],"color":"#00857a","darkerColor":"#00594f","textColor":"#FFFFFF","shortForms":["VTA","Santa Clara VTA"],"summary":"Santa Clara Valley Transportation Authority (VTA) operates the light rail system serving San Jose, Santa Clara, and surrounding communities.","history":"VTA Light Rail began service in 1987, connecting Santa Clara County communities with a modern light rail system. The network expanded through the 1990s and 2000s, reaching key destinations such as Mountain Vie
16w, Campbell, and Alum Rock. VTA continues to modernize its fleet and infrastructure, providing a crucial transit link in Silicon Valley.","stats":[{"label":"Rail Lines","value":"3"},{"label":"Stations","value":"59"},{"label":"System Length","value":"42.2 miles"},{"label":"Year Founded","value":"1987"}],"websiteUrl":"https://www.vta.org/","gtfsEnabled":true,"map":{"lat":37.3541,"lng":-121.9552,"zoom":11},"vehicleClassificationOverride":"light_rail"},{"name":"SMART (Sonoma-Marin Area Rail Transit)","slug":"smart","metric":false,"cities":["sonoma","marin","santa-rosa","san-rafael"],"color":"#6db33f","darkerColor":"#3e6b1a","textColor":"#FFFFFF","shortForms":["SMART"],"summary":"SMART provides commuter rail service connecting Sonoma and Marin counties in the North Bay region of the San Francisco Bay Area.","history":"SMART began service in 2017, restoring passenger rail to the North Bay for the first time in decades. The system was created to address growing congestion and provide a sustainable transportation alternative. SMART currently operates between Larkspur and Sonoma County Airport, with plans for future extensions.","stats":[{"label":"Stations","value":"12"},{"label":"System Length","value":"45 miles"},{"label":"Year Founded","value":"2017"}],"websiteUrl":"https://www.sonomamarintrain.org/","gtfsEnabled":true,"map":{"lat":38.2919,"lng":-122.458,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Sacramento Regional Transit","slug":"sacrt","metric":false,"cities":["sacramento"],"color":"#ffc72c","darkerColor":"#bfa000","textColor":"#000000","shortForms":["SacRT","Sacramento RT"],"summary":"Sacramento Regional Transit District (SacRT) operates the light rail system serving Sacramento and surrounding communities.","history":"SacRT launched its light rail service in 1987, initially connecting Watt/I-80 to Butterfield. The system expanded in the 1990s and 2000s, now serving Folsom, Rancho Cordova, and other suburbs. SacRT continues to modernize its fleet and expand service, playing a key role in the Sacramento region\'s transportation network.","stats":[{"label":"Rail Lines","value":"3"},{"label":"Stations","value":"53"},{"label":"System Length","value":"43 miles"},{"label":"Year Founded","value":"1987"}],"websiteUrl":"https://www.sacrt.com/","gtfsEnabled":true,"map":{"lat":38.5816,"lng":-121.4944,"zoom":11},"vehicleClassificationOverride":"light_rail"},{"name":"Charlotte Area Transit System","slug":"cats","metric":false,"cities":["charlotte"],"color":"#0072ce","darkerColor":"#004b87","textColor":"#FFFFFF","shortForms":["CATS"],"summary":"CATS operates the LYNX light rail and CityLYNX streetcar in Charlotte, North Carolina.","history":"The Charlotte Area Transit System (CATS) was established in 1999 to provide public transportation in the Charlotte metropolitan area. The LYNX Blue Line, the first light rail line in North Carolina, opened in 2007 and was later extended in 2018. CATS also operates the CityLYNX Gold Line streetcar, which began service in 2015. The system has played a significant role in Charlotte\'s urban development and continues to expand to meet the region\'s growing transportation needs.","stats":[{"label":"Year Founded","value":"1999"},{"label":"Light Rail Miles","value":"19"},{"label":"Streetcar Miles","value":"4"},{"label":"Stations","value":"38"},{"label":"Lines","value":"2"}],"websiteUrl":"https://charlottenc.gov/cats","gtfsEnabled":true,"map":{"lat":35.2271,"lng":-80.8431,"zoom":11},"vehicleClassificationOverride":"light_rail"},{"name":"Capital Metropolitan Transportation Authority","slug":"capitalmetro","metric":false,"cities":["austin"],"color":"#0074c2","darkerColor":"#005a99","textColor":"#FFFFFF","shortForms":["CapMetro","Capital Metro"],"summary":"Capital Metro operates the MetroRail Red Line and bus services in Austin, Texas.","history":"Capital Metro was established in 1985 to provide public transportation for Austin and surrounding communities. The MetroRail Red Line, a 32-mile commuter rail, began service in 2010, connecting downtown Austin to Leander. CapMetro has continued to expand its services, including plans for new light rail lines and rapid bus routes as part of Project Connect, a major transit expansion initiative approved by voters in 2020.","stats":[{"label":"Year Founded","value":"1985"},{"label":"Rail Line","value":"1 (Red Line)"},{"label":"System Length","value":"32 miles"},{"label":"Stations","value":"9"}],"websiteUrl":"https://www.capmetro.org/","gtfsEnabled":true,"map":{"lat":30.2672,"lng":-97.7431,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"OVapi (Netherlands Local & Regional Transit)","slug":"ovapi","metric":true,"cities":["amsterdam","rotterdam","utrecht","the-hague","eindhoven","groningen"],"color":"#003082","dar
16kerColor":"#00194a","textColor":"#FFFFFF","shortForms":["OVapi","Dutch Transit"],"summary":"OVapi provides unified access to real-time Dutch local and regional public transport data -- trams, metros, buses, and ferries. NS (Nederlandse Spoorwegen) national rail is tracked separately -- see the NS network.","history":"The Netherlands has a long tradition of integrated public transport, with regional operators and urban transit agencies developing extensive networks of trams, metros, and buses alongside the national rail system. OVapi emerged as an open API platform to aggregate and standardize real-time and static data from Dutch local and regional public transport providers, supporting seamless travel and journey planning across the country.","stats":[{"label":"Tram/Metro Lines","value":"40+"},{"label":"Bus Lines","value":"1,000+"}],"websiteUrl":"https://ovapi.nl/","gtfsEnabled":true,"map":{"lat":52.1326,"lng":5.2913,"zoom":7},"vehicleClassificationOverride":"regional_rail"},{"name":"Vy (Norwegian State Railways)","slug":"vy","metric":true,"cities":["oslo","bergen","trondheim","stavanger"],"color":"#00634b","darkerColor":"#004d3a","textColor":"#FFFFFF","shortForms":["Vy","NSB","Norwegian State Railways"],"summary":"Vy operates Norway\'s national and regional passenger rail services, connecting major cities and regions across the country.","history":"Vy, formerly known as Norges Statsbaner (NSB), has its origins in the 19th century, with the first railway line opening in 1854 between Oslo and Eidsvoll. NSB was the state railway company for over 150 years, playing a crucial role in Norway\'s development and modernization. In 2019, NSB was rebranded as Vy, reflecting a broader focus on mobility and public transport. Vy continues to operate most of Norway\'s long-distance, regional, and commuter trains, as well as some bus services, and is known for scenic routes such as the Bergen Line and Dovre Line.","stats":[{"label":"Year Founded","value":"1854"},{"label":"System Length","value":"4,200 km"},{"label":"Stations","value":"340+"},{"label":"Major Lines","value":"Bergen, Dovre, S\xf8rland, Nordland, \xd8stfold, Gj\xf8vik"}],"websiteUrl":"https://www.vy.no/","gtfsEnabled":false,"map":{"lat":60.472,"lng":8.4689,"zoom":5},"vehicleClassificationOverride":"regional_rail"},{"name":"Go-Ahead Norge","slug":"goaheadnordic","metric":true,"cities":["oslo","stavanger","kristiansand"],"color":"#e30613","darkerColor":"#a3000d","textColor":"#FFFFFF","shortForms":["Go-Ahead","Go-Ahead Norge"],"summary":"Go-Ahead Norge operates several long-distance and regional rail services in southern Norway, including the S\xf8rland, Arendal, and J\xe6ren lines.","history":"Go-Ahead Norge, a subsidiary of the UK-based Go-Ahead Group, began operating Norwegian rail services in December 2019 after winning a competitive tender. The company took over the S\xf8rland Line, Arendal Line, and J\xe6ren Line, providing both long-distance and commuter services between Oslo, Kristiansand, and Stavanger.","stats":[{"label":"Year Operations Began","value":"2019"},{"label":"System Length","value":"545 km"},{"label":"Stations","value":"35+"},{"label":"Major Lines","value":"S\xf8rland, Arendal, J\xe6ren"}],"websiteUrl":"https://go-aheadnordic.no/","gtfsEnabled":false,"map":{"lat":58.969,"lng":8.65,"zoom":6},"vehicleClassificationOverride":"regional_rail"},{"name":"SJ Nord","slug":"sj-nord","metric":true,"cities":["oslo","trondheim","bodo","roros","steinkjer"],"color":"#005baa","darkerColor":"#003d73","textColor":"#FFFFFF","shortForms":["SJ Nord","SJ Norge"],"summary":"SJ Nord operates long-distance and regional trains in central and northern Norway, including the Dovre, Nordland, Rauma, and R\xf8ros lines.","history":"SJ Nord, a subsidiary of Swedish operator SJ AB, began running trains in Norway in June 2020 after winning the Trafikkpakke Nord tender. The company operates key routes connecting Oslo, Trondheim, Bod\xf8, \xc5ndalsnes, and R\xf8ros, providing vital links across challenging and scenic terrain.","stats":[{"label":"Year Operations Began","value":"2020"},{"label":"System Length","value":"1,500+ km"},{"label":"Stations","value":"80+"},{"label":"Major Lines","value":"Dovre, Nordland, Rauma, R\xf8ros, Tr\xf8nderbanen"}],"websiteUrl":"https://www.sj.no/","gtfsEnabled":false,"map":{"lat":63.4305,"lng":10.3951,"zoom":5},"vehicleClassificationOverride":"regional_rail"}
16,{"name":"HSL (Helsinki Regional Transport)","slug":"hsl","metric":true,"cities":["helsinki","espoo","vantaa","kerava","kauniainen"],"color":"#009ee0","darkerColor":"#0077b6","textColor":"#FFFFFF","shortForms":["HSL","Helsingin seudun liikenne"],"summary":"HSL operates commuter rail, metro, trams, and buses in the Helsinki metropolitan area, providing integrated public transport across the region.","history":"Helsinki Regional Transport Authority (HSL) was established in 2010 to coordinate and operate public transport in the Helsinki region. The commuter rail network, operated in cooperation with VR, connects Helsinki with surrounding cities and suburbs. HSL also manages the Helsinki Metro, trams, and an extensive bus network, offering seamless travel with unified ticketing.","stats":[{"label":"Year Founded","value":"2010"},{"label":"Commuter Rail Lines","value":"15"},{"label":"Stations","value":"54"},{"label":"Metro Lines","value":"2"}],"websiteUrl":"https://www.hsl.fi/en","gtfsEnabled":true,"map":{"lat":60.1699,"lng":24.9384,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Miami-Dade Transit","slug":"miamidade","metric":false,"cities":["miami"],"color":"#008EAA","darkerColor":"#006B80","textColor":"#FFFFFF","shortForms":["MDT","Miami-Dade Transit"],"summary":"Miami-Dade Transit operates Metrorail, Metromover, Metrobus, and other public transportation services in Miami and the greater Miami-Dade County area.","history":"Miami-Dade Transit (MDT) was established in 1960 and has grown to become the largest transit agency in Florida. The Metrorail system opened in 1984, providing rapid transit service through Miami and surrounding communities. The Metromover, a free automated people mover, began operation in 1986, serving downtown Miami and connecting with Metrorail. MDT also operates an extensive Metrobus network and paratransit services, playing a vital role in the region\'s mobility and economic development.","stats":[{"label":"Year Founded","value":"1960"},{"label":"Metrorail Miles","value":"25"},{"label":"Metrorail Stations","value":"23"},{"label":"Metromover Stations","value":"21"},{"label":"Annual Ridership","value":"60m+"}],"websiteUrl":"https://www.miamidade.gov/transit/","gtfsEnabled":true,"map":{"lat":25.7617,"lng":-80.1918,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"North County Transit District","slug":"nctd","metric":false,"cities":["san-diego"],"color":"#005596","darkerColor":"#003f6b","textColor":"#FFFFFF","shortForms":["NCTD","COASTER","SPRINTER"],"summary":"North County Transit District (NCTD) operates COASTER commuter rail, SPRINTER light rail, and BREEZE bus services in northern San Diego County.","history":"NCTD was established in 1975 to provide public transportation in North San Diego County. The COASTER commuter rail began service in 1995, connecting Oceanside and downtown San Diego along the coast. The SPRINTER light rail, launched in 2008, links Oceanside and Escondido via a former freight rail corridor. NCTD also operates BREEZE buses and LIFT paratransit, serving a diverse and growing region.","stats":[{"label":"Year Founded","value":"1975"},{"label":"COASTER Route Miles","value":"41"},{"label":"COASTER Stations","value":"8"},{"label":"SPRINTER Route Miles","value":"22"},{"label":"SPRINTER Stations","value":"15"}],"websiteUrl":"https://gonctd.com/","map":{"lat":33.1959,"lng":-117.3795,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Transperth","slug":"transperth","metric":true,"cities":["perth"],"color":"#003DA5","darkerColor":"#002B75","textColor":"#FFFFFF","shortForms":["Transperth","PTA"],"summary":"Transperth is the public transport system serving the Perth metropolitan area in Western Australia, operating trains, buses, and ferries.","history":"Transperth was established in 1998 as the brand name for the Public Transport Authority of Western Australia\'s metropolitan services. Perth\'s suburban rail network dates back to 1881, with significant expansion in recent decades including the Mandurah Line (2007), Forrestfield-Airport Link (2022), and the Ellenbrook and Yanchep extensions (2024). The network now spans eight rail lines serving approximately 85
16stations across the Perth metro region, complemented by an extensive bus network and the South Perth ferry service.","stats":[{"label":"Rail Lines","value":"8"},{"label":"Train Stations","value":"85"},{"label":"Annual Ridership","value":"140m+"},{"label":"Operator","value":"Public Transport Authority of WA"}],"websiteUrl":"https://www.transperth.wa.gov.au","gtfsEnabled":true,"map":{"lat":-31.9523,"lng":115.8613,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"TransWA","slug":"transwa","metric":true,"cities":["perth"],"color":"#1A3668","darkerColor":"#0F2040","textColor":"#FFFFFF","shortForms":["TransWA","Transwa"],"summary":"TransWA is the regional public transport service of Western Australia, operating long-distance rail and coach services connecting Perth to regional centres.","history":"TransWA operates three rail services from East Perth: the Prospector to Kalgoorlie-Boulder (since 1971), the Australind to Bunbury (since 1947), and the AvonLink and MerredinLink commuter services to the Wheatbelt region. The Prospector covers 653 km in approximately 7 hours, making it one of Australia\'s longest-running regional rail services.","stats":[{"label":"Rail Routes","value":"3"},{"label":"Longest Route","value":"653 km"},{"label":"Operator","value":"Public Transport Authority of WA"}],"websiteUrl":"https://www.transwa.wa.gov.au","gtfsEnabled":true,"map":{"lat":-31.5,"lng":119.5,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"PID Prague","slug":"pid","metric":true,"cities":["prague"],"color":"#CF003D","darkerColor":"#9E0030","textColor":"#FFFFFF","shortForms":["PID","Prague"],"summary":"PID (Pražsk\xe1 integrovan\xe1 doprava) operates Prague\'s integrated transport network, including three metro lines, an extensive tram network, and regional rail lines connecting the city to surrounding Bohemia.","history":"Prague\'s metro opened in 1974 with Line C, followed by Line A in 1978 and Line B in 1985. PID was established in 1993 to integrate the capital\'s metro, tram, bus, and regional rail services under a single fare and information system, later expanding to coordinate regional rail across the wider Central Bohemian Region.","stats":[{"label":"Metro Lines","value":"3"},{"label":"Tram Routes","value":"36"},{"label":"Regional Rail Lines","value":"96"}],"websiteUrl":"https://pid.cz","gtfsEnabled":true,"map":{"lat":50.0755,"lng":14.4378,"zoom":12},"vehicleClassificationOverride":"subway"},{"name":"Ceske drahy","slug":"czech-rail","metric":true,"cities":["prague"],"countries":["Czechia"],"color":"#00457C","darkerColor":"#00325A","textColor":"#FFFFFF","shortForms":["CD","Czech Rail"],"summary":"Ceske drahy (CD) is Czechia\'s national rail operator, running Ex/R Intercity, Pendolino tilting-train, and regional (S/Sp) services across the country from a Prague-centered network.","history":"Ceske drahy was formed in 1993 when Czechoslovak State Railways split following the dissolution of Czechoslovakia. It operates the great majority of Czechia\'s national and regional passenger rail, from Pendolino tilting trains on trunk corridors to dense S-Bahn-style suburban services around Prague, Brno, and Ostrava.","stats":[{"label":"Routes","value":"927"},{"label":"Operator","value":"Ceske drahy"}],"websiteUrl":"https://www.cd.cz","gtfsEnabled":true,"map":{"lat":49.8175,"lng":15.473,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Krak\xf3w Trams","slug":"krakow","metric":true,"cities":["krakow"],"color":"#0F4C81","darkerColor":"#0A3560","textColor":"#FFFFFF","shortForms":["MPK Krak\xf3w"],"summary":"Krak\xf3w\'s tram network, operated by MPK Krak\xf3w, is one of the largest tram systems in Poland, serving the historic city and its surrounding districts.","history":"Trams have run in Krak\xf3w since 1882, originally horse-drawn before electrification in 1901. The network is operated today by Miejskie PrzedsiÄbiorstwo Komunikacyjne (MPK) Krak\xf3w under the coordination of the ZarzÄ
d Transportu Publicznego (ZTP), and remains a core part of the city\'s public transport alongside its bus network.","stats":[{"label":"Operator","value":"MPK Krak\xf3w"},{"label":"Vehicle Types","value":"Bombardier NGT6, PESA Krakowiak, Tatra"}],"websiteUrl":"https://mpk.krakow.pl/tramwaje","map":{"lat":50.0647,"lng":19.945,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"Warsaw Trams","slug":"warsaw","metric":true,"cities":["warsaw"],"color":"#C8102E","darkerColor":"#960B21","textColor":"#FFFFFF","shortForms":["WTP"],"summary":"Warsaw\'s tram network, operated by Tramwaje Warszawskie under the Warszawski Transport Publiczny (WTP) umbrella, is one of the largest in Europe, complementing the city\'s metro and bus services.","history":"Trams have operated in Warsaw since 1866, initially horse-drawn, with electrification completed by 1908. Much of the network was destroyed during World War II and rebuilt afterward. Today it is o
16perated by Tramwaje Warszawskie as part of the unified Warszawski Transport Publiczny system, which also coordinates the city\'s metro and bus networks.","stats":[{"label":"Operator","value":"Tramwaje Warszawskie"},{"label":"Tram Routes","value":"27"}],"websiteUrl":"https://www.wtp.waw.pl/","map":{"lat":52.2297,"lng":21.0122,"zoom":11},"vehicleClassificationOverride":"streetcar"},{"name":"PoznaÅ Trams","slug":"poznan","metric":true,"cities":["poznan"],"color":"#00843D","darkerColor":"#00622D","textColor":"#FFFFFF","shortForms":["MPK PoznaÅ"],"summary":"PoznaÅ\'s tram network, operated by MPK PoznaÅ, forms the backbone of the city\'s public transport alongside its extensive bus system.","history":"Trams have run in PoznaÅ since 1880, originally horse-drawn before electrification in 1898. The network is operated today by Miejskie PrzedsiÄbiorstwo Komunikacyjne (MPK) PoznaÅ, coordinated by the ZarzÄ
d Transportu Miejskiego (ZTM), and remains central to the city\'s transit alongside a wide regional bus network run by numerous smaller operators.","stats":[{"label":"Operator","value":"MPK PoznaÅ"},{"label":"Tram Routes","value":"23"}],"websiteUrl":"https://www.mpk.poznan.pl/","map":{"lat":52.4064,"lng":16.9252,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"GdaÅsk Trams","slug":"gdansk","metric":true,"cities":["gdansk"],"color":"#FDB913","darkerColor":"#C88D0B","textColor":"#000000","shortForms":["ZTM GdaÅsk"],"summary":"GdaÅsk\'s tram network, operated by ZarzÄ
d Transportu Miejskiego (ZTM) GdaÅsk, complements the city\'s bus network across the Tricity area.","history":"Trams have run in GdaÅsk since 1873, originally horse-drawn, with electrification completed by 1896. The network was substantially rebuilt after WWII damage and has continued expanding through the 2000s and 2010s, including new lines to CheÅm and Piecki-Migowo.","stats":[{"label":"Operator","value":"ZTM GdaÅsk"},{"label":"Tram Routes","value":"11"}],"websiteUrl":"https://ztm.gda.pl/","map":{"lat":54.352,"lng":18.6466,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"Riga Trams","slug":"riga","metric":true,"cities":["riga"],"color":"#8A1538","darkerColor":"#650F29","textColor":"#FFFFFF","shortForms":["RÄ«gas satiksme"],"summary":"Riga\'s tram network, operated by RÄ«gas satiksme, is one of the oldest in the Baltics, complementing the city\'s trolleybus and bus networks.","history":"Trams have run in Riga since 1882, originally horse-drawn, with electrification completed by 1901. The network is operated today by RÄ«gas satiksme, which also runs the city\'s trolleybus and bus services, making Riga one of the few European capitals to retain all three modes.","stats":[{"label":"Operator","value":"RÄ«gas satiksme"},{"label":"Tram Routes","value":"8"}],"websiteUrl":"https://www.rigassatiksme.lv/","map":{"lat":56.9496,"lng":24.1052,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"Sofia Trams","slug":"sofia","metric":true,"cities":["sofia"],"color":"#FFC72C","darkerColor":"#CC9E23","textColor":"#000000","shortForms":["ЦÐÐ"],"summary":"Sofia\'s tram network, operated by the Centre for Urban Mobility (ЦÐÐ), complements the city\'s metro, trolleybus, and bus networks.","history":"Trams have run in Sofia since 1901, initially electric from the outset. The network is operated today by the Centre for Urban Mobility (ЦенÑÑÑ Ð·Ð° гÑадÑка мобилноÑÑ), which coordinates all of Sofia\'s public transport modes, and remains a key part of the city\'s transit alongside its expanding metro system.","stats":[{"label":"Operator","value":"Center for Urban Mobility (ЦÐÐ)"},{"label":"Tram Routes","value":"24"}],"websiteUrl":"https://www.sofiatraffic.bg/","map":{"lat":42.6977,"lng":23.3219,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"Bucharest Trams","slug":"bucharest","metric":true,"cities":["bucharest"],"color":"#F5A623","darkerColor":"#C27F19","textColor":"#000000","shortForms":["STB"],"summary":"Bucharest\'s tram network, operated by STB (Societatea de Transport BucureÈti), complements the city\'s metro, trolleybus, and bus networks.","history":"Trams have run in Bucharest since 1894, initially horse-drawn with electrification following in 1899. The network is operated today by STB SA, part of the unified TPBI (Transport Public BucureÈti-Ilfov) authority, and remains one of the largest tram networks in Eastern Europe alongside the city\'s metro system (Metrorex, operated separately).","stats":[{"label":"Operator","value":"STB SA"},{"label":"Tram Routes","value":"14"}],"websiteUrl":"https://stbsa.ro/","map":{"lat":44.4268,"lng":26.1025,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"Cluj-Napoca Trams","slug":"clujnapoca","metric":true,"cities":["clujnapoca"],"color":"#009B77","darkerColor":"#00745A","textColor":"#FFFFFF","shortForms":["CTP Cluj"],"summary":"Cluj-Napoca\'s tram network is a single line operated by CTP Cluj, complementing the city\'s trolleybus and bus networks.","history":"Trams have run in Cluj-Napoca since 1911. The network today is a single route with a few branch variants, operated by Compania de Transport Public Cluj-Napoca (CTP Cluj), which also runs the city\'s trolleybus and bus services.","stats":[{"label":"Operator","value":"CTP Cluj"},{"label":"Tram Routes","value":"4"}],"websiteUrl":"https://ctpcj.ro/","map":{"lat":46.7712,"lng":23.6236,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"Rome Trams","slug":"rome","metric":true,"cities":["rome"],"color":"#8B1A2B","darkerColor":"#6B14
161F","textColor":"#FFFFFF","shortForms":["ATAC"],"summary":"Rome\'s tram network, operated by ATAC, is one of the oldest in Europe and still runs alongside the city\'s metro and extensive bus network.","history":"Rome\'s first horse-drawn trams appeared in the 1870s, electrifying by the turn of the century, and the network once spanned far more of the city before many lines were replaced by buses in the mid-20th century. Today ATAC (Azienda Tramvie ed Autobus del Comune di Roma) operates a compact surviving network of four lines through the historic center and outer districts, alongside the Metro and bus systems it also runs.","stats":[{"label":"Operator","value":"ATAC"},{"label":"Tram Routes","value":"4"}],"websiteUrl":"https://www.atac.roma.it/","map":{"lat":41.9028,"lng":12.4964,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"Turin Trams","slug":"turin","metric":true,"cities":["turin"],"color":"#00563F","darkerColor":"#003D2C","textColor":"#FFFFFF","shortForms":["GTT"],"summary":"Turin\'s tram network, operated by GTT (Gruppo Torinese Trasporti), complements the city\'s metro and extensive bus network.","history":"Trams have run in Turin since 1871, initially horse-drawn, with electrification completed by 1898. The network is operated today by GTT, which also runs Turin\'s automated Metro Line 1 and its bus services, and remains one of the largest surviving tram networks in Italy.","stats":[{"label":"Operator","value":"GTT"},{"label":"Tram Routes","value":"8"}],"websiteUrl":"https://www.gtt.to.it/","map":{"lat":45.0703,"lng":7.6869,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"BKK Budapest","slug":"bkk","metric":true,"cities":["budapest"],"color":"#FFD200","darkerColor":"#CCA800","textColor":"#000000","shortForms":["BKK","Budapest"],"summary":"BKK operates Budapest\'s public transport network including four metro lines, an extensive tram network, and suburban HEV rail lines.","history":"Budapest\'s first underground railway, the Millennium Underground (M1), opened in 1896 as continental Europe\'s first metro line and is now a UNESCO World Heritage Site. The network expanded with M2 (1970), M3 (1976), and M4 (2014). Budapest also operates one of Europe\'s largest tram networks, with iconic routes along the Danube, and five HEV suburban rail lines connecting the city to surrounding towns.","stats":[{"label":"Metro Lines","value":"4"},{"label":"Tram Routes","value":"38"},{"label":"HEV Lines","value":"5"},{"label":"Annual Ridership","value":"1.4b"}],"websiteUrl":"https://bkk.hu","gtfsEnabled":true,"map":{"lat":47.4979,"lng":19.0402,"zoom":12},"vehicleClassificationOverride":"subway"},{"name":"Hungarian Railways","slug":"mav","metric":true,"cities":[],"countries":["Hungary"],"color":"#14418B","darkerColor":"#0D2D61","textColor":"#FFFFFF","shortForms":["M\xc1V","MAV"],"summary":"M\xc1V operates Hungary\'s national railway network, with intercity, regional, and international services radiating from Budapest, alongside GYSEV services in the west of the country.","history":"Magyar \xc1llamvasutak (M\xc1V) was founded in 1868, shortly after the Austro-Hungarian Compromise, and grew into one of Central Europe\'s densest rail networks centred on Budapest\'s three grand terminals: Keleti, Nyugati, and D\xe9li. Passenger services are operated by M\xc1V-START, while GYSEV, a joint Hungarian-Austrian railway dating to 1872, serves the western border region. Hungary\'s position in the middle of Central Europe makes the network a major corridor for international trains to Austria, Slovakia, Czechia, Romania, Croatia, and Serbia.","stats":[{"label":"Year Founded","value":"1868"},{"label":"Route Kilometers","value":"7,700"},{"label":"Annual Ridership","value":"140m"},{"label":"Operators","value":"M\xc1V-START, GYSEV"}],"websiteUrl":"https://www.mavcsoport.hu","gtfsEnabled":true,"map":{"lat":47.1625,"lng":19.5033,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Slovakia National Rail","slug":"slovakia-rail","metric":true,"cities":[],"countries":["Slovakia"],"color":"#005BAC","darkerColor":"#003D73","textColor":"#FFFFFF","shortForms":["ŽSR","ZSSK","Slovak Railways"],"summary":"Slovakia\'s national passenger rail timetable covers services from ZSSK and other operators across the ŽSR network.","history":"Železnice Slovenskej republiky (ŽSR) manages Slovakia\'s railway infrastru
16cture and publishes the national passenger timetable as open GTFS data. Passenger trains are operated by ZSSK and other domestic and international operators.","stats":[{"label":"Infrastructure Manager","value":"ŽSR"},{"label":"Data","value":"Scheduled positions"}],"websiteUrl":"https://www.zsr.sk/","gtfsEnabled":true,"map":{"lat":48.669,"lng":19.699,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Finland National Rail","slug":"digitraffic","metric":true,"cities":[],"countries":["Finland"],"color":"#2D6A2E","darkerColor":"#1E4A1F","textColor":"#FFFFFF","shortForms":["VR","Digitraffic"],"summary":"Finland\'s national railway network operated by VR Group, covering long-distance, commuter, and regional rail services across the country.","history":"Finland\'s railway network dates back to 1862 with the opening of the Helsinki-H\xe4meenlinna line. VR Group (formerly Finnish State Railways) has operated the network since 1862, making it one of Europe\'s oldest continuously operating railway companies. The network connects major cities including Helsinki, Tampere, Turku, and Oulu, with the northernmost services reaching Kolari in Lapland. The Allegro service to St. Petersburg operated until 2022. Finland uses 1,524mm broad gauge, inherited from the Russian Empire era.","stats":[{"label":"Route Km","value":"5,918"},{"label":"Stations","value":"200+"},{"label":"Annual Ridership","value":"90m"},{"label":"Operator","value":"VR Group"}],"websiteUrl":"https://www.vr.fi","gtfsEnabled":true,"map":{"lat":62,"lng":25.5,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"Adelaide Metro","slug":"adelaide","metric":true,"cities":["adelaide"],"color":"#004B87","darkerColor":"#003460","textColor":"#FFFFFF","shortForms":["Adelaide Metro"],"summary":"Adelaide Metro operates the commuter rail and tram network serving the Adelaide metropolitan area in South Australia.","history":"Adelaide\'s first railway opened in 1856, making it one of Australia\'s oldest rail networks. The metropolitan rail system now comprises six lines radiating from Adelaide Railway Station, serving suburbs from Belair in the Adelaide Hills to Gawler in the north, Outer Harbor on the coast, and Seaford in the south. The iconic Glenelg tram line, originally opened in 1929, was modernised in 2007 and extended through the CBD to the Adelaide Entertainment Centre. The network underwent significant upgrades including electrification of the Seaford and Tonsley lines in 2014.","stats":[{"label":"Rail Lines","value":"6"},{"label":"Tram Line","value":"1"},{"label":"Annual Ridership","value":"13m+"},{"label":"Operator","value":"Adelaide Metro"}],"websiteUrl":"https://www.adelaidemetro.com.au","gtfsEnabled":true,"map":{"lat":-34.9285,"lng":138.6007,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"Irish Rail","slug":"irishrail","metric":true,"cities":["dublin"],"color":"#009A44","darkerColor":"#006E30","textColor":"#FFFFFF","shortForms":["Iarnr\xf3d \xc9ireann","I\xc9"],"summary":"Irish Rail (Iarnr\xf3d \xc9ireann) is the national railway operator of Ireland, running intercity, commuter, and DART services across the country.","history":"Iarnr\xf3d \xc9ireann was established in 1987 as part of the restructuring of C\xf3ras Iompair \xc9ireann (CI\xc9), Ireland\'s national transport authority. Rail services in Ireland date back to 1834 when the Dublin and Kingstown Railway opened as one of the earliest public railways in the world. The network expanded throughout the 19th century, connecting major cities and towns across the island. Today, Irish Rail operates InterCity services linking Dublin with Cork, Galway, Limerick, Waterford, Belfast, Sligo, and Westport, as well as the electrified DART (Dublin Area Rapid Transit) coastal commuter line and suburban commuter services radiating from Dublin.","stats":[{"label":"Stations","value":"152"},{"label":"Routes","value":"18"},{"label":"Annual Passengers","value":"52m+"},{"label":"Year Founded","value":"1987"}],"websiteUrl":"https://www.irishrail.ie","gtfsEnabled":true,"map":{"lat":53.4,"lng":-7.5,"zoom":7},"vehicleClassificationOverride":"regional_rail"},{"name":"WeGo Star","slug":"wego","metric":false,"cities":["nashville"],"color":"#0054A6","darkerColor":"#003D7A","textColor":"#FFFFFF","shortForms":["WeGo Star","Music City Star"],"summary":"The WeGo Star is Nashville\'s commuter rail line, connecting the eastern suburbs of Wilson County to downtown Nashville.","history":"The Music City Star, now branded as WeGo Star, began service in September 2006 as Middle Tennessee\'s first commuter rail line. It operates on a 32-mile corri
16dor from Lebanon to downtown Nashville, running along existing CSX freight rail tracks. The service was developed by the Regional Transportation Authority of Middle Tennessee to provide an alternative to the congested I-40 corridor. It serves seven stations and primarily caters to weekday commuters with morning inbound and evening outbound service.","stats":[{"label":"Year Founded","value":"2006"},{"label":"System Miles","value":"32"},{"label":"Stations","value":"7"},{"label":"Lines","value":"1"}],"websiteUrl":"https://www.wegotransit.com","map":{"lat":36.16,"lng":-86.58,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Eurostar","slug":"eurostar","metric":true,"cities":["london","paris","brussels","amsterdam"],"countries":["France","United Kingdom","Belgium","Netherlands"],"color":"#003764","darkerColor":"#00264A","textColor":"#FFFFFF","shortForms":["Eurostar"],"summary":"Eurostar is a high-speed rail service connecting London with Paris, Brussels, and Amsterdam via the Channel Tunnel.","history":"Eurostar began commercial service on 14 November 1994, initially running between London Waterloo and Paris Gare du Nord and Brussels-Midi. The service was made possible by the completion of the Channel Tunnel, linking the United Kingdom to mainland Europe by rail for the first time. In 2007, Eurostar moved its London terminus to the newly renovated St Pancras International, coinciding with the opening of High Speed 1, which dramatically cut journey times. The London-Paris journey dropped to around 2 hours 15 minutes. In 2018, Eurostar extended direct services to Amsterdam Centraal. The company merged with Thalys in 2023, creating a unified high-speed rail network across Western Europe under the Eurostar brand.","stats":[{"label":"Year Founded","value":"1994"},{"label":"Top Speed (km/h)","value":"300"},{"label":"Stations","value":"9"},{"label":"Countries","value":"4"}],"websiteUrl":"https://www.eurostar.com","gtfsEnabled":true,"map":{"lat":50.2,"lng":1.8,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"ScotRail","slug":"scotrail","metric":true,"cities":["edinburgh","glasgow"],"countries":["United Kingdom"],"color":"#1C4586","darkerColor":"#0F2D5C","textColor":"#FFFFFF","shortForms":["ScotRail"],"summary":"ScotRail operates most passenger rail services within Scotland, connecting cities, towns, and rural communities across the country.","history":"ScotRail is the brand used for most passenger rail services in Scotland. The franchise has been operated by various companies since British Rail was privatised in the 1990s. In 2022, ScotRail was brought into public ownership under Scottish Rail Holdings, a subsidiary of the Scottish Government. The network spans from the Highlands to the Borders, serving over 350 stations and carrying approximately 100 million passenger journeys per year. ScotRail operates a mix of urban commuter services around Glasgow and Edinburgh, intercity routes, and scenic rural lines including the West Highland Line and the Far North Line.","stats":[{"label":"Stations","value":"359"},{"label":"Annual Passengers","value":"100m"},{"label":"Year Established","value":"1983"},{"label":"Route Kilometers","value":"4,200"}],"websiteUrl":"https://www.scotrail.co.uk","gtfsEnabled":true,"map":{"lat":56.49,"lng":-4.2,"zoom":6},"vehicleClassificationOverride":"regional_rail"},{"name":"LNER","slug":"lner","metric":true,"cities":["london","edinburgh","leeds"],"countries":["United Kingdom"],"color":"#CE0E2D","darkerColor":"#9C0B22","textColor":"#FFFFFF","shortForms":["LNER"],"summary":"LNER operates intercity services on the East Coast Main Line between London King\'s Cross, Yorkshire, North East England, and Scotland.","history":"London North Eastern Railway (LNER) is the operator of intercity rail services on the East Coast Main Line, one of the most important rail corridors in Great Britain. The brand revived the name of the original LNER, one of the \'Big Four\' railway companies that operated from 1923 to 1948. The current LNER has been publicly owned since 2018, operated by DfT OLR Holdings. The East Coast Main Line runs from London King\'s Cross through Peterborough, Doncaster, York, Durham, and Newcastle to Edinburgh, with branches to Leeds, Hull, and other destinations. LNER operates the Azuma fleet of bi-mode trains, capable of running on both electrified and non-electrified track.","stats":[{"label":"Stations","value":"51"},{"label":"Annual Passengers","value":"25m"},{"label":"Year Established","value":"2018"},{"label":"Route Kilometers","value":"1,480"}],"websiteUrl":"https://www.lner.co.uk","gtfsEnabled":true,"map":{"lat":53.5,"lng":-1,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"Great Western Railway","slug":"great-western","metric":true,"cities":["london","bristol","cardiff"],"countries":["United Kingdom"],"color":"#0A493E","darkerColor":"#073029","textColor":"#FFFFFF","shortForms":["GWR"],"summary":"Great Western Railway operates intercity, commuter, and regional services from London Paddington across southern England and Wales.","history":"Great Western Railway (GWR) is a train operating company running services across a large swath of southern England and Wales. The brand takes its name from the original Great Western Railway, founded by Isambard Kingdom Brunel in 1833, which was one of the most famous railway companies in British history. The modern GWR has been operated by FirstGroup since 2015, running services from London Paddington to Bristol, Cardiff, Exeter, Plymouth, Penzance, and numerous other destinations. The network includes the newly electrified Great Western Main Line, high-speed intercity services, and scenic branch lines through Devon and Cornwall.","stats":[{"label":"Stations","value":"270+"},{"label":"Annual Passengers","value":"105m"},{"label":"Year Established","value":"2015"},{"label":"Route Kilometers","value":"3,600"}],"websiteUrl":"https://www.gwr.com","gtfsEnabled":true,"map":{"lat":51.5,"lng":-2.5,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"Avanti West Coast","slug":"avanti","metric":true,"cities":["london","birmingham","manchester"],"countries":["United Kingdom"],"color":"#582C83","darkerColor":"#3D1D5C","textColor":"#FFFFFF","shortForms":["Avanti"],"summary":"Avanti West Coast operates intercity services on the West Coast Main Line between London Euston, Birmingham, Manchester, Liverpool, and Glasgow.","stats":[{"label":"Stations","value":"76"},{"label":"Annual Passengers","value":"38m"},{"label":"Year Established","value":"2019"}],"websiteUrl":"https://www.avantiwestcoast.co.uk","gtfsEnabled":true,"map":{"lat":52.5,"lng":-2,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"CrossCountry","slug":"crosscountry","metric":true,"cities":["birmingham"],"countries":["United Kingdom"],"color":"#660F21","darkerColor":"#4A0B18","textColor":"#FFFFFF","shortForms":["CrossCountry","XC"],"summary":"CrossCountry operates long-distance services linking major cities across England, Scotland, and Wales without passing through London.","stats":[{"label":"Stations","value":"118"},{"label":"Annual Passengers","value":"40m"},{"label":"Year Established","value":"2007"}],"websiteUrl":"https://www.crosscountrytrains.co.uk","gtfsEnabled":true,"map":{"lat":52.5,"lng":-1.9,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"TransPennine Express","slug":"transpennine","metric":true,"cities":["manchester","leeds"],"countries":["United Kingdom"],"color":"#232B6A","dar
16kerColor":"#181D4A","textColor":"#FFFFFF","shortForms":["TPE"],"summary":"TransPennine Express operates inter-regional services across northern England and into Scotland.","stats":[{"label":"Stations","value":"60+"},{"label":"Annual Passengers","value":"30m"},{"label":"Year Established","value":"2004"}],"websiteUrl":"https://www.tpexpress.co.uk","gtfsEnabled":true,"map":{"lat":53.8,"lng":-1.8,"zoom":7},"vehicleClassificationOverride":"regional_rail"},{"name":"Northern","slug":"northern","metric":true,"cities":["manchester","leeds","liverpool"],"countries":["United Kingdom"],"color":"#262262","darkerColor":"#1A1745","textColor":"#FFFFFF","shortForms":["Northern"],"summary":"Northern operates commuter and regional rail services across the north of England.","stats":[{"label":"Stations","value":"470"},{"label":"Annual Passengers","value":"100m"},{"label":"Year Established","value":"2016"}],"websiteUrl":"https://www.northernrailway.co.uk","gtfsEnabled":true,"map":{"lat":53.8,"lng":-2.2,"zoom":7},"vehicleClassificationOverride":"commuter_rail"},{"name":"Southeastern","slug":"southeastern","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#00AEEF","darkerColor":"#008AC0","textColor":"#000000","shortForms":["Southeastern"],"summary":"Southeastern operates commuter and high-speed services across London, Kent, and East Sussex.","stats":[{"label":"Stations","value":"180"},{"label":"Annual Passengers","value":"180m"},{"label":"Year Established","value":"2006"}],"websiteUrl":"https://www.southeasternrailway.co.uk","gtfsEnabled":true,"map":{"lat":51.3,"lng":0.5,"zoom":8},"vehicleClassificationOverride":"commuter_rail"},{"name":"Southern","slug":"southern","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#8CC63F","darkerColor":"#6FA030","textColor":"#000000","shortForms":["Southern"],"summary":"Southern operates commuter services across London, Surrey, Sussex, and Hampshire.","stats":[{"label":"Stations","value":"160"},{"label":"Annual Passengers","value":"130m"},{"label":"Year Established","value":"2001"}],"websiteUrl":"https://www.southernrailway.com","gtfsEnabled":true,"map":{"lat":51.1,"lng":-0.2,"zoom":8},"vehicleClassificationOverride":"commuter_rail"},{"name":"Thameslink","slug":"thameslink","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#D7007B","darkerColor":"#A80060","textColor":"#FFFFFF","shortForms":["Thameslink"],"summary":"Thameslink operates cross-London services from Bedford and Cambridge through central London to Brighton and the south coast.","stats":[{"label":"Stations","value":"60+"},{"label":"Annual Passengers","value":"50m"},{"label":"Year Established","value":"1988"}],"websiteUrl":"https://www.thameslinkrailway.com","gtfsEnabled":true,"map":{"lat":51.4,"lng":-0.1,"zoom":8},"vehicleClassificationOverride":"commuter_rail"},{"name":"Great Northern","slug":"great-northern","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#4A0D66","darkerColor":"#350A4A","textColor":"#FFFFFF","shortForms":["Great Northern","GN"],"summary":"Great Northern operates commuter services from London King\'s Cross to Hertfordshire, Cambridgeshire, and beyond.","stats":[{"label":"Stations","value":"45"},{"label":"Annual Passengers","value":"50m"},{"label":"Year Established","value":"2014"}],"websiteUrl":"https://www.greatnorthernrail.com","gtfsEnabled":true,"map":{"lat":51.8,"lng":-0.1,"zoom":8},"vehicleClassificationOverride":"commuter_rail"},{"name":"South Western Railway","slug":"south-western","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#0066B3","darkerColor":"#004D87","textColor":"#FFFFFF","shortForms":["SWR"],"summary":"South Western Railway operates commuter and regional services from London Waterloo across Surrey, Hampshire, Dorset, Devon, and Somerset.","stats":[{"label":"Stations","value":"187"},{"label":"Annual Passengers","value":"210m"},{"label":"Year Established","value":"2017"}],"websiteUrl":"https://www.southwesternrailway.com","gtfsEnabled":true,"map":{"lat":51.1,"lng":-1.2,"zoom":7},"vehicleClassificationOverride":"commuter_rail"},{"name":"East Midlands Railway","slug":"east-midlands","metric":true,"cities":[],"countries":["United Kingdom"],"color":"#6B2C91","darkerColor":"#4F2069","textColor":"#FFFFFF","shortForms":["EMR"],"summary":"East Midlands Railway operates intercity and regional services across the East Midlands, connecting London St Pancras to Nottingham, Derby, and Sheffield.","stats":[{"label":"Stations","value":"100+"},{"label":"Annual Passengers","value":"30m"},{"label":"Year Established","value":"2019"}],"websiteUrl":"https://www.eastmidlandsrailway.co.uk","gtfsEnabled":true,"map":{"lat":52.9,"lng":-1.2,"zoom":7},"vehicleClassificationOverride":"regional_rail"},{"name":"c2c","slug":"c2c","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#B71C8D","darkerColor":"#8E1670","textColor":"#FFFFFF","shortForms":["c2c"],"summary":"c2c operates commuter services from London Fenchurch Street to Southend and towns across south Essex.","stats":[{"label":"Stations","value":"26"},{"label":"Annual Passengers","value":"40m"},{"label":"Year Established","value":"1996"}
16],"websiteUrl":"https://www.c2c-online.co.uk","gtfsEnabled":true,"map":{"lat":51.5,"lng":0.6,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"Chiltern Railways","slug":"chiltern","metric":true,"cities":["london","birmingham"],"countries":["United Kingdom"],"color":"#00BFB3","darkerColor":"#009990","textColor":"#000000","shortForms":["Chiltern"],"summary":"Chiltern Railways operates services from London Marylebone through the Chiltern Hills to Birmingham, Oxford, and Aylesbury.","stats":[{"label":"Stations","value":"35"},{"label":"Annual Passengers","value":"30m"},{"label":"Year Established","value":"1996"}],"websiteUrl":"https://www.chilternrailways.co.uk","gtfsEnabled":true,"map":{"lat":51.8,"lng":-1,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"Merseyrail","slug":"merseyrail","metric":true,"cities":["liverpool"],"countries":["United Kingdom"],"color":"#FFD200","darkerColor":"#CCA900","textColor":"#000000","shortForms":["Merseyrail"],"summary":"Merseyrail operates the commuter rail network across Merseyside, centred on Liverpool.","stats":[{"label":"Stations","value":"67"},{"label":"Annual Passengers","value":"40m"},{"label":"Year Established","value":"2003"}],"websiteUrl":"https://www.merseyrail.org","gtfsEnabled":true,"map":{"lat":53.4,"lng":-3,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Elizabeth line","slug":"elizabeth-line","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#6950A1","darkerColor":"#503D7A","textColor":"#FFFFFF","shortForms":["Elizabeth line","Crossrail"],"summary":"The Elizabeth line is a cross-London railway running from Reading and Heathrow in the west to Shenfield and Abbey Wood in the east.","stats":[{"label":"Stations","value":"41"},{"label":"Annual Passengers","value":"150m+"},{"label":"Year Opened","value":"2022"}],"websiteUrl":"https://tfl.gov.uk/modes/elizabeth-line","gtfsEnabled":true,"map":{"lat":51.52,"lng":-0.08,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"London Underground","slug":"tfl-underground","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#0019A8","darkerColor":"#001275","textColor":"#FFFFFF","shortForms":["Underground","The Tube","LU"],"summary":"The London Underground (the Tube) is one of the world\'s oldest and busiest metro systems, running 11 lines across Greater London under Transport for London.","stats":[{"label":"Lines","value":"11"},{"label":"Stations","value":"272"},{"label":"Annual Passengers","value":"1.2bn+"},{"label":"Year Opened","value":"1863"}],"websiteUrl":"https://tfl.gov.uk/modes/tube","gtfsEnabled":true,"map":{"lat":51.51,"lng":-0.1,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"London Overground","slug":"london-overground","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#EE7C0E","darkerColor":"#C06509","textColor":"#000000","shortForms":["Overground"],"summary":"London Overground is an orbital and suburban rail network connecting communities across Greater London.","stats":[{"label":"Stations","value":"113"},{"label":"Annual Passengers","value":"185m"},{"label":"Year Established","value":"2007"}],"websiteUrl":"https://tfl.gov.uk/modes/london-overground","gtfsEnabled":true,"map":{"lat":51.53,"lng":-0.07,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"London Northwestern Railway","slug":"london-northwestern","metric":true,"cities":["london","birmingham"],"countries":["United Kingdom"],"color":"#2D2E83","darkerColor":"#1F1F5C","textColor":"#FFFFFF","shortForms":["LNR"],"summary":"London Northwestern Railway operates commuter and regional services from London Euston to the West Midlands, Crewe, and Liverpool.","stats":[{"label":"Stations","value":"90+"},{"label":"Annual Passengers","value":"70m"},{"label":"Year Established","value":"2017"}],"websiteUrl":"https://www.londonnorthwesternrailway.co.uk","gtfsEnabled":true,"map":{"lat":52.3,"lng":-1.5,"zoom":7},"vehicleClassificationOverride":"commuter_rail"},{"name":"Hull Trains","slug":"hull-trains","metric":true,"cities":["london","leeds"],"countries":["United Kingdom"],"color":"#D6006E","darkerColor":"#A80057","textColor":"#FFFFFF","shortForms":["Hull Trains"],"summary":"Hull Trains is an open access operator running intercity services between London King\'s Cross and Hull via Doncaster.","stats":[{"label":"Trains per Day","value":"7"},{"label":"Year Established","value":"2000"}],"websiteUrl":"https://www.hulltrains.co.uk","gtfsEnabled":true,"map":{"lat":53.5,"lng":-0.5,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Grand Central","slug":"grand-central","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#1A1A1A","darkerColor":"#000000","textColor":"#FFFFFF","shortForms":["Grand Central"],"summary":"Grand Central is an open access operator running intercity services from London King\'s Cross to Sunderland and Bradford.","stats":[{"label":"Trains per Day","value":"8"},{"label":"Year Established","value":"2007"}],"websiteUrl":"https://www.grandcentralrail.com","gtfsEnabled":true,"map":{"lat":53.8,"lng":-1.3,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Caledonian Sleeper","slug":"caledonian-sleeper","metric":true,"cities":["london","edinburgh","glasgow"],"countries":["United Kingdom"],"color":"#1B365
16D","darkerColor":"#0F2240","textColor":"#FFFFFF","shortForms":["Caledonian Sleeper"],"summary":"The Caledonian Sleeper operates overnight trains between London Euston and Scottish destinations including Edinburgh, Glasgow, Fort William, Aberdeen, and Inverness.","stats":[{"label":"Routes","value":"5"},{"label":"Year Established","value":"2015"}],"websiteUrl":"https://www.sleeper.scot","gtfsEnabled":true,"map":{"lat":55,"lng":-3.5,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"Transport for Wales","slug":"transport-for-wales","metric":true,"cities":["cardiff"],"countries":["United Kingdom"],"color":"#DA291C","darkerColor":"#AE2016","textColor":"#FFFFFF","shortForms":["TfW"],"summary":"Transport for Wales operates rail services across Wales and the English borders, connecting Cardiff, Swansea, the Valleys, and cross-border routes.","stats":[{"label":"Stations","value":"247"},{"label":"Annual Passengers","value":"35m"},{"label":"Year Established","value":"2018"}],"websiteUrl":"https://www.tfwrail.wales","gtfsEnabled":true,"map":{"lat":52,"lng":-3.5,"zoom":7},"vehicleClassificationOverride":"regional_rail"},{"name":"Greater Anglia","slug":"greater-anglia","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#D70428","darkerColor":"#A80320","textColor":"#FFFFFF","shortForms":["Greater Anglia"],"summary":"Greater Anglia operates services from London Liverpool Street across East Anglia, including Norfolk, Suffolk, Essex, and Cambridgeshire.","stats":[{"label":"Stations","value":"133"},{"label":"Annual Passengers","value":"80m"},{"label":"Year Established","value":"2012"}],"websiteUrl":"https://www.greateranglia.co.uk","gtfsEnabled":true,"map":{"lat":52.2,"lng":1,"zoom":7},"vehicleClassificationOverride":"regional_rail"},{"name":"Heathrow Express","slug":"heathrow-express","metric":true,"cities":["london"],"countries":["United Kingdom"],"color":"#532E63","darkerColor":"#3D2249","textColor":"#FFFFFF","shortForms":["Heathrow Express","HX"],"summary":"Heathrow Express is a non-stop airport rail link between London Paddington and Heathrow Airport.","stats":[{"label":"Journey Time","value":"15 min"},{"label":"Frequency","value":"Every 15 min"},{"label":"Year Opened","value":"1998"}],"websiteUrl":"https://www.heathrowexpress.com","gtfsEnabled":true,"map":{"lat":51.49,"lng":-0.35,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"SL","slug":"sl","metric":true,"cities":["stockholm"],"countries":["Sweden"],"color":"#00A4E4","darkerColor":"#0077B3","textColor":"#FFFFFF","shortForms":["SL","Storstockholms Lokaltrafik"],"summary":"SL operates the metro, commuter rail, and light rail network across the greater Stockholm region.","history":"Storstockholms Lokaltrafik (SL) is the public transport authority for Stockholm County, responsible for metro, commuter rail, light rail, and bus services. The Stockholm metro (Tunnelbana) opened in 1950 and has grown into one of Europe\'s most distinctive subway systems, famous for its art-adorned stations. SL\'s commuter rail (Pendelt\xe5g) connects suburbs and satellite towns across the M\xe4laren Valley, while the Roslagsbanan and Saltsj\xf6banan narrow-gauge lines serve the northern and eastern suburbs. Together these rail services carry hundreds of millions of passengers annually, forming the backbone of transport in Sweden\'s capital region.","stats":[{"label":"Metro Lines","value":"3"},{"label":"Metro Stations","value":"100"},{"label":"Annual Ridership","value":"380m"},{"label":"Year Founded","value":"1967"}],"websiteUrl":"https://sl.se","gtfsEnabled":true,"map":{"lat":59.33,"lng":18.07,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"Sk\xe5netrafiken","slug":"skanetrafiken","metric":true,"cities":["malmo","helsingborg"],"countries":["Sweden"],"color":"#CE1141","darkerColor":"#9C0E32","textColor":"#FFFFFF","shortForms":["Sk\xe5netrafiken"],"summary":"Sk\xe5netrafiken operates P\xe5gat\xe5gen commuter trains and \xd6resundst\xe5g regional rail across southern Sweden\'s Sk\xe5ne region.","history":"Sk\xe5netrafiken is the regional public transport authority for Sk\xe5ne, Sweden\'s southernmost county. It operates the P\xe5gat\xe5gen commuter rail network connecting Malm\xf6, Lund, Helsingborg, Kristianstad, and other towns across the region. Sk\xe5netrafiken also coordinates \xd6resundst\xe5g services that cross the \xd8resund Bridge to Copenhagen, making it a key node in Scandinavian cross-border rail travel. The P\xe5gat\xe5gen network has expanded significantly since its launch in 1983, with the opening of the City Tunnel through central Malm\xf6 in 2010 greatly improving connectivity.","stats":[{"label":"Stations","value":"100+"},{"label":"Annual Ridership","value":"40m"},{"label":"Year Founded","value":"1999"},{"label":"Route Kilometers","value":"1,100"}],"websiteUrl":"https://www.skanetrafiken.se","gtfsEnabled":true,"map":{"lat":55.9,"lng":13.2,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"\xd6stg\xf6tatrafiken","slug":"ostgotatrafiken","metric":true,"cities":["linkoping","norrkoping"],"countries":["Sweden"],"color":"#E3000B","darkerColor":"#B00009","textColor":"#FFFFFF","shortForms":["\xd6stg\xf6tatrafiken","\xd6T"],"summary":"\xd6stg\xf6tatrafiken operates regional rail services connecting Link\xf6ping, Norrk\xf6ping, and surrounding towns in eastern Sweden.","history":"\xd6stg\xf6tatrafiken is the regional public transport authority for \xd6sterg\xf6tland County in eastern Sweden. The authority coordinates bus and rail services across the region, including the \xd6stg\xf6tapendeln commuter trains running between Link\xf6ping and Norrk\xf6ping, two of Sweden\'s larger cities. The rail services connect to the national network, providing links to Stockholm and Malm\xf6 via the Southern Main Line. \xd6stg\xf6tatrafiken has
16invested in modernizing its fleet and expanding service frequency to meet growing demand in one of Sweden\'s fastest-developing regions.","stats":[{"label":"Rail Stations","value":"15+"},{"label":"Year Founded","value":"1999"},{"label":"Route Kilometers","value":"200"}],"websiteUrl":"https://www.ostgotatrafiken.se","gtfsEnabled":true,"map":{"lat":58.5,"lng":15.9,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"SJ","slug":"sj","metric":true,"cities":["stockholm","gothenburg","malmo"],"countries":["Sweden"],"color":"#1D1D1B","darkerColor":"#000000","textColor":"#FFFFFF","shortForms":["SJ"],"summary":"SJ is Sweden\'s national intercity rail operator, running high-speed and long-distance trains across the country.","history":"SJ AB is the primary passenger train operator in Sweden, successor to the state railway Statens J\xe4rnv\xe4gar which dates back to 1856. SJ operates high-speed X 2000 tilting trains and newer SJ 3000 trainsets on intercity routes connecting Stockholm, Gothenburg, Malm\xf6, Sundsvall, and destinations across Sweden. Following rail deregulation in the 2000s, SJ became a state-owned company competing on the open market. The X 2000, introduced in 1990, reaches speeds of 200 km/h and dramatically reduced journey times between Sweden\'s major cities.","stats":[{"label":"Top Speed","value":"200 km/h"},{"label":"Annual Passengers","value":"32m"},{"label":"Year Founded","value":"1856"},{"label":"Stations","value":"284"}],"websiteUrl":"https://www.sj.se","gtfsEnabled":true,"map":{"lat":62,"lng":15,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"V\xe4sttrafik","slug":"vasttrafik","metric":true,"cities":["gothenburg"],"countries":["Sweden"],"color":"#00A5E3","darkerColor":"#007BB5","textColor":"#FFFFFF","shortForms":["V\xe4sttrafik"],"summary":"V\xe4sttrafik operates commuter and regional rail services across western Sweden\'s V\xe4stra G\xf6taland region.","history":"V\xe4sttrafik is the regional public transport authority for V\xe4stra G\xf6taland, Sweden\'s second most populous county centered on Gothenburg. The authority manages an extensive network of commuter trains, regional rail, trams, buses, and ferries. Rail services include Gothenburg\'s commuter trains connecting the city with surrounding towns like Alings\xe5s, Kungsbacka, and Trollh\xe4ttan. V\xe4sttrafik also coordinates the iconic Gothenburg tram network, one of the largest in Northern Europe, alongside regional rail links extending throughout western Sweden.","stats":[{"label":"Rail Stations","value":"100+"},{"label":"Annual Ridership","value":"300m"},{"label":"Year Founded","value":"1999"},{"label":"Route Kilometers","value":"2,000+"}],"websiteUrl":"https://www.vasttrafik.se","gtfsEnabled":true,"map":{"lat":57.7,"lng":12,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"\xd6resundst\xe5g","slug":"oresundstag","metric":true,"cities":["malmo","helsingborg"],"countries":["Sweden"],"color":"#9B59B6","darkerColor":"#7D3C98","textColor":"#FFFFFF","shortForms":["\xd6resundst\xe5g"],"summary":"\xd6resundst\xe5g operates cross-border regional trains between Sweden and Denmark via the \xd8resund Bridge.","history":"\xd6resundst\xe5g is a cross-border rail service connecting southern Sweden with Copenhagen, Denmark via the \xd8resund Bridge. Launched in 2000 when the bridge opened, the service transformed the \xd8resund region into an integrated commuter zone. Trains run from Gothenburg, Kalmar, and Karlskrona through Malm\xf6 and across the bridge to Copenhagen Airport and Copenhagen Central Station. The service is jointly operated by Swedish and Danish railway companies and carries millions of cross-border commuters annually, making it one of Europe\'s busiest international commuter rail links.","stats":[{"label":"Stations","value":"50+"},{"label":"Annual Ridership","value":"16m"},{"label":"Year Founded","value":"2000"},{"label":"Route Kilometers","value":"700"}],"websiteUrl":"https://www.oresundstag.se","gtfsEnabled":true,"map":{"lat":55.9,"lng":13,"zoom":8},"vehicleClassificationOverride":"commuter_rail"},{"name":"Vy T\xe5g","slug":"vytag","metric":true,"cities":[],"countries":["Sweden"],"color":"#00843D","darkerColor":"#005C2A","textColor":"#FFFFFF","shortForms":["Vy T\xe5g","Vy"],"summary":"Vy T\xe5g operates regional rail services in Swede
16n under contract to regional transit authorities.","history":"Vy T\xe5g AB is a Swedish subsidiary of the Norwegian state railway company Vy (formerly NSB). It operates several regional rail contracts across Sweden, running trains on behalf of county transit authorities. Vy T\xe5g serves routes in multiple regions, providing an important link in Sweden\'s deregulated rail market where regional authorities contract private operators to run services. The company has grown its Swedish operations significantly since entering the market, becoming one of the country\'s larger train operating companies.","stats":[{"label":"Year Founded","value":"2010"},{"label":"Routes","value":"17"}],"websiteUrl":"https://www.vy.se","gtfsEnabled":true,"map":{"lat":60,"lng":15,"zoom":5},"vehicleClassificationOverride":"regional_rail"},{"name":"Sn\xe4llt\xe5get","slug":"snalltaget","metric":true,"cities":["stockholm","malmo"],"countries":["Sweden"],"color":"#FF6B00","darkerColor":"#CC5500","textColor":"#FFFFFF","shortForms":["Sn\xe4llt\xe5get"],"summary":"Sn\xe4llt\xe5get operates intercity and seasonal overnight trains connecting Swedish cities and international destinations.","history":"Sn\xe4llt\xe5get (literally \'the fast train\') is a Swedish open-access train operator owned by Transdev. It runs intercity services between Stockholm and Malm\xf6, as well as seasonal overnight trains to ski resorts in the Swedish mountains and summer services to Berlin via Denmark. Sn\xe4llt\xe5get positions itself as a more affordable alternative to SJ on popular intercity routes, and has carved out a niche particularly with its night train services that connect northern and southern Sweden.","stats":[{"label":"Routes","value":"15"},{"label":"Year Founded","value":"2007"}],"websiteUrl":"https://www.snalltaget.se","gtfsEnabled":true,"map":{"lat":59,"lng":16,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"MTR Express","slug":"mtrexpress","metric":true,"cities":["stockholm","gothenburg"],"countries":["Sweden"],"color":"#D4A843","darkerColor":"#B08A2E","textColor":"#000000","shortForms":["MTRX","MTR Express"],"summary":"MTR Express operates high-frequency intercity trains between Stockholm and Gothenburg.","history":"MTR Express (branded as MTRX) is a Swedish open-access train operator owned by Hong Kong\'s MTR Corporation. Launched in 2015, it was the first company to compete directly with SJ on the lucrative StockholmâGothenburg corridor, Sweden\'s busiest rail route. MTRX operates modern Stadler FLIRT trains offering a premium service with Wi-Fi, power outlets, and onboard catering. The 3-hour journey between Sweden\'s two largest cities has made MTRX a popular choice for business and leisure travelers.","stats":[{"label":"Route","value":"StockholmâGothenburg"},{"label":"Journey Time","value":"3 hours"},{"label":"Year Founded","value":"2015"},{"label":"Trains per Day","value":"10+"}],"websiteUrl":"https://www.mtrexpress.se","gtfsEnabled":true,"map":{"lat":58.5,"lng":14,"zoom":6},"vehicleClassificationOverride":"intercity_rail"}
16,{"name":"T\xc5GAB","slug":"tagab","metric":true,"cities":[],"countries":["Sweden"],"color":"#2E4057","darkerColor":"#1A2636","textColor":"#FFFFFF","shortForms":["T\xc5GAB"],"summary":"T\xc5GAB operates regional rail services in central Sweden under contract to regional transit authorities.","history":"T\xc5GAB (T\xe5g i Bergslagen AB) is a Swedish train operating company that runs regional passenger rail services primarily in the Bergslagen region of central Sweden. The company operates under contract to regional transit authorities, connecting towns across Dalarna, G\xe4vleborg, \xd6rebro, and V\xe4stmanland counties. T\xc5GAB provides an essential rail link in central Sweden, serving communities between the major cities with regular regional train services.","stats":[{"label":"Routes","value":"4"},{"label":"Region","value":"Bergslagen"}],"websiteUrl":"https://www.tagab.se","gtfsEnabled":true,"map":{"lat":60,"lng":15.5,"zoom":7},"vehicleClassificationOverride":"regional_rail"},{"name":"V\xe4rmlandstrafik","slug":"varmlandstrafik","metric":true,"cities":[],"countries":["Sweden"],"color":"#008C45","darkerColor":"#006B35","textColor":"#FFFFFF","shortForms":["V\xe4rmlandstrafik"],"summary":"V\xe4rmlandstrafik operates regional rail services in V\xe4rmland county in western Sweden.","history":"V\xe4rmlandstrafik is the regional public transport authority for V\xe4rmland County in western Sweden. The authority coordinates bus and rail services across the region, including trains connecting Karlstad with surrounding towns and onward connections toward Oslo, Norway and Gothenburg. The Fryksdalsbanan and other rail lines provide important regional connectivity in an area where distances between population centers can be significant.","stats":[{"label":"Routes","value":"4"},{"label":"Region","value":"V\xe4rmland"}],"websiteUrl":"https://www.varmlandstrafik.se","gtfsEnabled":true,"map":{"lat":59.4,"lng":13.5,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"J\xf6nk\xf6pings L\xe4nstrafik","slug":"jlt","metric":true,"cities":["jonkoping"],"countries":["Sweden"],"color":"#E30613","darkerColor":"#B5050F","textColor":"#FFFFFF","shortForms":["JLT"],"summary":"J\xf6nk\xf6pings L\xe4nstrafik operates regional rail services in J\xf6nk\xf6ping county in southern Sweden.","history":"J\xf6nk\xf6pings L\xe4nstrafik (JLT) is the regional public transport authority for J\xf6nk\xf6ping County in southern Sweden. The authority manages the Kr\xf6sat\xe5gen regional rail services connecting J\xf6nk\xf6ping, N\xe4ssj\xf6, V\xe4rnamo, and other towns in the Sm\xe5land region. These trains provide vital regional connections and links to the national rail network. JLT has invested in modernizing services and increasing frequency on its rail routes to meet growing demand in the region.","stats":[{"label":"Rail Routes","value":"6"},{"label":"Region","value":"J\xf6nk\xf6ping/Sm\xe5land"}],"websiteUrl":"https://www.jlt.se","gtfsEnabled":true,"map":{"lat":57.8,"lng":14.2,"zoom":9},"vehicleClassificationOverride":"regional_rail"},{"name":"X-Trafik","slug":"xtrafik","metric":true,"cities":[],"countries":["Sweden"],"color":"#0072BC","darkerColor":"#005A96","textColor":"#FFFFFF","shortForms":["X-Trafik"],"summary":"X-Trafik operates regional rail services in G\xe4vleborg county in central-eastern Sweden.","history":"X-Trafik is the regional public transport authority for G\xe4vleborg County in central-eastern Sweden. The authority operates the X-t\xe5g regional rail services connecting G\xe4vle, Sandviken, and other towns in the region. These services provide connections to the national rail network, including links toward Stockholm to the south and Sundsvall to the north along the Norrland coast. X-Trafik has worked to maintain and improve rail connectivity in a region that historically relied heavily on rail transport for its iron and timber industries.","stats":[{"label":"Rail Routes","value":"2"},{"label":"Region","value":"G\xe4vleborg"}],"websiteUrl":"https://www.xtrafik.se","gtfsEnabled":true,"map":{"lat":60.7,"lng":17.1,"zoom":9},"vehicleClassificationOverride":"regional_rail"},{"name":"Santiago Metro & EFE","slug":"santiago","metric":true,"cities":["santiago"],"color":"#E4002B","darkerColor":"#B8001F","textColor":"#FFFFFF","shortForms":["Metro Santiago","Metro","EFE","Tren Nos","Tren Rancagua"],"summary":"Santiago Metro and EFE suburban trains to Nos and Rancagua, using official DTPM schedules. Train positions are schedule estimates.","history":"Metro de Santiago opened in 1975 with Line 1, becoming the second metro system in South America after Buenos Aires. The network has expanded significantly over the decades, with Line 2 opening in 1978, Line 5 in 1997, and Line 4 in 2005. Line 6 opened in 2017 and Line 3 in 2019, making it one of the most modern metro systems in the region. The system also integrates with EFE commuter rail services (Tren Nos and Tren Rancagua) connecting Santiago to surrounding areas. The metro carries over 2 million passengers daily and is a key part of Santiago\'s integrated public transit network.","stats":[{"label":"Metro Lines","value":"7"},{"label":"EFE Routes","value":"2"}
16],"websiteUrl":"https://www.metro.cl","map":{"lat":-33.4489,"lng":-70.6693,"zoom":11},"countries":["Chile"],"tripPlannerEnabled":false},{"name":"SNCF","slug":"sncf","metric":true,"cities":["paris"],"countries":["France"],"color":"#0C1E8A","darkerColor":"#091560","textColor":"#FFFFFF","shortForms":["SNCF","TGV","TER","Intercit\xe9s"],"summary":"SNCF operates France\'s national rail network, including high-speed TGV InOui and OUIGO services, Intercit\xe9s long-distance trains, and TER regional rail across the country.","history":"The Soci\xe9t\xe9 nationale des chemins de fer fran\xe7ais (SNCF) was created in 1938 as a nationalised railway company. France pioneered European high-speed rail with the TGV, which entered service between Paris and Lyon on 27 September 1981, reaching 260 km/h in commercial operation. The network expanded rapidly through the 1990s and 2000s with new lignes \xe0 grande vitesse (LGV) radiating from Paris to Marseille, Bordeaux, Strasbourg, and beyond. On 3 April 2007, a modified TGV set the current world speed record for conventional rail at 574.8 km/h. Today SNCF operates over 30,000 km of track, with TGV InOui and low-cost OUIGO serving major cities at up to 320 km/h, Intercit\xe9s providing long-distance conventional services, and TER networks covering regional connections across all of mainland France.","stats":[{"label":"Year Founded","value":"1938"},{"label":"Top Speed (km/h)","value":"320"},{"label":"Track (km)","value":"30,000+"},{"label":"Daily Trains","value":"15,000+"}],"websiteUrl":"https://www.sncf.com","gtfsEnabled":true,"map":{"lat":46.6,"lng":2.5,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"Renfe","slug":"renfe","metric":true,"cities":["madrid","barcelona"],"countries":["Spain"],"color":"#6b2a7d","darkerColor":"#4a1d57","textColor":"#FFFFFF","shortForms":["Renfe","Renfe Operadora"],"summary":"Renfe is the national railway operator of Spain, providing high-speed AVE, long-distance, and regional rail services across the country.","history":"Renfe (Red Nacional de los Ferrocarriles Espa\xf1oles) was established in 1941 following the nationalization of Spain\'s broad-gauge railways. It has since evolved into one of Europe\'s leading rail operators, notably launching the high-speed AVE service between Madrid and Seville in 1992 for Expo \'92. Spain now has the second-largest high-speed rail network in the world after China, with AVE trains reaching speeds of 310 km/h. In 2005, Renfe was restructured, separating train operations (Renfe Operadora) from infrastructure management (Adif).","stats":[{"label":"Route Kilometers","value":"15,000+"},{"label":"Annual Ridership","value":"500m+"},{"label":"Year Founded","value":"1941"},{"label":"Top Speed (km/h)","value":"310"}
16],"websiteUrl":"https://www.renfe.com","gtfsEnabled":true,"map":{"lat":40.4168,"lng":-3.7038,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"DB Fernverkehr","slug":"db","metric":true,"cities":["berlin","munich"],"countries":["Germany"],"color":"#ec0016","darkerColor":"#b80012","textColor":"#FFFFFF","shortForms":["DB","ICE","Deutsche Bahn"],"summary":"DB Fernverkehr operates Germany\'s long-distance rail network, including ICE high-speed trains reaching 300 km/h and IC/EC intercity services connecting major cities.","history":"Deutsche Bahn was formed in 1994 from the merger of the former West German Deutsche Bundesbahn and East German Deutsche Reichsbahn following German reunification. The ICE (Intercity-Express) high-speed network launched in 1991, and today DB Fernverkehr is one of Europe\'s largest long-distance rail operators, running ICE, IC, and EC services across Germany and into neighboring countries.","stats":[{"label":"Route Kilometers","value":"33,300+"},{"label":"Annual Ridership","value":"150m+"},{"label":"Year Founded","value":"1994"},{"label":"Top Speed (km/h)","value":"300"}],"websiteUrl":"https://www.bahn.de","gtfsEnabled":true,"map":{"lat":51.1657,"lng":10.4515,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"DB Regio","slug":"db-regio","metric":true,"cities":[],"countries":["Germany"],"color":"#1a5ba5","darkerColor":"#0e3f73","textColor":"#FFFFFF","shortForms":["DB Regio","RE","RB"],"summary":"DB Regio operates regional and commuter rail services across Germany, running RE (Regional-Express) and RB (Regionalbahn) trains connecting cities and towns nationwide.","history":"DB Regio AG is a subsidiary of Deutsche Bahn responsible for regional passenger rail services across Germany. It is the largest regional rail operator in the country, serving millions of commuters daily with RE and RB services. DB Regio also operates several S-Bahn networks and RegioNetz subsidiary lines in more rural areas.","stats":[{"label":"Route Kilometers","value":"27,000+"},{"label":"Annual Ridership","value":"1.7b+"},{"label":"Year Founded","value":"1999"},{"label":"Trains Daily","value":"24,000+"}],"websiteUrl":"https://www.dbregio.de","gtfsEnabled":true,"map":{"lat":51.1657,"lng":10.4515,"zoom":6},"vehicleClassificationOverride":"regional_rail"},{"name":"S-Bahn Berlin","slug":"sbahn-berlin","metric":true,"cities":["berlin"],"countries":["Germany"],"color":"#006F35","darkerColor":"#004d25","textColor":"#FFFFFF","shortForms":["S-Bahn Berlin"],"summary":"S-Bahn Berlin is the suburban railway system serving Berlin and surrounding Brandenburg, with 16 lines and over 170 stations.","history":"The Berlin S-Bahn has operated since 1924, making it one of the oldest electric suburban rail systems in the world. Divided during the Cold War between East and West Berlin operators, it was reunified after 1989. Today it is o
16perated by S-Bahn Berlin GmbH, a subsidiary of Deutsche Bahn, carrying over 400 million passengers annually across a network of 340 km.","stats":[{"label":"Route Kilometers","value":"340"},{"label":"Lines","value":"16"},{"label":"Stations","value":"170+"},{"label":"Year Founded","value":"1924"}],"websiteUrl":"https://sbahn.berlin","gtfsEnabled":true,"map":{"lat":52.52,"lng":13.405,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"S-Bahn Hamburg","slug":"sbahn-hamburg","metric":true,"cities":[],"countries":["Germany"],"color":"#009CDB","darkerColor":"#0073a3","textColor":"#FFFFFF","shortForms":["S-Bahn Hamburg"],"summary":"S-Bahn Hamburg is the suburban railway system serving Hamburg and its metropolitan region, with 6 lines and 68 stations.","history":"The Hamburg S-Bahn began operations in 1907 and has grown into a key part of the city\'s transit system. Operated by S-Bahn Hamburg GmbH, a Deutsche Bahn subsidiary, it serves over 270 million passengers per year across 147 km of track.","stats":[{"label":"Route Kilometers","value":"147"},{"label":"Lines","value":"6"},{"label":"Stations","value":"68"},{"label":"Year Founded","value":"1907"}],"websiteUrl":"https://www.s-bahn-hamburg.de","gtfsEnabled":true,"map":{"lat":53.5511,"lng":9.9937,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"S-Bahn M\xfcnchen","slug":"sbahn-munich","metric":true,"cities":["munich"],"countries":["Germany"],"color":"#00a6e2","darkerColor":"#007db3","textColor":"#FFFFFF","shortForms":["S-Bahn M\xfcnchen","S-Bahn Munich"],"summary":"S-Bahn M\xfcnchen is the suburban railway system serving Munich and its metropolitan region, with 8 lines and 150 stations.","history":"The Munich S-Bahn was inaugurated in 1972 for the Summer Olympics and has since become the backbone of Munich\'s public transport. Operated by DB Regio Bayern, it serves over 240 million passengers annually across 442 km of track, connecting the city center with surrounding suburbs and Munich Airport.","stats":[{"label":"Route Kilometers","value":"442"},{"label":"Lines","value":"8"},{"label":"Stations","value":"150"},{"label":"Year Founded","value":"1972"}],"websiteUrl":"https://www.s-bahn-muenchen.de","gtfsEnabled":true,"map":{"lat":48.1351,"lng":11.582,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"FlixTrain","slug":"flixtrain","metric":true,"cities":[],"countries":["Germany"],"color":"#73D700","darkerColor":"#5aab00","textColor":"#000000","shortForms":["FlixTrain","Flixtrain"],"summary":"FlixTrain is a private long-distance rail operator in Germany, offering low-cost intercity train services as an alternative to Deutsche Bahn.","history":"FlixTrain launched in 2018 as a rail extension of the FlixBus brand, operated by FlixMobility GmbH. It became the first private open-access long-distance rail operator to compete directly with Deutsche Bahn on major German routes. FlixTrain has since expanded to routes in Swede
16n and Austria, offering budget-friendly intercity travel.","stats":[{"label":"Year Founded","value":"2018"},{"label":"Routes","value":"10+"},{"label":"Cities Served","value":"40+"},{"label":"Countries","value":"3"}],"websiteUrl":"https://www.flixtrain.de","gtfsEnabled":true,"map":{"lat":51.1657,"lng":10.4515,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"S-Bahn Rhein-Main","slug":"sbahn-rhein-main","metric":true,"cities":[],"countries":["Germany"],"color":"#0065ae","darkerColor":"#004a80","textColor":"#FFFFFF","shortForms":["S-Bahn Rhein-Main","S-Bahn Frankfurt"],"summary":"S-Bahn Rhein-Main is the suburban railway system serving the Frankfurt/Rhine-Main metropolitan area, with 9 lines and 113 stations.","history":"The Rhine-Main S-Bahn launched in 1978 and has grown into one of Germany\'s busiest suburban rail systems, connecting Frankfurt with cities like Wiesbaden, Mainz, Darmstadt, Offenbach, and Hanau. Operated by DB Regio, it carries over 400,000 passengers daily across a network centered on the Frankfurt city tunnel.","stats":[{"label":"Route Kilometers","value":"303"},{"label":"Lines","value":"9"},{"label":"Stations","value":"113"},{"label":"Year Founded","value":"1978"}],"websiteUrl":"https://www.rmv.de","gtfsEnabled":true,"map":{"lat":50.1109,"lng":8.6821,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"metronom","slug":"metronom","metric":true,"cities":[],"countries":["Germany"],"color":"#e30613","darkerColor":"#b3050f","textColor":"#FFFFFF","shortForms":["metronom"],"summary":"metronom is a regional rail operator in Lower Saxony and Hamburg, running RE and RB services between Hamburg, Bremen, Hanover, G\xf6ttingen, and Uelzen.","history":"metronom Eisenbahngesellschaft mbH began operations in 2003, taking over regional rail routes from Deutsche Bahn in Lower Saxony. It operates distinctive red-and-white trains on some of northern Germany\'s busiest regional corridors, serving millions of commuters between Hamburg and the surrounding region.","stats":[{"label":"Route Kilometers","value":"480+"},{"label":"Annual Ridership","value":"42m+"},{"label":"Year Founded","value":"2003"},{"label":"Routes","value":"5"}],"websiteUrl":"https://www.der-metronom.de","gtfsEnabled":true,"map":{"lat":53,"lng":10,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"German Rail","slug":"german-rail","metric":true,"cities":[],"countries":["Germany"],"color":"#333333","darkerColor":"#1a1a1a","textColor":"#FFFFFF","shortForms":["German Rail","DE Rail"],"summary":"All rail services across Germany â every train operator including Deutsche Bahn, private railways, S-Bahn, and regional operators.","history":"Germany has one of the largest and most complex rail networks in Europe, with over 33,000 km of track operated by hundreds of companies. Since the 1994 rail reform, the market has gradually opened to competition, and today dozens of private operators run regional services alongside Deutsche Bahn. This network combines all German rail operators into a single unified view.","stats":[{"label":"Route Kilometers","value":"33,300+"},{"label":"Operators","value":"200+"},{"label":"Daily Trains","value":"40,000+"},{"label":"Stations","value":"5,700+"}],"websiteUrl":"https://www.bahn.de","gtfsEnabled":true,"map":{"lat":51.1657,"lng":10.4515,"zoom":6},"vehicleClassificationOverride":"rail"},{"name":"Renfe Cercan\xedas","slug":"renfe-cercanias","metric":true,"cities":["madrid","barcelona"],"countries":["Spain"],"color":"#e63027","darkerColor":"#b8221b","textColor":"#FFFFFF","shortForms":["Cercan\xedas","Rodalies"],"summary":"Renfe Cercan\xedas is Spain\'s commuter rail network, operating suburban train services in major metropolitan areas including Madrid, Barcelona, Valencia, Seville, and M\xe1laga.","history":"Cercan\xedas services began in 1989 as Renfe restructured its suburban operations to provide dedicated commuter rail. The network has grown to serve 12 metropolitan areas across Spain, known as Rodalies in Catalonia. It forms the backbone of daily commuting in Spanish cities, with the Madrid Cercan\xedas network being the largest, serving over 300 million passengers annually. The system integrates with metro and bus networks through shared stations and fare systems.","stats":[{"label":"Metropolitan Areas","value":"12"},{"label":"Annual Ridership","value":"400m+"},{"label":"Year Founded","value":"1989"},{"label":"Stations","value":"900+"}],"websiteUrl":"https://www.renfe.com/es/es/cercanias","gtfsEnabled":true,"map":{"lat":40.4168,"lng":-3.7038,"zoom":6},"vehicleClassificationOverride":"commuter_rail"},{"name":"Trenes Argentinos","slug":"trenes-argentinos","metric":true,"cities":["buenos-aires"],"countries":["Argentina"],"color":"#0072CE","darkerColor":"#004B8D","textColor":"#FFFFFF","shortForms":["Trenes Argentinos","SOFSE"],"summary":"Trenes Argentinos is the commuter rail network serving the Buenos Aires metropolitan area, operating seven lines that connect the city center with its suburbs.","history":"Buenos Aires\' commuter rail network dates back to the late 19th century, when British-owned companies built an extensive railway system radiating from the capital. After nationalization in 1948 under President Per\xf3n, the lines were grouped under Ferrocarriles Argentinos. Following privatization in the 1990s, various concessionaires operated the lines with mixed results. After the tragic Once station crash in 2012 that killed 51 people, the government created Trenes Argentinos Operadora Ferroviaria (SOFSE) to gradually take back operations. Today, SOFSE operates all seven metropolitan lines â Mitre, Sarmiento, Roca, San Mart\xedn, Belgrano Sur, Belgrano Norte, and Urquiza â carrying over 300 million passengers annually and undergoing significant modernization with new rolling stock and electrification projects.","stats":[{"label":"Lines","value":"7"},{"label":"Stations","value":"260+"},{"label":"Annual Ridership","value":"300m+"},{"label":"Year Nationalized","value":"1948"}],"websiteUrl":"https://www.argentina.gob.ar/transporte/trenes-argentinos","gtfsEnabled":true,"map":{"lat":-34.6037,"lng":-58.3816,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Buenos Aires Subte","slug":"subte","metric":true,"cities":["buenos-aires"],"countries":["Argentina"],"color":"#00A3E0","darkerColor":"#007BB5","textColor":"#FFFFFF","shortForms":["Subte","SBASE"],"summary":"The Buenos Aires Subte is the oldest metro system in Latin America and the Southern Hemisphere, serving the Argentine capital with six lines and a premetro light rail.","history":"The Subterr\xe1neo de Buenos Aires, universally known as the Subte, opened on December 1, 1913, making it the first underground railway in Latin America and the entire Southern Hemisphere. Line A originally ran between Plaza de Mayo and Plaza Miserere using wooden La Brugeoise cars that remained in service until 2013 â a century of continuous operation. The network expanded through the mid-20th century with Lines B through E, but growth stalled for decades due to economic instability. Line H, the first new line in over 60 years, began service in 2007 and continues to be extended. The Premetro (Line E2), a light rail line in the southern suburbs, has operated since 1987. Operated by Emova (formerly Metrov\xedas) under concession from Subterr\xe1neos de Buenos Aires Sociedad del Estado (SBASE), the system carries approximately 3
1600 million passengers per year across 90 stations.","stats":[{"label":"Year Founded","value":"1913"},{"label":"System Km","value":"56"},{"label":"Stations","value":"90"},{"label":"Lines","value":"6 + Premetro"}],"websiteUrl":"https://www.buenosaires.gob.ar/subte","gtfsEnabled":true,"map":{"lat":-34.6083,"lng":-58.3712,"zoom":12},"vehicleClassificationOverride":"subway"},{"name":"Indian Railways Premium","slug":"ir-premium","metric":true,"cities":["new-delhi","mumbai"],"countries":["India"],"color":"#e23744","darkerColor":"#b82d37","textColor":"#FFFFFF","shortForms":["IR Premium","Rajdhani","Shatabdi"],"summary":"India\'s premium long-distance rail services, including Rajdhani Express (connecting state capitals to Delhi), Shatabdi Express (daytime intercity), Duronto Express (non-stop), and Garib Rath (budget AC).","history":"Indian Railways, one of the world\'s largest rail networks, was established in 1853 with the first line between Bombay and Thane. The Rajdhani Express launched in 1969 connecting Delhi to Howrah, followed by Shatabdi Express in 1988 for fast daytime travel. Today, Indian Railways operates over 13,000 trains daily across 68,000+ route kilometres, serving 8 billion passengers annually. Premium services like Rajdhani, Shatabdi, Duronto, and the newer Vande Bharat Express represent the fastest and most prestigious trains in the network.","stats":[{"label":"Route Kilometres","value":"68,000+"},{"label":"Daily Trains","value":"13,000+"},{"label":"Year Founded","value":"1853"},{"label":"Top Speed (km/h)","value":"160"}],"websiteUrl":"https://www.indianrailways.gov.in","gtfsEnabled":true,"map":{"lat":22.5,"lng":79.5,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"Indian Railways Express","slug":"ir-express","metric":true,"cities":["new-delhi","mumbai"],"countries":["India"],"color":"#1a73e8","darkerColor":"#1557b0","textColor":"#FFFFFF","shortForms":["IR Express","Superfast"],"summary":"Express, Superfast, and Mail services forming the backbone of India\'s long-distance rail network, connecting thousands of cities and towns across the subcontinent.","history":"Express and Mail trains have been the workhorses of Indian Railways since the colonial era. The Mail trains, originally designed to carry mail between major cities, evolved into important passenger services. Superfast trains, introduced in the 1970s with a surcharge for higher speeds (above 100 km/h average), now form a large portion of long-distance services. Together, these ~2,000 trains connect virtually every major town in India.","stats":[{"label":"Express Trains","value":"1,200+"},{"label":"Superfast Trains","value":"700+"},{"label":"Year Founded","value":"1853"},{"label":"Countries","value":"India"}],"websiteUrl":"https://www.indianrailways.gov.in","gtfsEnabled":true,"map":{"lat":22.5,"lng":79.5,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"Indian Rail","slug":"indian-rail","metric":true,"cities":["new-delhi","mumbai"],"countries":["India"],"color":"#333333","darkerColor":"#222222","textColor":"#FFFFFF","shortForms":["IR","Indian Rail"],"summary":"All remaining Indian rail services â passenger, MEMU, DEMU, suburban, and heritage trains not covered by the dedicated premium or express networks.","history":"India\'s passenger, suburban, and local rail services carry the vast majority of the country\'s rail passengers. Mumbai\'s suburban railway alone handles over 7.5 million commuters daily. The MEMU (Mainline Electric Multiple Unit) and DEMU (Diesel Electric Multiple Unit) services provide affordable short-distance connectivity across rural and semi-urban India. Heritage toy trains like the Darjeeling Himalayan Railway and Nilgiri Mountain Railway are UNESCO World Heritage Sites.","stats":[{"label":"Passenger Trains","value":"2,400+"},{"label":"MEMU/DEMU","value":"300+"},{"label":"Year Founded","value":"1853"},{"label":"Countries","value":"India"}],"websiteUrl":"https://www.indianrailways.gov.in","gtfsEnabled":true,"map":{"lat":22.5,"lng":79.5,"zoom":5},"vehicleClassificationOverride":"regional_rail"},{"name":"Cairo Metro","slug":"cairo-metro","metric":true,"cities":["cairo"],"countries":["Egypt"],"color":"#E60012","darkerColor":"#A8000D","textColor":"#FFFFFF","shortForms":["Cairo Metro","Metro AnfÄq"],"summary":"Cairo Metro is the first metro system in Africa and the Middle East, serving Greater Cairo with three lines connecting the Egyptian capital.","history":"Cairo Metro opened on September 27, 1987, becoming the first metro system on the African continent and in the Middle East. Line 1 (Red) originally ran between Helwan and Ramses Square, developed with French and Soviet engineering support, and today extends 44 km between Helwan and New El Marg. Line 2 (Blue) o
16pened in 1996 between Shubra El Kheima and El Mounib, partially using Egyptian-built rolling stock. Line 3 (Green) opened in 2012 and has been expanded incrementally through May 2024, now running from Adly Mansour to Rod El Farag Corridor and crossing the Nile to serve Zamalek and Cairo University. The system carries roughly 3 to 4 million passengers per day across 84 stations and 106.8 km of track. Owned by the National Authority for Tunnels under Egypt\'s Ministry of Transport, Line 3 is operated under a 15-year concession by RATP Dev Mobility Cairo. Line 4, a fourth line linking Haram District to New Cairo, began construction in 2024.","stats":[{"label":"Year Founded","value":"1987"},{"label":"System Km","value":"106.8"},{"label":"Stations","value":"84"},{"label":"Lines","value":"3"}],"websiteUrl":"https://cairometro.gov.eg","gtfsEnabled":true,"map":{"lat":30.0444,"lng":31.2357,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"VBB","slug":"vbb","metric":true,"cities":["berlin"],"countries":["Germany"],"color":"#FDC300","darkerColor":"#C99B00","textColor":"#000000","shortForms":["VBB","Verkehrsverbund Berlin-Brandenburg"],"summary":"VBB (Verkehrsverbund Berlin-Brandenburg) is the regional transport authority coordinating rail, S-Bahn, U-Bahn, tram, and bus services across Berlin and the surrounding state of Brandenburg.","history":"VBB was established in 1996 to unify public transport planning and ticketing across Berlin and Brandenburg after German reunification. It coordinates over 40 operators across roughly 30,000 km\xb2 â one of the largest transport associations in Europe by area â with a single integrated fare system covering regional trains, the Berlin S-Bahn and U-Bahn, trams, and buses.","stats":[{"label":"Year Founded","value":"1996"},{"label":"Area km\xb2","value":"30,000"},{"label":"Operators","value":"40+"}],"websiteUrl":"https://www.vbb.de","gtfsEnabled":true,"map":{"lat":52.52,"lng":13.405,"zoom":9},"vehicleClassificationOverride":"regional_rail"},{"name":"Greater Cleveland Regional Transit Authority","slug":"gcrta","metric":false,"cities":["cleveland"],"color":"#C41230","darkerColor":"#8C0E23","textColor":"#FFFFFF","shortForms":["GCRTA","RTA"],"summary":"The Greater Cleveland Regional Transit Authority (GCRTA) operates rapid transit rail service in Cleveland, Ohio, combining the heavy rail Red Line with the light rail Blue, Green, and Waterfront Lines.","history":"GCRTA was established on December 30, 1974, assuming control of the Cleveland Transit System on September 5, 1975. Its predecessor system opened the Red Line in 1955, the first rapid transit line in the western hemisphere to connect a city\'s downtown directly to its major airport. The Blue and Green Lines trace back to a 1913 interurban route to Shaker Heights, later rebuilt and folded into the rapid transit network by 1981, with the Waterfront Line added in 1996 to serve North Coast Harbor and the Gateway Sports and Entertainment Complex. All four lines converge at Tower City Center in downtown Cleveland.","stats":[{"label":"Year Founded","value":"1975"},{"label":"Lines","value":"4"},{"label":"Rail Vehicles","value":"92"},{"label":"Annual Ridership","value":"24.5m"}],"websiteUrl":"https://www.riderta.com","map":{"lat":41.4993,"lng":-81.6944,"zoom":11},"vehicleClassificationOverride":"subway_default"},{"name":"Flytoget (Airport Express Train)","slug":"flytoget","metric":true,"cities":["oslo"],"color":"#E2001A","darkerColor":"#A10012","textColor":"#FFFFFF","shortForms":["Flytoget","Airport Express"],"summary":"Flytoget is the high-speed Airport Express Train connecting Oslo Airport Gardermoen to Oslo Central Station, with some services extending to Drammen.","history":"Construction on the dedicated Gardermoen Line began in 1994, and Flytoget started high-speed service alongside the airport\'s opening on October 8, 1998, reaching full capacity through the Romerike Tunnel in 1999. The line covers roughly 48 kilometers between Oslo S and Gardermoen, with the journey taking as little as 19 minutes at speeds up to 210 km/h. Some services extend west to Drammen via Lysaker and Sandvika, and the fleet is made up of GMB Class 71 electric trains built specifically for the route.","stats":[{"label":"Year Founded","value":"1998"},{"label":"Route Length (km)","value":"48"},{"label":"Top Speed (km/h)","value":"210"},{"label":"Journey Time","value":"19 min"}],"websiteUrl":"https://flytoget.no","map":{"lat":60.1939,"lng":11.1004,"zoom":9},"vehicleClassificationOverride":"regional_rail"},{"name":"Gr\xe5kallbanen","slug":"graakallbanen","metric":true,"cities":["trondheim"],"color":"#2E7D32","dar
16kerColor":"#1B5E20","textColor":"#FFFFFF","shortForms":["Gr\xe5kallbanen","Trondheim Tram"],"summary":"Gr\xe5kallbanen is Trondheim\'s tram line, running from St. Olav\'s Gate through By\xe5sen to Lian â the only tram system in Norway outside Oslo.","history":"A/S Graakalbanen was founded in 1916 to build a tramway from central Trondheim toward the Gr\xe5kallen mountain, with the first stretch from St. Olav\'s Gate to Munkvoll opening on July 18, 1924. The line was extended to Ugla in 1925 and reached its current terminus at Lian in 1933. It was the city\'s only surviving tram line after Trondheim closed the rest of its tramway network in 1988, saved by a political deal that established a dedicated operating company. Today it runs as Line 9, served by Class 8 articulated trams under AtB\'s regional transit network.","stats":[{"label":"Year Opened","value":"1924"},{"label":"Route Length (km)","value":"8.8"},{"label":"Line","value":"9"}],"websiteUrl":"https://www.atb.no","map":{"lat":63.408,"lng":10.385,"zoom":12},"vehicleClassificationOverride":"tram"},{"name":"Zagreb Trams","slug":"zagreb","metric":true,"cities":["zagreb"],"color":"#0057A8","darkerColor":"#003D75","textColor":"#FFFFFF","shortForms":["ZET"],"summary":"Zagreb\'s tram network, operated by ZagrebaÄki elektriÄni tramvaj (ZET), is one of the largest and busiest metre-gauge tram systems in Europe.","history":"Zagreb\'s first horse-drawn tram line opened in 1891, with the network electrified in 1910. Today ZET operates 15 daytime and 4 nighttime tram lines over roughly 116 km of metre-gauge track, alongside the city\'s bus network, making trams the backbone of public transport in the Croatian capital.","stats":[{"label":"Operator","value":"ZagrebaÄki elektriÄni tramvaj (ZET)"},{"label":"Tram Routes","value":"18"}],"websiteUrl":"https://www.zet.hr/","map":{"lat":45.815,"lng":15.9819,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"HŽPP","slug":"hzpp","metric":true,"cities":[],"countries":["Croatia"],"color":"#003DA5","darkerColor":"#002E7A","textColor":"#FFFFFF","shortForms":["HŽPP","HZPP"],"summary":"HŽ PutniÄki prijevoz (HŽPP) is Croatia\'s national passenger rail operator, running intercity, regional, and suburban trains across the country\'s rail network.","history":"HŽPP was established on 20 July 2006 when it split from Croatian Railways (Hrvatske željeznice), separating passenger operations from infrastructure management in line with EU directive 91/440 ahead of Croatia\'s EU accession. It now operates over the roughly 2,600km network maintained by HŽ Infrastruktura, connecting Zagreb with the country\'s other major cities and international destinations.","stats":[{"label":"Year Founded","value":"2006"},{"label":"Route Kilometers","value":"~2,600"}],"websiteUrl":"https://www.hzpp.hr/en","gtfsEnabled":true,"map":{"lat":45.1,"lng":15.5,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Paris M\xe9tro & Tram","slug":"idfm","metric":true,"cities":["paris"],"countries":["France"],"color":"#FFCD00","darkerColor":"#CBA300","textColor":"#000000","shortForms":["IDFM","M\xe9tro"],"summary":"\xcele-de-France Mobilit\xe9s (PRIM) coverage of the Paris M\xe9tro and tramway, with estimated train positions based on published timetables and live PRIM service disruption alerts. RER and Transilien are covered separately by the transilien network.","websiteUrl":"https://www.iledefrance-mobilites.fr/","gtfsEnabled":true,"map":{"lat":48.8566,"lng":2.3522,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"IaÈi Trams","slug":"iasi","metric":true,"cities":["iasi"],"color":"#00A650","darkerColor":"#00793C","textColor":"#FFFFFF","shortForms":["CTP IaÈi"],"summary":"IaÈi\'s tram network, operated by CTP IaÈi (Compania de Transport Public IaÈi), is one of Romania\'s oldest and remains the backbone of transit in the country\'s second-largest metropolitan area.","history":"Electric trams began running in IaÈi in 1900, after King Carol I granted the tramway concession to the German company AEG in 1898. Today the network is operated by CTP IaÈi (known as RATP IaÈi until 2016), running 9 tram routes alongside an extensive bus and trolleybus network across the city.","stats":[{"label":"Operator","value":"CTP IaÈi"},{"label":"Tram Routes","value":"9"}],"websiteUrl":"https://www.sctpiasi.ro/","map":{"lat":47.1585,"lng":27.6014,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"Szczecin Trams","slug":"szczecin","metric":true,"cities":["szczecin"],"color":"#EE7F00","darkerColor":"#B96200","textColor":"#FFFFFF","shortForms":["ZDiTM"],"summary":"Szczecin\'s tram network, operated by ZDiTM (ZarzÄ
d Dr\xf3g i Transportu Miejskiego), is one of Poland\'s largest and forms the backbone of public transit in the country\'s seventh-largest city.","history":"Trams have run in Szczecin since 1879, initially horse-drawn and electrified by 1896. Today the network is managed by ZDiTM, the city\'s transport authority, with 13 tram routes running alongside an extensive bus network across the city and its suburbs.","stats":[{"label":"Operator","value":"ZDiTM Szczecin"},{"label":"Tram Routes","value":"13"}],"websiteUrl":"https://www.zditm.szczecin.pl/","map":{"lat":53.4285,"lng":14.5528,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"Silesian Interurban Trams","slug":"silesia","metric":true,"cities":["katowice"],"color":"#004B87","darkerColor":"#00335C","textColor":"#FFFFFF","shortForms":["Tramwaje ÅlÄ
skie"],"summary":"One of Europe\'s largest tram networks, the Silesian Interurbans link Katowice with the surrounding cities of the Upper Silesian-ZagÅÄbie Metropolis (GZM), operated by Tramwaje ÅlÄ
skie.","history":"Trams have connected the industrial
16cities of Upper Silesia since 1894, growing into a dense interurban network unique in Poland for linking entire cities together rather than serving a single municipality. Today Tramwaje ÅlÄ
skie operates the network under the umbrella of ZTM/GZM, the metropolitan transport authority coordinating public transit across the region\'s 41 municipalities.","stats":[{"label":"Operator","value":"Tramwaje ÅlÄ
skie"},{"label":"Tram Routes","value":"29"}],"websiteUrl":"https://www.tram-silesia.pl/","map":{"lat":50.2649,"lng":19.0238,"zoom":11},"vehicleClassificationOverride":"streetcar"},{"name":"Lviv Trams","slug":"lviv","metric":true,"cities":["lviv"],"color":"#004990","darkerColor":"#00305F","textColor":"#FFFFFF","shortForms":["ÐÑвÑвелекÑÑоÑÑанÑ","Lvivelectrotrans"],"summary":"Lviv\'s tram network, operated by the municipal enterprise Lvivelectrotrans, was the first tram system in Ukraine and remains a defining part of the historic city\'s transit.","history":"Lviv\'s first horse-drawn tram opened on May 3, 1880 â the first tram in Ukraine â with electric traction introduced in 1894 and full electrification completed by 1908. Today the network is run by the municipal enterprise Lvivelectrotrans, which holds a monopoly on trams and trolleybuses in the city, operating 8 tram routes alongside an extensive trolleybus network.","stats":[{"label":"Operator","value":"Lvivelectrotrans"},{"label":"Tram Routes","value":"8"}],"websiteUrl":"http://lvivelectrotrans.com.ua/","map":{"lat":49.8397,"lng":24.0297,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"Greece National Rail","slug":"hellenictrain","metric":true,"cities":[],"countries":["Greece"],"color":"#005BAC","darkerColor":"#003D73","textColor":"#FFFFFF","shortForms":["Hellenic Train","TrainOSE"],"summary":"Greece\'s national passenger rail operator, running intercity, suburban, and international services across the country\'s core network including the Athens-Thessaloniki main line.","history":"Originally state-run as TrainOSE, Greece\'s national rail operator was privatized and acquired by Italy\'s Ferrovie dello Stato Italiane group in 2017, rebranding as Hellenic Train in 2022. The network spans roughly 2,300 route kilometres connecting Athens, Thessaloniki, and other major cities. Following the fatal Tempi rail disaster near Larissa in February 2023, the Greek government fast-tracked a nationwide satellite-based train tracking system, railway.gov.gr, which launched in 2026.","stats":[{"label":"Route Km","value":"2,293"},{"label":"Operator","value":"Hellenic Train"},{"label":"Fleet","value":"1,160+"},{"label":"Rebranded","value":"2022"}],"websiteUrl":"https://www.hellenictrain.gr/en","gtfsEnabled":true,"map":{"lat":39,"lng":22.5,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"Israel Railways","slug":"israel-railways","metric":true,"cities":[],"countries":["Israel"],"color":"#0060A9","darkerColor":"#004272","textColor":"#FFFFFF","shortForms":["Rakevet Yisrael","ISR"],"summary":"Israel\'s national passenger rail operator, running intercity and commuter trains that connect cities across the country including Tel Aviv, Haifa, Jerusalem, and Be\'er Sheva.","history":"Israel Railways traces back to the Ottoman-era Jaffa-Jerusalem line of 1892, but today\'s national network was rebuilt and expanded from the 1990s onward under the state-owned Israel Railways. The system now links the coastal plain, the north, and the Negev, with a high-speed line connecting Tel Aviv and Jerusalem in under half an hour since 2018 and full electrification of the core network completed in 2023.","stats":[{"label":"Founded","value":"1949"},{"label":"Electrified","value":"2023"}],"websiteUrl":"https://www.rail.co.il","map":{"lat":31.7683,"lng":35,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Jerusalem Light Rail","slug":"jerusalem-light-rail","metric":true,"cities":["jerusalem"],"color":"#C8102E","darkerColor":"#96000F","textColor":"#FFFFFF","shortForms":["Kfir","Cfir"],"summary":"Jerusalem\'s light rail Red Line, operated by Kfir, runs through the heart of the city connecting Neve Ya\'akov in the north to Hadassah Ein Kerem in the southwest.","history":"The Red
16Line opened in August 2011 as the first light rail line in Israel, running along Jaffa Road through Jerusalem\'s city center and past the Old City. Operation was originally run by CityPass before transferring to the Kfir consortium in 2022. A second (Green/Blue) line is under construction as part of a wider expansion of the network.","stats":[{"label":"Opened","value":"2011"},{"label":"Operator","value":"Kfir"}],"websiteUrl":"https://www.cfir.co.il","map":{"lat":31.7683,"lng":35.2137,"zoom":12},"vehicleClassificationOverride":"light_rail"},{"name":"Tel Aviv Red Line","slug":"telaviv-red-line","metric":true,"cities":["tel-aviv"],"color":"#E2231A","darkerColor":"#A81810","textColor":"#FFFFFF","shortForms":["Tevel","NTA"],"summary":"The Tel Aviv Light Rail\'s Red Line, operated by Tevel, connects Petah Tikva through central Tel Aviv to Bat Yam, the first line of a planned regional light rail network.","history":"The Red Line opened to the public in August 2023, becoming the first rapid transit line in the Tel Aviv metropolitan area. Built and planned by NTA (Netivei Ayalon), the roughly 24-kilometre line runs partly underground through central Tel Aviv and above ground at both ends, connecting Petah Tikva to Bat Yam. Additional Green and Purple lines are under construction as part of the wider Tel Aviv Light Rail system.","stats":[{"label":"Opened","value":"2023"},{"label":"Operator","value":"Tevel"}],"websiteUrl":"https://www.nta.co.il","map":{"lat":32.0853,"lng":34.7818,"zoom":12},"vehicleClassificationOverride":"light_rail"},{"name":"\xd6BB","slug":"oebb","metric":true,"cities":[],"countries":["Austria"],"color":"#E2002A","darkerColor":"#A90020","textColor":"#FFFFFF","shortForms":["\xd6BB","OEBB","Austrian Federal Railways","Railjet"],"summary":"\xd6BB is Austria\'s national railway, operating Railjet, InterCity, EuroCity, Nightjet, regional, and S-Bahn services across Austria and into neighboring countries.","history":"Austria\'s federal railway was established in 1923 and re-established after the Second World War. Today \xd6BB operates the backbone of Austrian passenger rail, including Railjet intercity services, one of Europe\'s largest night-train networks, and extensive regional and cross-border connections.","stats":[{"label":"Year Founded","value":"1923"},{"label":"Top Speed (km/h)","value":"230"},{"label":"Position Source","value":"Scheduled"}],"websiteUrl":"https://www.oebb.at","gtfsEnabled":true,"map":{"lat":47.5162,"lng":14.5501,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"WESTbahn","slug":"westbahn","metric":true,"cities":[],"countries":["Austria"],"color":"#009FE3","darkerColor":"#0076A8","textColor":"#FFFFFF","shortForms":["WESTbahn","WB"],"summary":"WESTbahn is an Austrian open-access operator running frequent intercity trains on the western railway corridor.","history":"WESTbahn began passenger service in 2011, introducing private competition on Austria\'s main east-west rail corridor. Its double-deck trains connect Vienna with major cities in Upper Austria, Salzburg, Tyrol, and Vorarlberg.","stats":[{"label":"Position Source","value":"Scheduled"},{"label":"Operator","value":"WESTbahn"}],"websiteUrl":"https://westbahn.at","gtfsEnabled":true,"map":{"lat":47.8,"lng":13.6,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Raaberbahn","slug":"raaberbahn","metric":true,"cities":[],"countries":["Austria","Hungary"],"color":"#009640","darkerColor":"#006B2E","textColor":"#FFFFFF","shortForms":["Raaberbahn","GYSEV"],"summary":"Raaberbahn operates regional passenger trains in eastern Austria and western Hungary, including cross-border services.","history":"The Austro-Hungarian railway company was founded in 1872 and remains jointly connected to both countries. It operates regional routes around Burgenland and western Hungary under the Raaberbahn and GYSEV names.","stats":[{"label":"Position Source","value":"Scheduled"},{"label":"Operator","value":"Raaberbahn / GYSEV"}],"websiteUrl":"https://www.raaberbahn.at","gtfsEnabled":true,"map":{"lat":47.75,"lng":16.5,"zoom":8},"vehicleClassificationOverride":"commuter_rail"},{"name":"Montafonerbahn","slug":"montafonerbahn","metric":true,"cities":[],"countries":["Austria"],"color":"#005A9C","darkerColor":"#003F6E","textColor":"#FFFFFF","shortForms":["Montafonerbahn","MBS"],"summary":"Montafonerbahn operates regional trains between Bludenz and Schruns in Austr
16ia\'s Vorarlberg region.","history":"The Montafonerbahn opened in 1905 and links the Alpine Montafon valley with the national railway at Bludenz. It is one of Austria\'s long-established regional railway operators.","stats":[{"label":"Position Source","value":"Scheduled"},{"label":"Operator","value":"Montafonerbahn"}],"websiteUrl":"https://www.montafonerbahn.at","gtfsEnabled":true,"map":{"lat":47.1,"lng":9.9,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"City Airport Train","slug":"city-airport-train","metric":true,"cities":[],"countries":["Austria"],"color":"#8DC63F","darkerColor":"#5F8D24","textColor":"#000000","shortForms":["City Airport Train","CAT"],"summary":"City Airport Train provides nonstop rail service between Vienna International Airport and Wien Mitte station.","history":"City Airport Train began operating in 2003 as a dedicated airport express. The service connects central Vienna and the airport without intermediate stops and offers airline check-in facilities at Wien Mitte.","stats":[{"label":"Position Source","value":"Scheduled"},{"label":"Operator","value":"City Airport Train"}],"websiteUrl":"https://www.cityairporttrain.com","gtfsEnabled":true,"map":{"lat":48.16,"lng":16.48,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"SBB CFF FFS","slug":"sbb","metric":true,"cities":[],"countries":["Switzerland"],"color":"#EB0000","darkerColor":"#B30000","textColor":"#FFFFFF","shortForms":["SBB","CFF","FFS","SBB CFF FFS"],"summary":"SBB CFF FFS is Switzerland\'s national railway, operating intercity, regional, and S-Bahn services across one of the densest and most punctual rail networks in the world.","history":"SBB was founded in 1902 through the nationalization of Switzerland\'s major private railway companies, unifying the network under Swiss federal ownership. It operates alongside dozens of private and cantonal railways under the Swiss integrated timetable (Taktfahrplan), a clockface scheduling system that synchronizes connections nationwide down to the minute. SBB carries well over a million passengers daily across its fully electrified network, consistently ranked among the most punctual and frequent in the world even through mountainous terrain.","stats":[{"label":"Year Founded","value":"1902"},{"label":"Route Kilometers","value":"3,200+"},{"label":"Daily Ridership","value":"1.3m+"},{"label":"Top Speed (km/h)","value":"200"}],"websiteUrl":"https://www.sbb.ch","gtfsEnabled":true,"map":{"lat":46.8182,"lng":8.2275,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Rh\xe4tische Bahn","slug":"rhb","metric":true,"cities":[],"countries":["Switzerland"],"color":"#A6192E","darkerColor":"#7A1220","textColor":"#FFFFFF","shortForms":["RhB","Rhaetian Railway"],"summary":"Rh\xe4tische Bahn (RhB) operates Switzerland\'s largest narrow-gauge rail network across Graub\xfcnden, running the UNESCO World Heritage Albula/Bernina line and the scenic Glacier and Bernina Express routes.","history":"Founded in 1889, RhB built an extensive metre-gauge network through the Alps of Graub\xfcnden, with engineering feats like the Landwasser Viaduct and crossings of the Albula and Bernina passes. The Albula/Bernina line was inscribed as a UNESCO World Heritage Site in 2008 in recognition of its landscape integration and engineering. RhB co-operates the Glacier Express with Matterhorn Gotthard Bahn, connecting Zermatt and St. Moritz, and its own Bernina Express crosses from Chur to Tirano, Italy, over the highest adhesion-rail crossing of the Alps.","stats":[{"label":"Year Founded","value":"1889"},{"label":"Route Kilometers","value":"384"},{"label":"Gauge","value":"1,000mm"},{"label":"UNESCO Line","value":"Albula/Bernina"}],"websiteUrl":"https://www.rhb.ch","gtfsEnabled":true,"map":{"lat":46.85,"lng":9.53,"zoom":9},"vehicleClassificationOverride":"regional_rail"},{"name":"BLS","slug":"bls","metric":true,"cities":[],"countries":["Switzerland"],"color":"#0060A9","darkerColor":"#00447A","textColor":"#FFFFFF","shortForms":["BLS"],"summary":"BLS AG operates regional and S-Bahn rail services across the BernâL\xf6tschbergâSimplon corridor, connecting the Bernese Oberland with the Simplon route into Italy.","history":"BLS traces its roots to the 1913 opening of the L\xf6tschberg Tunnel, built to link Bern with the Simplon Pass route into Italy. The modern BLS AG formed in 2006 through a merger of BLS L\xf6tschbergbahn and Regionalverkehr Mittelland, and today operates regional and S-Bahn passenger services under contract to Swiss cantons alongside its original L\xf6tschberg mainline corridor.","stats":[{"label":"Year Founded","value":"1913"},{"label":"Route Kilometers","value":"430+"},{"label":"Merger","value":"2006"},{"label":"Region","value":"BernâL\xf6tschbergâSimplon"}],"websiteUrl":"https://www.bls.ch","gtfsEnabled":true,"map":{"lat":46.6,"lng":7.6,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"Matterhorn Gotthard Bahn","slug":"mgb","metric":true,"cities":[],"countries":["Switzerland"],"color":"#D2001C","darkerColor":"#960014","textColor":"#FFFFFF","shortForms":["MGB","Matterhorn Gotthard Bahn"],"summary":"Matterhorn Gotthard Bahn (MGB) operates narrow-gauge rail in the Swiss Alps between Zermatt, Andermatt, and Disentis, co-operating the Glacier Express with Rh\xe4tische Bahn.","history":"Matterhorn Gotthard Bahn formed in 2003 from the merger of the Furka Oberalp Bahn (FO) and the Brig-Visp-Zermatt Bahn (BVZ). It operates the highest-altitude rail crossing of the Alps via the Furka Base Tunnel and provides the final approach into Zermatt, a car-free resort beneath the Matterhorn. Together with RhB, MGB co-operates the Glacier Express, marketed as the world\'s slowest express train, linking Zermatt to St. Moritz over roughly eight hours.","stats":[{"label":"Year Founded","value":"2003"},{"label":"Route Kilometers","value":"144"},{"label":"Gauge","value":"1,000mm"},{"label":"Highest Point","value":"Furka Base Tunnel"}],"websiteUrl":"https://www.matterhorngotthardbahn.ch","gtfsEnabled":true,"map":{"lat":46.55,"lng":8.3,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"Seattle Streetcar","slug":"seattlestreetcar","metric":false,"cities":["seattle"],"color":"#F47836","darkerColor":"#C2571E","textColor":"#FFFFFF","shortForms":["Seattle Streetcar"],"summary":"Seattle Streetcar operates the South Lake Union and First Hill streetcar lines, connecting downtown Seattle to nearby neighborhoods.","history":"The South Lake Union Streetcar opened in 2007, linking downtown Seattle to the South Lake Union neighborhood. The First Hill Streetcar followed in 2016, connecting Pioneer Square to Capitol Hill via First Hill. The system is owned by the Seattle Department of Transportation (SDOT) and operated under contract by King County Metro.","stats":[{"label":"Year Opened","value":"2007"},{"label":"Lines","value":"2"},{"label":"System Length","value":"3.8 miles"},{"label":"Operator","value":"SDOT / King County Metro"}],"websiteUrl":"https://www.seattle.gov/transportation/getting-around/transit/streetcar","map":{"lat":47.6222,"lng":-122.3253,"zoom":13},"vehicleClassificationOverride":"streetcar"},{"name":"Poland National Rail","slug":"polish-rail","metric":true,"cities":[],"countries":["Poland"],"color":"#C8102E","darkerColor":"#8C0B20","textColor":"#FFFFFF","shortForms":["PKP","Polish Rail"],"summary":"All passenger rail services across Poland â PKP Intercity, Polregio, Koleje Mazowieckie, SKM Warszawa, SKM Tr\xf3jmiasto, Koleje ÅlÄ
skie, ÅKA, and other regional operators comb
16ined into a single unified view.","history":"Poland\'s rail network dates to the 1840s and grew into one of Europe\'s densest, though decades of state ownership under PKP left it fragmented by the 2000s as regional voivodeships spun up their own operators. Today PKP Intercity runs long-distance and international services while over a dozen regional companies â Polregio, Koleje Mazowieckie, SKM Warszawa, SKM Tr\xf3jmiasto, Koleje ÅlÄ
skie, Koleje DolnoÅlÄ
skie, and others â cover commuter and regional routes, all running on infrastructure maintained by state operator PKP PLK.","stats":[{"label":"Route Km","value":"18,500+"},{"label":"Operators","value":"13"},{"label":"Daily Trains","value":"5,000+"}],"websiteUrl":"https://intercity.pl","gtfsEnabled":true,"map":{"lat":52,"lng":19.5,"zoom":6},"vehicleClassificationOverride":"rail"},{"name":"Romania National Rail","slug":"cfr","metric":true,"cities":[],"countries":["Romania"],"color":"#002B7F","darkerColor":"#001D57","textColor":"#FFFFFF","shortForms":["CFR","CFR CÄlÄtori"],"summary":"CFR CÄlÄtori operates Romania\'s national passenger rail network, running InterRegio, Regio, and international services on infrastructure maintained by state operator CFR.","history":"CÄile Ferate Rom\xe2ne (CFR) has run Romania\'s railways since 1880, building on the country\'s first line opened in 1854 between OraviÈa and Bazias. The current passenger operator, CFR CÄlÄtori, was split off as a separate company in 1998 and remains the only national-level passenger carrier, connecting nearly all of Romania\'s cities and towns over one of Southeastern Europe\'s densest rail networks.","stats":[{"label":"Route Km","value":"10,777"},{"label":"Stations","value":"~2,000"},{"label":"Operator","value":"CFR CÄlÄtori"},{"label":"Founded","value":"1880"}],"websiteUrl":"https://www.cfrcalatori.ro/en/","gtfsEnabled":true,"map":{"lat":45.9,"lng":25,"zoom":6},"vehicleClassificationOverride":"rail"},{"name":"Elron","slug":"elron","metric":true,"cities":[],"countries":["Estonia"],"color":"#FF711D","darkerColor":"#C24F00","textColor":"#FFFFFF","shortForms":["Elron","Eesti Liinirongid"],"summary":"Estonia\'s national passenger rail operator, running electric commuter trains around Tallinn and diesel intercity services connecting Tartu, Narva, Valga, and P\xe4rnu.","history":"Elron traces back to Elektriraudtee, founded in 1998 to run Tallinn\'s electrified commuter network. On 1 January 2014 it absorbed the diesel intercity routes previously run by Edelaraudtee, becoming Estonia\'s sole domestic passenger rail operator under the AS Eesti Liinirongid holding and rebranding as Elron. Its Stadler FLIRT electric and diesel fleet, delivered from 2013, earned the nickname \\"porgandid\\" (carrots) for its orange livery.","stats":[{"label":"Founded","value":"1998"},{"label":"Unified","value":"2014"},{"label":"Fleet","value":"38"},{"label":"Lines","value":"27"}],"websiteUrl":"https://elron.ee/en","gtfsEnabled":true,"map":{"lat":58.7,"lng":25.8,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"PATH","slug":"path","metric":false,"cities":["new-york"],"color":"#0047BB","darkerColor":"#00348A","textColor":"#FFFFFF","shortForms":["PATH"],"summary":"PATH is a rapid transit system connecting Manhattan with Hoboken, Jersey City, and Newark under the Hudson River.","history":"PATH traces its roots to the Hudson & Manhattan Railroad, which opened its first tunnels under the Hudson River in 1908, decades before comparable underwater rail crossings. The line struggled financially through much of the 20th century and was taken over by the Port Authority of New York and New Jersey in 1962, which rebranded it as PATH (Port Authority Trans-Hudson) and rebuilt the World Trade Center station as its Manhattan terminus. The WTC station was destroyed in the September 11, 2001 attacks and rebuilt as the Oculus, reopening in phases through 2003-2016. Today PATH carries commuters between four New Jersey terminals and Midtown/Lower Manhattan around the clock.","stats":[{"label":"Year Opened","value":"1908"},{"label":"Stations","value":"13"},{"label":"Daily Ridership (pre-pandemic)","value":"280k"},{"label":"Lines","value":"4"}],"websiteUrl":"https://www.panynj.gov/path/en/index.html","map":{"lat":40.7295,"lng":-74.0525,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"Tallinn Trams","slug":"tallinn","metric":true,"cities":["tallinn"],"color":"#00693E","darkerColor":"#00492B","textColor":"#FFFFFF","shortForms":["Tallinna Trammiliinid"],"summary":"Tallinn\'s tram network is one of the oldest in the Baltics, complementing the city\'s extensive trolleybus and bus network across the Estonian capital.","history":"Trams have run in Tallinn since 1888 (horse-drawn), electrified in 1925. The network today is operated as part of Tallinna Linnatranspordi AS, the city\'s public transport authority, which also runs Tallinn\'s buses and trolleybuses. Public transport has been free for registered Tallinn residents since 2013.","stats":[{"label":"Operator","value":"Tallinna Linnatranspordi AS"},{"label":"Tram Routes","value":"5"}],"websiteUrl":"https://www.tallinn.ee/","map":{"lat":59.437,"lng":24.7536,"zoom":12},"vehicleClassificationOverride":"streetcar"},{"name":"MTR","slug":"mtr","metric":true,"cities":["hong-kong"],"color":"#AE213B","darkerColor":"#7A1729","textColor":"#FFFFFF","shortForms":["MTR"],"summary":"The MTR (Mass Transit Railway) is Hong Kong\'s rapid transit network, operated by MTR Corporation, carrying millions of passengers daily across 10 heavy rail lines.","history":"The MTR opened in 1979 with the Kwun Tong Line, Hong Kong\'s first rapid transit line. It has since grown into one of the world\'s busiest and most profitable metro systems, later absorbing the former Kowloon-Canton Railway (KCR) network in 2007 to form today\'s integrated system spanning Hong Kong Island, Kowloon, and the New Territories.","stats":[{"label":"Year Founded","value":"1979"},{"label":"Heavy Rail Lines","value":"10"},{"label":"Stations","value":"97"},{"label":"Daily Ridership","value":"~5m"}],"websiteUrl":"https://www.mtr.com.hk","map":{"lat":22.3193,"lng":114.1694,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"MTR Light Rail","slug":"mtrlightrail","metric":true,"cities":["hong-kong"],"color":"#DAA520","darkerColor":"#9C7A17","textColor":"#FFFFFF","shortForms":["LRT","Light Rail"],"summary":"MTR Light Rail is a street-running light rail network serving Tuen Mun and Yuen Long in Hong Kong\'s New Territories, a separate system from the heavy rail MTR network.","history":"Light Rail opened on 18 September 1988 as the first rapid transit line built for the then-new towns of Tuen Mun and Yuen Long, originally operated by the Kowloon-Canton Railway (KCR) and folded into MTR Corporation when KCR and MTR merged in 2007.","stats":[{"label":"Year Founded","value":"1988"},{"label":"Routes","value":"11"},{"label":"Stations","value":"68"},{"label":"Daily Ridership","value":"~480k"}],"websiteUrl":"https://www.mtr.com.hk","map":{"lat":22.4,"lng":114,"zoom":12},"vehicleClassificationOverride":"light_rail"},{"name":"Taiwan Railways","slug":"taiwan-tra","metric":true,"cities":[],"countries":["Taiwan"],"color":"#0066B3","darkerColor":"#004A82","textColor":"#FFFFFF","shortForms":["TRA","Taiwan Rail"],"summary":"Taiwan\'s national conventional rail network, operated by the Taiwan Railway Administration, circling the island and connecting every major city outside the high-speed line.","history":"Taiwan\'s rail network dates to 1891 under Qing and Jap
16anese colonial rule, expanding into the island-circling system operated today by the Taiwan Railway Administration (TRA), which was corporatized into the Taiwan Railway Corporation in 2024.","stats":[{"label":"Route Kilometers","value":"1,065"},{"label":"Stations","value":"241"}],"websiteUrl":"https://www.railway.gov.tw","map":{"lat":23.9739,"lng":120.982,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Taiwan High Speed Rail","slug":"taiwan-thsr","metric":true,"cities":[],"countries":["Taiwan"],"color":"#E5202A","darkerColor":"#B0181F","textColor":"#FFFFFF","shortForms":["THSR","Taiwan HSR"],"summary":"Taiwan High Speed Rail connects Taipei and Kaohsiung along the island\'s western corridor, operated by Taiwan High Speed Rail Corporation (THSRC).","history":"THSR opened in 2007, built on Japanese Shinkansen technology, and cut the Taipei-Kaohsiung journey to under two hours â reshaping travel along Taiwan\'s densely populated west coast.","stats":[{"label":"Opened","value":"2007"},{"label":"Route Kilometers","value":"350"},{"label":"Stations","value":"12"}],"websiteUrl":"https://www.thsrc.com.tw","map":{"lat":23.9739,"lng":120.982,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Toei Subway","slug":"toei","metric":true,"cities":[],"countries":["Japan"],"color":"#00A73C","darkerColor":"#00792B","textColor":"#FFFFFF","shortForms":["Toei"],"summary":"Toei Subway operates four lines across Tokyo â Asakusa, Mita, Shinjuku, and Oedo â run by the Tokyo Metropolitan Bureau of Transportation, alongside the larger Tokyo Metro network.","history":"Toei\'s first line, the Asakusa Line, opened in 1960 as Japan\'s first subway line to through-run onto private railway tracks. The Oedo Line, completed in 2000, is the deepest and most circuitous of Tokyo\'s subway lines.","stats":[{"label":"Opened","value":"1960"},{"label":"Lines","value":"4"},{"label":"Stations","value":"106"}],"websiteUrl":"https://www.kotsu.metro.tokyo.jp/","map":{"lat":35.6895,"lng":139.6917,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"Tokyo Metro","slug":"tokyometro","metric":true,"cities":[],"countries":["Japan"],"color":"#0079C2","darkerColor":"#005A94","textColor":"#FFFFFF","shortForms":["Tokyo Metro"],"summary":"Tokyo Metro operates nine subway lines across central Tokyo, forming the busiest and most extensive part of the city\'s subway network alongside Toei Subway.","history":"The Ginza Line, opened in 1927, was Asia\'s first subway line. Tokyo Metro was formed in 2004 from the former Teito Rapid Transit Authority (TRTA) and now carries some of the highest ridership of any metro system in the world.","stats":[{"label":"Opened","value":"1927"},{"label":"Lines","value":"9"},{"label":"Stations","value":"180"}],"websiteUrl":"https://www.tokyometro.jp/","map":{"lat":35.6895,"lng":139.6917,"zoom":11},"vehicleClassificationOverride":"subway"},{"name":"Rocky Mountaineer","slug":"rocky-mountaineer","metric":true,"cities":["vancouver","kamloops","banff","lake-louise"],"countries":["Canada"],"color":"#8B4A2B","darkerColor":"#5F3119","textColor":"#FFFFFF","shortForms":["Rocky Mountaineer","RM"],"summary":"Rocky Mountaineer is a private luxury tourist train running seasonal, daylight-only scenic journeys through the Canadian Rockies on shared CP Rail freight track, with an overnight hotel stop at the midpoint of each multi-day route. This is a ghost train: there is no live GPS or GTFS-RT feed, positions are simulated from the published schedule.","history":"Rocky Mountaineer began operating in 1990 after acquiring the rights to run passenger rail through the Canadian Rockies from VIA Rail, building its business around daytime-only scenic travel -- trains never run overnight, stopping instead for a hotel break at the midpoint of each journey.","stats":[{"label":"Year Founded","value":"1990"},{"label":"Season","value":"AprilâOctober"},{"label":"Routes","value":"4"}],"websiteUrl":"https://www.rockymountaineer.com","gtfsEnabled":true,"map":{"lat":50.8,"lng":-118.5,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"The Ghan","slug":"the-ghan","metric":true,"cities":["adelaide","darwin"],"countries":["Australia"],"color":"#8B1A1A","darkerColor":"#5E1111","textColor":"#FFFFFF","shortForms":["The Ghan"],"summary":"The Ghan is Journey Beyond\'s transcontinental tourist train, crossing Australia\'s outback between Adelaide and Darwin via Alice Springs. This is a ghost train: there is no live GPS or GTFS-RT feed, positions are simulated from the published schedule.","history":"The Ghan takes its name from the Afghan cameleers who once supplied the route before the railway existed. The original narrow-gauge Central Australia Railway opened in stages from 1878, but only reached Alice Springs in 1929; the modern standard-gauge extension to Darwin, completing the full transcontinental route, wasn\'t finished until 2004.","stats":[{"label":"Year Founded","value":"1929"},{"label":"Distance (km)","value":"2,979"},{"label":"Darwin Extension","value":"2004"}],"websiteUrl":"https://www.journeybeyondrail.com.au","gtfsEnabled":true,"map":{"lat":-23.7,"lng":133,"zoom":4},"vehicleClassificationOverride":"intercity_rail"},{"name":"Indian Pacific","slug":"indian-pacific","metric":true,"cities":["sydney","adelaide","perth"],"countries":["Australia"],"color":"#1A3E8B","darkerColor":"#122A5F","textColor":"#FFFFFF","shortForms":["Indian Pacific"],"summary":"The Indian Pacific is Journey Beyond\'s transcontinental tourist train, crossing Australia coast-to-coast between Sydney and Perth via Adelaide -- including the Nullarbor Plain, home to the longest dead-straight stretch of railway track in the world. This is a ghost train: there is no live GPS or GTFS-RT feed, positions are simulated from the published schedule.","history":"The Indian Pacific began
16service in 1970, the same year the last gap in a uniform-gauge transcontinental line was completed, finally allowing a single train to run the full 4,352km between the Indian and Pacific Oceans without changing trains for a different rail gauge.","stats":[{"label":"Year Founded","value":"1970"},{"label":"Distance (km)","value":"4,352"},{"label":"Journey Length","value":"~4 days"}],"websiteUrl":"https://www.journeybeyondrail.com.au","gtfsEnabled":true,"map":{"lat":-31.5,"lng":128,"zoom":4},"vehicleClassificationOverride":"intercity_rail"},{"name":"Rovos Rail","slug":"rovos-rail","metric":true,"cities":["pretoria","cape-town"],"countries":["South Africa"],"color":"#6B4F2A","darkerColor":"#4A361C","textColor":"#FFFFFF","shortForms":["Rovos Rail","Pride of Africa"],"summary":"Rovos Rail is a private South African luxury tourist train, often called \'the most luxurious train in the world.\' Its flagship route, the Pride of Africa, crosses the Karoo between Pretoria and Cape Town over 4 days and 3 nights. This is a ghost train: there is no live GPS or GTFS-RT feed, positions are simulated from a representative schedule -- real departures run 2-4 times a month rather than on a fixed weekly pattern.","history":"Rovos Rail was founded in 1989 by South African businessman Rohan Vos, who restored a set of vintage steam-era carriages to create what has become one of the most exclusive rail experiences in the world, running multi-day journeys across Southern Africa.","stats":[{"label":"Year Founded","value":"1989"},{"label":"Distance (km)","value":"~1,600"},{"label":"Journey Length","value":"4 days"}],"websiteUrl":"https://www.rovos.com","gtfsEnabled":true,"map":{"lat":-30,"lng":23.5,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"Orient Express","slug":"orient-express","metric":true,"cities":["paris","venice"],"countries":["France","Switzerland","Austria","Italy"],"color":"#0A2E4D","darkerColor":"#061D33","textColor":"#FFFFFF","shortForms":["Orient Express","VSOE"],"summary":"The Venice Simplon-Orient-Express is Belmond\'s modern revival of the legendary luxury train, running an overnight journey between Paris and Venice via the Arlberg and Brenner passes. This is a ghost train: there is no live GPS or GTFS-RT feed, positions are simulated from a representative schedule -- real departures run 2-4 times a month, March through December.","history":"The original Orient Express began service in 1883, running between Paris and Constantinople (Istanbul) and becoming a byword for luxury rail travel. The modern Venice Simplon-Orient-Express, launched in 1982 using restored 1920s-30s carriages, revived the brand as a dedicated leisure journey rather than a point-to-point service, primarily running between Paris and Venice.","stats":[{"label":"Modern Revival","value":"1982"},{"label":"Journey Length","value":"~20.5 hours"},{"label":"Countries Crossed","value":"4"}],"websiteUrl":"https://www.belmond.com/trains/europe/venice-simplon-orient-express/","gtfsEnabled":true,"map":{"lat":46.8,"lng":9.5,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"Canberra Light Rail","slug":"canberralightrail","metric":true,"cities":["canberra"],"countries":["Australia"],"color":"#C8102E","darkerColor":"#8F0B21","textColor":"#FFFFFF","shortForms":["Light Rail"],"summary":"Canberra Light Rail is a single-line tram system connecting Gungahlin to the city centre, operated by Canberra Metro under contract to Transport Canberra.","history":"Canberra Light Rail opened in April 2019 as the ACT\'s first light rail line, linking the northern town centre of Gungahlin to Civic along Northbourne Avenue. It is operated by Canberra Metro Operations under a 20-year public-private partnership contract. A Stage 2 extension south to Woden is in planning.","stats":[{"label":"System Length","value":"12 km"},{"label":"Stops","value":"14"},{"label":"Annual Ridership","value":"4.1 million (2023)"},{"label":"Vehicle Type","value":"CAF Urbos 3"},{"label":"Year Opened","value":"2019"}],"websiteUrl":"https://www.transport.act.gov.au/travel-options/light-rail","map":{"lat":-35.2508,"lng":149.1324,"zoom":12},"vehicleClassificationOverride":"light_rail"},{"name":"Metro Manila Rail","slug":"manila","metric":true,"cities":["manila"],"countries":["Philippines"],"color":"#F8D01D","darkerColor":"#B69500","textColor":"#111111","shortForms":["LRT","MRT"],"summary":"Metro Manila\'s LRT-1, LRT-2, and MRT-3 lines connect major destinations across the Philippine capital region.","history":"Metro Manila\'s modern urban rail era began when LRT-1 opened in 1984, becoming the first rapid-transit line in Southeast Asia. MRT-3 began serving the EDSA corridor in 1999, and LRT-2 followed in 2003 with an east-west route through Manila and Quezon City. The three elevated rail lines form the backbone of the capital region\'s public transport network and continue to expand toward new interchange stations and surrounding cities.","stats":[{"label":"Lines","value":"3"},{"label":"Stations","value":"51"},{"label":"First Line Opened","value":"1984"}],"websiteUrl":"https://www.lrta.gov.ph/","gtfsEnabled":true,"map":{"lat":14.5995,"lng":120.9842,"zoom":11},"vehicleClassificationOverride":"rapid_transit"},{"name":"Gatwick Express","slug":"gatwick-express","metric":true,"cities":["london","brighton"],"countries":["United Kingdom"],"color":"#E31837","darkerColor":"#A61129","textColor":"#FFFFFF","shortForms":["Gatwick Express","GX"],"summary":"Gatwick Express runs airport rail services between London Victoria, Gatwick Airport, and Brighton.","stats":[{"label":"Journey Time","value":"30 min"},{"label":"Frequency","value":"Every 15 min"},{"label":"Year Established","value":"1984"}],"websiteUrl":"https://www.gatwickexpress.com","gtfsEnabled":true,"map":{"lat":51.161,"lng":-0.182,"zoom":9},"vehicleClassificationOverride":"intercity_rail"},{"name":"Lumo","slug":"lumo","metric":true,"cities":["london","edinburgh"],"countries":["United Kingdom"],"color":"#1C2B39","darkerColor":"#101820","textColor":"#FFFFFF","shortForms":["Lumo"],"summary":"Lumo operates open-access intercity passenger trains on the East Coast Main Line.","stats":[{"label":"Journey Time","value":"4h 15m"},{"label":"Year Established","value":"2021"}],"websiteUrl":"https://www.lumo.co.uk","gtfsEnabled":true,"map":{"lat":54.2,"lng":-1.5,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"Island Line","slug":"island-line","metric":true,"cities":[],"countries":["United Kingdom"],"color":"#005EB8","darkerColor":"#003B73","textColor":"#FFFFFF","shortForms":["Island Line","IL"],"summary":"Island Line connects Ryde and Shankl
16in by rail on the Isle of Wight.","stats":[{"label":"Stations","value":"8"},{"label":"Route Length","value":"8.5 mi"},{"label":"Year Reopened","value":"2021"}],"websiteUrl":"https://www.southwesternrailway.com/travelling-with-us/at-the-station/island-line","gtfsEnabled":true,"map":{"lat":50.65,"lng":-1.16,"zoom":11},"vehicleClassificationOverride":"commuter_rail"},{"name":"Singapore MRT/LRT","slug":"sgmrt","metric":true,"cities":["singapore"],"countries":["Singapore"],"color":"#E30613","darkerColor":"#B5050F","textColor":"#FFFFFF","shortForms":["MRT","LRT"],"summary":"Singapore\'s Mass Rapid Transit (MRT) and Light Rail Transit (LRT) network, operated by SMRT Trains and SBS Transit under the Land Transport Authority (LTA).","history":"Singapore\'s MRT network opened in 1987 and has grown into one of the most extensive urban rail systems in Southeast Asia, spanning multiple lines operated jointly by SMRT Trains and SBS Transit under LTA\'s unified planning. LRT lines provide feeder services connecting residential estates to the MRT trunk network.","stats":[{"label":"Operators","value":"SMRT / SBS Transit"},{"label":"Region","value":"Singapore"}],"websiteUrl":"https://www.lta.gov.sg","gtfsEnabled":true,"map":{"lat":1.3521,"lng":103.8198,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"Trenitalia Regionale Toscana","slug":"trenitalia-toscana","metric":true,"cities":["florence"],"countries":["Italy"],"color":"#1B3A6B","darkerColor":"#122747","textColor":"#FFFFFF","shortForms":["Trenitalia Toscana"],"summary":"Trenitalia\'s regional passenger trains across Tuscany, connecting Florence with Pisa, Livorno, Siena, Arezzo, Lucca, and the rest of the region under contract to Regione Toscana.","history":"Trenitalia, the passenger operator of the state-owned Ferrovie dello Stato Italiane group, runs Tuscany\'s regional rail network under a service contract with the regional government. The network radiates from Florence\'s Santa Maria Novella station across 14 lines reaching the region\'s other major cities and the wider rail network beyond Tuscany\'s borders, including cross-region corridors toward Bologna, La Spezia, and Parma.","stats":[{"label":"Regional Routes","value":"14"},{"label":"Stations","value":"313"},{"label":"Operator","value":"Trenitalia"}],"websiteUrl":"https://www.trenitalia.com","gtfsEnabled":true,"map":{"lat":43.5,"lng":11.1,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"Trenord","slug":"trenord","metric":true,"cities":["milan"],"countries":["Italy"],"color":"#00843D","darkerColor":"#00602C","textColor":"#FFFFFF","shortForms":["Trenord"],"summary":"Trenord operates Lombardy\'s regional and suburban rail network, radiating from Milan across the region under a joint venture between Trenitalia and Regione Lombardia.","history":"Trenord was formed in 2011 as a joint venture between Trenitalia and Regione Lombardia (via its holding company FNM), consolidating regional rail services previously split between Trenitalia and LeNord. It now operates Lombardy\'s full regional (R/RE) and suburban S-Bahn-style (S-line) network centred on Milan, connecting the city to Bergamo, Brescia, Como, Varese, Lecco, Pavia, Cremona, Mantova, and beyond.","stats":[{"label":"Regional Routes","value":"60"},{"label":"Stations","value":"494"},{"label":"Formed","value":"2011"}],"websiteUrl":"https://www.trenord.it","gtfsEnabled":true,"map":{"lat":45.6,"lng":9.5,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"Trenitalia Regionale Sardegna","slug":"trenitalia-sardegna","metric":true,"cities":["cagliari"],"countries":["Italy"],"color":"#1B3A6B","darkerColor":"#122747","textColor":"#FFFFFF","shortForms":["Trenitalia Sardegna"],"summary":"Trenitalia\'s regional passenger trains across Sardinia, connecting Cagliari with Oristano, Macomer, Sassari, Olbia, and the Iglesias-Carbonia branch under contract to Regione Sardegna.","history":"Trenitalia, the passenger operator of the state-owned Ferrovie dello Stato Italiane group, runs Sardinia\'s regional rail network under a service contract with the regional government. The network\'s main trunk connects Cagliari in the south to Sassari and Olbia in the north via Oristano and Macomer, with a branch serving the mining towns of Iglesias and Carbonia in the southwest.","stats":[{"label":"Stations","value":"37"},{"label":"Operator","value":"Trenitalia"}],"websiteUrl":"https://www.trenitalia.com","gtfsEnabled":true,"map":{"lat":40.1,"lng":9,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"Trenitalia Regionale (Lazio)","slug":"trenitalia-lazio","metric":true,"cities":["rome"],"countries":["Italy"],"color":"#008C45","darkerColor":"#006633","textColor":"#FFFFFF","shortForms":["Trenitalia Lazio"],"summary":"Regional trains serving Lazio, with estimated positions based on observed ViaggiaTreno timetables and live delays. Coverage grows as services are observed at major hubs.","websiteUrl":"https://www.trenitalia.com","gtfsEnabled":true,"map":{"lat":41.9,"lng":12.5,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"Trenitalia Regionale (Veneto)","slug":"trenitalia-veneto","metric":true,"cities":["venice"],"countries":["Italy"],"color":"#008C45","darkerColor":"#006633","textColor":"#FFFFFF","shortForms":["Trenitalia Veneto"],"summary":"Regional trains serving Veneto, with estimated positions based on observed ViaggiaTreno timetables and live delays. Coverage grows as services are observed at major hubs.","websiteUrl":"https://www.trenitalia.com","gtfsEnabled":true,"map":{"lat":45.44,"lng":12.32,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"Trenitalia Nazionale","slug":"trenitalia-nazionale","metric":true,"cities":["rome"],"countries":["Italy"],"color":"#C8102E","darkerColor":"#8F0B20","textColor":"#FFFFFF","shortForms":["Trenitalia Nazionale","Frecce"],"summary":"Trenitalia\'s national high-speed and Intercity trains (Frecciarossa, Frecciargento, Frecciabianca, Intercity, Eurocity) connecting Italy\'s major cities, positioned from a progressively self-built schedule rather than an official static feed.","history":"Unlike Trenitalia\'s regional operations, no official static GTFS exists for Italy\'s national high-speed and Intercity network. trains.fyi builds its own schedule for these trains by repeatedly observing Trenitalia\'s live ViaggiaTreno system and accumulating a confident, self-learned timetable over time -- see the Italy National Rail engine project for details. Coverage improves as more trains are observed and promoted;
16 this is a living, continuously-refined schedule rather than a fixed one.","stats":[{"label":"Categories","value":"Frecce, Intercity, Eurocity"},{"label":"Operator","value":"Trenitalia"}],"websiteUrl":"https://www.trenitalia.com","gtfsEnabled":true,"map":{"lat":42.5,"lng":12.5,"zoom":6}},{"name":"NS (Nederlandse Spoorwegen)","slug":"ns","metric":true,"cities":["amsterdam","rotterdam","utrecht","the-hague","eindhoven","groningen"],"color":"#FFC917","darkerColor":"#cc9f00","textColor":"#000000","shortForms":["NS","Dutch Railways"],"summary":"NS (Nederlandse Spoorwegen) is the principal operator of passenger rail services in the Netherlands, running intercity and sprinter trains across the national network.","history":"NS has operated the Netherlands\' national rail network since 1938, when it was formed from the merger of the country\'s two main railway companies. It runs the majority of domestic passenger rail services, including Intercity and Sprinter trains, and international services under the NS International brand.","stats":[{"label":"Railway Route KM","value":"3,223"},{"label":"Railway Stations","value":"400+"},{"label":"Year Founded","value":"1938"}],"websiteUrl":"https://www.ns.nl/","gtfsEnabled":true,"map":{"lat":52.1326,"lng":5.2913,"zoom":7},"vehicleClassificationOverride":"regional_rail"},{"name":"Ruter","slug":"ruter","metric":true,"cities":["oslo"],"countries":["Norway"],"color":"#00A19A","darkerColor":"#00726C","textColor":"#FFFFFF","shortForms":["Ruter"],"summary":"Ruter operates the Oslo Metro (T-banen) and tram network, connecting the Norwegian capital and surrounding Akershus county with 5 metro lines and 6 tram lines.","history":"Ruter AS was formed in 2008 as the public transport authority for Oslo and Akershus, consolidating what had previously been separately branded metro (T-banen), tram (Oslo Sporvognsdrift), bus, and ferry operations under one authority. The T-banen network dates to 1966 as one of the first metro systems in Scandinavia, while Oslo\'s trams have run since 1875, among the oldest tram networks still operating in Europe.","stats":[{"label":"Metro Lines","value":"5"},{"label":"Tram Lines","value":"6"},{"label":"Formed","value":"2008"}],"websiteUrl":"https://ruter.no","gtfsEnabled":true,"map":{"lat":59.9139,"lng":10.7522,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"CP â Comboios de Portugal","slug":"cp-portugal","metric":true,"cities":["lisbon"],"countries":["Portugal"],"color":"#E4032E","darkerColor":"#A80224","textColor":"#FFFFFF","shortForms":["CP"],"summary":"CP (Comboios de Portugal) is Portugal\'s national state-owned rail operator, running long-distance Alfa Pendular and Intercidades services alongside urban and regional lines radiating from Lisbon and Porto.","history":"Comboios de Portugal traces its roots to Portugal\'s 19th-century railway companies, nationalized and consolidated over the 20th century into today\'s state operator. CP runs the flagship Alfa Pendular tilting-train service between Lisbon, Porto, Coimbra, and the Algarve, Intercidades regional expresses, and dense suburban networks around Lisbon (Linha de Sintra, Linha de Cascais, Linha da Azambuja) and Porto.","stats":[{"label":"Routes","value":"179"},{"label":"Stations","value":"454"},{"label":"Operator","value":"CP"}],"websiteUrl":"https://www.cp.pt","gtfsEnabled":true,"map":{"lat":39.5,"lng":-8,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"ONCF","slug":"oncf-morocco","metric":true,"cities":["casablanca"],"countries":["Morocco"],"color":"#E31837","darkerColor":"#A30F27","textColor":"#FFFFFF","shortForms":["ONCF"],"summary":"ONCF (Office National des Chemins de Fer) is Morocco\'s national rail operator, running the Al Boraq high-speed line between Tangier and Casablanca alongside Al Atlas intercity and TNR suburban services.","history":"ONCF was established in 1963 to operate Morocco\'s national rail network, inherited from the French and Spanish colonial-era railway companies. In 2018 it launched Al Boraq, Africa\'s first and only true high-speed rail line, running at up to 320 km/h between Tangier and Casablanca via Rabat and K\xe9nitra. ONCF\'s Al Atlas intercity services extend the network further to Marrakech, F\xe8s, Oujda, and El Jadida, while TNR suburban trains serve the dense Casablanca-Rabat-K\xe9nitra corridor.","stats":[{"label":"Operator","value":"ONCF"}],"websiteUrl":"https://www.oncf.ma","gtfsEnabled":true,"map":{"lat":32.5,"lng":-6.5,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"CTrail Hartford Line","slug":"ctrail-hartford","metric":false,"cities":["hartford"],"countries":["United States"],"color":"#003057","darkerColor":"#001B33","textColor":"#FFFFFF","shortForms":["CTrail","Hartford Line"],"summary":"CTrail\'s Hartford Line connects New Haven, Hartford, and Springfield, Massachusetts, operated by Amtrak under contract to the Connecticut Department of Transportation.","history":"The Hartford Line launched in 2018, restoring frequent passenger service along the historic New HavenâHartfordâSpringfield rail corridor after decades of limited Amtrak-only service. CTDOT owns the Connecticut portion of the line and contracts operations to Amtrak, with service extending north into Massachusetts to Springfield.","stats":[{"label":"Year Launched","value":"2018"},{"label":"Stations","value":"9"}],"websiteUrl":"https://hartfordline.com","gtfsEnabled":true,"map":{"lat":41.9,"lng":-72.7,"zoom":8},"vehicleClassificationOverride":"regional_rail"},{"name":"NMBS/SNCB","slug":"nmbs-belgium","metric":true,"cities":["brussels"],"countries":["Belgium"],"color":"#1E4694","darkerColor":"#152E63","textColor":"#FFFFFF","shortForms":["NMBS","SNCB"],"summary":"NMBS/SNCB is Belgium\'s national rail operator, running Intercity (IC), Local (L), Suburban (S), and Peak (P) services across the country\'s dense national network.","history":"NMBS (Dutch) / SNCB (French) was formed in 1926 as Belgium\'s national railway company, taking over operations from a patchwork of earlier private and state railways dating to Belgium\'s 1835 rail pioneer era -- continental Europe\'s first railway line. Today it operates a dense national network radiating through Brussels\' three main stations (Midi, Central, Nord), connecting every major Belgian city with frequent Intercity and local services.","stats":[{"label":"Routes","value":"1,289"},{"label":"Stations","value":"2,185"},{"label":"Founded","value":"1926"}],"websiteUrl":"https://www.belgiantrain.be","gtfsEnabled":true,"map":{"lat":50.5039,"lng":4.4699,"zoom":8},"vehicleClassificationOverride":"intercity_rail"},{"name":"Romania Private Operators","slug":"romania-private","metric":true,"cities":["bucharest"],"countries":["Romania"],"color":"#002B7F","darkerColor":"#001D55","textColor":"#FFFFFF","shortForms":["Regio CÄlÄtori","Transferoviar"],"summary":"Private passenger rail operators running regional and long-distance services across Romania alongside state operator CFR, following the market\'s 2010s liberalization: Regio CÄlÄtori, Transferoviar Calatori, Astra Trans Carpatic, InterRegional CÄlÄtori, Softrans, and Ferotrafic-TFI.","history":"Romania liberalized its passenger rail market starting in 2014, allowing private operators to compete with state incumbent CFR CÄlÄtori on regional and long-distance routes. Several companies now run scheduled service across the country, from short regional shuttles to routes crossing multiple regions, using rolling stock leased or acquired from CFR\'s retired fleet.","stats":[{"label":"Routes","value":"269"},{"label":"Stations","value":"749"},{"label":"Operators","value":"6"}],"websiteUrl":"https://www.regiotrans.ro/","gtfsEnabled":true,"map":{"lat":45.9432,"lng":24.9668,"zoom":7},"vehicleClassificationOverride":"regional_rail"},{"name":"Kyivpastrans Trams","slug":"kyivpastrans-tram","metric":true,"cities":["kyiv"],"countries":["Ukraine"],"color":"#0057B7","darkerColor":"#003D80","textColor":"#FFFFFF","shortForms":["Kyivpastrans"],"summary":"Kyivpastrans operates Kyiv\'s tram network, one of several tram systems serving the Ukrainian capital alongside the separately-operated Kyiv Metro.","history":"Kyiv\'s tram network dates to 1892, one of the oldest in Eastern Europe. Today it\'s operated by the municipal enterprise Kyivpastrans, which also runs the city\'s trolleybus and bus networks, connecting residential districts to the city center and to Kyiv Metro stations.","stats":[{"label":"Routes","value":"17"},{"label":"Stations","value":"167"},{"label":"Founded","value":"1892"}],"websiteUrl":"https://kpt.kyiv.ua/","gtfsEnabled":true,"map":{"lat":50.4501,"lng":30.5234,"zoom":11},"vehicleClassificationOverride":"tram"},{"name":"Vietnam Railways","slug":"vietnam-railways","metric":true,"cities":["hanoi","ho-chi-minh-city"],"countries":["Vietnam"],"color":"#C1272D","darkerColor":"#7A1A1D","textColor":"#FFFFFF","summary":"Vietnam Railways operates the North-South Reunification
16Express and regional trains along the length of the country. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published timetables.","websiteUrl":"http://vr.com.vn","gtfsEnabled":true,"map":{"lat":16,"lng":108,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"China Railway","slug":"china-railway","metric":true,"cities":["beijing","shanghai"],"countries":["China"],"color":"#D2242C","darkerColor":"#8A171D","textColor":"#FFFFFF","summary":"China Railway operates high-speed, intercity and conventional passenger trains across China. Positions are estimated from a community timetable feed, not live tracking. The feed assumes daily service; actual operating dates and cancellations may differ.","websiteUrl":"https://www.12306.cn","gtfsEnabled":true,"map":{"lat":35,"lng":104,"zoom":3},"vehicleClassificationOverride":"intercity_rail"},{"name":"State Railway of Thailand","slug":"thailand-railways","metric":true,"cities":["bangkok"],"countries":["Thailand"],"color":"#8B1E3F","darkerColor":"#5C1329","textColor":"#FFFFFF","summary":"The State Railway of Thailand operates long-distance trains on the Northern, Northeastern, Eastern, and Southern main lines out of Bangkok. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published timetables.","websiteUrl":"https://www.railway.co.th","gtfsEnabled":true,"map":{"lat":13.5,"lng":101,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"SRT Commuter Rail","slug":"thailand-srt","metric":true,"cities":["bangkok"],"countries":["Thailand"],"color":"#B5191E","darkerColor":"#7A1013","textColor":"#FFFFFF","summary":"SRT\'s Bangkok-area commuter and suburban rail: the Mahachai line, Airport Rail Link, and the Dark Red and Light Red Lines. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published headways.","websiteUrl":"https://www.railway.co.th","gtfsEnabled":true,"map":{"lat":13.75,"lng":100.5,"zoom":10},"vehicleClassificationOverride":"regional_rail"},{"name":"Hanoi Metro","slug":"hanoi-metro","metric":true,"cities":["hanoi"],"countries":["Vietnam"],"color":"#00843D","darkerColor":"#005A29","textColor":"#FFFFFF","summary":"Hanoi Metro operates two lines, Cat Linh-Ha Dong and Nhon-Hanoi Station. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published headways.","websiteUrl":"https://hanoimetro.net.vn","gtfsEnabled":true,"map":{"lat":21.0285,"lng":105.8542,"zoom":12},"vehicleClassificationOverride":"metro"},{"name":"Ho Chi Minh City Metro","slug":"hcmc-metro","metric":true,"cities":["ho-chi-minh-city"],"countries":["Vietnam"],"color":"#0055A4","darkerColor":"#003970","textColor":"#FFFFFF","summary":"Ho Chi Minh City Metro\'s Ben Thanh-Suoi Tien line, the city\'s first metro line, opened in 2024. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published headways.","websiteUrl":"https://hochiminhcitymetro.com","gtfsEnabled":true,"map":{"lat":10.8231,"lng":106.6297,"zoom":12},"vehicleClassificationOverride":"metro"},{"name":"Shanghai Metro","slug":"shanghai-metro","metric":true,"cities":["shanghai"],"countries":["China"],"color":"#E4002B","darkerColor":"#9A0020","textColor":"#FFFFFF","summary":"Shanghai Metro is one of the world\'s largest metro systems by route length. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published headways.","websiteUrl":"https://www.shmetro.com","gtfsEnabled":true,"map":{"lat":31.2304,"lng":121.4737,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"Shenzhen Metro","slug":"shenzhen-metro","metric":true,"cities":["shenzhen"],"countries":["China"],"color":"#00ABEB","darkerColor":"#0073A3","textColor":"#FFFFFF","summary":"Shenzhen Metro serves one of China\'s fastest-growing cities with a rapidly expanding network. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published headways.","websiteUrl":"https://www.szmc.net","gtfsEnabled":true,"map":{"lat":22.5431,"lng":114.0579,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"Egyptian National Railways","slug":"egypt-railways","metric":true,"cities":["cairo","alexandria"],"countries":["Egypt"],"color":"#C09A2E","darkerColor":"#8A6E1F","textColor":"#FFFFFF","summary":"Egyptian National Railways operates the Cairo-Aswan Upper Egypt main line and the Cairo-Alexandria corridor. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published timetables.","websiteUrl":"https://enr.gov.eg","gtfsEnabled":true,"map":{"lat":27,"lng":31,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"Kazakhstan Temir Zholy","slug":"kazakhstan-railways","metric":true,"cities":["almaty","astana"],"countries":["Kazakhstan"],"color":"#00AFCA","dar
16kerColor":"#007A8C","textColor":"#FFFFFF","summary":"Kazakhstan Temir Zholy operates long-distance trains between Almaty, Astana, and Shymkent, including the flagship Tulpar-Talgo services. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published timetables.","websiteUrl":"https://ticket.railways.kz","gtfsEnabled":true,"map":{"lat":46,"lng":74,"zoom":5},"vehicleClassificationOverride":"intercity_rail"},{"name":"Kereta Api Indonesia","slug":"indonesia-railways","metric":true,"cities":["jakarta","surabaya","bandung"],"countries":["Indonesia"],"color":"#F26522","darkerColor":"#A8420E","textColor":"#FFFFFF","summary":"Kereta Api Indonesia operates Java\'s intercity network, including the Argo Bromo Anggrek, Taksaka, Argo Lawu, Argo Dwipangga, Sancaka, Lodaya, Turangga, Malabar, Bima, and Sembrani named trains. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published timetables.","websiteUrl":"https://www.kai.id","gtfsEnabled":true,"map":{"lat":-7.3,"lng":109.5,"zoom":7},"vehicleClassificationOverride":"intercity_rail"},{"name":"Guangzhou Metro","slug":"guangzhou-metro","metric":true,"cities":["guangzhou"],"countries":["China"],"color":"#0089CF","darkerColor":"#005E8F","textColor":"#FFFFFF","summary":"Guangzhou Metro serves the Pearl River Delta\'s largest city with an extensive rapid transit network. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published headways.","websiteUrl":"https://www.gzmtr.com","gtfsEnabled":true,"map":{"lat":23.1291,"lng":113.2644,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"Beijing Subway","slug":"beijing-subway","metric":true,"cities":["beijing"],"countries":["China"],"color":"#005CA9","darkerColor":"#003D70","textColor":"#FFFFFF","summary":"Beijing Subway is the world\'s longest metro network by route length. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published headways.","websiteUrl":"https://www.bjsubway.com","gtfsEnabled":true,"map":{"lat":39.9042,"lng":116.4074,"zoom":11},"vehicleClassificationOverride":"metro"},{"name":"Jinshan Railway","slug":"jinshan-railway","metric":true,"cities":["shanghai"],"countries":["China"],"color":"#F58220","darkerColor":"#B85F13","textColor":"#FFFFFF","summary":"Jinshan Railway is China Railway Shanghai\'s suburban commuter line between Shanghai South and Jinshanwei. This is a ghost network: no live GPS or GTFS-RT feed exists, so positions are simulated from real published timetables.","websiteUrl":"https://www.shanghai.gov.cn","gtfsEnabled":true,"map":{"lat":31,"lng":121.35,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Vivi â Latvia National Rail","slug":"vivi","metric":true,"cities":["riga"],"countries":["Latvia"],"color":"#18567D","darkerColor":"#103B56","textColor":"#FFFFFF","shortForms":["Vivi"],"summary":"Published passenger services across Latvia using the official Vivi timetable. Positions are estimates, not live GPS locations.","history":"","stats":[],"websiteUrl":"https://www.vivi.lv","map":{"lat":56.95,"lng":24.12,"zoom":7},"vehicleClassificationOverride":"regional_rail","tripPlannerEnabled":false},{"name":"LTG Link â Lithuania National Rail","slug":"ltg-link","metric":true,"cities":["vilnius"],"countries":["Lithuania"],"color":"#18567D","darkerColor":"#103B56","textColor":"#FFFFFF","shortForms":["LTG Link"],"summary":"Passenger services in the published LTG Link timetable, including domestic and cross-border routes. Positions are estimates, not live GPS locations.","history":"","stats":[],"websiteUrl":"https://ltglink.lt","map":{"lat":54.6872,"lng":25.2797,"zoom":7},"vehicleClassificationOverride":"regional_rail","tripPlannerEnabled":false},{"name":"Ukrzaliznytsia â Ukraine National Rail","slug":"ukrzaliznytsia","metric":true,"cities":["kyiv"],"countries":["Ukraine"],"color":"#18567D","darkerColor":"#103B56","textColor":"#FFFFFF","shortForms":["Ukrzaliznytsia"],"summary":"Selected published long-distance Ukrzaliznytsia services; this feed does not cover every domestic or suburban train. Positions are estimates, not live GPS locations.","history":"","stats":[],"websiteUrl":"https://www.uz.gov.ua/","map":{"lat":50.45,"lng":30.52,"zoom":7},"vehicleClassificationOverride":"regional_rail","tripPlannerEnabled":false},{"name":"Srbijavoz â Serbia National Rail","slug":"srbijavoz","metric":true,"cities":["belgrade"],"countries":["Serbia"],"color":"#18567D","darkerColor":"#103B56","textColor":"#FFFFFF","shortForms":["Srbijavoz"],"summary":"Published Srbijavoz regional and intercity passenger services. Positions are estimates, not live GPS locations.","history":"","stats":[],"websiteUrl":"https://srbijavoz.rs","map":{"lat":44.8125,"lng":20.4612,"zoom":7},"vehicleClassificationOverride":"regional_rail","tripPlannerEnabled":false},{"name":"Trainkos â Kosovo Rail","slug":"trainkos","metric":true,"cities":["pristina"],"countries":["Kosovo"],"color":"#18567D","darkerColor":"#103B56","textColor":"#FFFFFF","shortForms":["Trainkos"],"summary":"Passenger services in the community transcription of the 2026 Trainkos timetable. Positions are estimates, not live GPS locations.","history":"","stats":[],"websiteUrl":"https://www.trainkos.com/","map":{"lat":42.6629,"lng":21.1655,"zoom":7},"vehicleClassificationOverride":"regional_rail","tripPlannerEnabled":false},{"name":"ŽRSM â North Macedonia Rail","slug":"mzi","metric":true,"cities":["skopje"],"countries":["North Macedonia"],"color":"#18567D","darkerColor":"#103B56","textColor":"#FFFFFF","shortForms":["ŽRSM"],"summary":"Passenger services in the community transcription of the 2025â2026 ŽRSM timetable. Positions are estimates, not live GPS locations.","history":"","stats":[],"websiteUrl":"https://mzt.mk/","map":{"lat":41.9981,"lng":21.4254,"zoom":7},"vehicleClassificationOverride":"regional_rail","tripPlannerEnabled":false},{"name":"BDZ â Bulgaria National Rail","slug":"bdz","metric":true,"cities":["sofia"],"countries":["Bulgaria"],"color":"#18567D","darkerColor":"#103B56","textColor":"#FFFFFF","shortForms":["BDZ"],"summary":"Bulgarian State Railways passenger services, with timetable estimates adjusted by live delays when available. Positions are estimates, not live GPS locations.","history":"","stats":[],"websiteUrl":"https://www.bdz.bg","map":{"lat":42.6977,"lng":23.3219,"zoom":7},"vehicleClassificationOverride":"regional_rail","tripPlannerEnabled":false},{"name":"Panama Canal Railway","slug":"panama-canal-railway","tripPlannerEnabled":false,"metric":true,"cities":["panama-city"],"countries":["Panama"],"color":"#0A3D62","darkerColor":"#062440","textColor":"#FFFFFF","summary":"Panama Canal Railway offers selected-date passenger excursions and charters between the Pacific and Atlantic coasts. A current dated timetable is not available in this app, so train position estimates are disabled. Freight movements are not covered.","websiteUrl":"https://www.panarail.com","gtfsEnabled":true,"map":{"lat":9.08,"lng":-79.7,"zoom":8},"vehicleClassificationOverride":"intercity_rail"},{"name":"S\xe3o Paulo Metro","slug":"sao-paulo-metro","metric":true,"cities":["sao-paulo"],"countries":["Brazil"],"color":"#0455A1","darkerColor":"#033767","textColor":"#FFFFFF","shortForms":["Metr\xf4","Metro SP"],"summary":"S\xe3o Paulo metro and monorail services, including concession-operated lines. Positions are estimates from SPTrans schedules.","history":"","stats":[],"websiteUrl":"https://www.metro.sp.gov.br","map":{"lat":-23.5505,"lng":-46.6333,"zoom":10},"vehicleClassificationOverride":"subway"},{"name":"S\xe3o Paulo Metropolitan Trains","slug":"sao-paulo-rail","metric":true,"cities":["sao-paulo"],"countries":["Brazil"],"color":"#CA016B","darkerColor":"#820044","textColor":"#FFFFFF","shortForms":["CPTM","ViaMobilidade","TIC Trens","Trivia"],"summary":"S\xe3o Paulo suburban rail lines 7â13, including CPTM and concession-operated services. Positions are estimates from SPTrans schedules.","history":"","stats":[],"websiteUrl":"https://www.cptm.sp.gov.br","map":{"lat":-23.5505,"lng":-46.6333,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"TrensRJ","slug":"trensrj","metric":true,"cities":["rio-de-janeiro"],"countries":["Brazil"],"color":"#0077B6","darkerColor":"#004D75","textColor":"#FFFFFF","shortForms":["TrensRJ","SuperVia"],"summary":"Rio de Janeiro suburban trains, formerly SuperVia. Schedule-based positions use a community reconstruction of published timetables; intermediate times are estimated.","history":"","stats":[],"websiteUrl":"https://www.trensrj.c
16om.br","map":{"lat":-22.9068,"lng":-43.1729,"zoom":10},"vehicleClassificationOverride":"commuter_rail","tripPlannerEnabled":false},{"name":"Metr\xf4Rio","slug":"metrorio","metric":true,"cities":["rio-de-janeiro"],"countries":["Brazil"],"color":"#E77405","darkerColor":"#934B03","textColor":"#FFFFFF","shortForms":["Metr\xf4Rio"],"summary":"Rio metro lines 1/4 and weekday line 2. Positions use estimated frequencies and journey times within published operating hours, not a live or published departure timetable.","history":"","stats":[],"websiteUrl":"https://www.metrorio.com.br","map":{"lat":-22.95,"lng":-43.27,"zoom":11},"vehicleClassificationOverride":"subway","tripPlannerEnabled":false},{"name":"Las Vegas Monorail","slug":"las-vegas-monorail","metric":false,"cities":["las-vegas"],"countries":["United States"],"color":"#133D8C","darkerColor":"#0B2454","textColor":"#FFFFFF","shortForms":["Las Vegas Monorail","LV Monorail"],"summary":"Seven stations between MGM Grand and SAHARA Las Vegas. Map positions are estimates based on published operating hours and ride times, with a six-minute modelled headway; no live train tracking.","history":"","stats":[],"websiteUrl":"https://www.lvmonorail.com","map":{"lat":36.129,"lng":-115.153,"zoom":13},"vehicleClassificationOverride":"monorail","tripPlannerEnabled":false},{"name":"Trenitalia France","slug":"trenitalia-france","metric":true,"cities":["paris","milan"],"countries":["France","Italy"],"color":"#C41230","darkerColor":"#C41230","textColor":"#FFFFFF","shortForms":["Trenitalia France","Frecciarossa"],"summary":"Frecciarossa services connecting Paris, Lyon, Marseille, Turin and Milan, with estimated positions based on live arrival predictions.","websiteUrl":"https://www.trenitalia.com/","gtfsEnabled":true,"map":{"lat":46,"lng":5.7,"zoom":6},"vehicleClassificationOverride":"intercity_rail"},{"name":"FGC","slug":"fgc","metric":true,"cities":["barcelona"],"countries":["Spain"],"color":"#E60028","darkerColor":"#E60028","textColor":"#FFFFFF","shortForms":["FGC","Ferrocarrils de la Generalitat de Catalunya"],"summary":"Ferrocarrils de la Generalitat de Catalunya operates Barcelona suburban and metro services, the LleidaâLa Pobla line and mountain railways. Live tracking is available for vehicles published in its open data feed.","websiteUrl":"https://www.fgc.cat/","gtfsEnabled":true,"map":{"lat":41.57,"lng":1.91,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"ZOU! Interm\xe9tropole","slug":"zou-transdev","metric":true,"cities":[],"countries":["France"],"color":"#E65014","darkerColor":"#E65014","textColor":"#FFFFFF","shortForms":["ZOU","ZOU!","Transdev Rail Sud Interm\xe9tropole"],"summary":"Transdev operates ZOU! trains between Marseille and Nice. Positions are estimated from live arrival predictions; SNCF-operated ZOU! TER services appear under SNCF.","websiteUrl":"https://zou.maregionsud.fr/","gtfsEnabled":true,"map":{"lat":43.4,"lng":6.25,"zoom":8},"vehicleClassificationOverride":"commuter_rail"},{"name":"Euskotren Trena","slug":"euskotren","metric":true,"cities":[],"countries":["Spain"],"color":"#005CA9","darkerColor":"#005CA9","textColor":"#FFFFFF","shortForms":["Euskotren","Euskotren Trena"],"summary":"Euskotrenâs metre-gauge passenger trains connect Bilbao, San Sebasti\xe1n and the Basque Country, with estimated positions based on live arrival predictions.","websiteUrl":"https://www.euskotren.eus/","gtfsEnabled":true,"map":{"lat":43.2,"lng":-2.4,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"SNCF Transilien / RER","slug":"transilien","metric":true,"cities":["paris"],"countries":["France"],"color":"#0088CE","darkerColor":"#0088CE","textColor":"#FFFFFF","shortForms":["Transilien","RER"],"summary":"SNCF Transilien and RER services in \xcele-de-France, with estimated train positions based on published timetables.","websiteUrl":"https://www.transilien.com/","gtfsEnabled":true,"map":{"lat":48.8566,"lng":2.3522,"zoom":9},"vehicleClassificationOverride":"commuter_rail"},{"name":"DSB","slug":"dsb","metric":true,"cities":[],"countries":["Denmark"],"color":"#C8102E","darkerColor":"#960C22","textColor":"#FFFFFF","shortForms":["DSB","Danske Statsbaner","S-tog","DSB Vores Tog"],"summary":"DSB rail services across Denmark, including InterCity, regional trains, Copenhagen S-trains, and DSB Vores Tog. Map positions are estimated from Rejseplanen timetables.","history":"","stats":[],"websiteUrl":"https://www.dsb.dk","map":{"lat":56,"lng":10,"zoom":7},"tripPlannerEnabled":true},{"name":"Tilt Train","slug":"tilt-train","metric":true,"cities":["brisbane"],"countries":["Australia"],"color":"#8B1E41","darkerColor":"#651530","textColor":"#FFFFFF","shortForms":["Queensland Rail Tilt Train","Rockh
16ampton Tilt Train","Bundaberg Tilt Train"],"summary":"Queensland Rail Travelâs Tilt Train connects Brisbane with Bundaberg and Rockhampton. Map positions are estimated from the operatorâs published service times and delay updates.","history":"","stats":[],"websiteUrl":"https://www.queenslandrailtravel.com.au/Pages/TiltTrain.aspx","map":{"lat":-25.4,"lng":152,"zoom":6},"vehicleClassificationOverride":"intercity_rail","tripPlannerEnabled":false},{"name":"AFE Tacuaremb\xf3âRivera","slug":"afe-uruguay","metric":true,"cities":[],"countries":["Uruguay"],"color":"#005CA9","darkerColor":"#002E54","textColor":"#FFFFFF","shortForms":["AFE Tacuaremb\xf3âRivera"],"summary":"Tacuaremb\xf3âRivera passenger trains on Mondays and Fridays. Positions are estimated from the published timetable. Untimed conditional stops are not shown.","history":"","stats":[],"websiteUrl":"https://www.afe.com.uy","map":{"lat":-31.3,"lng":-55.8,"zoom":9},"vehicleClassificationOverride":"commuter_rail","tripPlannerEnabled":false},{"name":"Armenian Railway","slug":"armenian-railway","metric":true,"cities":[],"countries":["Armenia","Georgia"],"color":"#B52D35","darkerColor":"#872129","textColor":"#FFFFFF","shortForms":["SCR","South Caucasus Railway","ÕÔ¿Ôµ","ЮÐÐÐ"],"summary":"South Caucasus Railway passenger services in Armenia, including seasonal and international trains to Georgia.","history":"Community-maintained GTFS from published South Caucasus Railway schedules (ODbL 1.0). Go preserves service dates and builds geometry from Armenian and Georgian OpenStreetMap tracks. Positions are timetable estimates.","stats":[],"websiteUrl":"https://www.railway.am/en/index","gtfsEnabled":false,"map":{"lat":40.5,"lng":44.55,"zoom":7},"vehicleClassificationOverride":"commuter_rail"},{"name":"CFL â Luxembourg Rail","slug":"cfl","metric":true,"cities":[],"countries":["Luxembourg"],"color":"#BE1622","darkerColor":"#BE1622","textColor":"#FFFFFF","shortForms":["CFL"],"summary":"CFL passenger trains across Luxembourg and the cross-border services included in the national ATP timetable.","history":"Official Administration des transports publics GTFS, licensed CC BY 4.0. Positions are timetable estimates using the original service calendars. Replacement buses are excluded.","stats":[],"websiteUrl":"https://www.cfl.lu/","gtfsEnabled":false,"map":{"lat":49.76,"lng":6.1,"zoom":8},"vehicleClassificationOverride":"commuter_rail"},{"name":"Mi Tren Cochabamba","slug":"cochabamba-mi-tren","metric":true,"cities":["cochabamba"],"countries":["Bolivia"],"color":"#00843D","darkerColor":"#00421E","textColor":"#FFFFFF","shortForms":["Mi Tren Cochabamba"],"summary":"Cochabamba red, green and yellow light rail lines. Positions use a reviewed community reconstruction of service hours and frequencies; intermediate times are estimated.","history":"","stats":[],"websiteUrl":"https://www.oopp.gob.bo","map":{"lat":-17.4,"lng":-66.2,"zoom":12},"vehicleClassificationOverride":"light_rail","tripPlannerEnabled":false},{"name":"Tranv\xeda de Cuenca","slug":"cuenca-tram","metric":true,"cities":["cuenca"],"countries":["Ecuador"],"color":"#CC2233","darkerColor":"#661119","textColor":"#FFFFFF","shortForms":["Tranv\xeda de Cuenca"],"summary":"Cuenca tram between R\xedo Tarqui and Parque Industrial. Positions use estimated frequencies and journey times within published operating hours.","history":"","stats":[],"websiteUrl":"https://tranvia.cuenca.gob.ec","map":{"lat":-2.9,"lng":-79,"zoom":12},"vehicleClassificationOverride":"light_rail","tripPlannerEnabled":false},{"name":"Dakar TER","slug":"dakar-ter","metric":true,"cities":["dakar"],"countries":["Senegal"],"color":"#991536","darkerColor":"#651025","textColor":"#FFFFFF","shortForms":["TER Dakar","Train Express R\xe9gional"],"summary":"Regional trains between Dakar and Diamniadio, serving 13 stations. Map positions are estimated from the operatorâs published timetable, including Sunday and holiday service. The airport extension is not included.","history":"","stats":[],"websiteUrl":"https://www.terdakar.sn","map":{"lat":14.727,"lng":-17.32,"zoom":11},"vehicleClassificationOverride":"commuter_rail","tripPlannerEnabled":false},{"name":"Fertagus","slug":"fertagus","metric":true,"cities":[],"countries":["Portugal"],"color":"#C74F4F","darkerColor":"#9B3636","textColor":"#FFFFFF","shortForms":["Fertagus"],"summary":"Fertagus passenger rail services linking Lisbon with Coina and Set\xfabal across the 25 de Abril Bridge.","history":"Schedules and route geometry come from the official Fertagus GTFS feed. The original service calendars and holiday exceptions are retained. Map positions are timetable estimates, not GPS observations.","stats":[],"websiteUrl":"https://www.fertagus.pt/","gtfsEnabled":false,"map":{"lat":38.63,"lng":-9.1,"zoom":10},"vehicleClassificationOverride":"commuter_rail"},{"name":"Georgian Railway","slug":"georgian-railway","metric":true,"cities":[],"countries":["Georgia"],"color":"#C8202B","darkerColor":"#9B1720","textColor":"#FFFFFF","shortForms":["GR","á¡áá¥áá áááááá¡ á ááááááá"],"summary":"Georgian Railway passenger services included in the maintained community timetable, covering intercity and regional trains.","history":"Uses the community GTFS published by Jonah Br\xfcchert from Georgian Railway schedules, with OpenStreetMap-derived geometry (ODbL 1.0). Original service dates are retained. Positions are timetable estimates; full operator completeness and international overlap still require verification.","stats":[],"websiteUrl":"https://www.railway.ge/en/","gtfsEnabled":false,"map":{"lat":42.08,"lng":43.6,"zoom":7},"vehicleClassificationOverride":"commuter_rail"},{"name":"INCOFER","slug":"incofer","metric":true,"cities":["san-jose-costa-rica"],"countries":["Costa Rica"],"color":"#002B7F","darkerColor":"#001b50","textColor":"#FFFFFF","shortForms":["Tren Costa Rica"],"summary":"Commuter rail serving San Jos\xe9, Heredia, Alajuela, Cartago and Bel\xe9n. Positions are estimates from the SIMOVI/UCR published timetable.","history":"","stats":[],"websiteUrl":"https://www.incofer.go.cr","map":{"lat":9.96,"lng":-84.09,"zoom":10},"vehicleClassificationOverride":"commuter_rail","tripPlannerEnabled":false},{"name":"Kenya Railways","slug":"kenya-railways","metric":true,"cities":["nairobi","mombasa"],"countries":["Kenya"],"color":"#8A2024","dar
16kerColor":"#591518","textColor":"#FFFFFF","shortForms":["Madaraka Express","Kenya SGR"],"summary":"Madaraka Express inter-county, afternoon and overnight trains between Nairobi and Mombasa, plus FridayâSunday trains to Suswa. Positions are estimates from the published 2026 timetable, not live tracking. Commuter and other metre-gauge services are not yet included.","history":"","stats":[],"websiteUrl":"https://krc.co.ke/madaraka-express-passenger-service/","map":{"lat":-2.5,"lng":38,"zoom":7},"vehicleClassificationOverride":"intercity_rail","tripPlannerEnabled":false},{"name":"Metro de Lima","slug":"lima-metro","metric":true,"cities":["lima"],"countries":["Peru"],"color":"#228B22","darkerColor":"#114511","textColor":"#FFFFFF","shortForms":["Metro de Lima"],"summary":"Lima Metro Line 1 and the five operating Line 2 stations. Map positions use estimated frequencies and journey times, not live tracking.","history":"","stats":[],"websiteUrl":"https://www.lineauno.pe","map":{"lat":-12.08,"lng":-77,"zoom":12},"vehicleClassificationOverride":"subway","tripPlannerEnabled":false},{"name":"Luxtram","slug":"luxtram","metric":true,"cities":[],"countries":["Luxembourg"],"color":"#782B90","darkerColor":"#782B90","textColor":"#FFFFFF","shortForms":["Luxtram"],"summary":"Luxembourg City tram services from the national ATP timetable.","history":"Official Administration des transports publics GTFS, licensed CC BY 4.0. Positions are timetable estimates using the original service calendars.","stats":[],"websiteUrl":"https://www.luxtram.lu/","gtfsEnabled":false,"map":{"lat":49.62,"lng":6.14,"zoom":11},"vehicleClassificationOverride":"light_rail"},{"name":"Metro de Panam\xe1","slug":"panama-metro","metric":true,"cities":["panama-city"],"countries":["Panama"],"color":"#E31B23","darkerColor":"#961117","textColor":"#FFFFFF","shortForms":["Metro Panam\xe1"],"summary":"Lines 1 and 2, including Villa Zaita and the Tocumen airport shuttle. Positions are modelled estimates using published operating parameters, not live tracking. Holiday variations are not included.","history":"","stats":[],"websiteUrl":"https://elmetrodepanama.com","map":{"lat":9.05,"lng":-79.47,"zoom":11},"vehicleClassificationOverride":"subway","tripPlannerEnabled":false},{"name":"PosadasâEncarnaci\xf3n","slug":"posadas-encarnacion","metric":true,"cities":[],"countries":["Argentina","Paraguay"],"color":"#0072CE","darkerColor":"#003967","textColor":"#FFFFFF","shortForms":["PosadasâEncarnaci\xf3n"],"summary":"International passenger shuttle between Argentina and Paraguay. Positions are estimates from the published MondayâSaturday timetable.","history":"","stats":[],"websiteUrl":"https://www.argentina.gob.ar/transporte/trenes-argentinos","map":{"lat":-27.37,"lng":-55.865,"zoom":9},"vehicleClassificationOverride":"commuter_rail","tripPlannerEnabled":false},{"name":"Metro de Quito","slug":"quito-metro","metric":true,"cities":["quito"],"countries":["Ecuador"],"color":"#E31D1B","darkerColor":"#710E0D","textColor":"#FFFFFF","shortForms":["Metro de Quito"],"summary":"Quito Metro Line 1. Positions are estimates based on published operating hours, frequencies and journey time.","history":"","stats":[],"websiteUrl":"https://metrodequito.gob.ec","map":{"lat":-0.22,"lng":-78.5,"zoom":12},"vehicleClassificationOverride":"subway","tripPlannerEnabled":false},{"name":"SŽ â Slovenia Rail","slug":"slovenia-rail","metric":true,"cities":[],"countries":["Slovenia"],"color":"#005A9C","darkerColor":"#005A9C","textColor":"#FFFFFF","shortForms":["SŽ"],"summary":"Slovenian Railways passenger trains included in the national IJPP timetable.","history":"Uses the community-maintained derp-si IJPP GTFS conversion of Slovenian public transport data (CC BY-SA 4.0). The import retains SŽ rail services and excludes buses, including replacement buses. Positions are timetable estimates with unchanged service calendars.","stats":[],"websiteUrl":"https://potniski.sz.si/","gtfsEnabled":false,"map":{"lat":46.13,"lng":14.82,"zoom":7},"vehicleClassificationOverride":"commuter_rail"},{"name":"Tren Urbano","slug":"tren-urbano","metric":true,"cities":["san-juan"],"countries":["Puerto Rico"],"color":"#c03230","darkerColor":"#80211f","textColor":"#FFFFFF","shortForms":["TU"],"summary":"San Juan metropolitan rail between Bayam\xf3n and Sagrado Coraz\xf3n. Positions are estimates from ATI schedules. This independent app is not affiliated with or sponsored by ATI.","history":"","stats":[],"websiteUrl":"https://www.ati.pr.gov","map":{"lat":18.41,"lng":-66.102,"zoom":12},"vehicleClassificationOverride":"subway","tripPlannerEnabled":false},{"name":"ŽPCG â Montenegro Rail","slug":"zpcg","metric":true,"cities":[],"countries":["Montenegro"],"color":"#00549E","darkerColor":"#00549E","textColor":"#FFFFFF","shortForms":["ŽPCG"],"summary":"Montenegro passenger trains, including BarâPodgoricaâBijelo Polje, PodgoricaâNikÅ¡iÄ, and international services present in the source.","history":"Uses a community GTFS transcription hosted by Jonah Br\xfcchert, listed by Transitous under ODbL 1.0. This is not an official live-position feed. Original service calendars are preserved; positions are timetable estimates.","stats":[],"websiteUrl":"https://zpcg.me/","gtfsEnabled":false,"map":{"lat":42.73,"lng":19.29,"zoom":8},"vehicleClassificationOverride":"commuter_rail"},{"name":"Metro de Santo Domingo","slug":"santo-domingo-metro","metric":true,"cities":["santo-domingo"],"countries":["Dominican Republic"],"color":"#0056A6","darkerColor":"#00396E","textColor":"#FFFFFF","shortForms":["Metro SD"],"summary":"Lines 1 and 2, including the Los Alcarrizos extension. Positions are modelled estimates using published journey times and historical peak intervals, with assumed off-peak frequencies. Holiday variations are not included.","history":"","stats":[],"websiteUrl":"https://www.opret.gob.do","map":{"lat":18.495,"lng":-69.935,"zoom":11},"vehicleClassificationOverride":"subway","tripPlannerEnabled":false},{"name":"Metro de Maracaibo","slug":"maracaibo-metro","metric":true,"cities":["maracaibo"],"countries":["Venezuela"],"color":"#F5A623","darkerColor":"#A36808","textColor":"#000000","shortForms":["MetroMara"],"summary":"Line 1 between Altos de La Vanega and Libertador. Positions are estimates from a community timetable; actual service may vary. Datos provistos por Crom Studio y la comunidad de Open Transit Venezuela (CC BY 4.0).","history":"","stats":[],"websiteUrl":"https://transporte.cromstudio.com.ve/","map":{"lat":10.628,"lng":-71.645,"zoom":13},"vehicleClassificationOverride":"subway","tripPlannerEnabled":false},{"name":"Tunis RFR â Line E","slug":"tunis-rfr","metric":true,"cities":["tunis"],"countries":["Tunisia"],"color":"#4A9A42","dar
16kerColor":"#286522","textColor":"#FFFFFF","shortForms":["SNCFT RFR","Tunis Bougatfa","RFR E"],"summary":"Tunis RFR Line E connects Tunis and Bougatfa through seven stations. Map positions are estimated from SNCFTâs published winter timetable, including Sunday and holiday service.","history":"","stats":[],"websiteUrl":"https://www.sncft.com.tn/voyageurs/banlieue-tunis/","map":{"lat":36.788,"lng":10.14,"zoom":12},"vehicleClassificationOverride":"commuter_rail","tripPlannerEnabled":false},{"name":"Metro do Porto","slug":"metro-porto","metric":true,"cities":[],"countries":["Portugal"],"color":"#199FDA","darkerColor":"#1377A3","textColor":"#FFFFFF","shortForms":["Metro do Porto"],"summary":"Porto Metro services on lines AâF, including the B express service.","history":"Official Metro do Porto GTFS schedules retain their service dates and holiday exceptions. Go generates detailed track geometry from OpenStreetMap. Map positions are timetable estimates.","stats":[],"websiteUrl":"https://www.metrodoporto.pt/","gtfsEnabled":false,"map":{"lat":41.19,"lng":-8.65,"zoom":11},"vehicleClassificationOverride":"light_rail"},{"name":"NRC LagosâIbadan","slug":"nigeria-lagos-ibadan","metric":true,"cities":["lagos","ibadan"],"countries":["Nigeria"],"color":"#008751","darkerColor":"#005C37","textColor":"#FFFFFF","shortForms":["NRC","LITS","Lagos Ibadan Railway"],"summary":"Nigerian Railway Corporation trains connect Lagos, Abeokuta and Ibadan through nine stations. Map positions are estimated from the published booking timetable, including additional ThursdayâSaturday services.","history":"","stats":[],"websiteUrl":"https://nrc.gsds.ng/timetable","map":{"lat":7.03,"lng":3.55,"zoom":8},"vehicleClassificationOverride":"intercity","tripPlannerEnabled":false},{"name":"STIB-MIVB","slug":"stib-mivb","metric":true,"cities":["brussels"],"countries":["Belgium"],"color":"#005CA9","darkerColor":"#005CA9","textColor":"#FFFFFF","shortForms":["STIB-MIVB"],"summary":"Brussels metro and tram services.","history":"Rail services use official schedules and source geometry, with original service dates retained. Source: STIB-MIVB â Open Data â 2026-09-14 (initial validated dataset), CC BY 4.0. Map positions are timetable estimates.","stats":[],"websiteUrl":"https://www.stib-mivb.be/","gtfsEnabled":false,"map":{"lat":50.85,"lng":4.35,"zoom":11}},{"name":"De Lijn Trams","slug":"de-lijn","metric":true,"cities":[],"countries":["Belgium"],"color":"#FFCB05","darkerColor":"#FFCB05","textColor":"#000000","shortForms":["De Lijn Trams"],"summary":"Trams in Antwerp and Ghent and the Belgian coast tram.","history":"Rail services use official schedules and source geometry, with original service dates retained. Source: De Lijn â Open Data â 2026-09-14 (initial validated dataset), CC BY 4.0. Map positions are timetable estimates.","stats":[],"websiteUrl":"https://www.delijn.be/","gtfsEnabled":false,"map":{"lat":51.08,"lng":3.8,"zoom":8},"vehicleClassificationOverride":"light_rail"},{"name":"LETEC Rail","slug":"tec-rail","metric":true,"cities":[],"countries":["Belgium"],"color":"#FFCD00","darkerColor":"#FFCD00","textColor":"#000000","shortForms":["LETEC Rail"],"summary":"Charleroi metro and Li\xe8ge tram services.","history":"Rail services use official schedules and source geometry, with original service dates retained. Source: LETEC â Open Data â 2026-09-11 (initial validated dataset), CC BY 4.0. Map positions are timetable estimates.","stats":[],"websiteUrl":"https://www.letec.be/","gtfsEnabled":false,"map":{"lat":50.5,"lng":4.95,"zoom":8}},{"name":"Metropolitano de Lisboa","slug":"metro-lisboa","metric":true,"cities":["lisbon"],"countries":["Portugal"],"color":"#E30613","darkerColor":"#AA050E","textColor":"#FFFFFF","shortForms":["Metro Lisboa"],"summary":"Lisbon Metro services on the Azul, Amarela, Verde and Vermelha lines.","history":"Official Metropolitano de Lisboa GTFS schedules retain their service dates and exceptions. Go generates detailed track geometry from OpenStreetMap. Map positions are timetable estimates.","stats":[],"websiteUrl":"https://www.metrolisboa.pt/","gtfsEnabled":false,"map":{"lat":38.757,"lng":-9.15,"zoom":12},"vehicleClassificationOverride":"subway"},{"name":"Haramain High-Speed Railway","slug":"haramain-hsr","tripPlannerEnabled":false,"metric":true,"cities":["makkah","jeddah","madinah"],"countries":["Saudi Arabia"],"color":"#8A6D3B","darkerColor":"#5C4826","textColor":"#FFFFFF","shortForms":["HHR"],"summary":"SAR\'s Haramain High-Speed Railway connecting Makkah, Jeddah, KAEC and Madinah. No official GTFS/GTFS-RT feed exists; positions are estimates from a scraped public timetable, not live GPS.","history":"","stats":[],"websiteUrl":"https://sar.hhr.sa","gtfsEnabled":true,"map":{"lat":22,"lng":39.4,"zoom":7},"vehicleClassificationOverride":"intercity_rail"}]');class n{constructor(e){this.name=e.name,this.slug=e.slug,this.metric=e.metric,this.cities=[...e.cities],this.countries=e.countries?[...e.countries]:[],this.color=e.color,this.darkerColor=e.darkerColor,this.textColor=e.textColor,this.shortForms=e.shortForms?[...e.shortForms]:[],this.summary=e.summary,this.history=e.history,this.stats=e.stats?[...e.stats]:[],this.websiteUrl=e.websiteUrl,this.map={...e.map},this.vehicleClassificationOverride=e.vehicleClassificationOverride}toJSON(){return{name:this.name??null,slug:this.slug??null,metric:this.metric??null,cities:[...this.cities],countries:[...this.countries],color:this.color??null,darkerColor:this.darkerColor??null,textColor:this.textColor??null,shortForms:[...this.shortForms],summary:this.summary??null,history:this.history??null,stats:[...this.stats],websiteUrl:this.websiteUrl??null,map:{...this.map},vehicleClassificationOverride:this.vehicleClassificationOverride??null}}getSpeedUnit(){return this.metric?"kph":"mph"}convertSpeed(e,t){return t===this.metric?e:t?.621371*e:1.60934*e}}
16class a{constructor(){this.networks=new Map,i.forEach(e=>{this.networks.set(e.slug,new n(e))})}static getInstance(){return a._instance||(a._instance=new a),a._instance}getNetwork(e){return this.networks.get(e)}getAllNetworks(){return Array.from(this.networks.values())}getNetworksByCity(e){return this.getAllNetworks().filter(t=>t.cities.includes(e))}getNetworksByCountryName(e){return this.getAllNetworks().filter(t=>t.countries.includes(e))}}let s=a.getInstance()},76653:(e,t,r)=>{"use strict";r.d(t,{cY:()=>y,FA:()=>N,g:()=>L,u:()=>c,Uj:()=>u,Fy:()=>b,tD:()=>G,bD:()=>function e(t,r){if(t===r)return!0;let i=Object.keys(t),n=Object.keys(r);for(let a of i){if(!n.includes(a))return!1;let i=t[a],s=r[a];if(U(i)&&U(s)){if(!e(i,s))return!1}else if(i!==s)return!1}for(let e of n)if(!i.includes(e))return!1;return!0},hp:()=>j,T9:()=>p,Tj:()=>m,yU:()=>g,XA:()=>f,mS:()=>h,Ku:()=>q,ZQ:()=>F,sr:()=>_,zJ:()=>v,c1:()=>A,Im:()=>z,lT:()=>I,zW:()=>M,jZ:()=>k,lV:()=>R,nr:()=>x,Ov:()=>O,gE:()=>w,Am:()=>B,I9:()=>V,P1:()=>S,eX:()=>P});var i=r(65364);let n=function(e){let t=[],r=0;for(let i=0;i<e.length;i++){let n=e.charCodeAt(i);n<128?t[r++]=n:(n<2048?t[r++]=n>>6|192:((64512&n)==55296&&i+1<e.length&&(64512&e.charCodeAt(i+1))==56320?(n=65536+((1023&n)<<10)+(1023&e.charCodeAt(++i)),t[r++]=n>>18|240,t[r++]=n>>12&63|128):t[r++]=n>>12|224,t[r++]=n>>6&63|128),t[r++]=63&n|128)}return t},a=function(e){let t=[],r=0,i=0;for(;r<e.length;){let n=e[r++];if(n<128)t[i++]=String.fromCharCode(n);else if(n>191&&n<224){let a=e[r++];t[i++]=String.fromCharCode((31&n)<<6|63&a)}else if(n>239&&n<365){let a=((7&n)<<18|(63&e[r++])<<12|(63&e[r++])<<6|63&e[r++])-65536;t[i++]=String.fromCharCode(55296+(a>>10)),t[i++]=String.fromCharCode(56320+(1023&a))}else{let a=e[r++],s=e[r++];t[i++]=String.fromCharCode((15&n)<<12|(63&a)<<6|63&s)}}return t.join("")},s={byteToCharMap_:null,charToByteMap_:null,byteToCharMapWebSafe_:null,charToByteMapWebSafe_:null,ENCODED_VALS_BASE:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",get ENCODED_VALS(){return this.ENCODED_VALS_BASE+"+/="},get ENCODED_VALS_WEBSAFE(){return this.ENCODED_VALS_BASE+"-_."},HAS_NATIVE_SUPPORT:"function"==typeof atob,encodeByteArray(e,t){if(!Array.isArray(e))throw Error("encodeByteArray takes an array as a parameter");this.init_();let r=t?this.byteToCharMapWebSafe_:this.byteToCharMap_,i=[];for(let t=0;t<e.length;t+=3){let n=e[t],a=t+1<e.length,s=a?e[t+1]:0,o=t+2<e.length,l=o?e[t+2]:0,u=n>>2,c=(3&n)<<4|s>>4,h=(15&s)<<2|l>>6,d=63&l;!o&&(d=64,a||(h=64)),i.push(r[u],r[c],r[h],r[d])}return i.join("")},encodeString(e,t){return this.HAS_NATIVE_SUPPORT&&!t?btoa(e):this.encodeByteArray(n(e),t)},decodeString(e,t){return this.HAS_NATIVE_SUPPORT&&!t?atob(e):a(this.decodeStringToByteArray(e,t))},decodeStringToByteArray(e,t){this.init_();let r=t?this.charToByteMapWebSafe_:this.charToByteMap_,i=[];for(let t=0;t<e.length;){let n=r[e.charAt(t++)],a=t<e.length?r[e.charAt(t)]:0,s=++t<e.length?r[e.charAt(t)]:64,l=++t<e.length?r[e.charAt(t)]:64;if(++t,null==n||null==a||null==s||null==l)throw new o;let u=n<<2|a>>4;if(i.push(u),64!==s){let e=a<<4&240|s>>2;if(i.push(e),64!==l){let e=s<<6&192|l;i.push(e)}}}return i},init_(){if(!this.byteToCharMap_){this.byteToCharMap_={},this.charToByteMap_={},this.byteToCharMapWebSafe_={},this.charToByteMapWebSafe_={};for(let e=0;e<this.ENCODED_VALS.length;e++)this.byteToCharMap_[e]=this.ENCODED_VALS.charAt(e),this.charToByteMap_[this.byteToCharMap_[e]]=e,this.byteToCharMapWebSafe_[e]=this.ENCODED_VALS_WEBSAFE.charAt(e),this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[e]]=e,e>=this.ENCODED_VALS_BASE.length&&(this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(e)]=e,this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(e)]=e)}}};class o extends Error{constructor(){super(...arguments),this.name="DecodeBase64StringError"}}let l=function(e){let t=n(e);return s.encodeByteArray(t,!0)},u=function(e){return l(e).replace(/\./g,"")},c=function(e){try{return s.decodeString(e,!0)}catch(e){console.error("base64Decode failed: ",e)}return null};function h(){if("u">typeof self)return self;if("u">typeof window)return window;if(void 0!==r.g)return r.g;throw Error("Unable to locate global object.")}let d=()=>{try{return h().__FIREBASE_DEFAULTS__||(()=>{if(void 0===i||void 0===i.env)return;let e=i.env.__FIREBASE_DEFAULTS__;if(e)return JSON.parse(e)})()||(()=>{let e;if("u"<typeof document)return;try{e=document.cookie.match(/__FIREBASE_DEFAULTS__=([^;
16]+)/)}catch(e){return}let t=e&&c(e[1]);return t&&JSON.parse(t)})()}catch(e){console.info(`Unable to get __FIREBASE_DEFAULTS__ due to: ${e}`);return}},m=e=>d()?.emulatorHosts?.[e],g=e=>{let t=m(e);if(!t)return;let r=t.lastIndexOf(":");if(r<=0||r+1===t.length)throw Error(`Invalid host ${t} with no separate hostname and port!`);let i=parseInt(t.substring(r+1),10);return"["===t[0]?[t.substring(1,r-1),i]:[t.substring(0,r),i]},p=()=>d()?.config,f=e=>d()?.[`_${e}`];class y{constructor(){this.reject=()=>{},this.resolve=()=>{},this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}wrapCallback(e){return(t,r)=>{t?this.reject(t):this.resolve(r),"function"==typeof e&&(this.promise.catch(()=>{}),1===e.length?e(t):e(t,r))}}}function v(e){try{return(e.startsWith("http://")||e.startsWith("https://")?new URL(e).hostname:e).endsWith(".cloudworkstations.dev")}catch{return!1}}async function w(e){return(await fetch(e,{credentials:"include"})).ok}function b(e,t){if(e.uid)throw Error('The "uid" field is no longer supported by mockUserToken. Please use "sub" instead for Firebase Auth User ID.');let r=t||"demo-project",i=e.iat||0,n=e.sub||e.user_id;if(!n)throw Error("mockUserToken must contain 'sub' or 'user_id' field!");let a={iss:`https://securetoken.google.com/${r}`,aud:r,iat:i,exp:i+3600,auth_time:i,sub:n,user_id:n,firebase:{sign_in_provider:"custom",identities:{}},...e};return[u(JSON.stringify({alg:"none",type:"JWT"})),u(JSON.stringify(a)),""].join(".")}let C={},T=!1;function S(e,t){if("u"<typeof window||"u"<typeof document||!v(window.location.host)||C[e]===t||C[e]||T)return;function r(e){return`__firebase__banner__${e}`}C[e]=t;let i="__firebase__banner",n=function(){let e={prod:[],emulator:[]};for(let t of Object.keys(C))C[t]?e.emulator.push(t):e.prod.push(t);return e}().prod.length>0;function a(){let e,t,a=(e=document.getElementById(i),t=!1,e||((e=document.createElement("div")).setAttribute("id",i),t=!0),{created:t,element:e}),s=r("text"),o=document.getElementById(s)||document.createElement("span"),l=r("learnmore"),u=document.getElementById(l)||document.createElement("a"),c=r("preprendIcon"),h=document.getElementById(c)||document.createElementNS("http://www.w3.org/2000/svg","svg");if(a.created){let e,t=a.element;t.style.display="flex",t.style.background="#7faaf0",t.style.position="fixed",t.style.bottom="5px",t.style.left="5px",t.style.padding=".5em",t.style.borderRadius="5px",t.style.alignItems="center",u.setAttribute("id",l),u.innerText="Learn more",u.href="https://firebase.google.com/docs/studio/preview-apps#preview-backend",u.setAttribute("target","__blank"),u.style.paddingLeft="5px",u.style.textDecoration="underline";let r=((e=document.createElement("span")).style.cursor="pointer",e.style.marginLeft="16px",e.style.fontSize="24px",e.innerHTML=" ×",e.onclick=()=>{let e;T=!0,(e=document.getElementById(i))&&e.remove()},e);h.setAttribute("width","24"),h.setAttribute("id",c),h.setAttribute("height","24"),h.setAttribute("viewBox","0 0 24 24"),h.setAttribute("fill","none"),h.style.marginLeft="-6px",t.append(h,o,u,r),document.body.appendChild(t)}n?(o.innerText="Preview backend disconnected.",h.innerHTML=`<g clip-path="url(#clip0_6013_33858)"> 17<path d="M4.8 17.6L12 5.6L19.2 17.6H4.8ZM6.91667 16.4H17.0833L12 7.93333L6.91667 16.4ZM12 15.6C12.1667 15.6 12.3056 15.5444 12.4167 15.4333C12.5389 15.3111 12.6 15.1667 12.6 15C12.6 14.8333 12.5389 14.6944 12.4167 14.5833C12.3056 14.4611 12.1667 14.4 12 14.4C11.8333 14.4 11.6889 14.4611 11.5667 14.5833C11.4556 14.6944 11.4 14.8333 11.4 15C11.4 15.1667 11.4556 15.3111 11.5667 15.4333C11.6889 15.5444 11.8333 15.6 12 15.6ZM11.4 13.6H12.6V10.4H11.4V13.6Z" fill="#212121"/> 18</g> 19<defs> 20<clipPath id="clip0_6013_33858"> 21<rect width="24" height="24" fill="white"/> 22</clipPath> 23</defs>`):(h.innerHTML=`<g clip-path="url(#clip0_6083_34804)"> 24<path d="M11.4 15.2H12.6V11.2H11.4V15.2ZM12 10C12.1667 10 12.3056 9.94444 12.4167 9.83333C12.5389 9.71111 12.6 9.56667 12.6 9.4C12.6 9.23333 12.5389 9.09444 12.4167 8.98333C12.3056 8.86111 12.1667 8.8 12 8.8C11.8333 8.8 11.6889 8.86111 11.5667 8.98333C11.4556 9.09444 11.4 9.23333 11.4 9.4C11.4 9.56667 11.4556 9.71111 11.5667 9.83333C11.6889 9.94444
2411.8333 10 12 10ZM12 18.4C11.1222 18.4 10.2944 18.2333 9.51667 17.9C8.73889 17.5667 8.05556 17.1111 7.46667 16.5333C6.88889 15.9444 6.43333 15.2611 6.1 14.4833C5.76667 13.7056 5.6 12.8778 5.6 12C5.6 11.1111 5.76667 10.2833 6.1 9.51667C6.43333 8.73889 6.88889 8.06111 7.46667 7.48333C8.05556 6.89444 8.73889 6.43333 9.51667 6.1C10.2944 5.76667 11.1222 5.6 12 5.6C12.8889 5.6 13.7167 5.76667 14.4833 6.1C15.2611 6.43333 15.9389 6.89444 16.5167 7.48333C17.1056 8.06111 17.5667 8.73889 17.9 9.51667C18.2333 10.2833 18.4 11.1111 18.4 12C18.4 12.8778 18.2333 13.7056 17.9 14.4833C17.5667 15.2611 17.1056 15.9444 16.5167 16.5333C15.9389 17.1111 15.2611 17.5667 14.4833 17.9C13.7167 18.2333 12.8889 18.4 12 18.4ZM12 17.2C13.4444 17.2 14.6722 16.6944 15.6833 15.6833C16.6944 14.6722 17.2 13.4444 17.2 12C17.2 10.5556 16.6944 9.32778 15.6833 8.31667C14.6722 7.30555 13.4444 6.8 12 6.8C10.5556 6.8 9.32778 7.30555 8.31667 8.31667C7.30556 9.32778 6.8 10.5556 6.8 12C6.8 13.4444 7.30556 14.6722 8.31667 15.6833C9.32778 16.6944 10.5556 17.2 12 17.2Z" fill="#212121"/> 25</g> 26<defs> 27<clipPath id="clip0_6083_34804"> 28<rect width="24" height="24" fill="white"/> 29</clipPath> 30</defs>`,o.innerText="Preview backend running in this workspace."),o.setAttribute("id",s)}"loading"===document.readyState?window.addEventListener("DOMContentLoaded",a):a()}function F(){return"u">typeof navigator&&"string"==typeof navigator.userAgent?navigator.userAgent:""}function k(){return"u">typeof window&&!!(window.cordova||window.phonegap||window.PhoneGap)&&/ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(F())}function E(){let e=d()?.forceEnvironment;if("node"===e)return!0;if("browser"===e)return!1;try{return"[object process]"===Object.prototype.toString.call(r.g.process)}catch(e){return!1}}function A(){return"u">typeof navigator&&"Cloudflare-Workers"===navigator.userAgent}function _(){let e="object"==typeof chrome?chrome.runtime:"object"==typeof browser?browser.runtime:void 0;return"object"==typeof e&&void 0!==e.id}function R(){return"object"==typeof navigator&&"ReactNative"===navigator.product}function I(){let e=F();return e.indexOf("MSIE ")>=0||e.indexOf("Trident/")>=0}function x(){return!E()&&!!navigator.userAgent&&navigator.userAgent.includes("Safari")&&!navigator.userAgent.includes("Chrome")}function O(){return!E()&&!!navigator.userAgent&&(navigator.userAgent.includes("Safari")||navigator.userAgent.includes("WebKit"))&&!navigator.userAgent.includes("Chrome")}function M(){try{return"object"==typeof indexedDB}catch(e){return!1}}function P(){return new Promise((e,t)=>{try{let r=!0,i="validate-browser-context-for-indexeddb-analytics-module",n=self.indexedDB.open(i);n.onsuccess=()=>{n.result.close(),r||self.indexedDB.deleteDatabase(i),e(!0)},n.onupgradeneeded=()=>{r=!1},n.onerror=()=>{t(n.error?.message||"")}}catch(e){t(e)}})}class L extends Error{constructor(e,t,r){super(t),this.code=e,this.customData=r,this.name="FirebaseError",Object.setPrototypeOf(this,L.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,N.prototype.create)}}class N{constructor(e,t,r){this.service=e,this.serviceName=t,this.errors=r}create(e,...t){var r,i;let n=t[0]||{},a=`${this.service}/${e}`,s=this.errors[e],o=s?(r=s,i=n,r.replace(D,(e,t)=>{let r=i[t];return null!=r?String(r):`<${t}?>`})):"Error",l=`${this.serviceName}: ${o} (${a}).`;return new L(a,l,n)}}let D=/\{\$([^}]+)}/g;function z(e){for(let t in e)if(Object.prototype.hasOwnProperty.call(e,t))return!1;return!0}function U(e){return null!==e&&"object"==typeof e}function B(e){let t=[];for(let[r,i]of Object.entries(e))Array.isArray(i)?i.forEach(e=>{t.push(encodeURIComponent(r)+"="+encodeURIComponent(e))}):t.push(encodeURIComponent(r)+"="+encodeURIComponent(i));return t.length?"&"+t.join("&"):""}function V(e){let t={};return e.replace(/^\?/,"").split("&").forEach(e=>{if(e){let[r,i]=e.split("=");
30t[decodeURIComponent(r)]=decodeURIComponent(i)}}),t}function j(e){let t=e.indexOf("?");if(!t)return"";let r=e.indexOf("#",t);return e.substring(t,r>0?r:void 0)}function G(e,t){let r=new K(e,t);return r.subscribe.bind(r)}class K{constructor(e,t){this.observers=[],this.unsubscribes=[],this.observerCount=0,this.task=Promise.resolve(),this.finalized=!1,this.onNoObservers=t,this.task.then(()=>{e(this)}).catch(e=>{this.error(e)})}next(e){this.forEachObserver(t=>{t.next(e)})}error(e){this.forEachObserver(t=>{t.error(e)}),this.close(e)}complete(){this.forEachObserver(e=>{e.complete()}),this.close()}subscribe(e,t,r){let i;if(void 0===e&&void 0===t&&void 0===r)throw Error("Missing Observer.");void 0===(i=!function(e,t){if("object"!=typeof e||null===e)return!1;for(let r of t)if(r in e&&"function"==typeof e[r])return!0;return!1}(e,["next","error","complete"])?{next:e,error:t,complete:r}:e).next&&(i.next=H),void 0===i.error&&(i.error=H),void 0===i.complete&&(i.complete=H);let n=this.unsubscribeOne.bind(this,this.observers.length);return this.finalized&&this.task.then(()=>{try{this.finalError?i.error(this.finalError):i.complete()}catch(e){}}),this.observers.push(i),n}unsubscribeOne(e){void 0!==this.observers&&void 0!==this.observers[e]&&(delete this.observers[e],this.observerCount-=1,0===this.observerCount&&void 0!==this.onNoObservers&&this.onNoObservers(this))}forEachObserver(e){if(!this.finalized)for(let t=0;t<this.observers.length;t++)this.sendOne(t,e)}sendOne(e,t){this.task.then(()=>{if(void 0!==this.observers&&void 0!==this.observers[e])try{t(this.observers[e])}catch(e){"u">typeof console&&console.error&&console.error(e)}})}close(e){this.finalized||(this.finalized=!0,void 0!==e&&(this.finalError=e),this.task.then(()=>{this.observers=void 0,this.onNoObservers=void 0}))}}function H(){}function q(e){return e&&e._delegate?e._delegate:e}},76988:function(e,t,r){"use strict";var i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.sendGAEvent=t.GoogleAnalytics=t.sendGTMEvent=t.GoogleTagManager=t.YouTubeEmbed=t.GoogleMapsEmbed=void 0;var n=r(93421);Object.defineProperty(t,"GoogleMapsEmbed",{enumerable:!0,get:function(){return i(n).default}});var a=r(5625);Object.defineProperty(t,"YouTubeEmbed",{enumerable:!0,get:function(){return i(a).default}});var s=r(62818);Object.defineProperty(t,"GoogleTagManager",{enumerable:!0,get:function(){return s.GoogleTagManager}}),Object.defineProperty(t,"sendGTMEvent",{enumerable:!0,get:function(){return s.sendGTMEvent}});var o=r(94464);Object.defineProperty(t,"GoogleAnalytics",{enumerable:!0,get:function(){return o.GoogleAnalytics}}),Object.defineProperty(t,"sendGAEvent",{enumerable:!0,get:function(){return o.sendGAEvent}})},77328:(e,t,r)=>{e.exports=r(88005)},79938:function(e,t,r){"use strict";var i=this&&this.__rest||function(e,t){var r={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&0>t.indexOf(i)&&(r[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var n=0,i=Object.getOwnPropertySymbols(e);n<i.length;n++)0>t.indexOf(i[n])&&Object.prototype.propertyIsEnumerable.call(e,i[n])&&(r[i[n]]=e[i[n]]);return r},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.GoogleMapsEmbed=void 0;let a=n(r(1018)),s=r(13949);t.GoogleMapsEmbed=e=>{var t=i(e,[]);return(0,s.formatData)(a.default,t)}},86087:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.YouTubeEmbed=t.GoogleMapsEmbed=t.GoogleAnalytics=void 0;var i=r(48477);Object.defineProperty(t,"GoogleAnalytics",{enumerable:!0,get:function(){return i.GoogleAnalytics}});var n=r(79938);Object.defineProperty(t,"GoogleMapsEmbed",{enumerable:!0,get:function(){return n.GoogleMapsEmbed}});var a=r(16110);Object.defineProperty(t,"YouTubeEmbed",{enumerable:!0,get:function(){return a.YouTubeEmbed}})},88220:e=>{var t={872:function(e,t){"use strict";t.byteLength=function(e){var t=l(e),r=t[0],i=t[1];return(r+i)*3/4-i},t.toByteArray=function(e){var t,r,a=l(e),s=a[0],o=a[1],u=new n((s+o)*3/4-o),c=0,h=o>0?s-4:s;for(r=0;r<h;r+=4)t=i[e.charCodeAt(r)]<<18|i[e.charCodeAt(r+1)]<<12|i[e.charCodeAt(r+2)]<<6|i[e.charCodeAt(r+3)],u[c++]=t>>16&255,u[c++]=t>>8&255,u[c++]=255&t;return 2===o&&(t=i[e.charCodeAt(r)]<<2|i[e.charCodeAt(r+1)]>>4,u[c++]=255&t),1===o&&(t=i[e.charCodeAt(r)]<<10|i[e.charCodeAt(r+1)]<<4|i[e.charCodeAt(r+2)]>>2,u[c++]=t>>8&255,u[c++]=255&t),u},t.fromByteArray=function(e){for(var t,i=e.length,n=i%3,a=[],s=0,o=i-n;s<o;s+=16383)a.push(function(e,t,i){for(var n,a=[],s=t;s<i;s+=3)n=(e[s]<<16&0xff0000)+(e[s+1]<<8&65280)+(255&e[s+2]),a.push(r[n>>18&63]+r[n>>12&63]+r[n>>6&63]+r[63&n]);return a.join("")}(e,s,s+16383>o?o:s+16383));return 1===n?a.push(r[(t=e[i-1])>>2]+r[t<<4&63]+"=="):2===n&&a.push(r[(t=(e[i-2]<<8)+e[i-1])>>10]+r[t>>4&63]+r[t<<2&63]+"="),a.join("")};for(var r=[],i=[],n="u">typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
30+/",s=0,o=a.length;s<o;++s)r[s]=a[s],i[a.charCodeAt(s)]=s;function l(e){var t=e.length;if(t%4>0)throw Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");-1===r&&(r=t);var i=r===t?0:4-r%4;return[r,i]}i[45]=62,i[95]=63},230:function(e,t,r){"use strict";var i=r(872),n=r(321),a="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;function s(e){if(e>0x7fffffff)throw RangeError('The value "'+e+'" is invalid for option "size"');var t=new Uint8Array(e);return Object.setPrototypeOf(t,o.prototype),t}function o(e,t,r){if("number"==typeof e){if("string"==typeof t)throw TypeError('The "string" argument must be of type string. Received type number');return c(e)}return l(e,t,r)}function l(e,t,r){if("string"==typeof e){var i=e,n=t;if(("string"!=typeof n||""===n)&&(n="utf8"),!o.isEncoding(n))throw TypeError("Unknown encoding: "+n);var a=0|m(i,n),l=s(a),u=l.write(i,n);return u!==a&&(l=l.slice(0,u)),l}if(ArrayBuffer.isView(e))return h(e);if(null==e)throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(R(e,ArrayBuffer)||e&&R(e.buffer,ArrayBuffer)||"u">typeof SharedArrayBuffer&&(R(e,SharedArrayBuffer)||e&&R(e.buffer,SharedArrayBuffer)))return function(e,t,r){var i;if(t<0||e.byteLength<t)throw RangeError('"offset" is outside of buffer bounds');if(e.byteLength<t+(r||0))throw RangeError('"length" is outside of buffer bounds');return Object.setPrototypeOf(i=void 0===t&&void 0===r?new Uint8Array(e):void 0===r?new Uint8Array(e,t):new Uint8Array(e,t,r),o.prototype),i}(e,t,r);if("number"==typeof e)throw TypeError('The "value" argument must not be of type number. Received type number');var c=e.valueOf&&e.valueOf();if(null!=c&&c!==e)return o.from(c,t,r);var g=function(e){if(o.isBuffer(e)){var t=0|d(e.length),r=s(t);return 0===r.length||e.copy(r,0,0,t),r}return void 0!==e.length?"number"!=typeof e.length||function(e){return e!=e}(e.length)?s(0):h(e):"Buffer"===e.type&&Array.isArray(e.data)?h(e.data):void 0}(e);if(g)return g;if("u">typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return o.from(e[Symbol.toPrimitive]("string"),t,r);throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function u(e){if("number"!=typeof e)throw TypeError('"size" argument must be of type number');if(e<0)throw RangeError('The value "'+e+'" is invalid for option "size"')}function c(e){return u(e),s(e<0?0:0|d(e))}function h(e){for(var t=e.length<0?0:0|d(e.length),r=s(t),i=0;i<t;i+=1)r[i]=255&e[i];return r}t.Buffer=o,t.SlowBuffer=function(e){return+e!=e&&(e=0),o.alloc(+e)},t.INSPECT_MAX_BYTES=50,t.kMaxLength=0x7fffffff,o.TYPED_ARRAY_SUPPORT=function(){try{var e=new Uint8Array(1),t={foo:function(){return 42}};return Object.setPrototypeOf(t,Uint8Array.prototype),Object.setPrototypeOf(e,t),42===e.foo()}catch(e){return!1}}(),!o.TYPED_ARRAY_SUPPORT&&"u">typeof console&&"function"==typeof console.error&&console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."),Object.defineProperty(o.prototype,"parent",{enumerable:!0,get:function(){if(o.isBuffer(this))return this.buffer}}),Object.defineProperty(o.prototype,"offset",{enumerable:!0,get:function(){if(o.isBuffer(this))return this.byteOffset}}),o.poolSize=8192,o.from=function(e,t,r){return l(e,t,r)},Object.setPrototypeOf(o.prototype,Uint8Array.prototype),Object.setPrototypeOf(o,Uint8Array),o.alloc=function(e,t,r){return(u(e),e<=0)?s(e):void 0!==t?"string"==typeof r?s(e).fill(t,r):s(e).fill(t):s(e)},o.allocUnsafe=function(e){return c(e)},o.allocUnsafeSlow=function(e){return c(e)};function d(e){if(e>=0x7fffffff)throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x7fffffff bytes");return 0|e}function m(e,t){if(o.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||R(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);var r=e.length,i=arguments.length>2&&!0===arguments[2];if(!i&&0===r)return 0;for(var n=!1;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":return k(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return A(e).length;default:if(n)return i?-1:k(e).length;t=(""+t).toLowerCase(),n=!0}}function g(e,t,r){var n,a,s,o=!1;if((void 0===t||t<0)&&(t=0),t>this.length||((void 0===r||r>this.length)&&(r=this.length),r<=0||(r>>>=0)<=(t>>>=0)))return"";for(e||(e="utf8");;)switch(e){case"hex":return function(e,t,r){var i=e.length;(!t||t<0)&&(t=0),(!r||r<0||r>i)&&(r=i);for(var n="",a=t;a<r;++a)n+=I[e[a]];return n}(this,t,r);case"utf8":case"utf-8":return v(this,t,r);case"ascii":return function(e,t,r){var i="";r=Math.min(e.length,r);for(var n=t;n<r;++n)i+=String.fromCharCode(127&e[n]);return i}(this,t,r);case"latin1":case"binary":return function(e,t,r){var i="";r=Math.min(e.length,r);for(var n=t;n<r;++n)i+=String.fromCharCode(e[n]);return i}(this,t,r);case"base64":return n=this,a=t,s=r,0===a&&s===n.length?i.fromByteArray(n):i.fromByteArray(n.slice(a,s));case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return function(e,t,r){for(var i=e.slice(t,r),n="",a=0;a<i.length;a+=2)n+=String.fromCharCode(i[a]+256*i[a+1]);return n}(this,t,r);default:if(o)throw TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),o=!0}}function p(e,t,r){var i=e[t];e[t]=e[r],e[r]=i}function f(e,t,r,i,n){var a;if(0===e.length)return -1;if("string"==typeof r?(i=r,r=0):r>0x7fffffff?r=0x7fffffff:r<-0x80000000&&(r=-0x80000000),(a=r*=1)!=a&&(r=n?0:e.length-1),r<0&&(r=e.length+r),r>=e.length)if(n)return -1;else r=e.length-1;else if(r<0)if(!n)return -1;else r=0;if("string"==typeof t&&(t=o.from(t,i)),o.isBuffer(t))return 0===t.length?-1:y(e,t,r,i,n);if("number"==typeof t){if(t&=255,"function"==typeof Uint8Array.prototype.indexOf)if(n)return Uint8Array.prototype.indexOf.call(e,t,r);else return Uint8Array.prototype.lastIndexOf.call(e,t,r);return y(e,[t],r,i,n)}throw TypeError("val must be string, number or Buffer")}function y(e,t,r,i,n){var a,s=1,o=e.length,l=t.length;if(void 0!==i&&("ucs2"===(i=String(i).toLowerCase())||"ucs-2"===i||"utf16le"===i||"utf-16le"===i)){if(e.length<2||t.length<2)return -1;s=2,o/=2,l/=2,r/=2}function u(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(n){var c=-1;for(a=r;a<o;
vendor: 12,357 bytes, line 30
30a++)if(u(e,a)===u(t,-1===c?0:a-c)){if(-1===c&&(c=a),a-c+1===l)return c*s}else -1!==c&&(a-=a-c),c=-1}else for(r+l>o&&(r=o-l),a=r;a>=0;a--){for(var h=!0,d=0;d<l;d++)if(u(e,a+d)!==u(t,d)){h=!1;break}if(h)return a}return -1}o.isBuffer=function(e){return null!=e&&!0===e._isBuffer&&e!==o.prototype},o.compare=function(e,t){if(R(e,Uint8Array)&&(e=o.from(e,e.offset,e.byteLength)),R(t,Uint8Array)&&(t=o.from(t,t.offset,t.byteLength)),!o.isBuffer(e)||!o.isBuffer(t))throw TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(e===t)return 0;for(var r=e.length,i=t.length,n=0,a=Math.min(r,i);n<a;++n)if(e[n]!==t[n]){r=e[n],i=t[n];break}return r<i?-1:+(i<r)},o.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},o.concat=function(e,t){if(!Array.isArray(e))throw TypeError('"list" argument must be an Array of Buffers');if(0===e.length)return o.alloc(0);if(void 0===t)for(r=0,t=0;r<e.length;++r)t+=e[r].length;var r,i=o.allocUnsafe(t),n=0;for(r=0;r<e.length;++r){var a=e[r];if(R(a,Uint8Array)&&(a=o.from(a)),!o.isBuffer(a))throw TypeError('"list" argument must be an Array of Buffers');a.copy(i,n),n+=a.length}return i},o.byteLength=m,o.prototype._isBuffer=!0,o.prototype.swap16=function(){var e=this.length;if(e%2!=0)throw RangeError("Buffer size must be a multiple of 16-bits");for(var t=0;t<e;t+=2)p(this,t,t+1);return this},o.prototype.swap32=function(){var e=this.length;if(e%4!=0)throw RangeError("Buffer size must be a multiple of 32-bits");for(var t=0;t<e;t+=4)p(this,t,t+3),p(this,t+1,t+2);return this},o.prototype.swap64=function(){var e=this.length;if(e%8!=0)throw RangeError("Buffer size must be a multiple of 64-bits");for(var t=0;t<e;t+=8)p(this,t,t+7),p(this,t+1,t+6),p(this,t+2,t+5),p(this,t+3,t+4);return this},o.prototype.toString=function(){var e=this.length;return 0===e?"":0==arguments.length?v(this,0,e):g.apply(this,arguments)},o.prototype.toLocaleString=o.prototype.toString,o.prototype.equals=function(e){if(!o.isBuffer(e))throw TypeError("Argument must be a Buffer");return this===e||0===o.compare(this,e)},o.prototype.inspect=function(){var e="",r=t.INSPECT_MAX_BYTES;return e=this.toString("hex",0,r).replace(/(.{2})/g,"$1 ").trim(),this.length>r&&(e+=" ... "),"<Buffer "+e+">"},a&&(o.prototype[a]=o.prototype.inspect),o.prototype.compare=function(e,t,r,i,n){if(R(e,Uint8Array)&&(e=o.from(e,e.offset,e.byteLength)),!o.isBuffer(e))throw TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===i&&(i=0),void 0===n&&(n=this.length),t<0||r>e.length||i<0||n>this.length)throw RangeError("out of range index");if(i>=n&&t>=r)return 0;if(i>=n)return -1;if(t>=r)return 1;if(t>>>=0,r>>>=0,i>>>=0,n>>>=0,this===e)return 0;for(var a=n-i,s=r-t,l=Math.min(a,s),u=this.slice(i,n),c=e.slice(t,r),h=0;h<l;++h)if(u[h]!==c[h]){a=u[h],s=c[h];break}return a<s?-1:+(s<a)},o.prototype.includes=function(e,t,r){return -1!==this.indexOf(e,t,r)},o.prototype.indexOf=function(e,t,r){return f(this,e,t,r,!0)},o.prototype.lastIndexOf=function(e,t,r){return f(this,e,t,r,!1)};function v(e,t,r){r=Math.min(e.length,r);for(var i=[],n=t;n<r;){var a,s,o,l,u=e[n],c=null,h=u>239?4:u>223?3:u>191?2:1;if(n+h<=r)switch(h){case 1:u<128&&(c=u);break;case 2:(192&(a=e[n+1]))==128&&(l=(31&u)<<6|63&a)>127&&(c=l);break;case 3:a=e[n+1],s=e[n+2],(192&a)==128&&(192&s)==128&&(l=(15&u)<<12|(63&a)<<6|63&s)>2047&&(l<55296||l>57343)&&(c=l);break;case 4:a=e[n+1],s=e[n+2],o=e[n+3],(192&a)==128&&(192&s)==128&&(192&o)==128&&(l=(15&u)<<18|(63&a)<<12|(63&s)<<6|63&o)>65535&&l<1114112&&(c=l)}null===c?(c=65533,h=1):c>65535&&(c-=65536,i.push(c>>>10&1023|55296),c=56320|1023&c),i.push(c),n+=h}var d=i,m=d.length;if(m<=4096)return String.fromCharCode.apply(String,d);for(var g="",p=0;p<m;)g+=String.fromCharCode.apply(String,d.slice(p,p+=4096));return g}function w(e,t,r){if(e%1!=0||e<0)throw RangeError("offset is not uint");if(e+t>r)throw RangeError("Trying to access beyond buffer length")}function b(e,t,r,i,n,a){if(!o.isBuffer(e))throw TypeError('"buffer" argument must be a Buffer instance');if(t>n||t<a)throw RangeError('"value" argument is out of bounds');if(r+i>e.length)throw RangeError("Index out of range")}function C(e,t,r,i,n,a){if(r+i>e.length||r<0)throw RangeError("Index out of range")}function T(e,t,r,i,a){return t*=1,r>>>=0,a||C(e,t,r,4,34028234663852886e22,-34028234663852886e22),n.write(e,t,r,i,23,4),r+4}function S(e,t,r,i,a){return t*=1,r>>>=0,a||C(e,t,r,8,17976931348623157e292,-17976931348623157e292),n.write(e,t,r,i,52,8),r+8}o.prototype.write=function(e,t,r,i){if(void 0===t)i="utf8",r=this.length,t=0;else if(void 0===r&&"string"==typeof t)i=t,r=this.length,t=0;else if(isFinite(t))t>>>=0,isFinite(r)?(r>>>=0,void 0===i&&(i="utf8")):(i=r,r=void 0);else throw Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");var n,a,s,o,l,u,c,h,d=this.length-t;if((void 0===r||r>d)&&(r=d),e.length>0&&(r<0||t<0)||t>this.length)throw RangeError("Attempt to write outside buffer bounds");i||(i="utf8");for(var m=!1;;)switch(i){case"hex":return function(e,t,r,i){r=Number(r)||0;var n=e.length-r;i?(i=Number(i))>n&&(i=n):i=n;var a=t.length;i>a/2&&(i=a/2);for(var s=0;s<i;++s){var o,l=parseInt(t.substr(2*s,2),16);if((o=l)!=o)break;e[r+s]=l}return s}(this,e,t,r);case"utf8":case"utf-8":return n=t,a=r,_(k(e,this.length-n),this,n,a);case"ascii":return s=t,o=r,_(E(e),this,s,o);case"latin1":case"binary":return function(e,t,r,i){return _(E(t),e,r,i)}(this,e,t,r);case"base64":return l=t,u=r,_(A(e),this,l,u);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return c=t,h=r,_(function(e,t){for(var r,i,n=[],a=0;a<e.length&&!((t-=2)<0);++a)i=(r=e.charCodeAt(a))>>8,n.push(r%256),n.push(i);return n}(e,this.length-c),this,c,h);default:if(m)throw TypeError("Unknown encoding: "+i);i=(""+i).toLowerCase(),m=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}},o.prototype.slice=function(e,t){var r=this.length;e=~~e,t=void 0===t?r:~~t,e<0?(e+=r)<0&&(e=0):e>r&&(e=r),t<0?(t+=r)<0&&(t=0):t>r&&(t=r),t<e&&(t=e);var i=this.subarray(e,t);return Object.setPrototypeOf(i,o.prototype),i},o.prototype.readUIntLE=function(e,t,r){e>>>=0,t>>>=0,r||w(e,t,this.length);for(var i=this[e],n=1,a=0;++a<t&&(n*=256);)i+=this[e+a]*n;return i},o.prototype.readUIntBE=function(e,t,r){e>>>=0,t>>>=0,r||w(e,t,this.length);for(var i=this[e+--t],n=1;t>0&&(n*=256);)i+=this[e+--t]*n;return i},o.prototype.readUInt8=function(e,t){return e>>>=0,t||w(e,1,this.length),this[e]},o.prototype.readUInt16LE=function(e,t){return e>>>=0,t||w(e,2,this.length),this[e]|this[e+1]<<8},o.prototype.readUInt16BE=function(e,t){return e>>>=0,t||w(e,2,this.length),this[e]<<8|this[e+1]},o.prototype.readUInt32LE=function(e,t){return e>>>=0,t||w(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+0x1000000*this[e+3]},o.prototype.readUInt32BE=function(e,t){return e>>>=0,t||w(e,4,this.length),0x1000000*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},o.prototype.readIntLE=function(e,t,r){e>>>=0,t>>>=0,r||w(e,t,this.length);for(var i=this[e],n=1,a=0;++a<t&&(n*=256);)i+=this[e+a]*n;return i>=(n*=128)&&(i-=Math.pow(2,8*t)),i},o.prototype.readIntBE=function(e,t,r){e>>>=0,t>>>=0,r||w(e,t,this.length);for(var i=t,n=1,a=this[e+--i];i>0&&(n*=256);)a+=this[e+--i]*n;return a>=(n*=128)&&(a-=Math.pow(2,8*t)),a},o.prototype.readInt8=function(e,t){return(e>>>=0,t||w(e,1,this.length),128&this[e])?-((255-this[e]+1)*1):this[e]},o.prototype.readInt16LE=function(e,t){e>>>=0,t||w(e,2,this.length);var r=this[e]|this[e+1]<<8;return 32768&r?0xffff0000|r:r},o.prototype.readInt16BE=function(e,t){e>>>=0,t||w(e,2,this.length);var r=this[e+1]|this[e]<<8;return 32768&r?0xffff0000|r:r},o.prototype.readInt32LE=function(e,t){return e>>>=0,t||w(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},o.prototype.readInt32BE=function(e,t){return e>>>=0,t||w(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},o.prototype.readFloatLE=function(e,t){return e>>>=0,t||w(e,4,this.length),n.read(this,e,!0,23,4)},o.prototype.readFloatBE=function(e,t){return e>>>=0,t||w(e,4,this.length),n.read(this,e,!1,23,4)},o.prototype.readDoubleLE=function(e,t){return e>>>=0,t||w(e,8,this.length),n.read(this,e,!0,52,8)},o.prototype.readDoubleBE=function(e,t){return e>>>=0,t||w(e,8,this.length),n.read(this,e,!1,52,8)},o.prototype.writeUIntLE=function(e,t,r,i){if(e*=1,t>>>=0,r>>>=0,!i){var n=Math.pow(2,8*r)-1;b(this,e,t,r,n,0)}var a=1,s=0;for(this[t]=255&e;++s<r&&(a*=256);)this[t+s]=e/a&255;return t+r},o.prototype.writeUIntBE=function(e,t,r,i){if(e*=1,t>>>=0,r>>>=0,!i){var n=Math.pow(2,8*r)-1;b(this,e,t,r,n,0)}var a=r-1,s=1;for(this[t+a]=255&e;--a>=0&&(s*=256);)this[t+a]=e/s&255;return t+r},o.prototype.writeUInt8=function(e,t,r){return e*=1,t>>>=0,r||b(this,e,t,1,255,0),this[t]=255&e,t+1},o.prototype.writeUInt16LE=function(e,t,r){return e*=1,t>>>=0,r||b(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},o.prototype.writeUInt16BE=function(e,t,r){return e*=1,t>>>=0,r||b(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},o.prototype.writeUInt32LE=function(e,t,r){return e*=1,t>>>=0,r||b(this,e,t,4,0xffffffff,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},o.prototype.writeUInt32BE=function(e,t,r){return e*=1,t>>>=0,r||b(this,e,t,4,0xffffffff,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},o.prototype.writeIntLE=function(e,t,r,i){if(e*=1,t>>>=0,!i){var n=Math.pow(2,8*r-1);b(this,e,t,r,n-1,-n)}var a=0,s=1,o=0;for(this[t]=255&e;++a<r&&(s*=256);)e<0&&0===o&&0!==this[t+a-1]&&(o=1),this[t+a]=(e/s|0)-o&255;return t+r},o.prototype.writeIntBE=function(e,t,r,i){if(e*=1,t>>>=0,!i){var n=Math.pow(2,8*r-1);b(this,e,t,r,n-1,-n)}var a=r-1,s=1,o=0;for(this[t+a]=255&e;--a>=0&&(s*=256);)e<0&&0===o&&0!==this[t+a+1]&&(o=1),this[t+a]=(e/s|0)-o&255;return t+r},o.prototype.writeInt8=function(e,t,r){return e*=1,t>>>=0,r||b(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},o.prototype.writeInt16LE=function(e,t,r){return e*=1,t>>>=0,r||b(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},o.prototype.writeInt16BE=function(e,t,r){return e*=1,t>>>=0,r||b(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},o.prototype.writeInt32LE=function(e,t,r){return e*=1,t>>>=0,r||b(this,e,t,4,0x7fffffff,-0x80000000),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},o.prototype.writeInt32BE=function(e,t,r){return e*=1,t>>>=0,r||b(this,e,t,4,0x7fffffff,-0x80000000),e<0&&(e=0xffffffff+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},o.prototype.writeFloatLE=function(e,t,r){return T(this,e,t,!0,r)},o.prototype.writeFloatBE=function(e,t,r){return T(this,e,t,!1,r)},o.prototype.writeDoubleLE=function(e,t,r){return S(this,e,t,!0,r)},o.prototype.writeDoubleBE=function(e,t,r){return S(this,e,t,!1,r)},o.prototype.copy=function(e,t,r,i){if(!o.isBuffer(e))throw TypeError("argument should be a Buffer");if(r||(r=0),i||0===i||(i=this.length),t>=e.length&&(t=e.length),t||(t=0),i>0&&i<r&&(i=r),i===r||0===e.length||0===this.length)return 0;if(t<0)throw RangeError("targetStart out of bounds");if(r<0||r>=this.length)throw RangeError("Index out of range");if(i<0)throw RangeError("sourceEnd out of bounds");i>this.length&&(i=this.length),e.length-t<i-r&&(i=e.length-t+r);var n=i-r;if(this===e&&"function"==typeof Uint8Array.prototype.copyWithin)this.copyWithin(t,r,i);else if(this===e&&r<t&&t<i)for(var a=n-1;a>=0;--a)e[a+t]=this[a+r];else Uint8Array.prototype.set.call(e,this.subarray(r,i),t);return n},o.prototype.fill=function(e,t,r,i){if("string"==typeof e){if("string"==typeof t?(i=t,t=0,r=this.length):"string"==typeof r&&(i=r,r=this.length),void 0!==i&&"string"!=typeof i)throw TypeError("encoding must be a string");if("string"==typeof i&&!o.isEncoding(i))throw TypeError("Unknown encoding: "+i);if(1===e.length){var n,a=e.charCodeAt(0);("utf8"===i&&a<128||"latin1"===i)&&(e=a)}}else"number"==typeof e?e&=255:"boolean"==typeof e&&(e=Number(e));if(t<0||this.length<t||this.length<r)throw RangeError("Out of range index");if(r<=t)return this;if(t>>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(n=t;n<r;++n)this[n]=e;
30else{var s=o.isBuffer(e)?e:o.from(e,i),l=s.length;if(0===l)throw TypeError('The value "'+e+'" is invalid for argument "value"');for(n=0;n<r-t;++n)this[n+t]=s[n%l]}return this};var F=/[^+/0-9A-Za-z-_]/g;function k(e,t){t=t||1/0;for(var r,i=e.length,n=null,a=[],s=0;s<i;++s){if((r=e.charCodeAt(s))>55295&&r<57344){if(!n){if(r>56319||s+1===i){(t-=3)>-1&&a.push(239,191,189);continue}n=r;continue}if(r<56320){(t-=3)>-1&&a.push(239,191,189),n=r;continue}r=(n-55296<<10|r-56320)+65536}else n&&(t-=3)>-1&&a.push(239,191,189);if(n=null,r<128){if((t-=1)<0)break;a.push(r)}else if(r<2048){if((t-=2)<0)break;a.push(r>>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;a.push(r>>12|224,r>>6&63|128,63&r|128)}else if(r<1114112){if((t-=4)<0)break;a.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}else throw Error("Invalid code point")}return a}function E(e){for(var t=[],r=0;r<e.length;++r)t.push(255&e.charCodeAt(r));return t}function A(e){return i.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(F,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function _(e,t,r,i){for(var n=0;n<i&&!(n+r>=t.length)&&!(n>=e.length);++n)t[n+r]=e[n];return n}function R(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}var I=function(){for(var e="0123456789abcdef",t=Array(256),r=0;r<16;++r)for(var i=16*r,n=0;n<16;++n)t[i+n]=e[r]+e[n];return t}()},321:function(e,t){t.read=function(e,t,r,i,n){var a,s,o=8*n-i-1,l=(1<<o)-1,u=l>>1,c=-7,h=r?n-1:0,d=r?-1:1,m=e[t+h];for(h+=d,a=m&(1<<-c)-1,m>>=-c,c+=o;c>0;a=256*a+e[t+h],h+=d,c-=8);for(s=a&(1<<-c)-1,a>>=-c,c+=i;c>0;s=256*s+e[t+h],h+=d,c-=8);if(0===a)a=1-u;else{if(a===l)return s?NaN:1/0*(m?-1:1);s+=Math.pow(2,i),a-=u}return(m?-1:1)*s*Math.pow(2,a-i)},t.write=function(e,t,r,i,n,a){var s,o,l,u=8*a-n-1,c=(1<<u)-1,h=c>>1,d=5960464477539062e-23*(23===n),m=i?0:a-1,g=i?1:-1,p=+(t<0||0===t&&1/t<0);for(isNaN(t=Math.abs(t))||t===1/0?(o=+!!isNaN(t),s=c):(s=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-s))<1&&(s--,l*=2),s+h>=1?t+=d/l:t+=d*Math.pow(2,1-h),t*l>=2&&(s++,l/=2),s+h>=c?(o=0,s=c):s+h>=1?(o=(t*l-1)*Math.pow(2,n),s+=h):(o=t*Math.pow(2,h-1)*Math.pow(2,n),s=0));n>=8;e[r+m]=255&o,m+=g,o/=256,n-=8);for(s=s<<n|o,u+=n;u>0;e[r+m]=255&s,m+=g,s/=256,u-=8);e[r+m-g]|=128*p}}},r={};function i(e){var n=r[e];if(void 0!==n)return n.exports;var a=r[e]={exports:{}},s=!0;try{t[e](a,a.exports,i),s=!1}finally{s&&delete r[e]}return a.exports}i.ab="//",e.exports=i(230)},89099:(e,t,r)=>{e.exports=r(7640)},93421:function(e,t,r){"use strict";var i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){let{apiKey:t,...r}=e,i={...r,key:t},{html:o}=(0,a.GoogleMapsEmbed)(i);return(0,n.jsx)(s.default,{height:i.height||null,width:i.width||null,html:o,dataNtpc:"GoogleMapsEmbed"})};let n=r(37876),a=r(86087),s=i(r(40125))},94464:function(e,t,r){"use strict";let i;var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.GoogleAnalytics=function(e){let{gaId:t,debugMode:r,dataLayerName:n="dataLayer",nonce:l}=e;return void 0===i&&(i=n),(0,s.useEffect)(()=>{performance.mark("mark_feature_usage",{detail:{feature:"next-third-parties-ga"}})},[]),(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(o.default,{id:"_next-ga-init",dangerouslySetInnerHTML:{__html:` 31 window['${n}'] = window['${n}'] || []; 32 function gtag(){window['${n}'].push(arguments);} 33 gtag('js', new Date()); 34 35 gtag('config', '${t}' ${r?",{ 'debug_mode': true }":""});`},nonce:l}),(0,a.jsx)(o.default,{id:"_next-ga",src:`https://www.googletagmanager.com/gtag/js?id=${t}`,nonce:l})]})},t.sendGAEvent=function(){void 0===i?console.warn("@next/third-parties: GA has not been initialized"):window[i]?window[i].push(arguments):console.warn(`@next/third-parties: GA dataLayer ${i} does not exist`)};let a=r(37876),s=r(14232),o=n(r(45105))},99904:(e,t,r)=>{"use strict";r.d(t,{L:()=>s});let i=JSON.parse('[{"name":"Boston","country":"USA","countrySlug":"usa","state":"Massachusetts","slug":"boston","highlighted":true,"timezone":"America/Ne
35w_York","map":{"lat":42.3601,"lng":-71.0589,"zoom":12}},{"name":"Chicago","country":"USA","countrySlug":"usa","state":"Illinois","slug":"chicago","highlighted":true,"timezone":"America/Chicago","map":{"lat":41.8781,"lng":-87.6298,"zoom":12}},{"name":"Los Angeles","country":"USA","countrySlug":"usa","state":"California","slug":"los-angeles","highlighted":true,"timezone":"America/Los_Angeles","map":{"lat":34.0522,"lng":-118.2437,"zoom":12}},{"name":"Minneapolis","country":"USA","countrySlug":"usa","state":"Minnesota","slug":"minneapolis","highlighted":true,"timezone":"America/Chicago","map":{"lat":44.9778,"lng":-93.265,"zoom":12}},{"name":"Montr\xe9al","country":"Canada","countrySlug":"canada","state":"Quebec","slug":"montreal","highlighted":true,"timezone":"America/Toronto","map":{"lat":45.5017,"lng":-73.5673,"zoom":12}},{"name":"New York","country":"USA","countrySlug":"usa","state":"New York","slug":"new-york","highlighted":true,"timezone":"America/New_York","map":{"lat":40.7128,"lng":-74.006,"zoom":12}},{"name":"Philadelphia","country":"USA","countrySlug":"usa","state":"Pennsylvania","slug":"philadelphia","highlighted":true,"timezone":"America/New_York","map":{"lat":39.9526,"lng":-75.1652,"zoom":12}},{"name":"Salt Lake City","country":"USA","countrySlug":"usa","state":"Utah","slug":"salt-lake-city","highlighted":true,"timezone":"America/Denver","map":{"lat":40.7608,"lng":-111.891,"zoom":12}},{"name":"San Francisco","country":"USA","countrySlug":"usa","state":"California","slug":"san-francisco","highlighted":true,"timezone":"America/Los_Angeles","map":{"lat":37.7749,"lng":-122.4194,"zoom":12}},{"name":"Toronto","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"toronto","highlighted":true,"timezone":"America/Toronto","map":{"lat":43.6532,"lng":-79.3832,"zoom":12}},{"name":"Vancouver","country":"Canada","countrySlug":"canada","state":"British Columbia","slug":"vancouver","highlighted":true,"timezone":"America/Vancouver","map":{"lat":49.2827,"lng":-123.1207,"zoom":12}},{"name":"Kamloops","country":"Canada","countrySlug":"canada","state":"British Columbia","slug":"kamloops","highlighted":false,"timezone":"America/Vancouver","map":{"lat":50.6745,"lng":-120.3273,"zoom":12}},{"name":"Banff","country":"Canada","countrySlug":"canada","state":"Alberta","slug":"banff","highlighted":false,"timezone":"America/Edmonton","map":{"lat":51.1784,"lng":-115.5708,"zoom":12}},{"name":"Lake Louise","country":"Canada","countrySlug":"canada","state":"Alberta","slug":"lake-louise","highlighted":false,"timezone":"America/Edmonton","map":{"lat":51.4254,"lng":-116.1773,"zoom":13}},{"name":"Washington DC","country":"USA","countrySlug":"usa","state":"District of Columbia","slug":"washington-dc","highlighted":true,"timezone":"America/New_York","map":{"lat":38.9072,"lng":-77.0369,"zoom":12}},{"name":"Ottawa","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"ottawa","highlighted":false,"timezone":"America/Toronto","map":{"lat":45.4215,"lng":-75.6972,"zoom":12}},{"name":"Calgary","country":"Canada","countrySlug":"canada","state":"Alberta","slug":"calgary","highlighted":false,"timezone":"America/Edmonton","map":{"lat":51.0447,"lng":-114.0719,"zoom":12}},{"name":"Edmonton","country":"Canada","countrySlug":"canada","state":"Alberta","slug":"edmonton","highlighted":false,"timezone":"America/Edmonton","map":{"lat":53.5461,"lng":-113.4938,"zoom":12}},{"name":"Qu\xe9bec City","country":"Canada","countrySlug":"canada","state":"Quebec","slug":"quebec-city","highlighted":false,"timezone":"America/Toronto","map":{"lat":46.8139,"lng":-71.208,"zoom":12}},{"name":"Winnipeg","country":"Canada","countrySlug":"canada","state":"Manitoba","slug":"winnipeg","highlighted":false,"timezone":"America/Winnipeg","map":{"lat":49.8951,"lng":-97.1384,"zoom":12}},{"name":"Halifax","country":"Canada","countrySlug":"canada","state":"Nova Scotia","slug":"halifax","highlighted":false,"timezone":"America/Halifax","map":{"lat":44.6488,"lng":-63.5752,"zoom":12}},{"name":"London","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"london-ontario","highlighted":false,"timezone":"America/Toronto","map":{"lat":42.9849,"lng":-81.2453,"zoom":12}},{"name":"Stratford","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"stratford-ontario","highlighted":false,"timezone":"America/Toronto","map":{"lat":43.37,"lng":-80.9822,"zoom":12}},{"name":"St. Marys","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"st-marys-ontario","highlighted":false,"timezone":"America/Toronto","map":{"lat":43.2584,"lng":-81.1445,"zoom":12}},{"name":"Guelph","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"guelph-ontario","highlighted":false,"timezone":"America/Toronto","map":{"lat":43.5448,"lng":-80.2482,"zoom":12}},{"name":"Hamilton","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"hamilton-ontario","highlighted":false,"timezone":"America/Toronto","map":{"lat":43.2557,"lng":-79.8711,"zoom":12}},{"name":"Kitchener","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"kitchener-ontario","highlighted":false,"timezone":"America/Toronto","map":{"lat":43.4516,"lng":-80.4925,"zoom":12}},{"name":"Windsor","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"windsor-ontario","highlighted":false,"timezone":"America/Toronto","map":{"lat":42.3149,"lng":-83.0364,"zoom":12}},{"name":"Saskatoon","country":"Canada","countrySlug":"canada","state":"Saskatchewan","slug":"saskatoon","highlighted":false,"timezone":"America/Regina","map":{"lat":52.1332,"lng":-106.67,"zoom":12}},{"name":"Regina","country":"Canada","countrySlug":"canada","state":"Saskatchewan","slug":"regina","highlighted":false,"timezone":"America/Regina","map":{"lat":50.4452,"lng":-104.6189,"zoom":12}},{"name":"Moncton","country":"Canada","countrySlug":"canada","state":"New Brunswick","slug":"moncton","highlighted":false,"timezone":"America/Halifax","map":{"lat":46.0878,"lng":-64.7782,"zoom":12}},{"name":"Kingston","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"kingston-ontario","highlighted":false,"timezone":"America/Toronto","map":{"lat":44.2312,"lng":-76.486,"zoom":12}},{"name":"Sudbury","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"sudbury","highlighted":false,"timezone":"America/Toronto","map":{"lat":46.4917,"lng":-80.993,"zoom":12}},{"name":"Thunder Bay","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"thunder-bay","highlighted":false,"timezone":"America/Toronto","map":{"lat":48.3809,"lng":-89.2477,"zoom":12}},{"name":"Seattle","country":"USA","countrySlug":"usa","state":"Washington","slug":"seattle","highlighted":true,"timezone":"America/Los_Angeles","map":{"lat":47.6062,"lng":-122.3321,"zoom":12}},{"name":"Portland","country":"USA","countrySlug":"usa","state":"Oregon","slug":"portland","highlighted":true,"timezone":"America/Los_Angeles","map":{"lat":45.5155,"lng":-122.6789,"zoom":12}},{"name":"Sacramento","country":"USA","countrySlug":"usa","state":"California","slug":"sacramento","highlighted":false,"timezone":"America/Los_Angeles","map":{"lat":38.5816,"lng":-121.4944,"zoom":12}},{"name":"San Diego","country":"USA","countrySlug":"usa","state":"California","slug":"san-diego","highlighted":false,"timezone":"America/Los_Angeles","map":{"lat":32.7157,"lng":-117.1611,"zoom":12}},{"name":"Denver","country":"USA","countrySlug":"usa","state":"Colorado","slug":"denver","highlighted":true,"timezone":"America/Denver","map":{"lat":39.7392,"lng":-104.9903,"zoom":12}},{"name":"Dallas","country":"USA","countrySlug":"usa","state":"Texas","slug":"dallas","highlighted":false,"timezone":"America/Chicago","map":{"lat":32.7767,"lng":-96.797,"zoom":12}},{"name":"Denton","country":"USA","countrySlug":"usa","state":"Texas","slug":"denton","highlighted":false,"timezone":"America/Chicago","map":{"lat":33.2148,"lng":-97.1331,"zoom":12}},{"name":"Houston","country":"USA","countrySlug":"usa","state":"Texas","slug":"houston","highlighted":false,"timezone":"America/Chicago","map":{"lat":29.7604,"lng":-95.3698,"zoom":12}},{"name":"Austin","country":"USA","countrySlug":"usa","state":"Texas","slug":"austin","highlighted":false,"timezone":"America/Chicago","map":{"lat":30.2672,"lng":-97.7431,"zoom":12}},{"name":"San Antonio","country":"USA","countrySlug":"usa","state":"Texas","slug":"san-antonio","highlighted":false,"timezone":"America/Chicago","map":{"lat":29.4241,"lng":-98.4936,"zoom":12}},{"name":"New Orleans","country":"USA","countrySlug":"usa","state":"Louisiana","slug":"new-orleans","highlighted":false,"timezone":"America/Chicago","map":{"lat":29.9511,"lng":-90.0715,"zoom":12}},{"name":"Miami","country":"USA","countrySlug":"usa","state":"Florida","slug":"miami","highlighted":true,"timezone":"America/Ne
35w_York","map":{"lat":25.7617,"lng":-80.1918,"zoom":12}},{"name":"Tampa","country":"USA","countrySlug":"usa","state":"Florida","slug":"tampa","highlighted":true,"timezone":"America/New_York","map":{"lat":27.9506,"lng":-82.4572,"zoom":12}},{"name":"Orlando","country":"USA","countrySlug":"usa","state":"Florida","slug":"orlando","highlighted":true,"timezone":"America/New_York","map":{"lat":28.5383,"lng":-81.3792,"zoom":12}},{"name":"Atlanta","country":"USA","countrySlug":"usa","state":"Georgia","slug":"atlanta","highlighted":false,"timezone":"America/New_York","map":{"lat":33.749,"lng":-84.388,"zoom":12}},{"name":"Charlotte","country":"USA","countrySlug":"usa","state":"North Carolina","slug":"charlotte","highlighted":false,"timezone":"America/New_York","map":{"lat":35.2271,"lng":-80.8431,"zoom":12}},{"name":"Nashville","country":"USA","countrySlug":"usa","state":"Tennessee","slug":"nashville","highlighted":false,"timezone":"America/Chicago","map":{"lat":36.1627,"lng":-86.7816,"zoom":11}},{"name":"Raleigh","country":"USA","countrySlug":"usa","state":"North Carolina","slug":"raleigh","highlighted":false,"timezone":"America/New_York","map":{"lat":35.7796,"lng":-78.6382,"zoom":12}},{"name":"Baltimore","country":"USA","countrySlug":"usa","state":"Maryland","slug":"baltimore","highlighted":true,"timezone":"America/New_York","map":{"lat":39.2904,"lng":-76.6122,"zoom":12}},{"name":"Pittsburgh","country":"USA","countrySlug":"usa","state":"Pennsylvania","slug":"pittsburgh","highlighted":false,"timezone":"America/New_York","map":{"lat":40.4406,"lng":-79.9959,"zoom":12}},{"name":"Cleveland","country":"USA","countrySlug":"usa","state":"Ohio","slug":"cleveland","highlighted":false,"timezone":"America/New_York","map":{"lat":41.4993,"lng":-81.6944,"zoom":12}},{"name":"Cincinnati","country":"USA","countrySlug":"usa","state":"Ohio","slug":"cincinnati","highlighted":false,"timezone":"America/New_York","map":{"lat":39.1031,"lng":-84.512,"zoom":12}},{"name":"Detroit","country":"USA","countrySlug":"usa","state":"Michigan","slug":"detroit","highlighted":false,"timezone":"America/Detroit","map":{"lat":42.3314,"lng":-83.0458,"zoom":12}},{"name":"Norfolk","country":"USA","countrySlug":"usa","state":"Virginia","slug":"norfolk","highlighted":false,"timezone":"America/New_York","map":{"lat":36.8508,"lng":-76.2859,"zoom":12}},{"name":"St. Louis","country":"USA","countrySlug":"usa","state":"Missouri","slug":"st-louis","highlighted":false,"timezone":"America/Chicago","map":{"lat":38.627,"lng":-90.1994,"zoom":12}},{"name":"Kansas City","country":"USA","countrySlug":"usa","state":"Missouri","slug":"kansas-city","highlighted":false,"timezone":"America/Chicago","map":{"lat":39.0997,"lng":-94.5786,"zoom":12}},{"name":"Albuquerque","country":"USA","countrySlug":"usa","state":"New Mexico","slug":"albuquerque","highlighted":false,"timezone":"America/Denver","map":{"lat":35.0844,"lng":-106.6504,"zoom":12}},{"name":"Burlington","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"burlington-ontario","highlighted":false,"timezone":"America/Toronto","map":{"lat":43.3255,"lng":-79.799,"zoom":12}},{"name":"Niagara Falls","country":"Canada","countrySlug":"canada","state":"Ontario","slug":"niagara-falls-ontario","highlighted":false,"timezone":"America/Toronto","map":{"lat":43.0896,"lng":-79.0849,"zoom":12}},{"name":"Mexico City","country":"Mexico","countrySlug":"mexico","state":"CDMX","slug":"mexico-city","highlighted":true,"timezone":"America/Mexico_City","map":{"lat":19.4326,"lng":-99.1332,"zoom":12}},{"name":"Medell\xedn","country":"Colombia","countrySlug":"colombia","state":"Antioquia","slug":"medellin","highlighted":false,"timezone":"America/Bogota","map":{"lat":6.2442,"lng":-75.5812,"zoom":12}},{"name":"Oklahoma City","country":"USA","countrySlug":"usa","state":"Oklahoma","slug":"oklahoma-city","highlighted":false,"timezone":"America/Chicago","map":{"lat":35.4676,"lng":-97.5164,"zoom":12}},{"name":"Oakland","country":"USA","countrySlug":"usa","state":"California","slug":"oakland","highlighted":false,"timezone":"America/Los_Angeles","map":{"lat":37.8044,"lng":-122.2712,"zoom":12}},{"name":"Sydney","country":"Australia","countrySlug":"australia","state":"New South Wales","slug":"sydney","highlighted":true,"timezone":"Australia/Sydney","map":{"lat":-33.8688,"lng":151.2093,"zoom":12}},{"name":"Newcastle","country":"Australia","countrySlug":"australia","state":"New South Wales","slug":"newcastle-nsw","highlighted":false,"timezone":"Australia/Sydney","map":{"lat":-32.9243,"lng":151.7739,"zoom":13}},{"name":"Perth","country":"Australia","countrySlug":"australia","state":"Western Australia","slug":"perth","highlighted":true,"timezone":"Australia/Perth","map":{"lat":-31.9523,"lng":115.8613,"zoom":12}},{"name":"Adelaide","country":"Australia","countrySlug":"australia","state":"South Australia","slug":"adelaide","highlighted":true,"timezone":"Australia/Adelaide","map":{"lat":-34.9285,"lng":138.6007,"zoom":12}},{"name":"Darwin","country":"Australia","countrySlug":"australia","state":"Northern Territory","slug":"darwin","highlighted":false,"timezone":"Australia/Darwin","map":{"lat":-12.4634,"lng":130.8456,"zoom":12}},{"name":"Pretoria","country":"South Africa","countrySlug":"south-africa","state":"Gauteng","slug":"pretoria","highlighted":true,"timezone":"Africa/Johannesburg","map":{"lat":-25.7479,"lng":28.2293,"zoom":12}},{"name":"Cape Town","country":"South Africa","countrySlug":"south-africa","state":"Western Cape","slug":"cape-town","highlighted":true,"timezone":"Africa/Johannesburg","map":{"lat":-33.9249,"lng":18.4241,"zoom":12}},{"name":"Melbourne","country":"Australia","countrySlug":"australia","state":"Victoria","slug":"melbourne","highlighted":true,"timezone":"Australia/Melbourne","map":{"lat":-37.8136,"lng":144.9631,"zoom":12}},{"name":"Brisbane","country":"Australia","countrySlug":"australia","state":"Queensland","slug":"brisbane","highlighted":true,"timezone":"Australia/Brisbane","map":{"lat":-27.4709,"lng":153.0235,"zoom":12}},{"name":"Kuala Lumpur","country":"Malaysia","countrySlug":"malaysia","state":"Kuala Lumpur","slug":"kuala-lumpur","highlighted":true,"timezone":"Asia/Kuala_Lumpur","map":{"lat":3.139,"lng":101.6869,"zoom":12}},{"name":"Auckland","country":"New-Zealand","countrySlug":"new-zealand","state":"Auckland","slug":"auckland","highlighted":true,"timezone":"Pacific/Auckland","map":{"lat":-36.8509,"lng":174.7645,"zoom":12}},{"name":"Wellington","country":"New-Zealand","countrySlug":"new-zealand","state":"Wellington","slug":"wellington","highlighted":true,"timezone":"Pacific/Auckland","map":{"lat":-41.2866,"lng":174.7756,"zoom":12}},{"name":"San Jose","country":"USA","countrySlug":"usa","state":"California","slug":"san-jose","highlighted":false,"timezone":"America/Los_Angeles","map":{"lat":37.3541,"lng":-121.9552,"zoom":12}},{"name":"Santa Clara","country":"USA","countrySlug":"usa","state":"California","slug":"santa-clara","highlighted":false,"timezone":"America/Los_Angeles","map":{"lat":37.3541,"lng":-121.9552,"zoom":12}},{"name":"Sonoma","country":"USA","countrySlug":"usa","state":"California","slug":"sonoma","highlighted":false,"timezone":"America/Los_Angeles","map":{"lat":38.2919,"lng":-122.458,"zoom":12}},{"name":"Marin","country":"USA","countrySlug":"usa","state":"California","slug":"marin","highlighted":false,"timezone":"America/Los_Angeles","map":{"lat":38.0834,"lng":-122.7633,"zoom":12}},{"name":"Santa Rosa","country":"USA","countrySlug":"usa","state":"California","slug":"santa-rosa","highlighted":false,"timezone":"America/Los_Angeles","map":{"lat":38.4405,"lng":-122.7144,"zoom":12}},{"name":"San Rafael","country":"USA","countrySlug":"usa","state":"California","slug":"san-rafael","highlighted":false,"timezone":"America/Los_Angeles","map":{"lat":37.9735,"lng":-122.5311,"zoom":12}},{"name":"Amsterdam","country":"Netherlands","countrySlug":"netherlands","state":"North Holland","slug":"amsterdam","highlighted":true,"timezone":"Europe/Amsterdam","map":{"lat":52.3676,"lng":4.9041,"zoom":12}},{"name":"Rotterdam","country":"Netherlands","countrySlug":"netherlands","state":"South Holland","slug":"rotterdam","highlighted":false,"timezone":"Europe/Amsterdam","map":{"lat":51.9225,"lng":4.4792,"zoom":12}},{"name":"Utrecht","country":"Netherlands","countrySlug":"netherlands","state":"Utrecht","slug":"utrecht","highlighted":false,"timezone":"Europe/Amsterdam","map":{"lat":52.0907,"lng":5.1214,"zoom":12}},{"name":"The Hague","country":"Netherlands","countrySlug":"netherlands","state":"South Holland","slug":"the-hague","highlighted":false,"timezone":"Europe/Amsterdam","map":{"lat":52.0705,"lng":4.3007,"zoom":12}},{"name":"Eindhoven","country":"Netherlands","countrySlug":"netherlands","state":"North Brabant","slug":"eindhoven","highlighted":false,"timezone":"Europe/Amsterdam","map":{"lat":51.4416,"lng":5.4697,"zoom":12}},{"name":"Groningen","country":"Netherlands","countrySlug":"netherlands","state":"Groningen","slug":"groningen","highlighted":false,"timezone":"Europe/Amsterdam","map":{"lat":53.2194,"lng":6.5665,"zoom":12}},{"name":"Prague","country":"Czechia","countrySlug":"czechia","state":null,"slug":"prague","highlighted":true,"timezone":"Europe/Prague","map":{"lat":50.0755,"lng":14.4378,"zoom":12}},{"name":"Krak\xf3w","country":"Poland","countrySlug":"poland","state":null,"slug":"krakow","highlighted":false,"timezone":"Europe/Warsaw","map":{"lat":50.0647,"lng":19.945,"zoom":12}},{"name":"Warsaw","country":"Poland","countrySlug":"poland","state":null,"slug":"warsaw","highlighted":true,"timezone":"Europe/Warsaw","map":{"lat":52.2297,"lng":21.0122,"zoom":12}},{"name":"PoznaÅ","country":"Poland","countrySlug":"poland","state":null,"slug":"poznan","highlighted":false,"timezone":"Europe/Warsaw","map":{"lat":52.4064,"lng":16.9252,"zoom":12}},{"name":"GdaÅsk","country":"Poland","countrySlug":"poland","state":null,"slug":"gdansk","highlighted":false,"timezone":"Europe/Warsaw","map":{"lat":54.352,"lng":18.6466,"zoom":12}},{"name":"Riga","country":"Latvia","countrySlug":"latvia","state":null,"slug":"riga","highlighted":false,"timezone":"Europe/Riga","map":{"lat":56.9496,"lng":24.1052,"zoom":12}},{"name":"Sofia","country":"Bulgaria","countrySlug":"bulgaria","state":null,"slug":"sofia","highlighted":false,"timezone":"Europe/Sofia","map":{"lat":42.6977,"lng":23.3219,"zoom":12}},{"name":"Bucharest","country":"Romania","countrySlug":"romania","state":null,"slug":"bucharest","highlighted":false,"timezone":"Europe/Bucharest","map":{"lat":44.4268,"lng":26.1025,"zoom":12}},{"name":"Cluj-Napoca","country":"Romania","countrySlug":"romania","state":null,"slug":"clujnapoca","highlighted":false,"timezone":"Europe/Bucharest","map":{"lat":46.7712,"lng":23.6236,"zoom":12}},{"name":"Budapest","country":"Hungary","countrySlug":"hungary","state":"Budapest","slug":"budapest","highlighted":true,"timezone":"Europe/Budapest","map":{"lat":47.4979,"lng":19.0402,"zoom":12}},{"name":"Oslo","country":"Norway","countrySlug":"norway","state":"Oslo","slug":"oslo","highlighted":true,"timezone":"Europe/Oslo","map":{"lat":59.9139,"lng":10.7522,"zoom":12}},{"name":"Bergen","country":"Norway","countrySlug":"norway","state":"Vestland","slug":"bergen","highlighted":false,"timezone":"Europe/Oslo","map":{"lat":60.3913,"lng":5.3221,"zoom":12}},{"name":"Trondheim","country":"Norway","countrySlug":"norway","state":"Tr\xf8ndelag","slug":"trondheim","highlighted":false,"timezone":"Europe/Oslo","map":{"lat":63.4305,"lng":10.3951,"zoom":12}},{"name":"Stavanger","country":"Norway","countrySlug":"norway","state":"Rogaland","slug":"stavanger","highlighted":false,"timezone":"Europe/Oslo","map":{"lat":58.969,"lng":5.7331,"zoom":12}},{"name":"Stockholm","country":"Sweden","countrySlug":"sweden","state":"Stockholm County","slug":"stockholm","highlighted":true,"timezone":"Europe/Stockholm","map":{"lat":59.3293,"lng":18.0686,"zoom":12}},{"name":"Gothenburg","country":"Sweden","countrySlug":"sweden","state":"V\xe4stra G\xf6taland County","slug":"gothenburg","highlighted":true,"timezone":"Europe/Stockholm","map":{"lat":57.7089,"lng":11.9746,"zoom":12}},{"name":"Malm\xf6","country":"Sweden","countrySlug":"sweden","state":"Sk\xe5ne County","slug":"malmo","highlighted":true,"timezone":"Europe/Stockholm","map":{"lat":55.604981,"lng":13.003822,"zoom":12}},{"name":"Uppsala","country":"Sweden","countrySlug":"sweden","state":"Uppsala County","slug":"uppsala","highlighted":false,"timezone":"Europe/Stockholm","map":{"lat":59.8586,"lng":17.6389,"zoom":12}},{"name":"V\xe4ster\xe5s","country":"Sweden","countrySlug":"sweden","state":"V\xe4stmanland County","slug":"vasteras","highlighted":false,"timezone":"Europe/Stockholm","map":{"lat":59.6099,"lng":16.5448,"zoom":12}},{"name":"\xd6rebro","country":"Sweden","countrySlug":"sweden","state":"\xd6rebro County","slug":"orebro","highlighted":false,"timezone":"Europe/Stockholm","map":{"lat":59.2753,"lng":15.2134,"zoom":12}},{"name":"Link\xf6ping","country":"Sweden","countrySlug":"sweden","state":"\xd6sterg\xf6tland County","slug":"linkoping","highlighted":false,"timezone":"Europe/Stockholm","map":{"lat":58.4108,"lng":15.6214,"zoom":12}},{"name":"Helsingborg","country":"Sweden","countrySlug":"sweden","state":"Sk\xe5ne County","slug":"helsingborg","highlighted":false,"timezone":"Europe/Stockholm","map":{"lat":56.0465,"lng":12.6945,"zoom":12}},{"name":"J\xf6nk\xf6ping","country":"Sweden","countrySlug":"sweden","state":"J\xf6nk\xf6ping County","slug":"jonkoping","highlighted":false,"timezone":"Europe/Stockholm","map":{"lat":57.7826,"lng":14.1618,"zoom":12}},{"name":"Norrk\xf6ping","country":"Sweden","countrySlug":"sweden","state":"\xd6sterg\xf6tland County","slug":"norrkoping","highlighted":false,"timezone":"Europe/Stockholm","map":{"lat":58.5877,"lng":16.1924,"zoom":12}},{"name":"Helsinki","country":"Finland","countrySlug":"finland","state":"Uusimaa","slug":"helsinki","highlighted":true,"timezone":"Europe/Helsinki","map":{"lat":60.1699,"lng":24.9384,"zoom":12}},{"name":"Espoo","country":"Finland","countrySlug":"finland","state":"Uusimaa","slug":"espoo","highlighted":false,"timezone":"Europe/Helsinki","map":{"lat":60.2055,"lng":24.6559,"zoom":12}},{"name":"Vantaa","country":"Finland","countrySlug":"finland","state":"Uusimaa","slug":"vantaa","highlighted":false,"timezone":"Europe/Helsinki","map":{"lat":60.2934,"lng":25.0378,"zoom":12}},{"name":"Kerava","country":"Finland","countrySlug":"finland","state":"Uusimaa","slug":"kerava","highlighted":false,"timezone":"Europe/Helsinki","map":{"lat":60.403,"lng":25.1056,"zoom":12}},{"name":"Kauniainen","country":"Finland","countrySlug":"finland","state":"Uusimaa","slug":"kauniainen","highlighted":false,"timezone":"Europe/Helsinki","map":{"lat":60.2167,"lng":24.7333,"zoom":13}},{"name":"Bod\xf8","country":"Norway","countrySlug":"norway","state":"Nordland","slug":"bodo","highlighted":false,"timezone":"Europe/Oslo","map":{"lat":67.2804,"lng":14.4049,"zoom":12}},{"name":"R\xf8ros","country":"Norway","countrySlug":"norway","state":"Tr\xf8ndelag","slug":"roros","highlighted":false,"timezone":"Europe/Oslo","map":{"lat":62.5748,"lng":11.3846,"zoom":12}},{"name":"Steinkjer","country":"Norway","countrySlug":"norway","state":"Tr\xf8ndelag","slug":"steinkjer","highlighted":false,"timezone":"Europe/Oslo","map":{"lat":64.0149,"lng":11.4951,"zoom":12}},{"name":"Kristiansand","country":"Norway","countrySlug":"norway","state":"Agder","slug":"kristiansand","highlighted":false,"timezone":"Europe/Oslo","map":{"lat":58.1467,"lng":7.9956,"zoom":12}},{"name":"Dublin","country":"Ireland","countrySlug":"ireland","state":"Leinster","slug":"dublin","highlighted":false,"timezone":"Europe/Dublin","map":{"lat":53.3498,"lng":-6.2603,"zoom":12}},{"name":"London","country":"United Kingdom","countrySlug":"united-kingdom","state":"England","slug":"london","highlighted":false,"timezone":"Europe/London","map":{"lat":51.5074,"lng":-0.1278,"zoom":12}},{"name":"Paris","country":"France","countrySlug":"france","state":"\xcele-de-France","slug":"paris","highlighted":false,"timezone":"Europe/Paris","map":{"lat":48.8566,"lng":2.3522,"zoom":12}},{"name":"Venice","country":"Italy","countrySlug":"italy","state":"Veneto","slug":"venice","highlighted":true,"timezone":"Europe/Rome","map":{"lat":45.4408,"lng":12.3155,"zoom":13}},{"name":"Brussels","country":"Belgium","countrySlug":"belgium","state":"Brussels","slug":"brussels","highlighted":fals
35e,"timezone":"Europe/Brussels","map":{"lat":50.8503,"lng":4.3517,"zoom":12}},{"name":"Edinburgh","country":"United Kingdom","countrySlug":"united-kingdom","state":"Scotland","slug":"edinburgh","highlighted":false,"timezone":"Europe/London","map":{"lat":55.9533,"lng":-3.1883,"zoom":12}},{"name":"Glasgow","country":"United Kingdom","countrySlug":"united-kingdom","state":"Scotland","slug":"glasgow","highlighted":false,"timezone":"Europe/London","map":{"lat":55.8642,"lng":-4.2518,"zoom":12}},{"name":"Manchester","country":"United Kingdom","countrySlug":"united-kingdom","state":"England","slug":"manchester","highlighted":false,"timezone":"Europe/London","map":{"lat":53.4808,"lng":-2.2426,"zoom":12}},{"name":"Birmingham","country":"United Kingdom","countrySlug":"united-kingdom","state":"England","slug":"birmingham","highlighted":false,"timezone":"Europe/London","map":{"lat":52.4862,"lng":-1.8904,"zoom":12}},{"name":"Leeds","country":"United Kingdom","countrySlug":"united-kingdom","state":"England","slug":"leeds","highlighted":false,"timezone":"Europe/London","map":{"lat":53.8008,"lng":-1.5491,"zoom":12}},{"name":"Liverpool","country":"United Kingdom","countrySlug":"united-kingdom","state":"England","slug":"liverpool","highlighted":false,"timezone":"Europe/London","map":{"lat":53.4084,"lng":-2.9916,"zoom":12}},{"name":"Bristol","country":"United Kingdom","countrySlug":"united-kingdom","state":"England","slug":"bristol","highlighted":false,"timezone":"Europe/London","map":{"lat":51.4545,"lng":-2.5879,"zoom":12}},{"name":"Cardiff","country":"United Kingdom","countrySlug":"united-kingdom","state":"Wales","slug":"cardiff","highlighted":false,"timezone":"Europe/London","map":{"lat":51.4816,"lng":-3.1791,"zoom":12}},{"name":"Santiago","country":"Chile","countrySlug":"chile","state":"Santiago Metropolitan","slug":"santiago","highlighted":true,"timezone":"America/Santiago","map":{"lat":-33.4489,"lng":-70.6693,"zoom":11}},{"name":"Madrid","country":"Spain","countrySlug":"spain","state":"Madrid","slug":"madrid","highlighted":true,"timezone":"Europe/Madrid","map":{"lat":40.4168,"lng":-3.7038,"zoom":11}},{"name":"Barcelona","country":"Spain","countrySlug":"spain","state":"Catalonia","slug":"barcelona","highlighted":true,"timezone":"Europe/Madrid","map":{"lat":41.3874,"lng":2.1686,"zoom":11}},{"name":"Buenos Aires","country":"Argentina","countrySlug":"argentina","state":"Buenos Aires","slug":"buenos-aires","highlighted":true,"timezone":"America/Argentina/Buenos_Aires","map":{"lat":-34.6037,"lng":-58.3816,"zoom":11}},{"name":"Phoenix","country":"USA","countrySlug":"usa","state":"Arizona","slug":"phoenix","highlighted":true,"timezone":"America/Phoenix","map":{"lat":33.4484,"lng":-112.074,"zoom":11}},{"name":"New Delhi","country":"India","countrySlug":"india","state":"Delhi","slug":"new-delhi","highlighted":true,"timezone":"Asia/Kolkata","map":{"lat":28.6139,"lng":77.209,"zoom":11}},{"name":"Mumbai","country":"India","countrySlug":"india","state":"Maharashtra","slug":"mumbai","highlighted":true,"timezone":"Asia/Kolkata","map":{"lat":19.076,"lng":72.8777,"zoom":11}},{"name":"Cairo","country":"Egypt","countrySlug":"egypt","state":null,"slug":"cairo","highlighted":true,"timezone":"Africa/Cairo","map":{"lat":30.0444,"lng":31.2357,"zoom":11}},{"name":"Casablanca","country":"Morocco","countrySlug":"morocco","state":null,"slug":"casablanca","highlighted":true,"timezone":"Africa/Casablanca","map":{"lat":33.5731,"lng":-7.5898,"zoom":11}},{"name":"Rome","country":"Italy","countrySlug":"italy","state":null,"slug":"rome","highlighted":false,"timezone":"Europe/Rome","map":{"lat":41.9028,"lng":12.4964,"zoom":12}},{"name":"Turin","country":"Italy","countrySlug":"italy","state":null,"slug":"turin","highlighted":false,"timezone":"Europe/Rome","map":{"lat":45.0703,"lng":7.6869,"zoom":12}},{"name":"Zagreb","country":"Croatia","countrySlug":"croatia","state":null,"slug":"zagreb","highlighted":false,"timezone":"Europe/Zagreb","map":{"lat":45.815,"lng":15.9819,"zoom":12}},{"name":"IaÈi","country":"Romania","countrySlug":"romania","state":null,"slug":"iasi","highlighted":false,"timezone":"Europe/Bucharest","map":{"lat":47.1585,"lng":27.6014,"zoom":12}},{"name":"Szczecin","country":"Poland","countrySlug":"poland","state":null,"slug":"szczecin","highlighted":false,"timezone":"Europe/Warsaw","map":{"lat":53.4285,"lng":14.5528,"zoom":12}},{"name":"Katowice","country":"Poland","countrySlug":"poland","state":null,"slug":"katowice","highlighted":false,"timezone":"Europe/Warsaw","map":{"lat":50.2649,"lng":19.0238,"zoom":11}},{"name":"Lviv","country":"Ukraine","countrySlug":"ukraine","state":null,"slug":"lviv","highlighted":false,"timezone":"Europe/Kyiv","map":{"lat":49.8397,"lng":24.0297,"zoom":12}},{"name":"Jerusalem","country":"Israel","countrySlug":"israel","state":null,"slug":"jerusalem","highlighted":false,"timezone":"Asia/Jerusalem","map":{"lat":31.7683,"lng":35.2137,"zoom":12}},{"name":"Tel Aviv","country":"Israel","countrySlug":"israel","state":null,"slug":"tel-aviv","highlighted":false,"timezone":"Asia/Jerusalem","map":{"lat":32.0853,"lng":34.7818,"zoom":12}},{"name":"Tallinn","country":"Estonia","countrySlug":"estonia","state":null,"slug":"tallinn","highlighted":false,"timezone":"Europe/Tallinn","map":{"lat":59.437,"lng":24.7536,"zoom":12}},{"name":"Hong Kong","country":"Hong Kong","countrySlug":"hong-kong","state":null,"slug":"hong-kong","highlighted":true,"timezone":"Asia/Hong_Kong","map":{"lat":22.3193,"lng":114.1694,"zoom":11}},{"name":"Canberra","country":"Australia","countrySlug":"australia","state":"Australian Capital Territory","slug":"canberra","highlighted":false,"timezone":"Australia/Sydney","map":{"lat":-35.2809,"lng":149.13,"zoom":12}},{"name":"Manila","country":"Philippines","countrySlug":"philippines","state":"Metro Manila","slug":"manila","highlighted":true,"timezone":"Asia/Manila","map":{"lat":14.5995,"lng":120.9842,"zoom":11}},{"name":"Singapore","country":"Singapore","countrySlug":"singapore","state":null,"slug":"singapore","highlighted":true,"timezone":"Asia/Singapore","map":{"lat":1.3521,"lng":103.8198,"zoom":11}},{"name":"Florence","country":"Italy","countrySlug":"italy","state":null,"slug":"florence","highlighted":false,"timezone":"Europe/Rome","map":{"lat":43.7696,"lng":11.2558,"zoom":12}},{"name":"Milan","country":"Italy","countrySlug":"italy","state":null,"slug":"milan","highlighted":true,"timezone":"Europe/Rome","map":{"lat":45.4642,"lng":9.19,"zoom":12}},{"name":"Cagliari","country":"Italy","countrySlug":"italy","state":null,"slug":"cagliari","highlighted":false,"timezone":"Europe/Rome","map":{"lat":39.2238,"lng":9.1217,"zoom":12}},{"name":"Lisbon","country":"Portugal","countrySlug":"portugal","state":null,"slug":"lisbon","highlighted":true,"timezone":"Europe/Lisbon","map":{"lat":38.7223,"lng":-9.1393,"zoom":12}},{"name":"Hartford","country":"USA","countrySlug":"usa","state":"Connecticut","slug":"hartford","highlighted":false,"timezone":"America/Ne
35w_York","map":{"lat":41.7658,"lng":-72.6734,"zoom":12}},{"name":"Kyiv","country":"Ukraine","countrySlug":"ukraine","state":null,"slug":"kyiv","highlighted":true,"timezone":"Europe/Kyiv","map":{"lat":50.4501,"lng":30.5234,"zoom":12}},{"name":"Hanoi","country":"Vietnam","countrySlug":"vietnam","state":null,"slug":"hanoi","highlighted":true,"timezone":"Asia/Ho_Chi_Minh","map":{"lat":21.0285,"lng":105.8542,"zoom":11}},{"name":"Ho Chi Minh City","country":"Vietnam","countrySlug":"vietnam","state":null,"slug":"ho-chi-minh-city","highlighted":true,"timezone":"Asia/Ho_Chi_Minh","map":{"lat":10.8231,"lng":106.6297,"zoom":11}},{"name":"Beijing","country":"China","countrySlug":"china","state":null,"slug":"beijing","highlighted":true,"timezone":"Asia/Shanghai","map":{"lat":39.9042,"lng":116.4074,"zoom":10}},{"name":"Shanghai","country":"China","countrySlug":"china","state":null,"slug":"shanghai","highlighted":true,"timezone":"Asia/Shanghai","map":{"lat":31.2304,"lng":121.4737,"zoom":10}},{"name":"Shenzhen","country":"China","countrySlug":"china","state":null,"slug":"shenzhen","highlighted":true,"timezone":"Asia/Shanghai","map":{"lat":22.5431,"lng":114.0579,"zoom":10}},{"name":"Guangzhou","country":"China","countrySlug":"china","state":null,"slug":"guangzhou","highlighted":true,"timezone":"Asia/Shanghai","map":{"lat":23.1291,"lng":113.2644,"zoom":10}},{"name":"Bangkok","country":"Thailand","countrySlug":"thailand","state":null,"slug":"bangkok","highlighted":true,"timezone":"Asia/Bangkok","map":{"lat":13.7563,"lng":100.5018,"zoom":10}},{"name":"Alexandria","country":"Egypt","countrySlug":"egypt","state":null,"slug":"alexandria","highlighted":true,"timezone":"Africa/Cairo","map":{"lat":31.2001,"lng":29.9187,"zoom":11}},{"name":"Almaty","country":"Kazakhstan","countrySlug":"kazakhstan","state":null,"slug":"almaty","highlighted":true,"timezone":"Asia/Almaty","map":{"lat":43.222,"lng":76.8512,"zoom":11}},{"name":"Astana","country":"Kazakhstan","countrySlug":"kazakhstan","state":null,"slug":"astana","highlighted":true,"timezone":"Asia/Almaty","map":{"lat":51.1694,"lng":71.4491,"zoom":11}},{"name":"Jakarta","country":"Indonesia","countrySlug":"indonesia","state":null,"slug":"jakarta","highlighted":true,"timezone":"Asia/Jakarta","map":{"lat":-6.2088,"lng":106.8456,"zoom":10}},{"name":"Surabaya","country":"Indonesia","countrySlug":"indonesia","state":null,"slug":"surabaya","highlighted":true,"timezone":"Asia/Jakarta","map":{"lat":-7.2575,"lng":112.7521,"zoom":11}},{"name":"Bandung","country":"Indonesia","countrySlug":"indonesia","state":null,"slug":"bandung","highlighted":true,"timezone":"Asia/Jakarta","map":{"lat":-6.9175,"lng":107.6191,"zoom":11}},{"name":"Vilnius","country":"Lithuania","countrySlug":"lithuania","slug":"vilnius","highlighted":false,"timezone":"Europe/Vilnius","map":{"lat":54.6872,"lng":25.2797,"zoom":11}},{"name":"Belgrade","country":"Serbia","countrySlug":"serbia","slug":"belgrade","highlighted":false,"timezone":"Europe/Belgrade","map":{"lat":44.8125,"lng":20.4612,"zoom":11}},{"name":"Pristina","country":"Kosovo","countrySlug":"kosovo","slug":"pristina","highlighted":false,"timezone":"Europe/Belgrade","map":{"lat":42.6629,"lng":21.1655,"zoom":11}},{"name":"Skopje","country":"North Macedonia","countrySlug":"north-macedonia","slug":"skopje","highlighted":false,"timezone":"Europe/Skopje","map":{"lat":41.9981,"lng":21.4254,"zoom":11}},{"name":"S\xe3o Paulo","slug":"sao-paulo","country":"Brazil","countrySlug":"brazil","state":"S\xe3o Paulo","highlighted":true,"timezone":"America/Sao_Paulo","map":{"lat":-23.5505,"lng":-46.6333,"zoom":11}},{"name":"Rio de Janeiro","slug":"rio-de-janeiro","country":"Brazil","countrySlug":"brazil","state":"Rio de Janeiro","highlighted":true,"timezone":"America/Sao_Paulo","map":{"lat":-22.9068,"lng":-43.1729,"zoom":11}},{"name":"Panama City","slug":"panama-city","country":"Panama","countrySlug":"panama","state":"Panam\xe1","highlighted":true,"timezone":"America/Panama","map":{"lat":8.9824,"lng":-79.5199,"zoom":11}},{"name":"Las Vegas","country":"USA","countrySlug":"usa","state":"Nevada","slug":"las-vegas","highlighted":false,"timezone":"America/Los_Angeles","map":{"lat":36.129,"lng":-115.153,"zoom":13}},{"name":"Nairobi","country":"Kenya","countrySlug":"kenya","slug":"nairobi","highlighted":false,"timezone":"Africa/Nairobi","map":{"lat":-1.2864,"lng":36.8172,"zoom":11}},{"name":"Mombasa","country":"Kenya","countrySlug":"kenya","slug":"mombasa","highlighted":false,"timezone":"Africa/Nairobi","map":{"lat":-4.0435,"lng":39.6682,"zoom":11}},{"name":"Lima","country":"Peru","countrySlug":"peru","state":"","slug":"lima","highlighted":false,"timezone":"America/Lima","map":{"lat":-12.08,"lng":-77,"zoom":12}},{"name":"Quito","country":"Ecuador","countrySlug":"ecuador","state":"","slug":"quito","highlighted":false,"timezone":"America/Guayaquil","map":{"lat":-0.22,"lng":-78.5,"zoom":12}},{"name":"Cuenca","country":"Ecuador","countrySlug":"ecuador","state":"","slug":"cuenca","highlighted":false,"timezone":"America/Guayaquil","map":{"lat":-2.9,"lng":-79,"zoom":12}},{"name":"Cochabamba","country":"Bolivia","countrySlug":"bolivia","state":"","slug":"cochabamba","highlighted":false,"timezone":"America/La_Paz","map":{"lat":-17.4,"lng":-66.2,"zoom":12}},{"name":"San Juan","country":"Puerto Rico","countrySlug":"puerto-rico","state":"","slug":"san-juan","highlighted":false,"timezone":"America/Puerto_Rico","map":{"lat":18.41,"lng":-66.102,"zoom":12}},{"name":"San Jos\xe9","country":"Costa Rica","countrySlug":"costa-rica","state":"","slug":"san-jose-costa-rica","highlighted":false,"timezone":"America/Costa_Rica","map":{"lat":9.9333,"lng":-84.0833,"zoom":11}},{"name":"Dakar","country":"Senegal","countrySlug":"senegal","slug":"dakar","highlighted":false,"timezone":"Africa/Dakar","map":{"lat":14.727,"lng":-17.32,"zoom":11}},{"name":"Santo Domingo","slug":"santo-domingo","country":"Dominican Republic","countrySlug":"dominican-republic","state":"Distrito Nacional","highlighted":true,"timezone":"America/Santo_Domingo","map":{"lat":18.495,"lng":-69.935,"zoom":11}},{"name":"Maracaibo","slug":"maracaibo","country":"Venezuela","countrySlug":"venezuela","state":"Zulia","highlighted":true,"timezone":"America/Caracas","map":{"lat":10.628,"lng":-71.645,"zoom":12}},{"name":"Tunis","country":"Tunisia","countrySlug":"tunisia","slug":"tunis","highlighted":false,"timezone":"Africa/Tunis","map":{"lat":36.8,"lng":10.17,"zoom":11}},{"name":"Lagos","country":"Nigeria","countrySlug":"nigeria","slug":"lagos","highlighted":false,"timezone":"Africa/Lagos","map":{"lat":6.52,"lng":3.36,"zoom":11}},{"name":"Ibadan","country":"Nigeria","countrySlug":"nigeria","slug":"ibadan","highlighted":false,"timezone":"Africa/Lagos","map":{"lat":7.45,"lng":3.9,"zoom":11}},{"name":"Makkah","country":"Saudi Arabia","countrySlug":"saudi-arabia","slug":"makkah","highlighted":true,"timezone":"Asia/Riyadh","map":{"lat":21.3891,"lng":39.8579,"zoom":11}},{"name":"Jeddah","country":"Saudi Arabia","countrySlug":"saudi-arabia","slug":"jeddah","highlighted":true,"timezone":"Asia/Riyadh","map":{"lat":21.4858,"lng":39.1925,"zoom":11}},{"name":"Madinah","country":"Saudi Arabia","countrySlug":"saudi-arabia","slug":"madinah","highlighted":true,"timezone":"Asia/Riyadh","map":{"lat":24.5247,"lng":39.5692,"zoom":11}}]');class n{constructor(e){this.name=e.name,this.country=e.country,this.countrySlug=e.countrySlug,this.state=e.state,this.slug=e.slug,this.highlighted=e.highlighted,this.timezone=e.timezone,this.map={...e.map}}toJSON(){return{name:this.name,country:this.country,countrySlug:this.countrySlug,state:this.state??null,slug:this.slug,highlighted:this.highlighted,timezone:this.timezone,map:{...this.map}}}getFormattedLocation(){return`${this.name}, ${this.state}, ${this.country}`}
35getLocalTime(){return new Date(new Date().toLocaleString("en-US",{timeZone:this.timezone}))}}class a{constructor(){this.cities=new Map,i.forEach(e=>{this.cities.set(e.slug,new n(e))})}static getInstance(){return a._instance||(a._instance=new a),a._instance}getCity(e){return this.cities.get(e)}getAllCities(){return Array.from(this.cities.values())}getHighlightedCities(){return this.getAllCities().filter(e=>e.highlighted)}getCitiesByCountry(e){let t=e.toLowerCase();return this.getAllCities().filter(e=>(e.countrySlug||"").toLowerCase()===t)}getCitiesByState(e,t){let r=t.toLowerCase();return this.getAllCities().filter(t=>t.state.toLowerCase()===e.toLowerCase()&&(t.countrySlug||"").toLowerCase()===r)}searchCities(e){let t=e.toLowerCase();return this.getAllCities().filter(e=>e.name.toLowerCase().includes(t)||e.state.toLowerCase().includes(t)||e.country.toLowerCase().includes(t))}}let s=a.getInstance()}},e=>{var t=t=>e(e.s=t);e.O(0,[6593,8792],()=>(t(56556),t(7640))),_N_E=e.O()}]);
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.