${selectedOperation}
↑
↓
-
+
⚙️
X
@@ -279,393 +263,379 @@ document.getElementById('addOperationBtn').addEventListener('click', function()
`;
+ pipelineList.appendChild(listItem);
- pipelineList.appendChild(listItem);
+ listItem.querySelector(".move-up").addEventListener("click", function (event) {
+ event.preventDefault();
+ if (listItem.previousElementSibling) {
+ pipelineList.insertBefore(listItem, listItem.previousElementSibling);
+ updateConfigInDropdown();
+ }
+ });
- listItem.querySelector('.move-up').addEventListener('click', function(event) {
- event.preventDefault();
- if (listItem.previousElementSibling) {
- pipelineList.insertBefore(listItem, listItem.previousElementSibling);
- updateConfigInDropdown();
- }
- });
+ listItem.querySelector(".move-down").addEventListener("click", function (event) {
+ event.preventDefault();
+ if (listItem.nextElementSibling) {
+ pipelineList.insertBefore(listItem.nextElementSibling, listItem);
+ updateConfigInDropdown();
+ }
+ });
- listItem.querySelector('.move-down').addEventListener('click', function(event) {
- event.preventDefault();
- if (listItem.nextElementSibling) {
- pipelineList.insertBefore(listItem.nextElementSibling, listItem);
- updateConfigInDropdown();
- }
+ listItem.querySelector(".remove").addEventListener("click", function (event) {
+ event.preventDefault();
+ pipelineList.removeChild(listItem);
+ hideOrShowPipelineHeader();
+ updateConfigInDropdown();
+ });
- });
+ listItem.querySelector(".pipelineSettings").addEventListener("click", function (event) {
+ event.preventDefault();
+ showpipelineSettingsModal(selectedOperation);
+ hideOrShowPipelineHeader();
+ });
- listItem.querySelector('.remove').addEventListener('click', function(event) {
- event.preventDefault();
- pipelineList.removeChild(listItem);
- hideOrShowPipelineHeader();
- updateConfigInDropdown();
- });
+ function showpipelineSettingsModal(operation) {
+ let pipelineSettingsModal = document.getElementById("pipelineSettingsModal");
+ let pipelineSettingsContent = document.getElementById("pipelineSettingsContent");
+ let operationData = apiDocs[operation].post.parameters || [];
- listItem.querySelector('.pipelineSettings').addEventListener('click', function(event) {
- event.preventDefault();
- showpipelineSettingsModal(selectedOperation);
- hideOrShowPipelineHeader();
- });
+ // Resolve the $ref reference to get actual schema properties
+ let refKey = apiDocs[operation].post.requestBody.content["multipart/form-data"].schema["$ref"].split("/").pop();
+ let requestBodyData = apiSchemas[refKey].properties || {};
- function showpipelineSettingsModal(operation) {
- let pipelineSettingsModal = document.getElementById('pipelineSettingsModal');
- let pipelineSettingsContent = document.getElementById('pipelineSettingsContent');
- let operationData = apiDocs[operation].post.parameters || [];
+ // Combine operationData and requestBodyData into a single array
+ operationData = operationData.concat(
+ Object.keys(requestBodyData).map((key) => ({
+ name: key,
+ schema: requestBodyData[key],
+ })),
+ );
- // Resolve the $ref reference to get actual schema properties
- let refKey = apiDocs[operation].post.requestBody.content['multipart/form-data'].schema['$ref'].split('/').pop();
- let requestBodyData = apiSchemas[refKey].properties || {};
+ pipelineSettingsContent.innerHTML = "";
- // Combine operationData and requestBodyData into a single array
- operationData = operationData.concat(Object.keys(requestBodyData).map(key => ({
- name: key,
- schema: requestBodyData[key]
- })));
+ operationData.forEach((parameter) => {
+ // If the parameter name is 'fileInput', return early to skip the rest of this iteration
+ if (parameter.name === "fileInput") return;
- pipelineSettingsContent.innerHTML = '';
+ let parameterDiv = document.createElement("div");
+ parameterDiv.className = "mb-3";
- operationData.forEach(parameter => {
- // If the parameter name is 'fileInput', return early to skip the rest of this iteration
- if (parameter.name === 'fileInput') return;
+ let parameterLabel = document.createElement("label");
+ parameterLabel.textContent = `${parameter.name} (${parameter.schema.type}): `;
+ parameterLabel.title = parameter.schema.description;
+ parameterLabel.setAttribute("for", parameter.name);
+ parameterDiv.appendChild(parameterLabel);
- let parameterDiv = document.createElement('div');
- parameterDiv.className = "mb-3";
+ let defaultValue = parameter.schema.example;
+ if (defaultValue === undefined) defaultValue = parameter.schema.default;
- let parameterLabel = document.createElement('label');
- parameterLabel.textContent = `${parameter.name} (${parameter.schema.type}): `;
- parameterLabel.title = parameter.schema.description;
- parameterLabel.setAttribute('for', parameter.name);
- parameterDiv.appendChild(parameterLabel);
+ let parameterInput;
- let defaultValue = parameter.schema.example;
- if (defaultValue === undefined) defaultValue = parameter.schema.default;
+ // check if enum exists in schema
+ if (parameter.schema.enum) {
+ // if enum exists, create a select element
+ parameterInput = document.createElement("select");
+ parameterInput.className = "form-control";
- let parameterInput;
+ // iterate over each enum value and create an option for it
+ parameter.schema.enum.forEach((value) => {
+ let option = document.createElement("option");
+ option.value = value;
+ option.text = value;
+ parameterInput.appendChild(option);
+ });
+ } else {
+ // switch-case statement for handling non-enum types
+ switch (parameter.schema.type) {
+ case "string":
+ if (parameter.schema.format === "binary") {
+ // This is a file input
- // check if enum exists in schema
- if (parameter.schema.enum) {
- // if enum exists, create a select element
- parameterInput = document.createElement('select');
- parameterInput.className = "form-control";
-
- // iterate over each enum value and create an option for it
- parameter.schema.enum.forEach(value => {
- let option = document.createElement('option');
- option.value = value;
- option.text = value;
- parameterInput.appendChild(option);
- });
- } else {
- // switch-case statement for handling non-enum types
- switch (parameter.schema.type) {
- case 'string':
- if (parameter.schema.format === 'binary') {
- // This is a file input
-
- //parameterInput = document.createElement('input');
- //parameterInput.type = 'file';
- //parameterInput.className = "form-control";
-
- parameterInput = document.createElement('input');
- parameterInput.type = 'text';
- parameterInput.className = "form-control";
- parameterInput.value = "FileInputPathToBeInputtedManuallyForOffline";
- } else {
- parameterInput = document.createElement('input');
- parameterInput.type = 'text';
- parameterInput.className = "form-control";
- if (defaultValue !== undefined) parameterInput.value = defaultValue;
- }
- break;
- case 'number':
- case 'integer':
- parameterInput = document.createElement('input');
- parameterInput.type = 'number';
- parameterInput.className = "form-control";
- if (defaultValue !== undefined) parameterInput.value = defaultValue;
- break;
- case 'boolean':
- parameterInput = document.createElement('input');
- parameterInput.type = 'checkbox';
- if (defaultValue === true) parameterInput.checked = true;
- break;
- case 'array':
- case 'object':
- //TODO compare to doc and check if fileInput array? parameter.schema.format === 'binary'
- parameterInput = document.createElement('textarea');
- parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}, If this is a fileInput, it is not currently supported`;
- parameterInput.className = "form-control";
- break;
- default:
- parameterInput = document.createElement('input');
- parameterInput.type = 'text';
- parameterInput.className = "form-control";
- if (defaultValue !== undefined) parameterInput.value = defaultValue;
- }
- }
- parameterInput.id = parameter.name;
-
- console.log("defaultValue", defaultValue);
- console.log("parameterInput", parameterInput);
- if (operationSettings[operation] && operationSettings[operation][parameter.name] !== undefined) {
- let savedValue = operationSettings[operation][parameter.name];
-
- switch (parameter.schema.type) {
- case 'number':
- case 'integer':
- parameterInput.value = savedValue.toString();
- break;
- case 'boolean':
- parameterInput.checked = savedValue;
- break;
- case 'array':
- case 'object':
- parameterInput.value = JSON.stringify(savedValue);
- break;
- default:
- parameterInput.value = savedValue;
- }
- }
- console.log("parameterInput2", parameterInput);
- parameterDiv.appendChild(parameterInput);
-
- pipelineSettingsContent.appendChild(parameterDiv);
- });
-
- if(hasSettings) {
- let saveButton = document.createElement('button');
- saveButton.textContent = saveSettings;
- saveButton.className = "btn btn-primary";
- saveButton.addEventListener('click', function(event) {
- event.preventDefault();
- let settings = {};
- operationData.forEach(parameter => {
- if (parameter.name !== "fileInput") {
- let value = document.getElementById(parameter.name).value;
- switch (parameter.schema.type) {
- case 'number':
- case 'integer':
- settings[parameter.name] = Number(value);
- break;
- case 'boolean':
- settings[parameter.name] = document.getElementById(parameter.name).checked;
- break;
- case 'array':
- case 'object':
- if (value === null || value === '') {
- settings[parameter.name] = '';
- } else {
- try {
- settings[parameter.name] = JSON.parse(value);
- } catch (err) {
- console.error(`Invalid JSON format for ${parameter.name}`);
- }
- }
- break;
- default:
- settings[parameter.name] = value;
- }
- }
- });
- operationSettings[operation] = settings;
- //pipelineSettingsModal.style.display = "none";
- });
- pipelineSettingsContent.appendChild(saveButton);
- saveButton.click();
- }
- //pipelineSettingsModal.style.display = "block";
-
- //pipelineSettingsModal.getElementsByClassName("close")[0].onclick = function() {
- // pipelineSettingsModal.style.display = "none";
- //}
-
- //window.onclick = function(event) {
- // if (event.target == pipelineSettingsModal) {
- // pipelineSettingsModal.style.display = "none";
- // }
- //}
- }
- showpipelineSettingsModal(selectedOperation);
- updateConfigInDropdown();
- hideOrShowPipelineHeader();
+ //parameterInput = document.createElement('input');
+ //parameterInput.type = 'file';
+ //parameterInput.className = "form-control";
+ parameterInput = document.createElement("input");
+ parameterInput.type = "text";
+ parameterInput.className = "form-control";
+ parameterInput.value = "FileInputPathToBeInputtedManuallyForOffline";
+ } else {
+ parameterInput = document.createElement("input");
+ parameterInput.type = "text";
+ parameterInput.className = "form-control";
+ if (defaultValue !== undefined) parameterInput.value = defaultValue;
+ }
+ break;
+ case "number":
+ case "integer":
+ parameterInput = document.createElement("input");
+ parameterInput.type = "number";
+ parameterInput.className = "form-control";
+ if (defaultValue !== undefined) parameterInput.value = defaultValue;
+ break;
+ case "boolean":
+ parameterInput = document.createElement("input");
+ parameterInput.type = "checkbox";
+ if (defaultValue === true) parameterInput.checked = true;
+ break;
+ case "array":
+ case "object":
+ //TODO compare to doc and check if fileInput array? parameter.schema.format === 'binary'
+ parameterInput = document.createElement("textarea");
+ parameterInput.placeholder = `Enter a JSON formatted ${parameter.schema.type}, If this is a fileInput, it is not currently supported`;
+ parameterInput.className = "form-control";
+ break;
+ default:
+ parameterInput = document.createElement("input");
+ parameterInput.type = "text";
+ parameterInput.className = "form-control";
+ if (defaultValue !== undefined) parameterInput.value = defaultValue;
+ }
+ }
+ parameterInput.id = parameter.name;
+ console.log("defaultValue", defaultValue);
+ console.log("parameterInput", parameterInput);
+ if (operationSettings[operation] && operationSettings[operation][parameter.name] !== undefined) {
+ let savedValue = operationSettings[operation][parameter.name];
+ switch (parameter.schema.type) {
+ case "number":
+ case "integer":
+ parameterInput.value = savedValue.toString();
+ break;
+ case "boolean":
+ parameterInput.checked = savedValue;
+ break;
+ case "array":
+ case "object":
+ parameterInput.value = JSON.stringify(savedValue);
+ break;
+ default:
+ parameterInput.value = savedValue;
+ }
+ }
+ console.log("parameterInput2", parameterInput);
+ parameterDiv.appendChild(parameterInput);
+ pipelineSettingsContent.appendChild(parameterDiv);
+ });
+ if (hasSettings) {
+ let saveButton = document.createElement("button");
+ saveButton.textContent = saveSettings;
+ saveButton.className = "btn btn-primary";
+ saveButton.addEventListener("click", function (event) {
+ event.preventDefault();
+ let settings = {};
+ operationData.forEach((parameter) => {
+ if (parameter.name !== "fileInput") {
+ let value = document.getElementById(parameter.name).value;
+ switch (parameter.schema.type) {
+ case "number":
+ case "integer":
+ settings[parameter.name] = Number(value);
+ break;
+ case "boolean":
+ settings[parameter.name] = document.getElementById(parameter.name).checked;
+ break;
+ case "array":
+ case "object":
+ if (value === null || value === "") {
+ settings[parameter.name] = "";
+ } else {
+ try {
+ settings[parameter.name] = JSON.parse(value);
+ } catch (err) {
+ console.error(`Invalid JSON format for ${parameter.name}`);
+ }
+ }
+ break;
+ default:
+ settings[parameter.name] = value;
+ }
+ }
+ });
+ operationSettings[operation] = settings;
+ //pipelineSettingsModal.style.display = "none";
+ });
+ pipelineSettingsContent.appendChild(saveButton);
+ saveButton.click();
+ }
+ //pipelineSettingsModal.style.display = "block";
+ //pipelineSettingsModal.getElementsByClassName("close")[0].onclick = function() {
+ // pipelineSettingsModal.style.display = "none";
+ //}
+ //window.onclick = function(event) {
+ // if (event.target == pipelineSettingsModal) {
+ // pipelineSettingsModal.style.display = "none";
+ // }
+ //}
+ }
+ showpipelineSettingsModal(selectedOperation);
+ updateConfigInDropdown();
+ hideOrShowPipelineHeader();
});
function updateConfigInDropdown() {
- let pipelineSelect = document.getElementById('pipelineSelect');
- let selectedOption = pipelineSelect.options[pipelineSelect.selectedIndex];
+ let pipelineSelect = document.getElementById("pipelineSelect");
+ let selectedOption = pipelineSelect.options[pipelineSelect.selectedIndex];
- // Get the current configuration as JSON
- let pipelineConfigJson = configToJson();
- console.log("pipelineConfigJson", pipelineConfigJson);
- if (!pipelineConfigJson) {
- console.error("Failed to update configuration: Invalid configuration");
- return;
- }
-
- // Update the value of the selected option with the new configuration
- selectedOption.value = pipelineConfigJson;
+ // Get the current configuration as JSON
+ let pipelineConfigJson = configToJson();
+ console.log("pipelineConfigJson", pipelineConfigJson);
+ if (!pipelineConfigJson) {
+ console.error("Failed to update configuration: Invalid configuration");
+ return;
+ }
+ // Update the value of the selected option with the new configuration
+ selectedOption.value = pipelineConfigJson;
}
-var saveBtn = document.getElementById('savePipelineBtn');
+var saveBtn = document.getElementById("savePipelineBtn");
// Remove any existing event listeners
-saveBtn.removeEventListener('click', savePipeline);
+saveBtn.removeEventListener("click", savePipeline);
// Add the event listener
-saveBtn.addEventListener('click', savePipeline);
-console.log("saveBtn", saveBtn)
+saveBtn.addEventListener("click", savePipeline);
+console.log("saveBtn", saveBtn);
function configToJson() {
- if (!validatePipeline()) {
- return null; // Return null if validation fails
- }
+ if (!validatePipeline()) {
+ return null; // Return null if validation fails
+ }
- var pipelineName = document.getElementById('pipelineName').value;
- let pipelineList = document.getElementById('pipelineList').children;
- let pipelineConfig = {
- "name": pipelineName,
- "pipeline": [],
- "_examples": {
- "outputDir": "{outputFolder}/{folderName}",
- "outputFileName": "{filename}-{pipelineName}-{date}-{time}"
- },
- "outputDir": "{outputFolder}",
- "outputFileName": "{filename}"
- };
+ var pipelineName = document.getElementById("pipelineName").value;
+ let pipelineList = document.getElementById("pipelineList").children;
+ let pipelineConfig = {
+ name: pipelineName,
+ pipeline: [],
+ _examples: {
+ outputDir: "{outputFolder}/{folderName}",
+ outputFileName: "{filename}-{pipelineName}-{date}-{time}",
+ },
+ outputDir: "{outputFolder}",
+ outputFileName: "{filename}",
+ };
- for (let i = 0; i < pipelineList.length; i++) {
- let operationName = pipelineList[i].querySelector('.operationName').textContent;
- let parameters = operationSettings[operationName] || {};
+ for (let i = 0; i < pipelineList.length; i++) {
+ let operationName = pipelineList[i].querySelector(".operationName").textContent;
+ let parameters = operationSettings[operationName] || {};
- parameters['fileInput'] = 'automated';
+ parameters["fileInput"] = "automated";
- pipelineConfig.pipeline.push({
- "operation": operationName,
- "parameters": parameters
- });
- }
+ pipelineConfig.pipeline.push({
+ operation: operationName,
+ parameters: parameters,
+ });
+ }
- return JSON.stringify(pipelineConfig, null, 2);
+ return JSON.stringify(pipelineConfig, null, 2);
}
-
-
function savePipeline() {
- let pipelineConfigJson = configToJson();
- if (!pipelineConfigJson) {
- console.error("Failed to save pipeline: Invalid configuration");
- return;
- }
+ let pipelineConfigJson = configToJson();
+ if (!pipelineConfigJson) {
+ console.error("Failed to save pipeline: Invalid configuration");
+ return;
+ }
- let pipelineName = document.getElementById('pipelineName').value;
- console.log("Downloading...");
- let a = document.createElement('a');
- a.href = URL.createObjectURL(new Blob([pipelineConfigJson], { type: 'application/json' }));
- a.download = pipelineName + '.json';
- a.style.display = 'none';
+ let pipelineName = document.getElementById("pipelineName").value;
+ console.log("Downloading...");
+ let a = document.createElement("a");
+ a.href = URL.createObjectURL(new Blob([pipelineConfigJson], { type: "application/json" }));
+ a.download = pipelineName + ".json";
+ a.style.display = "none";
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
}
-
async function processPipelineConfig(configString) {
- console.log("configString", configString);
- let pipelineConfig = JSON.parse(configString);
- let pipelineList = document.getElementById('pipelineList');
+ console.log("configString", configString);
+ let pipelineConfig = JSON.parse(configString);
+ let pipelineList = document.getElementById("pipelineList");
- while (pipelineList.firstChild) {
- pipelineList.removeChild(pipelineList.firstChild);
- }
- document.getElementById('pipelineName').value = pipelineConfig.name
- for (const operationConfig of pipelineConfig.pipeline) {
- let operationsDropdown = document.getElementById('operationsDropdown');
- operationsDropdown.value = operationConfig.operation;
- operationSettings[operationConfig.operation] = operationConfig.parameters;
+ while (pipelineList.firstChild) {
+ pipelineList.removeChild(pipelineList.firstChild);
+ }
+ document.getElementById("pipelineName").value = pipelineConfig.name;
+ for (const operationConfig of pipelineConfig.pipeline) {
+ let operationsDropdown = document.getElementById("operationsDropdown");
+ operationsDropdown.value = operationConfig.operation;
+ operationSettings[operationConfig.operation] = operationConfig.parameters;
- // assuming addOperation is async
- await new Promise((resolve) => {
- document.getElementById('addOperationBtn').addEventListener('click', resolve, { once: true });
- document.getElementById('addOperationBtn').click();
- });
+ // assuming addOperation is async
+ await new Promise((resolve) => {
+ document.getElementById("addOperationBtn").addEventListener("click", resolve, { once: true });
+ document.getElementById("addOperationBtn").click();
+ });
- let lastOperation = pipelineList.lastChild;
+ let lastOperation = pipelineList.lastChild;
- Object.keys(operationConfig.parameters).forEach(parameterName => {
- let input = document.getElementById(parameterName);
- if (input) {
- switch (input.type) {
- case 'checkbox':
- input.checked = operationConfig.parameters[parameterName];
- break;
- case 'number':
- input.value = operationConfig.parameters[parameterName].toString();
- break;
- case 'file':
- if (parameterName !== 'fileInput') {
- // Create a new file input element
- let newInput = document.createElement('input');
- newInput.type = 'file';
- newInput.id = parameterName;
+ Object.keys(operationConfig.parameters).forEach((parameterName) => {
+ let input = document.getElementById(parameterName);
+ if (input) {
+ switch (input.type) {
+ case "checkbox":
+ input.checked = operationConfig.parameters[parameterName];
+ break;
+ case "number":
+ input.value = operationConfig.parameters[parameterName].toString();
+ break;
+ case "file":
+ if (parameterName !== "fileInput") {
+ // Create a new file input element
+ let newInput = document.createElement("input");
+ newInput.type = "file";
+ newInput.id = parameterName;
- // Add the new file input to the main page (change the selector according to your needs)
- document.querySelector('#main').appendChild(newInput);
- }
- break;
- case 'text':
- case 'textarea':
- default:
- input.value = JSON.stringify(operationConfig.parameters[parameterName]);
- }
- }
- });
-
- }
+ // Add the new file input to the main page (change the selector according to your needs)
+ document.querySelector("#main").appendChild(newInput);
+ }
+ break;
+ case "text":
+ case "textarea":
+ default:
+ input.value = JSON.stringify(operationConfig.parameters[parameterName]);
+ }
+ }
+ });
+ }
}
-
-document.getElementById('uploadPipelineBtn').addEventListener('click', function() {
- document.getElementById('uploadPipelineInput').click();
+document.getElementById("uploadPipelineBtn").addEventListener("click", function () {
+ document.getElementById("uploadPipelineInput").click();
});
-document.getElementById('uploadPipelineInput').addEventListener('change', function(e) {
- let reader = new FileReader();
- reader.onload = function(event) {
- processPipelineConfig(event.target.result);
- };
- reader.readAsText(e.target.files[0]);
- hideOrShowPipelineHeader();
+document.getElementById("uploadPipelineInput").addEventListener("change", function (e) {
+ let reader = new FileReader();
+ reader.onload = function (event) {
+ processPipelineConfig(event.target.result);
+ };
+ reader.readAsText(e.target.files[0]);
+ hideOrShowPipelineHeader();
});
-document.getElementById('pipelineSelect').addEventListener('change', function(e) {
- let selectedPipelineJson = e.target.value; // assuming the selected value is the JSON string of the pipeline config
- processPipelineConfig(selectedPipelineJson);
+document.getElementById("pipelineSelect").addEventListener("change", function (e) {
+ let selectedPipelineJson = e.target.value; // assuming the selected value is the JSON string of the pipeline config
+ processPipelineConfig(selectedPipelineJson);
});
-
function hideOrShowPipelineHeader() {
- var pipelineHeader = document.getElementById('pipelineHeader');
- var pipelineList = document.getElementById('pipelineList');
+ var pipelineHeader = document.getElementById("pipelineHeader");
+ var pipelineList = document.getElementById("pipelineList");
- if (pipelineList.children.length === 0) {
- // Hide the pipeline header if there are no items in the pipeline list
- pipelineHeader.style.display = 'none';
- } else {
- // Show the pipeline header if there are items in the pipeline list
- pipelineHeader.style.display = 'block';
- }
+ if (pipelineList.children.length === 0) {
+ // Hide the pipeline header if there are no items in the pipeline list
+ pipelineHeader.style.display = "none";
+ } else {
+ // Show the pipeline header if there are items in the pipeline list
+ pipelineHeader.style.display = "block";
+ }
}
diff --git a/src/main/resources/static/js/search.js b/src/main/resources/static/js/search.js
index 674b54b7..2329f998 100644
--- a/src/main/resources/static/js/search.js
+++ b/src/main/resources/static/js/search.js
@@ -1,75 +1,76 @@
// Toggle search bar when the search icon is clicked
-document.querySelector('#search-icon').addEventListener('click', function(e) {
- e.preventDefault();
- var searchBar = document.querySelector('#navbarSearch');
- searchBar.classList.toggle('show');
+document.querySelector("#search-icon").addEventListener("click", function (e) {
+ e.preventDefault();
+ var searchBar = document.querySelector("#navbarSearch");
+ searchBar.classList.toggle("show");
});
-window.onload = function() {
- var items = document.querySelectorAll('.dropdown-item, .nav-link');
- var dummyContainer = document.createElement('div');
- dummyContainer.style.position = 'absolute';
- dummyContainer.style.visibility = 'hidden';
- dummyContainer.style.whiteSpace = 'nowrap'; // Ensure we measure full width
- document.body.appendChild(dummyContainer);
+window.onload = function () {
+ var items = document.querySelectorAll(".dropdown-item, .nav-link");
+ var dummyContainer = document.createElement("div");
+ dummyContainer.style.position = "absolute";
+ dummyContainer.style.visibility = "hidden";
+ dummyContainer.style.whiteSpace = "nowrap"; // Ensure we measure full width
+ document.body.appendChild(dummyContainer);
- var maxWidth = 0;
+ var maxWidth = 0;
- items.forEach(function(item) {
- var clone = item.cloneNode(true);
- dummyContainer.appendChild(clone);
- var width = clone.offsetWidth;
- if (width > maxWidth) {
- maxWidth = width;
- }
- dummyContainer.removeChild(clone);
- });
+ items.forEach(function (item) {
+ var clone = item.cloneNode(true);
+ dummyContainer.appendChild(clone);
+ var width = clone.offsetWidth;
+ if (width > maxWidth) {
+ maxWidth = width;
+ }
+ dummyContainer.removeChild(clone);
+ });
- document.body.removeChild(dummyContainer);
+ document.body.removeChild(dummyContainer);
- // Store max width for later use
- window.navItemMaxWidth = maxWidth;
+ // Store max width for later use
+ window.navItemMaxWidth = maxWidth;
};
// Show search results as user types in search box
-document.querySelector('#navbarSearchInput').addEventListener('input', function(e) {
- var searchText = e.target.value.toLowerCase();
- var items = document.querySelectorAll('.dropdown-item, .nav-link');
- var resultsBox = document.querySelector('#searchResults');
+document.querySelector("#navbarSearchInput").addEventListener("input", function (e) {
+ var searchText = e.target.value.toLowerCase();
+ var items = document.querySelectorAll(".dropdown-item, .nav-link");
+ var resultsBox = document.querySelector("#searchResults");
- // Clear any previous results
- resultsBox.innerHTML = '';
+ // Clear any previous results
+ resultsBox.innerHTML = "";
- items.forEach(function(item) {
- var titleElement = item.querySelector('.icon-text');
- var iconElement = item.querySelector('.icon');
- var itemHref = item.getAttribute('href');
- var tags = item.getAttribute('data-bs-tags') || ""; // If no tags, default to empty string
+ items.forEach(function (item) {
+ var titleElement = item.querySelector(".icon-text");
+ var iconElement = item.querySelector(".icon");
+ var itemHref = item.getAttribute("href");
+ var tags = item.getAttribute("data-bs-tags") || ""; // If no tags, default to empty string
- if (titleElement && iconElement && itemHref !== '#') {
- var title = titleElement.innerText;
- if ((title.toLowerCase().indexOf(searchText) !== -1 || tags.toLowerCase().indexOf(searchText) !== -1) && !resultsBox.querySelector(`a[href="${item.getAttribute('href')}"]`)) {
- var result = document.createElement('a');
- result.href = itemHref;
- result.classList.add('dropdown-item');
+ if (titleElement && iconElement && itemHref !== "#") {
+ var title = titleElement.innerText;
+ if (
+ (title.toLowerCase().indexOf(searchText) !== -1 || tags.toLowerCase().indexOf(searchText) !== -1) &&
+ !resultsBox.querySelector(`a[href="${item.getAttribute("href")}"]`)
+ ) {
+ var result = document.createElement("a");
+ result.href = itemHref;
+ result.classList.add("dropdown-item");
- var resultIcon = document.createElement('img');
- resultIcon.src = iconElement.src;
- resultIcon.alt = 'icon';
- resultIcon.classList.add('icon');
- result.appendChild(resultIcon);
+ var resultIcon = document.createElement("img");
+ resultIcon.src = iconElement.src;
+ resultIcon.alt = "icon";
+ resultIcon.classList.add("icon");
+ result.appendChild(resultIcon);
- var resultText = document.createElement('span');
- resultText.textContent = title;
- resultText.classList.add('icon-text');
- result.appendChild(resultText);
+ var resultText = document.createElement("span");
+ resultText.textContent = title;
+ resultText.classList.add("icon-text");
+ result.appendChild(resultText);
- resultsBox.appendChild(result);
- }
- }
- });
+ resultsBox.appendChild(result);
+ }
+ }
+ });
- // Set the width of the search results box to the maximum width
- resultsBox.style.width = window.navItemMaxWidth + 'px';
+ // Set the width of the search results box to the maximum width
+ resultsBox.style.width = window.navItemMaxWidth + "px";
});
-
-
diff --git a/src/main/resources/static/js/settings.js b/src/main/resources/static/js/settings.js
index 272b555b..77a55a3f 100644
--- a/src/main/resources/static/js/settings.js
+++ b/src/main/resources/static/js/settings.js
@@ -1,42 +1,33 @@
// Get the download option from local storage, or set it to 'sameWindow' if it doesn't exist
-var downloadOption = localStorage.getItem('downloadOption')
- || 'sameWindow';
+var downloadOption = localStorage.getItem("downloadOption") || "sameWindow";
// Set the selected option in the dropdown
-document.getElementById('downloadOption').value = downloadOption;
-
+document.getElementById("downloadOption").value = downloadOption;
// Save the selected option to local storage when the dropdown value changes
-document.getElementById('downloadOption').addEventListener(
- 'change',
- function() {
- downloadOption = this.value;
- localStorage.setItem('downloadOption',
- downloadOption);
- });
-
-
-// Get the zipThreshold value from local storage, or set it to 0 if it doesn't exist
-var zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4;
-
-// Set the value of the slider and the display span
-document.getElementById('zipThreshold').value = zipThreshold;
-document.getElementById('zipThresholdValue').textContent = zipThreshold;
-
-
-
-// Save the selected value to local storage when the slider value changes
-document.getElementById('zipThreshold').addEventListener('input', function() {
- zipThreshold = this.value;
- document.getElementById('zipThresholdValue').textContent = zipThreshold;
- localStorage.setItem('zipThreshold', zipThreshold);
+document.getElementById("downloadOption").addEventListener("change", function () {
+ downloadOption = this.value;
+ localStorage.setItem("downloadOption", downloadOption);
});
+// Get the zipThreshold value from local storage, or set it to 0 if it doesn't exist
+var zipThreshold = parseInt(localStorage.getItem("zipThreshold"), 10) || 4;
-var boredWaiting = localStorage.getItem('boredWaiting') || 'disabled';
-document.getElementById('boredWaiting').checked = boredWaiting === 'enabled';
+// Set the value of the slider and the display span
+document.getElementById("zipThreshold").value = zipThreshold;
+document.getElementById("zipThresholdValue").textContent = zipThreshold;
-document.getElementById('boredWaiting').addEventListener('change', function() {
- boredWaiting = this.checked ? 'enabled' : 'disabled';
- localStorage.setItem('boredWaiting', boredWaiting);
-});
\ No newline at end of file
+// Save the selected value to local storage when the slider value changes
+document.getElementById("zipThreshold").addEventListener("input", function () {
+ zipThreshold = this.value;
+ document.getElementById("zipThresholdValue").textContent = zipThreshold;
+ localStorage.setItem("zipThreshold", zipThreshold);
+});
+
+var boredWaiting = localStorage.getItem("boredWaiting") || "disabled";
+document.getElementById("boredWaiting").checked = boredWaiting === "enabled";
+
+document.getElementById("boredWaiting").addEventListener("change", function () {
+ boredWaiting = this.checked ? "enabled" : "disabled";
+ localStorage.setItem("boredWaiting", boredWaiting);
+});
diff --git a/src/main/resources/static/js/tab-container.js b/src/main/resources/static/js/tab-container.js
index bd97d2b6..2aa85b32 100644
--- a/src/main/resources/static/js/tab-container.js
+++ b/src/main/resources/static/js/tab-container.js
@@ -1,39 +1,38 @@
-
TabContainer = {
- initTabGroups() {
- const groups = document.querySelectorAll(".tab-group");
- const unloadedGroups = [...groups].filter(g => !g.initialised);
- unloadedGroups.forEach(group => {
- const containers = group.querySelectorAll(".tab-container");
- const tabTitles = [...containers].map(c => c.getAttribute("title"));
+ initTabGroups() {
+ const groups = document.querySelectorAll(".tab-group");
+ const unloadedGroups = [...groups].filter((g) => !g.initialised);
+ unloadedGroups.forEach((group) => {
+ const containers = group.querySelectorAll(".tab-container");
+ const tabTitles = [...containers].map((c) => c.getAttribute("title"));
- const tabList = document.createElement("div");
- tabList.classList.add("tab-buttons");
- tabTitles.forEach(title => {
- const tabButton = document.createElement("button");
- tabButton.innerHTML = title;
- tabButton.onclick = e => {
- this.setActiveTab(e.target);
- }
- tabList.appendChild(tabButton);
- });
- group.prepend(tabList);
+ const tabList = document.createElement("div");
+ tabList.classList.add("tab-buttons");
+ tabTitles.forEach((title) => {
+ const tabButton = document.createElement("button");
+ tabButton.innerHTML = title;
+ tabButton.onclick = (e) => {
+ this.setActiveTab(e.target);
+ };
+ tabList.appendChild(tabButton);
+ });
+ group.prepend(tabList);
- this.setActiveTab(tabList.firstChild);
+ this.setActiveTab(tabList.firstChild);
- group.initialised = true;
- });
- },
- setActiveTab(tabButton) {
- const group = tabButton.closest(".tab-group")
+ group.initialised = true;
+ });
+ },
+ setActiveTab(tabButton) {
+ const group = tabButton.closest(".tab-group");
- group.querySelectorAll(".active").forEach(el => el.classList.remove("active"));
+ group.querySelectorAll(".active").forEach((el) => el.classList.remove("active"));
- tabButton.classList.add("active");
- group.querySelector(`[title="${tabButton.innerHTML}"]`).classList.add("active");
- },
-}
+ tabButton.classList.add("active");
+ group.querySelector(`[title="${tabButton.innerHTML}"]`).classList.add("active");
+ },
+};
document.addEventListener("DOMContentLoaded", () => {
- TabContainer.initTabGroups();
-})
\ No newline at end of file
+ TabContainer.initTabGroups();
+});
diff --git a/src/main/resources/static/pdfjs/css/viewer.css b/src/main/resources/static/pdfjs/css/viewer.css
index 14a8aff0..ab0ad406 100644
--- a/src/main/resources/static/pdfjs/css/viewer.css
+++ b/src/main/resources/static/pdfjs/css/viewer.css
@@ -116,7 +116,6 @@
top: 0;
}
-
:root {
--annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,
");
--input-focus-border-color: Highlight;
@@ -139,9 +138,7 @@
.annotationLayer .textWidgetAnnotation :is(input, textarea):required,
.annotationLayer .choiceWidgetAnnotation select:required,
- .annotationLayer
- .buttonWidgetAnnotation:is(.checkBox, .radioButton)
- input:required {
+ .annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:required {
outline: 1.5px solid selectedItem;
}
@@ -228,9 +225,7 @@
height: 100%;
}
-.annotationLayer
-:is(.linkAnnotation, .buttonWidgetAnnotation.pushButton):not(.hasBorder)
-> a:hover {
+.annotationLayer :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton):not(.hasBorder) > a:hover {
opacity: 0.2;
background-color: rgba(255, 255, 0, 1);
box-shadow: 0 2px 10px rgba(255, 255, 0, 1);
@@ -268,9 +263,7 @@
.annotationLayer .textWidgetAnnotation :is(input, textarea):required,
.annotationLayer .choiceWidgetAnnotation select:required,
-.annotationLayer
-.buttonWidgetAnnotation:is(.checkBox, .radioButton)
-input:required {
+.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:required {
outline: 1.5px solid red;
}
@@ -288,9 +281,7 @@ input:required {
.annotationLayer .textWidgetAnnotation :is(input, textarea)[disabled],
.annotationLayer .choiceWidgetAnnotation select[disabled],
-.annotationLayer
-.buttonWidgetAnnotation:is(.checkBox, .radioButton)
-input[disabled] {
+.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input[disabled] {
background: none;
border: 2px solid var(--input-disabled-border-color);
cursor: not-allowed;
@@ -298,9 +289,7 @@ input[disabled] {
.annotationLayer .textWidgetAnnotation :is(input, textarea):hover,
.annotationLayer .choiceWidgetAnnotation select:hover,
-.annotationLayer
-.buttonWidgetAnnotation:is(.checkBox, .radioButton)
-input:hover {
+.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:hover {
border: 2px solid var(--input-hover-border-color);
}
@@ -489,7 +478,6 @@ input:hover {
z-index: -1;
}
-
:root {
--xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,
");
--xfa-focus-outline: auto;
@@ -827,10 +815,7 @@ input:hover {
--freetext-padding: 2px;
--resizer-bg-color: var(--outline-color);
--resizer-size: 6px;
- --resizer-shift: calc(
- 0px - (var(--outline-width) + var(--resizer-size)) / 2 -
- var(--outline-around-width)
- );
+ --resizer-shift: calc(0px - (var(--outline-width) + var(--resizer-size)) / 2 - var(--outline-around-width));
--editorFreeText-editing-cursor: text;
--editorInk-editing-cursor: url(../images/cursor-editorInk.svg) 0 16, pointer;
@@ -853,8 +838,7 @@ input:hover {
@media (-webkit-min-device-pixel-ratio: 1.1), (min-resolution: 1.1dppx) {
:root {
- --editorFreeText-editing-cursor: url(../images/cursor-editorFreeText.svg) 0 16,
- text;
+ --editorFreeText-editing-cursor: url(../images/cursor-editorFreeText.svg) 0 16, text;
}
}
@@ -1109,216 +1093,354 @@ input:hover {
}
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topLeft,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.topLeft,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topLeft,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.topLeft,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topLeft,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.topLeft,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topLeft,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.topLeft,
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomRight,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.bottomRight,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomRight,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.bottomRight,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomRight,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.bottomRight,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomRight {
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.bottomRight {
cursor: nwse-resize;
}
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topMiddle,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.topMiddle,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topMiddle,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.topMiddle,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topMiddle,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.topMiddle,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topMiddle,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.topMiddle,
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomMiddle,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.bottomMiddle,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomMiddle,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.bottomMiddle,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomMiddle,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.bottomMiddle,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomMiddle {
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.bottomMiddle {
cursor: ns-resize;
}
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topRight,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.topRight,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topRight,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.topRight,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topRight,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.topRight,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topRight,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.topRight,
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomLeft,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.bottomLeft,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomLeft,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.bottomLeft,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomLeft,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.bottomLeft,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomLeft {
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.bottomLeft {
cursor: nesw-resize;
}
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleRight,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.middleRight,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleRight,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.middleRight,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleRight,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.middleRight,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleRight,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.middleRight,
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleLeft,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.middleLeft,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleLeft,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.middleLeft,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleLeft,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.middleLeft,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleLeft {
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.middleLeft {
cursor: ew-resize;
}
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topLeft,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.topLeft,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topLeft,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.topLeft,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topLeft,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.topLeft,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topLeft,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.topLeft,
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomRight,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.bottomRight,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomRight,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.bottomRight,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomRight,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.bottomRight,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomRight {
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.bottomRight {
cursor: nesw-resize;
}
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topMiddle,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.topMiddle,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topMiddle,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.topMiddle,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topMiddle,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.topMiddle,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topMiddle,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.topMiddle,
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomMiddle,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.bottomMiddle,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomMiddle,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.bottomMiddle,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomMiddle,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.bottomMiddle,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomMiddle {
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.bottomMiddle {
cursor: ew-resize;
}
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.topRight,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.topRight,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.topRight,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.topRight,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.topRight,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.topRight,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.topRight,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.topRight,
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.bottomLeft,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.bottomLeft,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.bottomLeft,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.bottomLeft,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.bottomLeft,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.bottomLeft,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.bottomLeft {
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.bottomLeft {
cursor: nwse-resize;
}
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleRight,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.middleRight,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleRight,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.middleRight,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleRight,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.middleRight,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleRight,
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.middleRight,
.annotationEditorLayer[data-main-rotation="0"]
-:is([data-editor-rotation="90"], [data-editor-rotation="270"]) > .resizers > .resizer.middleLeft,
+ :is([data-editor-rotation="90"], [data-editor-rotation="270"])
+ > .resizers
+ > .resizer.middleLeft,
.annotationEditorLayer[data-main-rotation="90"]
-:is([data-editor-rotation="0"], [data-editor-rotation="180"]) > .resizers > .resizer.middleLeft,
+ :is([data-editor-rotation="0"], [data-editor-rotation="180"])
+ > .resizers
+ > .resizer.middleLeft,
.annotationEditorLayer[data-main-rotation="180"]
-:is([data-editor-rotation="270"], [data-editor-rotation="90"]) > .resizers > .resizer.middleLeft,
+ :is([data-editor-rotation="270"], [data-editor-rotation="90"])
+ > .resizers
+ > .resizer.middleLeft,
.annotationEditorLayer[data-main-rotation="270"]
-:is([data-editor-rotation="180"], [data-editor-rotation="0"]) > .resizers > .resizer.middleLeft {
+ :is([data-editor-rotation="180"], [data-editor-rotation="0"])
+ > .resizers
+ > .resizer.middleLeft {
cursor: ns-resize;
}
.annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="90"],
- [data-main-rotation="90"] [data-editor-rotation="0"],
- [data-main-rotation="180"] [data-editor-rotation="270"],
- [data-main-rotation="270"] [data-editor-rotation="180"]
- ) .altText {
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="90"],
+ [data-main-rotation="90"] [data-editor-rotation="0"],
+ [data-main-rotation="180"] [data-editor-rotation="270"],
+ [data-main-rotation="270"] [data-editor-rotation="180"]
+ )
+ .altText {
rotate: 270deg;
}
-[dir="ltr"] .annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="90"],
- [data-main-rotation="90"] [data-editor-rotation="0"],
- [data-main-rotation="180"] [data-editor-rotation="270"],
- [data-main-rotation="270"] [data-editor-rotation="180"]
- ) .altText {
+[dir="ltr"]
+ .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="90"],
+ [data-main-rotation="90"] [data-editor-rotation="0"],
+ [data-main-rotation="180"] [data-editor-rotation="270"],
+ [data-main-rotation="270"] [data-editor-rotation="180"]
+ )
+ .altText {
inset-inline-start: calc(100% - 8px);
}
-[dir="ltr"] .annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="90"],
- [data-main-rotation="90"] [data-editor-rotation="0"],
- [data-main-rotation="180"] [data-editor-rotation="270"],
- [data-main-rotation="270"] [data-editor-rotation="180"]
- ) .altText.small {
+[dir="ltr"]
+ .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="90"],
+ [data-main-rotation="90"] [data-editor-rotation="0"],
+ [data-main-rotation="180"] [data-editor-rotation="270"],
+ [data-main-rotation="270"] [data-editor-rotation="180"]
+ )
+ .altText.small {
inset-inline-start: calc(100% + 8px);
inset-block-start: 100%;
}
-[dir="rtl"] .annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="90"],
- [data-main-rotation="90"] [data-editor-rotation="0"],
- [data-main-rotation="180"] [data-editor-rotation="270"],
- [data-main-rotation="270"] [data-editor-rotation="180"]
- ) .altText {
+[dir="rtl"]
+ .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="90"],
+ [data-main-rotation="90"] [data-editor-rotation="0"],
+ [data-main-rotation="180"] [data-editor-rotation="270"],
+ [data-main-rotation="270"] [data-editor-rotation="180"]
+ )
+ .altText {
inset-block-end: calc(100% - 8px);
}
-[dir="rtl"] .annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="90"],
- [data-main-rotation="90"] [data-editor-rotation="0"],
- [data-main-rotation="180"] [data-editor-rotation="270"],
- [data-main-rotation="270"] [data-editor-rotation="180"]
- ) .altText.small {
+[dir="rtl"]
+ .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="90"],
+ [data-main-rotation="90"] [data-editor-rotation="0"],
+ [data-main-rotation="180"] [data-editor-rotation="270"],
+ [data-main-rotation="270"] [data-editor-rotation="180"]
+ )
+ .altText.small {
inset-inline-start: -8px;
inset-block-start: 0;
}
.annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="180"],
- [data-main-rotation="90"] [data-editor-rotation="90"],
- [data-main-rotation="180"] [data-editor-rotation="0"],
- [data-main-rotation="270"] [data-editor-rotation="270"]
- ) .altText {
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="180"],
+ [data-main-rotation="90"] [data-editor-rotation="90"],
+ [data-main-rotation="180"] [data-editor-rotation="0"],
+ [data-main-rotation="270"] [data-editor-rotation="270"]
+ )
+ .altText {
rotate: 180deg;
inset-block-end: calc(100% - 8px);
@@ -1326,64 +1448,74 @@ input:hover {
}
.annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="180"],
- [data-main-rotation="90"] [data-editor-rotation="90"],
- [data-main-rotation="180"] [data-editor-rotation="0"],
- [data-main-rotation="270"] [data-editor-rotation="270"]
- ) .altText.small {
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="180"],
+ [data-main-rotation="90"] [data-editor-rotation="90"],
+ [data-main-rotation="180"] [data-editor-rotation="0"],
+ [data-main-rotation="270"] [data-editor-rotation="270"]
+ )
+ .altText.small {
inset-inline-start: 100%;
inset-block-start: -8px;
}
.annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="270"],
- [data-main-rotation="90"] [data-editor-rotation="180"],
- [data-main-rotation="180"] [data-editor-rotation="90"],
- [data-main-rotation="270"] [data-editor-rotation="0"]
- ) .altText {
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="270"],
+ [data-main-rotation="90"] [data-editor-rotation="180"],
+ [data-main-rotation="180"] [data-editor-rotation="90"],
+ [data-main-rotation="270"] [data-editor-rotation="0"]
+ )
+ .altText {
rotate: 90deg;
}
-[dir="ltr"] .annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="270"],
- [data-main-rotation="90"] [data-editor-rotation="180"],
- [data-main-rotation="180"] [data-editor-rotation="90"],
- [data-main-rotation="270"] [data-editor-rotation="0"]
- ) .altText {
+[dir="ltr"]
+ .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="270"],
+ [data-main-rotation="90"] [data-editor-rotation="180"],
+ [data-main-rotation="180"] [data-editor-rotation="90"],
+ [data-main-rotation="270"] [data-editor-rotation="0"]
+ )
+ .altText {
inset-block-end: calc(100% - 8px);
}
-[dir="ltr"] .annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="270"],
- [data-main-rotation="90"] [data-editor-rotation="180"],
- [data-main-rotation="180"] [data-editor-rotation="90"],
- [data-main-rotation="270"] [data-editor-rotation="0"]
- ) .altText.small {
+[dir="ltr"]
+ .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="270"],
+ [data-main-rotation="90"] [data-editor-rotation="180"],
+ [data-main-rotation="180"] [data-editor-rotation="90"],
+ [data-main-rotation="270"] [data-editor-rotation="0"]
+ )
+ .altText.small {
inset-inline-start: -8px;
inset-block-start: 0;
}
-[dir="rtl"] .annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="270"],
- [data-main-rotation="90"] [data-editor-rotation="180"],
- [data-main-rotation="180"] [data-editor-rotation="90"],
- [data-main-rotation="270"] [data-editor-rotation="0"]
- ) .altText {
+[dir="rtl"]
+ .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="270"],
+ [data-main-rotation="90"] [data-editor-rotation="180"],
+ [data-main-rotation="180"] [data-editor-rotation="90"],
+ [data-main-rotation="270"] [data-editor-rotation="0"]
+ )
+ .altText {
inset-inline-start: calc(100% - 8px);
}
-[dir="rtl"] .annotationEditorLayer
-:is(
- [data-main-rotation="0"] [data-editor-rotation="270"],
- [data-main-rotation="90"] [data-editor-rotation="180"],
- [data-main-rotation="180"] [data-editor-rotation="90"],
- [data-main-rotation="270"] [data-editor-rotation="0"]
- ) .altText.small {
+[dir="rtl"]
+ .annotationEditorLayer
+ :is(
+ [data-main-rotation="0"] [data-editor-rotation="270"],
+ [data-main-rotation="90"] [data-editor-rotation="180"],
+ [data-main-rotation="180"] [data-editor-rotation="90"],
+ [data-main-rotation="270"] [data-editor-rotation="0"]
+ )
+ .altText.small {
inset-inline-start: calc(100% + 8px);
inset-block-start: 100%;
}
@@ -1421,7 +1553,6 @@ input:hover {
}
.altText.small {
-
inset-block-end: unset;
inset-inline-start: 0;
inset-block-start: calc(100% + 8px);
@@ -1515,7 +1646,6 @@ input:hover {
}
@media (prefers-color-scheme: dark) {
-
.altText .tooltip.show {
--alt-text-tooltip-bg: #1c1b22;
--alt-text-tooltip-fg: #fbfbfe;
@@ -1524,7 +1654,6 @@ input:hover {
}
@media screen and (forced-colors: active) {
-
.altText .tooltip.show {
--alt-text-tooltip-bg: Canvas;
--alt-text-tooltip-fg: CanvasText;
@@ -1581,7 +1710,6 @@ input:hover {
}
@media (prefers-color-scheme: dark) {
-
#altTextDialog {
--dialog-bg-color: #1c1b22;
--dialog-border-color: #1c1b22;
@@ -1604,7 +1732,6 @@ input:hover {
}
@media screen and (forced-colors: active) {
-
#altTextDialog {
--dialog-bg-color: Canvas;
--dialog-border-color: CanvasText;
@@ -2022,8 +2149,8 @@ input:hover {
--toolbar-border-color: rgba(184, 184, 184, 1);
--toolbar-box-shadow: 0 1px 0 var(--toolbar-border-color);
--toolbar-border-bottom: none;
- --toolbarSidebar-box-shadow: inset calc(-1px * var(--dir-factor)) 0 0 rgba(0, 0, 0, 0.25),
- 0 1px 0 rgba(0, 0, 0, 0.15), 0 0 1px rgba(0, 0, 0, 0.1);
+ --toolbarSidebar-box-shadow: inset calc(-1px * var(--dir-factor)) 0 0 rgba(0, 0, 0, 0.25), 0 1px 0 rgba(0, 0, 0, 0.15),
+ 0 0 1px rgba(0, 0, 0, 0.1);
--toolbarSidebar-border-bottom: none;
--button-hover-color: rgba(221, 222, 223, 1);
--toggled-btn-color: rgba(0, 0, 0, 1);
@@ -2319,8 +2446,7 @@ body {
font: message-box;
}
-:is(.toolbar, .editorParamsToolbar, .findbar, #sidebarContainer)
-:is(input, button, select),
+:is(.toolbar, .editorParamsToolbar, .findbar, #sidebarContainer) :is(input, button, select),
.secondaryToolbar :is(input, button, a, select) {
outline: none;
font: message-box;
@@ -2417,19 +2543,18 @@ body {
height: 100%;
width: calc(100% + 150px);
background: repeating-linear-gradient(
- 135deg,
- var(--progressBar-blend-color) 0,
- var(--progressBar-bg-color) 5px,
- var(--progressBar-bg-color) 45px,
- var(--progressBar-color) 55px,
- var(--progressBar-color) 95px,
- var(--progressBar-blend-color) 100px
+ 135deg,
+ var(--progressBar-blend-color) 0,
+ var(--progressBar-bg-color) 5px,
+ var(--progressBar-bg-color) 45px,
+ var(--progressBar-color) 55px,
+ var(--progressBar-color) 95px,
+ var(--progressBar-blend-color) 100px
);
animation: progressIndeterminate 1s linear infinite;
}
-#outerContainer.sidebarResizing
-:is(#sidebarContainer, #viewerContainer, #loadingBar) {
+#outerContainer.sidebarResizing :is(#sidebarContainer, #viewerContainer, #loadingBar) {
/* Improve responsiveness and avoid visual glitches when the sidebar is resized. */
transition-duration: 0s;
}
@@ -2600,8 +2725,9 @@ body {
.doorHanger,
.doorHangerRight {
border-radius: 2px;
- box-shadow: 0 1px 5px var(--doorhanger-border-color),
- 0 0 0 1px var(--doorhanger-border-color);
+ box-shadow:
+ 0 1px 5px var(--doorhanger-border-color),
+ 0 0 0 1px var(--doorhanger-border-color);
border: var(--doorhanger-border-color-whcm);
}
@@ -3455,8 +3581,7 @@ dialog :link {
cursor: grab !important;
}
-.grab-to-pan-grab
-*:not(input):not(textarea):not(button):not(select):not(:link) {
+.grab-to-pan-grab *:not(input):not(textarea):not(button):not(select):not(:link) {
cursor: inherit !important;
}
diff --git a/src/main/resources/templates/about.html b/src/main/resources/templates/about.html
index 1ce5726f..17e79d57 100644
--- a/src/main/resources/templates/about.html
+++ b/src/main/resources/templates/about.html
@@ -1,22 +1,21 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/account.html b/src/main/resources/templates/account.html
index b39da2f1..9b7f4df9 100644
--- a/src/main/resources/templates/account.html
+++ b/src/main/resources/templates/account.html
@@ -1,326 +1,286 @@
-
-
+
+
+
+
+
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
User Settings
-
-
- Default message if not found
-
-
- Default message if not found
-
-
- Default message if not found
-
-
- Default message if not found
-
-
-
-
-
-
-
-
-
User !
-
-
- Error Message
-
-
-
-
-
-
-
-
-
Change Password?
-
-
-
-
-
-
-
-
-
-
-
-
Sync browser settings with Account
-
-
Settings Comparison:
-
-
-
- Property
- Account Setting
- Web Browser Setting
-
-
-
-
-
-
-
-
- Sync Account -> Browser
- Sync Account <- Browser
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
User Settings
+
+
+
+ Default message if not found
+
+
+ Default message if not found
+
+
+ Default message if not found
+
+
+ Default message if not found
+
+
+
+
User !
+
+
+ Error Message
+
+
+
+
+
+
+ Password
+
+
+
+ Change Username
+
+
+
+
+
+
Change Password?
+
+
+
+
+
+
+
+
+
+
+
Sync browser settings with Account
+
+
Settings Comparison:
+
+
+
+ Property
+ Account Setting
+ Web Browser Setting
+
+
+
+
+
+
+
+
+ Sync Account -> Browser
+ Sync Account <- Browser
+
+
+
+
+
+
+
-
+
+
-
+
diff --git a/src/main/resources/templates/addUsers.html b/src/main/resources/templates/addUsers.html
index ff3eb559..0cf3306d 100644
--- a/src/main/resources/templates/addUsers.html
+++ b/src/main/resources/templates/addUsers.html
@@ -1,84 +1,78 @@
-
+
+
+
+
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
Admin User Control Settings
+
+
Admin User Control Settings
+
+
+
+ Username
+ Roles
+ Actions
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
- Username
- Roles
- Actions
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Add New User
-
- Default message if not found
-
-
-
+
Add New User
+
+ Default message if not found
+
+
+
+
Save User
+
+
+
-
+
+
-
+
diff --git a/src/main/resources/templates/auto-split-pdf.html b/src/main/resources/templates/auto-split-pdf.html
index 304216b9..e4d213d8 100644
--- a/src/main/resources/templates/auto-split-pdf.html
+++ b/src/main/resources/templates/auto-split-pdf.html
@@ -1,44 +1,43 @@
-
+
+
+
+
-
-
-
-
+
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/main/resources/templates/change-creds.html b/src/main/resources/templates/change-creds.html
index f5b86b67..4709e40b 100644
--- a/src/main/resources/templates/change-creds.html
+++ b/src/main/resources/templates/change-creds.html
@@ -1,90 +1,83 @@
-
-
+
+
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
-
User Settings
-
-
-
- Default message if not found
-
-
- Default message if not found
-
-
- Default message if not found
-
-
- Default message if not found
-
-
-
-
User !
-
-
-
-
-
Change Username and password
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
User Settings
+
+
+
+ Default message if not found
+
+
+ Default message if not found
+
+
+ Default message if not found
+
+
+ Default message if not found
+
+
+
+
User !
+
+
+
Change Username and password
+
+
+ Old Password
+
+
+
+ New Password
+
+
+
+ Confirm New Password
+
+
+
+ Change credentials!
+
+
+
+
+
-
+
+
-
+
diff --git a/src/main/resources/templates/convert/book-to-pdf.html b/src/main/resources/templates/convert/book-to-pdf.html
index 67facbb3..94229ccf 100644
--- a/src/main/resources/templates/convert/book-to-pdf.html
+++ b/src/main/resources/templates/convert/book-to-pdf.html
@@ -1,29 +1,31 @@
-
+
+
+
+
-
-
+
-
-
-
-
-
+
diff --git a/src/main/resources/templates/convert/file-to-pdf.html b/src/main/resources/templates/convert/file-to-pdf.html
index 774c2dc8..3949688f 100644
--- a/src/main/resources/templates/convert/file-to-pdf.html
+++ b/src/main/resources/templates/convert/file-to-pdf.html
@@ -1,37 +1,34 @@
-
+
+
+
+
-
-
-
-
+
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/main/resources/templates/convert/html-to-pdf.html b/src/main/resources/templates/convert/html-to-pdf.html
index f0d17e6e..11184606 100644
--- a/src/main/resources/templates/convert/html-to-pdf.html
+++ b/src/main/resources/templates/convert/html-to-pdf.html
@@ -1,36 +1,35 @@
-
+
+
+
+
-
-
+
-
-
-
-
-
-
+
diff --git a/src/main/resources/templates/convert/img-to-pdf.html b/src/main/resources/templates/convert/img-to-pdf.html
index 60478409..4de9e0f6 100644
--- a/src/main/resources/templates/convert/img-to-pdf.html
+++ b/src/main/resources/templates/convert/img-to-pdf.html
@@ -1,88 +1,82 @@
-
+
+
+
+
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
+
diff --git a/src/main/resources/templates/convert/markdown-to-pdf.html b/src/main/resources/templates/convert/markdown-to-pdf.html
index 4606d2b5..d0266aac 100644
--- a/src/main/resources/templates/convert/markdown-to-pdf.html
+++ b/src/main/resources/templates/convert/markdown-to-pdf.html
@@ -1,30 +1,31 @@
-
+
+
+
+
-
-
+
-
-
-
-
-
+
diff --git a/src/main/resources/templates/convert/pdf-to-book.html b/src/main/resources/templates/convert/pdf-to-book.html
index a136c5cf..e8ef9402 100644
--- a/src/main/resources/templates/convert/pdf-to-book.html
+++ b/src/main/resources/templates/convert/pdf-to-book.html
@@ -1,55 +1,47 @@
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
diff --git a/src/main/resources/templates/convert/pdf-to-csv.html b/src/main/resources/templates/convert/pdf-to-csv.html
index 463e1a9c..d21156f0 100644
--- a/src/main/resources/templates/convert/pdf-to-csv.html
+++ b/src/main/resources/templates/convert/pdf-to-csv.html
@@ -1,159 +1,143 @@
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
-
+
diff --git a/src/main/resources/templates/convert/pdf-to-html.html b/src/main/resources/templates/convert/pdf-to-html.html
index 7360e631..b2347f02 100644
--- a/src/main/resources/templates/convert/pdf-to-html.html
+++ b/src/main/resources/templates/convert/pdf-to-html.html
@@ -1,29 +1,30 @@
-
+
+
+
+
-
-
+
-
-
-
-
-
+
diff --git a/src/main/resources/templates/convert/pdf-to-img.html b/src/main/resources/templates/convert/pdf-to-img.html
index 52bf2e66..61034578 100644
--- a/src/main/resources/templates/convert/pdf-to-img.html
+++ b/src/main/resources/templates/convert/pdf-to-img.html
@@ -1,61 +1,58 @@
-
+
+
+
+
-
-
-
-
+
-
-
-
-
-
-
-
+
diff --git a/src/main/resources/templates/convert/pdf-to-pdfa.html b/src/main/resources/templates/convert/pdf-to-pdfa.html
index 5b0d5cf1..1b75a078 100644
--- a/src/main/resources/templates/convert/pdf-to-pdfa.html
+++ b/src/main/resources/templates/convert/pdf-to-pdfa.html
@@ -1,32 +1,31 @@
-
+
+
+
+
-
-
-
-
+
-
-
-
-
-
-
-
-
Currently doesn't work for multiple inputs at once
-
-
-
-
+
+
+
+
+
+
+
+
Currently doesn't work for multiple inputs at once
+
+
-
+
-
+
+
-
+
\ No newline at end of file
diff --git a/src/main/resources/templates/convert/pdf-to-presentation.html b/src/main/resources/templates/convert/pdf-to-presentation.html
index a08c202b..f0a4a44a 100644
--- a/src/main/resources/templates/convert/pdf-to-presentation.html
+++ b/src/main/resources/templates/convert/pdf-to-presentation.html
@@ -1,38 +1,38 @@
-
+
+
+
+
-
-
+
-
-
-
-
-
-
+
diff --git a/src/main/resources/templates/convert/pdf-to-text.html b/src/main/resources/templates/convert/pdf-to-text.html
index 8ad6e94a..cc6b7dcb 100644
--- a/src/main/resources/templates/convert/pdf-to-text.html
+++ b/src/main/resources/templates/convert/pdf-to-text.html
@@ -1,35 +1,38 @@
-
+
+
+
+
-
-
+
-
-
-
-
+
+
+
diff --git a/src/main/resources/templates/convert/pdf-to-word.html b/src/main/resources/templates/convert/pdf-to-word.html
index 8ed0d9a8..74e6f314 100644
--- a/src/main/resources/templates/convert/pdf-to-word.html
+++ b/src/main/resources/templates/convert/pdf-to-word.html
@@ -1,40 +1,40 @@
-
+
+
+
+
-
-
+
-
-
-
-
-
-
+
diff --git a/src/main/resources/templates/convert/pdf-to-xml.html b/src/main/resources/templates/convert/pdf-to-xml.html
index b26a97fe..701220c1 100644
--- a/src/main/resources/templates/convert/pdf-to-xml.html
+++ b/src/main/resources/templates/convert/pdf-to-xml.html
@@ -1,29 +1,30 @@
-
+
+
+
+
-
-
+
-
-
-
-
-
+
diff --git a/src/main/resources/templates/convert/url-to-pdf.html b/src/main/resources/templates/convert/url-to-pdf.html
index c74bd5d5..68044385 100644
--- a/src/main/resources/templates/convert/url-to-pdf.html
+++ b/src/main/resources/templates/convert/url-to-pdf.html
@@ -1,29 +1,30 @@
-
+
+
+
+
-
-
+
-
-
-
-
-
+
diff --git a/src/main/resources/templates/crop.html b/src/main/resources/templates/crop.html
index f0d2186f..825cfbec 100644
--- a/src/main/resources/templates/crop.html
+++ b/src/main/resources/templates/crop.html
@@ -1,147 +1,135 @@
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
diff --git a/src/main/resources/templates/error.html b/src/main/resources/templates/error.html
index 90e654f7..d3cbecb6 100644
--- a/src/main/resources/templates/error.html
+++ b/src/main/resources/templates/error.html
@@ -1,131 +1,39 @@
-
-
+
-
Error! :(
-
-
+
-
-
-
-
-
-
-
-
-
Oops!
-
We can't seem to find the page you're looking for.
-
Something went wrong
-
-
-
Need help / Found a issue?
-
If you're still having trouble, don't hesitate to reach out to us for help. You can submit a ticket on our GitHub page or contact us through Discord:
-
-
-
-
diff --git a/src/main/resources/templates/extract-page.html b/src/main/resources/templates/extract-page.html
index 77cc7496..a14e13d2 100644
--- a/src/main/resources/templates/extract-page.html
+++ b/src/main/resources/templates/extract-page.html
@@ -1,33 +1,33 @@
-
+
+
+
+
-
-
-
-
+
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/main/resources/templates/fragments/card.html b/src/main/resources/templates/fragments/card.html
index 1d8193cd..6fa05163 100644
--- a/src/main/resources/templates/fragments/card.html
+++ b/src/main/resources/templates/fragments/card.html
@@ -1,12 +1,12 @@
-
+
diff --git a/src/main/resources/templates/fragments/common.html b/src/main/resources/templates/fragments/common.html
index 633810ef..78f229c6 100644
--- a/src/main/resources/templates/fragments/common.html
+++ b/src/main/resources/templates/fragments/common.html
@@ -1,137 +1,144 @@
-
+
+
+
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
+
+
+
-
-
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
-
-
-
Lives: 3
-
Score: 0
-
High Score: 0
-
Level: 1
-
-
-
+
+
+
Lives: 3
+
Score: 0
+
High Score: 0
+
Level: 1
+
+
+
-
-
-
+
+
+
-
+
-
- Bored waiting?
-
-
-
-
-
+
+ Bored waiting?
+
\ No newline at end of file
diff --git a/src/main/resources/templates/fragments/errorBanner.html b/src/main/resources/templates/fragments/errorBanner.html
index 1bc79031..d9865b63 100644
--- a/src/main/resources/templates/fragments/errorBanner.html
+++ b/src/main/resources/templates/fragments/errorBanner.html
@@ -1,23 +1,5 @@
-
@@ -52,10 +34,10 @@
function copytrace() {
var flip = false
- if(!traceVisible) {
- toggletrace()
- flip = true
- }
+ if(!traceVisible) {
+ toggletrace()
+ flip = true
+ }
var traceContent = document.getElementById("traceContent");
var range = document.createRange();
range.selectNode(traceContent);
@@ -64,7 +46,7 @@
document.execCommand("copy");
window.getSelection().removeAllRanges();
if(flip){
- toggletrace()
+ toggletrace()
}
}
diff --git a/src/main/resources/templates/fragments/errorBannerPerPage.html b/src/main/resources/templates/fragments/errorBannerPerPage.html
index 48bf365c..e5a4f007 100644
--- a/src/main/resources/templates/fragments/errorBannerPerPage.html
+++ b/src/main/resources/templates/fragments/errorBannerPerPage.html
@@ -1,58 +1,49 @@
+
+
Error
+
+
Show Stack Trace
+
Copy Stack Trace
+
Help
+
+ ×
+
+
+
+
-
-
-
Error
-
-
Show Stack Trace
-
Copy Stack Trace
-
Help
-
- ×
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Oops!
-
Sorry for the issue!.
-
-
Need help / Found an issue?
-
If you're still having trouble, don't hesitate to reach out to us for help. You can submit a ticket on our GitHub page or contact us through Discord:
-
-
Go to Homepage
-
Close
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
Oops!
+
Sorry for the issue!.
+
+
Need help / Found an issue?
+
If you're still having trouble, don't hesitate to reach out to us for help. You can submit a ticket on our GitHub page or contact us through Discord:
+
+
Go to Homepage
+
Close
+
+
+
+
+
+
+
diff --git a/src/main/resources/templates/fragments/footer.html b/src/main/resources/templates/fragments/footer.html
index 219786ce..e382553b 100644
--- a/src/main/resources/templates/fragments/footer.html
+++ b/src/main/resources/templates/fragments/footer.html
@@ -1,58 +1,19 @@
-
-
-
-
+
Licenses
+
diff --git a/src/main/resources/templates/fragments/languages.html b/src/main/resources/templates/fragments/languages.html
index 3ca0092f..f44caef3 100644
--- a/src/main/resources/templates/fragments/languages.html
+++ b/src/main/resources/templates/fragments/languages.html
@@ -1,107 +1,28 @@
- Български
-
- العربية
-
- Català
-
- 简体中文
-
- 正體中文
-
- Deutsch
-
- English (GB)
-
- English (US)
-
- Euskara
-
- Español
-
- Français
-
- Indonesia
-
- Italiano
-
- Nederlands
-
- Polski
-
- Português (BR)
-
- Romanian
-
- Svenska
-
- Türkçe
-
- Русский
-
- 한국어
-
- 日本語
-
- Ελληνικά
-
- Hungarian
-
- हिन्दी
-
- Srpski
-
-
+ Български
+ العربية
+ Català
+ 简体中文
+ 正體中文
+ Deutsch
+ English (GB)
+ English (US)
+ Euskara
+ Español
+ Français
+ Indonesia
+ Italiano
+ Nederlands
+ Polski
+ Português (BR)
+ Romanian
+ Svenska
+ Türkçe
+ Русский
+ 한국어
+ 日本語
+ Ελληνικά
+ Hungarian
+ हिन्दी
+ Srpski
diff --git a/src/main/resources/templates/fragments/navbar.html b/src/main/resources/templates/fragments/navbar.html
index d75745da..c8ad96b6 100644
--- a/src/main/resources/templates/fragments/navbar.html
+++ b/src/main/resources/templates/fragments/navbar.html
@@ -1,315 +1,237 @@
-
-
-
-
-
-
-
-
-
+
diff --git a/src/main/resources/templates/licenses.html b/src/main/resources/templates/licenses.html
index fc28ad1a..8b8858c2 100644
--- a/src/main/resources/templates/licenses.html
+++ b/src/main/resources/templates/licenses.html
@@ -1,56 +1,42 @@
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
3rd Party licenses
+
+
+
+ Module
+ Version
+ License
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
3rd Party licenses
-
-
-
- Module
- Version
- License
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html
index 3d549ac7..049c1740 100644
--- a/src/main/resources/templates/login.html
+++ b/src/main/resources/templates/login.html
@@ -1,313 +1,175 @@
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+ const dropdown = document.getElementById('languageDropdown');
+ const dropdownItems = document.querySelectorAll('.lang_dropdown-item');
-
- Default message if not found
-
-
-
-
-
- English (GB)
-
-
-
-
+ // Additional functionality that was in your provided code:
+ document.querySelectorAll('.nav-item.dropdown').forEach((element) => {
+ const dropdownMenu = element.querySelector(".dropdown-menu");
+ if (dropdownMenu.id !== 'favoritesDropdown' && dropdownMenu.children.length <= 2 && dropdownMenu.querySelectorAll("hr.dropdown-divider").length === dropdownMenu.children.length) {
+ if (element.previousElementSibling && element.previousElementSibling.classList.contains('nav-item') && element.previousElementSibling.classList.contains('nav-item-separator')) {
+ element.previousElementSibling.remove();
+ }
+ element.remove();
+ }
+ });
+ // Sort languages by alphabet
+ const list = Array.from(document.querySelector('.dropdown-menu[aria-labelledby="languageDropdown"]').children).filter(child => child.matches('a'));
+ list.sort(function(a, b) {
+ var A = a.textContent.toUpperCase();
+ var B = b.textContent.toUpperCase();
+ return (A < B) ? -1 : (A > B) ? 1 : 0;
+ }).forEach(node => document.querySelector('.dropdown-menu[aria-labelledby="languageDropdown"]').appendChild(node));
+ });
-
-
Invalid username or
- password.
-
Your account has been locked.
-
-
+ function handleDropdownItemClick(event) {
+ event.preventDefault();
+ const languageCode = event.currentTarget.dataset.bsLanguageCode;
+ const dropdown = document.getElementById('languageDropdown');
-
+ if (languageCode) {
+ localStorage.setItem('languageCode', languageCode);
+ const currentLang = document.documentElement.getAttribute('lang');
+ if (currentLang !== languageCode) {
+ console.log("currentLang", currentLang)
+ console.log("languageCode", languageCode)
+ const currentUrl = window.location.href;
+ if (currentUrl.indexOf('?lang=') === -1) {
+ window.location.href = currentUrl + '?lang=' + languageCode;
+ } else {
+ window.location.href = currentUrl.replace(/\?lang=\w{2,}/, '?lang=' + languageCode);
+ }
+ }
+ dropdown.innerHTML = event.currentTarget.innerHTML; // Update the dropdown button's content
+ } else {
+ console.error("Language code is not set for this item.");
+ }
+ }
+
+
+
+ Default message if not found
+
+
-
-
-
+
+
+
+
+
+ Sign in
+
+
+
+
+ English (GB)
+
+
+
+
+
+
Invalid username or password.
+
Your account has been locked.
+
+
+
+
+
diff --git a/src/main/resources/templates/merge-pdfs.html b/src/main/resources/templates/merge-pdfs.html
index d97d88d9..3638391e 100644
--- a/src/main/resources/templates/merge-pdfs.html
+++ b/src/main/resources/templates/merge-pdfs.html
@@ -1,40 +1,39 @@
-
+
+
+
+
+
-
-
-
-
+
-
-
-
-
-
-
+
diff --git a/src/main/resources/templates/misc/add-image.html b/src/main/resources/templates/misc/add-image.html
index ae531a8f..1a0f96ee 100644
--- a/src/main/resources/templates/misc/add-image.html
+++ b/src/main/resources/templates/misc/add-image.html
@@ -1,141 +1,112 @@
-
-
-
+
+
+
+
-
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+ document.querySelectorAll(".show-on-file-selected").forEach(el => {
+ el.style.cssText = '';
+ });
+ }
+ });
+ document.addEventListener("DOMContentLoaded", () => {
+ document.querySelectorAll(".show-on-file-selected").forEach(el => {
+ el.style.cssText = "display:none !important";
+ })
+ });
+
-
-
-
-
-
-
-
- Download PDF
-
-
-
+
+
+
+
+
+
+
+ Download PDF
+
+
+
+
-
+
+
-
+
diff --git a/src/main/resources/templates/misc/add-page-numbers.html b/src/main/resources/templates/misc/add-page-numbers.html
index e484a72d..bd7104c2 100644
--- a/src/main/resources/templates/misc/add-page-numbers.html
+++ b/src/main/resources/templates/misc/add-page-numbers.html
@@ -1,154 +1,137 @@
-
+
+
+
+
+
-#myForm {
- display: flex;
- justify-content: center;
- align-items: center;
- margin-top: 20px;
-}
+
+
+
-
+ cell.addEventListener('mouseleave', function(e) {
+ if(e.target.classList.contains('selectedPosition')) {
+ e.target.classList.remove('selectedHovered');
+ }
+ });
+ });
+
+
+
+
+
diff --git a/src/main/resources/templates/misc/adjust-contrast.html b/src/main/resources/templates/misc/adjust-contrast.html
index 23effdd0..2b28a734 100644
--- a/src/main/resources/templates/misc/adjust-contrast.html
+++ b/src/main/resources/templates/misc/adjust-contrast.html
@@ -1,20 +1,17 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -46,265 +43,265 @@
-
-
+
-
-
-
-
-
-
+ document.getElementById('download-button').addEventListener('click', function() {
+ downloadPDF();
+ });
+
+
+
+
+
+
+
diff --git a/src/main/resources/templates/misc/auto-crop.html b/src/main/resources/templates/misc/auto-crop.html
index da6e6c22..d3f79ade 100644
--- a/src/main/resources/templates/misc/auto-crop.html
+++ b/src/main/resources/templates/misc/auto-crop.html
@@ -1,31 +1,30 @@
-
+
+
+
+
-
-
-
-
+
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/main/resources/templates/misc/auto-rename.html b/src/main/resources/templates/misc/auto-rename.html
index 0295acac..62712dce 100644
--- a/src/main/resources/templates/misc/auto-rename.html
+++ b/src/main/resources/templates/misc/auto-rename.html
@@ -1,30 +1,29 @@
-
+
+
+
+
-
-
-
-
+
-
-
-
-
-
+
diff --git a/src/main/resources/templates/misc/change-metadata.html b/src/main/resources/templates/misc/change-metadata.html
index 6affa6bf..e2c8de1c 100644
--- a/src/main/resources/templates/misc/change-metadata.html
+++ b/src/main/resources/templates/misc/change-metadata.html
@@ -1,261 +1,227 @@
-
+
+
+
+
-
-
-
+
-
-
-
-
-
-
+
diff --git a/src/main/resources/templates/misc/compare.html b/src/main/resources/templates/misc/compare.html
index ffe08a31..c9194005 100644
--- a/src/main/resources/templates/misc/compare.html
+++ b/src/main/resources/templates/misc/compare.html
@@ -1,190 +1,187 @@
-
+
+
+
+
+
-
-
-
-
-
+
-
-
-
-
-
+
+
diff --git a/src/main/resources/templates/misc/compress-pdf.html b/src/main/resources/templates/misc/compress-pdf.html
index c991a6c8..ef495577 100644
--- a/src/main/resources/templates/misc/compress-pdf.html
+++ b/src/main/resources/templates/misc/compress-pdf.html
@@ -1,50 +1,48 @@
-
+
+
+
+
-
-
-
-
+
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/main/resources/templates/misc/extract-image-scans.html b/src/main/resources/templates/misc/extract-image-scans.html
index 82f7313c..016cc973 100644
--- a/src/main/resources/templates/misc/extract-image-scans.html
+++ b/src/main/resources/templates/misc/extract-image-scans.html
@@ -1,54 +1,53 @@
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/src/main/resources/templates/misc/extract-images.html b/src/main/resources/templates/misc/extract-images.html
index e813e680..caf4b549 100644
--- a/src/main/resources/templates/misc/extract-images.html
+++ b/src/main/resources/templates/misc/extract-images.html
@@ -1,36 +1,35 @@
-
+
+
+
+
-
-
-
-
-