Files
Horizon-OC/docs/main.js
souldbminersmwc 962b8bc0a0 high ram oc
2025-09-09 16:39:28 -04:00

492 lines
24 KiB
JavaScript

var __awaiter = this && this.__awaiter || function(e, t, i, n) {
return new(i || (i = Promise))((function(a, r) {
function s(e) {
try {
o(n.next(e))
} catch (e) {
r(e)
}
}
function l(e) {
try {
o(n.throw(e))
} catch (e) {
r(e)
}
}
function o(e) {
var t;
e.done ? a(e.value) : (t = e.value, t instanceof i ? t : new i((function(e) {
e(t)
}))).then(s, l)
}
o((n = n.apply(e, t || [])).next())
}))
};
const CUST_REV_ADV = 2;
var CustPlatform;
! function(e) {
e[e.Undefined = 0] = "Undefined", e[e.Erista = 1] = "Erista", e[e.Mariko = 2] = "Mariko", e[e.All = 3] = "All"
}(CustPlatform || (CustPlatform = {}));
class CustEntry {
constructor(e, t, i, n, a, r, s = [0, 1e6], l = 1, o = !0) {
this.id = e, this.name = t, this.platform = i, this.size = n, this.desc = a, this.defval = r, this.step = l, this.zeroable = o, this.min = s[0], this.max = s[1]
}
validate() {
let e = new ErrorToolTip(this.id).clear();
return Number.isNaN(this.value) || void 0 === this.value ? (e.setMsg("Invalid value: Not a number").show(), !1) : !(!this.zeroable || 0 != this.value) || (this.value < this.min || this.value > this.max ? (e.setMsg(`Expected range: [${this.min}, ${this.max}], got ${this.value}.`).show(), !1) : this.value % this.step == 0 || (e.setMsg(`${this.value} % ${this.step} ≠ 0`).show(), !1))
}
getInputElement() {
return document.getElementById(this.id)
}
updateValueFromElement() {
var e;
this.value = Number(null === (e = this.getInputElement()) || void 0 === e ? void 0 : e.value)
}
isAvailableFor(e) {
return e === CustPlatform.Undefined || this.platform === e || this.platform === CustPlatform.All
}
createElement() {
let e = this.getInputElement();
if (!e) {
let t = document.createElement("div");
t.classList.add("grid", "cust-element"), e = document.createElement("input"), e.min = String(this.zeroable ? 0 : this.min), e.max = String(this.max), e.id = this.id, e.type = "number", e.step = String(this.step);
let i = document.createElement("label");
i.setAttribute("for", this.id), i.innerHTML = this.name, i.appendChild(e), t.appendChild(i);
let n = document.createElement("blockquote");
n.innerHTML = "<ul>" + this.desc.map((e => `<li>${e}</li>`)).join("") + "</ul>", n.setAttribute("for", this.id), t.appendChild(n), document.getElementById("config-list-basic").appendChild(t), new ErrorToolTip(this.id).addChangeListener()
}
e.value = String(this.value)
}
setElementValue() {
this.getInputElement().value = String(this.value)
}
setElementDefaultValue() {
this.getInputElement().value = String(this.defval)
}
removeElement() {
let e = this.getInputElement();
e && e.parentElement.parentElement.remove()
}
showElement() {
let e = this.getInputElement();
e && e.parentElement.parentElement.style.removeProperty("display")
}
hideElement() {
let e = this.getInputElement();
e && e.parentElement.parentElement.style.setProperty("display", "none")
}
}
class AdvEntry extends CustEntry {
createElement() {
let e = this.getInputElement();
if (!e) {
let t = document.createElement("div");
t.classList.add("grid", "cust-element"), e = document.createElement("input"), e.min = String(this.zeroable ? 0 : this.min), e.max = String(this.max), e.id = this.id, e.type = "number", e.step = String(this.step);
let i = document.createElement("label");
i.setAttribute("for", this.id), i.innerHTML = this.name, i.appendChild(e), t.appendChild(i);
let n = document.createElement("blockquote");
n.innerHTML = "<ul>" + this.desc.map((e => `<li>${e}</li>`)).join("") + "</ul>", n.setAttribute("for", this.id), t.appendChild(n), document.getElementById("config-list-advanced").appendChild(t), new ErrorToolTip(this.id).addChangeListener()
}
e.value = String(this.value)
}
}
class GpuEntry extends CustEntry {
constructor(e, t, i = CustPlatform.Mariko, n = 4, a = ["range: vMin ≤ x ≤ 960 (Zero is disabled)"], r = 480, s = [0, 960], l = 5, o = !1) {
super(e, t, i, n, a, r, s, l, o), this.id = e, this.name = t, this.platform = i, this.size = n, this.desc = a, this.defval = r, this.step = l, this.zeroable = o
}
createElement() {
let e = this.getInputElement();
if (!e) {
let t = document.createElement("div");
t.classList.add("grid", "cust-element"), e = document.createElement("input"), e.min = String(this.zeroable ? 0 : this.min), e.max = String(this.max), e.id = this.id, e.type = "number", e.step = String(this.step);
let i = document.createElement("label");
i.setAttribute("for", this.id), i.innerHTML = this.name, i.appendChild(e), t.appendChild(i);
let n = document.createElement("blockquote");
n.innerHTML = "<ul>" + this.desc.map((e => `<li>${e}</li>`)).join("") + "</ul>", n.setAttribute("for", this.id), t.appendChild(n), document.getElementById("config-list-gpu").appendChild(t), new ErrorToolTip(this.id).addChangeListener()
}
e.value = String(this.value)
}
}
var CustTable = [
new CustEntry("mtcConf", "DRAM Timing", CustPlatform.All, 4, [
"<b>0</b>: AUTO_ADJ_ALL: Auto adjust mtc table with LPDDR4 3733 Mbps specs, 8Gb density. Change timing with Advanced Config (Default)",
"<b>1</b>: CUSTOM_ADJ_ALL: Adjust only non-zero preset timings in Advanced Config",
"<b>2</b>: NO_ADJ_ALL: Use 1600 mtc table wihout adjusting (Timing becomes tighter if you raise dram clock)."
], 0, [0, 2], 1),
new CustEntry("commonCpuBoostClock", "Boost Clock in kHz", CustPlatform.All, 4, [
"System default: 1785000",
"Boost clock will be applied when applications request Boost Mode via performance configuration."
], 1785000, [204000, 2907000], 1, !1),
new CustEntry("commonEmcMemVolt", "EMC Vdd2 Voltage in uV", CustPlatform.All, 4, [
"Acceptable range: 1100000 ≤ x ≤ 1250000, and it should be divided evenly by 12500.",
"Erista Default: 1175000",
"Mariko Default: 1175000",
"Official LPDDR4(X) voltage: 1175mV (1175mV nominal)"
], 1175000, [11e5, 125e4], 12500),
new CustEntry("eristaCpuMaxVolt", "Erista CPU Max Voltage in mV", CustPlatform.Erista, 4, [
"Acceptable range: 1120 ≤ x ≤ 1300",
"Default: 1235"
], 1235, [1000, 1500], 1),
new CustEntry("eristaEmcMaxClock", "Erista RAM Max Clock in kHz", CustPlatform.Erista, 4, [
"Values should be ≥ 1600000, and divided evenly by 3200.",
"Recommended Clocks: 1862400, 2131200 (JEDEC)",
"<b>WARNING:</b> RAM overclock could be UNSTABLE if timing parameters are not suitable for your DRAM"
], 1862400, [16e5, 2428800], 3200),
new CustEntry("marikoCpuMaxVolt", "Mariko CPU Max Voltage in mV", CustPlatform.Mariko, 4, [
"System default: 1120",
"Acceptable range: 1120 ≤ x ≤ 1300",
"Changing this value affects cpu voltage calculation"
], 1235, [1120, 1300], 5),
new CustEntry("marikoEmcMaxClock", "Mariko RAM Max Clock in kHz", CustPlatform.Mariko, 4, [
"Values should be ≥ 1600000, and divided evenly by 9600.",
"Recommended Clocks: 1862400, 2131200, 2400000, etc. (JEDEC)",
"<b>WARNING:</b> RAM overclock could be UNSTABLE if timing parameters are not suitable for your DRAM."
], 1996800, [16e5, 3200000], 3200),
new CustEntry("marikoEmcVddqVolt", "EMC Vddq (Mariko Only) Voltage in uV", CustPlatform.Mariko, 4, [
"Acceptable range: 550000 ≤ x ≤ 650000",
"Value should be divided evenly by 5000",
"Default: 600000",
"Official lpddr4(x) range: 570mV~650mV (600mV nominal)",
"Not enabled by default."
], 600000, [55e4, 65e4], 5e3),
new CustEntry("marikoCpuUV", "Enable Mariko CPU Undervolt", CustPlatform.Mariko, 4, [
"Reduce CPU power draw",
"<b>0</b> : Default Table",
"<b>1</b> : Undervolt Level 1 (SLT - CPU speedo < 1650)",
"<b>2</b> : Undervolt Level 1 (SLT - CPU speedo >= 1650)"
], 0, [0, 2], 1),
new CustEntry("marikoGpuUV", "Enable Mariko GPU Undervolt", CustPlatform.Mariko, 4, [
"Reduce GPU power draw",
"Your GPU might not withstand undervolt, and can hang your console, or crash games",
"Undervolting too much will drop GPU performance even if it seems stable",
"GPU voltages are dynamic and will change with temperature and gpu speedo",
"<b>0</b> : Default Table",
"<b>1</b> : Undervolt Level 1 (SLT: Aggressive)",
"<b>2</b> : Undervolt Level 2 (HiOPT: Drastic)",
"<b>3</b> : Custom static GPU Voltage Table (Use Gpu Configuation below)"
], 0, [0, 3], 1),
new CustEntry("commonGpuVoltOffset", "GPU Volt Offset", CustPlatform.All, 4, [
"Negative Voltage offset value for gpu dynamic voltage calculation",
"For example, value of 10 will decrease 10mV gpu volt from all frequencies",
"Default gpu vmin: Erista - 812.5mV / Mariko - 610mV",
"Acceptable range: 0 ~ 100"
], 0, [0, 100], 1),
new CustEntry("marikoCpuHighVoltOffset", "CPU Voltage offset at high frequencies", CustPlatform.Mariko, 4, [
"Reduce CPU power draw at high clocks",
], 0, [0, 100], 1),
new CustEntry("marikoCpuHighUV", "Enable Mariko CPU High Undervolt", CustPlatform.Mariko, 4, [
"Reduce CPU power draw at high clocks by offsetting the voltage sent to the CPU",
], 0, [0, 12], 1),
new CustEntry("cpuMaxFreq", "Maximum allowed CPU Frequency (KHz)", CustPlatform.All, 4, [
"Default: 1785000",
"This is the maximum frequency for the CPU you can set in sys-clk-ocs2.",
"The value for this setting is capped at 2091mhz for Erista units and 2907MHz for Mariko units",
"Anything above 1785MHz for Erista units and 1963MHz for Mariko units is unsafe without undervolting"
], 1785000, [204000, 2907000], 1, !1),
new CustEntry("gpuMaxFreq", "Maximum allowed GPU Frequency (KHz)", CustPlatform.All, 4, [
"Default: 921600",
"This is the maximum frequency for the GPU you can set in sys-clk-ocs2.",
"The value for this setting is capped at 998mhz for Erista units, and 1305MHz on Mariko units",
"The maximum safe value without undervolt is 921MHz for Erista units and 1152MHz for Mariko units",
"Higher frequencies via GPU UV3 bypass this setting"
], 921600, [76800, 1305600], 1, !1),
new CustEntry("gpuVmax", "Mariko Maximum allowed GPU Voltage (mV)", CustPlatform.Mariko, 4, [
"Default: 800",
"This is the maximum voltage you can use in GPU UV3.",
"Anything above 800MV is considered UNSAFE (although it depends per frequency)"
], 800, [480, 1000], 1, !1),
new CustEntry("gpuVmin", "Mariko Minimum allowed GPU Voltage (mV)", CustPlatform.Mariko, 4, [
"Default: 600",
"This is the minimum voltage you can use in GPU UV3.",
"A higher Vmin is required for a higher max ram clock"
], 600, [480, 1000], 1, !1),
];
var AdvTable = [
new AdvEntry("marikoEmcDvbShift", "Step up Mariko EMC DVB Table", CustPlatform.Mariko, 4, [
"Each number adds 25mV to SoC voltage",
"Helps with stability at higher memory clock, with the only downside being slightly higher tempratures",
"Such functionality is completely useless on Erista units",
"Acceptable range : 0~9"
], 0, [0, 9], 1),
];
var GpuTable = [
new GpuEntry("0", "76.8"),
new GpuEntry("1", "153.6"),
new GpuEntry("2", "230.4"),
new GpuEntry("3", "307.2"),
new GpuEntry("4", "384.0"),
new GpuEntry("5", "460.8"),
new GpuEntry("6", "537.6"),
new GpuEntry("7", "614.4"),
new GpuEntry("8", "691.2"),
new GpuEntry("9", "768.0"),
new GpuEntry("10", "844.8"),
new GpuEntry("11", "921.6"),
new GpuEntry("12", "998.4"),
new GpuEntry("13", "1075.2", CustPlatform.Mariko),
new GpuEntry("14", "1152.0", CustPlatform.Mariko),
new GpuEntry("15", "1228.8 <span style='color:orange; font-weight:bold;'>(UNSAFE)</span>", CustPlatform.Mariko),
new GpuEntry("16", "1267.2 <span style='color:orange; font-weight:bold;'>(UNSAFE)</span>", CustPlatform.Mariko),
new GpuEntry("17", "1305.6 <span style='color:orange; font-weight:bold;'>(UNSAFE)</span>", CustPlatform.Mariko),
new GpuEntry("18", "1344.0 <span style='color:orange; font-weight:bold;'>(UNSAFE)</span>", CustPlatform.Mariko),
new GpuEntry("19", "1382.4 <span style='color:orange; font-weight:bold;'>(UNSAFE)</span>", CustPlatform.Mariko),
new GpuEntry("20", "1420.8 <span style='color:red; font-weight:bold;'>(DANGEROUS)</span>", CustPlatform.Mariko),
new GpuEntry("21", "1459.2 <span style='color:red; font-weight:bold;'>(DANGEROUS)</span>", CustPlatform.Mariko),
new GpuEntry("22", "1497.6 <span style='color:red; font-weight:bold;'>(DANGEROUS)</span>", CustPlatform.Mariko),
new GpuEntry("23", "1536.0 <span style='color:red; font-weight:bold;'>(DANGEROUS)</span>", CustPlatform.Mariko)
];
class ErrorToolTip {
constructor(e, t) {
this.id = e, this.msg = t, this.id = e, this.element = document.getElementById(e), t && this.setMsg(t)
}
setMsg(e) {
return this.msg = e, this
}
show() {
var e, t, i, n, a, r;
return null === (e = this.element) || void 0 === e || e.setAttribute("aria-invalid", "true"), this.msg && (null === (t = this.element) || void 0 === t || t.setAttribute("title", this.msg), null === (n = null === (i = this.element) || void 0 === i ? void 0 : i.parentElement) || void 0 === n || n.setAttribute("data-tooltip", this.msg), null === (r = null === (a = this.element) || void 0 === a ? void 0 : a.parentElement) || void 0 === r || r.setAttribute("data-placement", "top")), this
}
clear() {
var e, t, i, n, a, r;
return null === (e = this.element) || void 0 === e || e.removeAttribute("aria-invalid"), null === (t = this.element) || void 0 === t || t.removeAttribute("title"), null === (n = null === (i = this.element) || void 0 === i ? void 0 : i.parentElement) || void 0 === n || n.removeAttribute("data-tooltip"), null === (r = null === (a = this.element) || void 0 === a ? void 0 : a.parentElement) || void 0 === r || r.removeAttribute("data-placement"), this
}
addChangeListener() {
var e;
null === (e = this.element) || void 0 === e || e.addEventListener("change", (e => {
let t = CustTable.filter((e => e.id === this.id))[0];
t.value = Number(this.element.value), t.validate()
}))
}
}
class CustStorage {
constructor() {
this.storage = {}, this.key = "last_saved"
}
updateFromTable() {
let e = e => {
var t;
if (e.updateValueFromElement(), !e.validate()) throw null === (t = e.getInputElement()) || void 0 === t || t.focus(), new Error(`Invalid ${e.name}`)
};
CustTable.forEach(e), AdvTable.forEach(e), GpuTable.forEach(e), this.storage = {};
let t = Object.fromEntries(CustTable.map((e => [e.id, e.value])));
Object.keys(t).forEach((e => this.storage[e] = t[e])), t = Object.fromEntries(AdvTable.map((e => [e.id, e.value]))), Object.keys(t).forEach((e => this.storage[e] = t[e]))
}
setTable() {
let e = Object.keys(this.storage);
e.forEach((e => CustTable.filter((t => t.id == e))[0].value = this.storage[e])), e.forEach((e => AdvTable.filter((t => t.id == e))[0].value = this.storage[e])), CustTable.filter((t => !e.includes(t.id))).forEach((e => e.value = e.defval)), AdvTable.filter((t => !e.includes(t.id))).forEach((e => e.value = e.defval)), CustTable.forEach((e => {
var t;
if (!e.validate()) throw null === (t = e.getInputElement()) || void 0 === t || t.focus(), new Error(`Invalid ${e.name}`);
e.setElementValue()
})), AdvTable.forEach((e => {
var t;
if (!e.validate()) throw null === (t = e.getInputElement()) || void 0 === t || t.focus(), new Error(`Invalid ${e.name}`);
e.setElementValue()
})), GpuTable.forEach((e => {
var t;
if (!e.validate()) throw null === (t = e.getInputElement()) || void 0 === t || t.focus(), new Error(`Invalid ${e.name}`);
e.setElementValue()
}))
}
save() {
localStorage.setItem(this.key, JSON.stringify(this.storage))
}
load() {
let e = localStorage.getItem(this.key);
if (!e) return null;
let t = JSON.parse(e),
i = CustTable.map((e => e.id)),
n = Object.keys(t).filter((e => !i.includes(e)));
return n.length && console.log(`Ignored: ${n}`), Object.keys(t).filter((e => i.includes(e))).forEach((e => this.storage[e] = t[e])), i = AdvTable.map((e => e.id)), n = Object.keys(t).filter((e => !i.includes(e))), n.length && console.log(`Ignored: ${n}`), Object.keys(t).filter((e => i.includes(e))).forEach((e => this.storage[e] = t[e])), this.storage
}
}
class Cust {
constructor() {
this.storage = new CustStorage, this.magic = 1414747459, this.magicLen = 4, this.mapper = {
2: {
get: e => this.view.getUint16(e, !0),
set: (e, t) => this.view.setUint16(e, t, !0)
},
4: {
get: e => this.view.getUint32(e, !0),
set: (e, t) => this.view.setUint32(e, t, !0)
}
}
}
findMagicOffset() {
this.view = new DataView(this.buffer);
for (let e = 0; e < this.view.byteLength; e += this.magicLen)
if (this.mapper[this.magicLen].get(e) == this.magic) return void(this.beginOffset = e);
throw new Error("Invalid loader.kip file")
}
save() {
this.storage.updateFromTable();
let e = e => {
var t, i;
if (!e.offset) throw null === (t = e.getInputElement()) || void 0 === t || t.focus(), new Error(`Failed to get offset for ${e.name}`);
let n = this.mapper[e.size];
if (!n) throw null === (i = e.getInputElement()) || void 0 === i || i.focus(), new Error(`Unknown size at ${e.name}`);
n.set(e.offset, e.value)
};
CustTable.forEach(e), AdvTable.forEach(e), GpuTable.forEach(e), this.storage.save();
let t = document.createElement("a");
t.href = window.URL.createObjectURL(new Blob([this.buffer], {
type: "application/octet-stream"
})), t.download = "loader.kip", t.click(), this.toggleLoadLastSavedBtn(!0)
}
removeHTMLForm() {
CustTable.forEach((e => e.removeElement()))
}
toggleLoadLastSavedBtn(e) {
let t = document.getElementById("load_saved");
e ? (t.addEventListener("click", (() => {
this.storage.load() && this.storage.setTable()
})), t.style.removeProperty("display"), t.removeAttribute("disabled")) : t.style.setProperty("display", "none")
}
createHTMLForm() {
var e, t;
CustTable.forEach((e => e.createElement()));
let i = document.createElement("p");
i.innerHTML = "Advanced configuration", null === (e = document.getElementById("config-list-advanced")) || void 0 === e || e.appendChild(i);
let n = document.createElement("p");
n.innerHTML = "Gpu Volt configuration", null === (t = document.getElementById("config-list-gpu")) || void 0 === t || t.appendChild(n), AdvTable.forEach((e => e.createElement())), GpuTable.forEach((e => e.createElement()));
let a = document.getElementById("load_default");
a.removeAttribute("disabled"), a.addEventListener("click", (() => {
CustTable.forEach((e => e.setElementDefaultValue()))
})), this.toggleLoadLastSavedBtn(null !== this.storage.load());
let r = document.getElementById("save");
r.removeAttribute("disabled"), r.addEventListener("click", (() => {
try {
this.save()
} catch (e) {
console.error(e), alert(e)
}
}))
}
initCustTabs() {
const e = Array.from(document.querySelectorAll('nav[role="tablist"] > button'));
e.forEach((t => {
t.removeAttribute("disabled");
let i = Number(t.getAttribute("data-platform"));
t.addEventListener("click", (n => {
const a = ["outline"];
t.classList.remove(...a), e.filter((e => e != t)).forEach((e => e.classList.add(...a))), CustTable.forEach((e => {
e.isAvailableFor(i) ? e.showElement() : e.hideElement()
}))
}))
}))
}
parse() {
let e = this.beginOffset + this.magicLen;
if (this.rev = this.mapper[4].get(e), CUST_REV_ADV != this.rev) throw new Error(`Unsupported custRev, expected: 1, got ${this.rev}`);
e += 4, document.getElementById("cust_rev").innerHTML = `Cust v${this.rev} is loaded.`;
let t = t => {
var i;
t.offset = e;
let n = this.mapper[t.size];
if (!n) throw null === (i = t.getInputElement()) || void 0 === i || i.focus(), new Error(`Unknown size at ${t}`);
t.value = n.get(e), e += t.size, t.validate()
};
CustTable.forEach(t), AdvTable.forEach(t), GpuTable.forEach(t)
}
load(e) {
try {
this.buffer = e, this.findMagicOffset(), this.removeHTMLForm(), this.parse(), this.initCustTabs(), this.createHTMLForm()
} catch (e) {
console.error(e), alert(e)
}
}
}
class ReleaseAsset {
constructor(e) {
this.downloadUrl = e.browser_download_url, this.updatedAt = e.updated_at
}
}
class ReleaseInfo {
constructor() {
this.ocLatestApi = "https://api.github.com/repos/souldbminersmwc/Switch-OC-Suite-2/releases/latest"
}
load() {
return __awaiter(this, void 0, void 0, (function*() {
try {
this.parseOcResponse(yield this.responseFromApi(this.ocLatestApi).catch())
} catch (e) {
console.error(e), alert(e)
}
}))
}
responseFromApi(e) {
return __awaiter(this, void 0, void 0, (function*() {
const t = yield fetch(e, {
method: "GET",
headers: {
Accept: "application/json"
}
});
if (t.ok) return yield t.json();
throw new Error(`Failed to connect to "${e}": ${t.status}`)
}))
}
parseOcResponse(e) {
this.ocVer = e.tag_name, this.loaderKipAsset = new ReleaseAsset(e.assets.filter((e => e.name.endsWith("loader.kip")))[0]), this.sdOutZipAsset = new ReleaseAsset(e.assets.filter((e => e.name.endsWith("SdOut.zip")))[0]), this.sysclkOCAsset = new ReleaseAsset(e.assets.filter((e => e.name.endsWith("sys-clk-ocs2.zip")))[0])
}
}
class DownloadSection {
constructor() {
this.element = document.getElementById("download_btn_grid")
}
load() {
return __awaiter(this, void 0, void 0, (function*() {
for (; !this.isVisible();) yield new Promise((e => setTimeout(e, 1e3)));
const e = new ReleaseInfo;
yield e.load(), this.update("loader_kip_btn", `loader.kip <b>${e.ocVer}</b><br>${e.loaderKipAsset.updatedAt}`, e.loaderKipAsset.downloadUrl), this.update("sdout_zip_btn", `SdOut.zip <b>${e.ocVer}</b><br>${e.sdOutZipAsset.updatedAt}`, e.sdOutZipAsset.downloadUrl), this.update("ams_btn", `sys-clk-ocs2 <b>${e.ocVer}</b><br>${e.sysclkOCAsset.updatedAt}`, e.sysclkOCAsset.downloadUrl)
}))
}
isVisible() {
let e = this.element.getBoundingClientRect();
return e.top > 0 && e.left > 0 && e.bottom - e.height < (window.innerHeight || document.documentElement.clientHeight) && e.right - e.width < (window.innerWidth || document.documentElement.clientWidth)
}
update(e, t, i) {
let n = document.getElementById(e);
n.innerHTML = t, n.removeAttribute("aria-busy"), n.setAttribute("href", i)
}
}
const fileInput = document.getElementById("file");
fileInput.addEventListener("change", (e => {
var t = new Cust;
if (!e.target || !e.target.files) return;
let i = new FileReader;
i.readAsArrayBuffer(e.target.files[0]), i.onloadend = e => {
e.target.readyState == FileReader.DONE && t.load(e.target.result)
}
})), addEventListener("DOMContentLoaded", (e => __awaiter(this, void 0, void 0, (function*() {
yield(new DownloadSection).load()
}))));