<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Caub + DNS</title>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap" rel="stylesheet" />
    <style>
      :root {
        --nc-tx-1: #ffffff;
        --nc-tx-2: #eeeeee;
        --nc-bg-1: #090909;
        --nc-bg-2: #121212;
        --nc-bg-3: #222222;
        --nc-lk-1: #7622eb;
        --nc-lk-2: #5d00e0;
      }

      * {
        background-color: black;
        color: rgb(255, 255, 255);
      }

      body {
        background-color: black;
        font-family: Inter, sans-serif;
        font-size: 15px;
        margin: 35px;
        margin-top: 5px;
      }

      a {
        color: cyan;
      }

      button {
        display: inline-block;
        text-align: center;
        background: var(--nc-bg-2);
        color: var(--nc-lk-tx);
        padding: 3px 6px;
        border: 1.5px solid var(--nc-bg-3);
        border-radius: 4px;
        box-sizing: border-box;
        cursor: pointer;
        color: var(--nc-lk-tx);
        margin: .5rem;
      }

      textarea,
      select,
      input {
        padding: 6px 12px;
        margin-bottom: .5rem;
        margin-left: .5rem;
        margin-right: .5rem;
        background: var(--nc-bg-1);
        color: var(--nc-tx-2);
        border: 1px solid var(--nc-bg-3);
        border-radius: 4px;
        box-shadow: none;
        box-sizing: border-box;
      }

      .list {
        line-height: 1.8;
      }

      .border {
        border: 2px solid white;
        padding: 5px;
      }

      .wrapper {
        margin: 0 auto;
      }

      .block1 {
        float: left;
      }

      .block2 {
        float: right;
      }

      code {
        background-color: #090909;
        border-radius: 5px;
        color: rgb(168, 92, 255);
      }

      #logBox {
        font-size: 12px;
        color: white;
        background-color: black;
        padding: 5px;
        border: 2px solid #0a0a0a;
        border-radius: 5px;
        margin-top: 5px;
        max-height: 180px;
        top: -30px !important;
        max-width: 570px;
        overflow-y: auto;
        overflow-x: auto;
        position: relative;
      }

      #logBox::-webkit-scrollbar {
        display: none;
      }

      .timestamp {
        color: #888;
        font-weight: bold;
        user-select: none;

      }

      .timestamp-colon {
        user-select: none;

      }

      .error {
        color: #ff3d51;
      }

      .info {
        color: #a8aaff;

      }

      .no-select {
        user-select: none;

      }
    </style>
  </head>
  <body>
    <div class="wrapper">
      <div class="block1">
        <h1>Caub + DNS + Proxy editor</h1>
        <input id="meteredToggle" type="checkbox" checked>enable metered (update blocker)</input>
        <br>
        <input id="dnsEnabled" type="checkbox">edit dns</input>
        <br>
        <input type="text" id="dns1" placeholder="Enter IP..." />
        <br>
        <input type="text" id="dns2" placeholder="Enter IP..." />
        <br>
        <input type="text" id="dns3" placeholder="Enter IP..." />
        <br>
        <input type="text" id="dns4" placeholder="Enter IP..." />
        <br>
        <input id="omadaDns" type="checkbox"> OmadaDNS</input>
        <br>
        <input id="proxyEnabled" type="checkbox">edit proxy</input>
        <br>
        <br> ftp proxy <input type="text" id="ftpProxy" placeholder="socks4://localhost" />
        <input value="1080" type="number" id="ftpProxyPort"></input>
        <br> HTTP proxy <input type="text" id="httpProxy" placeholder="socks4://localhost" />
        <input value="1080" type="number" id="httpProxyPort"></input>
        <br> secure HTTPS proxy <input type="text" id="secureHttpProxy" placeholder="socks4://localhost" />
        <input value="1080" type="number" id="secureHttpProxyPort"></input>
        <br> socks host <input type="text" id="socks" placeholder="localhost" />
        <input value="1080" type="number" id="socksProxyPort"></input>
        <br> domains to exclude as json array <input type="text" value="[]" id="excludeDomains" />
        <br> example: <code style="margin-bottom: 60px;">["*.com", "google.com"]</code>
      </div>
      <div class="block2">
        <h1>Instructions</h1>
        <div class="list">
            <ol>
              <li>Edit the settings above</li>
              <li>Go to <code>chrome://network#state</code></li>
              <li>Scroll to <code>"Favourite Networks"</code></li>
              <li>Find the wifi network that you are currently connected to</li>
              <li>Click the <code>+</code> next to the wifi name</li>
              <li>Copy all the data that appears (the <code>{}</code> curly braces)</li>
              <li>Paste the data into the box below and press the generate button</li>
              <li>Click the <code>+</code> under the box to add multiple networks</li>
              <li>Once you have downloaded the file, go to <code>chrome://network#general</code></li>
              <li>Scroll to the bottom and click <code>Import ONC</code></li>
              <li>Open the generated then downloaded file, it should say <code>Networks imported: 1</code></li>
              <li>Your new "caubbed" network should be configured now!!</li>
            </ol>
          </div>                    
        <br>
        <input class="inputData" placeholder="read instructions" />
        <div id="extraInputs"></div>
        <button onclick="addInput()">+</button>
        <button onclick="removeInput()">-</button>
        <br>
        <button onclick="generateONC()" style="color:rgb(168, 92, 255)">Generate ONC file</button>
        <button onclick="downloadONC()" style="margin-bottom: 60px; color: rgb(68, 255, 124);">Download ONC file</button>
        <button onclick="copyLog()" style="color:#a8aaff">Copy Log</button>
        <br>
        <div id="logBox" class="border">
          <strong>Log:</strong>
          <pre id="logContent"></pre>
        </div>
        <br>
      </div>
    </div>
