@push.rocks/smartlinuxrepo 0.0.0-stage → 0.1.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.
Files changed (131) hide show
  1. package/.smartconfig.json +64 -0
  2. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  3. package/dist_ts/00_commitinfo_data.js +9 -0
  4. package/dist_ts/alpine/apkindex.d.ts +39 -0
  5. package/dist_ts/alpine/apkindex.js +211 -0
  6. package/dist_ts/alpine/pkginfo.d.ts +45 -0
  7. package/dist_ts/alpine/pkginfo.js +159 -0
  8. package/dist_ts/alpine/reader.d.ts +20 -0
  9. package/dist_ts/alpine/reader.js +89 -0
  10. package/dist_ts/arch/builder.d.ts +41 -0
  11. package/dist_ts/arch/builder.js +234 -0
  12. package/dist_ts/arch/reader.d.ts +16 -0
  13. package/dist_ts/arch/reader.js +271 -0
  14. package/dist_ts/arch/signer.d.ts +21 -0
  15. package/dist_ts/arch/signer.js +66 -0
  16. package/dist_ts/arch/vercmp.d.ts +12 -0
  17. package/dist_ts/arch/vercmp.js +170 -0
  18. package/dist_ts/debian/control.d.ts +22 -0
  19. package/dist_ts/debian/control.js +137 -0
  20. package/dist_ts/debian/gostring.d.ts +26 -0
  21. package/dist_ts/debian/gostring.js +145 -0
  22. package/dist_ts/debian/indexbuilder.d.ts +47 -0
  23. package/dist_ts/debian/indexbuilder.js +299 -0
  24. package/dist_ts/debian/mailaddress.d.ts +12 -0
  25. package/dist_ts/debian/mailaddress.js +736 -0
  26. package/dist_ts/debian/reader.d.ts +30 -0
  27. package/dist_ts/debian/reader.js +110 -0
  28. package/dist_ts/index.d.ts +23 -0
  29. package/dist_ts/index.js +18 -0
  30. package/dist_ts/plugins.d.ts +8 -0
  31. package/dist_ts/plugins.js +11 -0
  32. package/dist_ts/readers/ar.d.ts +31 -0
  33. package/dist_ts/readers/ar.js +87 -0
  34. package/dist_ts/readers/bytes.d.ts +58 -0
  35. package/dist_ts/readers/bytes.js +147 -0
  36. package/dist_ts/readers/bytesource.d.ts +40 -0
  37. package/dist_ts/readers/bytesource.js +154 -0
  38. package/dist_ts/readers/decompress.d.ts +43 -0
  39. package/dist_ts/readers/decompress.js +269 -0
  40. package/dist_ts/readers/gzipmember.d.ts +32 -0
  41. package/dist_ts/readers/gzipmember.js +176 -0
  42. package/dist_ts/readers/tar.d.ts +85 -0
  43. package/dist_ts/readers/tar.js +731 -0
  44. package/dist_ts/readers/text.d.ts +16 -0
  45. package/dist_ts/readers/text.js +96 -0
  46. package/dist_ts/rpm/builder.d.ts +28 -0
  47. package/dist_ts/rpm/builder.js +208 -0
  48. package/dist_ts/rpm/header.d.ts +138 -0
  49. package/dist_ts/rpm/header.js +546 -0
  50. package/dist_ts/rpm/reader.d.ts +20 -0
  51. package/dist_ts/rpm/reader.js +306 -0
  52. package/dist_ts/rpm/repoconfig.d.ts +15 -0
  53. package/dist_ts/rpm/repoconfig.js +38 -0
  54. package/dist_ts/rpm/repodata.d.ts +44 -0
  55. package/dist_ts/rpm/repodata.js +148 -0
  56. package/dist_ts/rpm/sign.d.ts +30 -0
  57. package/dist_ts/rpm/sign.js +183 -0
  58. package/dist_ts/rpm/updates.d.ts +38 -0
  59. package/dist_ts/rpm/updates.js +265 -0
  60. package/dist_ts/rpm/xml.d.ts +18 -0
  61. package/dist_ts/rpm/xml.js +90 -0
  62. package/dist_ts/shared/architecture.d.ts +8 -0
  63. package/dist_ts/shared/architecture.js +17 -0
  64. package/dist_ts/shared/errors.d.ts +38 -0
  65. package/dist_ts/shared/errors.js +22 -0
  66. package/dist_ts/shared/gopath.d.ts +13 -0
  67. package/dist_ts/shared/gopath.js +53 -0
  68. package/dist_ts/shared/gostrings.d.ts +14 -0
  69. package/dist_ts/shared/gostrings.js +29 -0
  70. package/dist_ts/shared/limits.d.ts +47 -0
  71. package/dist_ts/shared/limits.js +57 -0
  72. package/dist_ts/shared/types.d.ts +213 -0
  73. package/dist_ts/shared/types.js +13 -0
  74. package/dist_ts/shared/url.d.ts +18 -0
  75. package/dist_ts/shared/url.js +371 -0
  76. package/dist_ts/shared/validation.d.ts +21 -0
  77. package/dist_ts/shared/validation.js +58 -0
  78. package/dist_ts/signing/keys.d.ts +36 -0
  79. package/dist_ts/signing/keys.js +89 -0
  80. package/dist_ts/signing/openpgpframing.d.ts +33 -0
  81. package/dist_ts/signing/openpgpframing.js +93 -0
  82. package/dist_ts/signing/signers.d.ts +63 -0
  83. package/dist_ts/signing/signers.js +248 -0
  84. package/dist_ts/writers/gotar.d.ts +43 -0
  85. package/dist_ts/writers/gotar.js +218 -0
  86. package/license.md +19 -0
  87. package/package.json +56 -3
  88. package/readme.md +176 -0
  89. package/ts/00_commitinfo_data.ts +8 -0
  90. package/ts/alpine/apkindex.ts +241 -0
  91. package/ts/alpine/pkginfo.ts +183 -0
  92. package/ts/alpine/reader.ts +96 -0
  93. package/ts/arch/builder.ts +283 -0
  94. package/ts/arch/reader.ts +307 -0
  95. package/ts/arch/signer.ts +70 -0
  96. package/ts/arch/vercmp.ts +188 -0
  97. package/ts/debian/control.ts +150 -0
  98. package/ts/debian/gostring.ts +150 -0
  99. package/ts/debian/indexbuilder.ts +355 -0
  100. package/ts/debian/mailaddress.ts +754 -0
  101. package/ts/debian/reader.ts +126 -0
  102. package/ts/index.ts +46 -0
  103. package/ts/plugins.ts +13 -0
  104. package/ts/readers/ar.ts +102 -0
  105. package/ts/readers/bytes.ts +182 -0
  106. package/ts/readers/bytesource.ts +164 -0
  107. package/ts/readers/decompress.ts +332 -0
  108. package/ts/readers/gzipmember.ts +209 -0
  109. package/ts/readers/tar.ts +835 -0
  110. package/ts/readers/text.ts +91 -0
  111. package/ts/rpm/builder.ts +253 -0
  112. package/ts/rpm/header.ts +628 -0
  113. package/ts/rpm/reader.ts +317 -0
  114. package/ts/rpm/repoconfig.ts +45 -0
  115. package/ts/rpm/repodata.ts +219 -0
  116. package/ts/rpm/sign.ts +200 -0
  117. package/ts/rpm/updates.ts +314 -0
  118. package/ts/rpm/xml.ts +101 -0
  119. package/ts/shared/architecture.ts +16 -0
  120. package/ts/shared/errors.ts +78 -0
  121. package/ts/shared/gopath.ts +54 -0
  122. package/ts/shared/gostrings.ts +31 -0
  123. package/ts/shared/limits.ts +93 -0
  124. package/ts/shared/types.ts +251 -0
  125. package/ts/shared/url.ts +387 -0
  126. package/ts/shared/validation.ts +71 -0
  127. package/ts/signing/keys.ts +110 -0
  128. package/ts/signing/openpgpframing.ts +115 -0
  129. package/ts/signing/signers.ts +315 -0
  130. package/ts/writers/gotar.ts +256 -0
  131. package/README.md +0 -3
