dsh-desktop-kit 0.0.0-stage → 1.0.0
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/LICENSE +21 -0
- package/README.md +87 -2
- package/client.js +3349 -0
- package/cordis.patch.yml +5 -0
- package/index.js +80 -0
- package/package.json +60 -4
- package/plugins/dsh-gkb-ru-ui/cordis.patch.yml +6 -0
- package/plugins/dsh-gkb-ru-ui/lib/client.js +1083 -0
- package/plugins/dsh-gkb-ru-ui/lib/index.js +142 -0
- package/plugins/dsh-gkb-ru-ui/lib/skills.js +376 -0
- package/plugins/dsh-gkb-ru-ui/package.json +28 -0
- package/plugins/dsh-peak-guard/README.md +70 -0
- package/plugins/dsh-peak-guard/client.js +741 -0
- package/plugins/dsh-peak-guard/cordis.patch.yml +5 -0
- package/plugins/dsh-peak-guard/icon.svg +12 -0
- package/plugins/dsh-peak-guard/index.js +2 -0
- package/plugins/dsh-peak-guard/locale/en.json +6 -0
- package/plugins/dsh-peak-guard/locale/ru.json +6 -0
- package/plugins/dsh-peak-guard/locale/zh.json +6 -0
- package/plugins/dsh-peak-guard/package.json +33 -0
- package/plugins/dsh-profile-transfer/README.md +62 -0
- package/plugins/dsh-profile-transfer/bootstrap/01-INSTALL.cmd +7 -0
- package/plugins/dsh-profile-transfer/bootstrap/README-ARCHIVE.md +54 -0
- package/plugins/dsh-profile-transfer/bootstrap/README-/320/243/320/241/320/242/320/220/320/235/320/236/320/222/320/232/320/220.md +42 -0
- package/plugins/dsh-profile-transfer/bootstrap/install-on-clean-machine.ps1 +119 -0
- package/plugins/dsh-profile-transfer/bootstrap//320/243/320/241/320/242/320/220/320/235/320/236/320/222/320/230/320/242/320/254.cmd +5 -0
- package/plugins/dsh-profile-transfer/client.js +806 -0
- package/plugins/dsh-profile-transfer/cordis.patch.yml +3 -0
- package/plugins/dsh-profile-transfer/icon.svg +13 -0
- package/plugins/dsh-profile-transfer/index.js +375 -0
- package/plugins/dsh-profile-transfer/locale/en.json +6 -0
- package/plugins/dsh-profile-transfer/locale/ru.json +6 -0
- package/plugins/dsh-profile-transfer/locale/zh.json +6 -0
- package/plugins/dsh-profile-transfer/package.json +36 -0
- package/plugins/dsh-profile-transfer/transfer.js +1004 -0
- package/plugins/dsh-project-memory/README.md +71 -0
- package/plugins/dsh-project-memory/cordis.patch.yml +4 -0
- package/plugins/dsh-project-memory/icon.svg +12 -0
- package/plugins/dsh-project-memory/index.js +1240 -0
- package/plugins/dsh-project-memory/locale/en.json +6 -0
- package/plugins/dsh-project-memory/locale/ru.json +6 -0
- package/plugins/dsh-project-memory/locale/zh.json +6 -0
- package/plugins/dsh-project-memory/package.json +26 -0
- package/plugins/dsh-session-move/README.md +67 -0
- package/plugins/dsh-session-move/client.js +719 -0
- package/plugins/dsh-session-move/cordis.patch.yml +5 -0
- package/plugins/dsh-session-move/icon.svg +14 -0
- package/plugins/dsh-session-move/index.js +497 -0
- package/plugins/dsh-session-move/locale/en.json +6 -0
- package/plugins/dsh-session-move/locale/ru.json +6 -0
- package/plugins/dsh-session-move/locale/zh.json +6 -0
- package/plugins/dsh-session-move/package.json +31 -0
- package/skills/code-review-checklist/SKILL.md +37 -0
- package/skills/content-writing/README.md +87 -0
- package/skills/content-writing/SKILL.md +348 -0
- package/skills/content-writing/assets/checklists/fact-check.md +53 -0
- package/skills/content-writing/assets/checklists/publish.md +65 -0
- package/skills/content-writing/assets/checklists/social.md +40 -0
- package/skills/content-writing/assets/templates/article.md +47 -0
- package/skills/content-writing/assets/templates/brief.md +44 -0
- package/skills/content-writing/assets/templates/doctor-card.md +41 -0
- package/skills/content-writing/assets/templates/image-prompts.md +128 -0
- package/skills/content-writing/assets/templates/post-telegram.md +36 -0
- package/skills/content-writing/assets/templates/post-vk.md +42 -0
- package/skills/content-writing/assets/templates/press-release.md +56 -0
- package/skills/content-writing/assets/templates/science-pop-note.md +55 -0
- package/skills/content-writing/assets/templates/service-card.md +46 -0
- package/skills/content-writing/references/anti-ai-style.md +248 -0
- package/skills/content-writing/references/editing.md +185 -0
- package/skills/content-writing/references/fact-checking.md +205 -0
- package/skills/content-writing/references/government-medical.md +246 -0
- package/skills/content-writing/references/images.md +212 -0
- package/skills/content-writing/references/journalism.md +252 -0
- package/skills/content-writing/references/science-popular.md +218 -0
- package/skills/content-writing/references/seo-content.md +172 -0
- package/skills/content-writing/references/social-media.md +253 -0
- package/skills/content-writing/references/templates.md +291 -0
- package/skills/database-safety/SKILL.md +31 -0
- package/skills/debugging-playbook/SKILL.md +39 -0
- package/skills/design-critique/SKILL.md +118 -0
- package/skills/dev-workflow/SKILL.md +41 -0
- package/skills/git-and-ci/SKILL.md +40 -0
- package/skills/pg-upgrade-verify/SKILL.md +48 -0
- package/skills/project-deep-dive/SKILL.md +170 -0
- package/skills/project-deep-dive/references/recon-commands.md +78 -0
- package/skills/project-deep-dive/references/section-templates.md +102 -0
- package/skills/project-memory-maintenance/SKILL.md +170 -0
- package/skills/project-memory-maintenance/references/journal-template.md +48 -0
- package/skills/project-memory-maintenance/references/section-rules.md +57 -0
- package/skills/release-and-deploy/SKILL.md +39 -0
- package/skills/requirements-and-planning/SKILL.md +115 -0
- package/skills/security-review/SKILL.md +36 -0
- package/skills/seo/README.md +60 -0
- package/skills/seo/SKILL.md +329 -0
- package/skills/seo/assets/README.md +66 -0
- package/skills/seo/assets/scripts/LICENSE-playwright-core.txt +202 -0
- package/skills/seo/assets/scripts/README.md +179 -0
- package/skills/seo/assets/scripts/lib/args.mjs +105 -0
- package/skills/seo/assets/scripts/lib/browser.mjs +620 -0
- package/skills/seo/assets/scripts/lib/zip.mjs +191 -0
- package/skills/seo/assets/scripts/seo-audit.mjs +1675 -0
- package/skills/seo/assets/snippets/jsonld-breadcrumb.json +30 -0
- package/skills/seo/assets/snippets/jsonld-faq.json +39 -0
- package/skills/seo/assets/snippets/jsonld-medical-clinic.json +49 -0
- package/skills/seo/assets/snippets/jsonld-medical-webpage.json +33 -0
- package/skills/seo/assets/snippets/jsonld-organization.json +74 -0
- package/skills/seo/assets/snippets/jsonld-physician.json +46 -0
- package/skills/seo/assets/snippets/meta.blade.php +61 -0
- package/skills/seo/assets/snippets/robots.txt +61 -0
- package/skills/seo/assets/snippets/sitemap-urlset-example.xml +72 -0
- package/skills/seo/assets/snippets/sitemap.xml +36 -0
- package/skills/seo/references/audit-checklist.md +305 -0
- package/skills/seo/references/content-seo.md +198 -0
- package/skills/seo/references/eeat-medical.md +217 -0
- package/skills/seo/references/measurement.md +223 -0
- package/skills/seo/references/on-page.md +209 -0
- package/skills/seo/references/stack-recipes.md +693 -0
- package/skills/seo/references/structured-data.md +485 -0
- package/skills/seo/references/technical-seo.md +294 -0
- package/skills/service-desk-conventions/SKILL.md +40 -0
- package/skills/service-desk-db-safety/SKILL.md +52 -0
- package/skills/service-desk-release/SKILL.md +43 -0
- package/skills/service-desk-testing/SKILL.md +47 -0
- package/skills/service-desk-ui/SKILL.md +33 -0
- package/skills/skills-router/SKILL.md +91 -0
- package/skills/testing-strategy/SKILL.md +37 -0
- package/skills/ui-design-system/SKILL.md +45 -0
- package/skills/web-research/SKILL.md +40 -0
- package/skills/wow-design/SKILL.md +168 -0
- package/skills/wow-design/assets/kit/README.md +195 -0
- package/skills/wow-design/assets/kit/assets/css/base.css +158 -0
- package/skills/wow-design/assets/kit/assets/css/components.css +1001 -0
- package/skills/wow-design/assets/kit/assets/css/fonts.css +73 -0
- package/skills/wow-design/assets/kit/assets/css/pages.css +737 -0
- package/skills/wow-design/assets/kit/assets/css/tokens.css +218 -0
- package/skills/wow-design/assets/kit/assets/fonts/LICENSE-golos-text.txt +93 -0
- package/skills/wow-design/assets/kit/assets/fonts/LICENSE-lora.txt +93 -0
- package/skills/wow-design/assets/kit/assets/fonts/LICENSE-unbounded.txt +93 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-cyrillic-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-cyrillic-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-cyrillic-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-cyrillic-700-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-latin-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-latin-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-latin-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-latin-700-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-cyrillic-400-italic.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-cyrillic-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-cyrillic-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-cyrillic-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-latin-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-latin-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-latin-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-cyrillic-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-cyrillic-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-cyrillic-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-latin-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-latin-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-latin-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/js/kit.js +550 -0
- package/skills/wow-design/assets/kit/pages/dashboard.html +539 -0
- package/skills/wow-design/assets/kit/pages/hospital.html +430 -0
- package/skills/wow-design/assets/kit/showcase.html +1164 -0
- package/skills/wow-design/assets/scripts/LICENSE-axe-core.txt +362 -0
- package/skills/wow-design/assets/scripts/LICENSE-playwright-core.txt +202 -0
- package/skills/wow-design/assets/scripts/README.md +312 -0
- package/skills/wow-design/assets/scripts/audit.mjs +1200 -0
- package/skills/wow-design/assets/scripts/capture.mjs +337 -0
- package/skills/wow-design/assets/scripts/package.json +30 -0
- package/skills/wow-design/references/anti-patterns.md +249 -0
- package/skills/wow-design/references/critique-rubric.md +259 -0
- package/skills/wow-design/references/design-brief-template.md +46 -0
- package/skills/wow-design/references/inspiration.md +200 -0
- package/skills/wow-design/references/presets.md +96 -0
- package/skills/wow-design/references/principles.md +368 -0
- package/skills/wow-design/references/stack-recipes.md +93 -0
- package/skills/wow-design/references/visual-qa.md +79 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// Минимальный ZIP-ридер без внешних зависимостей (store + deflate, CRC32).
|
|
2
|
+
// Нужен валидатору, чтобы читать нужные файлы прямо из архива, не распаковывая всё в temp.
|
|
3
|
+
// ZIP64 и шифрованные архивы не поддерживаются — для портативного пакета DSH это не нужно.
|
|
4
|
+
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import zlib from 'node:zlib';
|
|
7
|
+
import crypto from 'node:crypto';
|
|
8
|
+
|
|
9
|
+
const EOCD_SIG = 0x06054b50;
|
|
10
|
+
const CD_SIG = 0x02014b50;
|
|
11
|
+
const LFH_SIG = 0x04034b50;
|
|
12
|
+
|
|
13
|
+
export class ZipError extends Error {
|
|
14
|
+
constructor(message, code = 'zip') {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = 'ZipError';
|
|
17
|
+
this.code = code;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const CRC_TABLE = (() => {
|
|
22
|
+
const table = new Uint32Array(256);
|
|
23
|
+
for (let n = 0; n < 256; n++) {
|
|
24
|
+
let c = n;
|
|
25
|
+
for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
26
|
+
table[n] = c >>> 0;
|
|
27
|
+
}
|
|
28
|
+
return table;
|
|
29
|
+
})();
|
|
30
|
+
|
|
31
|
+
export function crc32(buf) {
|
|
32
|
+
let c = 0xffffffff;
|
|
33
|
+
for (let i = 0; i < buf.length; i++) c = CRC_TABLE[(c ^ buf[i]) & 0xff] ^ (c >>> 8);
|
|
34
|
+
return (c ^ 0xffffffff) >>> 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function sha256(buf) {
|
|
38
|
+
return crypto.createHash('sha256').update(buf).digest('hex');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Декодирование имени записи: UTF-8 по флагу, иначе UTF-8/ibm866/latin1. */
|
|
42
|
+
function decodeName(buf, flags) {
|
|
43
|
+
if (flags & 0x800) {
|
|
44
|
+
try {
|
|
45
|
+
return new TextDecoder('utf-8', { fatal: true }).decode(buf);
|
|
46
|
+
} catch {
|
|
47
|
+
/* fallthrough */
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
return new TextDecoder('utf-8', { fatal: true }).decode(buf);
|
|
52
|
+
} catch {
|
|
53
|
+
try {
|
|
54
|
+
return new TextDecoder('ibm866').decode(buf); // OEM-кодировка русской Windows
|
|
55
|
+
} catch {
|
|
56
|
+
return buf.toString('latin1');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Прочитать ZIP-архив целиком в память и разобрать оглавление.
|
|
63
|
+
* @returns {{filePath:string, fileSize:number, archiveSha256:string, entries:Array, files:Array, dirs:Array, read:Function, readPath:Function, warnings:string[]}}
|
|
64
|
+
*/
|
|
65
|
+
export function readZip(filePath) {
|
|
66
|
+
const buf = fs.readFileSync(filePath);
|
|
67
|
+
const warnings = [];
|
|
68
|
+
|
|
69
|
+
let eocd = -1;
|
|
70
|
+
const minPos = Math.max(0, buf.length - 22 - 65535);
|
|
71
|
+
for (let i = buf.length - 22; i >= minPos; i--) {
|
|
72
|
+
if (buf.readUInt32LE(i) === EOCD_SIG) {
|
|
73
|
+
eocd = i;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (eocd < 0) throw new ZipError('Не найден EOCD (конец центрального каталога) — файл повреждён или это не ZIP', 'corrupt');
|
|
78
|
+
|
|
79
|
+
const disk = buf.readUInt16LE(eocd + 4);
|
|
80
|
+
const cdDisk = buf.readUInt16LE(eocd + 6);
|
|
81
|
+
const entriesDisk = buf.readUInt16LE(eocd + 8);
|
|
82
|
+
const entriesTotal = buf.readUInt16LE(eocd + 10);
|
|
83
|
+
const cdSize = buf.readUInt32LE(eocd + 12);
|
|
84
|
+
const cdOffset = buf.readUInt32LE(eocd + 16);
|
|
85
|
+
const commentLen = buf.readUInt16LE(eocd + 20);
|
|
86
|
+
if (eocd + 22 + commentLen > buf.length) warnings.push('EOCD-комментарий выходит за границу файла');
|
|
87
|
+
if (disk !== 0 || cdDisk !== 0 || entriesDisk !== entriesTotal) {
|
|
88
|
+
throw new ZipError('Многотомные ZIP не поддерживаются', 'unsupported');
|
|
89
|
+
}
|
|
90
|
+
if (cdOffset === 0xffffffff || cdSize === 0xffffffff || entriesTotal === 0xffff) {
|
|
91
|
+
throw new ZipError('ZIP64 не поддерживается валидатором', 'unsupported');
|
|
92
|
+
}
|
|
93
|
+
if (cdOffset + cdSize > buf.length) {
|
|
94
|
+
throw new ZipError('Центральный каталог выходит за границу файла — архив обрезан', 'corrupt');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const entries = [];
|
|
98
|
+
let p = cdOffset;
|
|
99
|
+
for (let i = 0; i < entriesTotal; i++) {
|
|
100
|
+
if (p + 46 > buf.length || buf.readUInt32LE(p) !== CD_SIG) {
|
|
101
|
+
throw new ZipError(`Повреждён центральный каталог ZIP (запись ${i + 1})`, 'corrupt');
|
|
102
|
+
}
|
|
103
|
+
const flags = buf.readUInt16LE(p + 8);
|
|
104
|
+
const method = buf.readUInt16LE(p + 10);
|
|
105
|
+
const crc = buf.readUInt32LE(p + 16);
|
|
106
|
+
const compSize = buf.readUInt32LE(p + 20);
|
|
107
|
+
const uncompSize = buf.readUInt32LE(p + 24);
|
|
108
|
+
const nameLen = buf.readUInt16LE(p + 28);
|
|
109
|
+
const extraLen = buf.readUInt16LE(p + 30);
|
|
110
|
+
const commentLen2 = buf.readUInt16LE(p + 32);
|
|
111
|
+
const extAttr = buf.readUInt32LE(p + 38);
|
|
112
|
+
const localOffset = buf.readUInt32LE(p + 42);
|
|
113
|
+
if (compSize === 0xffffffff || uncompSize === 0xffffffff || localOffset === 0xffffffff) {
|
|
114
|
+
throw new ZipError(`ZIP64-запись не поддерживается: ${decodeName(buf.subarray(p + 46, p + 46 + nameLen), flags)}`, 'unsupported');
|
|
115
|
+
}
|
|
116
|
+
const name = decodeName(buf.subarray(p + 46, p + 46 + nameLen), flags);
|
|
117
|
+
p += 46 + nameLen + extraLen + commentLen2;
|
|
118
|
+
|
|
119
|
+
const unixMode = (extAttr >>> 16) & 0xffff;
|
|
120
|
+
const isDir = name.endsWith('/') || (unixMode & 0o170000) === 0o040000 || (extAttr & 0x10) !== 0;
|
|
121
|
+
entries.push({
|
|
122
|
+
path: name.replace(/\\/g, '/'),
|
|
123
|
+
rawName: name,
|
|
124
|
+
isDir,
|
|
125
|
+
size: uncompSize,
|
|
126
|
+
compSize,
|
|
127
|
+
crc,
|
|
128
|
+
method,
|
|
129
|
+
flags,
|
|
130
|
+
encrypted: (flags & 1) !== 0,
|
|
131
|
+
localOffset,
|
|
132
|
+
extAttr,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const byPath = new Map(entries.map((e) => [e.path, e]));
|
|
137
|
+
|
|
138
|
+
function read(entry) {
|
|
139
|
+
if (!entry || entry.isDir) return Buffer.alloc(0);
|
|
140
|
+
if (entry.encrypted) throw new ZipError(`Запись зашифрована: ${entry.path}`, 'unsupported');
|
|
141
|
+
const off = entry.localOffset;
|
|
142
|
+
if (off + 30 > buf.length || buf.readUInt32LE(off) !== LFH_SIG) {
|
|
143
|
+
throw new ZipError(`Повреждён локальный заголовок записи: ${entry.path}`, 'corrupt');
|
|
144
|
+
}
|
|
145
|
+
const nameLen = buf.readUInt16LE(off + 26);
|
|
146
|
+
const extraLen = buf.readUInt16LE(off + 28);
|
|
147
|
+
const dataStart = off + 30 + nameLen + extraLen;
|
|
148
|
+
if (dataStart + entry.compSize > buf.length) {
|
|
149
|
+
throw new ZipError(`Обрезаны данные записи: ${entry.path}`, 'corrupt');
|
|
150
|
+
}
|
|
151
|
+
const compressed = buf.subarray(dataStart, dataStart + entry.compSize);
|
|
152
|
+
let data;
|
|
153
|
+
if (entry.method === 0) data = Buffer.from(compressed);
|
|
154
|
+
else if (entry.method === 8) {
|
|
155
|
+
try {
|
|
156
|
+
data = zlib.inflateRawSync(compressed);
|
|
157
|
+
} catch (e) {
|
|
158
|
+
throw new ZipError(`Ошибка распаковки (deflate): ${entry.path} — ${e.message}`, 'corrupt');
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
throw new ZipError(`Метод сжатия ${entry.method} не поддерживается: ${entry.path}`, 'unsupported');
|
|
162
|
+
}
|
|
163
|
+
if (data.length !== entry.size) {
|
|
164
|
+
throw new ZipError(`Размер записи не совпал (${data.length} != ${entry.size}): ${entry.path}`, 'corrupt');
|
|
165
|
+
}
|
|
166
|
+
const actual = crc32(data);
|
|
167
|
+
if (actual !== entry.crc) {
|
|
168
|
+
throw new ZipError(`CRC32 не совпал: ${entry.path}`, 'corrupt');
|
|
169
|
+
}
|
|
170
|
+
return data;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
filePath,
|
|
175
|
+
fileSize: buf.length,
|
|
176
|
+
archiveSha256: sha256(buf),
|
|
177
|
+
entries,
|
|
178
|
+
files: entries.filter((e) => !e.isDir),
|
|
179
|
+
dirs: entries.filter((e) => e.isDir),
|
|
180
|
+
read,
|
|
181
|
+
readPath(name) {
|
|
182
|
+
const entry = byPath.get(name.replace(/\\/g, '/'));
|
|
183
|
+
if (!entry) throw new ZipError(`Нет записи в архиве: ${name}`, 'missing');
|
|
184
|
+
return read(entry);
|
|
185
|
+
},
|
|
186
|
+
hasPath(name) {
|
|
187
|
+
return byPath.has(name.replace(/\\/g, '/'));
|
|
188
|
+
},
|
|
189
|
+
warnings,
|
|
190
|
+
};
|
|
191
|
+
}
|