Spaces:
Running
Running
| function base64ToUrl(base64, mimeType = '') { | |
| // Split the base64 string if it contains a data URL prefix | |
| const [prefix, data] = base64.includes(',') ? base64.split(',') : ['', base64]; | |
| // Try to extract the MIME type from the prefix if not provided | |
| const mime = mimeType || (prefix.match(/data:(.*?);base64/) || [])[1] || 'application/octet-stream'; | |
| // Decode base64 to raw binary data | |
| const binary = atob(data); | |
| const len = binary.length; | |
| const bytes = new Uint8Array(len); | |
| for (let i = 0; i < len; i++) { | |
| bytes[i] = binary.charCodeAt(i); | |
| } | |
| // Create a blob and generate a URL | |
| const blob = new Blob([bytes], { type: mime }); | |
| return URL.createObjectURL(blob); | |
| } | |
| function getElementByXpath(path, timeout = 5000) { | |
| return new Promise((resolve, reject) => { | |
| const intervalTime = 500; | |
| let elapsedTime = 0; | |
| const interval = setInterval(() => { | |
| let node = document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; | |
| if (node) { | |
| clearInterval(interval); | |
| resolve(node); | |
| } | |
| elapsedTime += intervalTime; | |
| if (elapsedTime >= timeout) { | |
| clearInterval(interval); | |
| reject(new Error(`XPath "${path}" not found within ${timeout}ms`)); | |
| } | |
| }, intervalTime); | |
| }); | |
| } | |
| async function uploadFileFromURL(url, filename, file_element) { | |
| try { | |
| if (!file_element) throw new Error("File input element not found."); | |
| const response = await fetch(url); | |
| if (!response.ok) throw new Error(`Failed to fetch file: ${response.statusText}`); | |
| const blob = await response.blob(); | |
| const newFile = new File([blob], filename, { type: blob.type }); | |
| const dataTransfer = new DataTransfer(); | |
| if (file_element.multiple) { | |
| for (const file of file_element.files) { | |
| dataTransfer.items.add(file); | |
| } | |
| } | |
| dataTransfer.items.add(newFile); | |
| file_element.files = dataTransfer.files; | |
| file_element.dispatchEvent(new Event("change", { bubbles: true })); | |
| } catch (error) { | |
| console.error("Error:", error); | |
| } | |
| } | |
| function waitForElement(selector, timeout = 5000) { | |
| return new Promise((resolve, reject) => { | |
| const intervalTime = 500; | |
| let elapsedTime = 0; | |
| const interval = setInterval(() => { | |
| const element = document.querySelector(selector); | |
| if (element) { | |
| clearInterval(interval); | |
| resolve(element); | |
| } | |
| elapsedTime += intervalTime; | |
| if (elapsedTime >= timeout) { | |
| clearInterval(interval); | |
| reject(new Error(`Element "${selector}" not found within ${timeout}ms`)); | |
| } | |
| }, intervalTime); | |
| }); | |
| } | |
| document.addEventListener("DOMContentLoaded", function () { | |
| getElementByXpath("//*[text()='Hide top bar']", 5000) | |
| .then((node) => { | |
| node.scrollIntoView(); | |
| node.click(); | |
| return waitForElement("#midi_file_input"); | |
| }) | |
| .then((file_upload) => { | |
| if (!file_upload) throw new Error("File input element not found."); | |
| // Wait for stability before proceeding | |
| return new Promise(resolve => setTimeout(() => resolve(file_upload), 500)); | |
| }) | |
| .then((file_upload) => { | |
| return waitForElement(".show_top_button").then((node) => { | |
| node.remove(); | |
| selector = document.getElementById("renderer_mode_selector"); | |
| selector.selectedIndex = 2; | |
| selector.dispatchEvent(new Event('change')); | |
| // return uploadFileFromURL("/output.mid", "output.mid", file_upload); | |
| }); | |
| }) | |
| .catch((error) => { | |
| console.error("Error:", error); | |
| }); | |
| }); | |
| window.addEventListener("message", async (event) => { | |
| if (event.data?.type === "load-midi" && event.data.name) { | |
| const url = event.data.url; | |
| const file_name = event.data.name | |
| const input = document.getElementById("midi_file_input"); | |
| if (url && input) { | |
| await uploadFileFromURL(url, file_name, input); | |
| } | |
| } | |
| }); | |