@openpresentation/opf 0.11.4 → 0.12.1
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/README.md +16 -0
- package/dist/audit.d.ts +156 -0
- package/dist/audit.js +7 -0
- package/dist/{catalogs-CUClB3nl.d.ts → catalogs-BnI7JKcn.d.ts} +3 -3
- package/dist/catalogs.d.ts +2 -2
- package/dist/catalogs.js +2 -1
- package/dist/{chunk-KJKASEPE.js → chunk-4LAM3N6S.js} +753 -42
- package/dist/chunk-6LZK2IZB.js +1690 -0
- package/dist/{chunk-NSVVQ52O.js → chunk-AUM5MXBR.js} +8 -6
- package/dist/{chunk-AEUSVEUY.js → chunk-E34DJ5LL.js} +50 -14
- package/dist/chunk-FYLJVF7X.js +18448 -0
- package/dist/{chunk-HJL64ETN.js → chunk-GJKJL4YY.js} +14 -0
- package/dist/{chunk-3H2U7FDR.js → chunk-HOBSL7AJ.js} +1867 -247
- package/dist/chunk-JKVKYVWL.js +1332 -0
- package/dist/{chunk-3OJN7QAW.js → chunk-MWPMJE6P.js} +18 -4
- package/dist/chunk-RUC7L5DJ.js +261 -0
- package/dist/chunk-S5W34SIJ.js +1 -0
- package/dist/chunk-V2537ENL.js +198 -0
- package/dist/{chunk-RXNFDGPC.js → chunk-WXSPETQ6.js} +311 -40
- package/dist/{composition-Dl-d9FRj.d.ts → composition-DWbCiMwF.d.ts} +559 -10
- package/dist/composition.d.ts +1 -1
- package/dist/composition.js +2 -1
- package/dist/convert.d.ts +261 -0
- package/dist/convert.js +1107 -0
- package/dist/diff.d.ts +145 -0
- package/dist/diff.js +604 -0
- package/dist/docs.js +72 -18
- package/dist/examples.d.ts +1 -1
- package/dist/examples.js +112 -112
- package/dist/font-policy.d.ts +15 -0
- package/dist/font-policy.js +1 -1
- package/dist/format.d.ts +20 -0
- package/dist/format.js +83 -0
- package/dist/index.d.ts +173 -24
- package/dist/index.js +926 -262
- package/dist/lint.d.ts +4 -4
- package/dist/lint.js +6 -5
- package/dist/markdown.d.ts +74 -0
- package/dist/markdown.js +1941 -0
- package/dist/pagination.d.ts +1 -1
- package/dist/pagination.js +6 -5
- package/dist/patch.d.ts +99 -0
- package/dist/patch.js +6 -0
- package/dist/{presentation-j5PVrqfV.d.ts → presentation-DcF-MZcz.d.ts} +452 -17
- package/dist/repo-readme.js +1 -1
- package/dist/{schemas-X_NniU4A.d.ts → schemas-BSjlG8-R.d.ts} +28 -0
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.js +1 -1
- package/dist/spec/catalogs/audiences/customers.json +5 -1
- package/dist/spec/catalogs/audiences/executives.json +5 -1
- package/dist/spec/catalogs/audiences/index.json +20 -8
- package/dist/spec/catalogs/audiences/investors.json +5 -1
- package/dist/spec/catalogs/audiences/marketing-team.json +5 -1
- package/dist/spec/catalogs/audiences/regulators.json +5 -1
- package/dist/spec/catalogs/audiences/sales-team.json +5 -1
- package/dist/spec/catalogs/manifest.json +2 -2
- package/dist/spec/reference/engine-defaults.json +1 -1
- package/dist/spec/reference/font-policy.json +311 -40
- package/dist/spec/reference/font-policy.schema.json +40 -0
- package/dist/spec/reference/symbol-font-encodings.json +18354 -0
- package/dist/spec/reference/symbol-font-encodings.schema.json +156 -0
- package/dist/spec/schemas/audience.schema.json +7 -7
- package/dist/spec/schemas/narrative.schema.json +1 -1
- package/dist/spec/schemas/opf.schema.json +597 -28
- package/dist/spec-files.d.ts +1 -1
- package/dist/spec-files.js +1 -1
- package/dist/symbol-font-encodings.d.ts +128 -0
- package/dist/symbol-font-encodings.js +1 -0
- package/dist/types.d.ts +4 -4
- package/dist/validator-DfG9yxba.d.ts +172 -0
- package/dist/validator.d.ts +4 -36
- package/dist/validator.js +5 -4
- package/package.json +32 -3
- package/dist/chunk-FDCWQHWO.js +0 -1366
package/dist/index.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
export { specFileEntries, specFileKinds, specFilePaths } from './chunk-
|
|
1
|
+
export { specFileEntries, specFileKinds, specFilePaths } from './chunk-GJKJL4YY.js';
|
|
2
2
|
export { getLayoutPreview, hasLayoutPreview, layoutPreviewIndex, layoutPreviewSlugs, layoutPreviews } from './chunk-PIQXLBBJ.js';
|
|
3
|
-
export {
|
|
4
|
-
export { FONT_POLICY, applyFontPolicyDecisions, fontAvailabilityDiagnostics, fontPolicyFor } from './chunk-RXNFDGPC.js';
|
|
3
|
+
export { SYMBOL_FONT_ENCODINGS, SYMBOL_FONT_FAMILIES, isSymbolEncodedFamily, mapSymbolText, symbolCodeForUnicode, symbolCodeOf, symbolFontEncodingFor, symbolUnicodeFor } from './chunk-FYLJVF7X.js';
|
|
5
4
|
export { OPFDataImportError, createDataContent, parseTabularData } from './chunk-SOSOBKQ2.js';
|
|
6
|
-
export { OPFPaginationError, paginatePresentation, paginateSlide } from './chunk-
|
|
7
|
-
|
|
8
|
-
export {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export {
|
|
12
|
-
import
|
|
13
|
-
|
|
5
|
+
export { OPFPaginationError, paginatePresentation, paginateSlide } from './chunk-AUM5MXBR.js';
|
|
6
|
+
export { DEFAULT_AUDIT_THRESHOLDS, DEFAULT_CHART_PALETTE, auditPresentation, auditRules, auditSource, findAuditRule } from './chunk-6LZK2IZB.js';
|
|
7
|
+
export { lintPresentation, lintSource } from './chunk-MWPMJE6P.js';
|
|
8
|
+
export { DEFAULT_VARIABLE_DATE_FORMAT, OPFValidationError, OPFVariableError, VARIABLE_KINDS, assertValid, assertValidCatalogRecord, assertValidPresentation, coerceVariableValue, formatVariableNumber, hasContentVariables, isTemplate, listVariables, resolveVariables, validate, validateCatalogRecord, validatePresentation, variableDeclarations } from './chunk-JKVKYVWL.js';
|
|
9
|
+
import { isRecord, visitContentPayloads, bareIdPattern } from './chunk-HOBSL7AJ.js';
|
|
10
|
+
export { CAPTIONABLE_FIELDS, CAPTION_FONT_RATIO, CAPTION_MAX_RATIO, CHART_SERIES_MIN_DIFFERENCE, CHART_SERIES_MIN_LIGHTNESS_STEP, CITATION_MARKER_RAISE, CITATION_MARKER_SCALE, DEFAULT_CHART_LABEL_SEPARATOR, DEFAULT_FONT_SCHEME, DEFAULT_FURNITURE_DATE_FORMAT, DEFAULT_SLIDE_NUMBER_FORMAT, FONT_SIZE_GRID_PER_PX, FOOTNOTE_MAX_RATIO, MAX_COMPOSITION_DEPTH, MAX_NUMBERING_LEVELS, MAX_NUMBERING_VALUE, MAX_ROMAN_VALUE, NUMBERING_STYLES, NUMBERING_SUFFIXES, OPFCompositionError, PICTURE_BULLET_SCALE, annotationText, captionSettings, chartColorForFill, chartLabelText, chartOptionSupport, chartOptionTarget, chartPaletteForFill, citationMarkerText, collectCitations, colorContrast, composeSlide, fitList, fitRichText, fitText, formatChartLabelNumber, formatChartLabelPercent, formatFurnitureDate, formatListNumber, formatSlideNumber, layoutCaption, layoutCode, layoutFootnotes, layoutFurniture, layoutMetric, layoutQuote, layoutTimeline, listNumbers, measureText, measureTextOutline, normalizeHexColor, numberingAtLevel, numberingStyleDraws, paragraphDirection, paragraphDirectionAt, physicalAlignment, placeTextLines, referencesSlide, resolveCanvasDimensions, resolveChartOptions, resolveColorRef, resolveFontFamilies, resolveFontSchemeReference, resolveLogo, resolveNumbering, resolveScriptFonts, resolveSlideDirection, resolveSocialProfile, resolveTextStyle, scriptFontRole, sliceNumberedItems, slideCitations, snapFontSizeDown, snapFontSizeUp, textColorForFill, textWidthMeasurer, walkCitationRuns, wrapText } from './chunk-HOBSL7AJ.js';
|
|
11
|
+
import './chunk-S5W34SIJ.js';
|
|
12
|
+
import { catalogEntries } from './chunk-E34DJ5LL.js';
|
|
13
|
+
export { audiences, catalogEntries, catalogIndexes, catalogKinds, catalogSchemaNames, catalogs, chartTypes, colorSchemes, fontSchemes, languages, layouts, narratives, purposes, socialPlatforms, themes, tones } from './chunk-E34DJ5LL.js';
|
|
14
|
+
export { audience, chartType, colorScheme, fontScheme, language, layout, narrative, presentation, purpose, schemaEntries, schemaNames, schemas, socialPlatform, theme, tone } from './chunk-4LAM3N6S.js';
|
|
15
|
+
export { FONT_POLICY, applyFontPolicyDecisions, fontAvailabilityDiagnostics, fontPolicyFor } from './chunk-WXSPETQ6.js';
|
|
14
16
|
|
|
15
17
|
// src/bundle.ts
|
|
16
18
|
function reportKey(kind, id) {
|
|
@@ -209,267 +211,929 @@ function bundlePresentation(value) {
|
|
|
209
211
|
return { presentation: presentation2, report };
|
|
210
212
|
}
|
|
211
213
|
|
|
212
|
-
// src/
|
|
213
|
-
var
|
|
214
|
-
var
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
"
|
|
229
|
-
|
|
230
|
-
"
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
214
|
+
// src/legible-color.ts
|
|
215
|
+
var channels = (hex) => [1, 3, 5].map((offset) => Number.parseInt(hex.slice(offset, offset + 2), 16));
|
|
216
|
+
var toHex = (values) => `#${values.map((value) => Math.max(0, Math.min(255, Math.round(value))).toString(16).padStart(2, "0")).join("").toUpperCase()}`;
|
|
217
|
+
var linear = (value) => {
|
|
218
|
+
const n = value / 255;
|
|
219
|
+
return n <= 0.04045 ? n / 12.92 : ((n + 0.055) / 1.055) ** 2.4;
|
|
220
|
+
};
|
|
221
|
+
var luminance = (hex) => {
|
|
222
|
+
const [r, g, b] = channels(hex);
|
|
223
|
+
return 0.2126 * linear(r) + 0.7152 * linear(g) + 0.0722 * linear(b);
|
|
224
|
+
};
|
|
225
|
+
var contrast = (a, b) => {
|
|
226
|
+
const x = luminance(a), y = luminance(b);
|
|
227
|
+
return (Math.max(x, y) + 0.05) / (Math.min(x, y) + 0.05);
|
|
228
|
+
};
|
|
229
|
+
var normalize = (value) => {
|
|
230
|
+
if (typeof value !== "string") return void 0;
|
|
231
|
+
const text = value.trim();
|
|
232
|
+
if (/^#[0-9a-f]{3}$/i.test(text)) return `#${[...text.slice(1)].map((c) => c + c).join("")}`.toUpperCase();
|
|
233
|
+
return /^#[0-9a-f]{6}([0-9a-f]{2})?$/i.test(text) ? text.slice(0, 7).toUpperCase() : void 0;
|
|
234
|
+
};
|
|
235
|
+
function toHsl(hex) {
|
|
236
|
+
const [r, g, b] = channels(hex).map((value) => value / 255);
|
|
237
|
+
const max = Math.max(r, g, b), min = Math.min(r, g, b), l = (max + min) / 2, d = max - min;
|
|
238
|
+
if (d === 0) return [0, 0, l];
|
|
239
|
+
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
240
|
+
const h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
|
|
241
|
+
return [h * 60, s, l];
|
|
242
|
+
}
|
|
243
|
+
function fromHsl(h, s, l) {
|
|
244
|
+
const hue = (h % 360 + 360) % 360, c = (1 - Math.abs(2 * l - 1)) * s, x = c * (1 - Math.abs(hue / 60 % 2 - 1)), m = l - c / 2;
|
|
245
|
+
const [r, g, b] = hue < 60 ? [c, x, 0] : hue < 120 ? [x, c, 0] : hue < 180 ? [0, c, x] : hue < 240 ? [0, x, c] : hue < 300 ? [x, 0, c] : [c, 0, x];
|
|
246
|
+
return toHex([(r + m) * 255, (g + m) * 255, (b + m) * 255]);
|
|
247
|
+
}
|
|
248
|
+
function legible(foreground, background, minimum) {
|
|
249
|
+
if (contrast(foreground, background) >= minimum) return foreground;
|
|
250
|
+
const [h, s, l] = toHsl(foreground), preferred = luminance(background) < 0.5 ? 1 : -1;
|
|
251
|
+
for (const direction of [preferred, -preferred]) {
|
|
252
|
+
for (let step = 1; step <= 100; step++) {
|
|
253
|
+
const lightness = l + direction * step / 100;
|
|
254
|
+
if (lightness < 0 || lightness > 1) break;
|
|
255
|
+
const candidate = fromHsl(h, s, lightness);
|
|
256
|
+
if (contrast(candidate, background) >= minimum) return candidate;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return contrast("#FFFFFF", background) >= contrast("#000000", background) ? "#FFFFFF" : "#000000";
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/code-syntax.ts
|
|
263
|
+
var CODE_HIGHLIGHT_MAX_LENGTH = 2e5;
|
|
264
|
+
var CODE_SYNTAX_MIN_CONTRAST = 4.5;
|
|
265
|
+
var CODE_PANEL_BACKGROUND = "#111827";
|
|
266
|
+
var CODE_PANEL_FOREGROUND = "#E5E7EB";
|
|
267
|
+
var set = (words) => new Set((words ?? "").split(/\s+/).filter(Boolean));
|
|
268
|
+
var JS_KEYWORDS = "break case catch class const continue debugger default delete do else enum export extends finally for from function if import in instanceof let new of return static super switch this throw try typeof var void while with yield async await as get set declare namespace module abstract implements interface private protected public readonly override keyof satisfies type is infer";
|
|
269
|
+
var JS = { line: ["//"], block: [["/*", "*/"]], strings: "'\"`", keywords: JS_KEYWORDS, literals: "true false null undefined NaN Infinity", types: "string number boolean object symbol bigint never unknown any void", defs: { function: "function", class: "type", interface: "type", enum: "type", type: "type" }, capsTypes: true, calls: true, decorators: true };
|
|
270
|
+
var C_LIKE_KEYWORDS = "auto break case catch char class const constexpr continue default delete do double else enum explicit extern false final float for friend goto if inline int long mutable namespace new noexcept nullptr operator override private protected public register return short signed sizeof static struct switch template this throw true try typedef typename union unsigned using virtual void volatile while";
|
|
271
|
+
var LANGUAGES = {
|
|
272
|
+
javascript: JS,
|
|
273
|
+
typescript: JS,
|
|
274
|
+
python: { line: ["#"], strings: `'"`, triple: ['"""', "'''"], keywords: "and as assert async await break class continue def del elif else except finally for from global if import in is lambda nonlocal not or pass raise return try while with yield match case self cls", literals: "True False None", types: "int float str bool bytes list dict set tuple object type", defs: { def: "function", class: "type" }, capsTypes: true, calls: true, decorators: true },
|
|
275
|
+
rust: { line: ["//"], block: [["/*", "*/"]], strings: '"', rawStrings: "r", keywords: "as async await break const continue crate dyn else enum extern fn for if impl in let loop match mod move mut pub ref return self Self static struct super trait type unsafe use where while", literals: "true false", types: "i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 bool char str String Vec Option Result Box", defs: { fn: "function", struct: "type", enum: "type", trait: "type", type: "type", mod: "type" }, capsTypes: true, calls: true, macros: true },
|
|
276
|
+
go: { line: ["//"], block: [["/*", "*/"]], strings: "\"'`", noEscapes: "`", keywords: "break case chan const continue default defer else fallthrough for func go goto if import interface map package range return select struct switch type var", literals: "true false nil iota", types: "int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr float32 float64 complex64 complex128 string bool byte rune error any", defs: { func: "function", type: "type" }, capsTypes: true, calls: true },
|
|
277
|
+
bash: { line: ["#"], strings: `'"`, noEscapes: "'", keywords: "if then else elif fi for while until do done case esac in function select time return exit break continue export local readonly declare unset set shift source alias trap eval exec", literals: "true false", variables: true, calls: false },
|
|
278
|
+
json: { line: ["//"], block: [["/*", "*/"]], strings: '"', literals: "true false null", quotedKeys: true },
|
|
279
|
+
yaml: { kind: "yaml" },
|
|
280
|
+
toml: { kind: "ini", line: ["#"] },
|
|
281
|
+
ini: { kind: "ini", line: ["#", ";"] },
|
|
282
|
+
markup: { kind: "markup" },
|
|
283
|
+
css: { kind: "css" },
|
|
284
|
+
sql: { line: ["--"], block: [["/*", "*/"]], strings: `'"`, ci: true, keywords: "add all alter and any as asc between by case check column commit constraint create cross database default delete desc distinct drop else end exists foreign from full group having if in index inner insert into is join key left like limit not null offset on or order outer primary references replace right rollback select set table then top union unique update values view when where with", literals: "true false", types: "int integer bigint smallint decimal numeric float real double varchar char text date time timestamp boolean serial uuid json" },
|
|
285
|
+
java: { line: ["//"], block: [["/*", "*/"]], strings: `"'`, keywords: "abstract assert break case catch class const continue default do else enum extends final finally for goto if implements import instanceof interface native new package private protected public return static strictfp super switch synchronized this throw throws transient try var volatile while record sealed permits", literals: "true false null", types: "boolean byte char double float int long short void String Object", defs: { class: "type", interface: "type", enum: "type", record: "type" }, capsTypes: true, calls: true, decorators: true },
|
|
286
|
+
csharp: { line: ["//"], block: [["/*", "*/"]], strings: `"'`, keywords: "abstract as async await base break case catch checked class const continue default delegate do else enum event explicit extern finally fixed for foreach goto if implicit in interface internal is lock namespace new operator out override params private protected public readonly ref return sealed sizeof stackalloc static struct switch this throw try typeof unchecked unsafe using var virtual volatile while record init required", literals: "true false null", types: "bool byte char decimal double float int long object sbyte short string uint ulong ushort void dynamic", defs: { class: "type", interface: "type", struct: "type", enum: "type", record: "type" }, capsTypes: true, calls: true, decorators: false },
|
|
287
|
+
kotlin: { line: ["//"], block: [["/*", "*/"]], strings: `"'`, triple: ['"""'], keywords: "abstract actual annotation as break by catch class companion const constructor continue crossinline data do else enum expect external final finally for fun get if import in infix init inline inner interface internal is it lateinit lazy noinline object open operator out override package private protected public reified return sealed set super suspend tailrec this throw try typealias val var vararg when where while", literals: "true false null", types: "Int Long Short Byte Float Double Boolean Char String Unit Any Nothing", defs: { fun: "function", class: "type", interface: "type", object: "type" }, capsTypes: true, calls: true, decorators: true },
|
|
288
|
+
swift: { line: ["//"], block: [["/*", "*/"]], strings: '"', triple: ['"""'], keywords: "actor as associatedtype async await break case catch class continue default defer deinit do else enum extension fallthrough fileprivate for func guard if import in init inout internal is let nonisolated open operator private protocol public repeat rethrows return self Self static struct subscript super switch throw throws try typealias var where while", literals: "true false nil", types: "Int Double Float Bool String Character Array Dictionary Set Optional Any", defs: { func: "function", class: "type", struct: "type", enum: "type", protocol: "type", extension: "type" }, capsTypes: true, calls: true, decorators: true },
|
|
289
|
+
ruby: { line: ["#"], strings: `'"`, keywords: "alias and begin break case class def defined do else elsif end ensure for if in module next not or redo rescue retry return self super then undef unless until when while yield require require_relative include extend attr_accessor attr_reader attr_writer private protected public", literals: "true false nil", defs: { def: "function", class: "type", module: "type" }, capsTypes: true, calls: true },
|
|
290
|
+
php: { line: ["//", "#"], block: [["/*", "*/"]], strings: `'"`, keywords: "abstract and array as break callable case catch class clone const continue declare default do echo else elseif empty enddeclare endfor endforeach endif endswitch endwhile extends final finally fn for foreach function global goto if implements include include_once instanceof insteadof interface isset list match namespace new or print private protected public readonly require require_once return static switch throw trait try unset use var while xor yield", literals: "true false null TRUE FALSE NULL", defs: { function: "function", class: "type", interface: "type", trait: "type" }, capsTypes: true, calls: true, variables: true },
|
|
291
|
+
c: { line: ["//"], block: [["/*", "*/"]], strings: `"'`, keywords: C_LIKE_KEYWORDS, literals: "true false NULL nullptr", types: "size_t ssize_t int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t bool FILE", calls: true, capsTypes: false, directives: true, defs: { struct: "type", enum: "type", union: "type", class: "type" } },
|
|
292
|
+
hcl: { line: ["#", "//"], block: [["/*", "*/"]], strings: '"', keywords: "resource data variable output locals module provider terraform for in if else dynamic content backend required_providers lifecycle", literals: "true false null", types: "string number bool list map set object tuple any", calls: true },
|
|
293
|
+
dockerfile: { line: ["#"], strings: `'"`, keywords: "FROM RUN CMD LABEL MAINTAINER EXPOSE ENV ADD COPY ENTRYPOINT VOLUME USER WORKDIR ARG ONBUILD STOPSIGNAL HEALTHCHECK SHELL AS", variables: true }
|
|
294
|
+
};
|
|
295
|
+
var ALIASES = {
|
|
296
|
+
js: "javascript",
|
|
297
|
+
javascript: "javascript",
|
|
298
|
+
mjs: "javascript",
|
|
299
|
+
cjs: "javascript",
|
|
300
|
+
jsx: "javascript",
|
|
301
|
+
node: "javascript",
|
|
302
|
+
nodejs: "javascript",
|
|
303
|
+
ts: "typescript",
|
|
304
|
+
typescript: "typescript",
|
|
305
|
+
tsx: "typescript",
|
|
306
|
+
mts: "typescript",
|
|
307
|
+
cts: "typescript",
|
|
308
|
+
python: "python",
|
|
309
|
+
py: "python",
|
|
310
|
+
python3: "python",
|
|
311
|
+
py3: "python",
|
|
312
|
+
rust: "rust",
|
|
313
|
+
rs: "rust",
|
|
314
|
+
go: "go",
|
|
315
|
+
golang: "go",
|
|
316
|
+
bash: "bash",
|
|
317
|
+
sh: "bash",
|
|
318
|
+
shell: "bash",
|
|
319
|
+
zsh: "bash",
|
|
320
|
+
console: "bash",
|
|
321
|
+
shellscript: "bash",
|
|
322
|
+
fish: "bash",
|
|
323
|
+
json: "json",
|
|
324
|
+
jsonc: "json",
|
|
325
|
+
json5: "json",
|
|
326
|
+
yaml: "yaml",
|
|
327
|
+
yml: "yaml",
|
|
328
|
+
toml: "toml",
|
|
329
|
+
ini: "ini",
|
|
330
|
+
conf: "ini",
|
|
331
|
+
cfg: "ini",
|
|
332
|
+
properties: "ini",
|
|
333
|
+
env: "ini",
|
|
334
|
+
markup: "markup",
|
|
335
|
+
html: "markup",
|
|
336
|
+
xml: "markup",
|
|
337
|
+
svg: "markup",
|
|
338
|
+
xhtml: "markup",
|
|
339
|
+
vue: "markup",
|
|
340
|
+
plist: "markup",
|
|
341
|
+
css: "css",
|
|
342
|
+
scss: "css",
|
|
343
|
+
less: "css",
|
|
344
|
+
sass: "css",
|
|
345
|
+
sql: "sql",
|
|
346
|
+
postgres: "sql",
|
|
347
|
+
postgresql: "sql",
|
|
348
|
+
mysql: "sql",
|
|
349
|
+
sqlite: "sql",
|
|
350
|
+
pgsql: "sql",
|
|
351
|
+
java: "java",
|
|
352
|
+
csharp: "csharp",
|
|
353
|
+
cs: "csharp",
|
|
354
|
+
"c#": "csharp",
|
|
355
|
+
kotlin: "kotlin",
|
|
356
|
+
kt: "kotlin",
|
|
357
|
+
swift: "swift",
|
|
358
|
+
ruby: "ruby",
|
|
359
|
+
rb: "ruby",
|
|
360
|
+
php: "php",
|
|
361
|
+
c: "c",
|
|
362
|
+
h: "c",
|
|
363
|
+
cpp: "c",
|
|
364
|
+
"c++": "c",
|
|
365
|
+
cc: "c",
|
|
366
|
+
cxx: "c",
|
|
367
|
+
hpp: "c",
|
|
368
|
+
hh: "c",
|
|
369
|
+
objc: "c",
|
|
370
|
+
hcl: "hcl",
|
|
371
|
+
terraform: "hcl",
|
|
372
|
+
tf: "hcl",
|
|
373
|
+
tfvars: "hcl",
|
|
374
|
+
dockerfile: "dockerfile",
|
|
375
|
+
docker: "dockerfile"
|
|
261
376
|
};
|
|
262
|
-
var
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
377
|
+
var CODE_HIGHLIGHT_LANGUAGES = Object.freeze(Object.keys(LANGUAGES));
|
|
378
|
+
function resolveCodeLanguage(language2) {
|
|
379
|
+
if (typeof language2 !== "string") return void 0;
|
|
380
|
+
const key = language2.trim().toLowerCase().replace(/^(?:language|lang)[-:]/, "").replace(/^\./, "");
|
|
381
|
+
return Object.hasOwn(ALIASES, key) ? ALIASES[key] : void 0;
|
|
382
|
+
}
|
|
383
|
+
var IDENT = /[\p{L}_$][\p{L}\p{N}_$]*/uy;
|
|
384
|
+
var NUMBER = /(?:0[xX][\da-fA-F_]+|0[bB][01_]+|0[oO][0-7_]+|\d[\d_]*(?:\.\d[\d_]*)?(?:[eE][+-]?\d[\d_]*)?)[a-zA-Z]{0,4}/y;
|
|
385
|
+
var isIdentChar = (character) => character !== void 0 && /[\p{L}\p{N}_$]/u.test(character);
|
|
386
|
+
function endOfLine(source, from) {
|
|
387
|
+
const index = source.slice(from).search(/\r\n|\r|\n/);
|
|
388
|
+
return index < 0 ? source.length : from + index;
|
|
389
|
+
}
|
|
390
|
+
function pushToken(tokens, start, end, kind) {
|
|
391
|
+
if (end <= start) return;
|
|
392
|
+
const last = tokens[tokens.length - 1];
|
|
393
|
+
if (last && last.kind === kind && last.end === start && kind !== "function" && kind !== "property") last.end = end;
|
|
394
|
+
else tokens.push({ start, end, kind });
|
|
395
|
+
}
|
|
396
|
+
function scanQuoted(source, from, quote, escapes, multiline) {
|
|
397
|
+
let index = from + 1;
|
|
398
|
+
while (index < source.length) {
|
|
399
|
+
const character = source[index];
|
|
400
|
+
if (escapes && character === "\\") {
|
|
401
|
+
index += 2;
|
|
402
|
+
continue;
|
|
274
403
|
}
|
|
404
|
+
if (character === quote) return index + 1;
|
|
405
|
+
if (!multiline && (character === "\n" || character === "\r")) return index;
|
|
406
|
+
index++;
|
|
407
|
+
}
|
|
408
|
+
return source.length;
|
|
409
|
+
}
|
|
410
|
+
function scanGeneric(source, def) {
|
|
411
|
+
const tokens = [];
|
|
412
|
+
const keywords = set(def.keywords), literals = set(def.literals), types = set(def.types);
|
|
413
|
+
const fold = (word) => def.ci ? word.toLowerCase() : word;
|
|
414
|
+
if (def.ci) for (const list of [keywords, literals, types]) for (const word of [...list]) {
|
|
415
|
+
list.delete(word);
|
|
416
|
+
list.add(word.toLowerCase());
|
|
275
417
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
418
|
+
const strings = def.strings ?? "", lineComments = def.line ?? [], blocks = def.block ?? [], triples = def.triple ?? [];
|
|
419
|
+
let index = 0, pendingDef;
|
|
420
|
+
const atLineStart = (position) => {
|
|
421
|
+
let at = position - 1;
|
|
422
|
+
while (at >= 0 && (source[at] === " " || source[at] === " ")) at--;
|
|
423
|
+
return at < 0 || source[at] === "\n" || source[at] === "\r";
|
|
424
|
+
};
|
|
425
|
+
while (index < source.length) {
|
|
426
|
+
const character = source[index];
|
|
427
|
+
if (/\s/.test(character)) {
|
|
428
|
+
index++;
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
const lineComment = lineComments.find((opener) => source.startsWith(opener, index));
|
|
432
|
+
if (lineComment && !(lineComment === "#" && def.directives) && !(lineComment === "#" && def.variables && source[index - 1] === "$") && !(def.variables && lineComment === "#" && index > 0 && !/[\s;&|(]/.test(source[index - 1]))) {
|
|
433
|
+
const end = endOfLine(source, index);
|
|
434
|
+
pushToken(tokens, index, end, "comment");
|
|
435
|
+
index = end;
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
const block = blocks.find(([opener]) => source.startsWith(opener, index));
|
|
439
|
+
if (block) {
|
|
440
|
+
const close = source.indexOf(block[1], index + block[0].length);
|
|
441
|
+
const end = close < 0 ? source.length : close + block[1].length;
|
|
442
|
+
pushToken(tokens, index, end, "comment");
|
|
443
|
+
index = end;
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
if (def.directives && character === "#" && atLineStart(index)) {
|
|
447
|
+
const match = /#[ \t]*\w+/y;
|
|
448
|
+
match.lastIndex = index;
|
|
449
|
+
const found = match.exec(source);
|
|
450
|
+
if (found) {
|
|
451
|
+
pushToken(tokens, index, index + found[0].length, "keyword");
|
|
452
|
+
index += found[0].length;
|
|
453
|
+
if (/include/.test(found[0])) {
|
|
454
|
+
const header = /[ \t]*(<[^>\n]*>)/y;
|
|
455
|
+
header.lastIndex = index;
|
|
456
|
+
const matched = header.exec(source);
|
|
457
|
+
if (matched) {
|
|
458
|
+
const start = index + matched[0].length - matched[1].length;
|
|
459
|
+
pushToken(tokens, start, start + matched[1].length, "string");
|
|
460
|
+
index += matched[0].length;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
const triple = triples.find((opener) => source.startsWith(opener, index));
|
|
467
|
+
if (triple) {
|
|
468
|
+
const close = source.indexOf(triple, index + 3);
|
|
469
|
+
const end = close < 0 ? source.length : close + 3;
|
|
470
|
+
pushToken(tokens, index, end, "string");
|
|
471
|
+
index = end;
|
|
472
|
+
pendingDef = void 0;
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
if (def.rawStrings && character === def.rawStrings && /^r#*"/.test(source.slice(index, index + 8)) && !isIdentChar(source[index - 1])) {
|
|
476
|
+
const hashes = /^r(#*)"/.exec(source.slice(index, index + 8))[1];
|
|
477
|
+
const close = source.indexOf(`"${hashes}`, index + 2 + hashes.length);
|
|
478
|
+
const end = close < 0 ? source.length : close + 1 + hashes.length;
|
|
479
|
+
pushToken(tokens, index, end, "string");
|
|
480
|
+
index = end;
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
if (strings.includes(character)) {
|
|
484
|
+
if (def === LANGUAGES.rust && character === "'" && !/^'(?:\\.[^']*|[^\\'])'/.test(source.slice(index, index + 12))) {
|
|
485
|
+
const match = /'[\p{L}_][\p{L}\p{N}_]*/uy;
|
|
486
|
+
match.lastIndex = index;
|
|
487
|
+
const found = match.exec(source);
|
|
488
|
+
const end2 = index + (found ? found[0].length : 1);
|
|
489
|
+
if (found) pushToken(tokens, index, end2, "type");
|
|
490
|
+
index = end2;
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
const escapes = !(def.noEscapes ?? "").includes(character);
|
|
494
|
+
const multiline = character === "`";
|
|
495
|
+
const end = scanQuoted(source, index, character, escapes, multiline);
|
|
496
|
+
let kind = "string";
|
|
497
|
+
if (def.quotedKeys) {
|
|
498
|
+
const after = /^[ \t]*:/.exec(source.slice(end, end + 40));
|
|
499
|
+
if (after) kind = "property";
|
|
500
|
+
}
|
|
501
|
+
pushToken(tokens, index, end, kind);
|
|
502
|
+
index = end;
|
|
503
|
+
pendingDef = void 0;
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
if (def.variables && character === "$") {
|
|
507
|
+
const match = /\$(?:\{[^}\n]*\}|[A-Za-z_]\w*|[0-9@#?!$*-])/y;
|
|
508
|
+
match.lastIndex = index;
|
|
509
|
+
const found = match.exec(source);
|
|
510
|
+
if (found) {
|
|
511
|
+
pushToken(tokens, index, index + found[0].length, "property");
|
|
512
|
+
index += found[0].length;
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (def.decorators && character === "@" && /[\p{L}_]/u.test(source[index + 1] ?? "")) {
|
|
517
|
+
const match = /@[\p{L}_][\p{L}\p{N}_$.]*/uy;
|
|
518
|
+
match.lastIndex = index;
|
|
519
|
+
const found = match.exec(source);
|
|
520
|
+
pushToken(tokens, index, index + found[0].length, "function");
|
|
521
|
+
index += found[0].length;
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
if (/\d/.test(character) && !isIdentChar(source[index - 1])) {
|
|
525
|
+
NUMBER.lastIndex = index;
|
|
526
|
+
const found = NUMBER.exec(source);
|
|
527
|
+
if (found) {
|
|
528
|
+
pushToken(tokens, index, index + found[0].length, "number");
|
|
529
|
+
index += found[0].length;
|
|
530
|
+
pendingDef = void 0;
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
if (def === LANGUAGES.python && /[rRbBfFuU]/.test(character) && /^[rRbBfFuU]{1,2}['"]/.test(source.slice(index, index + 3)) && !isIdentChar(source[index - 1])) {
|
|
535
|
+
const prefix = /^[rRbBfFuU]{1,2}/.exec(source.slice(index, index + 3))[0].length;
|
|
536
|
+
const quote = source[index + prefix];
|
|
537
|
+
const triple2 = source.startsWith(quote.repeat(3), index + prefix);
|
|
538
|
+
let end;
|
|
539
|
+
if (triple2) {
|
|
540
|
+
const close = source.indexOf(quote.repeat(3), index + prefix + 3);
|
|
541
|
+
end = close < 0 ? source.length : close + 3;
|
|
542
|
+
} else end = scanQuoted(source, index + prefix, quote, !/[rR]/.test(source.slice(index, index + prefix)), false);
|
|
543
|
+
pushToken(tokens, index, end, "string");
|
|
544
|
+
index = end;
|
|
545
|
+
pendingDef = void 0;
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
IDENT.lastIndex = index;
|
|
549
|
+
const identifier = IDENT.exec(source);
|
|
550
|
+
if (identifier) {
|
|
551
|
+
const word = identifier[0], end = index + word.length, folded = fold(word);
|
|
552
|
+
let kind;
|
|
553
|
+
if (pendingDef && !keywords.has(folded)) kind = pendingDef;
|
|
554
|
+
else if (keywords.has(folded)) {
|
|
555
|
+
kind = "keyword";
|
|
556
|
+
pendingDef = def.defs && Object.hasOwn(def.defs, folded) ? def.defs[folded] : void 0;
|
|
557
|
+
pushToken(tokens, index, end, kind);
|
|
558
|
+
index = end;
|
|
559
|
+
continue;
|
|
560
|
+
} else if (literals.has(word) || literals.has(folded)) kind = "number";
|
|
561
|
+
else if (types.has(folded)) kind = "type";
|
|
562
|
+
else if (def.calls && source[end] === "(") kind = "function";
|
|
563
|
+
else if (def.macros && source[end] === "!" && /[([{]/.test(source[end + 1] ?? "")) kind = "function";
|
|
564
|
+
else if (def.capsTypes && /^[A-Z]/.test(word) && /[a-z]/.test(word)) kind = "type";
|
|
565
|
+
pendingDef = void 0;
|
|
566
|
+
if (kind) pushToken(tokens, index, end, kind);
|
|
567
|
+
index = end;
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
pendingDef = void 0;
|
|
571
|
+
index++;
|
|
303
572
|
}
|
|
304
|
-
return
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
if (
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
573
|
+
return tokens;
|
|
574
|
+
}
|
|
575
|
+
var YAML_LITERALS = /* @__PURE__ */ new Set(["true", "false", "null", "yes", "no", "on", "off", "~", "True", "False", "Null", "TRUE", "FALSE", "NULL"]);
|
|
576
|
+
function scanYamlValue(source, start, end, tokens, comments) {
|
|
577
|
+
let index = start;
|
|
578
|
+
while (index < end) {
|
|
579
|
+
const character = source[index];
|
|
580
|
+
if (character === "#" && (index === start || /\s/.test(source[index - 1])) && comments.includes("#")) {
|
|
581
|
+
pushToken(tokens, index, end, "comment");
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
if (character === ";" && comments.includes(";") && (index === start || /\s/.test(source[index - 1]))) {
|
|
585
|
+
pushToken(tokens, index, end, "comment");
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
if (character === '"' || character === "'") {
|
|
589
|
+
const close = scanQuoted(source, index, character, character === '"', false);
|
|
590
|
+
pushToken(tokens, index, Math.min(close, end), "string");
|
|
591
|
+
index = Math.min(close, end);
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
if ((character === "&" || character === "*") && /[\w-]/.test(source[index + 1] ?? "")) {
|
|
595
|
+
const match = /[&*][\w-]+/y;
|
|
596
|
+
match.lastIndex = index;
|
|
597
|
+
const found2 = match.exec(source);
|
|
598
|
+
pushToken(tokens, index, index + found2[0].length, "type");
|
|
599
|
+
index += found2[0].length;
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
if (!isIdentChar(source[index - 1]) && /[\d-]/.test(character)) {
|
|
603
|
+
const match = /-?\d[\d_]*(?:\.\d+)?(?:[eE][+-]?\d+)?(?=[\s,\]}]|$)/y;
|
|
604
|
+
match.lastIndex = index;
|
|
605
|
+
const found2 = match.exec(source);
|
|
606
|
+
if (found2 && index + found2[0].length <= end) {
|
|
607
|
+
pushToken(tokens, index, index + found2[0].length, "number");
|
|
608
|
+
index += found2[0].length;
|
|
609
|
+
continue;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
const word = /[\w.~-]+/y;
|
|
613
|
+
word.lastIndex = index;
|
|
614
|
+
const found = word.exec(source);
|
|
615
|
+
if (found) {
|
|
616
|
+
if (YAML_LITERALS.has(found[0]) && !/[\w.-]/.test(source[index + found[0].length] ?? "")) pushToken(tokens, index, index + found[0].length, "number");
|
|
617
|
+
index += found[0].length;
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
index++;
|
|
334
621
|
}
|
|
335
622
|
}
|
|
336
|
-
function
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
344
|
-
function resolveReference(lookup, kind, reference) {
|
|
345
|
-
if (typeof reference === "string") return lookup(kind, reference);
|
|
346
|
-
if (!isRecord(reference)) return void 0;
|
|
347
|
-
const base = typeof reference.id === "string" ? lookup(kind, reference.id) : void 0;
|
|
348
|
-
return { ...base, ...reference };
|
|
349
|
-
}
|
|
350
|
-
function matchLanguageTag(document, tag) {
|
|
351
|
-
const wanted = splitTag(tag);
|
|
352
|
-
if (!wanted) return void 0;
|
|
353
|
-
const records = allRecords(document, "languages").filter((record) => typeof record.bcp47 === "string");
|
|
354
|
-
const key = canonicalTag(tag).toLowerCase();
|
|
355
|
-
const exact = records.find((record) => canonicalTag(record.bcp47).toLowerCase() === key);
|
|
356
|
-
if (exact) return exact;
|
|
357
|
-
const language2 = matchingLanguages[wanted.language] ?? wanted.language;
|
|
358
|
-
const script = wanted.script ?? vendoredScript(language2, wanted.region);
|
|
359
|
-
const candidates = records.flatMap((record) => {
|
|
360
|
-
const parts = splitTag(record.bcp47);
|
|
361
|
-
if (!parts || (matchingLanguages[parts.language] ?? parts.language) !== language2) return [];
|
|
362
|
-
const recordScript = normalizeScript(record.script) ?? parts.script ?? vendoredScript(language2, parts.region);
|
|
363
|
-
if (script && recordScript && script !== recordScript) return [];
|
|
364
|
-
return [{ record, region: parts.region }];
|
|
365
|
-
});
|
|
366
|
-
return candidates.find((candidate) => wanted.region && candidate.region === wanted.region)?.record ?? candidates.find((candidate) => !candidate.region)?.record ?? candidates[0]?.record;
|
|
367
|
-
}
|
|
368
|
-
function resolveLanguage(document, lookup, reference) {
|
|
369
|
-
if (typeof reference === "string") {
|
|
370
|
-
const value = reference.trim();
|
|
371
|
-
const byId = bareLanguageId.test(value) ? lookup("languages", value) : void 0;
|
|
372
|
-
if (byId) return { record: byId, languageId: value };
|
|
373
|
-
if (/^[a-z][a-z0-9+.-]*:/i.test(value) || !splitTag(value)) return void 0;
|
|
374
|
-
const matched = matchLanguageTag(document, value);
|
|
375
|
-
if (matched) return { record: matched, authoredTag: value, languageId: text(matched.id) };
|
|
376
|
-
return inferScript(value) ? { record: {}, authoredTag: value } : void 0;
|
|
623
|
+
function lineRanges(source) {
|
|
624
|
+
const ranges = [];
|
|
625
|
+
let cursor = 0;
|
|
626
|
+
const pattern = /\r\n|\r|\n/g;
|
|
627
|
+
for (let match = pattern.exec(source); match; match = pattern.exec(source)) {
|
|
628
|
+
ranges.push({ start: cursor, end: match.index });
|
|
629
|
+
cursor = match.index + match[0].length;
|
|
377
630
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
if (authoredTag !== void 0 && !splitTag(authoredTag)) return void 0;
|
|
381
|
-
const base = typeof reference.id === "string" ? lookup("languages", reference.id) : authoredTag ? matchLanguageTag(document, authoredTag) : void 0;
|
|
382
|
-
const record = { ...base, ...reference };
|
|
383
|
-
const tag = text(record.bcp47);
|
|
384
|
-
if (!tag || !splitTag(tag)) return void 0;
|
|
385
|
-
return { record, authoredTag, authoredOoxmlLang: text(reference.ooxmlLang), languageId: text(base?.id) };
|
|
386
|
-
}
|
|
387
|
-
function pairFamilies(value) {
|
|
388
|
-
if (!isRecord(value)) return void 0;
|
|
389
|
-
const major = text(value.major);
|
|
390
|
-
const minor = text(value.minor);
|
|
391
|
-
const heading = major ?? minor;
|
|
392
|
-
const body = minor ?? major;
|
|
393
|
-
return heading && body ? { heading, body } : void 0;
|
|
394
|
-
}
|
|
395
|
-
function schemeServesLanguage(scheme, language2) {
|
|
396
|
-
const entries = Array.isArray(scheme.languages) ? scheme.languages.filter((entry) => typeof entry === "string") : [];
|
|
397
|
-
if (entries.length === 0) return true;
|
|
398
|
-
const name = text(language2.name)?.toLowerCase();
|
|
399
|
-
if (!name) return false;
|
|
400
|
-
const base = name.replace(/\s*\([^)]*\)\s*$/, "");
|
|
401
|
-
return entries.some((entry) => {
|
|
402
|
-
const value = entry.trim().toLowerCase();
|
|
403
|
-
return value === name || value === base;
|
|
404
|
-
});
|
|
631
|
+
ranges.push({ start: cursor, end: source.length });
|
|
632
|
+
return ranges;
|
|
405
633
|
}
|
|
406
|
-
function
|
|
407
|
-
const
|
|
408
|
-
|
|
409
|
-
let
|
|
410
|
-
if (
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
const slide = slides[options.slideIndex];
|
|
416
|
-
if (isRecord(slide) && isRecord(slide.design)) design = { ...design, ...slide.design };
|
|
634
|
+
function yamlKey(source, from, to) {
|
|
635
|
+
const first = source[from];
|
|
636
|
+
if (first === void 0 || from >= to) return void 0;
|
|
637
|
+
let index = from;
|
|
638
|
+
if (first === '"' || first === "'") {
|
|
639
|
+
index = Math.min(scanQuoted(source, from, first, first === '"', false), to);
|
|
640
|
+
let at = index;
|
|
641
|
+
while (at < to && (source[at] === " " || source[at] === " ")) at++;
|
|
642
|
+
return source[index - 1] === first && source[at] === ":" && (at + 1 >= to || /\s/.test(source[at + 1])) ? { nameEnd: index, colon: at } : void 0;
|
|
417
643
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
if (
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
const
|
|
456
|
-
if (
|
|
644
|
+
if (/[\s#:{}[\],&*!|>%@`]/.test(first) || first === "-" && /[\s#:]/.test(source[from + 1] ?? " ")) return void 0;
|
|
645
|
+
for (; index < to; index++) {
|
|
646
|
+
const character = source[index];
|
|
647
|
+
if (character === "#" && /\s/.test(source[index - 1])) return void 0;
|
|
648
|
+
if (character === ":" && (index + 1 >= to || /\s/.test(source[index + 1]))) {
|
|
649
|
+
let nameEnd = index;
|
|
650
|
+
while (nameEnd > from && /\s/.test(source[nameEnd - 1])) nameEnd--;
|
|
651
|
+
return nameEnd > from ? { nameEnd, colon: index } : void 0;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
return void 0;
|
|
655
|
+
}
|
|
656
|
+
function scanYaml(source) {
|
|
657
|
+
const tokens = [];
|
|
658
|
+
let blockIndent = -1;
|
|
659
|
+
for (const { start, end } of lineRanges(source)) {
|
|
660
|
+
const text = source.slice(start, end), indent = /^ */.exec(text)[0].length;
|
|
661
|
+
if (blockIndent >= 0) {
|
|
662
|
+
if (text.trim() === "" || indent > blockIndent) {
|
|
663
|
+
if (text.trim() !== "") pushToken(tokens, start + indent, end, "string");
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
blockIndent = -1;
|
|
667
|
+
}
|
|
668
|
+
if (/^\s*#/.test(text)) {
|
|
669
|
+
pushToken(tokens, start + indent, end, "comment");
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
672
|
+
if (/^(?:---|\.\.\.)(?:\s|$)/.test(text)) {
|
|
673
|
+
pushToken(tokens, start, start + 3, "keyword");
|
|
674
|
+
scanYamlValue(source, start + 3, end, tokens, "#");
|
|
675
|
+
continue;
|
|
676
|
+
}
|
|
677
|
+
let cursor = start + indent;
|
|
678
|
+
const dash = /^(?:-\s+)+/.exec(text.slice(indent));
|
|
679
|
+
if (dash) cursor += dash[0].length;
|
|
680
|
+
let valueStart = cursor;
|
|
681
|
+
const key = yamlKey(source, cursor, end);
|
|
682
|
+
if (key) {
|
|
683
|
+
pushToken(tokens, cursor, key.nameEnd, "property");
|
|
684
|
+
valueStart = key.colon + 1;
|
|
685
|
+
}
|
|
686
|
+
scanYamlValue(source, valueStart, end, tokens, "#");
|
|
687
|
+
if (/(?:^|\s)[|>][+-]?\d?\s*(?:#.*)?$/.test(text.slice(valueStart - start))) blockIndent = indent;
|
|
457
688
|
}
|
|
458
|
-
return
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
689
|
+
return tokens;
|
|
690
|
+
}
|
|
691
|
+
function scanIni(source, def) {
|
|
692
|
+
const tokens = [], comments = (def.line ?? []).join("");
|
|
693
|
+
for (const { start, end } of lineRanges(source)) {
|
|
694
|
+
const text = source.slice(start, end), indent = /^\s*/.exec(text)[0].length, first = text[indent];
|
|
695
|
+
if (first === void 0) continue;
|
|
696
|
+
if (comments.includes(first)) {
|
|
697
|
+
pushToken(tokens, start + indent, end, "comment");
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
if (first === "[") {
|
|
701
|
+
const close = text.indexOf("]", indent);
|
|
702
|
+
const stop = close < 0 ? end : start + close + 1;
|
|
703
|
+
pushToken(tokens, start + indent, stop, "type");
|
|
704
|
+
scanYamlValue(source, stop, end, tokens, comments);
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
const key = /^("[^"\n]*"|'[^'\n]*'|[^\s=:#;"']+(?:\s+[^\s=:#;"']+)*)\s*[=:]/.exec(text.slice(indent));
|
|
708
|
+
let valueStart = start + indent;
|
|
709
|
+
if (key) {
|
|
710
|
+
pushToken(tokens, start + indent, start + indent + key[1].length, "property");
|
|
711
|
+
valueStart = start + indent + key[0].length;
|
|
712
|
+
}
|
|
713
|
+
scanYamlValue(source, valueStart, end, tokens, comments);
|
|
714
|
+
}
|
|
715
|
+
return tokens;
|
|
716
|
+
}
|
|
717
|
+
function scanMarkup(source) {
|
|
718
|
+
const tokens = [];
|
|
719
|
+
let index = 0;
|
|
720
|
+
while (index < source.length) {
|
|
721
|
+
const open = source.indexOf("<", index);
|
|
722
|
+
if (open < 0) break;
|
|
723
|
+
if (source.startsWith("<!--", open)) {
|
|
724
|
+
const close = source.indexOf("-->", open + 4);
|
|
725
|
+
const end = close < 0 ? source.length : close + 3;
|
|
726
|
+
pushToken(tokens, open, end, "comment");
|
|
727
|
+
index = end;
|
|
728
|
+
continue;
|
|
729
|
+
}
|
|
730
|
+
if (source.startsWith("<![CDATA[", open)) {
|
|
731
|
+
const close = source.indexOf("]]>", open);
|
|
732
|
+
const end = close < 0 ? source.length : close + 3;
|
|
733
|
+
pushToken(tokens, open, end, "string");
|
|
734
|
+
index = end;
|
|
735
|
+
continue;
|
|
736
|
+
}
|
|
737
|
+
const name = /<([/?!]?)([A-Za-z][\w:.-]*|DOCTYPE)?/y;
|
|
738
|
+
name.lastIndex = open;
|
|
739
|
+
const found = name.exec(source);
|
|
740
|
+
if (!found || !found[2]) {
|
|
741
|
+
index = open + 1;
|
|
742
|
+
continue;
|
|
743
|
+
}
|
|
744
|
+
pushToken(tokens, open + 1, open + found[0].length, "keyword");
|
|
745
|
+
index = open + found[0].length;
|
|
746
|
+
while (index < source.length && source[index] !== ">") {
|
|
747
|
+
const character = source[index];
|
|
748
|
+
if (character === '"' || character === "'") {
|
|
749
|
+
const close = source.indexOf(character, index + 1);
|
|
750
|
+
const end = close < 0 ? source.length : close + 1;
|
|
751
|
+
pushToken(tokens, index, end, "string");
|
|
752
|
+
index = end;
|
|
753
|
+
continue;
|
|
754
|
+
}
|
|
755
|
+
const attribute = /[A-Za-z_:@#][\w:.@#-]*/y;
|
|
756
|
+
attribute.lastIndex = index;
|
|
757
|
+
const matched = attribute.exec(source);
|
|
758
|
+
if (matched) {
|
|
759
|
+
pushToken(tokens, index, index + matched[0].length, "property");
|
|
760
|
+
index += matched[0].length;
|
|
761
|
+
continue;
|
|
762
|
+
}
|
|
763
|
+
index++;
|
|
764
|
+
}
|
|
765
|
+
if (source[index] === ">") index++;
|
|
766
|
+
}
|
|
767
|
+
return tokens;
|
|
768
|
+
}
|
|
769
|
+
function scanCss(source) {
|
|
770
|
+
const tokens = [];
|
|
771
|
+
let index = 0, depth = 0;
|
|
772
|
+
while (index < source.length) {
|
|
773
|
+
const character = source[index];
|
|
774
|
+
if (/\s/.test(character)) {
|
|
775
|
+
index++;
|
|
776
|
+
continue;
|
|
777
|
+
}
|
|
778
|
+
if (source.startsWith("/*", index)) {
|
|
779
|
+
const close = source.indexOf("*/", index + 2);
|
|
780
|
+
const end = close < 0 ? source.length : close + 2;
|
|
781
|
+
pushToken(tokens, index, end, "comment");
|
|
782
|
+
index = end;
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
if (character === '"' || character === "'") {
|
|
786
|
+
const end = scanQuoted(source, index, character, true, false);
|
|
787
|
+
pushToken(tokens, index, end, "string");
|
|
788
|
+
index = end;
|
|
789
|
+
continue;
|
|
790
|
+
}
|
|
791
|
+
if (character === "{") {
|
|
792
|
+
depth++;
|
|
793
|
+
index++;
|
|
794
|
+
continue;
|
|
795
|
+
}
|
|
796
|
+
if (character === "}") {
|
|
797
|
+
depth = Math.max(0, depth - 1);
|
|
798
|
+
index++;
|
|
799
|
+
continue;
|
|
800
|
+
}
|
|
801
|
+
if (character === "@") {
|
|
802
|
+
const match = /@[\w-]+/y;
|
|
803
|
+
match.lastIndex = index;
|
|
804
|
+
const found2 = match.exec(source);
|
|
805
|
+
if (found2) {
|
|
806
|
+
pushToken(tokens, index, index + found2[0].length, "keyword");
|
|
807
|
+
index += found2[0].length;
|
|
808
|
+
continue;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
if (character === "!") {
|
|
812
|
+
const match = /!\s*important/y;
|
|
813
|
+
match.lastIndex = index;
|
|
814
|
+
const found2 = match.exec(source);
|
|
815
|
+
if (found2) {
|
|
816
|
+
pushToken(tokens, index, index + found2[0].length, "keyword");
|
|
817
|
+
index += found2[0].length;
|
|
818
|
+
continue;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
if (character === "#" && depth > 0) {
|
|
822
|
+
const match = /#[\da-fA-F]{3,8}\b/y;
|
|
823
|
+
match.lastIndex = index;
|
|
824
|
+
const found2 = match.exec(source);
|
|
825
|
+
if (found2) {
|
|
826
|
+
pushToken(tokens, index, index + found2[0].length, "number");
|
|
827
|
+
index += found2[0].length;
|
|
828
|
+
continue;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
if (depth > 0 && (/\d/.test(character) || (character === "-" || character === "." || character === "+") && /\d/.test(source[index + 1] ?? ""))) {
|
|
832
|
+
const match = /[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?(?:%|[a-zA-Z]+)?/y;
|
|
833
|
+
match.lastIndex = index;
|
|
834
|
+
const found2 = match.exec(source);
|
|
835
|
+
if (found2 && !isIdentChar(source[index - 1])) {
|
|
836
|
+
pushToken(tokens, index, index + found2[0].length, "number");
|
|
837
|
+
index += found2[0].length;
|
|
838
|
+
continue;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
const word = /-?[\p{L}_][\p{L}\p{N}_-]*/uy;
|
|
842
|
+
word.lastIndex = index;
|
|
843
|
+
const found = word.exec(source);
|
|
844
|
+
if (found) {
|
|
845
|
+
const end = index + found[0].length;
|
|
846
|
+
let back = index - 1;
|
|
847
|
+
while (back >= 0 && /\s/.test(source[back])) back--;
|
|
848
|
+
const before = back >= 0 ? source[back] : "";
|
|
849
|
+
if (depth > 0 && /^\s*:(?!:)/.test(source.slice(end, end + 8)) && (before === "{" || before === ";" || before === "")) pushToken(tokens, index, end, "property");
|
|
850
|
+
else if (source[end] === "(") pushToken(tokens, index, end, "function");
|
|
851
|
+
index = end;
|
|
852
|
+
continue;
|
|
853
|
+
}
|
|
854
|
+
if (depth === 0 && (character === "." || character === "#")) {
|
|
855
|
+
const match = /[.#][\p{L}_-][\p{L}\p{N}_-]*/uy;
|
|
856
|
+
match.lastIndex = index;
|
|
857
|
+
const matched = match.exec(source);
|
|
858
|
+
if (matched) {
|
|
859
|
+
pushToken(tokens, index, index + matched[0].length, "type");
|
|
860
|
+
index += matched[0].length;
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
index++;
|
|
865
|
+
}
|
|
866
|
+
return tokens;
|
|
867
|
+
}
|
|
868
|
+
function tokenizeCode(source, language2) {
|
|
869
|
+
const id = resolveCodeLanguage(language2);
|
|
870
|
+
if (id === void 0 || typeof source !== "string" || source.length === 0 || source.length > CODE_HIGHLIGHT_MAX_LENGTH) return [];
|
|
871
|
+
const def = LANGUAGES[id];
|
|
872
|
+
let tokens;
|
|
873
|
+
switch (def.kind) {
|
|
874
|
+
case "yaml":
|
|
875
|
+
tokens = scanYaml(source);
|
|
876
|
+
break;
|
|
877
|
+
case "ini":
|
|
878
|
+
tokens = scanIni(source, def);
|
|
879
|
+
break;
|
|
880
|
+
case "markup":
|
|
881
|
+
tokens = scanMarkup(source);
|
|
882
|
+
break;
|
|
883
|
+
case "css":
|
|
884
|
+
tokens = scanCss(source);
|
|
885
|
+
break;
|
|
886
|
+
default:
|
|
887
|
+
tokens = scanGeneric(source, def);
|
|
888
|
+
}
|
|
889
|
+
return tokens.filter((token) => token.end > token.start).sort((a, b) => a.start - b.start);
|
|
890
|
+
}
|
|
891
|
+
function codeLineRuns(tokens, start, end, source) {
|
|
892
|
+
const runs = [];
|
|
893
|
+
const push = (from, to, kind) => {
|
|
894
|
+
if (kind === void 0 || source === void 0 || !source.slice(from, to).includes(" ")) {
|
|
895
|
+
runs.push(kind === void 0 ? { start: from, end: to } : { start: from, end: to, kind });
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
let at = from;
|
|
899
|
+
for (let index = from; index < to; index++) {
|
|
900
|
+
if (source[index] !== " ") continue;
|
|
901
|
+
if (index > at) runs.push({ start: at, end: index, kind });
|
|
902
|
+
runs.push({ start: index, end: index + 1 });
|
|
903
|
+
at = index + 1;
|
|
904
|
+
}
|
|
905
|
+
if (at < to) runs.push({ start: at, end: to, kind });
|
|
472
906
|
};
|
|
907
|
+
let cursor = start;
|
|
908
|
+
for (const token of tokens) {
|
|
909
|
+
if (token.end <= start) continue;
|
|
910
|
+
if (token.start >= end) break;
|
|
911
|
+
const from = Math.max(token.start, start), to = Math.min(token.end, end);
|
|
912
|
+
if (from > cursor) push(cursor, from);
|
|
913
|
+
push(from, to, token.kind);
|
|
914
|
+
cursor = to;
|
|
915
|
+
}
|
|
916
|
+
if (cursor < end) push(cursor, end);
|
|
917
|
+
return runs;
|
|
918
|
+
}
|
|
919
|
+
var distance = (a, b) => Math.hypot(...channels(a).map((value, index) => value - channels(b)[index]));
|
|
920
|
+
var FALLBACK = { keyword: "#C4B5FD", string: "#86EFAC", number: "#FCD34D", function: "#93C5FD", type: "#67E8F9", property: "#F9A8D4", comment: "#94A3B8" };
|
|
921
|
+
function codeSyntaxPalette(theme2 = {}, options = {}) {
|
|
922
|
+
const background = normalize(options.background) ?? CODE_PANEL_BACKGROUND, plain = normalize(options.foreground) ?? CODE_PANEL_FOREGROUND;
|
|
923
|
+
const minimum = options.minimumContrast ?? CODE_SYNTAX_MIN_CONTRAST;
|
|
924
|
+
const palette = { plain: legible(plain, background, minimum) };
|
|
925
|
+
const taken = [palette.plain];
|
|
926
|
+
const slots = [["keyword", theme2.primary], ["string", theme2.accent], ["number", theme2.secondary], ["comment", theme2.mutedText], ["function", void 0], ["type", void 0], ["property", void 0]];
|
|
927
|
+
for (const [kind, themed] of slots) {
|
|
928
|
+
const candidates = [normalize(themed), FALLBACK[kind]].filter((value) => value !== void 0).map((value) => legible(value, background, minimum));
|
|
929
|
+
let [h, s, l] = toHsl(FALLBACK[kind]);
|
|
930
|
+
let pick = candidates.find((candidate) => taken.every((other) => distance(candidate, other) >= 48));
|
|
931
|
+
for (let turn = 0; pick === void 0 && turn < 9; turn++) {
|
|
932
|
+
h += 40;
|
|
933
|
+
const candidate = legible(fromHsl(h, s, l), background, minimum);
|
|
934
|
+
if (taken.every((other) => distance(candidate, other) >= 48)) pick = candidate;
|
|
935
|
+
}
|
|
936
|
+
palette[kind] = pick ?? candidates[candidates.length - 1];
|
|
937
|
+
taken.push(palette[kind]);
|
|
938
|
+
}
|
|
939
|
+
return palette;
|
|
940
|
+
}
|
|
941
|
+
function codeSyntaxPaletteForScheme(scheme, options = {}) {
|
|
942
|
+
const record = scheme && typeof scheme === "object" ? scheme : {};
|
|
943
|
+
const pick = (role, slot, fallback) => normalize(record[role]) ?? normalize(record[slot]) ?? fallback;
|
|
944
|
+
return codeSyntaxPalette({ primary: pick("primary", "accent1", "#2563EB"), secondary: pick("secondary", "accent2", "#0F766E"), accent: pick("accent", "accent3", "#F59E0B") }, options);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// src/metric-trend.ts
|
|
948
|
+
var METRIC_TREND_SHAPES = Object.freeze({ up: "upArrow", down: "downArrow", flat: "rightArrow" });
|
|
949
|
+
var METRIC_TREND_MIN_CONTRAST = 4.5;
|
|
950
|
+
var SEMANTIC = {
|
|
951
|
+
up: { light: "#15803D", dark: "#4ADE80" },
|
|
952
|
+
down: { light: "#B91C1C", dark: "#F87171" }
|
|
953
|
+
};
|
|
954
|
+
function metricTrendColor(trend, options) {
|
|
955
|
+
const background = normalize(options.background) ?? "#FFFFFF";
|
|
956
|
+
if (trend === "flat") return legible(normalize(options.neutral) ?? (luminance(background) < 0.5 ? "#CBD5E1" : "#475569"), background, METRIC_TREND_MIN_CONTRAST);
|
|
957
|
+
const pair = SEMANTIC[trend];
|
|
958
|
+
return legible(luminance(background) < 0.5 ? pair.dark : pair.light, background, METRIC_TREND_MIN_CONTRAST);
|
|
959
|
+
}
|
|
960
|
+
function metricTrendPoints(shape, box) {
|
|
961
|
+
const { x: l, y: t, width: w, height: h } = box, r = l + w, b = t + h, hc = l + w / 2, vc = t + h / 2, ss = Math.min(w, h);
|
|
962
|
+
if (shape === "rightArrow") {
|
|
963
|
+
const x12 = r - ss * 0.5, y1 = vc - h * 0.25, y22 = vc + h * 0.25;
|
|
964
|
+
return [[l, y1], [x12, y1], [x12, t], [r, vc], [x12, b], [x12, y22], [l, y22]];
|
|
965
|
+
}
|
|
966
|
+
const dy = ss * 0.5, x1 = hc - w * 0.25, x2 = hc + w * 0.25;
|
|
967
|
+
if (shape === "upArrow") {
|
|
968
|
+
const y22 = t + dy;
|
|
969
|
+
return [[l, y22], [hc, t], [r, y22], [x2, y22], [x2, b], [x1, b], [x1, y22]];
|
|
970
|
+
}
|
|
971
|
+
const y2 = b - dy;
|
|
972
|
+
return [[l, y2], [x1, y2], [x1, t], [x2, t], [x2, y2], [r, y2], [hc, b]];
|
|
973
|
+
}
|
|
974
|
+
function metricTrendMark(layout2, options) {
|
|
975
|
+
const part = layout2.parts.find((candidate) => candidate.role === "trend");
|
|
976
|
+
if (!part || !part.visible || !part.fit || part.fit.sourceLines.length === 0) return void 0;
|
|
977
|
+
const trend = part.text.trim();
|
|
978
|
+
if (!Object.hasOwn(METRIC_TREND_SHAPES, trend)) return void 0;
|
|
979
|
+
const line = part.fit.sourceLines[0], origin = part.linePositions[0];
|
|
980
|
+
if (!origin || line.width <= 0) return void 0;
|
|
981
|
+
const size = part.fit.fontSize * 0.72, gap = part.fit.fontSize * 0.3, left = part.box.x, right = part.box.x + part.box.width;
|
|
982
|
+
const after = origin.x + line.width + gap, before = origin.x - gap - size;
|
|
983
|
+
const fitsAfter = after + size <= right + 0.01, fitsBefore = before >= left - 0.01;
|
|
984
|
+
const x = layout2.alignment === "left" ? fitsAfter ? after : fitsBefore ? before : void 0 : fitsBefore ? before : fitsAfter ? after : void 0;
|
|
985
|
+
if (x === void 0) return void 0;
|
|
986
|
+
const shape = METRIC_TREND_SHAPES[trend], box = { x, y: origin.baseline - size, width: size, height: size };
|
|
987
|
+
return { trend, shape, box, points: metricTrendPoints(shape, box), color: metricTrendColor(trend, options), ariaLabel: `Trend: ${trend}`, path: part.path };
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
// src/pattern-fills.ts
|
|
991
|
+
var PATTERN_PRESETS = Object.freeze([
|
|
992
|
+
"pct5",
|
|
993
|
+
"pct10",
|
|
994
|
+
"pct20",
|
|
995
|
+
"pct25",
|
|
996
|
+
"pct30",
|
|
997
|
+
"pct40",
|
|
998
|
+
"pct50",
|
|
999
|
+
"pct60",
|
|
1000
|
+
"pct70",
|
|
1001
|
+
"pct75",
|
|
1002
|
+
"pct80",
|
|
1003
|
+
"pct90",
|
|
1004
|
+
"horz",
|
|
1005
|
+
"vert",
|
|
1006
|
+
"ltHorz",
|
|
1007
|
+
"ltVert",
|
|
1008
|
+
"dkHorz",
|
|
1009
|
+
"dkVert",
|
|
1010
|
+
"narHorz",
|
|
1011
|
+
"narVert",
|
|
1012
|
+
"dashHorz",
|
|
1013
|
+
"dashVert",
|
|
1014
|
+
"cross",
|
|
1015
|
+
"dnDiag",
|
|
1016
|
+
"upDiag",
|
|
1017
|
+
"ltDnDiag",
|
|
1018
|
+
"ltUpDiag",
|
|
1019
|
+
"dkDnDiag",
|
|
1020
|
+
"dkUpDiag",
|
|
1021
|
+
"wdDnDiag",
|
|
1022
|
+
"wdUpDiag",
|
|
1023
|
+
"dashDnDiag",
|
|
1024
|
+
"dashUpDiag",
|
|
1025
|
+
"diagCross",
|
|
1026
|
+
"smCheck",
|
|
1027
|
+
"lgCheck",
|
|
1028
|
+
"smGrid",
|
|
1029
|
+
"lgGrid",
|
|
1030
|
+
"dotGrid",
|
|
1031
|
+
"smConfetti",
|
|
1032
|
+
"lgConfetti",
|
|
1033
|
+
"horzBrick",
|
|
1034
|
+
"diagBrick",
|
|
1035
|
+
"solidDmnd",
|
|
1036
|
+
"openDmnd",
|
|
1037
|
+
"dotDmnd",
|
|
1038
|
+
"plaid",
|
|
1039
|
+
"sphere",
|
|
1040
|
+
"weave",
|
|
1041
|
+
"divot",
|
|
1042
|
+
"shingle",
|
|
1043
|
+
"wave",
|
|
1044
|
+
"trellis",
|
|
1045
|
+
"zigZag"
|
|
1046
|
+
]);
|
|
1047
|
+
var PATTERN_PRESET_ALIASES = Object.freeze({ diagStripe: "wdUpDiag" });
|
|
1048
|
+
var PATTERN_TILE_SIZE = 8;
|
|
1049
|
+
var MEASURED = {
|
|
1050
|
+
pct5: "#......./......../......../......../....#.../......../......../........",
|
|
1051
|
+
pct10: "#......./......../....#.../......../#......./......../....#.../........",
|
|
1052
|
+
pct20: "#...#.../......../..#...#./......../#...#.../......../..#...#./........",
|
|
1053
|
+
pct25: "#...#.../..#...#./#...#.../..#...#./#...#.../..#...#./#...#.../..#...#.",
|
|
1054
|
+
pct30: "#.#.#.#./.#...#../#.#.#.#./...#...#/#.#.#.#./.#...#../#.#.#.#./...#...#",
|
|
1055
|
+
pct40: "#.#.#.#./.#.#.#.#/#.#.#.#./.#.#...#/#.#.#.#./.#.#.#.#/#.#.#.#./...#.#.#",
|
|
1056
|
+
pct50: "#.#.#.#./.#.#.#.#/#.#.#.#./.#.#.#.#/#.#.#.#./.#.#.#.#/#.#.#.#./.#.#.#.#",
|
|
1057
|
+
pct60: "###.###./.#.#.#.#/#.###.##/.#.#.#.#/###.###./.#.#.#.#/#.###.##/.#.#.#.#",
|
|
1058
|
+
pct70: ".###.###/##.###.#/.###.###/##.###.#/.###.###/##.###.#/.###.###/##.###.#",
|
|
1059
|
+
pct75: ".###.###/########/##.###.#/########/.###.###/########/##.###.#/########",
|
|
1060
|
+
pct80: "###.####/########/#######./########/###.####/########/#######./########",
|
|
1061
|
+
pct90: "########/########/########/####.###/########/########/########/.#######",
|
|
1062
|
+
horz: "########/......../......../......../......../......../......../........",
|
|
1063
|
+
vert: "#......./#......./#......./#......./#......./#......./#......./#.......",
|
|
1064
|
+
ltHorz: "########/......../......../......../########/......../......../........",
|
|
1065
|
+
ltVert: "#...#.../#...#.../#...#.../#...#.../#...#.../#...#.../#...#.../#...#...",
|
|
1066
|
+
dkHorz: "########/########/......../......../########/########/......../........",
|
|
1067
|
+
dkVert: "##..##../##..##../##..##../##..##../##..##../##..##../##..##../##..##..",
|
|
1068
|
+
narHorz: "########/......../########/......../########/......../########/........",
|
|
1069
|
+
narVert: ".#.#.#.#/.#.#.#.#/.#.#.#.#/.#.#.#.#/.#.#.#.#/.#.#.#.#/.#.#.#.#/.#.#.#.#",
|
|
1070
|
+
dashHorz: "####..../......../......../......../....####/......../......../........",
|
|
1071
|
+
dashVert: "#......./#......./#......./#......./....#.../....#.../....#.../....#...",
|
|
1072
|
+
cross: "########/#......./#......./#......./#......./#......./#......./#.......",
|
|
1073
|
+
dnDiag: "#......./.#....../..#...../...#..../....#.../.....#../......#./.......#",
|
|
1074
|
+
upDiag: ".......#/......#./.....#../....#.../...#..../..#...../.#....../#.......",
|
|
1075
|
+
ltDnDiag: "#...#.../.#...#../..#...#./...#...#/#...#.../.#...#../..#...#./...#...#",
|
|
1076
|
+
ltUpDiag: "...#...#/..#...#./.#...#../#...#.../...#...#/..#...#./.#...#../#...#...",
|
|
1077
|
+
dkDnDiag: "##..##../.##..##./..##..##/#..##..#/##..##../.##..##./..##..##/#..##..#",
|
|
1078
|
+
dkUpDiag: "..##..##/.##..##./##..##../#..##..#/..##..##/.##..##./##..##../#..##..#",
|
|
1079
|
+
wdDnDiag: "##.....#/###...../.###..../..###.../...###../....###./.....###/#.....##",
|
|
1080
|
+
wdUpDiag: "#.....##/.....###/....###./...###../..###.../.###..../###...../##.....#",
|
|
1081
|
+
dashDnDiag: "......../......../#...#.../.#...#../..#...#./...#...#/......../........",
|
|
1082
|
+
dashUpDiag: "......../......../...#...#/..#...#./.#...#../#...#.../......../........",
|
|
1083
|
+
diagCross: "#......#/.#....#./..#..#../...##.../...##.../..#..#../.#....#./#......#",
|
|
1084
|
+
smCheck: "#..##..#/.##..##./.##..##./#..##..#/#..##..#/.##..##./.##..##./#..##..#",
|
|
1085
|
+
lgCheck: "####..../####..../####..../####..../....####/....####/....####/....####",
|
|
1086
|
+
smGrid: "########/#...#.../#...#.../#...#.../########/#...#.../#...#.../#...#...",
|
|
1087
|
+
lgGrid: "########/#......./#......./#......./#......./#......./#......./#.......",
|
|
1088
|
+
dotGrid: "#.#.#.#./......../#......./......../#......./......../#......./........",
|
|
1089
|
+
smConfetti: "#......./....#.../.#....../......#./...#..../.......#/..#...../.....#..",
|
|
1090
|
+
lgConfetti: "#.##...#/..##..../......##/...##.##/##.##.../##....../....##../#...##.#",
|
|
1091
|
+
horzBrick: "########/#......./#......./#......./########/....#.../....#.../....#...",
|
|
1092
|
+
diagBrick: ".......#/......#./.....#../....#.../...##.../..#..#../.#....#./#......#",
|
|
1093
|
+
solidDmnd: "...#..../..###.../.#####../#######./.#####../..###.../...#..../........",
|
|
1094
|
+
openDmnd: "#.....#./.#...#../..#.#.../...#..../..#.#.../.#...#../#.....#./.......#",
|
|
1095
|
+
dotDmnd: "#......./......../..#...#./......../....#.../......../..#...#./........",
|
|
1096
|
+
plaid: "#.#.#.#./.#.#.#.#/#.#.#.#./.#.#.#.#/####..../####..../####..../####....",
|
|
1097
|
+
sphere: ".###.###/#...#..#/#...####/#...####/.###.###/#..##.../#####.../#####...",
|
|
1098
|
+
weave: "#...#.../.#.#.#../..#...#./.#...#.#/#...#.../...#.#../..#...#./.#.#...#",
|
|
1099
|
+
divot: "......../...#..../....#.../...#..../......../#......./.......#/#.......",
|
|
1100
|
+
shingle: "......##/#....#../.#..#.../..##..../....##../......#./.......#/.......#",
|
|
1101
|
+
wave: "......../...##.../..#..#.#/##....../......../...##.../..#..#.#/##......",
|
|
1102
|
+
trellis: "########/.##..##./########/#..##..#/########/.##..##./########/#..##..#",
|
|
1103
|
+
zigZag: "#......#/.#....#./..#..#../...##.../#......#/.#....#./..#..#../...##..."
|
|
1104
|
+
};
|
|
1105
|
+
function rows(preset) {
|
|
1106
|
+
const art = MEASURED[preset];
|
|
1107
|
+
if (!art) return void 0;
|
|
1108
|
+
return art.split("/").map((row) => [...row].reduce((bits, cell, index) => cell === "#" ? bits | 128 >> index : bits, 0));
|
|
1109
|
+
}
|
|
1110
|
+
var BITMAPS = /* @__PURE__ */ new Map();
|
|
1111
|
+
for (const preset of PATTERN_PRESETS) {
|
|
1112
|
+
const bitmap = rows(preset);
|
|
1113
|
+
if (bitmap) BITMAPS.set(preset, Object.freeze(bitmap));
|
|
1114
|
+
}
|
|
1115
|
+
function resolvePatternPreset(preset) {
|
|
1116
|
+
if (typeof preset !== "string") return void 0;
|
|
1117
|
+
if (BITMAPS.has(preset)) return preset;
|
|
1118
|
+
return Object.hasOwn(PATTERN_PRESET_ALIASES, preset) ? PATTERN_PRESET_ALIASES[preset] : void 0;
|
|
1119
|
+
}
|
|
1120
|
+
function patternBitmap(preset) {
|
|
1121
|
+
const resolved = resolvePatternPreset(preset);
|
|
1122
|
+
return resolved === void 0 ? void 0 : BITMAPS.get(resolved);
|
|
1123
|
+
}
|
|
1124
|
+
function patternRuns(preset) {
|
|
1125
|
+
const bitmap = patternBitmap(preset);
|
|
1126
|
+
if (!bitmap) return void 0;
|
|
1127
|
+
const runs = [];
|
|
1128
|
+
bitmap.forEach((row, y) => {
|
|
1129
|
+
for (let x = 0; x < 8; x++) {
|
|
1130
|
+
if (!(row & 128 >> x)) continue;
|
|
1131
|
+
const start = x;
|
|
1132
|
+
while (x + 1 < 8 && row & 128 >> x + 1) x++;
|
|
1133
|
+
runs.push({ x: start, y, width: x - start + 1 });
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
return runs;
|
|
473
1137
|
}
|
|
474
1138
|
|
|
475
|
-
export { bundlePresentation,
|
|
1139
|
+
export { CODE_HIGHLIGHT_LANGUAGES, CODE_HIGHLIGHT_MAX_LENGTH, CODE_PANEL_BACKGROUND, CODE_PANEL_FOREGROUND, CODE_SYNTAX_MIN_CONTRAST, METRIC_TREND_MIN_CONTRAST, METRIC_TREND_SHAPES, PATTERN_PRESETS, PATTERN_PRESET_ALIASES, PATTERN_TILE_SIZE, bundlePresentation, codeLineRuns, codeSyntaxPalette, codeSyntaxPaletteForScheme, metricTrendColor, metricTrendMark, metricTrendPoints, patternBitmap, patternRuns, resolveCodeLanguage, resolvePatternPreset, tokenizeCode };
|