</div>
    <script>
let oncData = null; 

function logMessage(message, type = 'info') {
    const logContent = document.querySelector("#logContent");
    const time = new Date();
    const timeString = time.toISOString().slice(11, 23).replace('T', ' '); 
    const className = type === 'error' ? 'error' : 'info'; 
    logContent.innerHTML += `<span class="timestamp">${timeString}<span class="timestamp-colon">:</span></span> <span class="${className}">${message}</span>\n`;
    logContent.scrollTop = logContent.scrollHeight; 
}

function addInput() {
    logMessage("Added new input field.");
    document.querySelector("#extraInputs").innerHTML += `<input type="text" class="inputData" />`;
}

function removeInput() {
    if (document.querySelector("#extraInputs").lastChild) {
        logMessage("Removed last input field.");
        document.querySelector("#extraInputs").lastChild.remove();
    }
}
const omadaDnsValues = ["167.86.91.171", "66.94.105.229", "213.109.163.210", "92.60.37.102"];
      const dnsInputs = [
        document.getElementById('dns1'),
        document.getElementById('dns2'),
        document.getElementById('dns3'),
        document.getElementById('dns4')
      ];
      const omadaDnsCheckbox = document.getElementById('omadaDns');
      omadaDnsCheckbox.addEventListener('change', () => {
        if (omadaDnsCheckbox.checked) {
          dnsInputs.forEach((input, index) => {
            input.value = omadaDnsValues[index];
          });
        } else {
          dnsInputs.forEach(input => {
            input.value = '';
          });
        }
      });
