@makhmudov.kay/az-editor 0.1.0-beta.11 → 0.1.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +2 -2
- package/dist/az-editor.css +1 -1
- package/dist/az-editor.js +1139 -678
- package/dist/library/EditorFrame.d.ts +1 -0
- package/dist/library/ImageInsertControl.d.ts +5 -0
- package/dist/library/hujjat/docx-images.d.ts +11 -0
- package/dist/library/hujjat/image-resource.d.ts +21 -0
- package/dist/library/image-insertion.d.ts +8 -0
- package/docs/inline-images.ru.md +21 -0
- package/docs/integration.ru.md +7 -5
- package/package.json +2 -1
package/dist/az-editor.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createContext as e, forwardRef as t, useCallback as n, useContext as r, useEffect as i, useImperativeHandle as a, useLayoutEffect as o, useMemo as s, useRef as c, useState as l, useSyncExternalStore as u } from "react";
|
|
2
|
-
import { DocxEditor as d, LOADING_SNAPSHOT as f, LocaleProvider as p, useChromeTranslate as m, useDocxEditor as h,
|
|
3
|
-
import { packagedFonts as
|
|
4
|
-
import
|
|
5
|
-
import { defineFontResolver as
|
|
6
|
-
import { createPortal as
|
|
7
|
-
import { Fragment as
|
|
2
|
+
import { DocxEditor as d, LOADING_SNAPSHOT as f, LocaleProvider as p, useChromeTranslate as m, useDocxEditor as h, useEditorEvent as g, useEditorState as _, useFonts as v } from "@docx-editor.dev/react";
|
|
3
|
+
import { packagedFonts as y } from "@docx-editor.dev/fonts";
|
|
4
|
+
import b from "jszip";
|
|
5
|
+
import { defineFontResolver as x } from "@docx-editor.dev/core/editor";
|
|
6
|
+
import { createPortal as S } from "react-dom";
|
|
7
|
+
import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
|
|
8
|
+
import { lineAtPosition as E } from "@docx-editor.dev/core/layout";
|
|
8
9
|
//#region src/library/ru.ts
|
|
9
|
-
var
|
|
10
|
+
var D = {
|
|
10
11
|
common: {
|
|
11
12
|
cancel: "Отмена",
|
|
12
13
|
apply: "Применить",
|
|
@@ -130,13 +131,13 @@ var T = {
|
|
|
130
131
|
blockSpacingRules: "Интервалы абзаца",
|
|
131
132
|
options: "Параметры интервалов…"
|
|
132
133
|
}
|
|
133
|
-
},
|
|
134
|
+
}, O = class extends Error {
|
|
134
135
|
code;
|
|
135
136
|
constructor(e) {
|
|
136
137
|
super(e), this.code = e;
|
|
137
138
|
}
|
|
138
139
|
};
|
|
139
|
-
function
|
|
140
|
+
function k(e) {
|
|
140
141
|
return e.throwIfAborted(), new Promise((t, n) => {
|
|
141
142
|
let r = () => {
|
|
142
143
|
cancelAnimationFrame(i), n(e.reason);
|
|
@@ -146,7 +147,7 @@ function D(e) {
|
|
|
146
147
|
e.addEventListener("abort", r, { once: !0 });
|
|
147
148
|
});
|
|
148
149
|
}
|
|
149
|
-
async function
|
|
150
|
+
async function A(e, t, n, r, i, a = Infinity) {
|
|
150
151
|
let o = t.ownerDocument, s = e.getZoom(), c = e.getZoomMode(), l = e.getCurrentPage("viewport"), u = Array.from(t.querySelectorAll("*")).filter((e) => e.scrollHeight > e.clientHeight || e.scrollWidth > e.clientWidth).map((e) => ({
|
|
151
152
|
el: e,
|
|
152
153
|
top: e.scrollTop,
|
|
@@ -164,9 +165,9 @@ async function O(e, t, n, r, i, a = Infinity) {
|
|
|
164
165
|
async function m() {
|
|
165
166
|
let t = p(), n = 0;
|
|
166
167
|
for (; n < 2;) {
|
|
167
|
-
await
|
|
168
|
+
await k(i);
|
|
168
169
|
let r = e.snapshot();
|
|
169
|
-
if (r.parseError) throw new
|
|
170
|
+
if (r.parseError) throw new O("INVALID_DOCX");
|
|
170
171
|
let a = p();
|
|
171
172
|
n = !r.isLoading && !r.isOpening && a === t ? n + 1 : 0, t = a;
|
|
172
173
|
}
|
|
@@ -174,24 +175,24 @@ async function O(e, t, n, r, i, a = Infinity) {
|
|
|
174
175
|
try {
|
|
175
176
|
i.throwIfAborted(), await e.save(), await o.fonts.ready, i.throwIfAborted(), e.setZoom(1), await m();
|
|
176
177
|
let s = e.snapshot().page.total;
|
|
177
|
-
if (s > a) throw new
|
|
178
|
-
if (!s) throw new
|
|
178
|
+
if (s > a) throw new O("PAGE_LIMIT_EXCEEDED");
|
|
179
|
+
if (!s) throw new O("RENDER_FAILED");
|
|
179
180
|
let c = e.getDocumentHandle?.().revision, l = [], u = [];
|
|
180
181
|
n.replaceChildren();
|
|
181
182
|
for (let r = 0; r < s; r++) {
|
|
182
183
|
i.throwIfAborted(), e.scrollToPage(r + 1), await m();
|
|
183
184
|
let a = t.querySelector(`.docx-page[data-page-index="${r}"]`);
|
|
184
|
-
if (!a || a.dataset.materialized !== "true") throw new
|
|
185
|
+
if (!a || a.dataset.materialized !== "true") throw new O("RENDER_FAILED");
|
|
185
186
|
await Promise.all(Array.from(a.querySelectorAll("img")).map((e) => e.decode())), await o.fonts.ready, await m();
|
|
186
187
|
let s = Number.parseFloat(a.style.width), c = Number.parseFloat(a.style.height);
|
|
187
|
-
if (!Number.isFinite(s) || !Number.isFinite(c) || s <= 0 || c <= 0) throw new
|
|
188
|
+
if (!Number.isFinite(s) || !Number.isFinite(c) || s <= 0 || c <= 0) throw new O("RENDER_FAILED");
|
|
188
189
|
let d = a.cloneNode(!0);
|
|
189
190
|
d.classList.add("az-print-sheet"), d.removeAttribute("contenteditable"), d.removeAttribute("aria-hidden"), d.querySelectorAll("[contenteditable]").forEach((e) => e.removeAttribute("contenteditable")), d.querySelectorAll("[data-docx-hf-label]").forEach((e) => e.remove()), d.style.setProperty("page", `az-sheet-${r}`), l.push({
|
|
190
191
|
widthPt: s * 72 / 96,
|
|
191
192
|
heightPt: c * 72 / 96
|
|
192
193
|
}), u.push(`@page az-sheet-${r} { size: ${(s * .75).toFixed(3)}pt ${(c * .75).toFixed(3)}pt; margin: 0; }`), n.append(d);
|
|
193
194
|
}
|
|
194
|
-
if (r.textContent = u.join("\n"), await Promise.all(Array.from(n.querySelectorAll("img")).map((e) => e.decode())), await o.fonts.ready, await m(), e.snapshot().page.total !== s || e.getDocumentHandle?.().revision !== c || n.children.length !== s) throw new
|
|
195
|
+
if (r.textContent = u.join("\n"), await Promise.all(Array.from(n.querySelectorAll("img")).map((e) => e.decode())), await o.fonts.ready, await m(), e.snapshot().page.total !== s || e.getDocumentHandle?.().revision !== c || n.children.length !== s) throw new O("RENDER_FAILED");
|
|
195
196
|
return l;
|
|
196
197
|
} catch (e) {
|
|
197
198
|
throw n.replaceChildren(), r.textContent = "", e;
|
|
@@ -203,11 +204,11 @@ async function O(e, t, n, r, i, a = Infinity) {
|
|
|
203
204
|
}
|
|
204
205
|
//#endregion
|
|
205
206
|
//#region src/library/print-document.ts
|
|
206
|
-
function
|
|
207
|
+
function j(e, t) {
|
|
207
208
|
let n = e.ownerDocument, r = ".az-editor-content, .az-document-editor";
|
|
208
209
|
return ((t instanceof Element ? t.closest(r) : null) ?? n.activeElement?.closest(r)) === e;
|
|
209
210
|
}
|
|
210
|
-
async function
|
|
211
|
+
async function M(e, t, n, r) {
|
|
211
212
|
let i = t.ownerDocument, a = i.defaultView, o = i.title, s = i.activeElement instanceof HTMLElement ? i.activeElement : null, c = e.getZoom(), l = e.getZoomMode(), u = e.getCurrentPage("viewport"), d = Array.from(t.querySelectorAll("*")).filter((e) => e.scrollHeight > e.clientHeight || e.scrollWidth > e.clientWidth).map((e) => ({
|
|
212
213
|
el: e,
|
|
213
214
|
top: e.scrollTop,
|
|
@@ -248,7 +249,7 @@ async function A(e, t, n, r) {
|
|
|
248
249
|
};
|
|
249
250
|
try {
|
|
250
251
|
E(), C = !0;
|
|
251
|
-
let n = (await
|
|
252
|
+
let n = (await A(e, t, _, v, x)).length;
|
|
252
253
|
return E(), m.textContent = `Страниц: ${n}. В диалоге печати выберите «Сохранить как PDF». Масштаб — 100%, поля — нет, колонтитулы браузера — выключены.`, h.disabled = !1, h.focus(), T;
|
|
253
254
|
} catch (e) {
|
|
254
255
|
throw T(), e;
|
|
@@ -256,29 +257,155 @@ async function A(e, t, n, r) {
|
|
|
256
257
|
w();
|
|
257
258
|
}
|
|
258
259
|
}
|
|
260
|
+
var N = () => /* @__PURE__ */ Error("Изображение повреждено или имеет неподдерживаемый формат. Используйте PNG или JPEG.");
|
|
261
|
+
function P(e) {
|
|
262
|
+
let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = (e) => t.getUint16(e), r = (e) => t.getUint32(e), i;
|
|
263
|
+
if (e.length >= 33 && r(0) === 2303741511 && r(4) === 218765834) {
|
|
264
|
+
if (r(8) !== 13 || r(12) !== 1229472850) throw N();
|
|
265
|
+
i = {
|
|
266
|
+
mime: "image/png",
|
|
267
|
+
width: r(16),
|
|
268
|
+
height: r(20)
|
|
269
|
+
};
|
|
270
|
+
let t = 8, n = !1, a = !1;
|
|
271
|
+
for (; t + 12 <= e.length;) {
|
|
272
|
+
let i = r(t), o = r(t + 4);
|
|
273
|
+
if (i > e.length - t - 12 || o === 1633899596 || o === 1700284774) throw N();
|
|
274
|
+
if (o === 1229209940 && (n = !0), t += 12 + i, o === 1229278788) {
|
|
275
|
+
a = i === 0 && t === e.length;
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (!n || !a) throw N();
|
|
280
|
+
} else if (e.length >= 4 && n(0) === 65496 && n(e.length - 2) === 65497) {
|
|
281
|
+
let a = 2, o = !1, s;
|
|
282
|
+
for (; a + 4 <= e.length;) {
|
|
283
|
+
if (e[a++] !== 255) throw N();
|
|
284
|
+
for (; e[a] === 255;) a++;
|
|
285
|
+
if (a + 3 > e.length) throw N();
|
|
286
|
+
let c = e[a++], l = n(a);
|
|
287
|
+
if (l < 2 || a + l > e.length) throw N();
|
|
288
|
+
if (c === 225 && l >= 16 && r(a + 2) === 1165519206 && n(a + 6) === 0) {
|
|
289
|
+
let e = a + 8, r = n(e) === 18761;
|
|
290
|
+
if (!r && n(e) !== 19789) throw N();
|
|
291
|
+
let i = (e) => t.getUint16(e, r), o = (e) => t.getUint32(e, r);
|
|
292
|
+
if (i(e + 2) !== 42) throw N();
|
|
293
|
+
let c = e + o(e + 4), u = a + l;
|
|
294
|
+
if (c < e || c + 2 > u) throw N();
|
|
295
|
+
let d = i(c);
|
|
296
|
+
if (c + 2 + d * 12 > u) throw N();
|
|
297
|
+
for (let e = 0; e < d; e++) {
|
|
298
|
+
let t = c + 2 + e * 12;
|
|
299
|
+
if (i(t) === 274) {
|
|
300
|
+
if (i(t + 2) !== 3 || o(t + 4) !== 1) throw N();
|
|
301
|
+
let e = i(t + 8);
|
|
302
|
+
if (s !== void 0 && s !== e) throw N();
|
|
303
|
+
s = e;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if ([
|
|
308
|
+
192,
|
|
309
|
+
193,
|
|
310
|
+
194
|
|
311
|
+
].includes(c)) {
|
|
312
|
+
if (l < 8 || e[a + 2] !== 8) throw N();
|
|
313
|
+
i = {
|
|
314
|
+
mime: "image/jpeg",
|
|
315
|
+
width: n(a + 5),
|
|
316
|
+
height: n(a + 3)
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
if (c === 218) {
|
|
320
|
+
o = !0;
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
a += l;
|
|
324
|
+
}
|
|
325
|
+
if (!o || !i) throw N();
|
|
326
|
+
i.orientation = s;
|
|
327
|
+
}
|
|
328
|
+
if (!i || !i.width || !i.height) throw N();
|
|
329
|
+
return i;
|
|
330
|
+
}
|
|
331
|
+
function ee(e, t) {
|
|
332
|
+
let n = "";
|
|
333
|
+
for (let t = 0; t < e.length; t += 8192) n += String.fromCharCode(...e.subarray(t, t + 8192));
|
|
334
|
+
return `data:${t};base64,${btoa(n)}`;
|
|
335
|
+
}
|
|
336
|
+
function te(e) {
|
|
337
|
+
if (e.length > 349552) throw Error("Изображение превышает 256 КиБ. Уменьшите его перед вставкой.");
|
|
338
|
+
let t = e.match(/^data:(image\/(?:png|jpeg));base64,([A-Za-z0-9+/]+={0,2})$/);
|
|
339
|
+
if (!t || t[2].length % 4) throw N();
|
|
340
|
+
let n;
|
|
341
|
+
try {
|
|
342
|
+
n = atob(t[2]);
|
|
343
|
+
} catch {
|
|
344
|
+
throw N();
|
|
345
|
+
}
|
|
346
|
+
if (n.length > 262144 || btoa(n) !== t[2]) throw N();
|
|
347
|
+
let r = Uint8Array.from(n, (e) => e.charCodeAt(0)), i = P(r);
|
|
348
|
+
if (i.mime !== t[1]) throw N();
|
|
349
|
+
if (i.width > 4096 || i.height > 4096 || i.width * i.height > 16777216) throw Error("Изображение превышает допустимые размеры (4096 пикселей, 16 Мп).");
|
|
350
|
+
if (i.orientation !== void 0 && i.orientation !== 1) throw Error("Изображение с ориентацией EXIF нужно повторно вставить через кнопку изображения.");
|
|
351
|
+
return {
|
|
352
|
+
...i,
|
|
353
|
+
data: r
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
function F(e, t) {
|
|
357
|
+
let n = /* @__PURE__ */ new Map();
|
|
358
|
+
for (let t of (e.getAttribute("style") ?? "").split(";").filter((e) => e.trim())) {
|
|
359
|
+
let e = t.indexOf(":"), r = t.slice(0, e).trim().toLowerCase();
|
|
360
|
+
if (e < 0 || !["width", "height"].includes(r)) throw Error("У изображения поддерживаются только ширина и высота без обтекания и эффектов.");
|
|
361
|
+
n.set(r, t.slice(e + 1).trim());
|
|
362
|
+
}
|
|
363
|
+
let r = (t) => {
|
|
364
|
+
let r = n.get(t) ?? e.getAttribute(t)?.trim();
|
|
365
|
+
if (r === void 0) return;
|
|
366
|
+
let i = r.match(/^(\d*\.?\d+)(pt|px|cm|mm|in)?$/i), a = i ? Number(i[1]) * {
|
|
367
|
+
pt: 1,
|
|
368
|
+
px: .75,
|
|
369
|
+
cm: 72 / 2.54,
|
|
370
|
+
mm: 72 / 25.4,
|
|
371
|
+
in: 72
|
|
372
|
+
}[(i[2] || "px").toLowerCase()] : NaN;
|
|
373
|
+
if (!Number.isFinite(a) || a < 1 / 12700 || a > 600) throw Error("Размер изображения должен быть не меньше 1 EMU (1/12700 pt) и не превышать 600 pt.");
|
|
374
|
+
return a;
|
|
375
|
+
}, i = r("width"), a = r("height");
|
|
376
|
+
if (i === void 0 && a === void 0) {
|
|
377
|
+
let e = Math.min(.75, 600 / t.width, 600 / t.height);
|
|
378
|
+
i = t.width * e, a = t.height * e;
|
|
379
|
+
} else i ??= a * t.width / t.height, a ??= i * t.height / t.width;
|
|
380
|
+
if (i < 1 / 12700 || a < 1 / 12700 || i > 600 || a > 600) throw Error("Размер изображения должен быть от 1 EMU до 600 pt.");
|
|
381
|
+
return {
|
|
382
|
+
width: Number(i.toFixed(4)),
|
|
383
|
+
height: Number(a.toFixed(4))
|
|
384
|
+
};
|
|
385
|
+
}
|
|
259
386
|
//#endregion
|
|
260
387
|
//#region src/library/layout-profile.ts
|
|
261
|
-
var
|
|
388
|
+
var I = Object.freeze({
|
|
262
389
|
widthMm: 210,
|
|
263
390
|
heightMm: 297,
|
|
264
391
|
topMm: 15,
|
|
265
392
|
rightMm: 20,
|
|
266
393
|
bottomMm: 35,
|
|
267
394
|
leftMm: 20
|
|
268
|
-
}),
|
|
269
|
-
function
|
|
395
|
+
}), L = (e) => Math.round(e * 1440 / 25.4);
|
|
396
|
+
function ne(e) {
|
|
270
397
|
return e.widthTwips - e.margins.left - e.margins.right - e.margins.gutter;
|
|
271
398
|
}
|
|
272
|
-
function
|
|
399
|
+
function R(e = {}) {
|
|
273
400
|
let t = e.page ?? {
|
|
274
|
-
widthTwips:
|
|
275
|
-
heightTwips:
|
|
401
|
+
widthTwips: L(I.widthMm),
|
|
402
|
+
heightTwips: L(I.heightMm),
|
|
276
403
|
orientation: "portrait",
|
|
277
404
|
margins: {
|
|
278
|
-
top:
|
|
279
|
-
right:
|
|
280
|
-
bottom:
|
|
281
|
-
left:
|
|
405
|
+
top: L(I.topMm),
|
|
406
|
+
right: L(I.rightMm),
|
|
407
|
+
bottom: L(I.bottomMm),
|
|
408
|
+
left: L(I.leftMm),
|
|
282
409
|
header: 0,
|
|
283
410
|
footer: 0,
|
|
284
411
|
gutter: 0
|
|
@@ -308,7 +435,7 @@ function P(e = {}) {
|
|
|
308
435
|
].some((e) => {
|
|
309
436
|
let t = n.margins[e];
|
|
310
437
|
return !Number.isSafeInteger(t) || t < 0 || t > 31680;
|
|
311
|
-
}) ||
|
|
438
|
+
}) || ne(n) <= 0 || n.heightTwips - n.margins.top - n.margins.bottom <= 0) throw RangeError("Некорректная геометрия страницы: нужны целые twips, согласованная ориентация и положительная область текста (размеры до 22 дюймов).");
|
|
312
439
|
let i = e.lineSpacingPolicy ?? "normalize";
|
|
313
440
|
if (!["normalize", "preserve"].includes(i)) throw TypeError("Неизвестная политика межстрочного интервала.");
|
|
314
441
|
return {
|
|
@@ -318,57 +445,57 @@ function P(e = {}) {
|
|
|
318
445
|
lineSpacingPolicy: i
|
|
319
446
|
};
|
|
320
447
|
}
|
|
321
|
-
function
|
|
448
|
+
function re(e, t) {
|
|
322
449
|
return e.widthTwips === t.widthTwips && e.heightTwips === t.heightTwips && e.orientation === t.orientation && Object.keys(e.margins).every((n) => e.margins[n] === t.margins[n]);
|
|
323
450
|
}
|
|
324
451
|
//#endregion
|
|
325
452
|
//#region src/library/hujjat/contract.ts
|
|
326
|
-
var
|
|
453
|
+
var ie = [
|
|
327
454
|
"uz",
|
|
328
455
|
"ru",
|
|
329
456
|
"uz_cyrl",
|
|
330
457
|
"en"
|
|
331
|
-
],
|
|
458
|
+
], ae = 1048576, z = class extends Error {
|
|
332
459
|
warnings;
|
|
333
460
|
constructor(e, t = []) {
|
|
334
461
|
super(e), this.name = "HujjatCompatibilityError", this.warnings = t;
|
|
335
462
|
}
|
|
336
|
-
},
|
|
337
|
-
function
|
|
463
|
+
}, oe = /* @__PURE__ */ new WeakMap();
|
|
464
|
+
function B(e, t, n, r = "warning", i = {}) {
|
|
338
465
|
let a = {
|
|
339
466
|
code: t,
|
|
340
467
|
message: n,
|
|
341
468
|
severity: r,
|
|
342
469
|
...i
|
|
343
|
-
}, o =
|
|
470
|
+
}, o = oe.get(e);
|
|
344
471
|
(!o || o.length !== e.length) && (o = {
|
|
345
472
|
length: e.length,
|
|
346
473
|
keys: new Set(e.map((e) => JSON.stringify(e)))
|
|
347
|
-
},
|
|
474
|
+
}, oe.set(e, o));
|
|
348
475
|
let s = JSON.stringify(a);
|
|
349
476
|
o.keys.has(s) || (e.push(a), o.keys.add(s), o.length = e.length);
|
|
350
477
|
}
|
|
351
|
-
function
|
|
352
|
-
if (!t && e.some((e) => e.severity === "loss")) throw new
|
|
478
|
+
function se(e, t = !1) {
|
|
479
|
+
if (!t && e.some((e) => e.severity === "loss")) throw new z("Hujjat не сохраняет часть содержимого. Проверьте warnings; allowLossy разрешает экспорт с указанными потерями.", e);
|
|
353
480
|
}
|
|
354
|
-
function
|
|
481
|
+
function ce(e) {
|
|
355
482
|
return e.length <= 100 && /^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*$/.test(e) && !e.split(".").some((e) => [
|
|
356
483
|
"__proto__",
|
|
357
484
|
"prototype",
|
|
358
485
|
"constructor"
|
|
359
486
|
].includes(e));
|
|
360
487
|
}
|
|
361
|
-
function
|
|
488
|
+
function le(e) {
|
|
362
489
|
return /courier|mono|consolas/i.test(e) ? "freemono" : /arial|helvetica|calibri|sans|verdana|tahoma|segoe|roboto/i.test(e) ? "freesans" : "freeserif";
|
|
363
490
|
}
|
|
364
|
-
var
|
|
491
|
+
var ue = new Set("div p span br hr b strong i em u s sub sup h1 h2 h3 h4 h5 h6 ul ol li table colgroup col thead tbody tfoot tr td th".split(" ")), de = new Set("script style iframe object embed svg math img picture video audio canvas link meta form input textarea select button template noscript base frame frameset".split(" ")), fe = new Set("div p h1 h2 h3 h4 h5 h6 ul ol li table thead tbody tfoot tr td th br hr img".split(" ")), pe = {
|
|
365
492
|
pt: 1,
|
|
366
493
|
px: .75,
|
|
367
494
|
in: 72,
|
|
368
495
|
cm: 72 / 2.54,
|
|
369
496
|
mm: 72 / 25.4,
|
|
370
497
|
pc: 12
|
|
371
|
-
},
|
|
498
|
+
}, me = new Set(("color font-family font-size font-weight font-style text-decoration text-align text-transform text-indent letter-spacing line-height white-space vertical-align background background-color width height margin padding border border-color border-width border-style border-collapse table-layout page-break-before page-break-after page-break-inside break-before break-after break-inside " + [
|
|
372
499
|
"top",
|
|
373
500
|
"right",
|
|
374
501
|
"bottom",
|
|
@@ -381,16 +508,16 @@ var ie = new Set("div p span br hr b strong i em u s sub sup h1 h2 h3 h4 h5 h6 u
|
|
|
381
508
|
`border-${e}-width`,
|
|
382
509
|
`border-${e}-color`
|
|
383
510
|
]).join(" ")).split(" "));
|
|
384
|
-
function
|
|
511
|
+
function he(e, t) {
|
|
385
512
|
let n = /* @__PURE__ */ new Map();
|
|
386
513
|
for (let r of e.split(";")) {
|
|
387
514
|
if (!r.trim()) continue;
|
|
388
|
-
let e = r.indexOf(":"), i = r.slice(0, e).trim().toLowerCase(), a = r.slice(e + 1).trim(), o = /[<>{}\\@]|url\s*\(|expression|javascript|vbscript|behavior|binding|import|\/\*|!important/i.test(a) || a.length > 200 || /[()]/.test(a.replace(/(?:rgb|hsl)a?\([\d\s.,%/+-]+\)/gi, "")), s = [...a.matchAll(/(-?\d*\.?\d+)\s*(pt|px|in|cm|mm|pc)\b/gi)].some((e) => Math.abs(Number(e[1])) *
|
|
389
|
-
if (e < 1 || !
|
|
515
|
+
let e = r.indexOf(":"), i = r.slice(0, e).trim().toLowerCase(), a = r.slice(e + 1).trim(), o = /[<>{}\\@]|url\s*\(|expression|javascript|vbscript|behavior|binding|import|\/\*|!important/i.test(a) || a.length > 200 || /[()]/.test(a.replace(/(?:rgb|hsl)a?\([\d\s.,%/+-]+\)/gi, "")), s = [...a.matchAll(/(-?\d*\.?\d+)\s*(pt|px|in|cm|mm|pc)\b/gi)].some((e) => Math.abs(Number(e[1])) * pe[e[2].toLowerCase()] > 600);
|
|
516
|
+
if (e < 1 || !me.has(i) || !a || o || s || i === "color" && a.toLowerCase() === "auto") B(t, "css-removed", `Стиль ${i || r} не поддерживается контрактом Hujjat.`);
|
|
390
517
|
else {
|
|
391
518
|
if (i === "font-family") {
|
|
392
|
-
let e =
|
|
393
|
-
a.replace(/['"]/g, "").toLowerCase() !== e &&
|
|
519
|
+
let e = le(a);
|
|
520
|
+
a.replace(/['"]/g, "").toLowerCase() !== e && B(t, "font-substitution", `Шрифт ${a} заменён на ${e}.`), a = e;
|
|
394
521
|
}
|
|
395
522
|
if (/^(page-)?break-(before|after|inside)$/.test(i)) {
|
|
396
523
|
let e = i.startsWith("break-");
|
|
@@ -399,7 +526,7 @@ function le(e, t) {
|
|
|
399
526
|
"avoid",
|
|
400
527
|
...i.endsWith("inside") ? [] : ["always"]
|
|
401
528
|
].includes(a)) {
|
|
402
|
-
|
|
529
|
+
B(t, "page-break-value-unsupported", `Значение ${a} для ${i} не поддерживается HTML-адаптером.`);
|
|
403
530
|
continue;
|
|
404
531
|
}
|
|
405
532
|
e && (i = `page-${i}`);
|
|
@@ -409,11 +536,11 @@ function le(e, t) {
|
|
|
409
536
|
}
|
|
410
537
|
return [...n].map(([e, t]) => `${e}:${t}`).join(";");
|
|
411
538
|
}
|
|
412
|
-
function
|
|
539
|
+
function ge(e) {
|
|
413
540
|
let t = document.createElement("template");
|
|
414
541
|
return t.innerHTML = e, t.content;
|
|
415
542
|
}
|
|
416
|
-
function
|
|
543
|
+
function _e(e) {
|
|
417
544
|
let t = [], n = [], r = () => {
|
|
418
545
|
n.length && t.push(n), n = [];
|
|
419
546
|
};
|
|
@@ -422,7 +549,7 @@ function de(e) {
|
|
|
422
549
|
n.push(e);
|
|
423
550
|
return;
|
|
424
551
|
}
|
|
425
|
-
let t = e instanceof Element &&
|
|
552
|
+
let t = e instanceof Element && fe.has(e.localName);
|
|
426
553
|
t && r();
|
|
427
554
|
for (let t of e.childNodes) i(t);
|
|
428
555
|
t && r();
|
|
@@ -447,34 +574,49 @@ function de(e) {
|
|
|
447
574
|
}
|
|
448
575
|
}
|
|
449
576
|
}
|
|
450
|
-
function
|
|
451
|
-
if (typeof e != "string" || !e.trim()) throw new
|
|
452
|
-
if (new TextEncoder().encode(e).length > 1048576) throw new
|
|
453
|
-
let t =
|
|
454
|
-
function
|
|
577
|
+
function ve(e) {
|
|
578
|
+
if (typeof e != "string" || !e.trim()) throw new z("HTML шаблона пуст.");
|
|
579
|
+
if (new TextEncoder().encode(e).length > 1048576) throw new z("HTML превышает 1 МБ (1048576 байт).");
|
|
580
|
+
let t = ge(e), n = document.createElement("div"), r = [], i = 0, a = 0;
|
|
581
|
+
function o(e, t, n, r) {
|
|
455
582
|
let i = 0;
|
|
456
|
-
for (let a of e.childNodes)
|
|
583
|
+
for (let a of e.childNodes) s(a, t, n, a instanceof Element ? `${r}/${a.localName}[${i++}]` : r);
|
|
457
584
|
}
|
|
458
|
-
function
|
|
459
|
-
if (++i > 5e4 || n > 100) throw new
|
|
585
|
+
function s(e, t, n, s) {
|
|
586
|
+
if (++i > 5e4 || n > 100) throw new z("HTML слишком сложный.");
|
|
460
587
|
if (e.nodeType === 3) {
|
|
461
588
|
t.appendChild(document.createTextNode(e.textContent ?? ""));
|
|
462
589
|
return;
|
|
463
590
|
}
|
|
464
591
|
if (!(e instanceof Element)) return;
|
|
465
|
-
let
|
|
466
|
-
if (
|
|
467
|
-
|
|
592
|
+
let c = e.localName.toLowerCase();
|
|
593
|
+
if (c === "img") {
|
|
594
|
+
try {
|
|
595
|
+
if (++a > 32) throw Error("В одном HTML-блоке допускается не более 32 изображений.");
|
|
596
|
+
let n = e.style;
|
|
597
|
+
if (Array.from(n).some((e) => !["width", "height"].includes(e))) throw Error("В Hujjat поддерживается строчное изображение без обтекания и эффектов; задайте только ширину и высоту.");
|
|
598
|
+
let r = e.getAttribute("src") ?? "", i = F(e, te(r)), o = document.createElement("img");
|
|
599
|
+
o.setAttribute("src", r), o.setAttribute("alt", Array.from(e.getAttribute("alt") ?? "").slice(0, 500).join("")), o.setAttribute("style", `width:${i.width}pt;height:${i.height}pt`), t.appendChild(o);
|
|
600
|
+
} catch (e) {
|
|
601
|
+
B(r, "image-invalid", e instanceof Error ? e.message : "Некорректное изображение.", "loss", {
|
|
602
|
+
stage: "import",
|
|
603
|
+
location: { htmlPath: s }
|
|
604
|
+
});
|
|
605
|
+
}
|
|
468
606
|
return;
|
|
469
607
|
}
|
|
470
|
-
if (
|
|
471
|
-
|
|
608
|
+
if (de.has(c)) {
|
|
609
|
+
B(r, "html-element-removed", `Элемент ${c} удалён: он не поддерживается HTML-блоком Hujjat.`, "loss");
|
|
472
610
|
return;
|
|
473
611
|
}
|
|
474
|
-
|
|
475
|
-
|
|
612
|
+
if (!ue.has(c)) {
|
|
613
|
+
B(r, "html-tag-unwrapped", `Тег ${c} удалён с сохранением текста.`), o(e, t, n + 1, s);
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
let l = document.createElement(c), u = e.getAttribute("style") ?? "";
|
|
617
|
+
if (["col", "colgroup"].includes(c) && e.hasAttribute("width") && !/(?:^|;)\s*width\s*:/i.test(u)) {
|
|
476
618
|
let t = e.getAttribute("width").trim();
|
|
477
|
-
|
|
619
|
+
u += `;width:${/^\d+(?:\.\d+)?$/.test(t) ? t + "px" : t}`;
|
|
478
620
|
}
|
|
479
621
|
if ([
|
|
480
622
|
"table",
|
|
@@ -482,64 +624,64 @@ function fe(e) {
|
|
|
482
624
|
"th",
|
|
483
625
|
"col",
|
|
484
626
|
"colgroup"
|
|
485
|
-
].includes(
|
|
486
|
-
let e = [...
|
|
487
|
-
e && e.toLowerCase() !== "auto" && (!/^(?:\d*\.)?\d+(?:pt|px|in|cm|mm|pc|%)$/i.test(e) || !Number.isFinite(parseFloat(e)) || parseFloat(e) <= 0 || t && Number(t[1]) *
|
|
627
|
+
].includes(c)) {
|
|
628
|
+
let e = [...u.matchAll(/(?:^|;)\s*width\s*:\s*([^;]+)/gi)].at(-1)?.[1].trim(), t = e?.match(/^(\d*\.?\d+)(pt|px|in|cm|mm|pc)$/i);
|
|
629
|
+
e && e.toLowerCase() !== "auto" && (!/^(?:\d*\.)?\d+(?:pt|px|in|cm|mm|pc|%)$/i.test(e) || !Number.isFinite(parseFloat(e)) || parseFloat(e) <= 0 || t && Number(t[1]) * pe[t[2].toLowerCase()] > 600) && B(r, "table-width-invalid", "Некорректная ширина таблицы или колонки.", "loss", {
|
|
488
630
|
stage: "import",
|
|
489
|
-
location: { htmlPath:
|
|
631
|
+
location: { htmlPath: s },
|
|
490
632
|
before: e
|
|
491
633
|
});
|
|
492
634
|
}
|
|
493
|
-
e.hasAttribute("bgcolor") && (
|
|
494
|
-
let
|
|
495
|
-
if (
|
|
635
|
+
e.hasAttribute("bgcolor") && (u += `;background-color:${e.getAttribute("bgcolor")}`);
|
|
636
|
+
let d = he(u, r);
|
|
637
|
+
if (d && l.setAttribute("style", d), c === "td" || c === "th") for (let t of ["colspan", "rowspan"]) {
|
|
496
638
|
let n = e.getAttribute(t);
|
|
497
|
-
n && /^\d+$/.test(n) && Number(n) >= 1 && Number(n) <= 100 ?
|
|
639
|
+
n && /^\d+$/.test(n) && Number(n) >= 1 && Number(n) <= 100 ? l.setAttribute(t, String(Number(n))) : n !== null && B(r, "table-span-invalid", "Некорректное объединение ячеек.", "loss", {
|
|
498
640
|
stage: "import",
|
|
499
|
-
location: { htmlPath:
|
|
641
|
+
location: { htmlPath: s },
|
|
500
642
|
before: n
|
|
501
643
|
});
|
|
502
644
|
}
|
|
503
|
-
if (
|
|
645
|
+
if (c === "col" || c === "colgroup") {
|
|
504
646
|
let t = e.getAttribute("span");
|
|
505
|
-
t !== null && (/^\d+$/.test(t) && Number(t) >= 1 && Number(t) <= 1e3 ?
|
|
647
|
+
t !== null && (/^\d+$/.test(t) && Number(t) >= 1 && Number(t) <= 1e3 ? l.setAttribute("span", String(Number(t))) : B(r, "table-span-invalid", "Некорректное число колонок.", "loss", {
|
|
506
648
|
stage: "import",
|
|
507
|
-
location: { htmlPath:
|
|
649
|
+
location: { htmlPath: s },
|
|
508
650
|
before: t
|
|
509
651
|
}));
|
|
510
652
|
}
|
|
511
|
-
|
|
653
|
+
o(e, l, n + 1, s), t.appendChild(l);
|
|
512
654
|
}
|
|
513
|
-
|
|
514
|
-
let
|
|
515
|
-
for (;
|
|
655
|
+
o(t, n, 0, ""), _e(n);
|
|
656
|
+
let c = /* @__PURE__ */ new Set(), l = document.createTreeWalker(n, NodeFilter.SHOW_TEXT);
|
|
657
|
+
for (; l.nextNode();) for (let e of l.currentNode.textContent.matchAll(/\{([^{}]+)\}/g)) {
|
|
516
658
|
let t = e[1];
|
|
517
|
-
/^[A-Za-z0-9_.]+$/.test(t) &&
|
|
659
|
+
/^[A-Za-z0-9_.]+$/.test(t) && c.add(t), ce(t) || B(r, "invalid-variable", `Проверьте переменную {${t}}: используйте ASCII-путь без пустых сегментов, до 100 символов.`);
|
|
518
660
|
}
|
|
519
|
-
let
|
|
520
|
-
if (new TextEncoder().encode(
|
|
661
|
+
let u = n.innerHTML || "<p></p>";
|
|
662
|
+
if (new TextEncoder().encode(u).length > 1048576) throw new z("HTML превышает 1 МБ (1048576 байт).");
|
|
521
663
|
return {
|
|
522
|
-
html:
|
|
523
|
-
variables: [...
|
|
664
|
+
html: u,
|
|
665
|
+
variables: [...c],
|
|
524
666
|
warnings: r
|
|
525
667
|
};
|
|
526
668
|
}
|
|
527
|
-
function
|
|
528
|
-
if (!
|
|
669
|
+
function ye(e) {
|
|
670
|
+
if (!ie.includes(e)) throw new z(`Неподдерживаемая локаль: ${e}.`);
|
|
529
671
|
}
|
|
530
|
-
function
|
|
531
|
-
|
|
672
|
+
function be(e, t) {
|
|
673
|
+
ye(t);
|
|
532
674
|
let n = e[t];
|
|
533
|
-
if (!n || !Array.isArray(n.blocks) || !n.blocks.length) throw new
|
|
675
|
+
if (!n || !Array.isArray(n.blocks) || !n.blocks.length) throw new z(`Нет HTML-шаблона для локали ${t}.`);
|
|
534
676
|
return n.blocks.map((e) => {
|
|
535
|
-
if (e.type !== "html" || typeof e.props?.html != "string" || e.style && Object.keys(e.style).length) throw new
|
|
677
|
+
if (e.type !== "html" || typeof e.props?.html != "string" || e.style && Object.keys(e.style).length) throw new z(`Блок ${e.type} или его внешние стили не поддерживаются редактором HTML; содержимое не изменено.`);
|
|
536
678
|
return e.props.html;
|
|
537
679
|
}).join("");
|
|
538
680
|
}
|
|
539
|
-
function
|
|
540
|
-
|
|
541
|
-
for (let t of Object.keys(e))
|
|
542
|
-
let r =
|
|
681
|
+
function xe(e, t, n) {
|
|
682
|
+
ye(t);
|
|
683
|
+
for (let t of Object.keys(e)) ye(t);
|
|
684
|
+
let r = ve(n), i = structuredClone(e);
|
|
543
685
|
return {
|
|
544
686
|
...r,
|
|
545
687
|
page: i[t]?.page,
|
|
@@ -557,25 +699,25 @@ function he(e, t, n) {
|
|
|
557
699
|
}
|
|
558
700
|
//#endregion
|
|
559
701
|
//#region src/library/hujjat/xml.ts
|
|
560
|
-
var
|
|
702
|
+
var V = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", Se = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"), H = (e, t) => Array.from(e?.children ?? []).filter((e) => e.namespaceURI === "http://schemas.openxmlformats.org/wordprocessingml/2006/main" && (!t || e.localName === t)), U = (e, t) => H(e, t)[0] ?? null, W = (e, t = "val") => e?.getAttributeNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", t) ?? "", G = (e, t) => W(U(e, t)), K = (e) => e !== null && ![
|
|
561
703
|
"0",
|
|
562
704
|
"false",
|
|
563
705
|
"off",
|
|
564
706
|
"none"
|
|
565
|
-
].includes(
|
|
566
|
-
function
|
|
567
|
-
if (/<!DOCTYPE|<!ENTITY/i.test(e)) throw new
|
|
707
|
+
].includes(W(e)), q = (e) => `${Number(e) / 20}pt`, Ce = (e) => Object.keys(e).length ? ` style="${Se(Object.entries(e).map(([e, t]) => `${e}:${t}`).join(";"))}"` : "";
|
|
708
|
+
function we(e) {
|
|
709
|
+
if (/<!DOCTYPE|<!ENTITY/i.test(e)) throw new z("XML с DTD/ENTITY не поддерживается.");
|
|
568
710
|
let t = new DOMParser().parseFromString(e, "application/xml");
|
|
569
|
-
if (t.querySelector("parsererror")) throw new
|
|
570
|
-
if (t.getElementsByTagName("*").length > 5e4) throw new
|
|
711
|
+
if (t.querySelector("parsererror")) throw new z("Повреждённый XML в DOCX.");
|
|
712
|
+
if (t.getElementsByTagName("*").length > 5e4) throw new z("Слишком сложный XML в DOCX.");
|
|
571
713
|
return t;
|
|
572
714
|
}
|
|
573
|
-
async function
|
|
715
|
+
async function J(e, t) {
|
|
574
716
|
let n = e.file(t);
|
|
575
|
-
return n ?
|
|
717
|
+
return n ? we(await new Promise((e, t) => {
|
|
576
718
|
let r = n.internalStream("uint8array"), i = 0, a = [];
|
|
577
719
|
r.on("data", (e) => {
|
|
578
|
-
i += e.length, i > 8388608 ? (r.pause(), t(new
|
|
720
|
+
i += e.length, i > 8388608 ? (r.pause(), t(new z("XML-часть DOCX превышает 8 МиБ."))) : a.push(e);
|
|
579
721
|
}), r.on("error", t), r.on("end", () => {
|
|
580
722
|
let t = new Uint8Array(i), n = 0;
|
|
581
723
|
for (let e of a) t.set(e, n), n += e.length;
|
|
@@ -583,11 +725,11 @@ async function q(e, t) {
|
|
|
583
725
|
}), r.resume();
|
|
584
726
|
})) : null;
|
|
585
727
|
}
|
|
586
|
-
function
|
|
728
|
+
function Y(e, t = {}) {
|
|
587
729
|
let n = { ...t };
|
|
588
|
-
|
|
589
|
-
let r =
|
|
590
|
-
i && (n["font-family"] = i),
|
|
730
|
+
U(e, "vanish") && (n["--az-hidden"] = K(U(e, "vanish")) ? "1" : "0");
|
|
731
|
+
let r = U(e, "rFonts"), i = W(r, "ascii") || W(r, "hAnsi") || W(r, "cs");
|
|
732
|
+
i && (n["font-family"] = i), G(e, "sz") && (n["font-size"] = `${Number(G(e, "sz")) / 2}pt`);
|
|
591
733
|
for (let [t, r, i, a] of [[
|
|
592
734
|
"b",
|
|
593
735
|
"font-weight",
|
|
@@ -598,14 +740,14 @@ function J(e, t = {}) {
|
|
|
598
740
|
"font-style",
|
|
599
741
|
"italic",
|
|
600
742
|
"normal"
|
|
601
|
-
]])
|
|
743
|
+
]]) U(e, t) && (n[r] = K(U(e, t)) ? i : a);
|
|
602
744
|
for (let t of [
|
|
603
745
|
"u",
|
|
604
746
|
"strike",
|
|
605
747
|
"dstrike"
|
|
606
748
|
]) {
|
|
607
|
-
let r =
|
|
608
|
-
r && (n[`--az-decoration-${t}`] =
|
|
749
|
+
let r = U(e, t);
|
|
750
|
+
r && (n[`--az-decoration-${t}`] = K(r) ? "1" : "0");
|
|
609
751
|
}
|
|
610
752
|
if ([
|
|
611
753
|
"u",
|
|
@@ -615,11 +757,11 @@ function J(e, t = {}) {
|
|
|
615
757
|
let e = [];
|
|
616
758
|
n["--az-decoration-u"] === "1" && e.push("underline"), (n["--az-decoration-strike"] === "1" || n["--az-decoration-dstrike"] === "1") && e.push("line-through"), n["text-decoration"] = e.join(" ") || "none";
|
|
617
759
|
}
|
|
618
|
-
let a =
|
|
760
|
+
let a = G(e, "color");
|
|
619
761
|
/^[\da-f]{6}$/i.test(a) && (n.color = `#${a}`);
|
|
620
|
-
let o = U(
|
|
621
|
-
/^[\da-f]{6}$/i.test(o) ? n["background-color"] = `#${o}` :
|
|
622
|
-
let s =
|
|
762
|
+
let o = W(U(e, "shd"), "fill");
|
|
763
|
+
/^[\da-f]{6}$/i.test(o) ? n["background-color"] = `#${o}` : G(e, "highlight") && G(e, "highlight") !== "none" && (n["background-color"] = G(e, "highlight"));
|
|
764
|
+
let s = G(e, "vertAlign");
|
|
623
765
|
return [
|
|
624
766
|
"superscript",
|
|
625
767
|
"subscript",
|
|
@@ -628,10 +770,10 @@ function J(e, t = {}) {
|
|
|
628
770
|
superscript: "super",
|
|
629
771
|
subscript: "sub",
|
|
630
772
|
baseline: "baseline"
|
|
631
|
-
}[s]),
|
|
773
|
+
}[s]), U(e, "caps") && (n["text-transform"] = K(U(e, "caps")) ? "uppercase" : "none"), G(e, "spacing") && (n["letter-spacing"] = q(G(e, "spacing"))), G(e, "position") && (n["--az-position"] = G(e, "position")), n;
|
|
632
774
|
}
|
|
633
|
-
function
|
|
634
|
-
let n = t.reduce((e, t) =>
|
|
775
|
+
function Te(e, t) {
|
|
776
|
+
let n = t.reduce((e, t) => Y(t, e), {}), r = {
|
|
635
777
|
...e,
|
|
636
778
|
...n
|
|
637
779
|
};
|
|
@@ -644,27 +786,27 @@ function ye(e, t) {
|
|
|
644
786
|
"1",
|
|
645
787
|
"0"
|
|
646
788
|
]]) n[t] !== void 0 && (r[t] = e[t] === i == (n[t] === i) ? a : i);
|
|
647
|
-
return
|
|
789
|
+
return Y(null, r);
|
|
648
790
|
}
|
|
649
|
-
function
|
|
650
|
-
let t = {}, n =
|
|
791
|
+
function Ee(e) {
|
|
792
|
+
let t = {}, n = G(e, "jc");
|
|
651
793
|
n && (t["text-align"] = {
|
|
652
794
|
both: "justify",
|
|
653
795
|
distribute: "justify",
|
|
654
796
|
start: "left",
|
|
655
797
|
end: "right"
|
|
656
798
|
}[n] ?? n);
|
|
657
|
-
let r =
|
|
658
|
-
for (let [e, n] of [["before", "margin-top"], ["after", "margin-bottom"]])
|
|
659
|
-
|
|
660
|
-
let i =
|
|
799
|
+
let r = U(e, "spacing");
|
|
800
|
+
for (let [e, n] of [["before", "margin-top"], ["after", "margin-bottom"]]) W(r, e) && (t[n] = q(W(r, e)));
|
|
801
|
+
W(r, "line") && (t["line-height"] = W(r, "lineRule") === "auto" || !W(r, "lineRule") ? String(Number(W(r, "line")) / 240) : q(W(r, "line")));
|
|
802
|
+
let i = U(e, "ind");
|
|
661
803
|
for (let [e, n] of [
|
|
662
804
|
["left", "margin-left"],
|
|
663
805
|
["right", "margin-right"],
|
|
664
806
|
["firstLine", "text-indent"]
|
|
665
|
-
])
|
|
666
|
-
let a =
|
|
667
|
-
a && (Number(a) !== 0 || !
|
|
807
|
+
]) W(i, e) && (t[n] = q(W(i, e)));
|
|
808
|
+
let a = W(i, "hanging");
|
|
809
|
+
a && (Number(a) !== 0 || !W(i, "firstLine")) && (t["text-indent"] = q(-Number(a)));
|
|
668
810
|
for (let [n, r, i] of [
|
|
669
811
|
[
|
|
670
812
|
"pageBreakBefore",
|
|
@@ -682,56 +824,56 @@ function be(e) {
|
|
|
682
824
|
"avoid"
|
|
683
825
|
]
|
|
684
826
|
]) {
|
|
685
|
-
let a =
|
|
686
|
-
a && (t[r] =
|
|
827
|
+
let a = U(e, n);
|
|
828
|
+
a && (t[r] = K(a) ? i : "auto");
|
|
687
829
|
}
|
|
688
830
|
return t;
|
|
689
831
|
}
|
|
690
|
-
function
|
|
832
|
+
function De(e) {
|
|
691
833
|
if (!e) return;
|
|
692
|
-
if (["nil", "none"].includes(
|
|
834
|
+
if (["nil", "none"].includes(W(e))) return "none";
|
|
693
835
|
let t = {
|
|
694
836
|
double: "double",
|
|
695
837
|
dotted: "dotted",
|
|
696
838
|
dashed: "dashed"
|
|
697
|
-
}[
|
|
698
|
-
return `${Number(
|
|
839
|
+
}[W(e)] ?? "solid", n = W(e, "color");
|
|
840
|
+
return `${Number(W(e, "sz") || 4) / 8}pt ${t} ${/^[\da-f]{6}$/i.test(n) ? "#" + n : "#000000"}`;
|
|
699
841
|
}
|
|
700
842
|
//#endregion
|
|
701
843
|
//#region src/library/hujjat/page-layout.ts
|
|
702
|
-
function
|
|
703
|
-
let t =
|
|
704
|
-
return
|
|
844
|
+
function Oe(e) {
|
|
845
|
+
let t = R().page, n = U(e, "pgSz"), r = U(e, "pgMar"), i = (e, t, n) => W(e, t) === "" ? n : Number(W(e, t)), a = i(n, "w", t.widthTwips), o = i(n, "h", t.heightTwips);
|
|
846
|
+
return R({ page: {
|
|
705
847
|
widthTwips: a,
|
|
706
848
|
heightTwips: o,
|
|
707
|
-
orientation:
|
|
849
|
+
orientation: W(n, "orient") || (a > o ? "landscape" : "portrait"),
|
|
708
850
|
margins: Object.fromEntries(Object.entries(t.margins).map(([e, t]) => [e, i(r, e, t)]))
|
|
709
851
|
} }).page;
|
|
710
852
|
}
|
|
711
|
-
function
|
|
712
|
-
let i =
|
|
853
|
+
function ke(e, t, n, r) {
|
|
854
|
+
let i = R(t), a = Array.from(e.getElementsByTagNameNS(V, "sectPr")), o;
|
|
713
855
|
try {
|
|
714
|
-
o = a.map(
|
|
856
|
+
o = a.map(Oe);
|
|
715
857
|
} catch (e) {
|
|
716
|
-
|
|
858
|
+
B(n, "unsupported-page-layout", e instanceof Error ? e.message : "Неподдерживаемые параметры страницы.", "loss", {
|
|
717
859
|
stage: "export",
|
|
718
860
|
location: { part: "word/document.xml" }
|
|
719
861
|
});
|
|
720
862
|
return;
|
|
721
863
|
}
|
|
722
|
-
if (a.length > 1 &&
|
|
864
|
+
if (a.length > 1 && B(n, "section-normalized", "HTML не хранит границы и типы переходов разделов Word.", "loss", {
|
|
723
865
|
stage: "export",
|
|
724
866
|
location: { part: "word/document.xml" },
|
|
725
867
|
before: a.length,
|
|
726
868
|
after: 1
|
|
727
|
-
}), o.some((e) => !
|
|
728
|
-
let s = o[0] ??
|
|
729
|
-
return
|
|
869
|
+
}), o.some((e) => !re(e, o[0]))) return;
|
|
870
|
+
let s = o[0] ?? R().page;
|
|
871
|
+
return re(s, r ? {
|
|
730
872
|
...r,
|
|
731
873
|
orientation: s.orientation,
|
|
732
874
|
widthTwips: s.orientation === "landscape" ? 16838 : 11906,
|
|
733
875
|
heightTwips: s.orientation === "landscape" ? 11906 : 16838
|
|
734
|
-
} :
|
|
876
|
+
} : R().page) || B(n, "layout-not-carried-by-html", "Размеры и поля страницы переданы отдельно в layout. Текущий PDF-контракт поддерживает только ориентацию A4 и фиксированные поля.", "warning", {
|
|
735
877
|
stage: "export",
|
|
736
878
|
location: {
|
|
737
879
|
part: "word/document.xml",
|
|
@@ -744,12 +886,12 @@ function Ce(e, t, n, r) {
|
|
|
744
886
|
}
|
|
745
887
|
//#endregion
|
|
746
888
|
//#region src/library/hujjat/paragraph-format.ts
|
|
747
|
-
function
|
|
889
|
+
function Ae(e) {
|
|
748
890
|
let t, n = "auto";
|
|
749
891
|
for (let r of e) {
|
|
750
|
-
let e =
|
|
751
|
-
|
|
752
|
-
let i =
|
|
892
|
+
let e = U(r, "spacing");
|
|
893
|
+
W(e, "line") !== "" && (t = Number(W(e, "line")));
|
|
894
|
+
let i = W(e, "lineRule");
|
|
753
895
|
(i === "auto" || i === "exact" || i === "atLeast") && (n = i);
|
|
754
896
|
}
|
|
755
897
|
return t !== void 0 && Number.isFinite(t) ? {
|
|
@@ -757,10 +899,10 @@ function we(e) {
|
|
|
757
899
|
rule: n
|
|
758
900
|
} : void 0;
|
|
759
901
|
}
|
|
760
|
-
function
|
|
902
|
+
function je(e) {
|
|
761
903
|
return e.rule === "auto" ? String(e.value / 240) : `${e.value / 20}pt`;
|
|
762
904
|
}
|
|
763
|
-
function
|
|
905
|
+
function Me(e) {
|
|
764
906
|
let t = 0, n = 0;
|
|
765
907
|
for (let r of e) {
|
|
766
908
|
if (r["--az-hidden"] === "1") continue;
|
|
@@ -771,20 +913,20 @@ function Ee(e) {
|
|
|
771
913
|
}
|
|
772
914
|
//#endregion
|
|
773
915
|
//#region src/library/hujjat/docx-chrome.ts
|
|
774
|
-
async function
|
|
775
|
-
let a = Object.keys(e.files).filter((e) => /^word\/(header|footer)[^/]*\.xml$/.test(e)), o = Array.from(t.getElementsByTagNameNS(
|
|
916
|
+
async function Ne(e, t, n, r, i) {
|
|
917
|
+
let a = Object.keys(e.files).filter((e) => /^word\/(header|footer)[^/]*\.xml$/.test(e)), o = Array.from(t.getElementsByTagNameNS(V, "sectPr")).flatMap((e) => H(e).filter((e) => ["headerReference", "footerReference"].includes(e.localName)));
|
|
776
918
|
if (n === void 0) {
|
|
777
|
-
(a.length || o.length) &&
|
|
919
|
+
(a.length || o.length) && B(r, "header-footer-removed", "Для сохранения колонтитулов передайте page (или locales с page) в exportHujjat.", "loss", { stage: "export" });
|
|
778
920
|
return;
|
|
779
921
|
}
|
|
780
922
|
let s = n === null ? null : structuredClone(n);
|
|
781
923
|
if (!a.length && !o.length && !s?.header && !s?.footer) return s;
|
|
782
924
|
s ??= {};
|
|
783
|
-
let c = await
|
|
925
|
+
let c = await J(e, "word/_rels/document.xml.rels"), l = K(U((await J(e, "word/settings.xml"))?.documentElement, "evenAndOddHeaders")), u = Array.from(c?.documentElement.children ?? []), d = /* @__PURE__ */ new Set();
|
|
784
926
|
for (let n of ["header", "footer"]) {
|
|
785
927
|
let a = o.filter((e) => e.localName === `${n}Reference`);
|
|
786
|
-
if (l || a.some((e) =>
|
|
787
|
-
s[n] = null,
|
|
928
|
+
if (l || a.some((e) => W(e, "type") !== "default") || a.length > 1 || Array.from(t.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "sectPr")).some((e) => K(U(e, "titlePg")))) {
|
|
929
|
+
s[n] = null, B(r, "header-footer-variants-unsupported", "Разные колонтитулы разделов, первой или чётной страницы не помещаются в locale.page.", "loss", {
|
|
788
930
|
stage: "export",
|
|
789
931
|
location: { part: `page.${n}` }
|
|
790
932
|
});
|
|
@@ -797,28 +939,28 @@ async function De(e, t, n, r, i) {
|
|
|
797
939
|
}
|
|
798
940
|
let f = c.getAttributeNS("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id"), p = u.find((e) => e.getAttribute("Id") === f), m = p?.getAttribute("Target") ?? "", h = m.startsWith("/word/") ? m.slice(1) : `word/${m}`;
|
|
799
941
|
if (!p || p.getAttribute("TargetMode") === "External" || p.getAttribute("Type") !== `http://schemas.openxmlformats.org/officeDocument/2006/relationships/${n}` || !/^word\/[A-Za-z0-9_.-]+\.xml$/.test(h) || !e.file(h)) {
|
|
800
|
-
s[n] = null,
|
|
942
|
+
s[n] = null, B(r, "header-footer-reference-unsupported", "Колонтитул с неподдерживаемой ссылкой не сохранён.", "loss", {
|
|
801
943
|
stage: "export",
|
|
802
944
|
location: { part: `page.${n}` }
|
|
803
945
|
});
|
|
804
946
|
continue;
|
|
805
947
|
}
|
|
806
948
|
d.add(h);
|
|
807
|
-
let g = (await
|
|
808
|
-
!g || g.namespaceURI !== "http://schemas.openxmlformats.org/wordprocessingml/2006/main" || g.localName !== (n === "header" ? "hdr" : "ftr") ? (s[n] = null,
|
|
949
|
+
let g = (await J(e, h))?.documentElement;
|
|
950
|
+
!g || g.namespaceURI !== "http://schemas.openxmlformats.org/wordprocessingml/2006/main" || g.localName !== (n === "header" ? "hdr" : "ftr") ? (s[n] = null, B(r, "header-footer-reference-unsupported", "Структура колонтитула повреждена.", "loss", {
|
|
809
951
|
stage: "export",
|
|
810
952
|
location: { part: h }
|
|
811
953
|
})) : s[n] = { html: i(g, h) };
|
|
812
954
|
}
|
|
813
|
-
return a.some((e) => !d.has(e)) &&
|
|
955
|
+
return a.some((e) => !d.has(e)) && B(r, "header-footer-unused-parts", "В DOCX остались колонтитулы вне единственного поддерживаемого варианта.", "loss", { stage: "export" }), s;
|
|
814
956
|
}
|
|
815
957
|
//#endregion
|
|
816
958
|
//#region src/library/hujjat/server-page.ts
|
|
817
|
-
var
|
|
818
|
-
function
|
|
959
|
+
var Pe = 102400;
|
|
960
|
+
function Fe(e) {
|
|
819
961
|
if (e == null) return;
|
|
820
962
|
let t = (e) => {
|
|
821
|
-
throw new
|
|
963
|
+
throw new z(`Некорректное поле page.${e} в контракте Hujjat.`);
|
|
822
964
|
};
|
|
823
965
|
(typeof e != "object" || Array.isArray(e)) && t("object");
|
|
824
966
|
let n = e, r = [
|
|
@@ -852,13 +994,13 @@ function ke(e) {
|
|
|
852
994
|
e in n && r !== null && ((!r || typeof r != "object" || Array.isArray(r) || typeof r.html != "string") && t(`${e}.html`), new TextEncoder().encode(r.html).length > 102400 && t(`${e}.html (100 КиБ)`));
|
|
853
995
|
}
|
|
854
996
|
}
|
|
855
|
-
function
|
|
856
|
-
if (
|
|
997
|
+
function Ie(e, t) {
|
|
998
|
+
if (Fe(e), !e) return e;
|
|
857
999
|
let n = structuredClone(e);
|
|
858
1000
|
for (let e of ["header", "footer"]) {
|
|
859
1001
|
let r = n[e];
|
|
860
1002
|
if (!r || !r.html.trim()) continue;
|
|
861
|
-
let i =
|
|
1003
|
+
let i = ve(r.html);
|
|
862
1004
|
n[e] = { html: i.html }, t.variables = [.../* @__PURE__ */ new Set([...t.variables, ...i.variables])], t.warnings.push(...i.warnings.map((t) => ({
|
|
863
1005
|
...t,
|
|
864
1006
|
location: {
|
|
@@ -867,101 +1009,186 @@ function Ae(e, t) {
|
|
|
867
1009
|
}
|
|
868
1010
|
})));
|
|
869
1011
|
}
|
|
870
|
-
return
|
|
1012
|
+
return Fe(n), n;
|
|
871
1013
|
}
|
|
872
|
-
function
|
|
873
|
-
let n =
|
|
874
|
-
return e?.orientation === "landscape" && ([n.page.widthTwips, n.page.heightTwips] = [n.page.heightTwips, n.page.widthTwips], n.page.orientation = "landscape"),
|
|
1014
|
+
function Le(e, t = {}) {
|
|
1015
|
+
let n = R();
|
|
1016
|
+
return e?.orientation === "landscape" && ([n.page.widthTwips, n.page.heightTwips] = [n.page.heightTwips, n.page.widthTwips], n.page.orientation = "landscape"), R({
|
|
875
1017
|
...t,
|
|
876
1018
|
page: t.page ?? n.page
|
|
877
1019
|
});
|
|
878
1020
|
}
|
|
879
1021
|
//#endregion
|
|
1022
|
+
//#region src/library/hujjat/docx-images.ts
|
|
1023
|
+
var Re = "http://schemas.openxmlformats.org/officeDocument/2006/relationships", X = "http://schemas.openxmlformats.org/drawingml/2006/main", ze = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", Be = "http://schemas.openxmlformats.org/drawingml/2006/picture";
|
|
1024
|
+
async function Ve(e) {
|
|
1025
|
+
return new Promise((t, n) => {
|
|
1026
|
+
let r = [], i = 0, a = !1, o = e.internalStream("uint8array");
|
|
1027
|
+
o.on("data", (e) => {
|
|
1028
|
+
a || (i += e.length, i > 262144 ? (a = !0, o.pause(), n(/* @__PURE__ */ Error("Изображение DOCX превышает 256 КиБ."))) : r.push(e));
|
|
1029
|
+
}).on("error", n).on("end", () => {
|
|
1030
|
+
if (a) return;
|
|
1031
|
+
let e = new Uint8Array(i), n = 0;
|
|
1032
|
+
for (let t of r) e.set(t, n), n += t.length;
|
|
1033
|
+
t(e);
|
|
1034
|
+
}).resume();
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
async function He(e) {
|
|
1038
|
+
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = Object.keys(e.files).filter((e) => /^word\/(?:document|header[^/]*|footer[^/]*)\.xml$/.test(e)), i = 0, a = 0;
|
|
1039
|
+
for (let o of r) {
|
|
1040
|
+
let r = (await J(e, o))?.documentElement, s = new Set(Array.from(r?.getElementsByTagNameNS(X, "blip") ?? []).map((e) => e.getAttributeNS(Re, "embed")).filter((e) => !!e));
|
|
1041
|
+
if (!s.size) continue;
|
|
1042
|
+
let c = (await J(e, `word/_rels/${o.slice(5)}.rels`))?.documentElement;
|
|
1043
|
+
for (let r of s) {
|
|
1044
|
+
let s = `${o}#${r}`;
|
|
1045
|
+
try {
|
|
1046
|
+
if (++a > 96) throw Error("В DOCX слишком много изображений.");
|
|
1047
|
+
let o = Array.from(c?.children ?? []).filter((e) => e.getAttribute("Id") === r), l = o[0], u = l?.getAttribute("Target") ?? "", d = u.startsWith("/word/media/") ? u.slice(1) : `word/${u}`;
|
|
1048
|
+
if (o.length !== 1 || l?.getAttribute("TargetMode") === "External" || l?.getAttribute("Type") !== "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" || !/^word\/media\/[A-Za-z0-9_.-]+$/.test(d) || !e.file(d)) throw Error("Изображение DOCX должно быть встроенным ресурсом PNG/JPEG.");
|
|
1049
|
+
let f = n.get(d);
|
|
1050
|
+
if (!f) {
|
|
1051
|
+
let t = await Ve(e.file(d));
|
|
1052
|
+
if (i += t.length, i > 2097152) throw Error("Общий размер изображений DOCX превышает 2 МиБ.");
|
|
1053
|
+
let r = ee(t, t[0] === 137 ? "image/png" : "image/jpeg");
|
|
1054
|
+
te(r), f = { src: r }, n.set(d, f);
|
|
1055
|
+
}
|
|
1056
|
+
t.set(s, f);
|
|
1057
|
+
} catch (e) {
|
|
1058
|
+
t.set(s, { error: e instanceof Error ? e.message : "Некорректное изображение DOCX." });
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
return t;
|
|
1063
|
+
}
|
|
1064
|
+
function Ue(e) {
|
|
1065
|
+
if (e.namespaceURI !== X) return !1;
|
|
1066
|
+
if (["xfrm", "prstGeom"].includes(e.localName)) return !0;
|
|
1067
|
+
if (["noFill", "effectLst"].includes(e.localName)) return e.children.length === 0;
|
|
1068
|
+
if (e.localName !== "ln" || e.children.length !== 1) return !1;
|
|
1069
|
+
let t = e.children[0];
|
|
1070
|
+
return t.namespaceURI === X && t.localName === "noFill" && t.children.length === 0;
|
|
1071
|
+
}
|
|
1072
|
+
function We(e, t, n, r) {
|
|
1073
|
+
let i = (t, n) => Array.from(e.getElementsByTagNameNS(t, n)), a = i(ze, "inline"), o = i(Be, "pic");
|
|
1074
|
+
if (!a.length && !o.length) return r("drawing-removed", "Фигуры и текстовые блоки Word не поддерживаются HTML-блоком Hujjat."), "";
|
|
1075
|
+
let s = (e) => (r("image-layout-unsupported", e), "");
|
|
1076
|
+
if (a.length !== 1 || o.length !== 1 || i(ze, "anchor").length) return s("Поддерживаются изображения в строке. Плавающее изображение нужно преобразовать в строчное.");
|
|
1077
|
+
let c = i(X, "srcRect").some((e) => [
|
|
1078
|
+
"l",
|
|
1079
|
+
"r",
|
|
1080
|
+
"t",
|
|
1081
|
+
"b"
|
|
1082
|
+
].some((t) => Number(e.getAttribute(t) || 0) !== 0)), l = i(X, "xfrm").some((e) => Number(e.getAttribute("rot") || 0) !== 0 || ["flipH", "flipV"].some((t) => ["1", "true"].includes(e.getAttribute(t) ?? ""))), u = i(X, "effectLst").some((e) => e.children.length) || i(X, "effectDag").length || i(X, "tile").length || i(X, "hlinkClick").length || i(X, "hlinkHover").length, d = i(Be, "spPr").some((e) => Array.from(e.children).some((e) => !Ue(e))) || i(X, "prstGeom").some((e) => e.getAttribute("prst") !== "rect") || i(X, "fillRect").some((e) => Array.from(e.attributes).some((e) => Number(e.value) !== 0)), f = i(X, "blip");
|
|
1083
|
+
if (c || l || u || d || f.some((e) => Array.from(e.children).some((e) => e.localName !== "extLst"))) return s("Обрезка, поворот, эффекты и ссылки изображения не сохраняются в Hujjat. Сначала примените их к самому файлу.");
|
|
1084
|
+
let p = Array.from(a[0].children).filter((e) => e.namespaceURI === ze && e.localName === "extent"), m = p[0], h = Number(m?.getAttribute("cx")) / 12700, g = Number(m?.getAttribute("cy")) / 12700;
|
|
1085
|
+
if (p.length !== 1 || !Number.isFinite(h) || !Number.isFinite(g) || h <= 0 || g <= 0 || h > 600 || g > 600) return s("Размер изображения должен быть больше нуля и не превышать 600 pt.");
|
|
1086
|
+
let _ = f[0], v = _?.getAttributeNS(Re, "embed"), y = n.get(`${t}#${v}`);
|
|
1087
|
+
if (f.length !== 1 || _?.hasAttributeNS("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "link") || !y || "error" in y) return r("image-invalid", y && "error" in y ? y.error : "Не удалось прочитать встроенное изображение DOCX."), "";
|
|
1088
|
+
let b = i(ze, "docPr")[0];
|
|
1089
|
+
if ([b, ...i(Be, "cNvPr")].some((e) => ["1", "true"].includes(e?.getAttribute("hidden") ?? ""))) return r("hidden-image-removed", "Скрытое изображение Word исключено из HTML."), "";
|
|
1090
|
+
let x = Array.from(b?.getAttribute("descr") || b?.getAttribute("title") || "").slice(0, 500).join("");
|
|
1091
|
+
return `<img src="${y.src}" alt="${Se(x)}" style="width:${Number(h.toFixed(4))}pt;height:${Number(g.toFixed(4))}pt">`;
|
|
1092
|
+
}
|
|
1093
|
+
function Ge(e, t, n, r, i) {
|
|
1094
|
+
let a = Math.round(n * 12700), o = Math.round(r * 12700);
|
|
1095
|
+
return `<w:r><w:drawing><wp:inline xmlns:wp="${ze}" xmlns:a="${X}" xmlns:pic="${Be}" xmlns:r="${Re}" distT="0" distB="0" distL="0" distR="0"><wp:extent cx="${a}" cy="${o}"/><wp:docPr id="${e}" name="Image ${e}" descr="${Se(i)}"/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic><a:graphicData uri="${Be}"><pic:pic><pic:nvPicPr><pic:cNvPr id="${e}" name="Image ${e}"/><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${t}"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${a}" cy="${o}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;
|
|
1096
|
+
}
|
|
1097
|
+
//#endregion
|
|
880
1098
|
//#region src/library/hujjat/docx-to-html.ts
|
|
881
|
-
async function
|
|
882
|
-
if (e.byteLength > 31457280) throw new
|
|
1099
|
+
async function Ke(e, t = {}, n) {
|
|
1100
|
+
if (e.byteLength > 31457280) throw new z("DOCX превышает 30 МиБ.");
|
|
883
1101
|
let r;
|
|
884
1102
|
try {
|
|
885
|
-
r = await
|
|
1103
|
+
r = await b.loadAsync(e);
|
|
886
1104
|
} catch {
|
|
887
|
-
throw new
|
|
1105
|
+
throw new z("Повреждённый файл DOCX.");
|
|
888
1106
|
}
|
|
889
1107
|
let i = Object.keys(r.files);
|
|
890
|
-
if (i.length > 2e3) throw new
|
|
891
|
-
if (i.some((e) => /vbaProject\.bin$/i.test(e))) throw new
|
|
892
|
-
let a = await
|
|
893
|
-
if (!Array.from(a?.getElementsByTagNameNS("*", "Override") ?? []).some((e) => e.getAttribute("PartName") === "/word/document.xml" && e.getAttribute("ContentType") === "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")) throw new
|
|
894
|
-
let o = await
|
|
895
|
-
if (!l) throw new
|
|
896
|
-
let u = [], d =
|
|
1108
|
+
if (i.length > 2e3) throw new z("В DOCX более 2000 частей.");
|
|
1109
|
+
if (i.some((e) => /vbaProject\.bin$/i.test(e))) throw new z("DOCX с макросами не поддерживается.");
|
|
1110
|
+
let a = await J(r, "[Content_Types].xml");
|
|
1111
|
+
if (!Array.from(a?.getElementsByTagNameNS("*", "Override") ?? []).some((e) => e.getAttribute("PartName") === "/word/document.xml" && e.getAttribute("ContentType") === "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")) throw new z("Файл не является обычным DOCX.");
|
|
1112
|
+
let o = await J(r, "word/document.xml"), s = await J(r, "word/styles.xml"), c = await J(r, "word/numbering.xml"), l = U(o?.documentElement, "body");
|
|
1113
|
+
if (!l) throw new z("В DOCX нет поддерживаемой структуры документа.");
|
|
1114
|
+
let u = [], d = await He(r), f = ke(l, t, u, n === void 0 ? void 0 : Le(n).page), p, m = (e, t, n = "warning", r, i) => B(u, e, t, n, {
|
|
897
1115
|
stage: "export",
|
|
898
|
-
location:
|
|
1116
|
+
location: p ? { ...p } : void 0,
|
|
899
1117
|
before: r,
|
|
900
1118
|
after: i
|
|
901
|
-
}),
|
|
902
|
-
i.some((e) => /^word\/comments/.test(e)) &&
|
|
903
|
-
let
|
|
1119
|
+
}), h = (e, t) => m(e, t, "loss"), g = new Map(Array.from(l.getElementsByTagNameNS(V, "p")).map((e, t) => [e, t])), _ = new Map(Array.from(l.getElementsByTagNameNS(V, "tbl")).map((e, t) => [e, t])), v = "word/document.xml", y = /* @__PURE__ */ new Map(), x = 0;
|
|
1120
|
+
i.some((e) => /^word\/comments/.test(e)) && h("review-removed", "Комментарии Word не сохраняются в HTML.");
|
|
1121
|
+
let S = U(s?.documentElement, "docDefaults"), C = {
|
|
904
1122
|
"margin-top": "0pt",
|
|
905
1123
|
"margin-bottom": "8px",
|
|
906
|
-
...
|
|
907
|
-
},
|
|
1124
|
+
...Ee(U(U(S, "pPrDefault"), "pPr"))
|
|
1125
|
+
}, w = {
|
|
908
1126
|
"font-family": "freeserif",
|
|
909
1127
|
"font-size": "12pt",
|
|
910
1128
|
color: "#111111",
|
|
911
|
-
...
|
|
912
|
-
},
|
|
913
|
-
function
|
|
1129
|
+
...Y(U(U(S, "rPrDefault"), "rPr"))
|
|
1130
|
+
}, T = new Map(H(s?.documentElement, "style").map((e) => [W(e, "styleId"), e]));
|
|
1131
|
+
function E(e, t = /* @__PURE__ */ new Set()) {
|
|
914
1132
|
if (!e || t.has(e) || t.size > 30) return [];
|
|
915
1133
|
t.add(e);
|
|
916
|
-
let n =
|
|
917
|
-
return n ? [...
|
|
1134
|
+
let n = T.get(e);
|
|
1135
|
+
return n ? [...E(G(n, "basedOn"), t), n] : [];
|
|
918
1136
|
}
|
|
919
|
-
let
|
|
920
|
-
if (++
|
|
1137
|
+
let D = H(s?.documentElement, "style").find((e) => W(e, "type") === "paragraph" && W(e, "default") === "1"), O = new Map(H(c?.documentElement, "num").map((e) => [W(e, "numId"), e])), k = new Map(H(c?.documentElement, "abstractNum").map((e) => [W(e, "abstractNumId"), e])), A = /* @__PURE__ */ new Set(), j = !1, M = 0, N = (e) => {
|
|
1138
|
+
if (++M > 5e4 || e > 80) throw new z("DOCX слишком сложный для HTML-адаптера.");
|
|
921
1139
|
};
|
|
922
|
-
function
|
|
923
|
-
if (
|
|
1140
|
+
function P(e, t, n) {
|
|
1141
|
+
if (N(n), e.namespaceURI !== "http://schemas.openxmlformats.org/wordprocessingml/2006/main") return h("unsupported-content", "Нестандартный объект Word не сохраняется в HTML."), "";
|
|
924
1142
|
switch (e.localName) {
|
|
925
|
-
case "t": return
|
|
926
|
-
let t = e === " " &&
|
|
927
|
-
return
|
|
1143
|
+
case "t": return Se(Array.from(e.textContent ?? "").map((e) => {
|
|
1144
|
+
let t = e === " " && j ? "\xA0" : e;
|
|
1145
|
+
return j = e === " ", t;
|
|
928
1146
|
}).join(""));
|
|
929
|
-
case "tab": return
|
|
930
|
-
case "br": return
|
|
1147
|
+
case "tab": return h("tab-normalized", "Положение текста после табуляции потеряно в HTML. Для точного расположения используйте исходный DOCX."), " ";
|
|
1148
|
+
case "br": return W(e, "type") === "page" ? "<div style=\"page-break-before:always\"></div>" : "<br>";
|
|
931
1149
|
case "cr": return "<br>";
|
|
932
1150
|
case "noBreakHyphen": return "‑";
|
|
933
1151
|
case "softHyphen": return "";
|
|
934
1152
|
case "r": {
|
|
935
|
-
|
|
936
|
-
...
|
|
937
|
-
runIndex:
|
|
1153
|
+
p = {
|
|
1154
|
+
...p,
|
|
1155
|
+
runIndex: x++
|
|
938
1156
|
};
|
|
939
|
-
let r =
|
|
940
|
-
if (i["--az-hidden"] === "1") return
|
|
941
|
-
Number(i["--az-position"]) &&
|
|
1157
|
+
let r = U(e, "rPr"), i = Y(r, Te(t, E(G(r, "rStyle")).map((e) => U(e, "rPr"))));
|
|
1158
|
+
if (i["--az-hidden"] === "1") return h("hidden-text-removed", "Скрытый текст Word исключён из HTML."), "";
|
|
1159
|
+
Number(i["--az-position"]) && m("baseline-shift-lost", "Вертикальное смещение фрагмента Word не представлено в HTML.", "loss", Number(i["--az-position"]) / 2, 0);
|
|
942
1160
|
let a = Object.fromEntries(Object.entries(i).filter(([e]) => !e.startsWith("--az-")));
|
|
943
|
-
return
|
|
1161
|
+
return H(e).filter((e) => e.localName !== "rPr").map((e) => P(e, i, n + 1)).join("").split(/(<div style="page-break-before:always"><\/div>)/).map((e) => e.startsWith("<div ") ? e : e ? `<span${Ce(a)}>${e}</span>` : "").join("");
|
|
944
1162
|
}
|
|
945
1163
|
case "hyperlink":
|
|
946
|
-
|
|
1164
|
+
B(u, "hyperlink-removed", "Ссылки сохраняются как текст без перехода.");
|
|
947
1165
|
break;
|
|
948
1166
|
case "del":
|
|
949
|
-
case "moveFrom": return
|
|
1167
|
+
case "moveFrom": return h("review-removed", "Исправления Word преобразуются в итоговый текст; история теряется."), "";
|
|
950
1168
|
case "ins":
|
|
951
1169
|
case "moveTo":
|
|
952
|
-
|
|
1170
|
+
h("review-removed", "Исправления Word преобразуются в итоговый текст; история теряется.");
|
|
953
1171
|
break;
|
|
954
|
-
case "drawing":
|
|
1172
|
+
case "drawing": {
|
|
1173
|
+
let t = y.get(v) ?? {
|
|
1174
|
+
count: 0,
|
|
1175
|
+
bytes: 0
|
|
1176
|
+
};
|
|
1177
|
+
if (t.count >= 32) throw new z("В одном HTML-блоке допускается не более 32 изображений.");
|
|
1178
|
+
let n = We(e, v, d, h);
|
|
1179
|
+
if (n && (t.count++, t.bytes += new TextEncoder().encode(n).length, y.set(v, t)), t.bytes > (v === "word/document.xml" ? 1048576 : 102400)) throw new z("Встроенные изображения превышают лимит HTML: 1 МБ на тело, 100 КиБ на колонтитул.");
|
|
1180
|
+
return j = !1, n;
|
|
1181
|
+
}
|
|
955
1182
|
case "pict":
|
|
956
|
-
case "object": return
|
|
1183
|
+
case "object": return h("drawing-removed", "Устаревшие рисунки, фигуры и текстовые блоки Word не поддерживаются HTML-блоком Hujjat."), "";
|
|
957
1184
|
case "footnoteReference":
|
|
958
|
-
case "endnoteReference": return
|
|
1185
|
+
case "endnoteReference": return h("notes-removed", "Сноски Word не поддерживаются HTML-блоком."), "";
|
|
959
1186
|
case "instrText":
|
|
960
|
-
case "fldChar": return
|
|
1187
|
+
case "fldChar": return h("field-flattened", "Поля Word сохраняют только имеющийся текстовый результат."), "";
|
|
961
1188
|
case "fldSimple":
|
|
962
|
-
|
|
1189
|
+
h("field-flattened", "Поля Word сохраняют только имеющийся текстовый результат.");
|
|
963
1190
|
break;
|
|
964
|
-
case "sdt": return
|
|
1191
|
+
case "sdt": return h("content-control-flattened", "Элементы управления Word преобразуются в обычный текст."), U(e, "sdtContent") ? P(U(e, "sdtContent"), t, n + 1) : "";
|
|
965
1192
|
case "sdtContent":
|
|
966
1193
|
case "smartTag":
|
|
967
1194
|
case "customXml": break;
|
|
@@ -972,53 +1199,53 @@ async function Me(e, t = {}, n) {
|
|
|
972
1199
|
case "commentRangeStart":
|
|
973
1200
|
case "commentRangeEnd":
|
|
974
1201
|
case "commentReference": return "";
|
|
975
|
-
default:
|
|
1202
|
+
default: h("unsupported-inline", `Элемент Word ${e.localName} не поддерживается HTML-адаптером.`);
|
|
976
1203
|
}
|
|
977
|
-
return Array.from(e.children).map((e) =>
|
|
978
|
-
}
|
|
979
|
-
function
|
|
980
|
-
|
|
981
|
-
part:
|
|
982
|
-
paragraphIndex:
|
|
983
|
-
},
|
|
984
|
-
let r =
|
|
985
|
-
if (
|
|
1204
|
+
return Array.from(e.children).map((e) => P(e, t, n + 1)).join("");
|
|
1205
|
+
}
|
|
1206
|
+
function ee(e, n) {
|
|
1207
|
+
p = {
|
|
1208
|
+
part: v,
|
|
1209
|
+
paragraphIndex: g.get(e)
|
|
1210
|
+
}, x = 0;
|
|
1211
|
+
let r = U(e, "pPr"), i = E(G(r, "pStyle") || W(D, "styleId")), a = U(r, "spacing");
|
|
1212
|
+
if (G(r, "pStyle") === "AzHujjatPageBoundary" && K(U(r, "pageBreakBefore")) && Array.from(r?.children ?? []).every((e) => e.namespaceURI === "http://schemas.openxmlformats.org/wordprocessingml/2006/main" && [
|
|
986
1213
|
"pStyle",
|
|
987
1214
|
"pageBreakBefore",
|
|
988
1215
|
"spacing"
|
|
989
|
-
].includes(e.localName)) &&
|
|
990
|
-
let o = [...i.map((e) =>
|
|
991
|
-
if (l && l !== "0" ||
|
|
992
|
-
let e =
|
|
993
|
-
s["margin-left"] =
|
|
1216
|
+
].includes(e.localName)) && W(a, "before") === "0" && W(a, "after") === "0" && W(a, "line") === "1" && W(a, "lineRule") === "exact" && Array.from(e.children).every((e) => e === r)) return { html: "<div style=\"page-break-before:always\"></div>" };
|
|
1217
|
+
let o = [...i.map((e) => U(e, "pPr")), r], s = Object.assign({}, C, ...o.map(Ee)), c = o.map((e) => U(e, "numPr")).filter(Boolean).at(-1), l = G(c, "numId"), d = Number(G(c, "ilvl") || 0), f = G(r, "pStyle") === "AzHujjatListContinuation";
|
|
1218
|
+
if (l && l !== "0" || f) {
|
|
1219
|
+
let e = O.get(l), t = Ee(U(H(k.get(G(e, "abstractNumId")), "lvl").find((e) => W(e, "ilvl") === String(d)), "pPr"));
|
|
1220
|
+
s["margin-left"] = q((parseFloat(s["margin-left"] ?? t["margin-left"] ?? "0") || 0) * 20 - 360), s["text-indent"] ??= t["text-indent"] ?? "0pt";
|
|
994
1221
|
}
|
|
995
1222
|
parseFloat(s["text-indent"] ?? "0") < 0 && parseFloat(s["margin-left"] ?? "0") >= 0 && (s["padding-left"] = s["margin-left"] ?? "0pt", s["margin-left"] = "0pt");
|
|
996
|
-
let
|
|
997
|
-
|
|
998
|
-
let
|
|
999
|
-
|
|
1000
|
-
...
|
|
1223
|
+
let _ = Ae([U(U(S, "pPrDefault"), "pPr"), ...o]);
|
|
1224
|
+
_ && (s["line-height"] = je(_));
|
|
1225
|
+
let y = Te(w, i.map((e) => U(e, "rPr"))), b = Y(U(r, "rPr"), y);
|
|
1226
|
+
b["--az-hidden"] === "1" && (m("hidden-paragraph-mark-lost", "Скрытый знак абзаца нельзя представить в HTML; его отдельный шрифт заменён стилем абзаца.", "loss", "hidden", "visible paragraph style"), b = {
|
|
1227
|
+
...y,
|
|
1001
1228
|
"--az-hidden": "0"
|
|
1002
|
-
}), s["font-family"] =
|
|
1003
|
-
let
|
|
1004
|
-
let t =
|
|
1005
|
-
return
|
|
1006
|
-
}),
|
|
1007
|
-
|
|
1008
|
-
let
|
|
1009
|
-
|
|
1229
|
+
}), s["font-family"] = b["font-family"], s["font-size"] = b["font-size"];
|
|
1230
|
+
let T = Array.from(e.getElementsByTagNameNS(V, "r")).map((e) => {
|
|
1231
|
+
let t = U(e, "rPr");
|
|
1232
|
+
return Y(t, Te(y, E(G(t, "rStyle")).map((e) => U(e, "rPr"))));
|
|
1233
|
+
}), A = s["line-height"];
|
|
1234
|
+
A && (/^\d*\.?\d+$/.test(A) ? Number(A) < 1 : A.endsWith("pt") && parseFloat(A) < Me([b, ...T])) && (t.lineSpacingPolicy === "preserve" ? m("line-height-overlap-risk", "Авторский тесный интервал сохранён; строки могут перекрываться. Фактические метрики шрифта требуют проверки.", "warning", A, A) : (s["line-height"] = /^\d*\.?\d+$/.test(A) ? "1" : "normal", m("line-height-normalized", "Тесный межстрочный интервал нормализован по размерам фрагментов. Проверьте переносы на используемых шрифтах.", "warning", A, s["line-height"]))), A?.endsWith("pt") && t.lineSpacingPolicy !== "preserve" && m("line-height-metrics-estimated", "Проверка интервала использует размеры и смещения фрагментов, а не метрики установленного шрифта. Результат нормализации требует проверки на используемых шрифтах.", "warning", A, s["line-height"]), _ && _.rule !== "auto" && m("line-rule-lost", "CSS line-height не сохраняет различие правил Word exact и atLeast.", "warning", _.rule, "CSS line-height"), o.some((e) => U(e, "tabs")) && h("tab-stops-removed", "Позиции, типы и заполнители табуляции не поддерживаются HTML-блоком.");
|
|
1235
|
+
let M = [U(U(S, "pPrDefault"), "pPr"), ...o].map((e) => U(e, "widowControl")).filter(Boolean).at(-1);
|
|
1236
|
+
M && B(u, "widow-control-lost", "Правило висячих строк Word не представлено в HTML-контракте.", "loss", {
|
|
1010
1237
|
stage: "export",
|
|
1011
|
-
location: { ...
|
|
1012
|
-
before:
|
|
1238
|
+
location: { ...p },
|
|
1239
|
+
before: K(M),
|
|
1013
1240
|
after: null
|
|
1014
|
-
}),
|
|
1015
|
-
let
|
|
1241
|
+
}), j = !0;
|
|
1242
|
+
let N = Array.from(e.children).filter((e) => e !== r).map((e) => P(e, y, n + 1)).join("").split("<div style=\"page-break-before:always\"></div>").map((e, t) => `${t ? "<div style=\"page-break-before:always\"></div>" : ""}<p${Ce(s)}>${e || "<br>"}</p>`).join("");
|
|
1016
1243
|
if (l && l !== "0") {
|
|
1017
|
-
let e =
|
|
1018
|
-
if (!t) return
|
|
1019
|
-
let n =
|
|
1020
|
-
return (!["decimal", "bullet"].includes(n) || d ||
|
|
1021
|
-
html:
|
|
1244
|
+
let e = O.get(l), t = H(k.get(G(e, "abstractNumId")), "lvl").find((e) => W(e, "ilvl") === String(d));
|
|
1245
|
+
if (!t) return B(u, "numbering-unsupported", "Не найдена нумерация списка.", "loss"), { html: N };
|
|
1246
|
+
let n = G(t, "numFmt");
|
|
1247
|
+
return (!["decimal", "bullet"].includes(n) || d || G(t, "start") && G(t, "start") !== "1" || U(e, "lvlOverride")) && B(u, "numbering-normalized", "Сложная нумерация/начальное число списка заменены обычным HTML-списком.", "loss"), {
|
|
1248
|
+
html: N,
|
|
1022
1249
|
list: {
|
|
1023
1250
|
id: l,
|
|
1024
1251
|
level: Math.min(d, 8),
|
|
@@ -1027,112 +1254,112 @@ async function Me(e, t = {}, n) {
|
|
|
1027
1254
|
};
|
|
1028
1255
|
}
|
|
1029
1256
|
return {
|
|
1030
|
-
html:
|
|
1031
|
-
continuation:
|
|
1257
|
+
html: N,
|
|
1258
|
+
continuation: G(r, "pStyle") === "AzHujjatListContinuation"
|
|
1032
1259
|
};
|
|
1033
1260
|
}
|
|
1034
|
-
function
|
|
1035
|
-
|
|
1036
|
-
let n =
|
|
1037
|
-
part:
|
|
1038
|
-
tableIndex:
|
|
1261
|
+
function te(e, t) {
|
|
1262
|
+
N(t);
|
|
1263
|
+
let n = U(e, "tblPr"), r = G(n, "tblStyle"), i = {
|
|
1264
|
+
part: v,
|
|
1265
|
+
tableIndex: _.get(e)
|
|
1039
1266
|
};
|
|
1040
|
-
|
|
1041
|
-
let a =
|
|
1042
|
-
o.length && !
|
|
1043
|
-
let
|
|
1267
|
+
p = i, U(n, "tblpPr") && h("floating-table-position-lost", "Плавающее размещение таблицы Word не поддерживается текущим HTML-контрактом; таблица остаётся в потоке документа."), r && B(u, "table-style-normalized", "Условные стили таблиц Word могут отличаться; проверьте границы и заливку.");
|
|
1268
|
+
let a = U(n, "tblBorders"), o = H(U(e, "tblGrid"), "gridCol").map((e) => Number(W(e, "w"))), s = W(U(n, "tblLayout"), "type") === "fixed", c = H(e, "tr"), l = /* @__PURE__ */ new Map(), d = Math.max(1, ...c.map((e) => H(e, "tc").reduce((e, t) => e + Number(G(U(t, "tcPr"), "gridSpan") || 1), 0))), f = o.length === d && o.every((e) => Number.isFinite(e) && e > 0);
|
|
1269
|
+
o.length && !f && h("table-grid-invalid", "Явная сетка Word содержит некорректные ширины или не совпадает с ячейками.");
|
|
1270
|
+
let m = [], g = [], y = 0;
|
|
1044
1271
|
c.forEach((e, r) => {
|
|
1045
|
-
let
|
|
1272
|
+
let p = U(e, "trPr"), _ = {}, v = {
|
|
1046
1273
|
...i,
|
|
1047
1274
|
rowIndex: r
|
|
1048
|
-
}, b =
|
|
1049
|
-
b &&
|
|
1275
|
+
}, b = U(p, "trHeight");
|
|
1276
|
+
b && W(b, "val") && W(b, "hRule") !== "auto" && (_.height = q(W(b, "val")), W(b, "hRule") === "exact" && B(u, "table-row-height-rule-lost", "Высота строки HTML задаёт минимум; правило Word exact станет atLeast.", "warning", {
|
|
1050
1277
|
stage: "export",
|
|
1051
|
-
location:
|
|
1278
|
+
location: v,
|
|
1052
1279
|
before: "exact",
|
|
1053
1280
|
after: "atLeast"
|
|
1054
|
-
})),
|
|
1281
|
+
})), U(p, "cantSplit") && (_["page-break-inside"] = K(U(p, "cantSplit")) ? "avoid" : "auto"), K(U(p, "tblHeader")) && (r === y ? y++ : B(u, "table-header-not-contiguous", "Повторяемая шапка вне начала таблицы не переносится в HTML.", "warning", {
|
|
1055
1282
|
stage: "export",
|
|
1056
|
-
location:
|
|
1057
|
-
})),
|
|
1283
|
+
location: v
|
|
1284
|
+
})), g.push(_);
|
|
1058
1285
|
let x = 0, S = [];
|
|
1059
|
-
Number(
|
|
1060
|
-
for (let i of
|
|
1061
|
-
let e =
|
|
1062
|
-
if (
|
|
1063
|
-
if (
|
|
1286
|
+
Number(G(U(e, "trPr"), "gridBefore") || 0) && h("table-grid-unsupported", "Таблица с пропущенными начальными ячейками требует проверки.");
|
|
1287
|
+
for (let i of H(e, "tc")) {
|
|
1288
|
+
let e = U(i, "tcPr"), p = Number(G(e, "gridSpan") || 1), m = U(e, "vMerge");
|
|
1289
|
+
if (U(e, "hMerge") && h("legacy-table-merge", "Старый формат горизонтального объединения hMerge требует преобразования в gridSpan."), !Number.isInteger(p) || p < 1 || p > 100) throw new z("Объединение таблицы превышает предел 100 ячеек.");
|
|
1290
|
+
if (m && W(m) !== "restart" && l.has(x) && l.get(x).span === p) {
|
|
1064
1291
|
let e = l.get(x);
|
|
1065
|
-
if (e.rowSpan++, e.rowSpan > 100) throw new
|
|
1066
|
-
i.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "t").length && i.textContent?.trim() &&
|
|
1292
|
+
if (e.rowSpan++, e.rowSpan > 100) throw new z("Объединение таблицы превышает 100 строк.");
|
|
1293
|
+
i.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "t").length && i.textContent?.trim() && h("table-merge-content", "Текст в продолжении объединённой ячейки требует ручной проверки."), x += p;
|
|
1067
1294
|
continue;
|
|
1068
1295
|
}
|
|
1069
|
-
let g = {},
|
|
1070
|
-
|
|
1071
|
-
let y = o.slice(x, x +
|
|
1072
|
-
if ((
|
|
1296
|
+
let g = {}, _ = U(e, "tcW");
|
|
1297
|
+
W(_, "type") === "dxa" ? g.width = q(W(_, "w")) : W(_, "type") === "pct" && (g.width = `${Number(W(_, "w")) / 50}%`);
|
|
1298
|
+
let y = o.slice(x, x + p);
|
|
1299
|
+
if ((f || s || !g.width) && y.length === p && y.every((e) => Number.isFinite(e) && e > 0)) {
|
|
1073
1300
|
let e = y.reduce((e, t) => e + t, 0);
|
|
1074
|
-
if (!s &&
|
|
1075
|
-
let t = Number(
|
|
1076
|
-
(!Number.isFinite(t) || t <= 0 || Math.abs(t - e) > 2 + 1e-7) &&
|
|
1301
|
+
if (!s && f && ["dxa", "pct"].includes(W(_, "type"))) {
|
|
1302
|
+
let t = Number(W(_, "w")) * (W(_, "type") === "pct" ? o.reduce((e, t) => e + t, 0) / 5e3 : 1);
|
|
1303
|
+
(!Number.isFinite(t) || t <= 0 || Math.abs(t - e) > 2 + 1e-7) && B(u, "table-width-normalized", "Ширина ячейки автоматической таблицы приведена к явной сетке колонок.", "loss", {
|
|
1077
1304
|
stage: "export",
|
|
1078
|
-
location:
|
|
1079
|
-
before: Number.isFinite(t) ? t :
|
|
1305
|
+
location: v,
|
|
1306
|
+
before: Number.isFinite(t) ? t : W(_, "w"),
|
|
1080
1307
|
after: e
|
|
1081
1308
|
});
|
|
1082
1309
|
}
|
|
1083
|
-
g.width =
|
|
1310
|
+
g.width = q(e);
|
|
1084
1311
|
}
|
|
1085
|
-
let b = U(
|
|
1086
|
-
/^[\da-f]{6}$/i.test(b) && (g["background-color"] = "#" + b),
|
|
1312
|
+
let b = W(U(e, "shd"), "fill");
|
|
1313
|
+
/^[\da-f]{6}$/i.test(b) && (g["background-color"] = "#" + b), G(e, "vAlign") && (g["vertical-align"] = G(e, "vAlign") === "center" ? "middle" : G(e, "vAlign"));
|
|
1087
1314
|
for (let t of [
|
|
1088
1315
|
"top",
|
|
1089
1316
|
"right",
|
|
1090
1317
|
"bottom",
|
|
1091
1318
|
"left"
|
|
1092
1319
|
]) {
|
|
1093
|
-
let i =
|
|
1320
|
+
let i = U(U(e, "tcBorders"), t), o = t === "top" && r > 0 || t === "bottom" && r < c.length - 1 ? "insideH" : t === "left" && x > 0 || t === "right" && x + p < d ? "insideV" : t, s = U(a, o), l = De(i ?? s);
|
|
1094
1321
|
l && (g[`border-${t}`] = l);
|
|
1095
|
-
let u =
|
|
1096
|
-
u &&
|
|
1322
|
+
let u = U(U(e, "tcMar"), t) ?? U(U(n, "tblCellMar"), t);
|
|
1323
|
+
u && W(u, "w") && (g[`padding-${t}`] = q(W(u, "w")));
|
|
1097
1324
|
}
|
|
1098
1325
|
let C = {
|
|
1099
1326
|
element: i,
|
|
1100
1327
|
rowSpan: 1,
|
|
1101
|
-
span:
|
|
1328
|
+
span: p,
|
|
1102
1329
|
html: F(i, t + 1),
|
|
1103
1330
|
css: g
|
|
1104
1331
|
};
|
|
1105
|
-
for (let e = x; e < x +
|
|
1106
|
-
|
|
1332
|
+
for (let e = x; e < x + p; e++) l.delete(e);
|
|
1333
|
+
m && W(m) === "restart" && l.set(x, C), S.push(C), x += p;
|
|
1107
1334
|
}
|
|
1108
1335
|
for (let e of l.keys()) e >= x && l.delete(e);
|
|
1109
|
-
|
|
1336
|
+
m.push(S);
|
|
1110
1337
|
});
|
|
1111
|
-
let b =
|
|
1112
|
-
width:
|
|
1338
|
+
let b = U(n, "tblW"), x = {
|
|
1339
|
+
width: W(b, "type") === "dxa" ? q(W(b, "w")) : W(b, "type") === "pct" ? `${Number(W(b, "w")) / 50}%` : "100%",
|
|
1113
1340
|
"border-collapse": "collapse"
|
|
1114
|
-
}, S =
|
|
1115
|
-
|
|
1116
|
-
let C =
|
|
1117
|
-
return `<table${
|
|
1341
|
+
}, S = U(n, "tblInd");
|
|
1342
|
+
W(S, "type") === "dxa" && (x["margin-left"] = q(W(S, "w"))), x["table-layout"] = s ? "fixed" : "auto";
|
|
1343
|
+
let C = m.map((e, t) => `<tr${Ce(g[t])}>${e.map((e) => `<td${e.span > 1 ? ` colspan="${e.span}"` : ""}${e.rowSpan > 1 ? ` rowspan="${e.rowSpan}"` : ""}${Ce(e.css)}>${e.html || "<p><br></p>"}</td>`).join("")}</tr>`), w = f ? `<colgroup>${o.map((e) => `<col style="width:${q(e)}">`).join("")}</colgroup>` : "";
|
|
1344
|
+
return `<table${Ce(x)}>${w}${y ? `<thead>${C.slice(0, y).join("")}</thead>` : ""}<tbody>${C.slice(y).join("")}</tbody></table>`;
|
|
1118
1345
|
}
|
|
1119
1346
|
function F(e, t) {
|
|
1120
|
-
|
|
1347
|
+
N(t);
|
|
1121
1348
|
let n = "", r, i = () => {
|
|
1122
1349
|
r && (n += `</${r.tag}>`), r = void 0;
|
|
1123
1350
|
};
|
|
1124
|
-
for (let a of Array.from(e.children)) if (a.namespaceURI !== "http://schemas.openxmlformats.org/wordprocessingml/2006/main") i(),
|
|
1351
|
+
for (let a of Array.from(e.children)) if (a.namespaceURI !== "http://schemas.openxmlformats.org/wordprocessingml/2006/main") i(), h("unsupported-content", "Нестандартный блок Word не сохраняется в HTML.");
|
|
1125
1352
|
else if (a.localName === "p") {
|
|
1126
|
-
let e =
|
|
1127
|
-
e.list ? ((r?.id !== e.list.id || r.tag !== e.list.tag) && (i(), r = e.list, r.tag === "ol" &&
|
|
1128
|
-
} else a.localName === "tbl" ? (i(), n +=
|
|
1353
|
+
let e = ee(a, t + 1);
|
|
1354
|
+
e.list ? ((r?.id !== e.list.id || r.tag !== e.list.tag) && (i(), r = e.list, r.tag === "ol" && A.has(r.id) && h("numbering-restart", "Продолжение нумерованного списка после другого блока начнётся с 1: Hujjat удаляет атрибут start."), A.add(r.id), n += `<${r.tag}>`), n += `<li>${e.html}</li>`) : e.continuation && r && n.endsWith("</li>") ? n = n.slice(0, -5) + e.html + "</li>" : (i(), n += e.html);
|
|
1355
|
+
} else a.localName === "tbl" ? (i(), n += te(a, t + 1)) : a.localName === "sectPr" || ([
|
|
1129
1356
|
"sdt",
|
|
1130
1357
|
"customXml",
|
|
1131
1358
|
"ins",
|
|
1132
1359
|
"del",
|
|
1133
1360
|
"moveFrom",
|
|
1134
1361
|
"moveTo"
|
|
1135
|
-
].includes(a.localName) ? (i(),
|
|
1362
|
+
].includes(a.localName) ? (i(), h("block-flattened", `Блок Word ${a.localName} преобразован без интерактивности/истории.`), ["del", "moveFrom"].includes(a.localName) || (n += F(U(a, "sdtContent") ?? a, t + 1))) : [
|
|
1136
1363
|
"tblPr",
|
|
1137
1364
|
"tblGrid",
|
|
1138
1365
|
"tcPr",
|
|
@@ -1140,29 +1367,29 @@ async function Me(e, t = {}, n) {
|
|
|
1140
1367
|
"bookmarkStart",
|
|
1141
1368
|
"bookmarkEnd",
|
|
1142
1369
|
"proofErr"
|
|
1143
|
-
].includes(a.localName) || (i(),
|
|
1370
|
+
].includes(a.localName) || (i(), h("unsupported-block", `Блок Word ${a.localName} не поддерживается HTML-адаптером.`)));
|
|
1144
1371
|
return i(), n;
|
|
1145
1372
|
}
|
|
1146
|
-
let
|
|
1147
|
-
return
|
|
1148
|
-
html:
|
|
1373
|
+
let I = F(l, 0) || "<p><br></p>", L = await Ne(r, l, n, u, (e, t) => (v = t, A.clear(), g = new Map(Array.from(e.getElementsByTagNameNS(V, "p")).map((e, t) => [e, t])), _ = new Map(Array.from(e.getElementsByTagNameNS(V, "tbl")).map((e, t) => [e, t])), F(e, 0) || "<p><br></p>"));
|
|
1374
|
+
return f && n !== void 0 && f.page.orientation !== (L?.orientation ?? "portrait") ? {
|
|
1375
|
+
html: I,
|
|
1149
1376
|
warnings: u,
|
|
1150
|
-
layout:
|
|
1377
|
+
layout: f,
|
|
1151
1378
|
page: {
|
|
1152
|
-
...
|
|
1153
|
-
orientation:
|
|
1379
|
+
...L,
|
|
1380
|
+
orientation: f.page.orientation
|
|
1154
1381
|
}
|
|
1155
1382
|
} : {
|
|
1156
|
-
html:
|
|
1383
|
+
html: I,
|
|
1157
1384
|
warnings: u,
|
|
1158
|
-
layout:
|
|
1159
|
-
page:
|
|
1385
|
+
layout: f,
|
|
1386
|
+
page: L
|
|
1160
1387
|
};
|
|
1161
1388
|
}
|
|
1162
1389
|
//#endregion
|
|
1163
1390
|
//#region src/library/hujjat/table-grid.ts
|
|
1164
|
-
var
|
|
1165
|
-
function
|
|
1391
|
+
var qe = 1e-7;
|
|
1392
|
+
function Je(e, t, n) {
|
|
1166
1393
|
let r = Array.from({ length: e + 1 }, () => []), i = (e, t, n) => {
|
|
1167
1394
|
r[e].push({
|
|
1168
1395
|
to: t,
|
|
@@ -1182,7 +1409,7 @@ function Pe(e, t, n) {
|
|
|
1182
1409
|
for (let n = 0; n < e.length; n++) for (let i of r[e[n]]) {
|
|
1183
1410
|
let r = o[e[n]] + i.distance;
|
|
1184
1411
|
if (a[i.to] !== -1) {
|
|
1185
|
-
if (Math.abs(o[i.to] - r) >
|
|
1412
|
+
if (Math.abs(o[i.to] - r) > qe) return null;
|
|
1186
1413
|
} else a[i.to] = a[t], o[i.to] = r, e.push(i.to);
|
|
1187
1414
|
}
|
|
1188
1415
|
}
|
|
@@ -1208,7 +1435,7 @@ function Pe(e, t, n) {
|
|
|
1208
1435
|
high: u
|
|
1209
1436
|
};
|
|
1210
1437
|
}
|
|
1211
|
-
function
|
|
1438
|
+
function Ye(e, t) {
|
|
1212
1439
|
let { groups: n } = e, r = [...e.edges];
|
|
1213
1440
|
if (t !== void 0) for (let i = 0; i < n; i++) r.push({
|
|
1214
1441
|
from: 0,
|
|
@@ -1222,12 +1449,12 @@ function Fe(e, t) {
|
|
|
1222
1449
|
let i = Array(n).fill(0);
|
|
1223
1450
|
for (let e = 0; e < n; e++) {
|
|
1224
1451
|
let e = !1;
|
|
1225
|
-
for (let { from: t, to: n, distance: a } of r) i[n] > i[t] + a +
|
|
1452
|
+
for (let { from: t, to: n, distance: a } of r) i[n] > i[t] + a + qe && (i[n] = i[t] + a, e = !0);
|
|
1226
1453
|
if (!e) return i.map((e) => e - i[0]);
|
|
1227
1454
|
}
|
|
1228
1455
|
return null;
|
|
1229
1456
|
}
|
|
1230
|
-
function
|
|
1457
|
+
function Xe(e) {
|
|
1231
1458
|
if (!e) return null;
|
|
1232
1459
|
let t = (t) => ({
|
|
1233
1460
|
...e,
|
|
@@ -1236,53 +1463,53 @@ function Ie(e) {
|
|
|
1236
1463
|
distance: e.distance - t
|
|
1237
1464
|
}))
|
|
1238
1465
|
}), n = t(1);
|
|
1239
|
-
if (
|
|
1240
|
-
if (!
|
|
1466
|
+
if (Ye(n)) return n;
|
|
1467
|
+
if (!Ye(e)) return null;
|
|
1241
1468
|
let r = 0, i = 1, a = e;
|
|
1242
|
-
for (let e = 0; e < 40 && i - r >
|
|
1469
|
+
for (let e = 0; e < 40 && i - r > qe; e++) {
|
|
1243
1470
|
let e = (r + i) / 2, n = t(e);
|
|
1244
|
-
|
|
1471
|
+
Ye(n) ? (r = e, a = n) : i = e;
|
|
1245
1472
|
}
|
|
1246
|
-
return r >
|
|
1473
|
+
return r > qe ? a : null;
|
|
1247
1474
|
}
|
|
1248
|
-
function
|
|
1249
|
-
let t =
|
|
1475
|
+
function Ze(e) {
|
|
1476
|
+
let t = Ye(e), n = Ye(e, 0);
|
|
1250
1477
|
if (n) return n;
|
|
1251
1478
|
let r = 0, i = Math.max(...t.map((t, n) => Math.max(e.low[n] - t, t - e.high[n]))) + 1;
|
|
1252
1479
|
for (let n = 0; n < 60 && i - r > 1e-6; n++) {
|
|
1253
|
-
let n = (r + i) / 2, a =
|
|
1480
|
+
let n = (r + i) / 2, a = Ye(e, n);
|
|
1254
1481
|
a ? (t = a, i = n) : r = n;
|
|
1255
1482
|
}
|
|
1256
1483
|
return t;
|
|
1257
1484
|
}
|
|
1258
|
-
function
|
|
1485
|
+
function Qe(e, t, n, r) {
|
|
1259
1486
|
let i = (e) => Number.isFinite(e) && e > 0 && e < (2 ** 53 - 1) / 4;
|
|
1260
|
-
if (!Number.isInteger(e) || e < 1 || e > 1e3 || !i(t) || Math.round(t) < e) throw new
|
|
1261
|
-
for (let t of n) if (!Number.isInteger(t.column) || !Number.isInteger(t.span) || t.column < 0 || t.span < 1 || t.column + t.span > e || !i(t.width)) throw new
|
|
1262
|
-
let a = (e) => e.source === "column" ? 0 : e.span === 1 ? 1 : 2, o = (e) => JSON.stringify(Object.entries(e.location ?? {}).sort(([e], [t]) => e < t ? -1 : +(e > t))), s = [...n].sort((e, t) => a(e) - a(t) || e.column - t.column || e.span - t.span || e.width - t.width || o(e).localeCompare(o(t), "en")), c = s.filter((e, t) => !t || a(e) !== a(s[t - 1]) || e.column !== s[t - 1].column || e.span !== s[t - 1].span || e.width !== s[t - 1].width), l =
|
|
1487
|
+
if (!Number.isInteger(e) || e < 1 || e > 1e3 || !i(t) || Math.round(t) < e) throw new z("Некорректный размер сетки таблицы.");
|
|
1488
|
+
for (let t of n) if (!Number.isInteger(t.column) || !Number.isInteger(t.span) || t.column < 0 || t.span < 1 || t.column + t.span > e || !i(t.width)) throw new z("Некорректное ограничение ширины таблицы.");
|
|
1489
|
+
let a = (e) => e.source === "column" ? 0 : e.span === 1 ? 1 : 2, o = (e) => JSON.stringify(Object.entries(e.location ?? {}).sort(([e], [t]) => e < t ? -1 : +(e > t))), s = [...n].sort((e, t) => a(e) - a(t) || e.column - t.column || e.span - t.span || e.width - t.width || o(e).localeCompare(o(t), "en")), c = s.filter((e, t) => !t || a(e) !== a(s[t - 1]) || e.column !== s[t - 1].column || e.span !== s[t - 1].span || e.width !== s[t - 1].width), l = Xe(Je(e, t, c));
|
|
1263
1490
|
if (!l) {
|
|
1264
1491
|
let n = [];
|
|
1265
|
-
l =
|
|
1492
|
+
l = Xe(Je(e, t, []));
|
|
1266
1493
|
for (let r of c) {
|
|
1267
|
-
let i =
|
|
1494
|
+
let i = Xe(Je(e, t, [...n, r]));
|
|
1268
1495
|
i && (i.groups < l.groups && n.push(r), l = i);
|
|
1269
1496
|
}
|
|
1270
1497
|
}
|
|
1271
|
-
let u =
|
|
1498
|
+
let u = Ze(l), d = l.offset.map((e, t) => e + u[l.component[t]]), f = Math.round(t), p = d.map((e) => Math.round(e));
|
|
1272
1499
|
p[0] = 0, p[e] = f;
|
|
1273
|
-
let m = d.map((e) => Math.floor(e + 1 +
|
|
1500
|
+
let m = d.map((e) => Math.floor(e + 1 + qe));
|
|
1274
1501
|
m[e] = f;
|
|
1275
1502
|
for (let t = e - 1; t > 0; t--) m[t] = Math.min(m[t], m[t + 1] - 1);
|
|
1276
1503
|
for (let t = 1; t < e; t++) {
|
|
1277
|
-
let e = Math.max(p[t - 1] + 1, Math.ceil(d[t] - 1 -
|
|
1278
|
-
if (e > m[t]) throw new
|
|
1504
|
+
let e = Math.max(p[t - 1] + 1, Math.ceil(d[t] - 1 - qe));
|
|
1505
|
+
if (e > m[t]) throw new z("Сетка не представима положительными twips без превышения допуска округления.");
|
|
1279
1506
|
p[t] = Math.max(e, Math.min(m[t], p[t]));
|
|
1280
1507
|
}
|
|
1281
|
-
if (p.some((e, t) => Math.abs(e - d[t]) > 1.0000001)) throw new
|
|
1508
|
+
if (p.some((e, t) => Math.abs(e - d[t]) > 1.0000001)) throw new z("Сетка не представима положительными twips без превышения допуска округления.");
|
|
1282
1509
|
let h = p.slice(1).map((e, t) => e - p[t]);
|
|
1283
1510
|
for (let e of s) {
|
|
1284
1511
|
let t = p[e.column + e.span] - p[e.column];
|
|
1285
|
-
Math.abs(t - e.width) > 2.0000001 &&
|
|
1512
|
+
Math.abs(t - e.width) > 2.0000001 && B(r, "table-width-normalized", "Заданная ширина конфликтует с общей сеткой таблицы.", "loss", {
|
|
1286
1513
|
stage: "import",
|
|
1287
1514
|
location: e.location,
|
|
1288
1515
|
before: e.width,
|
|
@@ -1293,7 +1520,7 @@ function Re(e, t, n, r) {
|
|
|
1293
1520
|
}
|
|
1294
1521
|
//#endregion
|
|
1295
1522
|
//#region src/library/hujjat/html-to-docx.ts
|
|
1296
|
-
var
|
|
1523
|
+
var $e = /^(font-|color$|text-align$|text-indent$|text-transform$|line-height$|letter-spacing$|white-space$|text-decoration$|vertical-align$)/, et = new Set("p div h1 h2 h3 h4 h5 h6 ul ol li table hr".split(" ")), tt = {
|
|
1297
1524
|
black: "000000",
|
|
1298
1525
|
white: "FFFFFF",
|
|
1299
1526
|
red: "FF0000",
|
|
@@ -1312,14 +1539,14 @@ var ze = /^(font-|color$|text-align$|text-indent$|text-transform$|line-height$|l
|
|
|
1312
1539
|
teal: "008080",
|
|
1313
1540
|
aqua: "00FFFF"
|
|
1314
1541
|
};
|
|
1315
|
-
function
|
|
1542
|
+
function nt(e) {
|
|
1316
1543
|
if (!e) return;
|
|
1317
1544
|
if (/^#[\da-f]{6}$/i.test(e)) return e.slice(1);
|
|
1318
1545
|
if (/^#[\da-f]{3}$/i.test(e)) return e.slice(1).split("").map((e) => e + e).join("");
|
|
1319
1546
|
let t = e.match(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
|
|
1320
|
-
return t ? t.slice(1).map((e) => Math.min(255, Number(e)).toString(16).padStart(2, "0")).join("") :
|
|
1547
|
+
return t ? t.slice(1).map((e) => Math.min(255, Number(e)).toString(16).padStart(2, "0")).join("") : tt[e.toLowerCase()];
|
|
1321
1548
|
}
|
|
1322
|
-
function
|
|
1549
|
+
function rt(e) {
|
|
1323
1550
|
if (e === "0") return 0;
|
|
1324
1551
|
let t = e?.match(/^(-?\d*\.?\d+)(pt|px|in|cm|mm|pc)$/i);
|
|
1325
1552
|
return t ? Number(t[1]) * {
|
|
@@ -1332,9 +1559,9 @@ function X(e) {
|
|
|
1332
1559
|
}[t[2].toLowerCase()] : void 0;
|
|
1333
1560
|
}
|
|
1334
1561
|
var Z = (e) => {
|
|
1335
|
-
let t =
|
|
1562
|
+
let t = rt(e);
|
|
1336
1563
|
return t === void 0 ? void 0 : Math.round(t * 20);
|
|
1337
|
-
},
|
|
1564
|
+
}, it = (e, t) => (Z(e[`margin-${t}`]) ?? 0) + Math.max(0, Z(e[`padding-${t}`]) ?? 0);
|
|
1338
1565
|
function Q(e, t) {
|
|
1339
1566
|
let n = { ...t }, r = e.style;
|
|
1340
1567
|
for (let e of Array.from(r)) n[e] = r.getPropertyValue(e).trim();
|
|
@@ -1363,73 +1590,98 @@ function Q(e, t) {
|
|
|
1363
1590
|
h3: "12pt"
|
|
1364
1591
|
}[i] ?? "12pt"), r.fontWeight || (n["font-weight"] = "bold")), n;
|
|
1365
1592
|
}
|
|
1366
|
-
var
|
|
1367
|
-
async function
|
|
1593
|
+
var at = (e) => Object.fromEntries(Object.entries(e).filter(([e]) => $e.test(e)));
|
|
1594
|
+
async function ot(e, t, n = R(), r) {
|
|
1368
1595
|
let i = {
|
|
1369
|
-
width:
|
|
1596
|
+
width: ne(n.page),
|
|
1370
1597
|
cell: !1
|
|
1371
|
-
}, a =
|
|
1598
|
+
}, a = ge(e), o = 1, s = [], c = ["header", "footer"].flatMap((e) => r?.[e]?.html.trim() ? [{
|
|
1372
1599
|
kind: e,
|
|
1373
|
-
root:
|
|
1374
|
-
}] : []), l = /* @__PURE__ */ new WeakMap();
|
|
1375
|
-
function
|
|
1600
|
+
root: ge(r[e].html)
|
|
1601
|
+
}] : []), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map(), d = "word/document.xml", f = 0, p = /* @__PURE__ */ new WeakMap();
|
|
1602
|
+
function m(e, t) {
|
|
1376
1603
|
let n = 0;
|
|
1377
1604
|
for (let r of e.childNodes) if (r instanceof Element) {
|
|
1378
1605
|
let e = `${t}/${r.localName}[${n++}]`;
|
|
1379
|
-
|
|
1606
|
+
p.set(r, e), m(r, e);
|
|
1380
1607
|
}
|
|
1381
1608
|
}
|
|
1382
|
-
|
|
1383
|
-
for (let e of c)
|
|
1384
|
-
let
|
|
1385
|
-
function
|
|
1609
|
+
m(a, "");
|
|
1610
|
+
for (let e of c) m(e.root, `page.${e.kind}`);
|
|
1611
|
+
let h = [];
|
|
1612
|
+
function g() {
|
|
1386
1613
|
let e = !0;
|
|
1387
|
-
for (let t of
|
|
1614
|
+
for (let t of h) t instanceof Element ? e = !1 : t.data = t.data.replace(/[\t\r\n\f ]+/g, " ").split("").filter((t) => {
|
|
1388
1615
|
if (t === " ") {
|
|
1389
1616
|
if (e) return !1;
|
|
1390
1617
|
e = !0;
|
|
1391
1618
|
} else e = !1;
|
|
1392
1619
|
return !0;
|
|
1393
1620
|
}).join("");
|
|
1394
|
-
for (let e =
|
|
1395
|
-
|
|
1396
|
-
break;
|
|
1621
|
+
for (let e = h.length - 1; e >= 0; e--) {
|
|
1622
|
+
let t = h[e];
|
|
1623
|
+
if (t instanceof Element) break;
|
|
1624
|
+
if (t.data) {
|
|
1625
|
+
t.data = t.data.replace(/ $/, "");
|
|
1626
|
+
break;
|
|
1627
|
+
}
|
|
1397
1628
|
}
|
|
1398
|
-
|
|
1629
|
+
h = [];
|
|
1399
1630
|
}
|
|
1400
|
-
function
|
|
1631
|
+
function _(e, n = !1) {
|
|
1401
1632
|
if (e.nodeType === 3) {
|
|
1402
|
-
n ||
|
|
1633
|
+
n || h.push(e);
|
|
1634
|
+
return;
|
|
1635
|
+
}
|
|
1636
|
+
let r = e instanceof Element ? e : null;
|
|
1637
|
+
if (r?.localName === "img") {
|
|
1638
|
+
h.push(r);
|
|
1403
1639
|
return;
|
|
1404
1640
|
}
|
|
1405
|
-
let
|
|
1641
|
+
let i = r && (et.has(r.localName) || [
|
|
1406
1642
|
"br",
|
|
1407
1643
|
"td",
|
|
1408
1644
|
"th",
|
|
1409
1645
|
"tr"
|
|
1410
1646
|
].includes(r.localName)), a = n || !!(r && /^(pre|pre-wrap|break-spaces)$/.test(r.style.whiteSpace));
|
|
1411
|
-
(i || a) &&
|
|
1412
|
-
for (let t of e.childNodes)
|
|
1413
|
-
(i || a) &&
|
|
1647
|
+
(i || a) && g(), a && B(t, "preformatted-text", "Предформатированный текст требует проверки переносов и табуляции после открытия.");
|
|
1648
|
+
for (let t of e.childNodes) _(t, a);
|
|
1649
|
+
(i || a) && g();
|
|
1414
1650
|
}
|
|
1415
|
-
|
|
1416
|
-
for (let e of c)
|
|
1417
|
-
let
|
|
1651
|
+
_(a), g();
|
|
1652
|
+
for (let e of c) _(e.root), g();
|
|
1653
|
+
let v = {
|
|
1418
1654
|
"font-family": r?.font_family ?? "freeserif",
|
|
1419
1655
|
"font-size": `${r?.font_size ?? 12}pt`,
|
|
1420
1656
|
color: "#111111"
|
|
1421
1657
|
};
|
|
1422
|
-
r?.line_height !== void 0 && (
|
|
1423
|
-
function
|
|
1424
|
-
let t = `<w:rFonts w:ascii="${
|
|
1425
|
-
return n !== void 0 && (t += `<w:sz w:val="${Math.round(n * 2)}"/>`), e["font-weight"] && (t += `<w:b w:val="${e["font-weight"] === "bold" || Number(e["font-weight"]) >= 600 ? "1" : "0"}"/>`), e["font-style"] && (t += `<w:i w:val="${e["font-style"] === "italic" ? "1" : "0"}"/>`), e["text-decoration"] && (t += `<w:u w:val="${e["text-decoration"].includes("underline") ? "single" : "none"}"/><w:strike w:val="${e["text-decoration"].includes("line-through") ? "1" : "0"}"/>`),
|
|
1658
|
+
r?.line_height !== void 0 && (v["line-height"] = String(r.line_height));
|
|
1659
|
+
function y(e) {
|
|
1660
|
+
let t = `<w:rFonts w:ascii="${Se(e["font-family"] || "freeserif")}" w:hAnsi="${Se(e["font-family"] || "freeserif")}"/>`, n = rt(e["font-size"]);
|
|
1661
|
+
return n !== void 0 && (t += `<w:sz w:val="${Math.round(n * 2)}"/>`), e["font-weight"] && (t += `<w:b w:val="${e["font-weight"] === "bold" || Number(e["font-weight"]) >= 600 ? "1" : "0"}"/>`), e["font-style"] && (t += `<w:i w:val="${e["font-style"] === "italic" ? "1" : "0"}"/>`), e["text-decoration"] && (t += `<w:u w:val="${e["text-decoration"].includes("underline") ? "single" : "none"}"/><w:strike w:val="${e["text-decoration"].includes("line-through") ? "1" : "0"}"/>`), nt(e.color) && (t += `<w:color w:val="${nt(e.color)}"/>`), nt(e["background-color"]) && (t += `<w:shd w:fill="${nt(e["background-color"])}"/>`), ["super", "sub"].includes(e["vertical-align"]) && (t += `<w:vertAlign w:val="${e["vertical-align"] === "super" ? "superscript" : "subscript"}"/>`), e["text-transform"] === "uppercase" && (t += "<w:caps/>"), Z(e["letter-spacing"]) !== void 0 && (t += `<w:spacing w:val="${Z(e["letter-spacing"])}"/>`), t;
|
|
1426
1662
|
}
|
|
1427
|
-
function
|
|
1663
|
+
function x(e, t) {
|
|
1428
1664
|
let n = "";
|
|
1429
|
-
for (let r of e) r.nodeType === 3
|
|
1665
|
+
for (let r of e) if (r.nodeType === 3) r.textContent && (n += `<w:r><w:rPr>${y(t)}</w:rPr><w:t xml:space="preserve">${Se(r.textContent)}</w:t></w:r>`);
|
|
1666
|
+
else if (r instanceof Element) {
|
|
1667
|
+
if (r.localName === "br") n += `<w:r><w:rPr>${y(Q(r, t))}</w:rPr><w:br/></w:r>`;
|
|
1668
|
+
else if (r.localName === "img") {
|
|
1669
|
+
let e = r.getAttribute("src") ?? "", t = te(e), i = F(r, t), a = l.get(e);
|
|
1670
|
+
if (!a) {
|
|
1671
|
+
let n = l.size + 1;
|
|
1672
|
+
a = {
|
|
1673
|
+
id: n,
|
|
1674
|
+
path: `media/image${n}.${t.mime === "image/png" ? "png" : "jpg"}`,
|
|
1675
|
+
data: t.data
|
|
1676
|
+
}, l.set(e, a);
|
|
1677
|
+
}
|
|
1678
|
+
let o = u.get(d) ?? /* @__PURE__ */ new Set();
|
|
1679
|
+
o.add(e), u.set(d, o), n += Ge(++f, `rIdImage${a.id}`, i.width, i.height, Array.from(r.getAttribute("alt") ?? "").slice(0, 500).join(""));
|
|
1680
|
+
} else n += x(r.childNodes, Q(r, t));
|
|
1681
|
+
}
|
|
1430
1682
|
return n;
|
|
1431
1683
|
}
|
|
1432
|
-
function
|
|
1684
|
+
function S(e, r, a, o = i) {
|
|
1433
1685
|
let s = Array.from(e), c = "", l = r["text-align"];
|
|
1434
1686
|
[
|
|
1435
1687
|
"left",
|
|
@@ -1440,16 +1692,16 @@ async function We(e, t, n = P(), r) {
|
|
|
1440
1692
|
let u = Math.max(o.before ?? 0, Z(r["margin-top"]) ?? 0), d = Math.max(o.after ?? 0, Z(r["margin-bottom"]) ?? (o.cell ? 0 : 120)), f = "", p = r["line-height"];
|
|
1441
1693
|
if (p && /^\d*\.?\d+%?$/.test(p)) {
|
|
1442
1694
|
let e = parseFloat(p) / (p.endsWith("%") ? 100 : 1), r = n.lineSpacingPolicy === "preserve";
|
|
1443
|
-
e < 1 &&
|
|
1695
|
+
e < 1 && B(t, r ? "line-height-overlap-risk" : "line-height-normalized", r ? "Тесный интервал сохранён; проверьте наложение строк." : "Тесный интервал увеличен до одинарного; проверьте переносы.", "warning", {
|
|
1444
1696
|
stage: "import",
|
|
1445
1697
|
location: { htmlPath: o.htmlPath },
|
|
1446
1698
|
before: e,
|
|
1447
1699
|
after: r ? e : 1
|
|
1448
1700
|
}), f = ` w:line="${Math.round(Math.max(+!r, e) * 240)}" w:lineRule="auto"`;
|
|
1449
|
-
} else if (
|
|
1701
|
+
} else if (rt(p) !== void 0) {
|
|
1450
1702
|
let e = [], i = (t) => e.push({
|
|
1451
1703
|
...t,
|
|
1452
|
-
"font-size": `${Math.round((
|
|
1704
|
+
"font-size": `${Math.round((rt(t["font-size"]) ?? 12) * 2) / 2}pt`
|
|
1453
1705
|
}), a = (e, t) => {
|
|
1454
1706
|
for (let n of e) if (n.nodeType === 3 && n.textContent) i(t);
|
|
1455
1707
|
else if (n instanceof Element) {
|
|
@@ -1458,13 +1710,13 @@ async function We(e, t, n = P(), r) {
|
|
|
1458
1710
|
}
|
|
1459
1711
|
};
|
|
1460
1712
|
i(r), a(s, r);
|
|
1461
|
-
let c = Z(p) / 20 <
|
|
1462
|
-
c &&
|
|
1713
|
+
let c = Z(p) / 20 < Me(e), l = n.lineSpacingPolicy === "normalize";
|
|
1714
|
+
c && B(t, l ? "line-height-normalized" : "line-height-overlap-risk", l ? "Тесный абсолютный интервал заменён естественным одинарным интервалом." : "Тесный абсолютный интервал сохранён; проверьте наложение строк.", "warning", {
|
|
1463
1715
|
stage: "import",
|
|
1464
1716
|
location: { htmlPath: o.htmlPath },
|
|
1465
1717
|
before: p,
|
|
1466
1718
|
after: l ? "normal" : p
|
|
1467
|
-
}), l &&
|
|
1719
|
+
}), l && B(t, "line-height-metrics-estimated", "Проверка интервала использует размеры фрагментов, а не метрики установленного шрифта. Результат требует проверки на используемых шрифтах.", "warning", {
|
|
1468
1720
|
stage: "import",
|
|
1469
1721
|
location: { htmlPath: o.htmlPath },
|
|
1470
1722
|
before: p,
|
|
@@ -1499,9 +1751,9 @@ async function We(e, t, n = P(), r) {
|
|
|
1499
1751
|
"avoid"
|
|
1500
1752
|
]
|
|
1501
1753
|
]) (r[e] === n || r[e] === "auto") && (c += `<w:${t} w:val="${r[e] === n ? "1" : "0"}"/>`);
|
|
1502
|
-
return a && (a.pending ? c += `<w:numPr><w:ilvl w:val="0"/><w:numId w:val="${a.id}"/></w:numPr>` : c += "<w:pStyle w:val=\"AzHujjatListContinuation\"/>", a.pending = !1), `<w:p><w:pPr>${c}<w:rPr>${
|
|
1754
|
+
return a && (a.pending ? c += `<w:numPr><w:ilvl w:val="0"/><w:numId w:val="${a.id}"/></w:numPr>` : c += "<w:pStyle w:val=\"AzHujjatListContinuation\"/>", a.pending = !1), `<w:p><w:pPr>${c}<w:rPr>${y(r)}</w:rPr></w:pPr>${x(s, r)}</w:p>`;
|
|
1503
1755
|
}
|
|
1504
|
-
function
|
|
1756
|
+
function C(e, t) {
|
|
1505
1757
|
let n = e.style, r = n.getPropertyValue(`border-${t}-style`) || n.borderStyle, i = n.getPropertyValue(`border-${t}-width`) || n.borderWidth, a = n.getPropertyValue(`border-${t}-color`) || n.borderColor;
|
|
1506
1758
|
return !r && !i ? "" : `<w:${t} w:val="${{
|
|
1507
1759
|
solid: "single",
|
|
@@ -1509,16 +1761,16 @@ async function We(e, t, n = P(), r) {
|
|
|
1509
1761
|
dotted: "dotted",
|
|
1510
1762
|
double: "double",
|
|
1511
1763
|
none: "nil"
|
|
1512
|
-
}[r] ?? "single"}" w:sz="${Math.max(0, Math.round((
|
|
1764
|
+
}[r] ?? "single"}" w:sz="${Math.max(0, Math.round((rt(i) ?? .75) * 8))}" w:color="${nt(a) ?? "000000"}"/>`;
|
|
1513
1765
|
}
|
|
1514
|
-
function
|
|
1515
|
-
let i = Array.from(e.querySelectorAll("tr")).filter((t) => t.closest("table") === e), a = /* @__PURE__ */ new Map(), o = 1, s = [], c = n.width?.endsWith("%") ? parseFloat(n.width) : void 0,
|
|
1516
|
-
let t =
|
|
1517
|
-
return t === void 0 ? e?.endsWith("%") ? parseFloat(e) *
|
|
1766
|
+
function w(e, n, r) {
|
|
1767
|
+
let i = Array.from(e.querySelectorAll("tr")).filter((t) => t.closest("table") === e), a = /* @__PURE__ */ new Map(), o = 1, s = [], c = n.width?.endsWith("%") ? parseFloat(n.width) : void 0, l = (r.left ?? 0) + (Z(n["margin-left"]) ?? 0), u = (r.right ?? 0) + (Z(n["margin-right"]) ?? 0), d = Math.max(1, r.width - l - u), f = Math.max(1, Math.round(Z(n.width) ?? (c === void 0 ? d : d * c / 100))), m = (e) => {
|
|
1768
|
+
let t = rt(e);
|
|
1769
|
+
return t === void 0 ? e?.endsWith("%") ? parseFloat(e) * f / 100 : void 0 : t * 20;
|
|
1518
1770
|
};
|
|
1519
|
-
(r.before || r.after || Z(n["margin-top"]) || Z(n["margin-bottom"])) &&
|
|
1771
|
+
(r.before || r.after || Z(n["margin-top"]) || Z(n["margin-bottom"])) && B(t, "table-margin-approximation", "Вертикальные отступы контейнера вокруг таблицы требуют проверки.");
|
|
1520
1772
|
let h = (e) => {
|
|
1521
|
-
if (e > 1e3) throw new
|
|
1773
|
+
if (e > 1e3) throw new z("Таблица содержит более 1000 столбцов с учётом объединённых ячеек.");
|
|
1522
1774
|
}, g = i.map((t) => {
|
|
1523
1775
|
let r = 0, i = [];
|
|
1524
1776
|
function c() {
|
|
@@ -1534,14 +1786,14 @@ async function We(e, t, n = P(), r) {
|
|
|
1534
1786
|
}
|
|
1535
1787
|
for (let o of Array.from(t.children).filter((e) => e.localName === "td" || e.localName === "th")) {
|
|
1536
1788
|
c();
|
|
1537
|
-
let t = Number(o.getAttribute("colspan") || 1),
|
|
1538
|
-
if (h(r + t), [...a].some(([e, n]) => e < r + t && e + n.span > r)) throw new
|
|
1539
|
-
let
|
|
1540
|
-
for (;
|
|
1541
|
-
let
|
|
1542
|
-
...
|
|
1789
|
+
let t = Number(o.getAttribute("colspan") || 1), l = Number(o.getAttribute("rowspan") || 1);
|
|
1790
|
+
if (h(r + t), [...a].some(([e, n]) => e < r + t && e + n.span > r)) throw new z("Ячейка пересекает продолжающееся объединение строк таблицы.");
|
|
1791
|
+
let u = [], d = o.parentElement;
|
|
1792
|
+
for (; d && d !== e;) u.unshift(d), d = d.parentElement;
|
|
1793
|
+
let f = (e) => ({
|
|
1794
|
+
...at(e),
|
|
1543
1795
|
...e["background-color"] ? { "background-color": e["background-color"] } : {}
|
|
1544
|
-
}), g = Q(o,
|
|
1796
|
+
}), g = Q(o, f(u.reduce((e, t) => Q(t, f(e)), n)));
|
|
1545
1797
|
o.localName === "th" && (g["font-weight"] = "bold");
|
|
1546
1798
|
let _ = m(g.width);
|
|
1547
1799
|
_ !== void 0 && Number.isFinite(_) && _ > 0 && s.push({
|
|
@@ -1549,15 +1801,15 @@ async function We(e, t, n = P(), r) {
|
|
|
1549
1801
|
span: t,
|
|
1550
1802
|
width: _,
|
|
1551
1803
|
source: "cell",
|
|
1552
|
-
location: { htmlPath:
|
|
1804
|
+
location: { htmlPath: p.get(o) }
|
|
1553
1805
|
}), i.push({
|
|
1554
1806
|
element: o,
|
|
1555
1807
|
column: r,
|
|
1556
1808
|
span: t,
|
|
1557
|
-
rowSpan:
|
|
1809
|
+
rowSpan: l,
|
|
1558
1810
|
css: g
|
|
1559
|
-
}),
|
|
1560
|
-
remaining:
|
|
1811
|
+
}), l > 1 && a.set(r, {
|
|
1812
|
+
remaining: l - 1,
|
|
1561
1813
|
span: t
|
|
1562
1814
|
}), r += t;
|
|
1563
1815
|
}
|
|
@@ -1585,23 +1837,23 @@ async function We(e, t, n = P(), r) {
|
|
|
1585
1837
|
span: 1,
|
|
1586
1838
|
width: n,
|
|
1587
1839
|
source: "column",
|
|
1588
|
-
location: { htmlPath:
|
|
1840
|
+
location: { htmlPath: p.get(r) }
|
|
1589
1841
|
});
|
|
1590
1842
|
_ += t;
|
|
1591
1843
|
}
|
|
1592
1844
|
}
|
|
1593
|
-
if (_ > o) throw new
|
|
1594
|
-
let
|
|
1845
|
+
if (_ > o) throw new z("Число явных колонок превышает логическую сетку ячеек.");
|
|
1846
|
+
let v = Qe(o, f, s, t), y = "<w:p><w:pPr><w:spacing w:before=\"0\" w:after=\"0\"/></w:pPr></w:p>", b = !0, x = g.map((e, n) => {
|
|
1595
1847
|
let r = i[n], a = Q(r, {}), o = Z(a.height), s = o !== void 0 && o >= 0 ? `<w:trHeight w:val="${o}" w:hRule="atLeast"/>` : "";
|
|
1596
1848
|
["avoid", "auto"].includes(a["page-break-inside"]) && (s += `<w:cantSplit w:val="${a["page-break-inside"] === "avoid" ? "1" : "0"}"/>`);
|
|
1597
1849
|
let c = r.parentElement?.localName === "thead";
|
|
1598
|
-
return c &&
|
|
1850
|
+
return c && b ? s += "<w:tblHeader/>" : c && B(t, "table-header-not-contiguous", "Повторяемая шапка должна находиться в начале таблицы.", "warning", {
|
|
1599
1851
|
stage: "import",
|
|
1600
|
-
location: { htmlPath:
|
|
1601
|
-
}), c || (
|
|
1602
|
-
let a =
|
|
1603
|
-
if (n > 1 && (o += `<w:gridSpan w:val="${n}"/>`), r > 1 && (o += "<w:vMerge w:val=\"restart\"/>"), !e) return `<w:tc><w:tcPr>${o}${r === 0 ? "<w:vMerge/>" : ""}</w:tcPr>${
|
|
1604
|
-
let s =
|
|
1852
|
+
location: { htmlPath: p.get(r) }
|
|
1853
|
+
}), c || (b = !1), `<w:tr>${s ? `<w:trPr>${s}</w:trPr>` : ""}${e.map(({ element: e, column: t, span: n, rowSpan: r, css: i }) => {
|
|
1854
|
+
let a = v.slice(t, t + n).reduce((e, t) => e + t, 0), o = `<w:tcW w:w="${a}" w:type="dxa"/>`;
|
|
1855
|
+
if (n > 1 && (o += `<w:gridSpan w:val="${n}"/>`), r > 1 && (o += "<w:vMerge w:val=\"restart\"/>"), !e) return `<w:tc><w:tcPr>${o}${r === 0 ? "<w:vMerge/>" : ""}</w:tcPr>${y}</w:tc>`;
|
|
1856
|
+
let s = nt(i["background-color"]);
|
|
1605
1857
|
s && (o += `<w:shd w:fill="${s}"/>`), [
|
|
1606
1858
|
"top",
|
|
1607
1859
|
"middle",
|
|
@@ -1612,30 +1864,30 @@ async function We(e, t, n = P(), r) {
|
|
|
1612
1864
|
"left",
|
|
1613
1865
|
"bottom",
|
|
1614
1866
|
"right"
|
|
1615
|
-
], l = c.map((t) =>
|
|
1867
|
+
], l = c.map((t) => C(e, t)).join("");
|
|
1616
1868
|
l && (o += `<w:tcBorders>${l}</w:tcBorders>`);
|
|
1617
1869
|
let u = c.map((e) => Z(i[`padding-${e}`]) === void 0 ? "" : `<w:${e} w:w="${Math.max(0, Z(i[`padding-${e}`]))}" w:type="dxa"/>`).join("");
|
|
1618
1870
|
u && (o += `<w:tcMar>${u}</w:tcMar>`);
|
|
1619
|
-
let d = Math.max(1, a - Math.max(0, Z(i["padding-left"]) ?? 0) - Math.max(0, Z(i["padding-right"]) ?? 0)), f =
|
|
1871
|
+
let d = Math.max(1, a - Math.max(0, Z(i["padding-left"]) ?? 0) - Math.max(0, Z(i["padding-right"]) ?? 0)), f = O(D(e.childNodes, at(i), void 0, {
|
|
1620
1872
|
width: d,
|
|
1621
1873
|
cell: !0
|
|
1622
1874
|
}));
|
|
1623
|
-
return (!f || f.endsWith("</w:tbl>")) && (f +=
|
|
1624
|
-
}).join("") || `<w:tc>${
|
|
1625
|
-
}).join(""),
|
|
1875
|
+
return (!f || f.endsWith("</w:tbl>")) && (f += y), `<w:tc><w:tcPr>${o}</w:tcPr>${f}</w:tc>`;
|
|
1876
|
+
}).join("") || `<w:tc>${y}</w:tc>`}</w:tr>`;
|
|
1877
|
+
}).join(""), S = v.map((e) => `<w:gridCol w:w="${e}"/>`).join(""), w = c !== void 0 && !l && !u ? `<w:tblW w:w="${Math.round(c * 50)}" w:type="pct"/>` : `<w:tblW w:w="${f}" w:type="dxa"/>`, T = [
|
|
1626
1878
|
"top",
|
|
1627
1879
|
"left",
|
|
1628
1880
|
"bottom",
|
|
1629
1881
|
"right"
|
|
1630
|
-
].map((t) =>
|
|
1631
|
-
return `<w:tbl><w:tblPr>${
|
|
1882
|
+
].map((t) => C(e, t)).join(""), E = n["table-layout"] === "auto" ? "autofit" : "fixed";
|
|
1883
|
+
return `<w:tbl><w:tblPr>${w}${l ? `<w:tblInd w:w="${l}" w:type="dxa"/>` : ""}${T ? `<w:tblBorders>${T}</w:tblBorders>` : ""}<w:tblLayout w:type="${E}"/></w:tblPr><w:tblGrid>${S}</w:tblGrid>${x}</w:tbl>`;
|
|
1632
1884
|
}
|
|
1633
|
-
function
|
|
1885
|
+
function T(e, t) {
|
|
1634
1886
|
return e.length && (e[0].before ||= t["page-break-before"] === "always", e[e.length - 1].after ||= t["page-break-after"] === "always"), e;
|
|
1635
1887
|
}
|
|
1636
|
-
function
|
|
1888
|
+
function E(e, n, r) {
|
|
1637
1889
|
if (n["page-break-inside"] !== "avoid") return e;
|
|
1638
|
-
if (e.some((e) => e.table)) return
|
|
1890
|
+
if (e.some((e) => e.table)) return B(t, "keep-group-not-representable", "Группа с таблицей не может быть целиком удержана на странице текущим HTML/DOCX-адаптером.", "loss", {
|
|
1639
1891
|
stage: "import",
|
|
1640
1892
|
location: { htmlPath: r },
|
|
1641
1893
|
before: "page-break-inside:avoid",
|
|
@@ -1651,63 +1903,63 @@ async function We(e, t, n = P(), r) {
|
|
|
1651
1903
|
};
|
|
1652
1904
|
});
|
|
1653
1905
|
}
|
|
1654
|
-
function
|
|
1655
|
-
let
|
|
1906
|
+
function D(e, n, a, c = i) {
|
|
1907
|
+
let l = [], u = [], d = 0, f = Array.from(e).filter((e) => e.nodeType !== 3 || e.textContent), m = (e, t = e) => ({
|
|
1656
1908
|
...c,
|
|
1657
1909
|
before: e === 0 ? c.before : void 0,
|
|
1658
|
-
after: t ===
|
|
1910
|
+
after: t === f.length - 1 ? c.after : void 0
|
|
1659
1911
|
}), h = (e) => {
|
|
1660
|
-
|
|
1912
|
+
u.length && l.push(...T([{ xml: S(u, n, a, m(d, e)) }], n)), u = [];
|
|
1661
1913
|
};
|
|
1662
|
-
for (let [e, i] of
|
|
1663
|
-
if (!(i instanceof Element) || !
|
|
1664
|
-
|
|
1914
|
+
for (let [e, i] of f.entries()) {
|
|
1915
|
+
if (!(i instanceof Element) || !et.has(i.localName)) {
|
|
1916
|
+
u.length || (d = e), u.push(i);
|
|
1665
1917
|
continue;
|
|
1666
1918
|
}
|
|
1667
1919
|
h(e - 1);
|
|
1668
|
-
let
|
|
1920
|
+
let f = Q(i, at(n)), g = {
|
|
1669
1921
|
...m(e),
|
|
1670
|
-
htmlPath:
|
|
1922
|
+
htmlPath: p.get(i)
|
|
1671
1923
|
};
|
|
1672
|
-
if (i.localName === "p" && r?.paragraph_spacing !== void 0 && (
|
|
1673
|
-
xml:
|
|
1924
|
+
if (i.localName === "p" && r?.paragraph_spacing !== void 0 && (f["margin-bottom"] ??= `${r.paragraph_spacing}pt`), r !== void 0 && i.localName === "h1" && (f["margin-bottom"] ??= "7.5pt"), i.localName === "table") l.push(...T(E([{
|
|
1925
|
+
xml: w(i, f, g),
|
|
1674
1926
|
table: !0
|
|
1675
|
-
}],
|
|
1927
|
+
}], f, g.htmlPath), f));
|
|
1676
1928
|
else if (i.localName === "ol" || i.localName === "ul") {
|
|
1677
1929
|
let e = o++;
|
|
1678
1930
|
s.push({
|
|
1679
1931
|
id: e,
|
|
1680
1932
|
tag: i.localName
|
|
1681
|
-
}), a &&
|
|
1933
|
+
}), a && B(t, "nested-list-normalized", "Вложенный список при открытии становится отдельным списком.", "loss");
|
|
1682
1934
|
let n = Array.from(i.children).filter((e) => e.localName === "li"), r = [];
|
|
1683
1935
|
for (let [t, i] of n.entries()) {
|
|
1684
1936
|
let a = {
|
|
1685
1937
|
id: e,
|
|
1686
1938
|
pending: !0
|
|
1687
|
-
}, o = Q(i,
|
|
1939
|
+
}, o = Q(i, at(f)), s = {
|
|
1688
1940
|
...g,
|
|
1689
1941
|
before: Math.max(t === 0 ? g.before ?? 0 : 0, Z(o["margin-top"]) ?? 0),
|
|
1690
1942
|
after: Math.max(t === n.length - 1 ? g.after ?? 0 : 0, Z(o["margin-bottom"]) ?? 0),
|
|
1691
|
-
left: (g.left ?? 0) +
|
|
1692
|
-
right: (g.right ?? 0) +
|
|
1693
|
-
}, c = Object.fromEntries(Object.entries(o).filter(([e]) => !/^(margin|padding)(-|$)/.test(e))),
|
|
1694
|
-
r.push(...
|
|
1943
|
+
left: (g.left ?? 0) + it(f, "left") + it(o, "left"),
|
|
1944
|
+
right: (g.right ?? 0) + it(f, "right") + it(o, "right")
|
|
1945
|
+
}, c = Object.fromEntries(Object.entries(o).filter(([e]) => !/^(margin|padding)(-|$)/.test(e))), l = D(i.childNodes, c, a, s);
|
|
1946
|
+
r.push(...T(E(l.length ? l : [{ xml: S([], c, a, s) }], o, p.get(i)), o));
|
|
1695
1947
|
}
|
|
1696
|
-
|
|
1697
|
-
} else i.localName === "div" && Array.from(i.children).some((e) =>
|
|
1948
|
+
l.push(...T(E(r, f, g.htmlPath), f));
|
|
1949
|
+
} else i.localName === "div" && Array.from(i.children).some((e) => et.has(e.localName)) ? l.push(...T(E(D(i.childNodes, at(f), a, {
|
|
1698
1950
|
...g,
|
|
1699
|
-
left: (g.left ?? 0) +
|
|
1700
|
-
right: (g.right ?? 0) +
|
|
1701
|
-
before: Math.max(g.before ?? 0, Z(
|
|
1702
|
-
after: Math.max(g.after ?? 0, Z(
|
|
1703
|
-
}),
|
|
1951
|
+
left: (g.left ?? 0) + it(f, "left"),
|
|
1952
|
+
right: (g.right ?? 0) + it(f, "right"),
|
|
1953
|
+
before: Math.max(g.before ?? 0, Z(f["margin-top"]) ?? 0),
|
|
1954
|
+
after: Math.max(g.after ?? 0, Z(f["margin-bottom"]) ?? 0)
|
|
1955
|
+
}), f, g.htmlPath), f)) : i.localName === "div" && !i.children.length && !i.textContent && f["page-break-before"] === "always" && Array.from(i.style).every((e) => ["page-break-before", "break-before"].includes(e)) ? l.push({
|
|
1704
1956
|
xml: "",
|
|
1705
1957
|
marker: !0
|
|
1706
|
-
}) : i.localName === "hr" ? (
|
|
1958
|
+
}) : i.localName === "hr" ? (B(t, "rule-normalized", "Разделитель HTML преобразован в строку."), l.push(...T([{ xml: S([document.createTextNode("────────────────")], f, void 0, c) }], f))) : l.push(...T([{ xml: S(i.childNodes, f, a, g) }], f));
|
|
1707
1959
|
}
|
|
1708
|
-
return h(
|
|
1960
|
+
return h(f.length - 1), l;
|
|
1709
1961
|
}
|
|
1710
|
-
function
|
|
1962
|
+
function O(e) {
|
|
1711
1963
|
let t = "<w:p><w:pPr><w:pStyle w:val=\"AzHujjatPageBoundary\"/><w:pageBreakBefore/><w:spacing w:before=\"0\" w:after=\"0\" w:line=\"1\" w:lineRule=\"exact\"/></w:pPr></w:p>", n = "", r = !1, i = 0;
|
|
1712
1964
|
for (let a of e) {
|
|
1713
1965
|
if (a.marker) {
|
|
@@ -1719,12 +1971,12 @@ async function We(e, t, n = P(), r) {
|
|
|
1719
1971
|
}
|
|
1720
1972
|
return n + t.repeat(i);
|
|
1721
1973
|
}
|
|
1722
|
-
let
|
|
1974
|
+
let k = O(D(a.childNodes, v)) || "<w:p/>", A = c.map((e) => (d = `word/${e.kind}1.xml`, {
|
|
1723
1975
|
...e,
|
|
1724
|
-
xml:
|
|
1976
|
+
xml: O(D(e.root.childNodes, v)) || "<w:p/>"
|
|
1725
1977
|
}));
|
|
1726
|
-
if (new TextEncoder().encode(
|
|
1727
|
-
let
|
|
1978
|
+
if (new TextEncoder().encode(k + A.map((e) => e.xml).join("")).byteLength > 8387584) throw new z("После преобразования HTML документ превышает допустимый размер XML (8 МиБ).");
|
|
1979
|
+
let j = new Set("font-family font-size font-weight font-style color background-color text-align text-decoration text-transform vertical-align letter-spacing line-height margin margin-top margin-bottom margin-left margin-right text-indent width border border-style border-width border-color border-top border-right border-bottom border-left border-collapse table-layout padding padding-top padding-right padding-bottom padding-left page-break-before page-break-after page-break-inside break-before break-after break-inside".split(" "));
|
|
1728
1980
|
for (let e of [a, ...c.map((e) => e.root)]) for (let n of e.querySelectorAll("[style]")) for (let e of Array.from(n.style)) {
|
|
1729
1981
|
let r = n.style.getPropertyValue(e);
|
|
1730
1982
|
if (e === "text-decoration-line" && /^(none|underline|line-through|underline line-through|line-through underline)$/.test(r) || e === "text-decoration-style" && ["initial", "solid"].includes(r) || e === "text-decoration-color" && ["initial", "currentcolor"].includes(r) || e === "text-decoration-thickness" && ["initial", "auto"].includes(r)) continue;
|
|
@@ -1733,46 +1985,57 @@ async function We(e, t, n = P(), r) {
|
|
|
1733
1985
|
"baseline",
|
|
1734
1986
|
"sub",
|
|
1735
1987
|
"super"
|
|
1736
|
-
].includes(r) &&
|
|
1988
|
+
].includes(r) && B(t, "baseline-shift-lost", "Вертикальное смещение HTML-фрагмента не представлено в DOCX-адаптере.", "loss", {
|
|
1737
1989
|
stage: "import",
|
|
1738
|
-
location: { htmlPath:
|
|
1990
|
+
location: { htmlPath: p.get(n) },
|
|
1739
1991
|
before: r,
|
|
1740
1992
|
after: "baseline"
|
|
1741
1993
|
});
|
|
1742
|
-
let a =
|
|
1743
|
-
(o || !s && !
|
|
1994
|
+
let a = et.has(n.localName) && !["table", "hr"].includes(n.localName), o = e.startsWith("padding") && !i && (!a || !["padding-left", "padding-right"].includes(e)) || e.startsWith("border") && !i && n.localName !== "table" || e === "font-size" && rt(r) === void 0 || ["color", "background-color"].includes(e) && nt(r) === void 0, s = (n.localName === "tr" || n.localName === "img") && e === "height" && Z(r) !== void 0 && Z(r) >= 0;
|
|
1995
|
+
(o || !s && !j.has(e) && !/^border-(top|right|bottom|left)-(width|style|color)$/.test(e)) && B(t, "html-style-approximation", `Стиль ${e} может измениться при открытии HTML в DOCX-редакторе.`, "warning", {
|
|
1744
1996
|
stage: "import",
|
|
1745
|
-
location: { htmlPath:
|
|
1997
|
+
location: { htmlPath: p.get(n) },
|
|
1746
1998
|
before: r
|
|
1747
1999
|
});
|
|
1748
2000
|
}
|
|
1749
|
-
let
|
|
1750
|
-
|
|
1751
|
-
let
|
|
1752
|
-
for (let { kind: e, xml: t } of
|
|
1753
|
-
let
|
|
1754
|
-
|
|
1755
|
-
let
|
|
1756
|
-
|
|
2001
|
+
let M = new b();
|
|
2002
|
+
M.file("[Content_Types].xml", "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/><Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/><Override PartName=\"/word/numbering.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\"/></Types>"), M.file("_rels/.rels", "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/></Relationships>"), M.file("word/_rels/document.xml.rels", "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rIdStyles\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rIdNumbering\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/></Relationships>");
|
|
2003
|
+
let N = n.page, P = "http://schemas.openxmlformats.org/officeDocument/2006/relationships", ee = A.map(({ kind: e }) => `<w:${e}Reference w:type="default" r:id="rId${e}"/>`).join("");
|
|
2004
|
+
for (let { kind: e, xml: t } of A) M.file(`word/${e}1.xml`, `<w:${e === "header" ? "hdr" : "ftr"} xmlns:w="${V}">${t}</w:${e === "header" ? "hdr" : "ftr"}>`);
|
|
2005
|
+
let I = await M.file("[Content_Types].xml").async("string");
|
|
2006
|
+
M.file("[Content_Types].xml", I.replace("</Types>", A.map(({ kind: e }) => `<Override PartName="/word/${e}1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${e}+xml"/>`).join("") + "</Types>"));
|
|
2007
|
+
let L = await M.file("word/_rels/document.xml.rels").async("string");
|
|
2008
|
+
if (M.file("word/_rels/document.xml.rels", L.replace("</Relationships>", A.map(({ kind: e }) => `<Relationship Id="rId${e}" Type="${P}/${e}" Target="${e}1.xml"/>`).join("") + "</Relationships>")), l.size) {
|
|
2009
|
+
M.file("[Content_Types].xml", (await M.file("[Content_Types].xml").async("string")).replace("</Types>", "<Default Extension=\"png\" ContentType=\"image/png\"/><Default Extension=\"jpg\" ContentType=\"image/jpeg\"/></Types>"));
|
|
2010
|
+
for (let e of l.values()) M.file(`word/${e.path}`, e.data);
|
|
2011
|
+
for (let [e, t] of u) {
|
|
2012
|
+
let n = `word/_rels/${e.slice(5)}.rels`, r = await M.file(n)?.async("string") ?? "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"></Relationships>", i = Array.from(t, (e) => {
|
|
2013
|
+
let t = l.get(e);
|
|
2014
|
+
return `<Relationship Id="rIdImage${t.id}" Type="${Re}/image" Target="${t.path}"/>`;
|
|
2015
|
+
}).join("");
|
|
2016
|
+
M.file(n, r.replace("</Relationships>", i + "</Relationships>"));
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
return M.file("word/document.xml", `<w:document xmlns:w="${V}" xmlns:r="${P}"><w:body>${k}<w:sectPr>${ee}<w:pgSz w:w="${N.widthTwips}" w:h="${N.heightTwips}" w:orient="${N.orientation}"/><w:pgMar ${Object.entries(N.margins).map(([e, t]) => `w:${e}="${t}"`).join(" ")}/></w:sectPr></w:body></w:document>`), M.file("word/styles.xml", `<w:styles xmlns:w="${V}"><w:docDefaults><w:rPrDefault><w:rPr>${y(v)}</w:rPr></w:rPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:pPr><w:spacing w:after="120"/></w:pPr></w:style><w:style w:type="paragraph" w:styleId="AzHujjatListContinuation"><w:name w:val="List continuation"/><w:basedOn w:val="Normal"/></w:style><w:style w:type="paragraph" w:styleId="AzHujjatPageBoundary"><w:name w:val="Page boundary"/><w:basedOn w:val="Normal"/></w:style></w:styles>`), M.file("word/numbering.xml", `<w:numbering xmlns:w="${V}">${s.map(({ id: e, tag: t }) => `<w:abstractNum w:abstractNumId="${e}"><w:multiLevelType w:val="singleLevel"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:numFmt w:val="${t === "ol" ? "decimal" : "bullet"}"/><w:lvlText w:val="${t === "ol" ? "%1." : "•"}"/><w:pPr><w:ind w:left="360" w:hanging="180"/></w:pPr></w:lvl></w:abstractNum><w:num w:numId="${e}"><w:abstractNumId w:val="${e}"/></w:num>`).join("")}</w:numbering>`), new Uint8Array(await M.generateAsync({
|
|
1757
2020
|
type: "arraybuffer",
|
|
1758
2021
|
compression: "DEFLATE"
|
|
1759
2022
|
}));
|
|
1760
2023
|
}
|
|
1761
2024
|
//#endregion
|
|
1762
2025
|
//#region src/library/hujjat/docx.ts
|
|
1763
|
-
async function
|
|
2026
|
+
async function st(e, t) {
|
|
1764
2027
|
let n = t.page === void 0 ? t.locales?.[t.locale]?.page : t.page;
|
|
1765
|
-
|
|
1766
|
-
let r = await
|
|
1767
|
-
return i.warnings.unshift(...r.warnings), i.layout = r.layout, i.page =
|
|
1768
|
-
}
|
|
1769
|
-
async function
|
|
1770
|
-
let r =
|
|
1771
|
-
r.page =
|
|
1772
|
-
let i =
|
|
1773
|
-
|
|
1774
|
-
let a = await
|
|
1775
|
-
return
|
|
2028
|
+
Fe(n);
|
|
2029
|
+
let r = await Ke(e, t.layout, n), i = xe(t.locales ?? {}, t.locale, r.html);
|
|
2030
|
+
return i.warnings.unshift(...r.warnings), i.layout = r.layout, i.page = Ie(r.page, i), i.page !== void 0 && (i.locales[t.locale].page = structuredClone(i.page)), se(i.warnings, t.allowLossy), i;
|
|
2031
|
+
}
|
|
2032
|
+
async function ct(e, t, n = {}) {
|
|
2033
|
+
let r = ve(be(e, t));
|
|
2034
|
+
r.page = Ie(e[t]?.page, r);
|
|
2035
|
+
let i = Le(r.page, n.layout);
|
|
2036
|
+
re(i.page, Le(r.page).page) || B(r.warnings, "layout-not-carried-by-html", "Геометрия layout отличается от настроек page на сервере. Текущий PDF-контракт поддерживает только ориентацию A4 и фиксированные поля.", "warning", { stage: "import" });
|
|
2037
|
+
let a = await ot(r.html, r.warnings, i, r.page);
|
|
2038
|
+
return se(r.warnings, n.allowLossy), {
|
|
1776
2039
|
...r,
|
|
1777
2040
|
document: a,
|
|
1778
2041
|
layout: i
|
|
@@ -1780,22 +2043,22 @@ async function Ke(e, t, n = {}) {
|
|
|
1780
2043
|
}
|
|
1781
2044
|
//#endregion
|
|
1782
2045
|
//#region src/library/document-diagnostics.ts
|
|
1783
|
-
async function
|
|
1784
|
-
if (e.byteLength > 31457280) throw new
|
|
1785
|
-
let t = await
|
|
1786
|
-
if (Object.keys(t.files).length > 2e3) throw new
|
|
1787
|
-
let [n, r] = await Promise.all([
|
|
1788
|
-
if (!i) throw new
|
|
1789
|
-
let a = [], o =
|
|
2046
|
+
async function lt(e) {
|
|
2047
|
+
if (e.byteLength > 31457280) throw new z("DOCX превышает 30 МиБ.");
|
|
2048
|
+
let t = await b.loadAsync(e);
|
|
2049
|
+
if (Object.keys(t.files).length > 2e3) throw new z("В DOCX более 2000 частей.");
|
|
2050
|
+
let [n, r] = await Promise.all([J(t, "word/document.xml"), J(t, "word/styles.xml")]), i = U(n?.documentElement, "body");
|
|
2051
|
+
if (!i) throw new z("Нет структуры документа Word.");
|
|
2052
|
+
let a = [], o = U(r?.documentElement, "docDefaults"), s = U(U(o, "pPrDefault"), "pPr"), c = Y(U(U(o, "rPrDefault"), "rPr")), l = new Map(H(r?.documentElement, "style").map((e) => [W(e, "styleId"), e])), u = H(r?.documentElement, "style").find((e) => W(e, "type") === "paragraph" && W(e, "default") === "1");
|
|
1790
2053
|
function d(e, t = /* @__PURE__ */ new Set()) {
|
|
1791
2054
|
if (!e || t.has(e) || t.size >= 30) return [];
|
|
1792
2055
|
t.add(e);
|
|
1793
2056
|
let n = l.get(e);
|
|
1794
|
-
return n ? [...d(
|
|
2057
|
+
return n ? [...d(G(n, "basedOn"), t), n] : [];
|
|
1795
2058
|
}
|
|
1796
|
-
let f = Array.from(i.getElementsByTagNameNS(
|
|
2059
|
+
let f = Array.from(i.getElementsByTagNameNS(V, "sectPr")), p = (e) => [U(e, "pgSz"), U(e, "pgMar")].map((e) => Array.from(e?.attributes ?? []).map((e) => [e.localName, e.value]).sort()).flat();
|
|
1797
2060
|
return f.forEach((e, t) => {
|
|
1798
|
-
t && JSON.stringify(p(e)) !== JSON.stringify(p(f[0])) &&
|
|
2061
|
+
t && JSON.stringify(p(e)) !== JSON.stringify(p(f[0])) && B(a, "source-section-layout", "Раздел использует другую геометрию. Она сохраняется в DOCX; единый профиль HTML её не описывает.", "warning", {
|
|
1799
2062
|
stage: "import",
|
|
1800
2063
|
location: {
|
|
1801
2064
|
part: "word/document.xml",
|
|
@@ -1804,18 +2067,18 @@ async function qe(e) {
|
|
|
1804
2067
|
before: JSON.stringify(p(e)),
|
|
1805
2068
|
after: JSON.stringify(p(e))
|
|
1806
2069
|
});
|
|
1807
|
-
}), Array.from(i.getElementsByTagNameNS(
|
|
2070
|
+
}), Array.from(i.getElementsByTagNameNS(V, "p")).forEach((e, t) => {
|
|
1808
2071
|
let n = {
|
|
1809
2072
|
part: "word/document.xml",
|
|
1810
2073
|
paragraphIndex: t
|
|
1811
|
-
}, r =
|
|
2074
|
+
}, r = U(e, "pPr"), i = d(G(r, "pStyle") || W(u, "styleId")), o = Ae([
|
|
1812
2075
|
s,
|
|
1813
|
-
...i.map((e) =>
|
|
2076
|
+
...i.map((e) => U(e, "pPr")),
|
|
1814
2077
|
r
|
|
1815
|
-
]), l =
|
|
1816
|
-
Array.from(e.getElementsByTagNameNS(
|
|
1817
|
-
let r =
|
|
1818
|
-
i["--az-hidden"] !== "1" && (f.push(i), Number(i["--az-position"]) &&
|
|
2078
|
+
]), l = Te(c, i.map((e) => U(e, "rPr"))), f = [Y(U(r, "rPr"), l)];
|
|
2079
|
+
Array.from(e.getElementsByTagNameNS(V, "r")).forEach((e, t) => {
|
|
2080
|
+
let r = U(e, "rPr"), i = Y(r, Te(l, d(G(r, "rStyle")).map((e) => U(e, "rPr"))));
|
|
2081
|
+
i["--az-hidden"] !== "1" && (f.push(i), Number(i["--az-position"]) && B(a, "source-baseline-shift", "Исходный фрагмент смещён по вертикали; сохранён без нормализации.", "warning", {
|
|
1819
2082
|
stage: "import",
|
|
1820
2083
|
location: {
|
|
1821
2084
|
...n,
|
|
@@ -1824,12 +2087,12 @@ async function qe(e) {
|
|
|
1824
2087
|
before: Number(i["--az-position"]) / 2,
|
|
1825
2088
|
after: Number(i["--az-position"]) / 2
|
|
1826
2089
|
}));
|
|
1827
|
-
}), o && (o.rule === "auto" ? o.value < 240 : o.value / 20 <
|
|
2090
|
+
}), o && (o.rule === "auto" ? o.value < 240 : o.value / 20 < Me(f)) && B(a, "source-tight-spacing", "Авторский тесный интервал сохранён. Проверьте наложение строк на используемых шрифтах.", "warning", {
|
|
1828
2091
|
stage: "import",
|
|
1829
2092
|
location: n,
|
|
1830
2093
|
before: `${o.rule}:${o.value}`,
|
|
1831
2094
|
after: `${o.rule}:${o.value}`
|
|
1832
|
-
}), [...Array.from(e.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "t")).map((e) => e.textContent ?? "").join("").matchAll(/\{([^{}]+)\}/g)].some((e) => !
|
|
2095
|
+
}), [...Array.from(e.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "t")).map((e) => e.textContent ?? "").join("").matchAll(/\{([^{}]+)\}/g)].some((e) => !ce(e[1])) && B(a, "invalid-variable", "В абзаце есть некорректный ключ переменной. Имя и исходный текст не изменены.", "warning", {
|
|
1833
2096
|
stage: "import",
|
|
1834
2097
|
location: n
|
|
1835
2098
|
});
|
|
@@ -1837,7 +2100,7 @@ async function qe(e) {
|
|
|
1837
2100
|
}
|
|
1838
2101
|
//#endregion
|
|
1839
2102
|
//#region src/library/font-diagnostics.ts
|
|
1840
|
-
function
|
|
2103
|
+
function ut(e) {
|
|
1841
2104
|
let t = 0, n = !1, r = !1, i = 0, a = [], o = /* @__PURE__ */ new Set(), s = {
|
|
1842
2105
|
state: typeof e == "function" ? "loading" : "unknown",
|
|
1843
2106
|
warnings: []
|
|
@@ -1854,7 +2117,7 @@ function Je(e) {
|
|
|
1854
2117
|
let r = (e, t) => e.family.toLowerCase() === t.family.toLowerCase() && e.weight === t.weight && e.style === t.style;
|
|
1855
2118
|
if (e.sources?.some((e) => r(e.request, n.from) && e.bytes.byteLength && e.availability !== "forbidden")) continue;
|
|
1856
2119
|
let i = (e) => `${e.family} (${e.weight}, ${e.style})`;
|
|
1857
|
-
|
|
2120
|
+
B(a, "font-redirect", "Настроена подстановка начертания шрифта. Сравните её с источником и PDF.", "warning", {
|
|
1858
2121
|
stage: "fonts",
|
|
1859
2122
|
before: i(n.from),
|
|
1860
2123
|
after: i(n.to)
|
|
@@ -1862,8 +2125,8 @@ function Je(e) {
|
|
|
1862
2125
|
}
|
|
1863
2126
|
}
|
|
1864
2127
|
}, u = (e) => {
|
|
1865
|
-
r = !0,
|
|
1866
|
-
}, d = typeof e == "function" ?
|
|
2128
|
+
r = !0, B(a, "font-load-failed", `Не удалось подготовить шрифт (${e}). Разметка может использовать замену или оценочные метрики.`, "warning", { stage: "fonts" }), c();
|
|
2129
|
+
}, d = typeof e == "function" ? x(async (n) => {
|
|
1867
2130
|
let r = i;
|
|
1868
2131
|
t++, c();
|
|
1869
2132
|
try {
|
|
@@ -1892,17 +2155,17 @@ function Je(e) {
|
|
|
1892
2155
|
}
|
|
1893
2156
|
//#endregion
|
|
1894
2157
|
//#region src/library/EditorMount.tsx
|
|
1895
|
-
var
|
|
1896
|
-
function
|
|
1897
|
-
let t =
|
|
2158
|
+
var dt = /* @__PURE__ */ new WeakMap(), ft = e(() => {});
|
|
2159
|
+
function pt(e) {
|
|
2160
|
+
let t = dt.get(e);
|
|
1898
2161
|
return t || (t = {
|
|
1899
2162
|
count: 0,
|
|
1900
2163
|
overflow: e.body.style.overflow
|
|
1901
|
-
},
|
|
1902
|
-
--t.count === 0 && (e.body.style.overflow = t.overflow,
|
|
2164
|
+
}, dt.set(e, t), e.body.style.overflow = "hidden"), ++t.count, () => {
|
|
2165
|
+
--t.count === 0 && (e.body.style.overflow = t.overflow, dt.delete(e));
|
|
1903
2166
|
};
|
|
1904
2167
|
}
|
|
1905
|
-
function
|
|
2168
|
+
function mt({ expanded: e, onCollapse: t, retainSelection: r, className: i, style: a, children: s }) {
|
|
1906
2169
|
let u = c(null), d = c(t), f = c(r), p = c(null), m = n(() => {
|
|
1907
2170
|
p.current?.(), p.current = null;
|
|
1908
2171
|
}, []);
|
|
@@ -1958,7 +2221,7 @@ function Qe({ expanded: e, onCollapse: t, retainSelection: r, className: i, styl
|
|
|
1958
2221
|
]) t.removeEventListener(e, g, !0);
|
|
1959
2222
|
};
|
|
1960
2223
|
if (!e) return _;
|
|
1961
|
-
let v =
|
|
2224
|
+
let v = pt(t), y = (e) => {
|
|
1962
2225
|
e.key !== "Escape" || e.defaultPrevented || t.querySelectorAll("[data-az-fullscreen=\"true\"]").item(t.querySelectorAll("[data-az-fullscreen=\"true\"]").length - 1) === h && (Array.from(t.querySelectorAll("[role=\"dialog\"], [role=\"menu\"], [role=\"listbox\"], [data-az-print-root]")).some((e) => !n.includes(e) && e.getClientRects().length && getComputedStyle(e).visibility !== "hidden") || (e.preventDefault(), e.stopImmediatePropagation(), d.current()));
|
|
1963
2226
|
};
|
|
1964
2227
|
return t.addEventListener("keydown", y, !0), () => {
|
|
@@ -1968,20 +2231,210 @@ function Qe({ expanded: e, onCollapse: t, retainSelection: r, className: i, styl
|
|
|
1968
2231
|
h,
|
|
1969
2232
|
e,
|
|
1970
2233
|
i
|
|
1971
|
-
]), /* @__PURE__ */
|
|
2234
|
+
]), /* @__PURE__ */ w("div", {
|
|
1972
2235
|
ref: u,
|
|
1973
2236
|
className: ["az-document-editor", i].filter(Boolean).join(" "),
|
|
1974
2237
|
style: a,
|
|
1975
|
-
children: h &&
|
|
2238
|
+
children: h && S(/* @__PURE__ */ w(ft, {
|
|
1976
2239
|
value: m,
|
|
1977
2240
|
children: s
|
|
1978
2241
|
}), h)
|
|
1979
2242
|
});
|
|
1980
2243
|
}
|
|
1981
2244
|
//#endregion
|
|
2245
|
+
//#region src/library/image-insertion.ts
|
|
2246
|
+
var ht = 10485760, gt = 2048;
|
|
2247
|
+
function _t(e, t) {
|
|
2248
|
+
if (!e || !t || e > 4096 || t > 4096 || e * t > 16777216) throw Error("Слишком большое изображение. Максимум — 4096 пикселей по стороне и 16 мегапикселей.");
|
|
2249
|
+
}
|
|
2250
|
+
function vt(e, t) {
|
|
2251
|
+
return new Promise((n, r) => e.toBlob((e) => e ? n(e) : r(/* @__PURE__ */ Error("Не удалось подготовить изображение.")), t, .86));
|
|
2252
|
+
}
|
|
2253
|
+
async function yt(e, t) {
|
|
2254
|
+
if (e.size > ht) throw Error("Файл слишком большой. Выберите PNG или JPEG размером до 10 МБ.");
|
|
2255
|
+
t.throwIfAborted();
|
|
2256
|
+
let n = new Uint8Array(await e.arrayBuffer());
|
|
2257
|
+
t.throwIfAborted();
|
|
2258
|
+
let r = P(n);
|
|
2259
|
+
_t(r.width, r.height);
|
|
2260
|
+
let i;
|
|
2261
|
+
try {
|
|
2262
|
+
i = await createImageBitmap(new Blob([n], { type: r.mime }), { imageOrientation: "from-image" });
|
|
2263
|
+
} catch {
|
|
2264
|
+
throw Error("Не удалось прочитать изображение. Выберите исправный PNG или JPEG.");
|
|
2265
|
+
}
|
|
2266
|
+
try {
|
|
2267
|
+
t.throwIfAborted(), _t(i.width, i.height);
|
|
2268
|
+
let n = document.createElement("canvas"), a = Math.min(1, gt / Math.max(i.width, i.height));
|
|
2269
|
+
for (let o = 0; o < 18; o++) {
|
|
2270
|
+
t.throwIfAborted(), n.width = Math.max(1, Math.round(i.width * a)), n.height = Math.max(1, Math.round(i.height * a));
|
|
2271
|
+
let o = n.getContext("2d");
|
|
2272
|
+
if (!o) throw Error("Браузер не поддерживает подготовку изображений.");
|
|
2273
|
+
o.drawImage(i, 0, 0, n.width, n.height);
|
|
2274
|
+
let s = await vt(n, r.mime);
|
|
2275
|
+
if (t.throwIfAborted(), s.size <= 262144) {
|
|
2276
|
+
let n = new Uint8Array(await s.arrayBuffer());
|
|
2277
|
+
t.throwIfAborted();
|
|
2278
|
+
let r = P(n), i = Math.min(.75, 400 / r.width, 500 / r.height);
|
|
2279
|
+
return {
|
|
2280
|
+
data: n,
|
|
2281
|
+
mime: r.mime,
|
|
2282
|
+
widthPoints: r.width * i,
|
|
2283
|
+
heightPoints: r.height * i,
|
|
2284
|
+
description: Array.from(e.name).slice(0, 500).join("")
|
|
2285
|
+
};
|
|
2286
|
+
}
|
|
2287
|
+
a *= .75;
|
|
2288
|
+
}
|
|
2289
|
+
throw Error("Не удалось уменьшить изображение до 256 КБ. Выберите другой файл.");
|
|
2290
|
+
} finally {
|
|
2291
|
+
i.close();
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
//#endregion
|
|
2295
|
+
//#region src/library/ImageInsertControl.tsx
|
|
2296
|
+
function bt(e, t) {
|
|
2297
|
+
return e.anchor.paragraphId === t.anchor.paragraphId && e.anchor.offset === t.anchor.offset && e.head.paragraphId === t.head.paragraphId && e.head.offset === t.head.offset;
|
|
2298
|
+
}
|
|
2299
|
+
function xt({ disabled: e, documentKey: t }) {
|
|
2300
|
+
let n = h(), r = _((e) => !e.editable || e.isLoading || !!e.isOpening || !!e.parseError), i = e || r, a = c(!1), s = c(null), u = c(null), [d, f] = l(!1), [p, m] = l("");
|
|
2301
|
+
function v(e) {
|
|
2302
|
+
e.controller.abort(), e.pin && e.editor.releaseSelection(e.pin), u.current === e && (u.current = null);
|
|
2303
|
+
}
|
|
2304
|
+
o(() => {
|
|
2305
|
+
a.current = !i, i && u.current && (v(u.current), f(!1));
|
|
2306
|
+
}, [i]), o(() => (f(!1), m(""), () => {
|
|
2307
|
+
u.current && v(u.current);
|
|
2308
|
+
}), [n, t]), o(() => {
|
|
2309
|
+
let e = s.current, t = () => {
|
|
2310
|
+
u.current && v(u.current), f(!1);
|
|
2311
|
+
};
|
|
2312
|
+
return e?.addEventListener("cancel", t), () => e?.removeEventListener("cancel", t);
|
|
2313
|
+
}, []), g("change", () => {
|
|
2314
|
+
let e = u.current;
|
|
2315
|
+
e && !e.committing && (v(e), f(!1));
|
|
2316
|
+
}), g("selectionChange", () => {
|
|
2317
|
+
let e = u.current;
|
|
2318
|
+
e && e.editor.getDocumentHandle().revision === e.revision && !bt(e.surface.state().selection, e.selection) && (v(e), f(!1));
|
|
2319
|
+
});
|
|
2320
|
+
function y(e) {
|
|
2321
|
+
let t = e.editor.snapshot();
|
|
2322
|
+
return u.current === e && !e.controller.signal.aborted && a.current && e.editor.surface === e.surface && e.editor.mountGeneration === e.generation && e.editor.getDocumentHandle().revision === e.revision && bt(e.surface.state().selection, e.selection) && t.editable && t.selectionCollapsed && !t.isLoading && !t.isOpening && !t.parseError;
|
|
2323
|
+
}
|
|
2324
|
+
function b() {
|
|
2325
|
+
n?.surface && a.current && !d && (u.current && v(u.current), n.snapshot().selectionCollapsed ? (m(""), u.current = {
|
|
2326
|
+
editor: n,
|
|
2327
|
+
surface: n.surface,
|
|
2328
|
+
pin: n.retainSelection(),
|
|
2329
|
+
revision: n.getDocumentHandle().revision,
|
|
2330
|
+
generation: n.mountGeneration,
|
|
2331
|
+
selection: structuredClone(n.surface.state().selection),
|
|
2332
|
+
controller: new AbortController(),
|
|
2333
|
+
committing: !1
|
|
2334
|
+
}, s.current && (s.current.value = "", s.current.click())) : m("Установите курсор в месте вставки изображения."));
|
|
2335
|
+
}
|
|
2336
|
+
async function x(e) {
|
|
2337
|
+
let t = e.target.files?.[0];
|
|
2338
|
+
e.target.value = "";
|
|
2339
|
+
let n = u.current;
|
|
2340
|
+
if (n) {
|
|
2341
|
+
if (!t) v(n);
|
|
2342
|
+
else {
|
|
2343
|
+
f(!0);
|
|
2344
|
+
try {
|
|
2345
|
+
let e = await yt(t, n.controller.signal);
|
|
2346
|
+
if (u.current !== n || !a.current) return;
|
|
2347
|
+
if (!y(n)) throw Error("Документ или позиция курсора изменились. Выберите изображение ещё раз.");
|
|
2348
|
+
n.editor.focus();
|
|
2349
|
+
let r = {
|
|
2350
|
+
type: "insertImage",
|
|
2351
|
+
...e,
|
|
2352
|
+
expectedPackageRevision: n.revision
|
|
2353
|
+
}, i = n.editor.canExecuteImageCommand(r);
|
|
2354
|
+
if (!i.ok) throw Error(`Не удалось вставить изображение: ${i.reason}`);
|
|
2355
|
+
let { paragraphId: o, offset: s } = n.selection.anchor, c = E(n.surface.layout(), o, s), l = n.editor.getPageSetup(), d = l ? (l.pageWidthTwips - l.marginsTwips.left - l.marginsTwips.right - (l.gutterTwips ?? 0)) / 20 : 400, f = l ? (l.pageHeightTwips - l.marginsTwips.top - l.marginsTwips.bottom) / 20 : 500, p = c && c.box.width > 0 ? Math.min(c.box.width, d) : d, m = Math.min(1, p / e.widthPoints, f / e.heightPoints);
|
|
2356
|
+
n.committing = !0;
|
|
2357
|
+
let h = await n.surface.insertImage({
|
|
2358
|
+
paragraphId: o,
|
|
2359
|
+
offset: s,
|
|
2360
|
+
bytes: e.data,
|
|
2361
|
+
mime: e.mime,
|
|
2362
|
+
description: e.description,
|
|
2363
|
+
widthPoints: e.widthPoints * m,
|
|
2364
|
+
heightPoints: e.heightPoints * m,
|
|
2365
|
+
expectedPackageRevision: n.revision,
|
|
2366
|
+
commitGuard: () => !!(y(n) && n.editor.canExecuteImageCommand(r).ok)
|
|
2367
|
+
});
|
|
2368
|
+
if (!h.ok) {
|
|
2369
|
+
let e = h.detail ?? h.reason;
|
|
2370
|
+
throw Error(e === "cross-cell-drawing" ? "В этой ячейке установите курсор в начале или конце текста и повторите вставку изображения." : `Не удалось вставить изображение: ${e}`);
|
|
2371
|
+
}
|
|
2372
|
+
u.current === n && a.current && n.editor.focus();
|
|
2373
|
+
} catch (e) {
|
|
2374
|
+
u.current === n && !n.controller.signal.aborted && m(e instanceof Error ? e.message : "Не удалось вставить изображение.");
|
|
2375
|
+
} finally {
|
|
2376
|
+
u.current === n && (v(n), f(!1));
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
return /* @__PURE__ */ T("div", {
|
|
2382
|
+
className: "az-image-insert-control",
|
|
2383
|
+
children: [
|
|
2384
|
+
/* @__PURE__ */ w("button", {
|
|
2385
|
+
type: "button",
|
|
2386
|
+
className: "az-image-insert-button",
|
|
2387
|
+
"aria-label": "Вставить изображение",
|
|
2388
|
+
title: d ? "Подготовка изображения…" : "Вставить изображение",
|
|
2389
|
+
disabled: !!(i || d),
|
|
2390
|
+
"aria-busy": d,
|
|
2391
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
2392
|
+
onClick: b,
|
|
2393
|
+
children: /* @__PURE__ */ T("svg", {
|
|
2394
|
+
width: "20",
|
|
2395
|
+
height: "20",
|
|
2396
|
+
viewBox: "0 0 24 24",
|
|
2397
|
+
fill: "none",
|
|
2398
|
+
stroke: "currentColor",
|
|
2399
|
+
strokeWidth: "1.6",
|
|
2400
|
+
"aria-hidden": "true",
|
|
2401
|
+
children: [
|
|
2402
|
+
/* @__PURE__ */ w("rect", {
|
|
2403
|
+
x: "3",
|
|
2404
|
+
y: "3",
|
|
2405
|
+
width: "18",
|
|
2406
|
+
height: "18",
|
|
2407
|
+
rx: "2"
|
|
2408
|
+
}),
|
|
2409
|
+
/* @__PURE__ */ w("circle", {
|
|
2410
|
+
cx: "8",
|
|
2411
|
+
cy: "8",
|
|
2412
|
+
r: "1.5"
|
|
2413
|
+
}),
|
|
2414
|
+
/* @__PURE__ */ w("path", { d: "m3 17 5-5 4 4 4-6 5 7" })
|
|
2415
|
+
]
|
|
2416
|
+
})
|
|
2417
|
+
}),
|
|
2418
|
+
/* @__PURE__ */ w("input", {
|
|
2419
|
+
ref: s,
|
|
2420
|
+
type: "file",
|
|
2421
|
+
accept: "image/png,image/jpeg,.png,.jpg,.jpeg",
|
|
2422
|
+
"aria-label": "Файл изображения",
|
|
2423
|
+
hidden: !0,
|
|
2424
|
+
onChange: (e) => void x(e)
|
|
2425
|
+
}),
|
|
2426
|
+
p && /* @__PURE__ */ w("div", {
|
|
2427
|
+
role: "alert",
|
|
2428
|
+
className: "az-image-insert-error",
|
|
2429
|
+
children: p
|
|
2430
|
+
})
|
|
2431
|
+
]
|
|
2432
|
+
});
|
|
2433
|
+
}
|
|
2434
|
+
//#endregion
|
|
1982
2435
|
//#region src/library/EditorFrame.tsx
|
|
1983
|
-
function
|
|
1984
|
-
let t = h(), n =
|
|
2436
|
+
function St({ forwardedRef: e }) {
|
|
2437
|
+
let t = h(), n = _((e) => e.zoom), i = r(ft);
|
|
1985
2438
|
return o(i, [n, i]), a(e, () => ({
|
|
1986
2439
|
load: (e) => {
|
|
1987
2440
|
t?.load(e);
|
|
@@ -2000,7 +2453,7 @@ function $e({ forwardedRef: e }) {
|
|
|
2000
2453
|
snapshot: (e) => t?.snapshot(e) ?? f
|
|
2001
2454
|
}), [t]), null;
|
|
2002
2455
|
}
|
|
2003
|
-
function
|
|
2456
|
+
function Ct({ forwardedRef: e, ...t }) {
|
|
2004
2457
|
let n = m(), [r, a] = l(() => typeof matchMedia < "u" && matchMedia("(prefers-color-scheme: dark)").matches);
|
|
2005
2458
|
i(() => {
|
|
2006
2459
|
if (t.colorMode !== "system") return;
|
|
@@ -2008,15 +2461,15 @@ function et({ forwardedRef: e, ...t }) {
|
|
|
2008
2461
|
return n(), e.addEventListener("change", n), () => e.removeEventListener("change", n);
|
|
2009
2462
|
}, [t.colorMode]);
|
|
2010
2463
|
let o = t.colorMode === "dark" || t.colorMode === "system" && r, c = t.chrome !== !1, u = c && t.rulers !== !1, f = s(() => ({
|
|
2011
|
-
hyperlink: (e) => /* @__PURE__ */
|
|
2012
|
-
contentControl: (e) => /* @__PURE__ */
|
|
2013
|
-
equation: () => /* @__PURE__ */
|
|
2014
|
-
contextMenu: t.contextMenu === !1 ? !1 : (e) => /* @__PURE__ */
|
|
2464
|
+
hyperlink: (e) => /* @__PURE__ */ w(d.HyperLink, { ...e }),
|
|
2465
|
+
contentControl: (e) => /* @__PURE__ */ w(d.ContentControl, { ...e }),
|
|
2466
|
+
equation: () => /* @__PURE__ */ w(d.Equation, {}),
|
|
2467
|
+
contextMenu: t.contextMenu === !1 ? !1 : (e) => /* @__PURE__ */ w(d.ContextMenu, {
|
|
2015
2468
|
...e,
|
|
2016
2469
|
t: n
|
|
2017
2470
|
})
|
|
2018
2471
|
}), [t.contextMenu, n]);
|
|
2019
|
-
return /* @__PURE__ */
|
|
2472
|
+
return /* @__PURE__ */ T(d.Root, {
|
|
2020
2473
|
document: t.document,
|
|
2021
2474
|
fonts: t.fonts,
|
|
2022
2475
|
locale: t.locale,
|
|
@@ -2027,22 +2480,22 @@ function et({ forwardedRef: e, ...t }) {
|
|
|
2027
2480
|
onChange: t.onChange,
|
|
2028
2481
|
onFontError: t.onFontError,
|
|
2029
2482
|
popups: f,
|
|
2030
|
-
children: [/* @__PURE__ */
|
|
2483
|
+
children: [/* @__PURE__ */ w(St, { forwardedRef: e }), /* @__PURE__ */ T("div", {
|
|
2031
2484
|
className: [
|
|
2032
2485
|
"docx-editor",
|
|
2033
2486
|
"az-editor-frame",
|
|
2034
2487
|
o && "dark"
|
|
2035
2488
|
].filter(Boolean).join(" "),
|
|
2036
2489
|
children: [
|
|
2037
|
-
c && /* @__PURE__ */
|
|
2490
|
+
c && /* @__PURE__ */ T("div", {
|
|
2038
2491
|
className: "az-editor-chrome",
|
|
2039
|
-
children: [t.titleBar !== !1 && /* @__PURE__ */
|
|
2492
|
+
children: [t.titleBar !== !1 && /* @__PURE__ */ T("div", {
|
|
2040
2493
|
className: "az-editor-titlebar",
|
|
2041
2494
|
children: [
|
|
2042
2495
|
t.renderTitleBarLeft?.(),
|
|
2043
|
-
/* @__PURE__ */
|
|
2496
|
+
/* @__PURE__ */ T("div", {
|
|
2044
2497
|
className: "az-editor-title",
|
|
2045
|
-
children: [/* @__PURE__ */
|
|
2498
|
+
children: [/* @__PURE__ */ w("span", { children: t.title }), t.menu !== !1 && /* @__PURE__ */ w(d.Menu, {
|
|
2046
2499
|
t: n,
|
|
2047
2500
|
fileName: t.title,
|
|
2048
2501
|
onOpen: t.onOpen,
|
|
@@ -2052,23 +2505,30 @@ function et({ forwardedRef: e, ...t }) {
|
|
|
2052
2505
|
}),
|
|
2053
2506
|
t.renderTitleBarRight?.()
|
|
2054
2507
|
]
|
|
2055
|
-
}), /* @__PURE__ */
|
|
2508
|
+
}), /* @__PURE__ */ T("div", {
|
|
2056
2509
|
className: "az-editor-toolbar-row",
|
|
2057
|
-
children: [
|
|
2510
|
+
children: [
|
|
2511
|
+
/* @__PURE__ */ w(d.Toolbar, { t: n }),
|
|
2512
|
+
/* @__PURE__ */ w(xt, {
|
|
2513
|
+
disabled: t.imagesDisabled || t.mode === "view",
|
|
2514
|
+
documentKey: t.document
|
|
2515
|
+
}),
|
|
2516
|
+
t.controls
|
|
2517
|
+
]
|
|
2058
2518
|
})]
|
|
2059
2519
|
}),
|
|
2060
|
-
u && /* @__PURE__ */
|
|
2520
|
+
u && /* @__PURE__ */ w("div", {
|
|
2061
2521
|
className: "az-editor-ruler-row",
|
|
2062
2522
|
"data-testid": "docx-editor-ruler-row",
|
|
2063
2523
|
"data-ruler-unit": t.rulerUnit,
|
|
2064
|
-
children: /* @__PURE__ */
|
|
2524
|
+
children: /* @__PURE__ */ w(d.HorizontalRuler, { unit: t.rulerUnit })
|
|
2065
2525
|
}),
|
|
2066
|
-
c && /* @__PURE__ */
|
|
2067
|
-
/* @__PURE__ */
|
|
2526
|
+
c && /* @__PURE__ */ w(d.FontNotice, { t: n }),
|
|
2527
|
+
/* @__PURE__ */ T("div", {
|
|
2068
2528
|
className: "az-editor-workspace",
|
|
2069
2529
|
children: [
|
|
2070
|
-
c && t.navigation !== !1 && /* @__PURE__ */
|
|
2071
|
-
/* @__PURE__ */
|
|
2530
|
+
c && t.navigation !== !1 && /* @__PURE__ */ w(d.Navigation, {}),
|
|
2531
|
+
/* @__PURE__ */ T(d.Viewport, {
|
|
2072
2532
|
className: o ? "dark" : void 0,
|
|
2073
2533
|
style: {
|
|
2074
2534
|
flex: 1,
|
|
@@ -2077,38 +2537,38 @@ function et({ forwardedRef: e, ...t }) {
|
|
|
2077
2537
|
overflowAnchor: "none"
|
|
2078
2538
|
},
|
|
2079
2539
|
children: [
|
|
2080
|
-
c && /* @__PURE__ */
|
|
2081
|
-
/* @__PURE__ */
|
|
2082
|
-
u && /* @__PURE__ */
|
|
2540
|
+
c && /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w(d.HeaderFooterChrome, {}), /* @__PURE__ */ w(d.NotesChrome, {})] }),
|
|
2541
|
+
/* @__PURE__ */ w(d.Content, {}),
|
|
2542
|
+
u && /* @__PURE__ */ w("div", {
|
|
2083
2543
|
className: "az-editor-vertical-ruler",
|
|
2084
2544
|
"data-ruler-unit": t.rulerUnit,
|
|
2085
|
-
children: /* @__PURE__ */
|
|
2545
|
+
children: /* @__PURE__ */ w(d.VerticalRuler, { unit: t.rulerUnit })
|
|
2086
2546
|
}),
|
|
2087
2547
|
t.children
|
|
2088
2548
|
]
|
|
2089
2549
|
}),
|
|
2090
|
-
c && /* @__PURE__ */
|
|
2550
|
+
c && /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w(d.PageNumber, {}), /* @__PURE__ */ w(d.Loading, { overlay: !0 })] })
|
|
2091
2551
|
]
|
|
2092
2552
|
})
|
|
2093
2553
|
]
|
|
2094
2554
|
})]
|
|
2095
2555
|
});
|
|
2096
2556
|
}
|
|
2097
|
-
var
|
|
2098
|
-
return /* @__PURE__ */
|
|
2557
|
+
var wt = t(function(e, t) {
|
|
2558
|
+
return /* @__PURE__ */ w(p, {
|
|
2099
2559
|
i18n: e.i18n,
|
|
2100
|
-
children: /* @__PURE__ */
|
|
2560
|
+
children: /* @__PURE__ */ w(Ct, {
|
|
2101
2561
|
...e,
|
|
2102
2562
|
forwardedRef: t
|
|
2103
2563
|
})
|
|
2104
2564
|
});
|
|
2105
|
-
}),
|
|
2106
|
-
function
|
|
2565
|
+
}), Tt = () => {};
|
|
2566
|
+
function Et({ onStatusChange: e, fonts: t }) {
|
|
2107
2567
|
let n = c(e);
|
|
2108
2568
|
o(() => {
|
|
2109
2569
|
n.current = e;
|
|
2110
2570
|
});
|
|
2111
|
-
let r =
|
|
2571
|
+
let r = _((e) => e.page.total), a = _((e) => e.isLoading || !!e.isOpening) || t.state === "loading", l = _((e) => e.parseError), u = _((e) => e.fontSubstitutions), d = s(() => {
|
|
2112
2572
|
let e = [...t.warnings, ...(u ?? []).map((e) => ({
|
|
2113
2573
|
code: "font-unavailable",
|
|
2114
2574
|
message: `Шрифт ${e} недоступен движку.`,
|
|
@@ -2139,20 +2599,20 @@ function rt({ onStatusChange: e, fonts: t }) {
|
|
|
2139
2599
|
d
|
|
2140
2600
|
]), null;
|
|
2141
2601
|
}
|
|
2142
|
-
var
|
|
2143
|
-
let n = c(null), r = c(null), f = c(null), [p, m] = l(""), [h, g] = l(!1),
|
|
2602
|
+
var Dt = t(function(e, t) {
|
|
2603
|
+
let n = c(null), r = c(null), f = c(null), [p, m] = l(""), [h, g] = l(!1), _ = e.fullscreen ?? h, b = (t) => {
|
|
2144
2604
|
e.fullscreen === void 0 && g(t), e.onFullscreenChange?.(t);
|
|
2145
|
-
}, x = s(() =>
|
|
2605
|
+
}, x = s(() => y(), []), S = v(x), E = e.fonts ?? S, O = s(() => ut(E), [E]), k = u(O.subscribe, O.snapshot, O.snapshot), A = c(e), N = c(0), P = c(!1), ee = c(O);
|
|
2146
2606
|
o(() => {
|
|
2147
|
-
|
|
2607
|
+
A.current = e, ee.current = O;
|
|
2148
2608
|
}), o(() => {
|
|
2149
2609
|
O.reset();
|
|
2150
2610
|
}, [O, e.document]);
|
|
2151
|
-
async function
|
|
2152
|
-
if (!
|
|
2611
|
+
async function te(e, t) {
|
|
2612
|
+
if (!A.current.onDiagnostics) return;
|
|
2153
2613
|
let n;
|
|
2154
2614
|
try {
|
|
2155
|
-
n = await
|
|
2615
|
+
n = await lt(e);
|
|
2156
2616
|
} catch {
|
|
2157
2617
|
n = [{
|
|
2158
2618
|
code: "diagnostics-unavailable",
|
|
@@ -2161,28 +2621,28 @@ var it = t(function(e, t) {
|
|
|
2161
2621
|
stage: "import"
|
|
2162
2622
|
}];
|
|
2163
2623
|
}
|
|
2164
|
-
P.current && t === N.current &&
|
|
2624
|
+
P.current && t === N.current && A.current.onDiagnostics?.(n);
|
|
2165
2625
|
}
|
|
2166
2626
|
i(() => {
|
|
2167
2627
|
P.current = !0;
|
|
2168
2628
|
let t = ++N.current;
|
|
2169
|
-
return
|
|
2629
|
+
return A.current.onDiagnostics?.([]), e.document && e.document !== "blank" && te(e.document, t), () => {
|
|
2170
2630
|
P.current = !1, ++N.current;
|
|
2171
2631
|
};
|
|
2172
2632
|
}, [e.document]);
|
|
2173
|
-
let
|
|
2174
|
-
function
|
|
2633
|
+
let F = (t) => e.ui !== !1 && e.ui?.[t] !== !1;
|
|
2634
|
+
function I(e) {
|
|
2175
2635
|
let t = r.current?.querySelector("[data-menu=\"file\"] > [role=\"menuitem\"][aria-expanded=\"true\"]");
|
|
2176
2636
|
t?.click(), t?.focus(), e();
|
|
2177
2637
|
}
|
|
2178
|
-
async function
|
|
2638
|
+
async function L() {
|
|
2179
2639
|
let t = n.current?.getEditor();
|
|
2180
2640
|
if (!t || !r.current || t.snapshot().isLoading || t.snapshot().parseError || window.document.querySelector("[data-az-print-root]")) return;
|
|
2181
2641
|
f.current?.abort();
|
|
2182
2642
|
let i = new AbortController();
|
|
2183
2643
|
f.current = i, m("");
|
|
2184
2644
|
try {
|
|
2185
|
-
await
|
|
2645
|
+
await M(t, r.current, e.title ?? "Документ.docx", i.signal);
|
|
2186
2646
|
} catch (e) {
|
|
2187
2647
|
!i.signal.aborted && !(e instanceof DOMException && e.name === "AbortError") && m(e instanceof Error ? e.message : "Не удалось подготовить PDF.");
|
|
2188
2648
|
}
|
|
@@ -2200,17 +2660,17 @@ var it = t(function(e, t) {
|
|
|
2200
2660
|
if (s && t.contains(s)) return;
|
|
2201
2661
|
r.preventDefault(), r.stopImmediatePropagation();
|
|
2202
2662
|
let c = n.current?.getEditor(), l = c?.snapshot();
|
|
2203
|
-
!c || !l?.editable || l.isLoading || l.isOpening || l.parseError || e.mode === "view" || e.actionsDisabled ||
|
|
2663
|
+
!c || !l?.editable || l.isLoading || l.isOpening || l.parseError || e.mode === "view" || e.actionsDisabled || k.state === "loading" || (a === "undo" ? l.canUndo : l.canRedo) && c.exec({ type: a });
|
|
2204
2664
|
};
|
|
2205
2665
|
return t.addEventListener("keydown", i, !0), () => t.removeEventListener("keydown", i, !0);
|
|
2206
2666
|
}, [
|
|
2207
2667
|
e.mode,
|
|
2208
2668
|
e.actionsDisabled,
|
|
2209
|
-
|
|
2669
|
+
k.state
|
|
2210
2670
|
]), i(() => {
|
|
2211
2671
|
let t = (t) => {
|
|
2212
|
-
if (t.defaultPrevented || !(t.ctrlKey || t.metaKey) || t.altKey || t.shiftKey || !r.current || !
|
|
2213
|
-
let n = t.code === "KeyS" ? e.onSave : t.code === "KeyO" ? e.onOpen : t.code === "KeyP" &&
|
|
2672
|
+
if (t.defaultPrevented || !(t.ctrlKey || t.metaKey) || t.altKey || t.shiftKey || !r.current || !j(r.current, t.target) || window.document.querySelector("[data-az-print-root]") || t.code !== "KeyS" && t.code !== "KeyO" && !(t.code === "KeyP" && F("print"))) return;
|
|
2673
|
+
let n = t.code === "KeyS" ? e.onSave : t.code === "KeyO" ? e.onOpen : t.code === "KeyP" && F("print") ? () => void L() : void 0;
|
|
2214
2674
|
t.preventDefault(), t.stopImmediatePropagation(), e.actionsDisabled || n?.();
|
|
2215
2675
|
};
|
|
2216
2676
|
return window.addEventListener("keydown", t, !0), () => window.removeEventListener("keydown", t, !0);
|
|
@@ -2218,25 +2678,25 @@ var it = t(function(e, t) {
|
|
|
2218
2678
|
async save() {
|
|
2219
2679
|
let e = N.current, t = await n.current?.save();
|
|
2220
2680
|
if (!t) throw Error("Документ ещё не готов к сохранению.");
|
|
2221
|
-
return
|
|
2681
|
+
return te(t, e), t;
|
|
2222
2682
|
},
|
|
2223
2683
|
async exportHujjat(e) {
|
|
2224
2684
|
let t = await n.current?.save();
|
|
2225
|
-
if (!t) throw new
|
|
2226
|
-
return
|
|
2685
|
+
if (!t) throw new z("Документ ещё не готов к экспорту.");
|
|
2686
|
+
return st(t, e);
|
|
2227
2687
|
},
|
|
2228
2688
|
insertVariable(e) {
|
|
2229
|
-
if (!
|
|
2689
|
+
if (!ce(e)) throw new z("Некорректный ключ переменной. Используйте client.name, ASCII, до 100 символов.");
|
|
2230
2690
|
let t = n.current?.exec({
|
|
2231
2691
|
type: "pasteWithoutFormatting",
|
|
2232
2692
|
text: `{${e}}`
|
|
2233
2693
|
});
|
|
2234
|
-
if (!t?.ok) throw new
|
|
2694
|
+
if (!t?.ok) throw new z(t && !t.ok ? t.reason : "Редактор ещё не готов.");
|
|
2235
2695
|
n.current?.focus();
|
|
2236
2696
|
},
|
|
2237
2697
|
setParagraphPagination(t) {
|
|
2238
2698
|
let r = n.current?.getEditor()?.snapshot();
|
|
2239
|
-
if (!r || r.isLoading || r.isOpening || r.parseError ||
|
|
2699
|
+
if (!r || r.isLoading || r.isOpening || r.parseError || k.state === "loading" || e.mode === "view" || e.actionsDisabled) throw new z("Редактор недоступен для изменения.");
|
|
2240
2700
|
let i = {};
|
|
2241
2701
|
for (let e of [
|
|
2242
2702
|
"keepNext",
|
|
@@ -2244,7 +2704,7 @@ var it = t(function(e, t) {
|
|
|
2244
2704
|
"widowControl",
|
|
2245
2705
|
"pageBreakBefore"
|
|
2246
2706
|
]) if (t[e] !== void 0) {
|
|
2247
|
-
if (typeof t[e] != "boolean") throw new
|
|
2707
|
+
if (typeof t[e] != "boolean") throw new z("Правила абзаца должны быть boolean.");
|
|
2248
2708
|
i[e] = t[e];
|
|
2249
2709
|
}
|
|
2250
2710
|
if (!Object.keys(i).length) return;
|
|
@@ -2252,17 +2712,17 @@ var it = t(function(e, t) {
|
|
|
2252
2712
|
type: "setParagraphFormat",
|
|
2253
2713
|
...i
|
|
2254
2714
|
});
|
|
2255
|
-
if (!a.ok) throw new
|
|
2715
|
+
if (!a.ok) throw new z(a.reason);
|
|
2256
2716
|
n.current?.focus();
|
|
2257
2717
|
},
|
|
2258
2718
|
focus() {
|
|
2259
2719
|
n.current?.focus();
|
|
2260
2720
|
},
|
|
2261
|
-
print:
|
|
2262
|
-
})), /* @__PURE__ */
|
|
2721
|
+
print: L
|
|
2722
|
+
})), /* @__PURE__ */ w(mt, {
|
|
2263
2723
|
className: e.className,
|
|
2264
2724
|
style: e.style,
|
|
2265
|
-
expanded:
|
|
2725
|
+
expanded: _,
|
|
2266
2726
|
onCollapse: () => b(!1),
|
|
2267
2727
|
retainSelection: () => {
|
|
2268
2728
|
let e = n.current?.getEditor(), t = e?.retainSelection();
|
|
@@ -2270,37 +2730,38 @@ var it = t(function(e, t) {
|
|
|
2270
2730
|
e?.focus(), t && e?.releaseSelection(t);
|
|
2271
2731
|
};
|
|
2272
2732
|
},
|
|
2273
|
-
children: /* @__PURE__ */
|
|
2733
|
+
children: /* @__PURE__ */ T("div", {
|
|
2274
2734
|
className: "az-editor-content",
|
|
2275
2735
|
ref: r,
|
|
2276
|
-
children: [p && /* @__PURE__ */
|
|
2736
|
+
children: [p && /* @__PURE__ */ w("div", {
|
|
2277
2737
|
role: "alert",
|
|
2278
2738
|
className: "az-print-error",
|
|
2279
2739
|
children: p
|
|
2280
|
-
}), /* @__PURE__ */
|
|
2740
|
+
}), /* @__PURE__ */ w(wt, {
|
|
2741
|
+
imagesDisabled: e.actionsDisabled || k.state === "loading",
|
|
2281
2742
|
ref: n,
|
|
2282
2743
|
document: e.document ?? "blank",
|
|
2283
2744
|
title: e.title ?? "Документ.docx",
|
|
2284
2745
|
fonts: O.fonts,
|
|
2285
2746
|
locale: e.locale ?? "ru-RU",
|
|
2286
|
-
i18n: e.i18n ??
|
|
2747
|
+
i18n: e.i18n ?? D,
|
|
2287
2748
|
mode: e.mode ?? "edit",
|
|
2288
2749
|
colorMode: e.colorMode ?? "light",
|
|
2289
2750
|
zoom: e.zoom,
|
|
2290
2751
|
zoomMode: e.zoomMode,
|
|
2291
|
-
chrome:
|
|
2292
|
-
rulers:
|
|
2752
|
+
chrome: F("chrome"),
|
|
2753
|
+
rulers: F("rulers"),
|
|
2293
2754
|
rulerUnit: e.rulerUnit ?? "cm",
|
|
2294
|
-
titleBar:
|
|
2295
|
-
controls: /* @__PURE__ */
|
|
2755
|
+
titleBar: F("titleBar"),
|
|
2756
|
+
controls: /* @__PURE__ */ T(C, { children: [e.renderToolbarEnd?.(), (F("fullscreen") || _) && /* @__PURE__ */ w("button", {
|
|
2296
2757
|
type: "button",
|
|
2297
2758
|
className: "az-fullscreen-toggle",
|
|
2298
|
-
"aria-expanded":
|
|
2299
|
-
title:
|
|
2300
|
-
"aria-label":
|
|
2759
|
+
"aria-expanded": _,
|
|
2760
|
+
title: _ ? e.labels?.collapse ?? "Свернуть редактор" : e.labels?.expand ?? "Развернуть на всю страницу",
|
|
2761
|
+
"aria-label": _ ? e.labels?.collapse ?? "Свернуть редактор" : e.labels?.expand ?? "Развернуть на всю страницу",
|
|
2301
2762
|
onMouseDown: (e) => e.preventDefault(),
|
|
2302
|
-
onClick: () => b(!
|
|
2303
|
-
children: /* @__PURE__ */
|
|
2763
|
+
onClick: () => b(!_),
|
|
2764
|
+
children: /* @__PURE__ */ w("svg", {
|
|
2304
2765
|
width: "20",
|
|
2305
2766
|
height: "20",
|
|
2306
2767
|
viewBox: "0 0 24 24",
|
|
@@ -2308,63 +2769,63 @@ var it = t(function(e, t) {
|
|
|
2308
2769
|
stroke: "currentColor",
|
|
2309
2770
|
strokeWidth: "1.6",
|
|
2310
2771
|
"aria-hidden": "true",
|
|
2311
|
-
children: /* @__PURE__ */
|
|
2772
|
+
children: /* @__PURE__ */ w("path", { d: _ ? "M3 8h5V3M16 3v5h5M21 16h-5v5M8 21v-5H3" : "M8 3H3v5M21 8V3h-5M16 21h5v-5M3 16v5h5" })
|
|
2312
2773
|
})
|
|
2313
2774
|
})] }),
|
|
2314
|
-
navigation:
|
|
2315
|
-
contextMenu:
|
|
2775
|
+
navigation: F("navigation"),
|
|
2776
|
+
contextMenu: F("contextMenu"),
|
|
2316
2777
|
renderTitleBarLeft: e.renderTitleBarLeft,
|
|
2317
2778
|
renderTitleBarRight: e.renderTitleBarRight,
|
|
2318
2779
|
onChange: (t) => {
|
|
2319
|
-
t.source || (++N.current,
|
|
2780
|
+
t.source || (++N.current, A.current.onDiagnostics?.([]), e.onChange?.());
|
|
2320
2781
|
},
|
|
2321
2782
|
onSave: e.onSave,
|
|
2322
2783
|
onOpen: e.onOpen,
|
|
2323
2784
|
onFontError: (e) => {
|
|
2324
|
-
|
|
2785
|
+
ee.current === O && P.current && (O.fail(e.code), A.current.onFontError?.(`Не удалось загрузить шрифт (${e.code}). Переносы могут отличаться от Word.`));
|
|
2325
2786
|
},
|
|
2326
|
-
menu:
|
|
2787
|
+
menu: F("menu") && {
|
|
2327
2788
|
reportIssue: !1,
|
|
2328
|
-
onOpen:
|
|
2329
|
-
onSave:
|
|
2330
|
-
children: /* @__PURE__ */
|
|
2789
|
+
onOpen: Tt,
|
|
2790
|
+
onSave: Tt,
|
|
2791
|
+
children: /* @__PURE__ */ T(d.Menu.File, {
|
|
2331
2792
|
preset: !1,
|
|
2332
2793
|
children: [
|
|
2333
|
-
e.fileActions?.map((t) => /* @__PURE__ */
|
|
2334
|
-
onSelect: () =>
|
|
2794
|
+
e.fileActions?.map((t) => /* @__PURE__ */ w(d.Menu.Row, {
|
|
2795
|
+
onSelect: () => I(t.onSelect),
|
|
2335
2796
|
disabled: e.actionsDisabled || t.disabled,
|
|
2336
2797
|
children: t.label
|
|
2337
2798
|
}, t.id)),
|
|
2338
|
-
e.onOpen && /* @__PURE__ */
|
|
2339
|
-
onSelect: () =>
|
|
2799
|
+
e.onOpen && /* @__PURE__ */ w(d.Menu.Row, {
|
|
2800
|
+
onSelect: () => I(e.onOpen),
|
|
2340
2801
|
disabled: e.actionsDisabled,
|
|
2341
2802
|
shortcut: "Ctrl+O",
|
|
2342
|
-
children: e.labels?.open ?? e.i18n?.toolbar?.open ??
|
|
2803
|
+
children: e.labels?.open ?? e.i18n?.toolbar?.open ?? D.toolbar?.open
|
|
2343
2804
|
}),
|
|
2344
|
-
e.onSave && /* @__PURE__ */
|
|
2345
|
-
onSelect: () =>
|
|
2805
|
+
e.onSave && /* @__PURE__ */ w(d.Menu.Row, {
|
|
2806
|
+
onSelect: () => I(e.onSave),
|
|
2346
2807
|
disabled: e.actionsDisabled,
|
|
2347
2808
|
shortcut: "Ctrl+S",
|
|
2348
|
-
children: e.labels?.save ?? e.i18n?.toolbar?.save ??
|
|
2809
|
+
children: e.labels?.save ?? e.i18n?.toolbar?.save ?? D.toolbar?.save
|
|
2349
2810
|
}),
|
|
2350
|
-
e.onExportPdf && /* @__PURE__ */
|
|
2351
|
-
onSelect: () =>
|
|
2811
|
+
e.onExportPdf && /* @__PURE__ */ w(d.Menu.Row, {
|
|
2812
|
+
onSelect: () => I(e.onExportPdf),
|
|
2352
2813
|
disabled: e.actionsDisabled,
|
|
2353
2814
|
children: e.labels?.exportPdf ?? "Скачать PDF"
|
|
2354
2815
|
}),
|
|
2355
|
-
|
|
2356
|
-
onSelect: () =>
|
|
2816
|
+
F("print") && /* @__PURE__ */ w(d.Menu.Row, {
|
|
2817
|
+
onSelect: () => I(() => void L()),
|
|
2357
2818
|
disabled: e.actionsDisabled,
|
|
2358
2819
|
shortcut: "Ctrl+P",
|
|
2359
2820
|
children: e.labels?.print ?? "Распечатать…"
|
|
2360
2821
|
}),
|
|
2361
|
-
/* @__PURE__ */
|
|
2822
|
+
/* @__PURE__ */ w(d.Menu.PageSetup, {})
|
|
2362
2823
|
]
|
|
2363
2824
|
})
|
|
2364
2825
|
},
|
|
2365
|
-
children: /* @__PURE__ */
|
|
2826
|
+
children: /* @__PURE__ */ w(Et, {
|
|
2366
2827
|
onStatusChange: e.onStatusChange,
|
|
2367
|
-
fonts:
|
|
2828
|
+
fonts: k
|
|
2368
2829
|
})
|
|
2369
2830
|
})]
|
|
2370
2831
|
})
|
|
@@ -2372,12 +2833,12 @@ var it = t(function(e, t) {
|
|
|
2372
2833
|
});
|
|
2373
2834
|
//#endregion
|
|
2374
2835
|
//#region src/library/AzHtmlEditor.tsx
|
|
2375
|
-
function
|
|
2836
|
+
function Ot(...e) {
|
|
2376
2837
|
let t = /* @__PURE__ */ new Map();
|
|
2377
2838
|
for (let n of e.flat()) t.set(JSON.stringify(n), n);
|
|
2378
2839
|
return [...t.values()];
|
|
2379
2840
|
}
|
|
2380
|
-
var
|
|
2841
|
+
var kt = t(function(e, t) {
|
|
2381
2842
|
let { initialHtml: r, layout: s, page: u, onChange: d, onStatusChange: f, renderFallback: p, ...m } = e, [h] = l(r), [g] = l(() => structuredClone(u)), [_] = l(() => s ? {
|
|
2382
2843
|
...s,
|
|
2383
2844
|
page: s.page ? {
|
|
@@ -2390,7 +2851,7 @@ var ot = t(function(e, t) {
|
|
|
2390
2851
|
pages: 0,
|
|
2391
2852
|
error: null,
|
|
2392
2853
|
warnings: []
|
|
2393
|
-
}), S = c(b),
|
|
2854
|
+
}), S = c(b), C = c(null), E = c(null), D = c(!1), O = c(0), k = c(0), A = c(e);
|
|
2394
2855
|
o(() => {
|
|
2395
2856
|
A.current = e;
|
|
2396
2857
|
});
|
|
@@ -2406,7 +2867,7 @@ var ot = t(function(e, t) {
|
|
|
2406
2867
|
error: null
|
|
2407
2868
|
});
|
|
2408
2869
|
try {
|
|
2409
|
-
let n = await
|
|
2870
|
+
let n = await ct({ uz: {
|
|
2410
2871
|
blocks: [{
|
|
2411
2872
|
type: "html",
|
|
2412
2873
|
props: { html: h.trim() ? h : "<p><br></p>" }
|
|
@@ -2420,7 +2881,7 @@ var ot = t(function(e, t) {
|
|
|
2420
2881
|
E.current = n, y(n.document), j({ warnings: n.warnings });
|
|
2421
2882
|
} catch (e) {
|
|
2422
2883
|
if (!D.current || t !== O.current) return;
|
|
2423
|
-
let n = e instanceof
|
|
2884
|
+
let n = e instanceof z ? e.warnings : [];
|
|
2424
2885
|
j({
|
|
2425
2886
|
phase: n.some((e) => e.severity === "loss") ? "blocked" : "error",
|
|
2426
2887
|
warnings: n,
|
|
@@ -2446,12 +2907,12 @@ var ot = t(function(e, t) {
|
|
|
2446
2907
|
});
|
|
2447
2908
|
}, [j]), P = n(() => {
|
|
2448
2909
|
D.current && ["ready", "exporting"].includes(S.current.phase) && (++k.current, j({ dirty: !0 }), A.current.onChange?.());
|
|
2449
|
-
}, [j]),
|
|
2910
|
+
}, [j]), ee = n((e) => {
|
|
2450
2911
|
D.current && e === O.current && S.current.phase === "exporting" && j({ phase: "ready" });
|
|
2451
2912
|
}, [j]);
|
|
2452
2913
|
return a(t, () => ({
|
|
2453
2914
|
async exportHtml(e = {}) {
|
|
2454
|
-
if (!D.current || S.current.phase !== "ready" || !E.current || !
|
|
2915
|
+
if (!D.current || S.current.phase !== "ready" || !E.current || !C.current) throw new z("HTML-редактор ещё не готов или занят.");
|
|
2455
2916
|
let t = E.current, n = t.warnings.some((e) => e.code === "line-height-normalized");
|
|
2456
2917
|
if (!S.current.dirty && !n) return {
|
|
2457
2918
|
html: h,
|
|
@@ -2467,15 +2928,15 @@ var ot = t(function(e, t) {
|
|
|
2467
2928
|
error: null
|
|
2468
2929
|
});
|
|
2469
2930
|
try {
|
|
2470
|
-
let n = await
|
|
2931
|
+
let n = await C.current.exportHujjat({
|
|
2471
2932
|
locale: "uz",
|
|
2472
2933
|
allowLossy: !0,
|
|
2473
2934
|
layout: _,
|
|
2474
2935
|
page: t.page
|
|
2475
2936
|
});
|
|
2476
|
-
if (!D.current || r !== O.current || i !== k.current) throw new
|
|
2477
|
-
let a =
|
|
2478
|
-
return j({ warnings: a }),
|
|
2937
|
+
if (!D.current || r !== O.current || i !== k.current) throw new z("Черновик изменился или закрыт во время экспорта. Повторите экспорт актуального документа.");
|
|
2938
|
+
let a = Ot(t.warnings, n.warnings);
|
|
2939
|
+
return j({ warnings: a }), se(a, e.allowLossy), {
|
|
2479
2940
|
html: n.html,
|
|
2480
2941
|
variables: n.variables,
|
|
2481
2942
|
warnings: a,
|
|
@@ -2484,23 +2945,23 @@ var ot = t(function(e, t) {
|
|
|
2484
2945
|
changed: !0
|
|
2485
2946
|
};
|
|
2486
2947
|
} finally {
|
|
2487
|
-
|
|
2948
|
+
ee(r);
|
|
2488
2949
|
}
|
|
2489
2950
|
},
|
|
2490
2951
|
async acceptImportLoss() {
|
|
2491
|
-
if (!D.current || S.current.phase !== "blocked") throw new
|
|
2952
|
+
if (!D.current || S.current.phase !== "blocked") throw new z("Нет ожидающего решения об импорте.");
|
|
2492
2953
|
await M(!0);
|
|
2493
2954
|
},
|
|
2494
2955
|
insertVariable(e) {
|
|
2495
|
-
if (!D.current || S.current.phase !== "ready" || A.current.mode === "view" || !
|
|
2496
|
-
|
|
2956
|
+
if (!D.current || S.current.phase !== "ready" || A.current.mode === "view" || !C.current) throw new z("Редактор недоступен для изменения.");
|
|
2957
|
+
C.current.insertVariable(e);
|
|
2497
2958
|
},
|
|
2498
2959
|
focus() {
|
|
2499
|
-
|
|
2960
|
+
C.current?.focus();
|
|
2500
2961
|
},
|
|
2501
2962
|
setParagraphPagination(e) {
|
|
2502
|
-
if (!D.current || S.current.phase !== "ready" || A.current.mode === "view" || A.current.actionsDisabled || !
|
|
2503
|
-
|
|
2963
|
+
if (!D.current || S.current.phase !== "ready" || A.current.mode === "view" || A.current.actionsDisabled || !C.current) throw new z("Редактор недоступен для изменения.");
|
|
2964
|
+
C.current.setParagraphPagination(e);
|
|
2504
2965
|
}
|
|
2505
2966
|
}), [
|
|
2506
2967
|
h,
|
|
@@ -2508,10 +2969,10 @@ var ot = t(function(e, t) {
|
|
|
2508
2969
|
g,
|
|
2509
2970
|
M,
|
|
2510
2971
|
j,
|
|
2511
|
-
|
|
2512
|
-
]), v ? /* @__PURE__ */
|
|
2972
|
+
ee
|
|
2973
|
+
]), v ? /* @__PURE__ */ w(Dt, {
|
|
2513
2974
|
...m,
|
|
2514
|
-
ref:
|
|
2975
|
+
ref: C,
|
|
2515
2976
|
document: v,
|
|
2516
2977
|
ui: e.ui !== !1 && {
|
|
2517
2978
|
menu: !1,
|
|
@@ -2522,26 +2983,26 @@ var ot = t(function(e, t) {
|
|
|
2522
2983
|
actionsDisabled: e.actionsDisabled || b.phase !== "ready",
|
|
2523
2984
|
onChange: P,
|
|
2524
2985
|
onStatusChange: N
|
|
2525
|
-
}) : /* @__PURE__ */
|
|
2986
|
+
}) : /* @__PURE__ */ w("div", {
|
|
2526
2987
|
className: ["az-html-editor", e.className].filter(Boolean).join(" "),
|
|
2527
2988
|
style: e.style,
|
|
2528
|
-
children: p ? p(b) : /* @__PURE__ */
|
|
2989
|
+
children: p ? p(b) : /* @__PURE__ */ T("div", {
|
|
2529
2990
|
role: b.error ? "alert" : "status",
|
|
2530
|
-
children: [b.error ?? "Загрузка документа…", b.warnings.length > 0 && /* @__PURE__ */
|
|
2991
|
+
children: [b.error ?? "Загрузка документа…", b.warnings.length > 0 && /* @__PURE__ */ w("ul", { children: b.warnings.map((e, t) => /* @__PURE__ */ w("li", { children: e.message }, t)) })]
|
|
2531
2992
|
})
|
|
2532
2993
|
});
|
|
2533
|
-
}),
|
|
2534
|
-
function
|
|
2994
|
+
}), At = 31457280, jt = "application/vnd.openxmlformats-officedocument.wordprocessingml.document", Mt = `${jt}.main+xml`, Nt = 8388608, $ = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
2995
|
+
function Pt(e) {
|
|
2535
2996
|
let t = new DOMParser().parseFromString(e, "application/xml");
|
|
2536
2997
|
if (t.getElementsByTagName("parsererror").length || /<!DOCTYPE/i.test(e)) throw Error("XML документа повреждён или содержит неподдерживаемую структуру.");
|
|
2537
2998
|
return t;
|
|
2538
2999
|
}
|
|
2539
|
-
function
|
|
3000
|
+
function Ft(e, t) {
|
|
2540
3001
|
let n = e.file(t);
|
|
2541
3002
|
return n ? new Promise((e, t) => {
|
|
2542
3003
|
let r = n.internalStream("uint8array"), i = [], a = 0;
|
|
2543
3004
|
r.on("data", (e) => {
|
|
2544
|
-
a += e.byteLength, a >
|
|
3005
|
+
a += e.byteLength, a > Nt ? (r.pause(), t(/* @__PURE__ */ Error("Структура документа слишком большая для этого прототипа."))) : i.push(e);
|
|
2545
3006
|
}), r.on("error", t), r.on("end", () => {
|
|
2546
3007
|
let t = new Uint8Array(a), n = 0;
|
|
2547
3008
|
for (let e of i) t.set(e, n), n += e.byteLength;
|
|
@@ -2549,27 +3010,27 @@ function ft(e, t) {
|
|
|
2549
3010
|
}), r.resume();
|
|
2550
3011
|
}) : Promise.resolve("");
|
|
2551
3012
|
}
|
|
2552
|
-
async function
|
|
3013
|
+
async function It(e) {
|
|
2553
3014
|
if (!/\.docx$/i.test(e.name)) throw Error("Откройте файл DOCX. Форматы DOC, DOCM и PDF здесь не поддерживаются.");
|
|
2554
3015
|
if (!e.size) throw Error("Файл DOCX пуст.");
|
|
2555
3016
|
if (e.size > 31457280) throw Error("Максимальный размер DOCX — 30 МБ.");
|
|
2556
3017
|
let t = new Uint8Array(await e.arrayBuffer()), n;
|
|
2557
3018
|
try {
|
|
2558
|
-
n = await
|
|
3019
|
+
n = await b.loadAsync(t);
|
|
2559
3020
|
} catch {
|
|
2560
3021
|
throw Error("Файл повреждён, зашифрован или не является DOCX.");
|
|
2561
3022
|
}
|
|
2562
3023
|
let r = Object.keys(n.files);
|
|
2563
3024
|
if (r.length > 2e3) throw Error("Слишком много вложенных частей в DOCX для этого прототипа.");
|
|
2564
3025
|
if (!n.file("[Content_Types].xml") || !n.file("word/document.xml")) throw Error("Файл не содержит структуру DOCX.");
|
|
2565
|
-
let i =
|
|
2566
|
-
if (Array.from(i.getElementsByTagNameNS("*", "Override")).find((e) => e.getAttribute("PartName") === "/word/document.xml")?.getAttribute("ContentType") !==
|
|
2567
|
-
let a =
|
|
3026
|
+
let i = Pt(await Ft(n, "[Content_Types].xml"));
|
|
3027
|
+
if (Array.from(i.getElementsByTagNameNS("*", "Override")).find((e) => e.getAttribute("PartName") === "/word/document.xml")?.getAttribute("ContentType") !== Mt || r.some((e) => /vbaProject\.bin$/i.test(e))) throw Error("Поддерживается только обычный DOCX без макросов.");
|
|
3028
|
+
let a = Pt(await Ft(n, "word/document.xml"));
|
|
2568
3029
|
if (a.documentElement.localName !== "document" || !a.getElementsByTagNameNS($, "body").length) throw Error("XML документа повреждён или использует неподдерживаемую разновидность DOCX.");
|
|
2569
3030
|
let o = /* @__PURE__ */ new Set(), s = [a];
|
|
2570
3031
|
for (let e of ["word/styles.xml", "word/fontTable.xml"]) {
|
|
2571
|
-
let t = await
|
|
2572
|
-
t && s.push(
|
|
3032
|
+
let t = await Ft(n, e);
|
|
3033
|
+
t && s.push(Pt(t));
|
|
2573
3034
|
}
|
|
2574
3035
|
for (let e of s) {
|
|
2575
3036
|
for (let t of e.getElementsByTagNameNS($, "rFonts")) for (let e of [
|
|
@@ -2586,7 +3047,7 @@ async function pt(e) {
|
|
|
2586
3047
|
e && o.add(e);
|
|
2587
3048
|
}
|
|
2588
3049
|
}
|
|
2589
|
-
let c = await
|
|
3050
|
+
let c = await Ft(n, "docProps/app.xml"), l = c ? Number(Pt(c).getElementsByTagNameNS("*", "Pages")[0]?.textContent) : 0, { openDocumentForExport: u } = await import("@docx-editor.dev/core/export"), d = u(t.slice());
|
|
2590
3051
|
if (!d.ok) throw Error("Не удалось открыть структуру DOCX. Текущий документ сохранён в редакторе.");
|
|
2591
3052
|
return d.session.dispose(), {
|
|
2592
3053
|
name: e.name,
|
|
@@ -2603,16 +3064,16 @@ async function pt(e) {
|
|
|
2603
3064
|
}
|
|
2604
3065
|
};
|
|
2605
3066
|
}
|
|
2606
|
-
function
|
|
3067
|
+
function Lt(e) {
|
|
2607
3068
|
return `${(e.replace(/\.docx$/i, "").replace(/[<>:"/\\|?*\x00-\x1f]/g, "_").trim() || "Документ").replace(/ — редакция$/, "")} — редакция.docx`;
|
|
2608
3069
|
}
|
|
2609
|
-
function
|
|
2610
|
-
let n = URL.createObjectURL(new Blob([e], { type:
|
|
3070
|
+
function Rt(e, t) {
|
|
3071
|
+
let n = URL.createObjectURL(new Blob([e], { type: jt })), r = document.createElement("a");
|
|
2611
3072
|
r.href = n, r.download = t, document.body.append(r), r.click(), r.remove(), window.setTimeout(() => URL.revokeObjectURL(n), 3e4);
|
|
2612
3073
|
}
|
|
2613
3074
|
//#endregion
|
|
2614
3075
|
//#region src/library/pdf-export.ts
|
|
2615
|
-
async function
|
|
3076
|
+
async function zt(e, t, n, r = {}) {
|
|
2616
3077
|
let i = AbortSignal.any([AbortSignal.timeout(95e3), ...r.signal ? [r.signal] : []]);
|
|
2617
3078
|
i.throwIfAborted();
|
|
2618
3079
|
let a = new FormData();
|
|
@@ -2641,13 +3102,13 @@ async function gt(e, t, n, r = {}) {
|
|
|
2641
3102
|
warnings: (o.headers.get("x-pdf-warnings") ?? "").split(",").filter(Boolean)
|
|
2642
3103
|
};
|
|
2643
3104
|
}
|
|
2644
|
-
function
|
|
3105
|
+
function Bt(e) {
|
|
2645
3106
|
let t = URL.createObjectURL(e.blob), n = document.createElement("a");
|
|
2646
3107
|
n.href = t, n.download = e.filename, document.body.append(n), n.click(), n.remove(), setTimeout(() => URL.revokeObjectURL(t), 6e4);
|
|
2647
3108
|
}
|
|
2648
3109
|
//#endregion
|
|
2649
3110
|
//#region src/library/pdf-profile.ts
|
|
2650
|
-
var
|
|
3111
|
+
var Vt = {
|
|
2651
3112
|
id: "az-editor-pdf-a0c6eaaeb90716f0",
|
|
2652
3113
|
protocolVersion: 1,
|
|
2653
3114
|
core: "2.27.0",
|
|
@@ -2794,19 +3255,19 @@ var vt = {
|
|
|
2794
3255
|
};
|
|
2795
3256
|
//#endregion
|
|
2796
3257
|
//#region src/library/hujjat/api.ts
|
|
2797
|
-
function
|
|
2798
|
-
if (!e || !Object.keys(e).length) throw new
|
|
3258
|
+
function Ht(e) {
|
|
3259
|
+
if (!e || !Object.keys(e).length) throw new z("Нет локалей шаблона.");
|
|
2799
3260
|
for (let [t, n] of Object.entries(e)) {
|
|
2800
|
-
if (
|
|
3261
|
+
if (ye(t), Fe(n?.page), !n || !Array.isArray(n.blocks) || !n.blocks.length) throw new z(`Нет блоков для ${t}.`);
|
|
2801
3262
|
for (let e of n.blocks) if (e.type === "html") {
|
|
2802
|
-
if (typeof e.props?.html != "string" || !e.props.html.trim()) throw new
|
|
2803
|
-
if (new TextEncoder().encode(e.props.html).length > 1048576) throw new
|
|
3263
|
+
if (typeof e.props?.html != "string" || !e.props.html.trim()) throw new z(`Пустой HTML для ${t}.`);
|
|
3264
|
+
if (new TextEncoder().encode(e.props.html).length > 1048576) throw new z(`HTML для ${t} превышает 1 МБ.`);
|
|
2804
3265
|
}
|
|
2805
3266
|
}
|
|
2806
3267
|
}
|
|
2807
|
-
function
|
|
2808
|
-
if (
|
|
2809
|
-
if (!e.productId || !e.name.trim() || e.name.length > 255) throw new
|
|
3268
|
+
function Ut(e, t) {
|
|
3269
|
+
if (Ht(t), !t.uz) throw new z("Для создания шаблона обязательна локаль uz.");
|
|
3270
|
+
if (!e.productId || !e.name.trim() || e.name.length > 255) throw new z("Укажите продукт и название шаблона до 255 символов.");
|
|
2810
3271
|
return {
|
|
2811
3272
|
product_id: e.productId,
|
|
2812
3273
|
name: e.name,
|
|
@@ -2814,11 +3275,11 @@ function bt(e, t) {
|
|
|
2814
3275
|
locales: structuredClone(t)
|
|
2815
3276
|
};
|
|
2816
3277
|
}
|
|
2817
|
-
async function
|
|
3278
|
+
async function Wt(e) {
|
|
2818
3279
|
let t = AbortSignal.any([AbortSignal.timeout(95e3), ...e.signal ? [e.signal] : []]);
|
|
2819
|
-
t.throwIfAborted(),
|
|
3280
|
+
t.throwIfAborted(), Ht(e.locales);
|
|
2820
3281
|
let n = e.locale ?? "uz";
|
|
2821
|
-
|
|
3282
|
+
ye(n);
|
|
2822
3283
|
let r = new Headers(e.headers);
|
|
2823
3284
|
r.set("Content-Type", "application/json"), r.set("Accept", "application/pdf, application/json");
|
|
2824
3285
|
let i = await (e.fetcher ?? fetch)(e.url, {
|
|
@@ -2846,4 +3307,4 @@ async function xt(e) {
|
|
|
2846
3307
|
};
|
|
2847
3308
|
}
|
|
2848
3309
|
//#endregion
|
|
2849
|
-
export {
|
|
3310
|
+
export { Dt as AzDocumentEditor, kt as AzHtmlEditor, jt as DOCX_MIME, ie as HUJJAT_LOCALES, Pe as HUJJAT_MAX_CHROME_BYTES, ae as HUJJAT_MAX_HTML_BYTES, I as HUJJAT_PAGE, z as HujjatCompatibilityError, At as MAX_DOCX_BYTES, lt as analyzeDocxFormatting, Ut as createHujjatTemplatePayload, Rt as downloadDocx, Bt as downloadPdf, Lt as exportFilename, st as exportHujjatDocx, ct as importHujjatTemplate, Vt as pdfRenderProfile, It as readDocxFile, be as readHujjatHtml, Wt as requestHujjatPreview, zt as requestPdf, R as resolveHtmlLayout, ve as sanitizeHujjatHtml, Fe as validateHujjatPage, ce as validateHujjatVariable, xe as withHujjatLocale };
|