Update public source

This commit is contained in:
2026-10-07 11:36:30 +03:00
parent ada4eb3923
commit b77276b65d
+420 -26
View File
@@ -1222,6 +1222,8 @@
step,
mask.value,
);
updateMaskBulkVisibility();
},
);
@@ -1340,24 +1342,291 @@
refresh();
}
function getMethodSteps() {
return Array.from(
stepsContainer.querySelectorAll(
"[data-method-step]",
),
);
}
function getBulkMaskSteps() {
return getMethodSteps().filter(
(step) =>
step.dataset.bulkMaskStep ===
"true",
);
}
function getStepMask(step) {
const maskInput =
step.querySelector(
'input[name$="_mask"]',
);
return maskInput
? maskInput.value.trim()
: "";
}
function getStepWorkloadProfile(step) {
const workload =
step.querySelector(
"[data-workload-profile]",
);
return workload
? workload.value
: "2";
}
function setStepWorkloadProfile(
step,
value,
) {
const workload =
step.querySelector(
"[data-workload-profile]",
);
if (workload) {
workload.value =
String(value || "2");
}
}
function refreshBulkMaskGroup() {
const group =
document.querySelector(
"[data-mask-bulk-group]",
);
const bulkSteps =
getBulkMaskSteps();
if (!group || bulkSteps.length === 0) {
if (group) {
group.remove();
}
return;
}
const firstStep =
bulkSteps[0];
const title =
group.querySelector(
"[data-mask-bulk-group-title]",
);
const count =
group.querySelector(
"[data-mask-bulk-group-count]",
);
const list =
group.querySelector(
"[data-mask-bulk-group-list]",
);
const toggle =
group.querySelector(
"[data-mask-bulk-group-toggle]",
);
const firstStepTitle =
firstStep.querySelector(
".method-step-title",
);
const stepNumber =
firstStepTitle
? firstStepTitle.textContent
.replace(
/^Step\s+/i,
"",
)
.trim()
: "1";
title.textContent =
`Step ${stepNumber} — Mask`;
count.textContent =
`Маски: ${bulkSteps.length}`;
list.innerHTML = "";
bulkSteps.forEach(
(step) => {
const item =
document.createElement("li");
item.textContent =
getStepMask(step);
list.appendChild(item);
},
);
toggle.textContent =
group.classList.contains(
"is-expanded",
)
? "Скрыть список"
: "Показать список";
}
function createBulkMaskGroup(
bulkSteps,
) {
const existing =
document.querySelector(
"[data-mask-bulk-group]",
);
if (existing) {
existing.remove();
}
if (bulkSteps.length === 0) {
return;
}
const group =
document.createElement("div");
group.className =
"method-step-bulk-group";
group.dataset.maskBulkGroup =
"true";
group.innerHTML = `
<div
class="method-step-bulk-group-title"
data-mask-bulk-group-title
></div>
<div
class="method-step-bulk-group-mode"
>
Mode 3
</div>
<div
class="method-step-bulk-group-summary"
>
<strong
data-mask-bulk-group-count
></strong>
<button
type="button"
class="methods-button-secondary"
data-mask-bulk-group-toggle
>
Показать список
</button>
</div>
<div
class="method-step-bulk-group-list"
data-mask-bulk-group-list
>
<ol></ol>
</div>
`;
group.querySelector(
"[data-mask-bulk-group-toggle]",
).addEventListener(
"click",
() => {
group.classList.toggle(
"is-expanded",
);
refreshBulkMaskGroup();
},
);
stepsContainer.insertBefore(
group,
bulkSteps[0],
);
bulkSteps.forEach(
(step) => {
step.dataset.bulkMaskStep =
"true";
step.classList.add(
"method-step-bulk-hidden",
);
},
);
refreshBulkMaskGroup();
}
function updateMaskBulkVisibility() {
const bulk =
document.getElementById("mask-bulk");
const hasMaskMode =
Array.from(
stepsContainer.querySelectorAll(
"[data-attack-mode]",
),
).some(
(modeSelect) =>
modeSelect.value === "3",
const bulkSteps =
getBulkMaskSteps();
if (bulkSteps.length > 0) {
addMaskBulkButton.disabled =
false;
return;
}
const mode3Steps =
getMethodSteps().filter(
(step) => {
const modeSelect =
step.querySelector(
"[data-attack-mode]",
);
return (
modeSelect &&
modeSelect.value === "3"
);
},
);
addMaskBulkButton.disabled =
!hasMaskMode;
const manualMode3Steps =
mode3Steps.filter(
(step) =>
getStepMask(step) !== "",
);
if (!hasMaskMode) {
if (manualMode3Steps.length > 0) {
addMaskBulkButton.disabled =
true;
bulk.classList.remove(
"is-visible",
);
return;
}
addMaskBulkButton.disabled =
mode3Steps.length === 0;
if (mode3Steps.length === 0) {
bulk.classList.remove(
"is-visible",
);
@@ -1368,13 +1637,65 @@
function addBulkMasks(
masks,
) {
const methodSteps =
getMethodSteps();
const sourceStep =
methodSteps.find(
(step) => {
const modeSelect =
step.querySelector(
"[data-attack-mode]",
);
return (
modeSelect &&
modeSelect.value === "3"
);
},
);
if (!sourceStep) {
return;
}
const workloadProfile =
getStepWorkloadProfile(
sourceStep,
);
const oldBulkSteps =
getBulkMaskSteps();
oldBulkSteps.forEach(
(step) => {
step.remove();
},
);
const firstStep =
sourceStep;
const bulkSteps = [
firstStep,
];
while (
bulkSteps.length <
masks.length
) {
bulkSteps.push(
addStep(),
);
}
masks.forEach(
(mask) => {
const newStep =
addStep();
(mask, index) => {
const step =
bulkSteps[index];
const modeSelect =
newStep.querySelector(
step.querySelector(
"[data-attack-mode]",
);
@@ -1384,25 +1705,45 @@
new Event("change"),
);
const newMask =
newStep.querySelector(
setStepWorkloadProfile(
step,
workloadProfile,
);
const maskInput =
step.querySelector(
'input[name$="_mask"]',
);
newMask.value =
maskInput.value =
mask;
newMask.dispatchEvent(
maskInput.dispatchEvent(
new Event(
"input",
{ bubbles: true },
),
);
step.dataset.bulkMaskStep =
"true";
step.classList.add(
"method-step-bulk-hidden",
);
},
);
stepCountInput.value =
stepCount;
rebuildStepNumbers();
createBulkMaskGroup(
bulkSteps,
);
updateMaskBulkVisibility();
}
@@ -1420,6 +1761,9 @@
step.className =
"method-step";
step.dataset.methodStep =
"true";
step.dataset.step =
currentStepNumber;
@@ -1618,7 +1962,7 @@
() => {
if (
stepsContainer.children.length <= 1
getMethodSteps().length <= 1
) {
return;
}
@@ -1626,6 +1970,7 @@
step.remove();
rebuildStepNumbers();
updateMaskBulkVisibility();
},
);
@@ -1666,9 +2011,7 @@
function rebuildStepNumbers() {
const stepElements =
Array.from(
stepsContainer.children,
);
getMethodSteps();
stepCount =
stepElements.length;
@@ -1728,6 +2071,8 @@
},
);
refreshBulkMaskGroup();
stepCountInput.value =
stepCount;
}
@@ -1805,18 +2150,42 @@
if (addMaskBulkButton.disabled) {
return;
}
const bulk =
document.getElementById(
"mask-bulk",
);
const textarea =
bulk.querySelector(
"[data-mask-bulk]",
);
const bulkSteps =
getBulkMaskSteps();
if (bulkSteps.length > 0) {
textarea.value =
bulkSteps
.map(
(step) =>
getStepMask(step),
)
.join("\n");
textarea.dispatchEvent(
new Event(
"input",
{ bubbles: true },
),
);
}
bulk.classList.add(
"is-visible",
);
bulk.querySelector(
"[data-mask-bulk]",
).focus();
textarea.focus();
},
);
@@ -1838,6 +2207,31 @@
} else {
addStep();
}
const initialMode3Steps =
getMethodSteps().filter(
(step) => {
const modeSelect =
step.querySelector(
"[data-attack-mode]",
);
return (
modeSelect &&
modeSelect.value === "3" &&
getStepMask(step) !== ""
);
},
);
if (initialMode3Steps.length > 1) {
createBulkMaskGroup(
initialMode3Steps,
);
}
updateMaskBulkVisibility();
</script>
{% endblock %}