MikroTikPatch/index.html
elseif fc469087be
Update index.html
Signed-off-by: elseif <elseif@live.cn>
2025-09-08 10:22:15 +08:00

990 lines
42 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" >
<head>
<meta charset="utf-8" />
<title>MikroTik RouterOS Patched Versions</title>
<link href="https://unpkg.com/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link href="https://unpkg.com/firacode/distr/fira_code.css" rel="stylesheet">
<style>
body,html {
height: 100%;
font-size: 100%
}
*,:after,:before {box-sizing: border-box}
body {
background: #F7F7F7;
color: #757575;
margin: 0;
font-family: arial,sans-serif;
line-height: 1.5;
}
.wrapper { background:white; }
table { background: #fff; }
table thead, table tfoot { background: #f5f5f5; }
/* --- DARK THEME --- */
body.dark {
background: #1e1e1e;
color: #ddd;
}
body.dark .wrapper {
background: #2a2a2a;
}
body.dark h1,h2,h3,h4,h5,h6 {
color: #f0f0f0;
}
body.dark a { color:#4ea3ff; }
body.dark a:hover { color:#81c8ff; }
body.dark table {
background: #2a2a2a;
border-color: #444;
}
body.dark table thead, body.dark table tfoot {
background: #333;
}
body.dark table tr td,
body.dark table tr th {
color: #ddd;
}
body.dark .downloadTable tbody tr:hover {
background-color: #333 !important;
}
body.dark .downloadTable thead tr {
background-color: #444 !important;
}
body.dark .downloadTable thead th {
color: #eee !important;
}
body.dark #command pre {
background: #111;
color: #eaeaea;
}
/* دکمه تغییر تم */
#theme-toggle {
position: fixed;
top: 60px;
right: 15px;
background: #0992c9;
color: #fff;
border: none;
padding: 8px 14px;
cursor: pointer;
border-radius: 6px;
font-size: 14px;
z-index: 2000;
}
#theme-toggle:hover {
background: #0775a1;
}
body,html {
height: 100%;
font-size: 100%
}
*,:after,:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box
}
body {
background: #F7F7F7;
color: #757575;
padding-top:80px;
font-family:arial,sans-serif;
padding: 0;
margin: 0;
font-style: normal;
line-height: 1.5;
cursor: auto;
opacity:1;
}
a {-webkit-transition: all 200ms ease-in-out;transition: all 200ms ease-in-out; color:#4984AE;text-decoration: none;}
a:hover{color: #2F5B7B}
h1,h2,h3,h4,h5,h6{font-family:'Open Sans',sans-serif;font-weight:normal;margin-bottom:18px;margin-top:26px;color:#626262;}
h1 {font-weight: 300}
h2{font-size:1.875rem}
h3{font-size:1.5rem}
.text-center{text-align:center}
.button {
border-style: solid;
border-width: 0;
cursor: pointer;
line-height: normal;
margin: 0 0 1.25rem;
position: relative;
text-align: center;
border-radius: 0;
display: inline-block;
font-size: 1rem;
background-color: #0992c9;
border-color: #0775a1;
color: #fff;
transition: background-color .3s ease-out;
padding: 1rem 2rem 1.0625rem
}
.button:focus,.button:hover,button:focus,button:hover {
background-color: #0775a1;
color: #fff
}
.button.secondary,button.secondary {
background-color: #e7e7e7;
border-color: #b9b9b9;
color: #333
}
.button.secondary:focus,.button.secondary:hover,button.secondary:focus,button.secondary:hover {
background-color: #b9b9b9;
color: #333
}
.wrapper{background:white;max-width:1600px;margin:auto;overflow:auto;padding-top:25px; padding-bottom: 35px;position: relative;}
.row {
max-width: 62.5rem;
margin: 0 auto
}
.row.collapse>.column,.row.collapse>.columns {
padding-left: 0;
padding-right: 0
}
.row.collapse .row {
margin-left: 0;
margin-right: 0
}
.row .row {
width: auto;
max-width: none;
margin: 0 -.9375rem
}
.row .row.collapse {
width: auto;
margin: 0;
max-width: none
}
.column,.columns {
padding-left: .9375rem;
padding-right: .9375rem;
width: 100%;
float: left
}
[class*=column]+[class*=column]:last-child {float: right}
[class*=column]+[class*=column].end { float: left}
hr {
border: solid #ddd;
border-width: 1px 0 0;
margin: 1.25rem 0 1.1875rem;
height: 0
}
b,strong { font-weight: 700}
small {font-size: 60%}
table {
background: #fff;
margin-bottom: 1.25rem;
border: 1px solid #ddd;
table-layout: auto
}
table caption {
background: 0 0;
color: #222;
font-size: 1rem;
font-weight: 700
}
table tfoot,table thead {
background: #f5f5f5;
}
table tfoot tr td,table tfoot tr th,table thead tr td,table thead tr th {
padding: .5rem .625rem .625rem;
font-size: .875rem;
font-weight: 700;
color: #222
}
table tr td,table tr th {
padding: .5625rem .625rem;
font-size: .875rem;
color: #222;
text-align: left;
}
table tr.alt,table tr.even,table tr:nth-of-type(even) {
background: #f9f9f9
}
table tbody tr td,table tbody tr th,table tfoot tr td,table tfoot tr th,table thead tr th,table tr td {
display: table-cell;
line-height: 1.125rem;
}
.table{width:100%;border:0;border-collapse:collapse;}
.table tr:nth-of-type(even){background-color:transparent;}
.table td{padding:4px 10px 4px 0;color:#757575}
.table thead {background:transparent;}
.table thead th{padding:4px 10px 4px 0;color:#747474}
.downloadTable, .fullWidth{width:100%;}
.downloadTable tbody tr{border-bottom:1px solid #e3e3e3}
.downloadTable tbody tr:hover{background-color:#f7f7f7}
.downloadTable td{padding:6px 10px}
.downloadTable tbody tr.ht td{background-color:#888;border-bottom:0;}
.downloadTable tbody tr td.boldy{font-weight:bold;color:#ddd}
.downloadTable tbody tr:last-child{border-bottom:0;}
.downloadTable thead tr{background-color:#4caf50;}
.downloadTable thead th{color:white;padding:12px 5px}
.downloadTable tbody tr:first-child td:first-child{font-weight:bold;width:230px;}
.downloadTable tbody tr.hv td:not(:first-child){min-width:150px;}
.downloadTable td {padding: 0 4px; }
.downloadTable tr td:first-child {padding: 6px 10px;}
.download-btn, .changelog-btn, .checksums-btn { padding: 10px; color: grey;font-size: 1.2em;}
.download-btn:hover {color: #007bff;}
.downloadTable tr:hover .checksum-btn {
visibility: visible;
}
.download_version_row:hover{
background: #f0f3f7;
cursor: pointer;
}
.small-1 {
width: 8.33333%
}
.small-11 {
width: 91.66667%
}
.filter-blue {
filter: invert(39%) sepia(88%) saturate(5000%) hue-rotate(190deg) brightness(95%) contrast(90%);
}
.table-wrapper { position: relative; }
thead { position: relative; }
.collapse-btn {
position: absolute;
top: 50%;
right: 8px;
transform: translateY(-50%);
background: #fff;
border: 1px solid #ccc;
border-radius: 2px;
padding: 2px 6px;
cursor: pointer;
font-size: 0.85em;
line-height: 1;
}
.collapse-btn:hover {
background: gray;
}
.github-corner svg {clip-path: polygon(0 0, 100% 0, 100% 100%);}
.github-corner:hover .octo-arm {animation: octocat-wave 560ms ease-in-out;}
@keyframes octocat-wave {
0% { transform: rotate(0deg);}
20% {transform: rotate(-25deg);}
40% {transform: rotate(10deg);}
60% {transform: rotate(-25deg);}
80% {transform: rotate(10deg);}
100% {transform: rotate(0deg);}
}
@media (max-width: 500px) {
.github-corner:hover .octo-arm {animation: none;}
.github-corner .octo-arm {animation: octocat-wave 560ms ease-in-out;}
}
.reveal-modal {
display: none;
position: fixed;
z-index: 1005;
width: 60%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: auto;
background-color: #fff;
padding: 1.875rem;
border: 1px solid #666;
box-shadow: 0 0 10px rgba(0,0,0,.4)
}
.reveal-modal .close-reveal-modal {
font-size: 2.5rem;
line-height: 1;
position: absolute;
top: .625rem;
right: 1.375rem;
color: #aaa;
font-weight: 700;
cursor: pointer
}
#version-buttons {margin-bottom: 12px;}
#version-buttons button {
background-color: #b9b9b9;
color: #fff;
border: none;
padding: 6px 12px;
margin-left: 6px;
border-radius: 1px;
cursor: pointer;
}
#version-buttons button:hover {background-color: #555;}
#version-buttons button.active {background-color: #4caf50;}
#command-container {
position: relative;
margin-top: 12px;
}
#copy-btn {
position: absolute;
top: 10px;
right: 10px;
background-color: #4caf50;
color: white;
border: none;
padding: 4px 8px;
border-radius: 3px;
cursor: pointer;
font-size: 12px;
z-index: 10;
}
#copy-btn i {margin-right: 6px;}
#copy-btn:hover {background-color: #45a049;}
#command pre {
font-family: 'Fira Code', monospace !important;
font-size: 13px;
line-height: 1.5;
background-color: #1e1e1e;
color: #d4d4d4;
padding: 12px;
border-radius: 3px;
overflow-x: auto;
}
#command .bash { color: #c586c0; font-weight: bold; }
#command .url { color: #569cd6; }
#command .version { color: #4ec9b0; font-weight: bold; }
#command pre:hover {background-color: #2c2c2c;}
.loading {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-style: italic;
color: gray;
background: rgba(255,255,255,0.9);
padding: 15px 25px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.2);
z-index: 1000;
}
.loading i {
margin-right: 10px;
animation: fa-spin 1s linear infinite;
}
</style>
</head>
<body>
<script>
async function fetch_latest_versions(url, defaultValue, timeout = 3000) {
try {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
const res = await fetch(url, { signal: controller.signal });
clearTimeout(id);
if(res.ok){
const text = await res.text();
return text.split(" ")[0];
}
} catch(e) {
console.warn("fetch failed or timeout:", e);
}
return defaultValue;
}
async function init() {
const i18n = {
en: {
language: "Language:",
infoLabel1:`If you are already running <b>patched</b> RouterOS, upgrading to the latest version can be done by clicking on <b>"Check For Updates"</b>
in <b>QuickSet or System > Packages</b>
menu in WebFig or WinBox.`,
infoLabel2:`For more information about <b>install and upgrade</b> see the <a href="https://help.mikrotik.com/docs/" target="_blank">Documentation</a><br>
For more information about <b>patch</b> see the <a href="https://github.com/elseif/MikroTikPatch" target="_blank">MikroTikPatch</a>`,
installCmdLabel:"<b>Install Command</b>",
proxyLabel:"Use a proxy service to accelerate access to GitHub files",
clearCache:"Clear Cache",
copyUrlsClearCache:"Copy URLs to Clear Cache",
loading:"Loading...",
},
zh: {
language: "语言:",
infoLabel1:`如果你已经在运行<b>Patch</b>过的RouterOS可以通过WebFig或WinBox中的<b>QuickSet或System > Packages</b>菜单点击<b>"Check For Updates"</b>来升级到最新版本。`,
infoLabel2:`有关<b>安装和升级</b>的更多信息,请参阅<a href="https://help.mikrotik.com/docs/" target="_blank">文档</a><br>有关<b>Patch</b>的更多信息,请参阅<a href="https://github.com/elseif/MikroTikPatch" target="_blank">MikroTikPatch</a>`,
installCmdLabel:"<b>安装命令</b>",
proxyLabel:"使用代理服务加速访问GitHub文件",
clearCache:"清除缓存",
copyUrlsClearCache:"复制链接以清除缓存",
loading:"加载中...",
}
};
function setLanguage(lang) {
document.querySelectorAll("[data-i18n]").forEach(el => {
const key = el.getAttribute("data-i18n");
if (i18n[lang] && i18n[lang][key]) {
el.innerHTML = i18n[lang][key];
}
});
localStorage.setItem("lang", lang);
}
function initLanguage() {
let savedLang = localStorage.getItem("lang");
if (!savedLang) {
savedLang = navigator.language.startsWith("zh") ? "zh" : "en";
}
document.getElementById("lang-switcher").value = savedLang;
setLanguage(savedLang);
}
document.getElementById("lang-switcher").addEventListener("change", e => {
setLanguage(e.target.value);
});
initLanguage();
const loading = document.getElementById("loading");
loading.style.display = "inline";
const routeros7_stable = await fetch_latest_versions("https://upgrade.mikrotik.ltd/routeros/NEWESTa7.stable", "7.19.4");
const routeros7_testing = await fetch_latest_versions("https://upgrade.mikrotik.ltd/routeros/NEWESTa7.testing", "7.20beta9");
const routeros6_longterm = await fetch_latest_versions("https://upgrade.mikrotik.ltd/routeros/NEWEST6.long-term", "6.49.18");
const routeros6_stable = await fetch_latest_versions("https://upgrade.mikrotik.ltd/routeros/NEWEST6.stable", "6.49.19");
loading.style.display = "none";
const downloads =[
{
title:"RouterOS v7",
versions:[
{
title:"Stable",
version:routeros7_stable,
},
{
title:"Testing",
version:routeros7_testing,
}
],
groups: [
{
title:"ARM64 / AMPERE",
arch:"arm64",
downloads:[
{
title:"Main package",
type:"main"
},
{
title:"Extra packages",
type:"extra"
},
{
title:"ISO image for AMPERE",
type:"iso"
}
]
},
{
title:"X86",
arch:"x86",
downloads:[
{
title:"Main package",
type:"main"
},
{
title:"Extra packages",
type:"extra"
},
{
title:"CD Image",
type:"iso"
},
{
title:"Install image",
type:"install"
}
]
},
{
title:"GENERAL",
arch:"general",
downloads:[
{
title:"Netinstall (Windows)",
type:"netinstall_windows"
},
{
title:"Netinstall (CLI Linux)",
type:"netinstall_linux_cli"
},
{
title:"Changelog",
type:"changlog"
},
]
}
]
},
{
title:"RouterOS v6",
versions:[
{
title:"Long-Term",
version:routeros6_longterm,
},
{
title:"Stable",
version:routeros6_stable,
}
],
groups: [
{
title:"X86",
arch:"x86",
downloads:[
{
title:"Extra packages",
type:"extra"
},
{
title:"CD Image",
type:"iso"
},
{
title:"Install image",
type:"install"
},
{
title:"Changelog",
type:"changlog"
}
]
}
]
},
{
title:"Cloud Hosted Router",
versions:[
{
title:"Long-Term",
version:routeros6_longterm,
},
{
title:"Stable",
version:routeros6_stable,
},
{
title:"Stable",
version:routeros7_stable,
},
{
title:"Testing",
version:routeros7_testing,
}
],
groups:[
{
title:"X86",
arch:"x86",
downloads:[
{
title:"Main package",
type:"main"
},
{
title:"Extra packages",
type:"extra"
},
{
title:"VHDX image",
type:"vhdx"
},
{
title:"VMDK image",
type:"vmdk"
},
{
title:"VDI image",
type:"vdi"
},
{
title:"VirtualPC image",
type:"vhd"
},
{
title:"Raw disk image",
type:"img"
},
{
title:"OVA template ",
type:"ova"
}
],
},
{
title:"ARM64 / AMPERE",
arch:"arm64",
downloads:[
{
title:"Main package",
type:"main"
},
{
title:"Extra packages",
type:"extra"
},
{
title:"VHDX image",
type:"vhdx"
},
{
title:"VMDK image",
type:"vmdk"
},
{
title:"VDI image",
type:"vdi"
},
{
title:"VirtualPC image",
type:"vhd"
},
{
title:"Raw disk image",
type:"img"
}
],
}
]
},
]
const fileNames = (version,arch,type) => {
const files = [];
if(version.charAt(0) === "6" && arch != "x86") return files;
if(type === "main" && version.charAt(0) === "7" )
files.push(`routeros-${version}${arch === "x86" ? "" : "-"+arch}.npk`);
if(type === "iso")
files.push(`mikrotik-${version}${arch === "x86" ? "" : "-"+arch}.iso`);
if(type === "extra")
files.push(`all_packages-${arch}-${version}.zip`);
if(type === "install")
files.push(`install-image-${version}${arch === "x86" ? "" : "-"+arch}.zip`);
if(type in {vhdx:1, vmdk:1, vdi:1, vhd:1, img:1}){
files.push(`chr-${version}${arch === "x86" ? "" : "-"+arch}.${type}.zip`);
if(arch === "x86" && version.charAt(0) != "6" ) files.push(`chr-${version}-legacy-bios.${type}.zip`);
}
if(type === "ova" && version.charAt(0) != "6"){
files.push(`chr-${version}${arch === "x86" ? "" : "-"+arch}.${type}.zip`);
if(arch === "x86" ) files.push(`chr-${version}-legacy-bios.${type}.zip`);
}
if(type === "netinstall_windows")
files.push(`netinstall-${version}.zip`);
if(type === "netinstall_linux_cli")
files.push(`netinstall-${version}.tar.gz`);
return files;
};
const baseUrl = (version,arch) => `${localStorage.getItem("gh-proxy-enabled") === "true" ? "https://gh-proxy.com/":""}https://github.com/elseif/MikroTikPatch/releases/download/${version}${arch === "x86" ? "":arch === "general"? "": "-"+arch}/`;
const container = document.getElementById("download-rows");
downloads.forEach((download, index) => {
const wrapper = document.createElement("div");
wrapper.className = "table-wrapper";
const table = document.createElement("table");
table.className = "table tablev downloadTable"
table.innerHTML = `
<thead>
<tr>
<th>${download.title}</th>
${download.versions.map(v => `<th>${v.version} ${v.title}</th>`).join("")}
</tr>
</thead>
<tbody>
${download.groups.map(g => {
return `
<tr class="ht">
<td class="boldy">${g.title}</td>
<td colspan="${download.versions.length}"></td>
</tr>
${g.downloads.map(d => {
return `
<tr class="hv">
<td>${d.title}</td>
${download.versions.map(v => {
if(d.type === "changlog"){
return `<td><a href="https://upgrade.mikrotik.ltd/routeros/${v.version}/CHANGELOG" class="download-btn" title="${d.title}" target="_blank"><i class="fa fa-file-text"></i></a></td>`;
}else{
const files = fileNames(v.version,g.arch,d.type);
if (files && files.length > 0) {
const links = files.map(file => {
const url = `${baseUrl(v.version, g.arch)}${file}`;
if (download.versions.length === 4 && d.type in {vhdx:1,vmdk:1,vdi:1,vhd:1,img:1,ova:1} ){
if (v.version.charAt(0) === "6" ){
return `<a href="${url}" class="download-btn" title="${file}" target="_blank"><i class="fa fa-save"></i> Legacy</a>`;
}else{
if (file.includes("legacy-bios")){
return `<a href="${url}" class="download-btn" title="${file}" target="_blank"><i class="fa fa-save"></i> Legacy</a>`;
}else{
return `<a href="${url}" class="download-btn" title="${file}" target="_blank"><i class="fa fa-save"></i> UEFI</a>`;
}
}
}else{
return `<a href="${url}" class="download-btn" title="${file}" target="_blank"><i class="fa fa-save"></i></a>`;
}
}).join(" ");
return `<td>${links}</td>`;
}else{
return `<td></td>`;
}
}
}).join("")}
</tr>
`;
}).join("")}
`;
}).join("")}
</tbody>
`
const btn = document.createElement("button");
btn.className = "collapse-btn";
btn.innerHTML = `<i class="fa fa-minus"></i>`;
table.querySelector("thead").appendChild(btn);
wrapper.appendChild(table);
container.appendChild(wrapper);
const tbody = table.querySelector("tbody");
if (index === 0) {
tbody.style.display = "";
btn.innerHTML = `<i class="fa fa-minus"></i>`;
} else {
tbody.style.display = "none";
btn.innerHTML = `<i class="fa fa-plus"></i>`;
}
btn.onclick = () => {
if (tbody.style.display === "none") {
tbody.style.display = "";
btn.innerHTML = `<i class="fa fa-minus"></i>`;
} else {
tbody.style.display = "none";
btn.innerHTML = `<i class="fa fa-plus"></i>`;
}
};
});
document.getElementById("clear-cache").onclick = e => {
const links = document.querySelectorAll("a[href^='https://gh-proxy.com/https://github.com/elseif/MikroTikPatch/']");
document.getElementById("urls-list").innerText = Array.from(links).map(a => a.href).filter(href => !href.includes(".yml")).join("\n");
document.getElementById("urls-pannel").style.display = "block";
};
document.getElementById("urls-close").onclick = () => {
document.getElementById("urls-pannel").style.display = "none";
};
document.getElementById("copy-to-clear-cache").onclick = () => {
const el = document.getElementById("urls-list");
const range = document.createRange();
range.selectNodeContents(el);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
document.execCommand("copy");
window.open("https://cache.gh-proxy.com/", "_blank");
document.getElementById("urls-pannel").style.display = "none";
}
const ghProxyCheckbox = document.querySelector('input[name="gh-proxy"]');
ghProxyCheckbox.checked = localStorage.getItem("gh-proxy-enabled") === "true";
document.getElementById("clear-cache").style.display = ghProxyCheckbox.checked ?"inline-block":"none";
ghProxyCheckbox.addEventListener("change", () => {
if (ghProxyCheckbox.checked) {
localStorage.setItem("gh-proxy-enabled", "true");
const links = document.querySelectorAll("a[href^='https://github.com/elseif/MikroTikPatch/']");
links.forEach(link => {
link.href = link.href.replace(/^https:\/\/github\.com\//, "https://gh-proxy.com/https://github.com/");
});
document.getElementById("clear-cache").style.display = "inline-block";
} else {
localStorage.setItem("gh-proxy-enabled", "false");
const links = document.querySelectorAll("a[href^='https://gh-proxy.com/https://github.com/elseif/MikroTikPatch/']");
links.forEach(link => {
link.href = link.href.replace(/^https:\/\/gh-proxy\.com\//, "");
});
document.getElementById("clear-cache").style.display = "none";
}
const activeBtn = document.querySelector("#version-buttons button.active");
if (activeBtn) updateCommand(activeBtn.dataset.version);
});
const versionBtns = document.getElementById("version-buttons");
const commandDiv = document.getElementById("command");
const copyBtn = document.getElementById("copy-btn");
versionBtns.innerHTML = `
<span data-i18n="installCmdLabel"></span>
<label><input type="radio" name="tool" value="curl" checked>curl</label>
<label><input type="radio" name="tool" value="wget">wget</label>
<button data-version="${routeros7_stable}">RouterOS v7 Stable</button>
<button data-version="${routeros7_testing}">RouterOS v7 Testing</button>
<button data-version="${routeros6_longterm}">RouterOS v6 Long-Term</button>
<button data-version="${routeros6_stable}">RouterOS v6 Stable</button>
`
function updateCommand(version) {
const tool = document.querySelector('input[name="tool"]:checked').value;
let cmd;
const proxy = `${localStorage.getItem("gh-proxy-enabled") === "true"?" | sed 's#https://github.com#https:/gh-proxy.com/https://github.com#g'":""}`;
if (tool === "curl") {
cmd = `<pre ${proxy === ""?"":"style='font-size:12px'"}><span class="bash">curl</span> <span class="url">https://mikrotik.ltd/chr.sh</span>${proxy} | <span class="bash">bash</span> -s <span class="version">${version}</span></pre>`;
} else {
cmd = `<pre ${proxy === ""?"":"style='font-size:11px'"}><span class="bash">wget</span> -O - <span class="url">https://mikrotik.ltd/chr.sh</span>${proxy} | <span class="bash">bash</span> -s <span class="version">${version}</span></pre>`;
}
commandDiv.innerHTML = cmd;
}
document.querySelectorAll('input[name="tool"]').forEach(radio => {
radio.addEventListener("change", () => {
const activeBtn = document.querySelector("#version-buttons button.active");
if (activeBtn) updateCommand(activeBtn.dataset.version);
});
});
const buttons = document.querySelectorAll("#version-buttons button");
buttons.forEach(btn => {
btn.addEventListener("click", () => {
updateCommand(btn.dataset.version);
buttons.forEach(b => b.classList.remove("active"));
btn.classList.add("active");
});
});
updateCommand(buttons[0].dataset.version);
buttons[0].classList.add("active");
copyBtn.addEventListener("click", () => {
const code = commandDiv.querySelector("pre").innerText;
navigator.clipboard.writeText(code).then(() => {
copyBtn.innerHTML = `<i class="fa fa-copy"></i>Copied!`;
setTimeout(() => { copyBtn.innerHTML = `<i class="fa fa-copy"></i>Copy`; }, 1500);
}).catch(err => {
console.error("Copy failed:", err);
});
});
const themeBtn = document.getElementById("theme-toggle");
const currentTheme = localStorage.getItem("theme");
if(currentTheme === "dark"){
document.body.classList.add("dark");
themeBtn.innerHTML = '<i class="fa fa-sun-o"></i> Light';
}
themeBtn.addEventListener("click", ()=>{
document.body.classList.toggle("dark");
if(document.body.classList.contains("dark")){
themeBtn.innerHTML = '<i class="fa fa-sun-o"></i> Light';
localStorage.setItem("theme","dark");
} else {
themeBtn.innerHTML = '<i class="fa fa-moon-o"></i> Dark';
localStorage.setItem("theme","light");
}
});
}
window.addEventListener("DOMContentLoaded", init);
</script>
<script async defer src="https://buttons.github.io/buttons.js"></script>
<div class="wrapper">
<button id="theme-toggle"><i class="fa fa-moon-o"></i> Dark</button>
<a href="https://github.com/elseif/MikroTikPatch" class="github-corner" aria-label="View source on GitHub" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 250 250" fill="#151513" style="position: absolute; top: 0; right: 0">
<path d="M0 0l115 115h15l12 27 108 108V0z" fill="#151513"/>
<path class="octo-arm" fill="#fff" d="M128 109c-15-9-9-19-9-19 3-7 2-11 2-11-1-7 3-2 3-2 4 5 2 11 2 11-3 10 5 15 9 16" style="-webkit-transform-origin: 130px 106px; transform-origin: 130px 106px"/>
<path class="octo-body" fill="#fff" d="M115 115s4 2 5 0l14-14c3-2 6-3 8-3-8-11-15-24 2-41 5-5 10-7 16-7 1-2 3-7 12-11 0 0 5 3 7 16 4 2 8 5 12 9s7 8 9 12c14 3 17 7 17 7-4 8-9 11-11 11 0 6-2 11-7 16-16 16-30 10-41 2 0 3-1 7-5 11l-12 11c-1 1 1 5 1 5z"/>
</svg>
</a>
<div class="row">
<div class="text-center">
<h1 class="filter-blue" style="margin-top: 20px;"><b>MikroTik RouterOS Patched Versions</b></h1>
</div>
</div>
<div class="row text-center">
<div>
<a href="https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_6.yml" target="_blank"><img src="https://mikrotik.ltd/badge/mikrotik_patch_6.yml" alt="Patch Mikrotik RouterOS 6.x"></a>
<a href="https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_7.yml" target="_blank"><img src="https://mikrotik.ltd/badge/mikrotik_patch_7.yml" alt="Patch Mikrotik RouterOS 7.x"></a>
</div>
<div>
<img src="https://img.shields.io/endpoint?logo=icloud&url=https://mikrotik.ltd/status/cloud" alt="Cloud Status">
<img src="https://img.shields.io/endpoint?logo=googlecloudstorage&url=https://mikrotik.ltd/status/dartnode" alt="VPS Status">
</div>
<a class="github-button" href="https://github.com/elseif/MikroTikPatch" data-icon="octicon-star" data-size="large" data-show-count="true" aria-label="Star elseif/MikroTikPatch on GitHub">Star</a>
<a class="github-button" href="https://github.com/elseif/MikroTikPatch/fork" data-icon="octicon-repo-forked" data-size="large" data-show-count="true" aria-label="Fork elseif/MikroTikPatch on GitHub">Fork</a>
</div>
<div class="row">
<p data-i18n="infoLabel1"></p>
<p data-i18n="infoLabel2"></p>
<div id="version-buttons"></div >
<div id="command-container">
<button id="copy-btn"><i class="fa fa-copy"></i>Copy</button>
<div id="command"></div>
</div>
<div style="height: 30px;">
<label><input type="checkbox" name="gh-proxy"><span data-i18n="proxyLabel"></span></label>
<a data-i18n="clearCache" id="clear-cache" class="button secondary" style="margin: 0px 10px !important;padding: 6px;font-size: .8125rem;height: 30px;" href="#" title="gh-proxy"></a>
</div>
</div>
<div class="row" style="display: flex; align-items: center; justify-content: center; ">
<div id="urls-pannel" class="reveal-modal" style="display: none;" tabindex="0">
<a id="urls-close" class="close-reveal-modal" aria-label="Close">×</a>
<div id="urls-list" style="margin: 20px; font-size: 16px;overflow:auto;height: 300px;"></div>
<div style="display: flex; align-items: center; justify-content: center; ">
<a data-i18n="copyUrlsClearCache" id="copy-to-clear-cache" class="button" style="margin-bottom: 0;padding: 8px;; width:180px;height:30px;font-size: .8125rem;" href="#" title="gh-proxy"></a>
</div>
</div>
</div>
<div class="row" id="download-rows" style="margin-top: 2vh;">
<div class="loading" id="loading"><i class="fa fa-spinner"></i><span data-i18n="loading"></span></div>
</div>
<div class="row">
<ul style="display: flex; align-items: center; justify-content: center; gap: 20px; list-style: none; padding: 0; margin: 0; ">
<li>
<a href="https://t.me/mikrotikpatch" target="_blank" title="Telegram">
<i class="fa fa-telegram fa-2x"></i>
</a>
</li>
<li>
<a href="https://github.com/elseif/MikroTikPatch" target="_blank" title="GitHub">
<i class="fa fa-github fa-2x"></i>
</a>
</li>
<li style="display: flex; gap: 6px;">
<span data-i18n="language"></span>
<select id="lang-switcher">
<option value="en">English</option>
<option value="zh">中文</option>
</select>
</li>
</ul>
</div>
</div>
</body>
</html>