const BASE_MAP_URL = new URL("/public-transport/lines/", document.baseURI) const DAY_IN_MS = 8.64e+7; async function waitForElement(iframe, selector, options = { timeout: 15000, multiple: false }){ let timeout = options?.timeout || 15000 let multiple = options?.multiple || false let el = null; let startDate = Date.now() if(multiple){ while(!( el = iframe.contentWindow.document.querySelectorAll(selector) )?.length){ await new Promise(res => setTimeout(res, 500)) if(Date.now() > startDate+timeout) { throw new Error("Element search timeout") } } } else { while(( el = iframe.contentWindow.document.querySelector(selector) ) == null){ await new Promise(res => setTimeout(res, 500)) if(Date.now() > startDate+timeout) { throw new Error("Element search timeout") } } } return el } async function spawnIframe(url){ /** @type {HTMLIFrameElement} */ let iframe = document.createElement("iframe") let container = document.createElement("div") container.classList.add("thinking") container.style.left = Math.round(Math.random()*(window.innerWidth-400))+"px" container.style.top = Math.round(Math.random()*(window.innerHeight-350))+"px" let img = document.createElement("img") img.src = "/lol/math.gif" container.append(img) container.append(iframe) document.body.append(container) await navigateIframe(iframe, url) return iframe } async function navigateIframe(iframe, url){ let prom = new Promise(res => iframe.addEventListener("load", res(), {once: true})) iframe.src = new URL(url, BASE_MAP_URL).toString() await prom return iframe } async function getLineDetails(iframe){ let lineElement = await waitForElement(iframe, `[class|="content"] [class|="pictoAndDirection"]`) let linePictoElement = await waitForElement(iframe, `[class|="content"] [class|="linePictoSvg"]`) let directionTextElement = await waitForElement(iframe, `[class|="content"] [class|="directionText"]`) let line = { displayName: lineElement.getAttribute("aria-label"), picto: linePictoElement.src, name: linePictoElement.getAttribute("aria-label"), direction: directionTextElement.innerText, timetable: null } return line } async function getStopTimeTable(iframe, stop_description, amount=1){ let timetable = [] for(let dayOffset = 0; dayOffset { iframe.parentElement.remove() }, Math.random()*1000) return nextPassage }