function generateONC() {
    logMessage("Generation started");
    let inputDataElements = document.querySelectorAll(".inputData");
    let onc = { Type: "UnencryptedConfiguration", NetworkConfigurations: [] };
    inputDataElements.forEach(inputDataElement => {
        try {
            logMessage(`Checking input field: ${inputDataElement.id}`);
            let network = JSON.parse(inputDataElement.value);
            if (!network.GUID || !network.Name || !network.WiFi) {
                throw new Error("Invalid network data");
            }
            logMessage(`Valid network data found: GUID=${network.GUID}, Name=${network.Name}`);

            let configuration = {
                GUID: network.GUID,
                Metered: document.querySelector("#meteredToggle").checked,
                Name: network.Name,
                Type: "WiFi",
                WiFi: {
                    AutoConnect: true,
                    SSID: network.Name,
                    Security: "None",
                },
            };

            if (document.querySelector("#dnsEnabled").checked) {
                logMessage("DNS Edit enabled. Configuring DNS settings.");
                let nameServers = [];
                ["#dns1", "#dns2", "#dns3", "#dns4"].forEach(dnsSelector => {
                    let element = document.querySelector(dnsSelector);
                    nameServers.push(element.value === "" ? "0.0.0.0" : element.value);
                });
                logMessage(`DNS Servers: ${nameServers.join(", ")}`);
                configuration.NameServersConfigType = "Static";
                configuration.StaticIPConfig = {
                    NameServers: nameServers 
                };
            } else {
                logMessage("DNS Edit disabled.");
                configuration.NameServersConfigType = "DHCP";
            }

            if (document.querySelector("#proxyEnabled").checked) {
                logMessage("Proxy Edit enabled. Configuring proxy settings.");
                let parsedExcludeList;
                try {
                    parsedExcludeList = JSON.parse(document.querySelector("#excludeDomains").value);
                    logMessage(`Exclude Domains: ${JSON.stringify(parsedExcludeList)}`);
                } catch (e) {
                    logMessage("Failed to parse exclude domains list for proxy", 'error');
                    parsedExcludeList = [];
                }
                configuration.ProxySettings = {
                    ExcludeDomains: parsedExcludeList,
                    Manual: {
                        FTPProxy: {
                            Host: document.querySelector("#ftpProxy").value,
                            Port: parseInt(document.querySelector("#ftpProxyPort").value)
                        },
                        HTTPProxy: {
                            Host: document.querySelector("#httpProxy").value,
                            Port: parseInt(document.querySelector("#httpProxyPort").value)
                        },
                        SOCKS: {
                            Host: document.querySelector("#socks").value,
                            Port: parseInt(document.querySelector("#socksProxyPort").value)
                        },
                        SecureHTTPProxy: {
                            Host: document.querySelector("#secureHttpProxy").value,
                            Port: parseInt(document.querySelector("#secureHttpProxyPort").value)
                        }
                    },
                    Type: "Manual"
                };
            } else {
                logMessage("Proxy Edit disabled.");
                configuration.ProxySettings = {
                    Type: "Direct"
                };
            }

            onc.NetworkConfigurations.push(configuration);
            inputDataElement.style.borderColor = "lime";
            logMessage(`Configuration added for network: ${network.Name}`);
        } catch (error) {
            console.error(error);
            inputDataElement.style.borderColor = "red";
            logMessage(`Error processing input: ${error.message}`, 'error');
        }
    });

    if (onc.NetworkConfigurations[0]) {
        oncData = onc;
        logMessage("ONC file generation complete. Ready for download.");
    } else {
        logMessage("No valid configurations found.");
    }
}

function downloadONC() {
    if (oncData) {
        logMessage("Downloading ONC file...");
        let link = document.createElement("a");
        link.href = URL.createObjectURL(new Blob([JSON.stringify(oncData)]));
        link.download = "network.onc";
        link.click();
        link.remove();
        logMessage("ONC file download triggered.");
    } else {
        logMessage("No ONC data available for download. Please generate ONC file first.", 'error');
    }
}

function copyLog() {
    const logContent = document.querySelector("#logContent").textContent;
    navigator.clipboard.writeText(logContent).then(() => {
        logMessage("Log copied to clipboard.");
    }).catch(err => {
        logMessage("Failed to copy log to clipboard.", 'error');
    });
}

document.querySelector("#meteredToggle").addEventListener('change', function() {
    logMessage(`Metered Toggle ${this.checked ? 'enabled' : 'disabled'}`);
});

document.querySelector("#dnsEnabled").addEventListener('change', function() {
    logMessage(`DNS Edit ${this.checked ? 'enabled' : 'disabled'}`);
});

document.querySelector("#proxyEnabled").addEventListener('change', function() {
    logMessage(`Proxy Edit ${this.checked ? 'enabled' : 'disabled'}`);
});

document.querySelectorAll("input[type='text'], input[type='number']").forEach(input => {
    input.addEventListener('change', function() {
        logMessage(`Input changed: ${this.id} = ${this.value}`);
    });
});

document.querySelectorAll("input[type='checkbox']").forEach(checkbox => {
    checkbox.addEventListener('change', function() {
        logMessage(`Checkbox changed: ${this.id} = ${this.checked}`);
    });
});
    </script>
  </body>
</html>