updated skills
This commit is contained in:
@@ -98,4 +98,3 @@ Universal — no DOM or Node-only APIs at the package boundary.
|
||||
`sideEffects: false`. Internal deps: `@suaveplan/crypto-hash`,
|
||||
`@suaveplan/error`, `@suaveplan/types`. External deps:
|
||||
`@opentelemetry/api`, `tslib`, `zod`.
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ calculateDimensions(pixel, 9999);
|
||||
### `calculateDimensions(parsed: ParsedImgproxyUrl, defaultWidth: number): ImgproxyDimensions`
|
||||
|
||||
- **Parameters:**
|
||||
- `parsed` — output of `parseImgproxyUrl`.
|
||||
- `defaultWidth` — width used when the URL is in aspect-ratio mode
|
||||
- `parsed` — output of `parseImgproxyUrl`.
|
||||
- `defaultWidth` — width used when the URL is in aspect-ratio mode
|
||||
without a `w`/`h` hint.
|
||||
- **Returns:** `{ width, height }`, both non-negative integers. Either
|
||||
axis may be `0` (meaning "auto / unspecified").
|
||||
|
||||
@@ -60,9 +60,9 @@ operationToImgproxy(parsed.operation, width, height, parsed.gravity);
|
||||
### `operationToImgproxy(op: ImgproxyOperation, width: number, height: number, gravity: string): string`
|
||||
|
||||
- **Parameters:**
|
||||
- `op` — one of `""|cover|crop|fit|stretch|resize`.
|
||||
- `width`, `height` — non-negative integers; either may be zero.
|
||||
- `gravity` — a grammar code accepted by `gravityToImgproxy`.
|
||||
- `op` — one of `""|cover|crop|fit|stretch|resize`.
|
||||
- `width`, `height` — non-negative integers; either may be zero.
|
||||
- `gravity` — a grammar code accepted by `gravityToImgproxy`.
|
||||
- **Returns:** the imgproxy processing string, or `""` when the
|
||||
operation cannot be expressed (e.g. `crop` without both dims).
|
||||
|
||||
|
||||
@@ -76,10 +76,10 @@ function tryParse(path: string): string | null {
|
||||
- **Parameters:** `path` — the URL path including leading `/`.
|
||||
- **Returns:** a frozen `ParsedImgproxyUrl` (see `types/types.ts`).
|
||||
- **Throws:**
|
||||
- `CaddyImgproxyError(INVALID_URL)` when the regex rejects the
|
||||
- `CaddyImgproxyError(INVALID_URL)` when the regex rejects the
|
||||
input — bad prefix, malformed dimensions, quality outside
|
||||
`1..100`.
|
||||
- `CaddyImgproxyError(MISSING_DIMENSIONS)` when an operation
|
||||
- `CaddyImgproxyError(MISSING_DIMENSIONS)` when an operation
|
||||
(`v|c|f|s|r`) is present without any dimension grammar.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
@@ -68,14 +68,14 @@ const sig = signImgproxyPath({
|
||||
### `signImgproxyPath(options: SignImgproxyPathOptions): string`
|
||||
|
||||
- **Parameters:**
|
||||
- `options.key` — lower-hex HMAC key, even length, non-empty.
|
||||
- `options.salt` — lower-hex salt, even length, non-empty.
|
||||
- `options.path` — the imgproxy path being signed.
|
||||
- `options.hash` — optional `SignerHashLike` injection seam.
|
||||
- `options.key` — lower-hex HMAC key, even length, non-empty.
|
||||
- `options.salt` — lower-hex salt, even length, non-empty.
|
||||
- `options.path` — the imgproxy path being signed.
|
||||
- `options.hash` — optional `SignerHashLike` injection seam.
|
||||
- **Returns:** base64url-encoded signature, no padding.
|
||||
- **Throws:**
|
||||
- `CaddyImgproxyError(INVALID_KEY)` for malformed / empty / odd-length key.
|
||||
- `CaddyImgproxyError(INVALID_SALT)` for malformed / empty / odd-length salt.
|
||||
- `CaddyImgproxyError(INVALID_KEY)` for malformed / empty / odd-length key.
|
||||
- `CaddyImgproxyError(INVALID_SALT)` for malformed / empty / odd-length salt.
|
||||
|
||||
### `SignerHashLike`
|
||||
|
||||
|
||||
@@ -70,10 +70,10 @@ const url = buildImgproxyUrl({ parsed, domain: "example.com", config });
|
||||
### `buildImgproxyUrl(options: BuildImgproxyUrlOptions): string`
|
||||
|
||||
- **Parameters:**
|
||||
- `options.parsed` — output of `parseImgproxyUrl`.
|
||||
- `options.domain` — virtual-host segment for the S3 path.
|
||||
- `options.config` — validated `ImgproxyConfig`.
|
||||
- `options.hash` — optional signer hash override.
|
||||
- `options.parsed` — output of `parseImgproxyUrl`.
|
||||
- `options.domain` — virtual-host segment for the S3 path.
|
||||
- `options.config` — validated `ImgproxyConfig`.
|
||||
- `options.hash` — optional signer hash override.
|
||||
- **Returns:** the full imgproxy path including the signature prefix.
|
||||
|
||||
### `BuildImgproxyUrlOptions`
|
||||
|
||||
@@ -62,4 +62,3 @@ console.log(c.contrast("#ffffff")); // WCAG contrast ratio
|
||||
- `@suaveplan/colours/utils` — clamping and rounding utilities
|
||||
- `@suaveplan/colours/errors` — `ColourError` and factory functions
|
||||
- `@suaveplan/colours/error-codes` — `COLOUR_CODES` registry
|
||||
|
||||
|
||||
@@ -131,4 +131,3 @@ Bun, Node, Deno, and modern browsers.
|
||||
## License
|
||||
|
||||
MIT — Suaveplan Team.
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ function pickBackgroundColour(pixels, w, h) {
|
||||
|
||||
The flood-fill uses an explicit stack (`pop()`) rather than recursion to
|
||||
avoid blowing the call stack on large emblems. We `add` to `visited`
|
||||
*before* enqueueing the neighbour, which guarantees each pixel is touched
|
||||
_before_ enqueueing the neighbour, which guarantees each pixel is touched
|
||||
at most twice (once when discovered, once when its packed index is popped).
|
||||
The neighbour set is computed as a small inline array of `-1`-sentinel
|
||||
checks for the four cardinal directions; benchmarks against a `for (const
|
||||
|
||||
@@ -62,6 +62,6 @@ The inner `tryMerge` first tests the horizontal merge (same `y`, same
|
||||
against `available` before accepting; this avoids painting through
|
||||
transparent pixels. The outer loop terminates when a full pass produces
|
||||
zero merges, so each call is idempotent. We deliberately do not try
|
||||
*non*-same-extent merges here — that is the job of `optimiseOverlap`,
|
||||
_non_-same-extent merges here — that is the job of `optimiseOverlap`,
|
||||
which can produce overlapping output and is therefore a strictly stronger
|
||||
(but more expensive) operation.
|
||||
|
||||
@@ -18,7 +18,7 @@ on the layer list and is the only pass that mutates `layer.rects`.
|
||||
- Composites every layer into a per-cell `target` grid first (lower-z to
|
||||
higher-z), then walks rect by rect deciding whether removal would
|
||||
change the composited output.
|
||||
- A rect is removed iff *every* one of its required cells is either
|
||||
- A rect is removed iff _every_ one of its required cells is either
|
||||
covered by a sibling rect at the same z-index or overdrawn by a higher-z
|
||||
rect of any colour.
|
||||
- In-place mutation via `Array.prototype.splice` — the converter calls
|
||||
|
||||
@@ -61,7 +61,7 @@ const cover = perIslandCover(info.islands, candidates, w, h);
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The centroid term is computed against the running set of *uncovered*
|
||||
The centroid term is computed against the running set of _uncovered_
|
||||
required pixels, not the original set — this keeps selections clustered
|
||||
even as the residual shrinks. We use a precomputed `maxDist =
|
||||
sqrt(w² + h²)` so the proximity term is normalised to `[0, 1]`; without
|
||||
|
||||
@@ -59,7 +59,7 @@ const cover = enhancedGreedyCover(candidates, required, cols, rows);
|
||||
The internal `histogramSweep` builds a column-by-column heights table and
|
||||
then walks each row with a monotonic stack. When the stack pops, every
|
||||
height ≥ the popped column's height yields a distinct maximal rect of
|
||||
width `x - leftBound` and height `rectH`. We emit *every* nested height so
|
||||
width `x - leftBound` and height `rectH`. We emit _every_ nested height so
|
||||
the greedy cover can pick a smaller-but-better-positioned rect when the
|
||||
maximal-tall one would force an awkward residual. The transposed sweep is
|
||||
implemented as a fresh `boolean[][]` rather than an index permutation
|
||||
|
||||
@@ -77,7 +77,7 @@ The strip strategy only contributes when it fully covers the required
|
||||
mask. We compute coverage by intersecting each valid strip with the
|
||||
`required` grid (via `pack`) and comparing the resulting count to a
|
||||
single pre-tallied `totalRequired`. The adjacent-rect merge pass runs
|
||||
*after* the strategies have produced their winners; running it earlier
|
||||
_after_ the strategies have produced their winners; running it earlier
|
||||
would force a merge on results that would have been pruned anyway. The
|
||||
final reduce uses a strictly-less-than comparison (`a.length <= b.length`)
|
||||
so the first result wins on ties — this preserves deterministic ordering
|
||||
|
||||
@@ -85,4 +85,3 @@ console.log(result.finalColours); // colour count after quantisation
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
|
||||
@@ -56,4 +56,3 @@ const result = proc.planTransform(meta, {
|
||||
- [`src/types/image-detect/image-detect.md`](./src/types/image-detect/image-detect.md) — Format detection types and constants
|
||||
- [`src/errors/errors.md`](./src/errors/errors.md) — `ImageError` hierarchy and typed factories
|
||||
- [`src/error-codes/error-codes.md`](./src/error-codes/error-codes.md) — Stable `IMAGE.*` error code registry
|
||||
|
||||
|
||||
Reference in New Issue
Block a user