@@ -0,0 +1,371 @@
1
+ /**
2
+ * Gitea 28.2.0's URL check for package metadata (`validation.IsValidURL`,
3
+ * `modules/validation/helpers.go:42-50`): Go 1.27's `url.ParseRequestURI`
4
+ * succeeds, the scheme is `http` or `https` (case-insensitive), and the host's
5
+ * port part holds only digits (`portOnly`/`validPort`,
6
+ * `modules/validation/binding.go:131-152`; no range check, an empty port
7
+ * passes). Readers keep a URL field only when this returns true.
8
+ *
9
+ * The port follows Go's `net/url` byte for byte on the UTF-8 encoding of the
10
+ * value, including its quirks: `http:x` is an opaque URL and passes,
11
+ * `http://` (empty host) passes, a query or fragment is never validated, and a
12
+ * `#` before the first `/` is part of the host and fails. Only the parts of the
13
+ * parser that can change the result for `http`/`https` are ported. Expected
14
+ * values come from Go: `test/fixtures/url/isvalidurl.gitea.json`.
15
+ *
16
+ * Internal: not exported from the package entry.
17
+ */
18
+ export function isValidUrl(valueArg) {
19
+ if (typeof valueArg !== 'string') {
20
+ return false;
21
+ }
22
+ const raw = utf8.encode(valueArg);
23
+ // parse(): control characters anywhere, then the empty and `*` forms
24
+ if (raw.some((byte) => byte < 0x20 || byte === 0x7f) || raw.length === 0) {
25
+ return false;
26
+ }
27
+ const scheme = splitScheme(raw);
28
+ if (scheme === null) {
29
+ return false;
30
+ }
31
+ const schemeName = ascii(raw.subarray(0, scheme)).toLowerCase();
32
+ if (schemeName !== 'http' && schemeName !== 'https') {
33
+ return false;
34
+ }
35
+ let rest = raw.subarray(scheme + 1);
36
+ const questionMarks = count(rest, QUESTION);
37
+ if (questionMarks === 1 && rest[rest.length - 1] === QUESTION) {
38
+ rest = rest.subarray(0, rest.length - 1);
39
+ }
40
+ else if (questionMarks > 0) {
41
+ rest = rest.subarray(0, rest.indexOf(QUESTION));
42
+ }
43
+ if (rest[0] !== SLASH) {
44
+ // a rootless path with a scheme is opaque and not validated further
45
+ return true;
46
+ }
47
+ let host = new Uint8Array(0);
48
+ let path = rest;
49
+ if (rest[1] === SLASH) {
50
+ const slash = rest.indexOf(SLASH, 2);
51
+ const authority = slash < 0 ? rest.subarray(2) : rest.subarray(2, slash);
52
+ path = slash < 0 ? new Uint8Array(0) : rest.subarray(slash);
53
+ const parsedHost = parseAuthority(authority);
54
+ if (parsedHost === null) {
55
+ return false;
56
+ }
57
+ host = parsedHost;
58
+ }
59
+ if (unescape(path, 'other') === null) {
60
+ return false;
61
+ }
62
+ return isDigits(portOnly(host));
63
+ }
64
+ const utf8 = new TextEncoder();
65
+ const SLASH = 0x2f;
66
+ const QUESTION = 0x3f;
67
+ const COLON = 0x3a;
68
+ const PERCENT = 0x25;
69
+ const AT = 0x40;
70
+ const OPEN_BRACKET = 0x5b;
71
+ const CLOSE_BRACKET = 0x5d;
72
+ const DOT = 0x2e;
73
+ /** Characters Go's `shouldEscape` leaves alone in a host besides alphanumerics and `-_.~`. */
74
+ const HOST_SAFE = new Set([..."!$&'()*+,;=:[]<>\""].map((character) => character.charCodeAt(0)));
75
+ /** Characters `validUserinfo` accepts besides alphanumerics. */
76
+ const USERINFO_SAFE = new Set([..."-._:~!$&'()*+,;=%@"].map((character) => character.charCodeAt(0)));
77
+ /** `getScheme`: the index of the scheme's colon, or `null` when there is no scheme or it is malformed. */
78
+ function splitScheme(rawArg) {
79
+ for (let i = 0; i < rawArg.length; i++) {
80
+ const c = rawArg[i];
81
+ if (isAlpha(c)) {
82
+ continue;
83
+ }
84
+ if (isDigit(c) || c === 0x2b || c === 0x2d || c === DOT) {
85
+ if (i === 0) {
86
+ return null;
87
+ }
88
+ continue;
89
+ }
90
+ return c === COLON && i > 0 ? i : null;
91
+ }
92
+ return null;
93
+ }
94
+ /** `parseAuthority`: the unescaped host, or `null` on a parse error. */
95
+ function parseAuthority(authorityArg) {
96
+ const at = authorityArg.lastIndexOf(AT);
97
+ const host = parseHost(at < 0 ? authorityArg : authorityArg.subarray(at + 1));
98
+ if (host === null || at < 0) {
99
+ return host;
100
+ }
101
+ const userinfo = authorityArg.subarray(0, at);
102
+ // validUserinfo iterates runes: any byte >= 0x80 is a rune outside the allowed set
103
+ if (!userinfo.every((byte) => isAlpha(byte) || isDigit(byte) || USERINFO_SAFE.has(byte))) {
104
+ return null;
105
+ }
106
+ const colon = userinfo.indexOf(COLON);
107
+ const parts = colon < 0 ? [userinfo] : [userinfo.subarray(0, colon), userinfo.subarray(colon + 1)];
108
+ return parts.every((part) => unescape(part, 'other') !== null) ? host : null;
109
+ }
110
+ /** `parseHost` for `http`/`https` (strict colons, the Go 1.26+ default Gitea's go.mod selects). */
111
+ function parseHost(hostArg) {
112
+ const openBracket = hostArg.lastIndexOf(OPEN_BRACKET);
113
+ if (openBracket > 0) {
114
+ return null;
115
+ }
116
+ if (openBracket === 0) {
117
+ const closeBracket = hostArg.lastIndexOf(CLOSE_BRACKET);
118
+ if (closeBracket < 0) {
119
+ return null;
120
+ }
121
+ const colonPort = hostArg.subarray(closeBracket + 1);
122
+ if (!isOptionalPort(colonPort)) {
123
+ return null;
124
+ }
125
+ const hostname = hostArg.subarray(1, closeBracket);
126
+ const zone = indexOfZone(hostname);
127
+ let unescapedHostname;
128
+ if (zone >= 0) {
129
+ const hostPart = unescape(hostname.subarray(0, zone), 'host');
130
+ const zonePart = unescape(hostname.subarray(zone), 'zone');
131
+ unescapedHostname = hostPart === null || zonePart === null ? null : concat(hostPart, zonePart);
132
+ }
133
+ else {
134
+ unescapedHostname = unescape(hostname, 'host');
135
+ }
136
+ // only an IPv6 address may sit in brackets (netip.ParseAddr, then !Is4)
137
+ if (unescapedHostname === null || !isIpv6Address(unescapedHostname)) {
138
+ return null;
139
+ }
140
+ return concat(Uint8Array.of(OPEN_BRACKET), unescapedHostname, Uint8Array.of(CLOSE_BRACKET), colonPort);
141
+ }
142
+ const colon = hostArg.indexOf(COLON);
143
+ if (colon >= 0 && !isOptionalPort(hostArg.subarray(colon))) {
144
+ return null;
145
+ }
146
+ return unescape(hostArg, 'host');
147
+ }
148
+ /** Go's `unescape` for the path, userinfo, host and zone modes; `null` on an invalid escape or host byte. */
149
+ function unescape(bytesArg, modeArg) {
150
+ let escapes = 0;
151
+ for (let i = 0; i < bytesArg.length;) {
152
+ const c = bytesArg[i];
153
+ if (c === PERCENT) {
154
+ escapes++;
155
+ if (i + 2 >= bytesArg.length || !isHex(bytesArg[i + 1]) || !isHex(bytesArg[i + 2])) {
156
+ return null;
157
+ }
158
+ const isPercentEscape = bytesArg[i + 1] === 0x32 && bytesArg[i + 2] === 0x35;
159
+ if (modeArg === 'host' && unhex(bytesArg[i + 1]) < 8 && !isPercentEscape) {
160
+ return null;
161
+ }
162
+ if (modeArg === 'zone') {
163
+ const value = (unhex(bytesArg[i + 1]) << 4) | unhex(bytesArg[i + 2]);
164
+ if (!isPercentEscape && value !== 0x20 && shouldEscapeInHost(value)) {
165
+ return null;
166
+ }
167
+ }
168
+ i += 3;
169
+ continue;
170
+ }
171
+ if (modeArg !== 'other' && c < 0x80 && shouldEscapeInHost(c)) {
172
+ return null;
173
+ }
174
+ i++;
175
+ }
176
+ if (escapes === 0) {
177
+ return bytesArg;
178
+ }
179
+ const result = new Uint8Array(bytesArg.length - 2 * escapes);
180
+ let length = 0;
181
+ for (let i = 0; i < bytesArg.length; i++) {
182
+ if (bytesArg[i] === PERCENT) {
183
+ result[length++] = (unhex(bytesArg[i + 1]) << 4) | unhex(bytesArg[i + 2]);
184
+ i += 2;
185
+ }
186
+ else {
187
+ result[length++] = bytesArg[i];
188
+ }
189
+ }
190
+ return result;
191
+ }
192
+ /** Go's `shouldEscape(c, encodeHost)` (identical for `encodeZone`). */
193
+ function shouldEscapeInHost(cArg) {
194
+ if (isAlpha(cArg) || isDigit(cArg)) {
195
+ return false;
196
+ }
197
+ return !(HOST_SAFE.has(cArg) || cArg === 0x2d || cArg === 0x5f || cArg === DOT || cArg === 0x7e);
198
+ }
199
+ /** Index of the first `%25` (the RFC 6874 zone introducer), or -1. */
200
+ function indexOfZone(bytesArg) {
201
+ for (let i = 0; i + 2 < bytesArg.length; i++) {
202
+ if (bytesArg[i] === PERCENT && bytesArg[i + 1] === 0x32 && bytesArg[i + 2] === 0x35) {
203
+ return i;
204
+ }
205
+ }
206
+ return -1;
207
+ }
208
+ /**
209
+ * Whether `netip.ParseAddr` parses the bytes as an IPv6 address (with an
210
+ * optional non-empty zone). An input whose first `.`, `:` or `%` is not `:` is
211
+ * an IPv4 address or an error, both refused in brackets.
212
+ */
213
+ function isIpv6Address(bytesArg) {
214
+ const first = bytesArg.findIndex((byte) => byte === DOT || byte === COLON || byte === PERCENT);
215
+ if (first < 0 || bytesArg[first] !== COLON) {
216
+ return false;
217
+ }
218
+ let s = bytesArg;
219
+ const zone = s.indexOf(PERCENT);
220
+ if (zone >= 0) {
221
+ if (zone === s.length - 1) {
222
+ return false;
223
+ }
224
+ s = s.subarray(0, zone);
225
+ }
226
+ let ellipsis = -1;
227
+ if (s.length >= 2 && s[0] === COLON && s[1] === COLON) {
228
+ ellipsis = 0;
229
+ s = s.subarray(2);
230
+ if (s.length === 0) {
231
+ return true;
232
+ }
233
+ }
234
+ let i = 0;
235
+ while (i < 16) {
236
+ let off = 0;
237
+ let acc = 0;
238
+ for (; off < s.length; off++) {
239
+ const c = s[off];
240
+ if (!isHex(c)) {
241
+ break;
242
+ }
243
+ acc = acc * 16 + unhex(c);
244
+ if (off > 3 || acc > 0xffff) {
245
+ return false;
246
+ }
247
+ }
248
+ if (off === 0) {
249
+ return false;
250
+ }
251
+ if (off < s.length && s[off] === DOT) {
252
+ if ((ellipsis < 0 && i !== 12) || i + 4 > 16 || !isIpv4Fields(s)) {
253
+ return false;
254
+ }
255
+ s = s.subarray(s.length);
256
+ i += 4;
257
+ break;
258
+ }
259
+ i += 2;
260
+ s = s.subarray(off);
261
+ if (s.length === 0) {
262
+ break;
263
+ }
264
+ if (s[0] !== COLON || s.length === 1) {
265
+ return false;
266
+ }
267
+ s = s.subarray(1);
268
+ if (s[0] === COLON) {
269
+ if (ellipsis >= 0) {
270
+ return false;
271
+ }
272
+ ellipsis = i;
273
+ s = s.subarray(1);
274
+ if (s.length === 0) {
275
+ break;
276
+ }
277
+ }
278
+ }
279
+ if (s.length !== 0) {
280
+ return false;
281
+ }
282
+ return i < 16 ? ellipsis >= 0 : ellipsis < 0;
283
+ }
284
+ /** `parseIPv4Fields`: four decimal octets without leading zeros. */
285
+ function isIpv4Fields(bytesArg) {
286
+ let value = 0;
287
+ let digits = 0;
288
+ let dots = 0;
289
+ for (let i = 0; i < bytesArg.length; i++) {
290
+ const c = bytesArg[i];
291
+ if (isDigit(c)) {
292
+ if (digits === 1 && value === 0) {
293
+ return false;
294
+ }
295
+ value = value * 10 + (c - 0x30);
296
+ digits++;
297
+ if (value > 255) {
298
+ return false;
299
+ }
300
+ }
301
+ else if (c === DOT) {
302
+ if (i === 0 || i === bytesArg.length - 1 || bytesArg[i - 1] === DOT || dots === 3) {
303
+ return false;
304
+ }
305
+ dots++;
306
+ value = 0;
307
+ digits = 0;
308
+ }
309
+ else {
310
+ return false;
311
+ }
312
+ }
313
+ return dots === 3;
314
+ }
315
+ /** `validOptionalPort`: empty, or `:` followed by digits only. */
316
+ function isOptionalPort(bytesArg) {
317
+ return bytesArg.length === 0 || (bytesArg[0] === COLON && isDigits(bytesArg.subarray(1)));
318
+ }
319
+ /** Gitea's `portOnly` on the parsed host. */
320
+ function portOnly(hostArg) {
321
+ const colon = hostArg.indexOf(COLON);
322
+ if (colon < 0) {
323
+ return new Uint8Array(0);
324
+ }
325
+ for (let i = 0; i + 1 < hostArg.length; i++) {
326
+ if (hostArg[i] === CLOSE_BRACKET && hostArg[i + 1] === COLON) {
327
+ return hostArg.subarray(i + 2);
328
+ }
329
+ }
330
+ if (hostArg.includes(CLOSE_BRACKET)) {
331
+ return new Uint8Array(0);
332
+ }
333
+ return hostArg.subarray(colon + 1);
334
+ }
335
+ function isDigits(bytesArg) {
336
+ return bytesArg.every(isDigit);
337
+ }
338
+ function isDigit(cArg) {
339
+ return cArg >= 0x30 && cArg <= 0x39;
340
+ }
341
+ function isAlpha(cArg) {
342
+ return (cArg >= 0x41 && cArg <= 0x5a) || (cArg >= 0x61 && cArg <= 0x7a);
343
+ }
344
+ function isHex(cArg) {
345
+ return isDigit(cArg) || (cArg >= 0x41 && cArg <= 0x46) || (cArg >= 0x61 && cArg <= 0x66);
346
+ }
347
+ function unhex(cArg) {
348
+ return isDigit(cArg) ? cArg - 0x30 : (cArg | 0x20) - 0x61 + 10;
349
+ }
350
+ function count(bytesArg, byteArg) {
351
+ let total = 0;
352
+ for (const byte of bytesArg) {
353
+ if (byte === byteArg) {
354
+ total++;
355
+ }
356
+ }
357
+ return total;
358
+ }
359
+ function ascii(bytesArg) {
360
+ return String.fromCharCode(...bytesArg);
361
+ }
362
+ function concat(...partsArg) {
363
+ const result = new Uint8Array(partsArg.reduce((sum, part) => sum + part.length, 0));
364
+ let offset = 0;
365
+ for (const part of partsArg) {
366
+ result.set(part, offset);
367
+ offset += part.length;
368
+ }
369
+ return result;
370
+ }
371
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc2hhcmVkL3VybC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQUMsUUFBZ0I7SUFDekMsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNqQyxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2xDLHFFQUFxRTtJQUNyRSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDekUsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2hDLElBQUksTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ3BCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ2hFLElBQUksVUFBVSxLQUFLLE1BQU0sSUFBSSxVQUFVLEtBQUssT0FBTyxFQUFFLENBQUM7UUFDcEQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDcEMsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUM1QyxJQUFJLGFBQWEsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDOUQsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDM0MsQ0FBQztTQUFNLElBQUksYUFBYSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzdCLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUNELElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDO1FBQ3RCLG9FQUFvRTtRQUNwRSxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxJQUFJLElBQUksR0FBZSxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxJQUFJLElBQUksR0FBRyxJQUFJLENBQUM7SUFDaEIsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDdEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDckMsTUFBTSxTQUFTLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekUsSUFBSSxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVELE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM3QyxJQUFJLFVBQVUsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUN4QixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFDRCxJQUFJLEdBQUcsVUFBVSxDQUFDO0lBQ3BCLENBQUM7SUFDRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDckMsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsT0FBTyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDbEMsQ0FBQztBQUlELE1BQU0sSUFBSSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7QUFDL0IsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ25CLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQztBQUN0QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDbkIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDO0FBQ3JCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQztBQUNoQixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUM7QUFDMUIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzNCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQztBQUVqQiw4RkFBOEY7QUFDOUYsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLG9CQUFvQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqRyxnRUFBZ0U7QUFDaEUsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLG9CQUFvQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVyRywwR0FBMEc7QUFDMUcsU0FBUyxXQUFXLENBQUMsTUFBa0I7SUFDckMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN2QyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEIsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNmLFNBQVM7UUFDWCxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUN4RCxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDWixPQUFPLElBQUksQ0FBQztZQUNkLENBQUM7WUFDRCxTQUFTO1FBQ1gsQ0FBQztRQUNELE9BQU8sQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUN6QyxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsd0VBQXdFO0FBQ3hFLFNBQVMsY0FBYyxDQUFDLFlBQXdCO0lBQzlDLE1BQU0sRUFBRSxHQUFHLFlBQVksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDeEMsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5RSxJQUFJLElBQUksS0FBSyxJQUFJLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzVCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzlDLG1GQUFtRjtJQUNuRixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN6RixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3RDLE1BQU0sS0FBSyxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuRyxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQy9FLENBQUM7QUFFRCxtR0FBbUc7QUFDbkcsU0FBUyxTQUFTLENBQUMsT0FBbUI7SUFDcEMsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN0RCxJQUFJLFdBQVcsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNwQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxJQUFJLFdBQVcsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN0QixNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3hELElBQUksWUFBWSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUMvQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNuRCxNQUFNLElBQUksR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDbkMsSUFBSSxpQkFBb0MsQ0FBQztRQUN6QyxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNkLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM5RCxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMzRCxpQkFBaUIsR0FBRyxRQUFRLEtBQUssSUFBSSxJQUFJLFFBQVEsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNqRyxDQUFDO2FBQU0sQ0FBQztZQUNOLGlCQUFpQixHQUFHLFFBQVEsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUNELHdFQUF3RTtRQUN4RSxJQUFJLGlCQUFpQixLQUFLLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7WUFDcEUsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsRUFBRSxpQkFBaUIsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ3pHLENBQUM7SUFDRCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3JDLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMzRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxPQUFPLFFBQVEsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUVELDZHQUE2RztBQUM3RyxTQUFTLFFBQVEsQ0FBQyxRQUFvQixFQUFFLE9BQW9CO0lBQzFELElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztJQUNoQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sR0FBSSxDQUFDO1FBQ3RDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixJQUFJLENBQUMsS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUNsQixPQUFPLEVBQUUsQ0FBQztZQUNWLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDbkYsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1lBQ0QsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUM7WUFDN0UsSUFBSSxPQUFPLEtBQUssTUFBTSxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3pFLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztZQUNELElBQUksT0FBTyxLQUFLLE1BQU0sRUFBRSxDQUFDO2dCQUN2QixNQUFNLEtBQUssR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDckUsSUFBSSxDQUFDLGVBQWUsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQ3BFLE9BQU8sSUFBSSxDQUFDO2dCQUNkLENBQUM7WUFDSCxDQUFDO1lBQ0QsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNQLFNBQVM7UUFDWCxDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssT0FBTyxJQUFJLENBQUMsR0FBRyxJQUFJLElBQUksa0JBQWtCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUM3RCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxDQUFDLEVBQUUsQ0FBQztJQUNOLENBQUM7SUFDRCxJQUFJLE9BQU8sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNsQixPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxVQUFVLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUM7SUFDN0QsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN6QyxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUM1QixNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ1QsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakMsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQsdUVBQXVFO0FBQ3ZFLFNBQVMsa0JBQWtCLENBQUMsSUFBWTtJQUN0QyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNuQyxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxPQUFPLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksS0FBSyxJQUFJLElBQUksSUFBSSxLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssR0FBRyxJQUFJLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQztBQUNuRyxDQUFDO0FBRUQsc0VBQXNFO0FBQ3RFLFNBQVMsV0FBVyxDQUFDLFFBQW9CO0lBQ3ZDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQzdDLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLE9BQU8sSUFBSSxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3BGLE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ1osQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLGFBQWEsQ0FBQyxRQUFvQjtJQUN6QyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLEtBQUssR0FBRyxJQUFJLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxLQUFLLE9BQU8sQ0FBQyxDQUFDO0lBQy9GLElBQUksS0FBSyxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDM0MsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsSUFBSSxDQUFDLEdBQUcsUUFBUSxDQUFDO0lBQ2pCLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEMsSUFBSSxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDZCxJQUFJLElBQUksS0FBSyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFCLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUNELENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBQ0QsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDbEIsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUN0RCxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEIsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ25CLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDVixPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQztRQUNkLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNaLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNaLE9BQU8sR0FBRyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUM3QixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakIsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNkLE1BQU07WUFDUixDQUFDO1lBQ0QsR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFCLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUM7Z0JBQzVCLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNkLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUNELElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNqRSxPQUFPLEtBQUssQ0FBQztZQUNmLENBQUM7WUFDRCxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDekIsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNQLE1BQU07UUFDUixDQUFDO1FBQ0QsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNQLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNuQixNQUFNO1FBQ1IsQ0FBQztRQUNELElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3JDLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUNELENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xCLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQ25CLElBQUksUUFBUSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNsQixPQUFPLEtBQUssQ0FBQztZQUNmLENBQUM7WUFDRCxRQUFRLEdBQUcsQ0FBQyxDQUFDO1lBQ2IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEIsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNuQixNQUFNO1lBQ1IsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBQ0QsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ25CLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztBQUMvQyxDQUFDO0FBRUQsb0VBQW9FO0FBQ3BFLFNBQVMsWUFBWSxDQUFDLFFBQW9CO0lBQ3hDLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNkLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNmLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQztJQUNiLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDekMsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDZixJQUFJLE1BQU0sS0FBSyxDQUFDLElBQUksS0FBSyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNoQyxPQUFPLEtBQUssQ0FBQztZQUNmLENBQUM7WUFDRCxLQUFLLEdBQUcsS0FBSyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUNoQyxNQUFNLEVBQUUsQ0FBQztZQUNULElBQUksS0FBSyxHQUFHLEdBQUcsRUFBRSxDQUFDO2dCQUNoQixPQUFPLEtBQUssQ0FBQztZQUNmLENBQUM7UUFDSCxDQUFDO2FBQU0sSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxJQUFJLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ2xGLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztZQUNELElBQUksRUFBRSxDQUFDO1lBQ1AsS0FBSyxHQUFHLENBQUMsQ0FBQztZQUNWLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDYixDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLElBQUksS0FBSyxDQUFDLENBQUM7QUFDcEIsQ0FBQztBQUVELGtFQUFrRTtBQUNsRSxTQUFTLGNBQWMsQ0FBQyxRQUFvQjtJQUMxQyxPQUFPLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUYsQ0FBQztBQUVELDZDQUE2QztBQUM3QyxTQUFTLFFBQVEsQ0FBQyxPQUFtQjtJQUNuQyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3JDLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ2QsT0FBTyxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBQ0QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDNUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssYUFBYSxJQUFJLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDN0QsT0FBTyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNqQyxDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sSUFBSSxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDckMsQ0FBQztBQUVELFNBQVMsUUFBUSxDQUFDLFFBQW9CO0lBQ3BDLE9BQU8sUUFBUSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNqQyxDQUFDO0FBRUQsU0FBUyxPQUFPLENBQUMsSUFBWTtJQUMzQixPQUFPLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQztBQUN0QyxDQUFDO0FBRUQsU0FBUyxPQUFPLENBQUMsSUFBWTtJQUMzQixPQUFPLENBQUMsSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQztBQUMxRSxDQUFDO0FBRUQsU0FBUyxLQUFLLENBQUMsSUFBWTtJQUN6QixPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLENBQUM7QUFDM0YsQ0FBQztBQUVELFNBQVMsS0FBSyxDQUFDLElBQVk7SUFDekIsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7QUFDakUsQ0FBQztBQUVELFNBQVMsS0FBSyxDQUFDLFFBQW9CLEVBQUUsT0FBZTtJQUNsRCxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDZCxLQUFLLE1BQU0sSUFBSSxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQzVCLElBQUksSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ3JCLEtBQUssRUFBRSxDQUFDO1FBQ1YsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxTQUFTLEtBQUssQ0FBQyxRQUFvQjtJQUNqQyxPQUFPLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQztBQUMxQyxDQUFDO0FBRUQsU0FBUyxNQUFNLENBQUMsR0FBRyxRQUFzQjtJQUN2QyxNQUFNLE1BQU0sR0FBRyxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwRixJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDZixLQUFLLE1BQU0sSUFBSSxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3pCLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3hCLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIn0=
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Refuses anything but a valid `Date` whose whole seconds fit an OpenPGP v4
3
+ * time field (1970-01-01 to 2106-02-07).
4
+ */
5
+ export declare function assertTimestamp(valueArg: unknown, fieldArg?: string): asserts valueArg is Date;
6
+ export declare function assertBytes(valueArg: unknown, fieldArg: string): asserts valueArg is Uint8Array;
7
+ /** Refuses anything that is not an object with a `Symbol.asyncIterator` method; the chunks are checked as they arrive. */
8
+ export declare function assertAsyncIterable(valueArg: unknown, fieldArg: string): asserts valueArg is AsyncIterable<unknown>;
9
+ export declare function assertString(valueArg: unknown, fieldArg: string): asserts valueArg is string;
10
+ /** True when the text contains a C0 control character, DEL or a C1 control character. */
11
+ export declare function hasControlCharacter(textArg: string): boolean;
12
+ /**
13
+ * True when the text can name one path segment of a served file: non-empty,
14
+ * not `.` or `..`, no `/` and no control characters.
15
+ */
16
+ export declare function isPathSegment(valueArg: string): boolean;
17
+ /**
18
+ * A name that becomes one path or tar-entry segment: non-empty, no `/`, no
19
+ * control characters.
20
+ */
21
+ export declare function assertSegmentName(valueArg: unknown, fieldArg: string): asserts valueArg is string;
@@ -0,0 +1,58 @@
1
+ import { LinuxRepoError } from './errors.js';
2
+ /** The largest creation time an OpenPGP v4 packet can carry (seconds since the epoch). */
3
+ const MAX_OPENPGP_SECONDS = 0xffffffff;
4
+ /**
5
+ * Refuses anything but a valid `Date` whose whole seconds fit an OpenPGP v4
6
+ * time field (1970-01-01 to 2106-02-07).
7
+ */
8
+ export function assertTimestamp(valueArg, fieldArg = 'timestamp') {
9
+ if (!(valueArg instanceof Date) || !Number.isFinite(valueArg.getTime())) {
10
+ throw new LinuxRepoError('invalid-input', `${fieldArg} must be a valid Date`, { field: fieldArg });
11
+ }
12
+ const seconds = Math.floor(valueArg.getTime() / 1000);
13
+ if (seconds < 0 || seconds > MAX_OPENPGP_SECONDS) {
14
+ throw new LinuxRepoError('invalid-input', `${fieldArg} is outside 1970-01-01..2106-02-07`, {
15
+ field: fieldArg,
16
+ });
17
+ }
18
+ }
19
+ export function assertBytes(valueArg, fieldArg) {
20
+ if (!(valueArg instanceof Uint8Array)) {
21
+ throw new LinuxRepoError('invalid-input', `${fieldArg} must be a Uint8Array`, { field: fieldArg });
22
+ }
23
+ }
24
+ /** Refuses anything that is not an object with a `Symbol.asyncIterator` method; the chunks are checked as they arrive. */
25
+ export function assertAsyncIterable(valueArg, fieldArg) {
26
+ if (valueArg === null ||
27
+ typeof valueArg !== 'object' ||
28
+ typeof valueArg[Symbol.asyncIterator] !== 'function') {
29
+ throw new LinuxRepoError('invalid-input', `${fieldArg} must be an AsyncIterable<Uint8Array>`, { field: fieldArg });
30
+ }
31
+ }
32
+ export function assertString(valueArg, fieldArg) {
33
+ if (typeof valueArg !== 'string') {
34
+ throw new LinuxRepoError('invalid-input', `${fieldArg} must be a string`, { field: fieldArg });
35
+ }
36
+ }
37
+ /** True when the text contains a C0 control character, DEL or a C1 control character. */
38
+ export function hasControlCharacter(textArg) {
39
+ return /\p{Cc}/u.test(textArg);
40
+ }
41
+ /**
42
+ * True when the text can name one path segment of a served file: non-empty,
43
+ * not `.` or `..`, no `/` and no control characters.
44
+ */
45
+ export function isPathSegment(valueArg) {
46
+ return valueArg !== '' && valueArg !== '.' && valueArg !== '..' && !valueArg.includes('/') && !hasControlCharacter(valueArg);
47
+ }
48
+ /**
49
+ * A name that becomes one path or tar-entry segment: non-empty, no `/`, no
50
+ * control characters.
51
+ */
52
+ export function assertSegmentName(valueArg, fieldArg) {
53
+ assertString(valueArg, fieldArg);
54
+ if (valueArg.length === 0 || valueArg.includes('/') || hasControlCharacter(valueArg)) {
55
+ throw new LinuxRepoError('invalid-input', `${fieldArg} must be non-empty and contain no "/" or control characters`, { field: fieldArg });
56
+ }
57
+ }
58
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3NoYXJlZC92YWxpZGF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFN0MsMEZBQTBGO0FBQzFGLE1BQU0sbUJBQW1CLEdBQUcsVUFBVSxDQUFDO0FBRXZDOzs7R0FHRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsUUFBaUIsRUFBRSxRQUFRLEdBQUcsV0FBVztJQUN2RSxJQUFJLENBQUMsQ0FBQyxRQUFRLFlBQVksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDeEUsTUFBTSxJQUFJLGNBQWMsQ0FBQyxlQUFlLEVBQUUsR0FBRyxRQUFRLHVCQUF1QixFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDckcsQ0FBQztJQUNELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ3RELElBQUksT0FBTyxHQUFHLENBQUMsSUFBSSxPQUFPLEdBQUcsbUJBQW1CLEVBQUUsQ0FBQztRQUNqRCxNQUFNLElBQUksY0FBYyxDQUFDLGVBQWUsRUFBRSxHQUFHLFFBQVEsb0NBQW9DLEVBQUU7WUFDekYsS0FBSyxFQUFFLFFBQVE7U0FDaEIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztBQUNILENBQUM7QUFFRCxNQUFNLFVBQVUsV0FBVyxDQUFDLFFBQWlCLEVBQUUsUUFBZ0I7SUFDN0QsSUFBSSxDQUFDLENBQUMsUUFBUSxZQUFZLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDdEMsTUFBTSxJQUFJLGNBQWMsQ0FBQyxlQUFlLEVBQUUsR0FBRyxRQUFRLHVCQUF1QixFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDckcsQ0FBQztBQUNILENBQUM7QUFFRCwwSEFBMEg7QUFDMUgsTUFBTSxVQUFVLG1CQUFtQixDQUFDLFFBQWlCLEVBQUUsUUFBZ0I7SUFDckUsSUFDRSxRQUFRLEtBQUssSUFBSTtRQUNqQixPQUFPLFFBQVEsS0FBSyxRQUFRO1FBQzVCLE9BQVEsUUFBNEMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssVUFBVSxFQUN6RixDQUFDO1FBQ0QsTUFBTSxJQUFJLGNBQWMsQ0FBQyxlQUFlLEVBQUUsR0FBRyxRQUFRLHVDQUF1QyxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDckgsQ0FBQztBQUNILENBQUM7QUFFRCxNQUFNLFVBQVUsWUFBWSxDQUFDLFFBQWlCLEVBQUUsUUFBZ0I7SUFDOUQsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNqQyxNQUFNLElBQUksY0FBYyxDQUFDLGVBQWUsRUFBRSxHQUFHLFFBQVEsbUJBQW1CLEVBQUUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUNqRyxDQUFDO0FBQ0gsQ0FBQztBQUVELHlGQUF5RjtBQUN6RixNQUFNLFVBQVUsbUJBQW1CLENBQUMsT0FBZTtJQUNqRCxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxhQUFhLENBQUMsUUFBZ0I7SUFDNUMsT0FBTyxRQUFRLEtBQUssRUFBRSxJQUFJLFFBQVEsS0FBSyxHQUFHLElBQUksUUFBUSxLQUFLLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMvSCxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLFFBQWlCLEVBQUUsUUFBZ0I7SUFDbkUsWUFBWSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNqQyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksbUJBQW1CLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUNyRixNQUFNLElBQUksY0FBYyxDQUN0QixlQUFlLEVBQ2YsR0FBRyxRQUFRLDZEQUE2RCxFQUN4RSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FDcEIsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDIn0=
@@ -0,0 +1,36 @@
1
+ /** An Alpine key pair in Gitea's stored forms. */
2
+ export interface IAlpineKeyPair {
3
+ /** PKCS#1 PEM (`RSA PRIVATE KEY`). */
4
+ privateKeyPem: string;
5
+ /** PKIX/SPKI PEM (`PUBLIC KEY`). */
6
+ publicKeyPem: string;
7
+ }
8
+ /** An OpenPGP key pair, armored. */
9
+ export interface IOpenPgpKeyPair {
10
+ privateKeyArmored: string;
11
+ publicKeyArmored: string;
12
+ /** The v4 fingerprint, 40 uppercase hex digits. */
13
+ fingerprint: string;
14
+ }
15
+ /**
16
+ * Generates an RSA-4096 Alpine key pair in Gitea's forms (Gitea
17
+ * `util.GenerateKeyPair(4096)`: PKCS#1 private key, PKIX public key, e=65537).
18
+ * The codec stores nothing. A failure inside node:crypto propagates unchanged.
19
+ */
20
+ export declare function generateAlpineKeyPair(): Promise<IAlpineKeyPair>;
21
+ /**
22
+ * Generates an RSA-4096 OpenPGP v4 key pair (primary key for certification and
23
+ * signing, RSA-4096 encryption subkey, no expiry) whose creation time is
24
+ * `timestamp` and whose single user ID is exactly `userId`. Bad input is
25
+ * `invalid-input`; a failure inside openpgp.js propagates unchanged.
26
+ */
27
+ export declare function generateOpenPgpKeyPair(inputArg: {
28
+ userId: string;
29
+ timestamp: Date;
30
+ }): Promise<IOpenPgpKeyPair>;
31
+ /**
32
+ * Gitea's Alpine key name: `<ownerLowerName>@<hex>.rsa.pub`, where `<hex>` is
33
+ * the lowercase hex SHA-256 of the PKIX (SPKI) DER of the RSA public key
34
+ * (Gitea `util.CreatePublicKeyFingerprint`). Pass the owner's lower-case name.
35
+ */
36
+ export declare function giteaAlpineKeyName(ownerLowerName: string, publicKeyPem: string): string;
@@ -0,0 +1,89 @@
1
+ import * as plugins from '../plugins.js';
2
+ import { LinuxRepoError } from '../shared/errors.js';
3
+ import { assertSegmentName, assertString, assertTimestamp, hasControlCharacter } from '../shared/validation.js';
4
+ const RSA_BITS = 4096;
5
+ /**
6
+ * Generates an RSA-4096 Alpine key pair in Gitea's forms (Gitea
7
+ * `util.GenerateKeyPair(4096)`: PKCS#1 private key, PKIX public key, e=65537).
8
+ * The codec stores nothing. A failure inside node:crypto propagates unchanged.
9
+ */
10
+ export async function generateAlpineKeyPair() {
11
+ const { privateKey, publicKey } = await new Promise((resolve, reject) => {
12
+ plugins.crypto.generateKeyPair('rsa', {
13
+ modulusLength: RSA_BITS,
14
+ publicExponent: 0x10001,
15
+ privateKeyEncoding: { type: 'pkcs1', format: 'pem' },
16
+ publicKeyEncoding: { type: 'spki', format: 'pem' },
17
+ }, (error, publicKeyArg, privateKeyArg) => {
18
+ if (error) {
19
+ reject(error);
20
+ }
21
+ else {
22
+ resolve({ privateKey: privateKeyArg, publicKey: publicKeyArg });
23
+ }
24
+ });
25
+ });
26
+ return { privateKeyPem: privateKey, publicKeyPem: publicKey };
27
+ }
28
+ /**
29
+ * Generates an RSA-4096 OpenPGP v4 key pair (primary key for certification and
30
+ * signing, RSA-4096 encryption subkey, no expiry) whose creation time is
31
+ * `timestamp` and whose single user ID is exactly `userId`. Bad input is
32
+ * `invalid-input`; a failure inside openpgp.js propagates unchanged.
33
+ */
34
+ export async function generateOpenPgpKeyPair(inputArg) {
35
+ if (inputArg === null || typeof inputArg !== 'object') {
36
+ throw new LinuxRepoError('invalid-input', 'input must be an object', { field: 'input' });
37
+ }
38
+ assertString(inputArg.userId, 'userId');
39
+ if (inputArg.userId.length === 0 || hasControlCharacter(inputArg.userId)) {
40
+ throw new LinuxRepoError('invalid-input', 'userId must be non-empty and contain no control characters', {
41
+ field: 'userId',
42
+ });
43
+ }
44
+ assertTimestamp(inputArg.timestamp);
45
+ const generated = await plugins.openpgp.generateKey({
46
+ type: 'rsa',
47
+ rsaBits: RSA_BITS,
48
+ userIDs: [{ name: inputArg.userId }],
49
+ date: inputArg.timestamp,
50
+ format: 'object',
51
+ config: { v6Keys: false },
52
+ });
53
+ return {
54
+ privateKeyArmored: generated.privateKey.armor(),
55
+ publicKeyArmored: generated.publicKey.armor(),
56
+ fingerprint: generated.privateKey.getFingerprint().toUpperCase(),
57
+ };
58
+ }
59
+ /**
60
+ * Gitea's Alpine key name: `<ownerLowerName>@<hex>.rsa.pub`, where `<hex>` is
61
+ * the lowercase hex SHA-256 of the PKIX (SPKI) DER of the RSA public key
62
+ * (Gitea `util.CreatePublicKeyFingerprint`). Pass the owner's lower-case name.
63
+ */
64
+ export function giteaAlpineKeyName(ownerLowerName, publicKeyPem) {
65
+ assertSegmentName(ownerLowerName, 'ownerLowerName');
66
+ assertString(publicKeyPem, 'publicKeyPem');
67
+ const label = /-----BEGIN ([A-Z0-9 ]+)-----/.exec(publicKeyPem)?.[1];
68
+ if (label !== 'PUBLIC KEY') {
69
+ throw new LinuxRepoError('invalid-key', 'the Alpine public key must be a PKIX "PUBLIC KEY" PEM', {
70
+ field: 'publicKeyPem',
71
+ });
72
+ }
73
+ let key;
74
+ try {
75
+ key = plugins.crypto.createPublicKey({ key: publicKeyPem, format: 'pem' });
76
+ }
77
+ catch (error) {
78
+ throw new LinuxRepoError('invalid-key', 'the Alpine public key cannot be read', { field: 'publicKeyPem' }, {
79
+ cause: error,
80
+ });
81
+ }
82
+ if (key.asymmetricKeyType !== 'rsa') {
83
+ throw new LinuxRepoError('invalid-key', 'the Alpine public key must be an RSA key', { field: 'publicKeyPem' });
84
+ }
85
+ const der = key.export({ type: 'spki', format: 'der' });
86
+ const hex = plugins.crypto.createHash('sha256').update(der).digest('hex');
87
+ return `${ownerLowerName}@${hex}.rsa.pub`;
88
+ }
89
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3NpZ25pbmcva2V5cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFlBQVksRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQWtCaEgsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBRXRCOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLHFCQUFxQjtJQUN6QyxNQUFNLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxHQUFHLE1BQU0sSUFBSSxPQUFPLENBQTRDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ2pILE9BQU8sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUM1QixLQUFLLEVBQ0w7WUFDRSxhQUFhLEVBQUUsUUFBUTtZQUN2QixjQUFjLEVBQUUsT0FBTztZQUN2QixrQkFBa0IsRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtZQUNwRCxpQkFBaUIsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtTQUNuRCxFQUNELENBQUMsS0FBSyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsRUFBRTtZQUNyQyxJQUFJLEtBQUssRUFBRSxDQUFDO2dCQUNWLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNoQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sT0FBTyxDQUFDLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztZQUNsRSxDQUFDO1FBQ0gsQ0FBQyxDQUNGLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJ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
@@ -0,0 +1,33 @@
1
+ import { type IOpenPgpSigner } from './signers.js';
2
+ /**
3
+ * Signs the concatenation of the chunks of `data` and returns the signer's
4
+ * binary packet unchanged (Arch `.sig`, RPM header tags). The signer reads
5
+ * `data` to its end exactly once.
6
+ */
7
+ export declare function createDetachedBinarySignature(inputArg: {
8
+ data: AsyncIterable<Uint8Array>;
9
+ signer: IOpenPgpSigner;
10
+ timestamp: Date;
11
+ }): Promise<Uint8Array>;
12
+ /** Signs `data` and returns an armored detached signature (`Release.gpg`, `repomd.xml.asc`). */
13
+ export declare function createDetachedArmoredSignature(inputArg: {
14
+ data: Uint8Array;
15
+ signer: IOpenPgpSigner;
16
+ timestamp: Date;
17
+ }): Promise<string>;
18
+ /**
19
+ * Cleartext-signs `text` (`InRelease`). The text must be canonical: no CR and
20
+ * no trailing spaces or tabs on any line. The signed text is `text` without
21
+ * its final line break; the output always ends the text with one line break
22
+ * before the signature block, as GnuPG and Go do. Lines starting with `-` are
23
+ * dash-escaped. The header is always `Hash: SHA256`.
24
+ */
25
+ export declare function createCleartextSignedMessage(inputArg: {
26
+ text: string;
27
+ signer: IOpenPgpSigner;
28
+ timestamp: Date;
29
+ }): Promise<string>;
30
+ /** ASCII armor for one signature packet list. */
31
+ export declare function armorSignature(packetArg: Uint8Array): string;
32
+ /** Refuses text that is not canonical cleartext input. */
33
+ export declare function assertCanonicalText(textArg: unknown): asserts textArg is string;