Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9c9ddb4
fix: layer flag bit 2
arbaev May 13, 2026
a1bd4de
refactor: `arraybufferPlugin` rewritten to use `resolveId`
arbaev May 13, 2026
05db6be
chore: `demo/vite.config.ts` aliases
arbaev May 13, 2026
7cfa3ee
fix: architectural dimension fractions now honor `DIMDEC`
arbaev May 13, 2026
b0ce1ee
fix: entities inside a block now inherit the parent INSERT's effectiv…
arbaev May 13, 2026
15be390
fix: HATCH solid fills with elliptic-arc boundary edges
arbaev May 13, 2026
528b2a9
fix: DIMCLRT (DIMSTYLE-level dimension text color)
arbaev May 13, 2026
0053ed3
fix: dimension labels now honor `DIMDEC` & `$DIMADEC`
arbaev May 13, 2026
b4cca19
fix: short dimensions now flip arrows outward
arbaev May 13, 2026
3075b47
feat: MTEXT now supports inline scoped formatting
arbaev May 14, 2026
0c1e315
feat: MTEXT now support inline `\W<n>;` and `\Q<n>;`
arbaev May 14, 2026
b54396a
fix: outside arrow tail
arbaev May 14, 2026
0d07d17
fix: DIMSTYLE `DIMCLRD` (code 176) and `DIMCLRE` (code 177)
arbaev May 14, 2026
81050a7
fix: correct render TEXT/MTEXT/ATTRIB/ATTDEF with `styleName`
arbaev May 14, 2026
1566ab5
fix: DIMCLRT now applies to specialized dimension types
arbaev May 14, 2026
46e661d
feat: radial dimensions state-machine
arbaev May 14, 2026
a1cbb56
fix: `DIMTIH` and `DIMTOH` are now read only from the DIMSTYLE record
arbaev May 14, 2026
defaf11
fix: diametric dimensions with off-segment text now honor DIMTOH
arbaev May 14, 2026
afe2a55
fix: outside arrow tail for radial dims
arbaev May 14, 2026
1c5d253
feat: REGION entities support
arbaev May 14, 2026
53fc3f7
fix: MULTILEADER entities
arbaev May 15, 2026
51c2d11
fix: MULTILEADER line and text colors
arbaev May 15, 2026
24dfdbf
feat: support for the standard arrowhead blocks
arbaev May 15, 2026
a7e549d
fix: render DIMENSION with a pre-rendered associated block first
arbaev May 15, 2026
de7c29a
fix: render order
arbaev May 15, 2026
26a54ee
fix: wide LWPOLYLINE / POLYLINE inside a scaled INSERT
arbaev May 15, 2026
2c6bdd2
fix: nested DIMENSIONs
arbaev May 16, 2026
6bd8777
fix: wide LWPOLYLINE / POLYLINE with a width discontinuity at a vertex
arbaev May 16, 2026
602ecf1
feat: support `STYLE.widthFactor` (DXF code 41)
arbaev May 16, 2026
b771f71
fix: ATTRIB and ATTDEF aligned correctly
arbaev May 16, 2026
dbbf8db
feat: `parseDxf` now rejects AutoCAD Binary DXF files correctly
arbaev May 16, 2026
fd12f21
docs: release 1.6.0
arbaev May 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,12 @@ async function loadFile(file) {

## Features

- **21 DXF entity types** — LINE, CIRCLE, ARC, ELLIPSE, SPLINE, POLYLINE, LWPOLYLINE, TEXT, MTEXT, DIMENSION, HATCH, INSERT, SOLID, 3DFACE, LEADER, MULTILEADER, MLINE, XLINE, RAY, ATTDEF, HELIX, plus ATTRIB within blocks
- **22 DXF entity types** — LINE, CIRCLE, ARC, ELLIPSE, SPLINE, POLYLINE, LWPOLYLINE, TEXT, MTEXT, DIMENSION, HATCH, INSERT, SOLID, 3DFACE, LEADER, MULTILEADER, MLINE, XLINE, RAY, ATTDEF, HELIX, REGION (contour via HATCH boundary), plus ATTRIB within blocks
- **Variable-width polylines** — per-vertex `startWidth`/`endWidth` tapering, constant-width, arrows, donuts rendered as mesh geometry with miter joins
- **Standard arrowhead blocks** — DIMENSION endpoints and LEADER tips honour DIMBLK / DIMLDRBLK; all 18 stock AutoCAD blocks rendered with the correct shape (`_ClosedFilled`, `_Open*`, `_Dot*`, `_Origin*`, `_Box*`, `_Datum*`, `_ArchTick`, `_Integral`, `_None`, …)
- **Linetype rendering** — DASHED, HIDDEN, CENTER, PHANTOM, DOT, DASHDOT with LTSCALE support
- **Hatch patterns** — 25 built-in AutoCAD patterns with multi-boundary clipping
- **Vector text** — crisp at any zoom; Liberation Sans/Serif fonts; bold, italic, underline, MTEXT formatting
- **Vector text** — crisp at any zoom; Liberation Sans/Serif fonts; bold, italic, underline, overline, strikethrough; MTEXT inline scoped formatting (color/font/size/decoration inside `{…}` groups)
- **Picking & associations** — bbox-based raycast, hover/click events, semantic links derived from DXF (LEADER↔TEXT, INSERT+ATTRIB, MLEADER, DIMENSION)
- **Search APIs** — `findEntitiesByText` / `findEntitiesByLayer` / `findEntitiesByType`, paired with `viewer.zoomToEntity` / `zoomToLayer` for find-and-focus UX
- **Dark theme** — instant switching
Expand Down
4 changes: 2 additions & 2 deletions demo/components/StatsSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ interface Stat {
}

const stats: Stat[] = [
{ value: 21, label: "entity types", sub: "LINE · ARC · SPLINE · HATCH · INSERT · MTEXT · …" },
{ value: 945, label: "tests", sub: "100% green CI on every push" },
{ value: 22, label: "entity types", sub: "LINE · ARC · SPLINE · HATCH · INSERT · MTEXT · REGION · …" },
{ value: 1141, label: "tests", sub: "100% green CI on every push" },
{ value: 25, label: "hatch patterns", sub: "ANSI31 · ANSI32 · ANSI33 · GRASS · NET · …" },
{ value: 7, label: "dimension types", sub: "linear · aligned · radial · diametric · angular · ordinate · 3-pt" },
{ value: 6, label: "AA modes", sub: "MSAA · SMAA · FXAA · TAA · SSAA · none" },
Expand Down
16 changes: 13 additions & 3 deletions demo/components/WhatsNewSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,19 @@ interface WhatsNewItem {

const whatsNew: WhatsNewItem[] = [
{
pkg: "dxf-vuer",
version: "2.6.0",
text: "Keyboard navigation — arrow keys pan, +/- zoom, 0 resets the view; canvas is now focusable and respects form fields",
pkg: "dxf-render",
version: "1.6.0",
text: "REGION entities now render their contour by borrowing the boundary edges of any HATCH that references them as a source object (DXF codes 97/330) — no ACIS decoding needed. The REGION becomes pickable too, so hatched details with a REGION outline (common in AutoCAD-built profile drawings) finally show their visible boundary and fire entity-hover / entity-click events.",
},
{
pkg: "dxf-render",
version: "1.6.0",
text: "Standard AutoCAD arrowhead blocks at DIMENSION endpoints and on LEADER / MULTILEADER tips — all 18 names now supported: filled / blank dots, ticks, boxes, origin rings, integral, open arrows at 30° / 90°, datum, and none. Previously only ticks were recognised; everything else collapsed to a default triangle.",
},
{
pkg: "dxf-render",
version: "1.6.0",
text: "MTEXT inline scoped formatting — \\C, \\H, \\f, \\L\\l, \\O\\o, \\K\\k inside brace groups {…} now apply only to that scope and revert on the closing brace. Each line is a list of MTextRun segments with per-run color / height / bold / italic / font / underline / overline / strikethrough. \\W<n>; (width factor) and \\Q<n>; (obliquing angle) are now honored too.",
},
{
pkg: "dxf-vuer",
Expand Down
59 changes: 43 additions & 16 deletions demo/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,51 @@
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
import { arraybufferPlugin } from "../packages/dxf-render/vite-plugins/arraybuffer";

export default defineConfig({
plugins: [vue()],
publicDir: path.resolve(__dirname, "../public"),
server: {
port: 5173,
open: true,
},
build: {
outDir: path.resolve(__dirname, "../dist-demo"),
emptyOutDir: true,
sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
three: ["three", "three/addons/curves/NURBSCurve.js"],
// In dev (`pnpm dev`), resolve dxf-vuer/dxf-render to their source files
// instead of the pre-built dist bundles. Without these aliases, changes
// inside packages/*/src require a full `pnpm build` before they show up
// in the demo; with them, Vite's HMR picks up edits directly.
// Production builds (`pnpm build:demo`) skip the aliases and import dist
// — matching what end users get.
// The arraybufferPlugin is also dev-only: dxf-render's source imports
// fonts via `?arraybuffer`, which is a custom suffix defined by that
// plugin. Without it the .ttf files import as something opentype.js
// can't parse ("buffer is not an object").
export default defineConfig(({ command }) => {
const useSourceAliases = command === "serve";
return {
plugins: useSourceAliases ? [vue(), arraybufferPlugin()] : [vue()],
publicDir: path.resolve(__dirname, "../public"),
resolve: {
alias: useSourceAliases
? {
"dxf-vuer/style.css": path.resolve(__dirname, "../packages/dxf-vuer/src/styles.css"),
"dxf-vuer": path.resolve(__dirname, "../packages/dxf-vuer/src/index.ts"),
"dxf-render": path.resolve(__dirname, "../packages/dxf-render/src/index.ts"),
// dxf-render's source files use the "@/" alias to refer to their
// own ./src — reproduce it here so Vite can follow those imports.
// dxf-vuer's source doesn't use "@/", so no conflict.
"@/": path.resolve(__dirname, "../packages/dxf-render/src") + "/",
}
: {},
},
server: {
port: 5173,
open: true,
},
build: {
outDir: path.resolve(__dirname, "../dist-demo"),
emptyOutDir: true,
sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
three: ["three", "three/addons/curves/NURBSCurve.js"],
},
},
},
},
},
};
});
48 changes: 48 additions & 0 deletions packages/dxf-render/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,53 @@
# Changelog

## 1.6.0

### Features

- **Standard AutoCAD arrowhead blocks** — full support for all 18 standard names at DIMENSION endpoints and on LEADER/MULTILEADER tips: `_ClosedFilled` (default), `_Closed` / `_ClosedBlank`, `_Open` / `_Open30` / `_OpenArrow`, `_DatumFilled` / `_DatumBlank`, `_ArchTick`, `_Oblique`, `_Small`, `_Tick`, `_Dot` / `_DotSmall` / `_DotBlank` / `_DotSmallBlank`, `_Origin` / `_Origin2`, `_Box` / `_BoxFilled`, `_Integral`, `_None`. New `render/arrowheads.ts` module owns the geometry; `DimVars.arrowKind` (discriminated `ArrowKind` union) replaces the previous `useTicks` boolean. The "outside arrows" flip for short dim lines now only fires for direction-dependent arrow-shape kinds — dots, ticks, boxes and origin rings sit at the endpoint as-is. For LEADERs an unknown DIMLDRBLK name falls back to the user-defined block geometry.
- **REGION entities** — parsed (minimally; ACIS modeler data skipped) and rendered as their own contour. When a HATCH lists the REGION's handle in its boundary path source objects (DXF codes 97/330), the REGION borrows the HATCH's already-parsed boundary edges as its visible curve. Drawn with the REGION's own color/layer/linetype (OCS comes from the HATCH). Pickable too. New parser pass `linkRegionsToHatchBoundaries`; new renderer `collectors/regionCollector.ts`.
- **`STYLE.widthFactor` (DXF code 41)** — now honored across TEXT, ATTRIB, ATTDEF, MTEXT and DIMENSION text. A STYLE explicitly authored as narrow (e.g. ISO-25 with `widthFactor=0.8`) no longer renders at width factor 1. Priority chain: `entity.xScale` / `entity.scale` → `STYLE.widthFactor` → `1.0`. MTEXT seeds the initial format-state `widthFactor` from STYLE; inline `\W<n>;` still overrides. DIMENSION text resolves via DIMSTYLE.DIMTXSTY (code 340) → STYLE → widthFactor, threaded through the dim-line gap calculation so breaks stay correct under stretch.
- **MTEXT inline scoped formatting `{…}`** — `\C`, `\H`, `\f`, `\L\l`, `\O\o`, `\K\k` inside brace groups now apply only to that scope and revert on the closing brace. Previously every formatting code inside braces was stripped. The line model was replaced with a runs model: each `MTextLine` carries an ordered array of `MTextRun` segments, each with its own color/height/bold/italic/font/underline/overline/strikethrough. Word-wrap, tabs and 9-point attachment alignment now operate across all runs of a line. Overline (`\O`) and strikethrough (`\K`) decorations are also drawn (previously silently stripped). New exports: `MTextRun` interface and `getMTextLineText(line)` helper.
- **MTEXT inline `\W<n>;` (width factor) and `\Q<n>;` (obliquing angle)** — `\W2;` makes glyphs twice as wide; `\Q15;` shears them by 15° (positive slants right). Both codes participate in brace scoping and combine with other formatting. Word-wrap and inter-run advance account for the width factor.
- **Angular dimension precision (`DIMADEC`)** — DIMSTYLE code 179 and header `$DIMADEC` are now read; angular dim labels use them for decimal places instead of the linear `DIMDEC`.
- **Radial dimension state-machine** — radial dims are now rendered through a proper layout state-machine driven by `DIMTIH` (74), `DIMTOH` (73), `DIMTAD` (77), `DIMGAP` (147), `DIMTMOVE` (279) and `DIMUPT` (288), instead of a hard-coded ANSI horizontal layout. Aligned mode (ISO default): dim line follows the radius angle with DIMTAD-driven break/continue around text and DIMTMOVE-driven connectors. Horizontal mode (ANSI): preserved. New DIMSTYLE fields: `dimtad`, `dimgap`, `dimtmove`, `dimupt`, `dimatfit`. New header keys: `$DIMTAD`, `$DIMTIH`, `$DIMTOH`, `$DIMTMOVE`.
- **Binary DXF detection** — `parseDxf` now rejects AutoCAD Binary DXF files with a clear message (`"Binary DXF format is not supported. Save the file as ASCII (text) DXF and try again."`) instead of failing later with a cryptic scanner error. Detection is a single `startsWith("AutoCAD Binary DXF")` on the decoded text and works for sync `parseDxf`, async `parseDxfAsync`, and the Vue `loadDXFFromBuffer` pipeline.

### Bug Fixes

- **ATTRIB/ATTDEF FIT/ALIGNED** — `horizontalJustification = 3` (ALIGNED) or `= 5` (FIT) now render correctly between the two alignment points instead of being anchored at the second one. Affects both `renderAttribs` (inside INSERT) and `collectAttdefEntity`.
- **Wide LWPOLYLINE/POLYLINE with a width discontinuity at a vertex** — e.g. an arrow drawn as two segments (`0/0` then `120/0`). The junction is now re-emitted as a duplicate center point so the wider segment opens at its real start width instead of inheriting the previous segment's end width. Zero-width segments inside an otherwise-wide polyline are also rendered as thin lines (a zero-area mesh strip is invisible).
- **Wide LWPOLYLINE/POLYLINE inside a scaled INSERT** — thickness now scales with the parent matrix. Previously `halfWidth` stayed in entity-local units while the path was transformed, so a polyline inside an INSERT with scale 225 (typical for pre-rendered dim blocks with `_ArchTick` arrowheads) kept its 0.4-unit thickness and rendered sub-pixel.
- **Nested DIMENSION inside a block** — now uses its pre-rendered associated block (`entity.block`) when present, instead of falling through to the DIMSTYLE-synthesizing path. The dispatch in `insertCollector.ts` previously ignored `entity.block` for in-block dimensions — only the top-level dispatch checked it. New `processDimensionEntity` helper shared by all three call sites.
- **DIMENSION with a pre-rendered associated block (`entity.block`)** — rendered through the block instead of synthesized from DIMSTYLE rules. AutoCAD/Revit/Civil3D stash WYSIWYG dim geometry (lines, arrowheads, MTEXT) into anonymous `*D###` / `DIMBLOCKn-…` blocks; reading those directly bypasses any `DIMTXT × DIMSCALE` mismatch in the source DIMSTYLE. Fallback to the DIMSTYLE path when the dim has no block or the block is empty.
- **Render order** — solid fills (HATCH, SOLID, 3DFACE) no longer cover block outlines that were added to the scene before flush. Each material kind now carries an explicit `renderOrder` (`MESH=0`, `LINE=1`, `OVERLAY=2`); a stable sort runs after `GeometryCollector.flush()` so hatches draw first, then outlines, then text/arrows, regardless of when each object joined the group.
- **MULTILEADER entities from real AutoCAD-2018 files now render** — `CONTEXT_DATA` parser used wrong section codes (301/302 instead of 302/304) and squashed every closing `}` under one case; `entity.leaders` ended up empty and `entity.text` was overwritten with the literal `"LEADER_LINE{"`. Codes are now correctly paired per-level. `leaderCollector` no longer drops a LEADER_LINE that carries only the arrow-tip vertex.
- **MULTILEADER `textHeight` and `arrowSize`** — read from the correct DXF codes. `textHeight` now comes from CONTEXT_DATA code `41` (was reading `40` = OverallContentScale ≈ 1.0, making labels invisible on multi-thousand-unit drawings); `arrowSize` from entity-level code `42`.
- **MULTILEADER line and text colors** — honor AutoCAD's CmEntityColor / MLEADERSTYLE precedence chain. Entity-level color codes (`91` LeaderLineColor, top-scope `90` TextColor, `340` styleHandle, `90` PropertyOverrideFlag) are now parsed. New `parser/sections/objects.ts` reads `MLEADERSTYLE` records out of OBJECTS. `decodeCmEntityColor(raw)` decodes the 32-bit `AcCmEntityColor` value. `resolveMLeaderColor` walks: entity-override → MLEADERSTYLE → fallback. Separate `lineColor` and `textColor` are derived per MULTILEADER.
- **Spline-shaped MULTILEADER leaders** — `LeaderLineType` flag at entity-level code `170` (0=invisible, 1=straight, 2=spline) is now parsed. Spline mode interpolates a LEADER_LINE with 3+ points as a Catmull-Rom curve; the common 1-vertex case builds a cubic Bezier whose end-tangent at the landing follows the LEADER's `doglegVector`, so the curve enters the dogleg shelf tangentially. Arrow direction follows the curve's tangent at the tip.
- **Aligned radial dims with text outside the arc and diametric dims with off-segment text** — now extend the dim line past each arrow base by `arrowSize × OUTSIDE_ARROW_TAIL_RATIO`, so the arrow reads as a shaft + head instead of a bare triangle.
- **Diametric dimensions with off-segment text honor DIMTOH** — `DIMTOH=0` (ISO default) extends the diameter line past the nearest endpoint outward to the far edge of the text and rotates the text to match the diameter direction. The previous leader + horizontal text + shelf path is preserved for explicit `DIMTOH=1` (ANSI).
- **Diametric dimensions with on-segment text** — projected-onto-segment text (`t ∈ [0,1]`) renders aligned to the diameter regardless of perpendicular distance from the line. The previous `perpDist < textHeight` constraint forced default-position dims with a normal DIMTAD=1 offset into the wrong "leader + horizontal text" branch.
- **Aligned-text radial dim text position** — mirrored across the radius axis when the source CAD wrote `textPos` on the perp side opposite to the readable rotation's "above". Previously the readability flip silently inverted the perpendicular convention, putting glyph ascenders pointing at the line.
- **`DIMTIH` and `DIMTOH` read only from DIMSTYLE** — header `$DIMTIH`/`$DIMTOH` are AutoCAD's editor-current values for creating new dimensions, not defaults for rendering existing ones. Missing DIMSTYLE fields now propagate as `undefined` (interpreted as 0 / ISO aligned).
- **DIMCLRT for specialized dimension types** — angular, radial, diametric, ordinate now use DIMSTYLE's `DIMCLRT` for text color instead of inheriting the dim entity's geometry color. New `textColor` field on `DimensionTypeParams` wired through `addDimensionTextToCollector` in all four specialized helpers.
- **TEXT/MTEXT/ATTRIB/ATTDEF bold/italic via `styleName`** — STYLE-table parser now reads ACAD XDATA descriptor (code 1071) and unpacks bits 24 (italic) and 25 (bold) into `DxfStyle.bold` / `DxfStyle.italic`. Text collectors look them up at emit time so e.g. `arial b` (fontFile `Arial Bold.ttf`) renders through faux-bold. MTEXT inline `\f...|b0|i0;` still overrides per-run.
- **DIMSTYLE DIMCLRD (code 176) and DIMCLRE (code 177)** — parsed and applied so dim line / arrows / extension lines pick up the colors configured in the style instead of always inheriting the dimension entity's color. Values `0` (BYBLOCK) and `256` (BYLAYER) fall back to entity color. ACI 7/255/250/251 routed through theme-adaptive sentinels.
- **Per-entity XDATA DSTYLE override: DIMDEC (271) and DIMADEC (179)** — override chain is now `entity XDATA → DIMSTYLE → header → default` for these two as well. Previously only DIMTXT/DIMASZ/DIMSCALE were handled.
- **Short linear/rotated/aligned dimensions flip arrows outward** — when dim line length is below `2.5 × arrowSize`, arrowheads are placed with tips at the extension lines pointing inward and bases sitting outside; the dim line extends past each arrow base by a tail so each side reads as a proper arrow. Previously inward-pointing arrows formed a "bowtie" / diamond for tiny dimensions.
- **Dimension labels in decimal mode honor `DIMDEC` and `DIMZIN`** — `formatDimNumber` previously ignored `DIMDEC` and rendered with hardcoded 4-place precision. DIMZIN bit 2 (`& 4`) suppresses leading zeros, bit 3 (`& 8`) trailing zeros; when DIMZIN is absent the previous strip-trailing default is preserved.
- **DIMCLRT and MTEXT inline `\C<index>;`** — route ACI 7/255 and grays 250/251 through theme-adaptive sentinels (`ACI7_COLOR`, `\0ACI250/251`) instead of resolving directly to a literal hex. A new `aciToColor()` helper centralizes the rule.
- **LWPOLYLINE parser no longer aborts on code 91 (Vertex Identifier)** — previously fell into the `default` branch, returned a truncated vertex list, then re-entered with another partial run padded with `{x: undefined, y: undefined}` vertices. Three.js rendered the `undefined` coords as stray lines reaching to the world origin.
- **HATCH solid fills with elliptic-arc boundary edges (edge type 3)** — DXF stores start/end angles in **degrees** for edge type 3 (codes 50/51), unlike the ELLIPSE entity (codes 41/42) which uses radians. Values were previously passed as radians, so triangulated fills collapsed.
- **Layer flag bit 2** — bit 0x02 ("frozen by default in new viewports") no longer hides layers in model space; only bit 0x01 controls `frozen` per the DXF spec.
- **Architectural dimension fractions honor `DIMDEC`** — fraction denominator is `2^DIMDEC` instead of a hardcoded 16 (1/16"). E.g. `DIMDEC=3` renders `6'-1 3/8"` instead of `6'-1 5/16"`. `DIMDEC=0` rounds to whole inches. Defaults to 1/16" when not specified.
- **Entities on layer "0" inside a block inherit the parent INSERT's effective color** — per AutoCAD convention. Includes ATTRIBs attached to INSERT. The cached block template fast path stores a `BYBLOCK_COLOR` sentinel for layer-0 ByLayer entities and resolves it to `insertColor` at instantiation.
- **`arraybufferPlugin` rewritten** to use `resolveId` + virtual modules instead of `transform`. Now works in Vite dev server (Vite's built-in asset middleware previously intercepted `.ttf?arraybuffer` requests before the plugin could run). Production output unchanged.

### Stats

- 1141 tests across 52 files (was 945 across 44).

## 1.5.0

### Features
Expand Down
Loading
Loading