PageSourceSearch

https://xn--e1aaha1awdex0e.xn--p1ai/wp-content/themes/qwalls/assets/js/calculator.js?ver=1.0

js xn--e1aaha1awdex0e.xn--p1ai collected 2026-10-07 15:18:53 UTC 11,922 bytes, 249 lines download raw bytes

1(function () {
2    "use strict";
3
4    var PRICES_RUBLES = {
5        wallsAreaTotalPricePerSquareMeter: 3500,
6        wallPerimeterPricePerLinearMeter: 550,
7        innerCornerPricePerLinearMeter: 800,
8        outerCornerPricePerLinearMeter: 1200,
9        doorOpeningBypassPricePerUnit: 6000,
10        windowOpeningBypassPricePerUnit: 6000,
11        socketOrSwitchEmbeddedPricePerUnit: 850
12    };
13
14    function getCalculatorRootElement() {
15        return document.querySelector('[data-calc="silent-walls"]');
16    }
17
18    function querySelectorSafe(rootElement, selector) {
19        if (!rootElement) return null;
20        return rootElement.querySelector(selector);
21    }
22
23    function querySelectorAllSafe(rootElement, selector) {
24        if (!rootElement) return [];
25        return Array.prototype.slice.call(rootElement.querySelectorAll(selector));
26    }
27
28    function normalizeNumericString(rawValue) {
29        if (rawValue === null || rawValue === undefined) return "";
30        var normalizedString = String(rawValue).trim();
31        normalizedString = normalizedString.replace(/\u00A0/g, " ").replace(/\s+/g, "");
32        normalizedString = normalizedString.replace(/[^\d.,]/g, "");
33        if (!normalizedString) return "";
34
35        var hasDot = normalizedString.indexOf(".") !== -1;
36        var hasComma = normalizedString.indexOf(",") !== -1;
37
38        if (hasDot && hasComma) {
39            normalizedString = normalizedString.replace(/,/g, "");
40        } else {
41            normalizedString = normalizedString.replace(",", ".");
42        }
43
44        return normalizedString;
45    }
46
47    function parseNumberFromInputValue(rawValue) {
48        var normalizedString = normalizeNumericString(rawValue);
49        if (!normalizedString) return 0;
50        var parsedValue = parseFloat(normalizedString);
51        if (!Number.isFinite(parsedValue)) return 0;
52        return parsedValue;
53    }
54
55    function parsePositiveIntegerFromInputValue(rawValue) {
56        var parsedInteger = Math.floor(parseNumberFromInputValue(rawValue));
57        if (!Number.isFinite(parsedInteger)) return 0;
58        if (parsedInteger < 0) return 0;
59        return parsedInteger;
60    }
61
62    function roundToTwoDecimals(value) {
63        return Math.round(value * 100) / 100;
64    }
65
66    function formatDecimalWithComma(value) {
67        return String(roundToTwoDecimals(value)).replace(".", ",");
68    }
69
70    function formatValueWithUnit(value, unit, shouldBeInteger) {
71        if (shouldBeInteger) return String(Math.floor(value)) + " " + unit;
72        return formatDecimalWithComma(value) + " " + unit;
73    }
74
75    function formatRubles(value) {
76        var integerValue = Math.round(value);
77        return integerValue.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ") + " ₽";
78    }
79
80    function collectCalculatorInputs(calculatorRootElement) {
81        var inputElementsByFieldName = {};
82        querySelectorAllSafe(calculatorRootElement, "[data-calc-field]").forEach(function (element) {
83            var fieldName = element.getAttribute("data-calc-field");
84            if (!fieldName) return;
85            inputElementsByFieldName[fieldName] = element;
86        });
87
88        var wallsAreaSquareMeters = parseNumberFromInputValue(
89            inputElementsByFieldName.wallsAreaSquareMeters ? inputElementsByFieldName.wallsAreaSquareMeters.value : 0
90        );
91
92        var wallPerimeterLinearMeters = parseNumberFromInputValue(
93            inputElementsByFieldName.wallPerimeterLinearMeters ? inputElementsByFieldName.wallPerimeterLinearMeters.value : 0
94        );
95
96        var innerCornerLinearMeters = parseNumberFromInputValue(
97            inputElementsByFieldName.innerCornerLinearMeters ? inputElementsByFieldName.innerCornerLinearMeters.value : 0
98        );
99
100        var outerCornerLinearMeters = parseNumberFromInputValue(
101            inputElementsByFieldName.outerCornerLinearMeters ? inputElementsByFieldName.outerCornerLinearMeters.value : 0
102        );
103
104        var doorOpeningsCount = parsePositiveIntegerFromInputValue(
105            inputElementsByFieldName.doorOpeningsCount ? inputElementsByFieldName.doorOpeningsCount.value : 0
106        );
107
108        var windowOpeningsCount = parsePositiveIntegerFromInputValue(
109            inputElementsByFieldName.windowOpeningsCount ? inputElementsByFieldName.windowOpeningsCount.value : 0
110        );
111
112        var socketAndSwitchEmbedsCount = parsePositiveIntegerFromInputValue(
113            inputElementsByFieldName.socketAndSwitchEmbedsCount ? inputElementsByFieldName.socketAndSwitchEmbedsCount.value : 0
114        );
115
116        return {
117            wallsAreaSquareMeters: wallsAreaSquareMeters,
118            wallPerimeterLinearMeters: wallPerimeterLinearMeters,
119            innerCornerLinearMeters: innerCornerLinearMeters,
120            outerCornerLinearMeters: outerCornerLinearMeters,
121            doorOpeningsCount: doorOpeningsCount,
122            windowOpeningsCount: windowOpeningsCount,
123            socketAndSwitchEmbedsCount: socketAndSwitchEmbedsCount
124        };
125    }
126
127    function calculateTotalPriceRubles(calculatorInputs) {
128        return (
129            calculatorInputs.wallsAreaSquareMeters * PRICES_RUBLES.wallsAreaTotalPricePerSquareMeter +
130            calculatorInputs.wallPerimeterLinearMeters * PRICES_RUBLES.wallPerimeterPricePerLinearMeter +
131            calculatorInputs.innerCornerLinearMeters * PRICES_RUBLES.innerCornerPricePerLinearMeter +
132            calculatorInputs.outerCornerLinearMeters * PRICES_RUBLES.outerCornerPricePerLinearMeter +
133            calculatorInputs.doorOpeningsCount * PRICES_RUBLES.doorOpeningBypassPricePerUnit +
134            calculatorInputs.windowOpeningsCount * PRICES_RUBLES.windowOpeningBypassPricePerUnit +
135            calculatorInputs.socketAndSwitchEmbedsCount * PRICES_RUBLES.socketOrSwitchEmbeddedPricePerUnit
136        );
137    }
138
139    function buildEnteredParametersRows(calculatorInputs) {
140        var rows = [];
141
142        if (calculatorInputs.wallsAreaSquareMeters > 0) rows.push("Площадь комнаты: " + formatValueWithUnit(calculatorInputs.wallsAreaSquareMeters, "м²", false));
143        if (calculatorInputs.wallPerimeterLinearMeters > 0) rows.push("Периметр стен: " + formatValueWithUnit(calculatorInputs.wallPerimeterLinearMeters, "пог.м", false));
144        if (calculatorInputs.innerCornerLinearMeters > 0) rows.push("Внутренние углы: " + formatValueWithUnit(calculatorInputs.innerCornerLinearMeters, "пог.м", false));
145        if (calculatorInputs.outerCornerLinearMeters > 0) rows.push("Внешние углы: " + formatValueWithUnit(calculatorInputs.outerCornerLinearMeters, "пог.м", false));
146        if (calculatorInputs.doorOpeningsCount > 0) rows.push("Дверные проёмы 90×200: " + formatValueWithUnit(calculatorInputs.doorOpeningsCount, "шт.", true));
147        if (calculatorInputs.windowOpeningsCount > 0) rows.push("Оконные проёмы 140×140: " + formatValueWithUnit(calculatorInputs.windowOpeningsCount, "шт.", true));
148        if (calculatorInputs.socketAndSwitchEmbedsCount > 0) rows.push("Закладные под розетки/выключатели: " + formatValueWithUnit(calculatorInputs.socketAndSwitchEmbedsCount, "шт.", true));
149
150        return rows;
151    }
152
153    function renderCalculatorResult(calculatorRootElement, calculatorInputs, totalPriceRubles) {
154        var parametersInfoElement = querySelectorSafe(calculatorRootElement, '[data-calc="info"]') || querySelectorSafe(calculatorRootElement, ".calc__info");
155        var totalElement = querySelectorSafe(calculatorRootElement, '[data-calc="total"]') || querySelectorSafe(calculatorRootElement, ".calc__total");
156
157        var enteredParameterRows = buildEnteredParametersRows(calculatorInputs);
158
159        if (parametersInfoElement) {
160            if (enteredParameterRows.length === 0) {
161                parametersInfoElement.textContent = "*Вы еще не ввели параметры";
162            } else {
163                parametersInfoElement.innerHTML = enteredParameterRows.map(function (rowText) {
164                    return "<div>" + rowText + "</div>";
165                }).join("");
166            }
167        }
168
169        if (totalElement) {
170            totalElement.textContent = "ИТОГО: " + formatRubles(totalPriceRubles);
171        }
172    }
173
174    function setLeadPayload(totalPriceRubles, calculatorInputs) {
175        var enteredParameterRows = buildEnteredParametersRows(calculatorInputs);
176
177        var payload = {
178            totalPriceRubles: Math.round(totalPriceRubles),
179            wallsAreaSquareMeters: calculatorInputs.wallsAreaSquareMeters,
180            wallPerimeterLinearMeters: calculatorInputs.wallPerimeterLinearMeters,
181            innerCornerLinearMeters: calculatorInputs.innerCornerLinearMeters,
182            outerCornerLinearMeters: calculatorInputs.outerCornerLinearMeters,
183            doorOpeningsCount: calculatorInputs.doorOpeningsCount,
184            windowOpeningsCount: calculatorInputs.windowOpeningsCount,
185            socketAndSwitchEmbedsCount: calculatorInputs.socketAndSwitchEmbedsCount,
186            parametersText: enteredParameterRows.join("; ")
187        };
188
189        try {
190            sessionStorage.setItem("qwalls_silent_walls_calculator_payload", JSON.stringify(payload));
191        } catch (e) {}
192
193        window.qwallsSilentWallsCalculatorPayload = payload;
194
195        var hiddenTotalField = document.querySelector('input[name="calc_total"]');
196        if (hiddenTotalField) hiddenTotalField.value = String(payload.totalPriceRubles);
197
198        var hiddenParametersField = document.querySelector('input[name="calc_params"]');
199        if (hiddenParametersField) hiddenParametersField.value = payload.parametersText;
200
201        var hiddenPayloadField = document.querySelector('input[name="calc_payload"]');
202        if (hiddenPayloadField) hiddenPayloadField.value = JSON.stringify(payload);
203    }
204
205    function isHiddenByCSS(element) {
206        if (!element) return true;
207        return element.offsetParent === null;
208    }
209
210    function initCalculator() {
211        var calculatorRootElement = getCalculatorRootElement();
212        if (!calculatorRootElement) return;
213
214        function updateCalculator() {
215            if (isHiddenByCSS(calculatorRootElement)) return;
216            var calculatorInputs = collectCalculatorInputs(calculatorRootElement);
217            var totalPriceRubles = calculateTotalPriceRubles(calculatorInputs);
218            renderCalculatorResult(calculatorRootElement, calculatorInputs, totalPriceRubles);
219            setLeadPayload(totalPriceRubles, calculatorInputs);
220        }
221
222        querySelectorAllSafe(calculatorRootElement, "[data-calc-field]").forEach(function (inputElement) {
223            inputElement.addEventListener("input", updateCalculator);
224            inputElement.addEventListener("change", updateCalculator);
225        });
226
227        var submitButtonElement = querySelectorSafe(calculatorRootElement, '[data-calc="submit"]');
228        if (submitButtonElement) {
229            submitButtonElement.addEventListener("click", function () {
230                var calculatorInputs = collectCalculatorInputs(calculatorRootElement);
231                var totalPriceRubles = calculateTotalPriceRubles(calculatorInputs);
232                setLeadPayload(totalPriceRubles, calculatorInputs);
233            });
234        }
235
236        updateCalculator();
237
238        document.addEventListener("qwalls:calc:shown", function (e) {
239            if (!e || !e.detail) return;
240            if (e.detail === "silent-walls") updateCalculator();
241        });
242    }
243
244    if (document.readyState === "loading") {
245        document.addEventListener("DOMContentLoaded", initCalculator);
246    } else {
247        initCalculator();
248    }
249})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.