tempest-react-sdk 0.27.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/bin/lib/css/analyze.mjs +149 -0
- package/bin/lib/css/analyze.test.mjs +136 -0
- package/bin/lib/css/collect.mjs +152 -0
- package/bin/lib/css/findings.mjs +79 -0
- package/bin/lib/css/fix.e2e.test.mjs +99 -0
- package/bin/lib/css/fix.mjs +138 -0
- package/bin/lib/css/fix.test.mjs +108 -0
- package/bin/lib/css/index.mjs +16 -0
- package/bin/lib/css/parse.mjs +398 -0
- package/bin/lib/css/parse.test.mjs +146 -0
- package/bin/lib/css/properties.mjs +399 -0
- package/bin/lib/css/repetition.mjs +213 -0
- package/bin/lib/css/repetition.test.mjs +166 -0
- package/bin/lib/css/semantic.mjs +327 -0
- package/bin/lib/css/semantic.test.mjs +201 -0
- package/bin/lib/css/tokens.mjs +119 -0
- package/bin/lib/doctor/doctor.e2e.test.mjs +45 -0
- package/bin/tempest.mjs +169 -7
- package/dist/charts/scales.cjs +2 -0
- package/dist/charts/scales.cjs.map +1 -0
- package/dist/charts/scales.js +29 -0
- package/dist/charts/scales.js.map +1 -0
- package/dist/charts.cjs +1 -1
- package/dist/charts.d.ts +91 -0
- package/dist/charts.js +9 -8
- package/dist/components/BottomNavigation/BottomNavigation.module.cjs.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.module.js.map +1 -1
- package/dist/components/Carousel/Carousel.module.cjs.map +1 -1
- package/dist/components/Carousel/Carousel.module.js.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.cjs +3 -0
- package/dist/components/CodeBlock/CodeBlock.cjs.map +1 -0
- package/dist/components/CodeBlock/CodeBlock.js +53 -0
- package/dist/components/CodeBlock/CodeBlock.js.map +1 -0
- package/dist/components/CodeBlock/CodeBlock.module.cjs +2 -0
- package/dist/components/CodeBlock/CodeBlock.module.cjs.map +1 -0
- package/dist/components/CodeBlock/CodeBlock.module.js +29 -0
- package/dist/components/CodeBlock/CodeBlock.module.js.map +1 -0
- package/dist/components/CodeBlock/tokenize.cjs +3 -0
- package/dist/components/CodeBlock/tokenize.cjs.map +1 -0
- package/dist/components/CodeBlock/tokenize.js +267 -0
- package/dist/components/CodeBlock/tokenize.js.map +1 -0
- package/dist/components/Navbar/Navbar.module.cjs.map +1 -1
- package/dist/components/Navbar/Navbar.module.js.map +1 -1
- package/dist/components/QRCode/QRCode.cjs +2 -0
- package/dist/components/QRCode/QRCode.cjs.map +1 -0
- package/dist/components/QRCode/QRCode.js +49 -0
- package/dist/components/QRCode/QRCode.js.map +1 -0
- package/dist/components/QRCode/QRCode.module.cjs +2 -0
- package/dist/components/QRCode/QRCode.module.cjs.map +1 -0
- package/dist/components/QRCode/QRCode.module.js +9 -0
- package/dist/components/QRCode/QRCode.module.js.map +1 -0
- package/dist/components/QRCode/qr-encode.cjs +2 -0
- package/dist/components/QRCode/qr-encode.cjs.map +1 -0
- package/dist/components/QRCode/qr-encode.js +295 -0
- package/dist/components/QRCode/qr-encode.js.map +1 -0
- package/dist/components/QRCode/qr-tables.cjs +2 -0
- package/dist/components/QRCode/qr-tables.cjs.map +1 -0
- package/dist/components/QRCode/qr-tables.js +366 -0
- package/dist/components/QRCode/qr-tables.js.map +1 -0
- package/dist/components/ScrollArea/ScrollArea.cjs +1 -1
- package/dist/components/ScrollArea/ScrollArea.cjs.map +1 -1
- package/dist/components/ScrollArea/ScrollArea.js +22 -16
- package/dist/components/ScrollArea/ScrollArea.js.map +1 -1
- package/dist/components/ScrollArea/ScrollArea.module.cjs.map +1 -1
- package/dist/components/ScrollArea/ScrollArea.module.js.map +1 -1
- package/dist/components/Sparkline/Sparkline.cjs +2 -0
- package/dist/components/Sparkline/Sparkline.cjs.map +1 -0
- package/dist/components/Sparkline/Sparkline.js +64 -0
- package/dist/components/Sparkline/Sparkline.js.map +1 -0
- package/dist/components/Sparkline/Sparkline.module.cjs +2 -0
- package/dist/components/Sparkline/Sparkline.module.cjs.map +1 -0
- package/dist/components/Sparkline/Sparkline.module.js +10 -0
- package/dist/components/Sparkline/Sparkline.module.js.map +1 -0
- package/dist/components/Sparkline/sparkline-geometry.cjs +2 -0
- package/dist/components/Sparkline/sparkline-geometry.cjs.map +1 -0
- package/dist/components/Sparkline/sparkline-geometry.js +56 -0
- package/dist/components/Sparkline/sparkline-geometry.js.map +1 -0
- package/dist/components/Table/Table.cjs +1 -1
- package/dist/components/Table/Table.cjs.map +1 -1
- package/dist/components/Table/Table.js +37 -30
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Table/Table.module.cjs.map +1 -1
- package/dist/components/Table/Table.module.js.map +1 -1
- package/dist/components/VirtualList/VirtualList.cjs +1 -1
- package/dist/components/VirtualList/VirtualList.cjs.map +1 -1
- package/dist/components/VirtualList/VirtualList.js +13 -11
- package/dist/components/VirtualList/VirtualList.js.map +1 -1
- package/dist/components/VirtualList/VirtualList.module.cjs.map +1 -1
- package/dist/components/VirtualList/VirtualList.module.js.map +1 -1
- package/dist/hooks/use-scroll-overflow.cjs +2 -0
- package/dist/hooks/use-scroll-overflow.cjs.map +1 -0
- package/dist/hooks/use-scroll-overflow.js +22 -0
- package/dist/hooks/use-scroll-overflow.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +445 -2
- package/dist/tempest-react-sdk.js +197 -190
- package/dist/theme/create-theme.cjs +3 -3
- package/dist/theme/create-theme.cjs.map +1 -1
- package/dist/theme/create-theme.js +52 -28
- package/dist/theme/create-theme.js.map +1 -1
- package/dist/theme/data-viz-ramps.cjs +2 -0
- package/dist/theme/data-viz-ramps.cjs.map +1 -0
- package/dist/theme/data-viz-ramps.js +58 -0
- package/dist/theme/data-viz-ramps.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlock.js","names":[],"sources":["../../../src/components/CodeBlock/CodeBlock.tsx"],"sourcesContent":["import { Fragment, useMemo } from \"react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nimport { CopyButton } from \"../CopyButton\";\nimport { resolveLanguage, tokenizeLines } from \"./tokenize\";\nimport styles from \"./CodeBlock.module.css\";\n\nexport interface CodeBlockProps extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /** The source to display. Leading and trailing blank lines are trimmed. */\n code: string;\n /** Grammar name or alias (`ts`, `bash`, `json`…). Unknown values render plain. */\n language?: string;\n /** Shown in the header, usually a file path. */\n filename?: ReactNode;\n /** Number the lines. Default `false`. */\n showLineNumbers?: boolean;\n /** 1-based line numbers to mark as the point of the snippet. */\n highlightLines?: readonly number[];\n /** Offer a copy button. Default `true`. */\n copyable?: boolean;\n /** Cap the height in px or any CSS length; the body scrolls past it. */\n maxHeight?: number | string;\n /** Wrap long lines instead of scrolling sideways. Default `false`. */\n wrap?: boolean;\n /**\n * Accessible name for the code region. Defaults to naming the language, and\n * to the filename when there is one.\n */\n label?: string;\n}\n\n/**\n * A read-only code sample: syntax colours, optional line numbers, copy button.\n *\n * The `<pre>` is always focusable. A code block is scrollable and holds nothing\n * focusable inside, so without a tab stop a keyboard user can see there is more\n * code past the edge and has no way to reach it. It is the one scroll container\n * where the stop is unconditional rather than measured — a code sample is\n * expected to be reachable, read and selected on its own.\n *\n * Colours come from an approximate scanner, not a parser — see {@link tokenize}.\n *\n * @example\n * <CodeBlock code={snippet} language=\"ts\" filename=\"src/main.ts\" showLineNumbers />\n * <CodeBlock code={log} language=\"bash\" maxHeight={280} />\n */\nexport function CodeBlock({\n code,\n language,\n filename,\n showLineNumbers = false,\n highlightLines,\n copyable = true,\n maxHeight,\n wrap = false,\n label,\n className,\n ...rest\n}: CodeBlockProps) {\n const trimmed = useMemo(() => code.replace(/^\\n+/, \"\").replace(/\\s+$/, \"\"), [code]);\n const lines = useMemo(() => tokenizeLines(trimmed, language), [trimmed, language]);\n const resolved = resolveLanguage(language);\n const marked = useMemo(() => new Set(highlightLines ?? []), [highlightLines]);\n\n const name =\n label ??\n (filename && typeof filename === \"string\"\n ? `Código: ${filename}`\n : `Bloco de código${resolved === \"plain\" ? \"\" : ` em ${resolved}`}`);\n\n const hasHeader = Boolean(filename) || copyable;\n\n return (\n <div className={cn(styles.wrapper, className)} {...rest}>\n {hasHeader && (\n <div className={styles.header}>\n <span className={styles.filename}>\n {filename ?? (resolved === \"plain\" ? \"\" : resolved)}\n </span>\n {copyable && <CopyButton value={trimmed} className={styles.copy} />}\n </div>\n )}\n\n <pre\n className={cn(styles.pre, wrap && styles.wrap)}\n style={{ maxHeight }}\n tabIndex={0}\n role=\"group\"\n aria-label={name}\n >\n <code className={styles.code} data-language={resolved}>\n {lines.map((tokens, index) => (\n <Fragment key={index}>\n <span\n className={cn(styles.line, marked.has(index + 1) && styles.marked)}\n >\n {showLineNumbers && (\n /*\n * The number is decoration: it must not land in the\n * clipboard when the reader selects the snippet, and a\n * screen reader announcing \"one const two import\" adds\n * nothing. `user-select: none` in CSS plus this.\n */\n <span className={styles.lineNumber} aria-hidden=\"true\">\n {index + 1}\n </span>\n )}\n <span className={styles.lineContent}>\n {tokens.map((token, tokenIndex) => (\n <span\n key={tokenIndex}\n className={styles[token.kind]}\n data-token={token.kind}\n >\n {token.value}\n </span>\n ))}\n </span>\n </span>\n {/*\n * A real newline character, and outside the line box.\n * It has to be real so that selecting the snippet by\n * hand and copying yields the source instead of one\n * run-together line. It has to be outside because the\n * line is an inline-block: a newline within one is\n * consumed inside that box, and every line ends up\n * side by side on a single row. The last one is\n * dropped so the block does not end in blank space.\n */}\n {index < lines.length - 1 ? \"\\n\" : null}\n </Fragment>\n ))}\n </code>\n </pre>\n </div>\n );\n}\n"],"mappings":";;;;;;;AAgDA,SAAgB,EAAU,EACtB,SACA,aACA,aACA,qBAAkB,IAClB,mBACA,cAAW,IACX,cACA,UAAO,IACP,UACA,cACA,GAAG,KACY;CACf,IAAM,IAAU,QAAc,EAAK,QAAQ,QAAQ,EAAE,CAAC,CAAC,QAAQ,QAAQ,EAAE,GAAG,CAAC,CAAI,CAAC,GAC5E,IAAQ,QAAc,EAAc,GAAS,CAAQ,GAAG,CAAC,GAAS,CAAQ,CAAC,GAC3E,IAAW,EAAgB,CAAQ,GACnC,IAAS,QAAc,IAAI,IAAI,KAAkB,CAAC,CAAC,GAAG,CAAC,CAAc,CAAC,GAEtE,IACF,MACC,KAAY,OAAO,KAAa,WAC3B,WAAW,MACX,kBAAkB,MAAa,UAAU,KAAK,OAAO,QAEzD,IAAY,EAAQ,KAAa;CAEvC,OACI,kBAAC,OAAD;EAAK,WAAW,EAAG,EAAO,SAAS,CAAS;EAAG,GAAI;YAAnD,CACK,KACG,kBAAC,OAAD;GAAK,WAAW,EAAO;aAAvB,CACI,kBAAC,QAAD;IAAM,WAAW,EAAO;cACnB,MAAa,MAAa,UAAU,KAAK;GACxC,CAAA,GACL,KAAY,kBAAC,GAAD;IAAY,OAAO;IAAS,WAAW,EAAO;GAAO,CAAA,CACjE;MAGT,kBAAC,OAAD;GACI,WAAW,EAAG,EAAO,KAAK,KAAQ,EAAO,IAAI;GAC7C,OAAO,EAAE,aAAU;GACnB,UAAU;GACV,MAAK;GACL,cAAY;aAEZ,kBAAC,QAAD;IAAM,WAAW,EAAO;IAAM,iBAAe;cACxC,EAAM,KAAK,GAAQ,MAChB,kBAAC,GAAD,EAAA,UAAA,CACI,kBAAC,QAAD;KACI,WAAW,EAAG,EAAO,MAAM,EAAO,IAAI,IAAQ,CAAC,KAAK,EAAO,MAAM;eADrE,CAGK,KAOG,kBAAC,QAAD;MAAM,WAAW,EAAO;MAAY,eAAY;gBAC3C,IAAQ;KACP,CAAA,GAEV,kBAAC,QAAD;MAAM,WAAW,EAAO;gBACnB,EAAO,KAAK,GAAO,MAChB,kBAAC,QAAD;OAEI,WAAW,EAAO,EAAM;OACxB,cAAY,EAAM;iBAEjB,EAAM;MACL,GALG,CAKH,CACT;KACC,CAAA,CACJ;QAWL,IAAQ,EAAM,SAAS,IAAI,OAAO,IAC7B,EAAA,GAtCK,CAsCL,CACb;GACC,CAAA;EACL,CAAA,CACJ;;AAEb"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=`tempest_wrapper_xdAwS`,t=`tempest_header_8LI5O`,n=`tempest_filename_IJaOa`,r=`tempest_copy_1sWYD`,i=`tempest_pre_1FhUD`,a=`tempest_code_LzjrW`,o=`tempest_wrap_ZMMcG`,s=`tempest_lineContent_pmXXV`,c=`tempest_line_oMdOA`,l=`tempest_marked_uYt-k`,u=`tempest_lineNumber_QnG-9`,d=`tempest_comment_SXwoI`,f=`tempest_string_KlC9t`,p=`tempest_number_xT7lt`,m=`tempest_keyword_PrsZ5`,h=`tempest_literal_7mCqM`,g=`tempest_tag_YF1kB`,_=`tempest_attribute_1O6-k`,v=`tempest_property_bLrIs`,y=`tempest_punctuation_teKJo`,b=`tempest_plain_KdCB1`,x={wrapper:e,header:t,filename:n,copy:r,pre:i,code:a,wrap:o,lineContent:s,line:c,marked:l,lineNumber:u,comment:d,string:f,number:p,keyword:m,literal:h,function:`tempest_function_c2AFf`,tag:g,attribute:_,property:v,punctuation:y,plain:b};exports.attribute=_,exports.code=a,exports.comment=d,exports.copy=r,exports.default=x,exports.filename=n,exports.header=t,exports.keyword=m,exports.line=c,exports.lineContent=s,exports.lineNumber=u,exports.literal=h,exports.marked=l,exports.number=p,exports.plain=b,exports.pre=i,exports.property=v,exports.punctuation=y,exports.string=f,exports.tag=g,exports.wrap=o,exports.wrapper=e;
|
|
2
|
+
//# sourceMappingURL=CodeBlock.module.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlock.module.cjs","names":[],"sources":["../../../src/components/CodeBlock/CodeBlock.module.css"],"sourcesContent":[".wrapper {\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-lg);\n background-color: var(--tempest-surface);\n overflow: hidden;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--tempest-space-2);\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border-bottom: 1px solid var(--tempest-border);\n background-color: var(--tempest-bg);\n}\n\n.filename {\n font-family: var(--tempest-font-mono);\n font-size: var(--tempest-text-xs);\n color: var(--tempest-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.copy {\n flex-shrink: 0;\n}\n\n.pre {\n margin: 0;\n padding: var(--tempest-space-3) 0;\n overflow: auto;\n font-family: var(--tempest-font-mono);\n font-size: var(--tempest-text-sm);\n line-height: 1.6;\n tab-size: 4;\n}\n\n.pre:focus-visible {\n outline: var(--tempest-focus-ring-width) solid var(--tempest-focus-ring-color);\n outline-offset: -2px;\n}\n\n.code {\n display: block;\n font: inherit;\n min-width: max-content;\n}\n\n.wrap .code {\n min-width: 0;\n}\n\n.wrap .lineContent {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n/*\n * `inline-block` with a full-width box, not `flex`: the line break comes from\n * the real newline character inside the line, and a flex item would wrap on it\n * and render every line twice as tall. Full width is what lets the marked-line\n * background span the whole row rather than stopping at the last character.\n */\n.line {\n display: inline-block;\n width: 100%;\n padding-inline: var(--tempest-space-3);\n}\n\n/*\n * The marked line is called out with a left bar and a tinted ground rather than\n * a different text colour: the syntax colours already carry meaning, and\n * recolouring the text would collide with them.\n *\n * The tint is a thin wash of the primary rather than `--tempest-primary-soft`,\n * because it sits *behind text*. The soft token is a solid ground and moved the\n * effective background far enough to drop a keyword to 3.94:1 in dark mode —\n * the syntax colours are solved against the code surface, so the highlight has\n * to leave that surface roughly where it was. The bar carries the emphasis.\n */\n.marked {\n background-color: color-mix(in srgb, var(--tempest-primary) 10%, transparent);\n box-shadow: inset 2px 0 0 var(--tempest-primary);\n}\n\n/*\n * The gutter wears the comment colour, not `--tempest-text-subtle`: subtle is\n * tuned to recede against the page and measures 4.04:1 on the dark code\n * surface, which is below AA. The comment token recedes the same way and is\n * solved for that surface.\n */\n.lineNumber {\n display: inline-block;\n width: 2.5ch;\n margin-right: var(--tempest-space-3);\n text-align: right;\n color: var(--tempest-code-comment);\n user-select: none;\n}\n\n.lineContent {\n white-space: pre;\n}\n\n/*\n * Syntax colours come from their own `--tempest-code-*` tokens, not from the\n * chart ramp. The ramp is validated for marks, where the contrast floor is 3:1;\n * this is text and needs 4.5:1, and measuring the ramp as text fails in both\n * modes (a keyword came out at 3.47 on the dark surface, a string at 2.03 on\n * the light one). The code tokens are solved for that floor instead.\n */\n.comment {\n color: var(--tempest-code-comment);\n font-style: italic;\n}\n\n.string {\n color: var(--tempest-code-string);\n}\n\n.number {\n color: var(--tempest-code-number);\n}\n\n.keyword {\n color: var(--tempest-code-keyword);\n font-weight: 600;\n}\n\n.literal {\n color: var(--tempest-code-literal);\n}\n\n.function {\n color: var(--tempest-code-function);\n}\n\n.tag {\n color: var(--tempest-code-tag);\n}\n\n.attribute {\n color: var(--tempest-code-attribute);\n}\n\n.property {\n color: var(--tempest-code-property);\n}\n\n.punctuation {\n color: var(--tempest-code-punctuation);\n}\n\n.plain {\n color: var(--tempest-text);\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/components/CodeBlock/CodeBlock.module.css
|
|
2
|
+
var e = "tempest_wrapper_xdAwS", t = "tempest_header_8LI5O", n = "tempest_filename_IJaOa", r = "tempest_copy_1sWYD", i = "tempest_pre_1FhUD", a = "tempest_code_LzjrW", o = "tempest_wrap_ZMMcG", s = "tempest_lineContent_pmXXV", c = "tempest_line_oMdOA", l = "tempest_marked_uYt-k", u = "tempest_lineNumber_QnG-9", d = "tempest_comment_SXwoI", f = "tempest_string_KlC9t", p = "tempest_number_xT7lt", m = "tempest_keyword_PrsZ5", h = "tempest_literal_7mCqM", g = "tempest_tag_YF1kB", _ = "tempest_attribute_1O6-k", v = "tempest_property_bLrIs", y = "tempest_punctuation_teKJo", b = "tempest_plain_KdCB1", x = {
|
|
3
|
+
wrapper: e,
|
|
4
|
+
header: t,
|
|
5
|
+
filename: n,
|
|
6
|
+
copy: r,
|
|
7
|
+
pre: i,
|
|
8
|
+
code: a,
|
|
9
|
+
wrap: o,
|
|
10
|
+
lineContent: s,
|
|
11
|
+
line: c,
|
|
12
|
+
marked: l,
|
|
13
|
+
lineNumber: u,
|
|
14
|
+
comment: d,
|
|
15
|
+
string: f,
|
|
16
|
+
number: p,
|
|
17
|
+
keyword: m,
|
|
18
|
+
literal: h,
|
|
19
|
+
function: "tempest_function_c2AFf",
|
|
20
|
+
tag: g,
|
|
21
|
+
attribute: _,
|
|
22
|
+
property: v,
|
|
23
|
+
punctuation: y,
|
|
24
|
+
plain: b
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { _ as attribute, a as code, d as comment, r as copy, x as default, n as filename, t as header, m as keyword, c as line, s as lineContent, u as lineNumber, h as literal, l as marked, p as number, b as plain, i as pre, v as property, y as punctuation, f as string, g as tag, o as wrap, e as wrapper };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=CodeBlock.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlock.module.js","names":[],"sources":["../../../src/components/CodeBlock/CodeBlock.module.css"],"sourcesContent":[".wrapper {\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-lg);\n background-color: var(--tempest-surface);\n overflow: hidden;\n}\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--tempest-space-2);\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border-bottom: 1px solid var(--tempest-border);\n background-color: var(--tempest-bg);\n}\n\n.filename {\n font-family: var(--tempest-font-mono);\n font-size: var(--tempest-text-xs);\n color: var(--tempest-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.copy {\n flex-shrink: 0;\n}\n\n.pre {\n margin: 0;\n padding: var(--tempest-space-3) 0;\n overflow: auto;\n font-family: var(--tempest-font-mono);\n font-size: var(--tempest-text-sm);\n line-height: 1.6;\n tab-size: 4;\n}\n\n.pre:focus-visible {\n outline: var(--tempest-focus-ring-width) solid var(--tempest-focus-ring-color);\n outline-offset: -2px;\n}\n\n.code {\n display: block;\n font: inherit;\n min-width: max-content;\n}\n\n.wrap .code {\n min-width: 0;\n}\n\n.wrap .lineContent {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n/*\n * `inline-block` with a full-width box, not `flex`: the line break comes from\n * the real newline character inside the line, and a flex item would wrap on it\n * and render every line twice as tall. Full width is what lets the marked-line\n * background span the whole row rather than stopping at the last character.\n */\n.line {\n display: inline-block;\n width: 100%;\n padding-inline: var(--tempest-space-3);\n}\n\n/*\n * The marked line is called out with a left bar and a tinted ground rather than\n * a different text colour: the syntax colours already carry meaning, and\n * recolouring the text would collide with them.\n *\n * The tint is a thin wash of the primary rather than `--tempest-primary-soft`,\n * because it sits *behind text*. The soft token is a solid ground and moved the\n * effective background far enough to drop a keyword to 3.94:1 in dark mode —\n * the syntax colours are solved against the code surface, so the highlight has\n * to leave that surface roughly where it was. The bar carries the emphasis.\n */\n.marked {\n background-color: color-mix(in srgb, var(--tempest-primary) 10%, transparent);\n box-shadow: inset 2px 0 0 var(--tempest-primary);\n}\n\n/*\n * The gutter wears the comment colour, not `--tempest-text-subtle`: subtle is\n * tuned to recede against the page and measures 4.04:1 on the dark code\n * surface, which is below AA. The comment token recedes the same way and is\n * solved for that surface.\n */\n.lineNumber {\n display: inline-block;\n width: 2.5ch;\n margin-right: var(--tempest-space-3);\n text-align: right;\n color: var(--tempest-code-comment);\n user-select: none;\n}\n\n.lineContent {\n white-space: pre;\n}\n\n/*\n * Syntax colours come from their own `--tempest-code-*` tokens, not from the\n * chart ramp. The ramp is validated for marks, where the contrast floor is 3:1;\n * this is text and needs 4.5:1, and measuring the ramp as text fails in both\n * modes (a keyword came out at 3.47 on the dark surface, a string at 2.03 on\n * the light one). The code tokens are solved for that floor instead.\n */\n.comment {\n color: var(--tempest-code-comment);\n font-style: italic;\n}\n\n.string {\n color: var(--tempest-code-string);\n}\n\n.number {\n color: var(--tempest-code-number);\n}\n\n.keyword {\n color: var(--tempest-code-keyword);\n font-weight: 600;\n}\n\n.literal {\n color: var(--tempest-code-literal);\n}\n\n.function {\n color: var(--tempest-code-function);\n}\n\n.tag {\n color: var(--tempest-code-tag);\n}\n\n.attribute {\n color: var(--tempest-code-attribute);\n}\n\n.property {\n color: var(--tempest-code-property);\n}\n\n.punctuation {\n color: var(--tempest-code-punctuation);\n}\n\n.plain {\n color: var(--tempest-text);\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var e={ts:`typescript`,typescript:`typescript`,js:`javascript`,javascript:`javascript`,mjs:`javascript`,cjs:`javascript`,tsx:`tsx`,jsx:`jsx`,json:`json`,jsonc:`json`,css:`css`,scss:`css`,html:`html`,xml:`html`,svg:`html`,sh:`bash`,bash:`bash`,shell:`bash`,zsh:`bash`,console:`bash`,py:`python`,python:`python`,sql:`sql`};function t(t){return t?e[t.toLowerCase()]??`plain`:`plain`}var n=`as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|keyof|let|new|of|private|protected|public|readonly|return|satisfies|set|static|super|switch|this|throw|try|type|typeof|var|void|while|with|yield`,r=`true|false|null|undefined|NaN|Infinity`,i={typescript:a(!1),javascript:a(!1),tsx:a(!0),jsx:a(!0),json:[{kind:`property`,pattern:/"(?:[^"\\]|\\.)*"(?=\s*:)/y},{kind:`string`,pattern:/"(?:[^"\\]|\\.)*"/y},{kind:`number`,pattern:/-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/y},{kind:`literal`,pattern:/\b(?:true|false|null)\b/y},{kind:`punctuation`,pattern:/[{}[\],:]/y}],css:[{kind:`comment`,pattern:/\/\*[\s\S]*?\*\//y},{kind:`string`,pattern:/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/y},{kind:`keyword`,pattern:/@[a-zA-Z-]+/y},{kind:`property`,pattern:/--?[a-zA-Z][\w-]*(?=\s*:)/y},{kind:`function`,pattern:/[a-zA-Z-]+(?=\()/y},{kind:`number`,pattern:/-?\d+(?:\.\d+)?(?:px|rem|em|%|s|ms|vh|vw|fr|deg)?/y},{kind:`punctuation`,pattern:/[{}();:,>+~]/y}],html:[{kind:`comment`,pattern:/<!--[\s\S]*?-->/y},{kind:`string`,pattern:/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/y},{kind:`tag`,pattern:/<\/?[a-zA-Z][\w:-]*/y},{kind:`attribute`,pattern:/[a-zA-Z][\w:-]*(?==)/y},{kind:`punctuation`,pattern:/\/?>|=/y}],bash:[{kind:`comment`,pattern:/#[^\n]*/y},{kind:`string`,pattern:/"(?:[^"\\]|\\.)*"|'[^']*'/y},{kind:`keyword`,pattern:/\b(?:if|then|else|elif|fi|for|while|do|done|case|esac|function|return|export|local|source|set|cd|echo)\b/y},{kind:`property`,pattern:/\$\{?[A-Za-z_][\w]*\}?/y},{kind:`attribute`,pattern:/(?<=\s)--?[a-zA-Z][\w-]*/y},{kind:`punctuation`,pattern:/[|&;()<>]/y}],python:[{kind:`comment`,pattern:/#[^\n]*/y},{kind:`string`,pattern:/"""[\s\S]*?"""|'''[\s\S]*?'''|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/y},{kind:`keyword`,pattern:/\b(?: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)\b/y},{kind:`literal`,pattern:/\b(?:True|False|None|self)\b/y},{kind:`number`,pattern:/\b\d+(?:\.\d+)?\b/y},{kind:`function`,pattern:/[A-Za-z_]\w*(?=\()/y},{kind:`punctuation`,pattern:/[{}[\]().,:;=+\-*/<>!]/y}],sql:[{kind:`comment`,pattern:/--[^\n]*|\/\*[\s\S]*?\*\//y},{kind:`string`,pattern:/'(?:[^']|'')*'/y},{kind:`keyword`,pattern:/\b(?:select|from|where|insert|into|values|update|set|delete|create|table|alter|drop|index|join|inner|left|right|outer|on|group|by|order|having|limit|offset|as|and|or|not|in|is|null|distinct|union|all|with|returning|primary|key|foreign|references|default)\b/iy},{kind:`number`,pattern:/\b\d+(?:\.\d+)?\b/y},{kind:`punctuation`,pattern:/[(),;*=<>]/y}],plain:[]};function a(e){let t=[{kind:`comment`,pattern:/\/\/[^\n]*|\/\*[\s\S]*?\*\//y},{kind:`string`,pattern:/`(?:[^`\\]|\\.)*`|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/y},{kind:`keyword`,pattern:RegExp(`\\b(?:${n})\\b`,`y`)},{kind:`literal`,pattern:RegExp(`\\b(?:${r})\\b`,`y`)},{kind:`number`,pattern:/\b(?:0[xX][\da-fA-F_]+|\d[\d_]*(?:\.[\d_]+)?(?:[eE][+-]?\d+)?)\b/y},{kind:`function`,pattern:/[A-Za-z_$][\w$]*(?=\s*\()/y},{kind:`punctuation`,pattern:/[{}[\]().,;:?!=<>+\-*/%&|^~]/y}];return e&&t.splice(2,0,{kind:`tag`,pattern:/<\/?[A-Za-z][\w.]*|\/>/y}),t}function o(e,n){let r=i[t(n)];if(r.length===0)return e===``?[]:[{kind:`plain`,value:e}];let a=[],o=0,s=0,c=t=>{t>o&&a.push({kind:`plain`,value:e.slice(o,t)})};for(;s<e.length;){let t=null;for(let n of r){n.pattern.lastIndex=s;let r=n.pattern.exec(e);if(r&&r[0].length>0){t={kind:n.kind,value:r[0]};break}}t?(c(s),a.push(t),s+=t.value.length,o=s):s++}return c(e.length),a}function s(e,t){let n=[[]];for(let r of o(e,t))r.value.split(`
|
|
2
|
+
`).forEach((e,t)=>{t>0&&n.push([]),e!==``&&n[n.length-1].push({kind:r.kind,value:e})});return n}exports.resolveLanguage=t,exports.tokenize=o,exports.tokenizeLines=s;
|
|
3
|
+
//# sourceMappingURL=tokenize.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenize.cjs","names":[],"sources":["../../../src/components/CodeBlock/tokenize.ts"],"sourcesContent":["/** What a token is painted as. */\nexport type TokenKind =\n | \"plain\"\n | \"comment\"\n | \"string\"\n | \"number\"\n | \"keyword\"\n | \"literal\"\n | \"function\"\n | \"punctuation\"\n | \"tag\"\n | \"attribute\"\n | \"property\";\n\nexport interface Token {\n kind: TokenKind;\n value: string;\n}\n\n/** Languages the tokenizer knows. Anything else renders as plain text. */\nexport type CodeLanguage =\n | \"typescript\"\n | \"javascript\"\n | \"tsx\"\n | \"jsx\"\n | \"json\"\n | \"css\"\n | \"html\"\n | \"bash\"\n | \"python\"\n | \"sql\"\n | \"plain\";\n\n/** Aliases people actually type, mapped onto the grammars above. */\nconst ALIASES: Record<string, CodeLanguage> = {\n ts: \"typescript\",\n typescript: \"typescript\",\n js: \"javascript\",\n javascript: \"javascript\",\n mjs: \"javascript\",\n cjs: \"javascript\",\n tsx: \"tsx\",\n jsx: \"jsx\",\n json: \"json\",\n jsonc: \"json\",\n css: \"css\",\n scss: \"css\",\n html: \"html\",\n xml: \"html\",\n svg: \"html\",\n sh: \"bash\",\n bash: \"bash\",\n shell: \"bash\",\n zsh: \"bash\",\n console: \"bash\",\n py: \"python\",\n python: \"python\",\n sql: \"sql\",\n};\n\n/**\n * Normalise a language name onto a known grammar.\n *\n * @param language - Whatever the caller passed, e.g. `\"ts\"` or `\"Shell\"`.\n * @returns The grammar to use; `\"plain\"` when there is no match.\n */\nexport function resolveLanguage(language: string | undefined): CodeLanguage {\n if (!language) return \"plain\";\n return ALIASES[language.toLowerCase()] ?? \"plain\";\n}\n\n/** One grammar rule: a sticky pattern and the kind it produces. */\ninterface Rule {\n kind: TokenKind;\n pattern: RegExp;\n}\n\nconst JS_KEYWORDS =\n \"as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|keyof|let|new|of|private|protected|public|readonly|return|satisfies|set|static|super|switch|this|throw|try|type|typeof|var|void|while|with|yield\";\n\nconst JS_LITERALS = \"true|false|null|undefined|NaN|Infinity\";\n\n/**\n * Rules per grammar, tried in order at each position.\n *\n * Order carries meaning: comments and strings come first so a keyword inside a\n * string stays a string. Every pattern is sticky (`y`) and anchored by\n * `lastIndex`, so a rule can only match where the scanner currently stands.\n */\nconst GRAMMARS: Record<CodeLanguage, Rule[]> = {\n typescript: jsRules(false),\n javascript: jsRules(false),\n tsx: jsRules(true),\n jsx: jsRules(true),\n json: [\n { kind: \"property\", pattern: /\"(?:[^\"\\\\]|\\\\.)*\"(?=\\s*:)/y },\n { kind: \"string\", pattern: /\"(?:[^\"\\\\]|\\\\.)*\"/y },\n { kind: \"number\", pattern: /-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/y },\n { kind: \"literal\", pattern: /\\b(?:true|false|null)\\b/y },\n { kind: \"punctuation\", pattern: /[{}[\\],:]/y },\n ],\n css: [\n { kind: \"comment\", pattern: /\\/\\*[\\s\\S]*?\\*\\//y },\n { kind: \"string\", pattern: /\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/y },\n { kind: \"keyword\", pattern: /@[a-zA-Z-]+/y },\n { kind: \"property\", pattern: /--?[a-zA-Z][\\w-]*(?=\\s*:)/y },\n { kind: \"function\", pattern: /[a-zA-Z-]+(?=\\()/y },\n { kind: \"number\", pattern: /-?\\d+(?:\\.\\d+)?(?:px|rem|em|%|s|ms|vh|vw|fr|deg)?/y },\n { kind: \"punctuation\", pattern: /[{}();:,>+~]/y },\n ],\n html: [\n { kind: \"comment\", pattern: /<!--[\\s\\S]*?-->/y },\n { kind: \"string\", pattern: /\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/y },\n { kind: \"tag\", pattern: /<\\/?[a-zA-Z][\\w:-]*/y },\n { kind: \"attribute\", pattern: /[a-zA-Z][\\w:-]*(?==)/y },\n { kind: \"punctuation\", pattern: /\\/?>|=/y },\n ],\n bash: [\n { kind: \"comment\", pattern: /#[^\\n]*/y },\n { kind: \"string\", pattern: /\"(?:[^\"\\\\]|\\\\.)*\"|'[^']*'/y },\n {\n kind: \"keyword\",\n pattern:\n /\\b(?:if|then|else|elif|fi|for|while|do|done|case|esac|function|return|export|local|source|set|cd|echo)\\b/y,\n },\n { kind: \"property\", pattern: /\\$\\{?[A-Za-z_][\\w]*\\}?/y },\n { kind: \"attribute\", pattern: /(?<=\\s)--?[a-zA-Z][\\w-]*/y },\n { kind: \"punctuation\", pattern: /[|&;()<>]/y },\n ],\n python: [\n { kind: \"comment\", pattern: /#[^\\n]*/y },\n {\n kind: \"string\",\n pattern: /\"\"\"[\\s\\S]*?\"\"\"|'''[\\s\\S]*?'''|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/y,\n },\n {\n kind: \"keyword\",\n pattern:\n /\\b(?: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)\\b/y,\n },\n { kind: \"literal\", pattern: /\\b(?:True|False|None|self)\\b/y },\n { kind: \"number\", pattern: /\\b\\d+(?:\\.\\d+)?\\b/y },\n { kind: \"function\", pattern: /[A-Za-z_]\\w*(?=\\()/y },\n { kind: \"punctuation\", pattern: /[{}[\\]().,:;=+\\-*/<>!]/y },\n ],\n sql: [\n { kind: \"comment\", pattern: /--[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//y },\n { kind: \"string\", pattern: /'(?:[^']|'')*'/y },\n {\n kind: \"keyword\",\n // Case-insensitive: SQL is written both ways and both should paint.\n pattern:\n /\\b(?:select|from|where|insert|into|values|update|set|delete|create|table|alter|drop|index|join|inner|left|right|outer|on|group|by|order|having|limit|offset|as|and|or|not|in|is|null|distinct|union|all|with|returning|primary|key|foreign|references|default)\\b/iy,\n },\n { kind: \"number\", pattern: /\\b\\d+(?:\\.\\d+)?\\b/y },\n { kind: \"punctuation\", pattern: /[(),;*=<>]/y },\n ],\n plain: [],\n};\n\n/** The shared JavaScript-family rules, with JSX tags added for tsx/jsx. */\nfunction jsRules(withJsx: boolean): Rule[] {\n const rules: Rule[] = [\n { kind: \"comment\", pattern: /\\/\\/[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//y },\n {\n kind: \"string\",\n pattern: /`(?:[^`\\\\]|\\\\.)*`|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/y,\n },\n { kind: \"keyword\", pattern: new RegExp(`\\\\b(?:${JS_KEYWORDS})\\\\b`, \"y\") },\n { kind: \"literal\", pattern: new RegExp(`\\\\b(?:${JS_LITERALS})\\\\b`, \"y\") },\n {\n kind: \"number\",\n pattern: /\\b(?:0[xX][\\da-fA-F_]+|\\d[\\d_]*(?:\\.[\\d_]+)?(?:[eE][+-]?\\d+)?)\\b/y,\n },\n { kind: \"function\", pattern: /[A-Za-z_$][\\w$]*(?=\\s*\\()/y },\n { kind: \"punctuation\", pattern: /[{}[\\]().,;:?!=<>+\\-*/%&|^~]/y },\n ];\n if (withJsx) {\n // Before the keyword rule, so `<Button` reads as a tag and not as `<`.\n rules.splice(2, 0, { kind: \"tag\", pattern: /<\\/?[A-Za-z][\\w.]*|\\/>/y });\n }\n return rules;\n}\n\n/**\n * Split source into coloured tokens.\n *\n * This is a **scanner, not a parser**: it recognises comments, strings, numbers,\n * keywords and punctuation by pattern, and knows nothing about scope, types or\n * grammar. That is a deliberate ceiling. A real parser per language is a\n * dependency the size of the rest of the SDK, and the payoff — being right about\n * the corner cases in a documentation snippet — is small. Where it is unsure it\n * emits `plain`, which renders as ordinary text rather than as something wrong.\n *\n * Unknown languages produce a single `plain` token, so an unhighlighted block is\n * a normal outcome and never an error.\n *\n * @param code - The source.\n * @param language - Grammar name or alias.\n * @returns Tokens covering the input exactly, in order.\n *\n * @example\n * tokenize(\"const x = 1;\", \"ts\");\n * // [{kind: \"keyword\", value: \"const\"}, {kind: \"plain\", value: \" x \"}, …]\n */\nexport function tokenize(code: string, language: string | undefined): Token[] {\n const rules = GRAMMARS[resolveLanguage(language)];\n if (rules.length === 0) return code === \"\" ? [] : [{ kind: \"plain\", value: code }];\n\n const tokens: Token[] = [];\n let plainFrom = 0;\n let at = 0;\n\n const flushPlain = (until: number) => {\n if (until > plainFrom) tokens.push({ kind: \"plain\", value: code.slice(plainFrom, until) });\n };\n\n while (at < code.length) {\n let matched: Token | null = null;\n for (const rule of rules) {\n rule.pattern.lastIndex = at;\n const found = rule.pattern.exec(code);\n if (found && found[0].length > 0) {\n matched = { kind: rule.kind, value: found[0] };\n break;\n }\n }\n if (matched) {\n flushPlain(at);\n tokens.push(matched);\n at += matched.value.length;\n plainFrom = at;\n } else {\n at++;\n }\n }\n flushPlain(code.length);\n return tokens;\n}\n\n/**\n * The same tokens, split at newlines so each line can be rendered on its own.\n *\n * Line numbers and highlighted lines both need a per-line structure, and a token\n * is free to span a line break — a block comment usually does. Splitting here\n * keeps that out of the component.\n *\n * @param code - The source.\n * @param language - Grammar name or alias.\n * @returns One token array per line. Always at least one line.\n */\nexport function tokenizeLines(code: string, language: string | undefined): Token[][] {\n const lines: Token[][] = [[]];\n for (const token of tokenize(code, language)) {\n const pieces = token.value.split(\"\\n\");\n pieces.forEach((piece, index) => {\n if (index > 0) lines.push([]);\n if (piece !== \"\") lines[lines.length - 1].push({ kind: token.kind, value: piece });\n });\n }\n return lines;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
//#region src/components/CodeBlock/tokenize.ts
|
|
2
|
+
var e = {
|
|
3
|
+
ts: "typescript",
|
|
4
|
+
typescript: "typescript",
|
|
5
|
+
js: "javascript",
|
|
6
|
+
javascript: "javascript",
|
|
7
|
+
mjs: "javascript",
|
|
8
|
+
cjs: "javascript",
|
|
9
|
+
tsx: "tsx",
|
|
10
|
+
jsx: "jsx",
|
|
11
|
+
json: "json",
|
|
12
|
+
jsonc: "json",
|
|
13
|
+
css: "css",
|
|
14
|
+
scss: "css",
|
|
15
|
+
html: "html",
|
|
16
|
+
xml: "html",
|
|
17
|
+
svg: "html",
|
|
18
|
+
sh: "bash",
|
|
19
|
+
bash: "bash",
|
|
20
|
+
shell: "bash",
|
|
21
|
+
zsh: "bash",
|
|
22
|
+
console: "bash",
|
|
23
|
+
py: "python",
|
|
24
|
+
python: "python",
|
|
25
|
+
sql: "sql"
|
|
26
|
+
};
|
|
27
|
+
function t(t) {
|
|
28
|
+
return t ? e[t.toLowerCase()] ?? "plain" : "plain";
|
|
29
|
+
}
|
|
30
|
+
var n = "as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|keyof|let|new|of|private|protected|public|readonly|return|satisfies|set|static|super|switch|this|throw|try|type|typeof|var|void|while|with|yield", r = "true|false|null|undefined|NaN|Infinity", i = {
|
|
31
|
+
typescript: a(!1),
|
|
32
|
+
javascript: a(!1),
|
|
33
|
+
tsx: a(!0),
|
|
34
|
+
jsx: a(!0),
|
|
35
|
+
json: [
|
|
36
|
+
{
|
|
37
|
+
kind: "property",
|
|
38
|
+
pattern: /"(?:[^"\\]|\\.)*"(?=\s*:)/y
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
kind: "string",
|
|
42
|
+
pattern: /"(?:[^"\\]|\\.)*"/y
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
kind: "number",
|
|
46
|
+
pattern: /-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/y
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
kind: "literal",
|
|
50
|
+
pattern: /\b(?:true|false|null)\b/y
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
kind: "punctuation",
|
|
54
|
+
pattern: /[{}[\],:]/y
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
css: [
|
|
58
|
+
{
|
|
59
|
+
kind: "comment",
|
|
60
|
+
pattern: /\/\*[\s\S]*?\*\//y
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
kind: "string",
|
|
64
|
+
pattern: /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/y
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
kind: "keyword",
|
|
68
|
+
pattern: /@[a-zA-Z-]+/y
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
kind: "property",
|
|
72
|
+
pattern: /--?[a-zA-Z][\w-]*(?=\s*:)/y
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
kind: "function",
|
|
76
|
+
pattern: /[a-zA-Z-]+(?=\()/y
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
kind: "number",
|
|
80
|
+
pattern: /-?\d+(?:\.\d+)?(?:px|rem|em|%|s|ms|vh|vw|fr|deg)?/y
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
kind: "punctuation",
|
|
84
|
+
pattern: /[{}();:,>+~]/y
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
html: [
|
|
88
|
+
{
|
|
89
|
+
kind: "comment",
|
|
90
|
+
pattern: /<!--[\s\S]*?-->/y
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
kind: "string",
|
|
94
|
+
pattern: /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/y
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
kind: "tag",
|
|
98
|
+
pattern: /<\/?[a-zA-Z][\w:-]*/y
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
kind: "attribute",
|
|
102
|
+
pattern: /[a-zA-Z][\w:-]*(?==)/y
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
kind: "punctuation",
|
|
106
|
+
pattern: /\/?>|=/y
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
bash: [
|
|
110
|
+
{
|
|
111
|
+
kind: "comment",
|
|
112
|
+
pattern: /#[^\n]*/y
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
kind: "string",
|
|
116
|
+
pattern: /"(?:[^"\\]|\\.)*"|'[^']*'/y
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
kind: "keyword",
|
|
120
|
+
pattern: /\b(?:if|then|else|elif|fi|for|while|do|done|case|esac|function|return|export|local|source|set|cd|echo)\b/y
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
kind: "property",
|
|
124
|
+
pattern: /\$\{?[A-Za-z_][\w]*\}?/y
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
kind: "attribute",
|
|
128
|
+
pattern: /(?<=\s)--?[a-zA-Z][\w-]*/y
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
kind: "punctuation",
|
|
132
|
+
pattern: /[|&;()<>]/y
|
|
133
|
+
}
|
|
134
|
+
],
|
|
135
|
+
python: [
|
|
136
|
+
{
|
|
137
|
+
kind: "comment",
|
|
138
|
+
pattern: /#[^\n]*/y
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
kind: "string",
|
|
142
|
+
pattern: /"""[\s\S]*?"""|'''[\s\S]*?'''|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/y
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
kind: "keyword",
|
|
146
|
+
pattern: /\b(?: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)\b/y
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
kind: "literal",
|
|
150
|
+
pattern: /\b(?:True|False|None|self)\b/y
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
kind: "number",
|
|
154
|
+
pattern: /\b\d+(?:\.\d+)?\b/y
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
kind: "function",
|
|
158
|
+
pattern: /[A-Za-z_]\w*(?=\()/y
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
kind: "punctuation",
|
|
162
|
+
pattern: /[{}[\]().,:;=+\-*/<>!]/y
|
|
163
|
+
}
|
|
164
|
+
],
|
|
165
|
+
sql: [
|
|
166
|
+
{
|
|
167
|
+
kind: "comment",
|
|
168
|
+
pattern: /--[^\n]*|\/\*[\s\S]*?\*\//y
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
kind: "string",
|
|
172
|
+
pattern: /'(?:[^']|'')*'/y
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
kind: "keyword",
|
|
176
|
+
pattern: /\b(?:select|from|where|insert|into|values|update|set|delete|create|table|alter|drop|index|join|inner|left|right|outer|on|group|by|order|having|limit|offset|as|and|or|not|in|is|null|distinct|union|all|with|returning|primary|key|foreign|references|default)\b/iy
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
kind: "number",
|
|
180
|
+
pattern: /\b\d+(?:\.\d+)?\b/y
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
kind: "punctuation",
|
|
184
|
+
pattern: /[(),;*=<>]/y
|
|
185
|
+
}
|
|
186
|
+
],
|
|
187
|
+
plain: []
|
|
188
|
+
};
|
|
189
|
+
function a(e) {
|
|
190
|
+
let t = [
|
|
191
|
+
{
|
|
192
|
+
kind: "comment",
|
|
193
|
+
pattern: /\/\/[^\n]*|\/\*[\s\S]*?\*\//y
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
kind: "string",
|
|
197
|
+
pattern: /`(?:[^`\\]|\\.)*`|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/y
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
kind: "keyword",
|
|
201
|
+
pattern: RegExp(`\\b(?:${n})\\b`, "y")
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
kind: "literal",
|
|
205
|
+
pattern: RegExp(`\\b(?:${r})\\b`, "y")
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
kind: "number",
|
|
209
|
+
pattern: /\b(?:0[xX][\da-fA-F_]+|\d[\d_]*(?:\.[\d_]+)?(?:[eE][+-]?\d+)?)\b/y
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
kind: "function",
|
|
213
|
+
pattern: /[A-Za-z_$][\w$]*(?=\s*\()/y
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
kind: "punctuation",
|
|
217
|
+
pattern: /[{}[\]().,;:?!=<>+\-*/%&|^~]/y
|
|
218
|
+
}
|
|
219
|
+
];
|
|
220
|
+
return e && t.splice(2, 0, {
|
|
221
|
+
kind: "tag",
|
|
222
|
+
pattern: /<\/?[A-Za-z][\w.]*|\/>/y
|
|
223
|
+
}), t;
|
|
224
|
+
}
|
|
225
|
+
function o(e, n) {
|
|
226
|
+
let r = i[t(n)];
|
|
227
|
+
if (r.length === 0) return e === "" ? [] : [{
|
|
228
|
+
kind: "plain",
|
|
229
|
+
value: e
|
|
230
|
+
}];
|
|
231
|
+
let a = [], o = 0, s = 0, c = (t) => {
|
|
232
|
+
t > o && a.push({
|
|
233
|
+
kind: "plain",
|
|
234
|
+
value: e.slice(o, t)
|
|
235
|
+
});
|
|
236
|
+
};
|
|
237
|
+
for (; s < e.length;) {
|
|
238
|
+
let t = null;
|
|
239
|
+
for (let n of r) {
|
|
240
|
+
n.pattern.lastIndex = s;
|
|
241
|
+
let r = n.pattern.exec(e);
|
|
242
|
+
if (r && r[0].length > 0) {
|
|
243
|
+
t = {
|
|
244
|
+
kind: n.kind,
|
|
245
|
+
value: r[0]
|
|
246
|
+
};
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
t ? (c(s), a.push(t), s += t.value.length, o = s) : s++;
|
|
251
|
+
}
|
|
252
|
+
return c(e.length), a;
|
|
253
|
+
}
|
|
254
|
+
function s(e, t) {
|
|
255
|
+
let n = [[]];
|
|
256
|
+
for (let r of o(e, t)) r.value.split("\n").forEach((e, t) => {
|
|
257
|
+
t > 0 && n.push([]), e !== "" && n[n.length - 1].push({
|
|
258
|
+
kind: r.kind,
|
|
259
|
+
value: e
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
return n;
|
|
263
|
+
}
|
|
264
|
+
//#endregion
|
|
265
|
+
export { t as resolveLanguage, o as tokenize, s as tokenizeLines };
|
|
266
|
+
|
|
267
|
+
//# sourceMappingURL=tokenize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenize.js","names":[],"sources":["../../../src/components/CodeBlock/tokenize.ts"],"sourcesContent":["/** What a token is painted as. */\nexport type TokenKind =\n | \"plain\"\n | \"comment\"\n | \"string\"\n | \"number\"\n | \"keyword\"\n | \"literal\"\n | \"function\"\n | \"punctuation\"\n | \"tag\"\n | \"attribute\"\n | \"property\";\n\nexport interface Token {\n kind: TokenKind;\n value: string;\n}\n\n/** Languages the tokenizer knows. Anything else renders as plain text. */\nexport type CodeLanguage =\n | \"typescript\"\n | \"javascript\"\n | \"tsx\"\n | \"jsx\"\n | \"json\"\n | \"css\"\n | \"html\"\n | \"bash\"\n | \"python\"\n | \"sql\"\n | \"plain\";\n\n/** Aliases people actually type, mapped onto the grammars above. */\nconst ALIASES: Record<string, CodeLanguage> = {\n ts: \"typescript\",\n typescript: \"typescript\",\n js: \"javascript\",\n javascript: \"javascript\",\n mjs: \"javascript\",\n cjs: \"javascript\",\n tsx: \"tsx\",\n jsx: \"jsx\",\n json: \"json\",\n jsonc: \"json\",\n css: \"css\",\n scss: \"css\",\n html: \"html\",\n xml: \"html\",\n svg: \"html\",\n sh: \"bash\",\n bash: \"bash\",\n shell: \"bash\",\n zsh: \"bash\",\n console: \"bash\",\n py: \"python\",\n python: \"python\",\n sql: \"sql\",\n};\n\n/**\n * Normalise a language name onto a known grammar.\n *\n * @param language - Whatever the caller passed, e.g. `\"ts\"` or `\"Shell\"`.\n * @returns The grammar to use; `\"plain\"` when there is no match.\n */\nexport function resolveLanguage(language: string | undefined): CodeLanguage {\n if (!language) return \"plain\";\n return ALIASES[language.toLowerCase()] ?? \"plain\";\n}\n\n/** One grammar rule: a sticky pattern and the kind it produces. */\ninterface Rule {\n kind: TokenKind;\n pattern: RegExp;\n}\n\nconst JS_KEYWORDS =\n \"as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|keyof|let|new|of|private|protected|public|readonly|return|satisfies|set|static|super|switch|this|throw|try|type|typeof|var|void|while|with|yield\";\n\nconst JS_LITERALS = \"true|false|null|undefined|NaN|Infinity\";\n\n/**\n * Rules per grammar, tried in order at each position.\n *\n * Order carries meaning: comments and strings come first so a keyword inside a\n * string stays a string. Every pattern is sticky (`y`) and anchored by\n * `lastIndex`, so a rule can only match where the scanner currently stands.\n */\nconst GRAMMARS: Record<CodeLanguage, Rule[]> = {\n typescript: jsRules(false),\n javascript: jsRules(false),\n tsx: jsRules(true),\n jsx: jsRules(true),\n json: [\n { kind: \"property\", pattern: /\"(?:[^\"\\\\]|\\\\.)*\"(?=\\s*:)/y },\n { kind: \"string\", pattern: /\"(?:[^\"\\\\]|\\\\.)*\"/y },\n { kind: \"number\", pattern: /-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/y },\n { kind: \"literal\", pattern: /\\b(?:true|false|null)\\b/y },\n { kind: \"punctuation\", pattern: /[{}[\\],:]/y },\n ],\n css: [\n { kind: \"comment\", pattern: /\\/\\*[\\s\\S]*?\\*\\//y },\n { kind: \"string\", pattern: /\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/y },\n { kind: \"keyword\", pattern: /@[a-zA-Z-]+/y },\n { kind: \"property\", pattern: /--?[a-zA-Z][\\w-]*(?=\\s*:)/y },\n { kind: \"function\", pattern: /[a-zA-Z-]+(?=\\()/y },\n { kind: \"number\", pattern: /-?\\d+(?:\\.\\d+)?(?:px|rem|em|%|s|ms|vh|vw|fr|deg)?/y },\n { kind: \"punctuation\", pattern: /[{}();:,>+~]/y },\n ],\n html: [\n { kind: \"comment\", pattern: /<!--[\\s\\S]*?-->/y },\n { kind: \"string\", pattern: /\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/y },\n { kind: \"tag\", pattern: /<\\/?[a-zA-Z][\\w:-]*/y },\n { kind: \"attribute\", pattern: /[a-zA-Z][\\w:-]*(?==)/y },\n { kind: \"punctuation\", pattern: /\\/?>|=/y },\n ],\n bash: [\n { kind: \"comment\", pattern: /#[^\\n]*/y },\n { kind: \"string\", pattern: /\"(?:[^\"\\\\]|\\\\.)*\"|'[^']*'/y },\n {\n kind: \"keyword\",\n pattern:\n /\\b(?:if|then|else|elif|fi|for|while|do|done|case|esac|function|return|export|local|source|set|cd|echo)\\b/y,\n },\n { kind: \"property\", pattern: /\\$\\{?[A-Za-z_][\\w]*\\}?/y },\n { kind: \"attribute\", pattern: /(?<=\\s)--?[a-zA-Z][\\w-]*/y },\n { kind: \"punctuation\", pattern: /[|&;()<>]/y },\n ],\n python: [\n { kind: \"comment\", pattern: /#[^\\n]*/y },\n {\n kind: \"string\",\n pattern: /\"\"\"[\\s\\S]*?\"\"\"|'''[\\s\\S]*?'''|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/y,\n },\n {\n kind: \"keyword\",\n pattern:\n /\\b(?: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)\\b/y,\n },\n { kind: \"literal\", pattern: /\\b(?:True|False|None|self)\\b/y },\n { kind: \"number\", pattern: /\\b\\d+(?:\\.\\d+)?\\b/y },\n { kind: \"function\", pattern: /[A-Za-z_]\\w*(?=\\()/y },\n { kind: \"punctuation\", pattern: /[{}[\\]().,:;=+\\-*/<>!]/y },\n ],\n sql: [\n { kind: \"comment\", pattern: /--[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//y },\n { kind: \"string\", pattern: /'(?:[^']|'')*'/y },\n {\n kind: \"keyword\",\n // Case-insensitive: SQL is written both ways and both should paint.\n pattern:\n /\\b(?:select|from|where|insert|into|values|update|set|delete|create|table|alter|drop|index|join|inner|left|right|outer|on|group|by|order|having|limit|offset|as|and|or|not|in|is|null|distinct|union|all|with|returning|primary|key|foreign|references|default)\\b/iy,\n },\n { kind: \"number\", pattern: /\\b\\d+(?:\\.\\d+)?\\b/y },\n { kind: \"punctuation\", pattern: /[(),;*=<>]/y },\n ],\n plain: [],\n};\n\n/** The shared JavaScript-family rules, with JSX tags added for tsx/jsx. */\nfunction jsRules(withJsx: boolean): Rule[] {\n const rules: Rule[] = [\n { kind: \"comment\", pattern: /\\/\\/[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//y },\n {\n kind: \"string\",\n pattern: /`(?:[^`\\\\]|\\\\.)*`|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/y,\n },\n { kind: \"keyword\", pattern: new RegExp(`\\\\b(?:${JS_KEYWORDS})\\\\b`, \"y\") },\n { kind: \"literal\", pattern: new RegExp(`\\\\b(?:${JS_LITERALS})\\\\b`, \"y\") },\n {\n kind: \"number\",\n pattern: /\\b(?:0[xX][\\da-fA-F_]+|\\d[\\d_]*(?:\\.[\\d_]+)?(?:[eE][+-]?\\d+)?)\\b/y,\n },\n { kind: \"function\", pattern: /[A-Za-z_$][\\w$]*(?=\\s*\\()/y },\n { kind: \"punctuation\", pattern: /[{}[\\]().,;:?!=<>+\\-*/%&|^~]/y },\n ];\n if (withJsx) {\n // Before the keyword rule, so `<Button` reads as a tag and not as `<`.\n rules.splice(2, 0, { kind: \"tag\", pattern: /<\\/?[A-Za-z][\\w.]*|\\/>/y });\n }\n return rules;\n}\n\n/**\n * Split source into coloured tokens.\n *\n * This is a **scanner, not a parser**: it recognises comments, strings, numbers,\n * keywords and punctuation by pattern, and knows nothing about scope, types or\n * grammar. That is a deliberate ceiling. A real parser per language is a\n * dependency the size of the rest of the SDK, and the payoff — being right about\n * the corner cases in a documentation snippet — is small. Where it is unsure it\n * emits `plain`, which renders as ordinary text rather than as something wrong.\n *\n * Unknown languages produce a single `plain` token, so an unhighlighted block is\n * a normal outcome and never an error.\n *\n * @param code - The source.\n * @param language - Grammar name or alias.\n * @returns Tokens covering the input exactly, in order.\n *\n * @example\n * tokenize(\"const x = 1;\", \"ts\");\n * // [{kind: \"keyword\", value: \"const\"}, {kind: \"plain\", value: \" x \"}, …]\n */\nexport function tokenize(code: string, language: string | undefined): Token[] {\n const rules = GRAMMARS[resolveLanguage(language)];\n if (rules.length === 0) return code === \"\" ? [] : [{ kind: \"plain\", value: code }];\n\n const tokens: Token[] = [];\n let plainFrom = 0;\n let at = 0;\n\n const flushPlain = (until: number) => {\n if (until > plainFrom) tokens.push({ kind: \"plain\", value: code.slice(plainFrom, until) });\n };\n\n while (at < code.length) {\n let matched: Token | null = null;\n for (const rule of rules) {\n rule.pattern.lastIndex = at;\n const found = rule.pattern.exec(code);\n if (found && found[0].length > 0) {\n matched = { kind: rule.kind, value: found[0] };\n break;\n }\n }\n if (matched) {\n flushPlain(at);\n tokens.push(matched);\n at += matched.value.length;\n plainFrom = at;\n } else {\n at++;\n }\n }\n flushPlain(code.length);\n return tokens;\n}\n\n/**\n * The same tokens, split at newlines so each line can be rendered on its own.\n *\n * Line numbers and highlighted lines both need a per-line structure, and a token\n * is free to span a line break — a block comment usually does. Splitting here\n * keeps that out of the component.\n *\n * @param code - The source.\n * @param language - Grammar name or alias.\n * @returns One token array per line. Always at least one line.\n */\nexport function tokenizeLines(code: string, language: string | undefined): Token[][] {\n const lines: Token[][] = [[]];\n for (const token of tokenize(code, language)) {\n const pieces = token.value.split(\"\\n\");\n pieces.forEach((piece, index) => {\n if (index > 0) lines.push([]);\n if (piece !== \"\") lines[lines.length - 1].push({ kind: token.kind, value: piece });\n });\n }\n return lines;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Navbar.module.cjs","names":[],"sources":["../../../src/components/Navbar/Navbar.module.css"],"sourcesContent":[".navbar {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-4);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n min-height: 56px;\n width: 100%;\n font-family: var(--tempest-font-sans);\n padding-top: max(var(--tempest-space-3), env(safe-area-inset-top, 0));\n}\n\n.navbar.surface {\n background: var(--tempest-surface);\n color: var(--tempest-text);\n}\n\n.navbar.primary {\n background: var(--tempest-primary
|
|
1
|
+
{"version":3,"file":"Navbar.module.cjs","names":[],"sources":["../../../src/components/Navbar/Navbar.module.css"],"sourcesContent":[".navbar {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-4);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n min-height: 56px;\n width: 100%;\n font-family: var(--tempest-font-sans);\n padding-top: max(var(--tempest-space-3), env(safe-area-inset-top, 0));\n}\n\n.navbar.surface {\n background: var(--tempest-surface);\n color: var(--tempest-text);\n}\n\n.navbar.primary {\n background: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n}\n\n.navbar.transparent {\n background: transparent;\n color: inherit;\n}\n\n.navbar.bordered {\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.navbar.sticky {\n position: sticky;\n top: 0;\n z-index: 30;\n backdrop-filter: saturate(180%) blur(8px);\n}\n\n.logo {\n display: inline-flex;\n align-items: center;\n flex: 0 0 auto;\n}\n\n.nav {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n flex: 1 1 auto;\n min-width: 0;\n overflow-x: auto;\n}\n\n.actions {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n flex: 0 0 auto;\n margin-left: auto;\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Navbar.module.js","names":[],"sources":["../../../src/components/Navbar/Navbar.module.css"],"sourcesContent":[".navbar {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-4);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n min-height: 56px;\n width: 100%;\n font-family: var(--tempest-font-sans);\n padding-top: max(var(--tempest-space-3), env(safe-area-inset-top, 0));\n}\n\n.navbar.surface {\n background: var(--tempest-surface);\n color: var(--tempest-text);\n}\n\n.navbar.primary {\n background: var(--tempest-primary
|
|
1
|
+
{"version":3,"file":"Navbar.module.js","names":[],"sources":["../../../src/components/Navbar/Navbar.module.css"],"sourcesContent":[".navbar {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-4);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n min-height: 56px;\n width: 100%;\n font-family: var(--tempest-font-sans);\n padding-top: max(var(--tempest-space-3), env(safe-area-inset-top, 0));\n}\n\n.navbar.surface {\n background: var(--tempest-surface);\n color: var(--tempest-text);\n}\n\n.navbar.primary {\n background: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n}\n\n.navbar.transparent {\n background: transparent;\n color: inherit;\n}\n\n.navbar.bordered {\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.navbar.sticky {\n position: sticky;\n top: 0;\n z-index: 30;\n backdrop-filter: saturate(180%) blur(8px);\n}\n\n.logo {\n display: inline-flex;\n align-items: center;\n flex: 0 0 auto;\n}\n\n.nav {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n flex: 1 1 auto;\n min-width: 0;\n overflow-x: auto;\n}\n\n.actions {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n flex: 0 0 auto;\n margin-left: auto;\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../../utils/cn.cjs"),t=require("./qr-encode.cjs"),n=require("./QRCode.module.cjs");let r=require("react"),i=require("react/jsx-runtime");function a({value:a,size:o=160,level:s=`M`,margin:c=4,color:l=`#000000`,background:u=`#ffffff`,label:d,className:f,style:p,...m}){let{path:h,side:g}=(0,r.useMemo)(()=>{let e=t.encodeQR(a,{level:s});return{path:t.matrixToPath(e,c),side:e.size+c*2}},[a,s,c]);return(0,i.jsx)(`div`,{className:e.cn(n.default.wrapper,f),style:{width:o,height:o,...p},...m,children:(0,i.jsxs)(`svg`,{className:n.default.svg,viewBox:`0 0 ${g} ${g}`,width:o,height:o,role:`img`,"aria-label":d??`QR code: ${a}`,shapeRendering:`crispEdges`,children:[(0,i.jsx)(`rect`,{width:g,height:g,fill:u}),(0,i.jsx)(`path`,{d:h,fill:l})]})})}exports.QRCode=a;
|
|
2
|
+
//# sourceMappingURL=QRCode.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QRCode.cjs","names":[],"sources":["../../../src/components/QRCode/QRCode.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nimport { encodeQR, matrixToPath } from \"./qr-encode\";\nimport type { QRErrorCorrection } from \"./qr-encode\";\nimport styles from \"./QRCode.module.css\";\n\nexport interface QRCodeProps extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /** The payload. Encoded as UTF-8 when it is not plain digits or upper-case text. */\n value: string;\n /** Rendered side in px, quiet zone included. Default `160`. */\n size?: number;\n /** Error correction level. Default `\"M\"`. */\n level?: QRErrorCorrection;\n /** Quiet zone in modules. The standard asks for 4; below that, scanners start to miss. */\n margin?: number;\n /** Module colour. Defaults to black — see the note on dark mode below. */\n color?: string;\n /** Background colour. Defaults to white. */\n background?: string;\n /**\n * Accessible name. Defaults to naming the payload, because a screen reader\n * user cannot scan the symbol: the content has to reach them as text.\n */\n label?: string;\n}\n\n/**\n * A QR symbol, encoded in the browser and drawn as SVG.\n *\n * No dependency and no network round trip: an image service would leak the\n * payload — a payment link, a session token, an invite — to a third party, and\n * the encoder is a few kilobytes.\n *\n * SVG rather than canvas so the symbol stays sharp at any size and prints at\n * the printer's resolution instead of the screen's. Everything is one path\n * (horizontal runs merged), because a version-10 symbol is 3 481 modules and\n * that many elements costs real paint time.\n *\n * The colours are **black on white in both themes, on purpose** — they are the\n * one part of the SDK that ignores the theme tokens. Scanners expect\n * dark-on-light, and the ones that cope with an inverted symbol do it slowly and\n * unreliably; a QR that looks integrated with a dark page and scans on the third\n * try is worse than one that looks pasted on. Wiring the modules to\n * `--tempest-text` would flip them light in dark mode and leave a light symbol\n * on the white background, which scans as nothing at all. Override\n * `color`/`background` only with a scanner in hand.\n *\n * @throws {QRCapacityError} When the payload is too long for a version-40\n * symbol at the chosen level. That is a programming error rather than a state\n * to render, so it surfaces instead of silently drawing nothing — wrap it in\n * `ErrorBoundary` if the payload comes from user input.\n *\n * @example\n * <QRCode value=\"https://tempest.dev\" />\n * <QRCode value={pixPayload} level=\"H\" size={220} label=\"QR do Pix\" />\n */\nexport function QRCode({\n value,\n size = 160,\n level = \"M\",\n margin = 4,\n color = \"#000000\",\n background = \"#ffffff\",\n label,\n className,\n style,\n ...rest\n}: QRCodeProps) {\n const { path, side } = useMemo(() => {\n const matrix = encodeQR(value, { level });\n return {\n path: matrixToPath(matrix, margin),\n side: matrix.size + margin * 2,\n };\n }, [value, level, margin]);\n\n return (\n <div\n className={cn(styles.wrapper, className)}\n style={{ width: size, height: size, ...style }}\n {...rest}\n >\n <svg\n className={styles.svg}\n viewBox={`0 0 ${side} ${side}`}\n width={size}\n height={size}\n role=\"img\"\n aria-label={label ?? `QR code: ${value}`}\n shapeRendering=\"crispEdges\"\n >\n <rect width={side} height={side} fill={background} />\n <path d={path} fill={color} />\n </svg>\n </div>\n );\n}\n"],"mappings":"0JA2DA,SAAgB,EAAO,CACnB,QACA,OAAO,IACP,QAAQ,IACR,SAAS,EACT,QAAQ,UACR,aAAa,UACb,QACA,YACA,QACA,GAAG,GACS,CACZ,GAAM,CAAE,OAAM,SAAA,EAAA,EAAA,QAAA,KAAuB,CACjC,IAAM,EAAS,EAAA,SAAS,EAAO,CAAE,OAAM,CAAC,EACxC,MAAO,CACH,KAAM,EAAA,aAAa,EAAQ,CAAM,EACjC,KAAM,EAAO,KAAO,EAAS,CACjC,CACJ,EAAG,CAAC,EAAO,EAAO,CAAM,CAAC,EAEzB,OACI,EAAA,EAAA,IAAA,CAAC,MAAD,CACI,UAAW,EAAA,GAAG,EAAA,QAAO,QAAS,CAAS,EACvC,MAAO,CAAE,MAAO,EAAM,OAAQ,EAAM,GAAG,CAAM,EAC7C,GAAI,YAEJ,EAAA,EAAA,KAAA,CAAC,MAAD,CACI,UAAW,EAAA,QAAO,IAClB,QAAS,OAAO,EAAK,GAAG,IACxB,MAAO,EACP,OAAQ,EACR,KAAK,MACL,aAAY,GAAS,YAAY,IACjC,eAAe,sBAPnB,EASI,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,MAAO,EAAM,OAAQ,EAAM,KAAM,CAAa,CAAA,GACpD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAG,EAAM,KAAM,CAAQ,CAAA,CAC5B,GACJ,CAAA,CAEb"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { cn as e } from "../../utils/cn.js";
|
|
2
|
+
import { encodeQR as t, matrixToPath as n } from "./qr-encode.js";
|
|
3
|
+
import r from "./QRCode.module.js";
|
|
4
|
+
import { useMemo as i } from "react";
|
|
5
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/QRCode/QRCode.tsx
|
|
7
|
+
function s({ value: s, size: c = 160, level: l = "M", margin: u = 4, color: d = "#000000", background: f = "#ffffff", label: p, className: m, style: h, ...g }) {
|
|
8
|
+
let { path: _, side: v } = i(() => {
|
|
9
|
+
let e = t(s, { level: l });
|
|
10
|
+
return {
|
|
11
|
+
path: n(e, u),
|
|
12
|
+
side: e.size + u * 2
|
|
13
|
+
};
|
|
14
|
+
}, [
|
|
15
|
+
s,
|
|
16
|
+
l,
|
|
17
|
+
u
|
|
18
|
+
]);
|
|
19
|
+
return /* @__PURE__ */ a("div", {
|
|
20
|
+
className: e(r.wrapper, m),
|
|
21
|
+
style: {
|
|
22
|
+
width: c,
|
|
23
|
+
height: c,
|
|
24
|
+
...h
|
|
25
|
+
},
|
|
26
|
+
...g,
|
|
27
|
+
children: /* @__PURE__ */ o("svg", {
|
|
28
|
+
className: r.svg,
|
|
29
|
+
viewBox: `0 0 ${v} ${v}`,
|
|
30
|
+
width: c,
|
|
31
|
+
height: c,
|
|
32
|
+
role: "img",
|
|
33
|
+
"aria-label": p ?? `QR code: ${s}`,
|
|
34
|
+
shapeRendering: "crispEdges",
|
|
35
|
+
children: [/* @__PURE__ */ a("rect", {
|
|
36
|
+
width: v,
|
|
37
|
+
height: v,
|
|
38
|
+
fill: f
|
|
39
|
+
}), /* @__PURE__ */ a("path", {
|
|
40
|
+
d: _,
|
|
41
|
+
fill: d
|
|
42
|
+
})]
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { s as QRCode };
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=QRCode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QRCode.js","names":[],"sources":["../../../src/components/QRCode/QRCode.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nimport { encodeQR, matrixToPath } from \"./qr-encode\";\nimport type { QRErrorCorrection } from \"./qr-encode\";\nimport styles from \"./QRCode.module.css\";\n\nexport interface QRCodeProps extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /** The payload. Encoded as UTF-8 when it is not plain digits or upper-case text. */\n value: string;\n /** Rendered side in px, quiet zone included. Default `160`. */\n size?: number;\n /** Error correction level. Default `\"M\"`. */\n level?: QRErrorCorrection;\n /** Quiet zone in modules. The standard asks for 4; below that, scanners start to miss. */\n margin?: number;\n /** Module colour. Defaults to black — see the note on dark mode below. */\n color?: string;\n /** Background colour. Defaults to white. */\n background?: string;\n /**\n * Accessible name. Defaults to naming the payload, because a screen reader\n * user cannot scan the symbol: the content has to reach them as text.\n */\n label?: string;\n}\n\n/**\n * A QR symbol, encoded in the browser and drawn as SVG.\n *\n * No dependency and no network round trip: an image service would leak the\n * payload — a payment link, a session token, an invite — to a third party, and\n * the encoder is a few kilobytes.\n *\n * SVG rather than canvas so the symbol stays sharp at any size and prints at\n * the printer's resolution instead of the screen's. Everything is one path\n * (horizontal runs merged), because a version-10 symbol is 3 481 modules and\n * that many elements costs real paint time.\n *\n * The colours are **black on white in both themes, on purpose** — they are the\n * one part of the SDK that ignores the theme tokens. Scanners expect\n * dark-on-light, and the ones that cope with an inverted symbol do it slowly and\n * unreliably; a QR that looks integrated with a dark page and scans on the third\n * try is worse than one that looks pasted on. Wiring the modules to\n * `--tempest-text` would flip them light in dark mode and leave a light symbol\n * on the white background, which scans as nothing at all. Override\n * `color`/`background` only with a scanner in hand.\n *\n * @throws {QRCapacityError} When the payload is too long for a version-40\n * symbol at the chosen level. That is a programming error rather than a state\n * to render, so it surfaces instead of silently drawing nothing — wrap it in\n * `ErrorBoundary` if the payload comes from user input.\n *\n * @example\n * <QRCode value=\"https://tempest.dev\" />\n * <QRCode value={pixPayload} level=\"H\" size={220} label=\"QR do Pix\" />\n */\nexport function QRCode({\n value,\n size = 160,\n level = \"M\",\n margin = 4,\n color = \"#000000\",\n background = \"#ffffff\",\n label,\n className,\n style,\n ...rest\n}: QRCodeProps) {\n const { path, side } = useMemo(() => {\n const matrix = encodeQR(value, { level });\n return {\n path: matrixToPath(matrix, margin),\n side: matrix.size + margin * 2,\n };\n }, [value, level, margin]);\n\n return (\n <div\n className={cn(styles.wrapper, className)}\n style={{ width: size, height: size, ...style }}\n {...rest}\n >\n <svg\n className={styles.svg}\n viewBox={`0 0 ${side} ${side}`}\n width={size}\n height={size}\n role=\"img\"\n aria-label={label ?? `QR code: ${value}`}\n shapeRendering=\"crispEdges\"\n >\n <rect width={side} height={side} fill={background} />\n <path d={path} fill={color} />\n </svg>\n </div>\n );\n}\n"],"mappings":";;;;;;AA2DA,SAAgB,EAAO,EACnB,UACA,UAAO,KACP,WAAQ,KACR,YAAS,GACT,WAAQ,WACR,gBAAa,WACb,UACA,cACA,UACA,GAAG,KACS;CACZ,IAAM,EAAE,SAAM,YAAS,QAAc;EACjC,IAAM,IAAS,EAAS,GAAO,EAAE,SAAM,CAAC;EACxC,OAAO;GACH,MAAM,EAAa,GAAQ,CAAM;GACjC,MAAM,EAAO,OAAO,IAAS;EACjC;CACJ,GAAG;EAAC;EAAO;EAAO;CAAM,CAAC;CAEzB,OACI,kBAAC,OAAD;EACI,WAAW,EAAG,EAAO,SAAS,CAAS;EACvC,OAAO;GAAE,OAAO;GAAM,QAAQ;GAAM,GAAG;EAAM;EAC7C,GAAI;YAEJ,kBAAC,OAAD;GACI,WAAW,EAAO;GAClB,SAAS,OAAO,EAAK,GAAG;GACxB,OAAO;GACP,QAAQ;GACR,MAAK;GACL,cAAY,KAAS,YAAY;GACjC,gBAAe;aAPnB,CASI,kBAAC,QAAD;IAAM,OAAO;IAAM,QAAQ;IAAM,MAAM;GAAa,CAAA,GACpD,kBAAC,QAAD;IAAM,GAAG;IAAM,MAAM;GAAQ,CAAA,CAC5B;;CACJ,CAAA;AAEb"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QRCode.module.cjs","names":[],"sources":["../../../src/components/QRCode/QRCode.module.css"],"sourcesContent":[".wrapper {\n display: inline-block;\n line-height: 0;\n border-radius: var(--tempest-radius-md);\n overflow: hidden;\n}\n\n.svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n"],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QRCode.module.js","names":[],"sources":["../../../src/components/QRCode/QRCode.module.css"],"sourcesContent":[".wrapper {\n display: inline-block;\n line-height: 0;\n border-radius: var(--tempest-radius-md);\n overflow: hidden;\n}\n\n.svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./qr-tables.cjs");var t=class extends Error{length;level;constructor(e,t){super(`Payload of ${e} bytes does not fit in a version-40 QR symbol at level ${t}. Shorten the data, or drop to a lower correction level.`),this.length=e,this.level=t,this.name=`QRCapacityError`}},n={numeric:1,alphanumeric:2,byte:4},r=/^[0-9]*$/,i=/^[0-9A-Z $%*+\-./:]*$/;function a(e){return r.test(e)?`numeric`:i.test(e)?`alphanumeric`:`byte`}function o(e,t){let n=t<=9?0:t<=26?1:2;return e===`numeric`?[10,12,14][n]:e===`alphanumeric`?[9,11,13][n]:[8,16,16][n]}var s=class{bits=[];append(e,t){for(let n=t-1;n>=0;n--)this.bits.push(e>>>n&1)}get length(){return this.bits.length}};function c(e){return Array.from(new TextEncoder().encode(e))}function l(e,t){if(t===`numeric`){let t=Math.floor(e.length/3),n=e.length%3;return t*10+(n===0?0:n===1?4:7)}return t===`alphanumeric`?Math.floor(e.length/2)*11+e.length%2*6:c(e).length*8}function u(t,n,r){if(r===`numeric`){for(let e=0;e<n.length;e+=3){let r=n.slice(e,e+3);t.append(Number(r),r.length*3+1)}return}if(r===`alphanumeric`){for(let r=0;r<n.length;r+=2){let i=e.ALPHANUMERIC_CHARS.indexOf(n[r]);r+1===n.length?t.append(i,6):t.append(i*45+e.ALPHANUMERIC_CHARS.indexOf(n[r+1]),11)}return}for(let e of c(n))t.append(e,8)}function d(e,t){return t===`byte`?c(e).length:e.length}function f(n,r,i,a){let s=l(n,r);for(let t=Math.max(1,a);t<=40;t++){let n=e.dataCodewords(t,i)*8;if(4+o(r,t)+s<=n)return t}throw new t(d(n,r),i)}var p=new Uint8Array(512),m=new Uint8Array(256);{let e=1;for(let t=0;t<255;t++)p[t]=e,m[e]=t,e=e<<1^(e&128?285:0);for(let e=255;e<512;e++)p[e]=p[e-255]}function h(e,t){return e===0||t===0?0:p[m[e]+m[t]]}function g(e){let t=[1];for(let n=0;n<e;n++){let e=Array(t.length+1).fill(0);for(let r=0;r<t.length;r++)e[r]^=t[r],e[r+1]^=h(t[r],p[n]);t=e}return t}function _(e,t){let n=g(t),r=Array(t).fill(0);for(let i of e){let e=i^r[0];r.shift(),r.push(0);for(let i=0;i<t;i++)r[i]^=h(n[i+1],e)}return r}function v(t,n,r){let i=e.ECC_BLOCK_COUNT[r][n-1],a=e.ECC_CODEWORDS_PER_BLOCK[r][n-1],o=Math.floor(e.rawDataModules(n)/8),s=Math.floor(o/i)-a,c=o%i,l=[],u=[],d=0;for(let e=0;e<i;e++){let n=s+ +(e>=i-c),r=t.slice(d,d+n);d+=n,l.push(r),u.push(_(r,a))}let f=[];for(let e=0;e<s+1;e++)for(let t of l)e<t.length&&f.push(t[e]);for(let e=0;e<a;e++)for(let t of u)f.push(t[e]);return f}function y(e){let t=e*4+17;return{size:t,modules:Array.from({length:t},()=>Array(t).fill(!1)),reserved:Array.from({length:t},()=>Array(t).fill(!1))}}function b(e,t,n,r,i=!0){t<0||n<0||t>=e.size||n>=e.size||(e.modules[n][t]=r,i&&(e.reserved[n][t]=!0))}function x(e,t,n){for(let r=-1;r<=7;r++)for(let i=-1;i<=7;i++){let a=Math.max(Math.abs(i-3),Math.abs(r-3));b(e,t+i,n+r,a!==2&&a<=3)}}function S(e,t,n){for(let r=-2;r<=2;r++)for(let i=-2;i<=2;i++)b(e,t+i,n+r,Math.max(Math.abs(i),Math.abs(r))!==1)}function C(t,n){x(t,0,0),x(t,t.size-7,0),x(t,0,t.size-7);for(let e=8;e<t.size-8;e++){let n=e%2==0;b(t,e,6,n),b(t,6,e,n)}let r=e.alignmentPatternPositions(n);for(let e of r)for(let n of r)n===6&&e===6||n===6&&e===t.size-7||n===t.size-7&&e===6||S(t,n,e);for(let e=0;e<9;e++)b(t,e,8,!1),b(t,8,e,!1);for(let e=0;e<8;e++)b(t,t.size-1-e,8,!1),b(t,8,t.size-1-e,!1);if(b(t,8,t.size-8,!0),n>=7){let e=w(n);for(let n=0;n<18;n++){let r=(e>>>n&1)==1,i=t.size-11+n%3,a=Math.floor(n/3);b(t,i,a,r),b(t,a,i,r)}}}function w(e){let t=e;for(let e=0;e<12;e++)t=t<<1^(t>>>11)*7973;return e<<12|t}function T(t,n){let r=e.ECC_FORMAT_BITS[t]<<3|n,i=r;for(let e=0;e<10;e++)i=i<<1^(i>>>9)*1335;return(r<<10|i)^21522}function E(e,t,n){let r=T(t,n);for(let t=0;t<=5;t++)b(e,8,t,(r>>>t&1)==1);b(e,8,7,(r>>>6&1)==1),b(e,8,8,(r>>>7&1)==1),b(e,7,8,(r>>>8&1)==1);for(let t=9;t<15;t++)b(e,14-t,8,(r>>>t&1)==1);for(let t=0;t<8;t++)b(e,e.size-1-t,8,(r>>>t&1)==1);for(let t=8;t<15;t++)b(e,8,e.size-15+t,(r>>>t&1)==1);b(e,8,e.size-8,!0)}function D(e,t){let n=0,r=!0;for(let i=e.size-1;i>=1;i-=2){i===6&&(i=5);for(let a=0;a<e.size;a++){let o=r?e.size-1-a:a;for(let r=0;r<2;r++){let a=i-r;if(e.reserved[o][a])continue;let s=t[n>>>3];e.modules[o][a]=s!==void 0&&(s>>>7-(n&7)&1)==1,n++}}r=!r}}var O=[(e,t)=>(e+t)%2==0,(e,t)=>t%2==0,e=>e%3==0,(e,t)=>(e+t)%3==0,(e,t)=>(Math.floor(t/2)+Math.floor(e/3))%2==0,(e,t)=>e*t%2+e*t%3==0,(e,t)=>(e*t%2+e*t%3)%2==0,(e,t)=>((e+t)%2+e*t%3)%2==0];function k(e,t){let n=O[t];for(let t=0;t<e.size;t++)for(let r=0;r<e.size;r++)!e.reserved[t][r]&&n(r,t)&&(e.modules[t][r]=!e.modules[t][r])}function A(e){let{size:t,modules:n}=e,r=0,i=e=>e>=5?3+(e-5):0;for(let e=0;e<t;e++){let a=1;for(let o=1;o<t;o++)n[e][o]===n[e][o-1]?a++:(r+=i(a),a=1);r+=i(a)}for(let e=0;e<t;e++){let a=1;for(let o=1;o<t;o++)n[o][e]===n[o-1][e]?a++:(r+=i(a),a=1);r+=i(a)}for(let e=0;e<t-1;e++)for(let i=0;i<t-1;i++){let t=n[e][i];t===n[e][i+1]&&t===n[e+1][i]&&t===n[e+1][i+1]&&(r+=3)}let a=[!0,!1,!0,!0,!0,!1,!0],o=(e,t)=>{for(let n=0;n<a.length;n++)if(e[t+n]!==a[n])return!1;let n=e.slice(Math.max(0,t-4),t),r=e.slice(t+7,t+11),i=e=>e.length===4&&e.every(e=>!e);return i(n)||i(r)};for(let e=0;e<t;e++){let i=n[e],a=n.map(t=>t[e]);for(let e=0;e+7<=t;e++)o(i,e)&&(r+=40),o(a,e)&&(r+=40)}let s=0;for(let e of n)for(let t of e)t&&s++;let c=s*100/(t*t);return r+=Math.floor(Math.abs(c-50)/5)*10,r}function j(e){return{size:e.size,modules:e.modules.map(e=>[...e]),reserved:e.reserved.map(e=>[...e])}}function M(t,r={}){let{level:i=`M`,minVersion:c=1}=r,l=a(t),p=f(t,l,i,c),m=new s;m.append(n[l],4),m.append(d(t,l),o(l,p)),u(m,t,l);let h=e.dataCodewords(p,i)*8;m.append(0,Math.min(4,h-m.length)),m.append(0,(8-m.length%8)%8);let g=[];for(let e=0;e<m.length;e+=8){let t=0;for(let n=0;n<8;n++)t=t<<1|m.bits[e+n];g.push(t)}for(let e=236;g.length<h/8;e^=253)g.push(e);let _=v(g,p,i),b=y(p);C(b,p),D(b,_);let x=null,S=0,w=1/0;for(let e=0;e<8;e++){let t=j(b);k(t,e),E(t,i,e);let n=A(t);n<w&&(w=n,S=e,x=t)}let T=x;return{size:T.size,modules:T.modules,version:p,level:i,mode:l,mask:S}}function N(e,t=4){let n=[];for(let r=0;r<e.size;r++){let i=-1;for(let a=0;a<=e.size;a++){let o=a<e.size&&e.modules[r][a];o&&i===-1&&(i=a),!o&&i!==-1&&(n.push(`M${i+t} ${r+t}h${a-i}v1h-${a-i}z`),i=-1)}}return n.join(``)}exports.QRCapacityError=t,exports.encodeQR=M,exports.matrixToPath=N,exports.reedSolomon=_,exports.selectMode=a;
|
|
2
|
+
//# sourceMappingURL=qr-encode.cjs.map
|