css-calipers 0.15.0 → 1.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/LICENSE.txt +1 -1
  2. package/README.md +70 -434
  3. package/dist/cjs/color/formats/display-p3/display-p3.js +25 -0
  4. package/dist/cjs/color/formats/escalate.js +41 -0
  5. package/dist/cjs/color/formats/hex/hex.js +28 -0
  6. package/dist/cjs/color/formats/hexAlpha/hexAlpha.js +25 -0
  7. package/dist/cjs/color/formats/hsl/hsl.js +23 -0
  8. package/dist/cjs/color/formats/hwb/hwb.js +24 -0
  9. package/dist/cjs/color/formats/index.js +36 -0
  10. package/dist/cjs/color/formats/internals.js +93 -0
  11. package/dist/cjs/color/formats/lab/lab.js +24 -0
  12. package/dist/cjs/color/formats/lch/lch.js +23 -0
  13. package/dist/cjs/color/formats/oklab/oklab.js +24 -0
  14. package/dist/cjs/color/formats/oklch/oklch.js +28 -0
  15. package/dist/cjs/color/formats/resolve.js +16 -0
  16. package/dist/cjs/color/formats/rgb/rgb.js +29 -0
  17. package/dist/cjs/color/formats/rgba/rgba.js +27 -0
  18. package/dist/cjs/color/formats/types.js +11 -0
  19. package/dist/cjs/color/index.js +619 -0
  20. package/dist/cjs/color/types.js +2 -0
  21. package/dist/cjs/core.js +11 -8
  22. package/dist/cjs/corpus.js +53 -0
  23. package/dist/cjs/css-values/cssValues.js +78 -0
  24. package/dist/cjs/css-values/index.js +36 -0
  25. package/dist/cjs/css-values/multi.js +290 -0
  26. package/dist/cjs/css-values/propertyMap.js +2 -0
  27. package/dist/cjs/css-values/spec.js +197 -0
  28. package/dist/cjs/default.js +17 -0
  29. package/dist/cjs/factory.js +1 -1
  30. package/dist/cjs/float.js +110 -0
  31. package/dist/cjs/index.js +29 -9
  32. package/dist/cjs/integer.js +114 -0
  33. package/dist/cjs/internal/createCoreApi.js +103 -38
  34. package/dist/cjs/internal/errors.js +13 -14
  35. package/dist/cjs/internal/toPlainDecimal.js +31 -0
  36. package/dist/cjs/measurements.js +41 -0
  37. package/dist/cjs/ratio.js +57 -22
  38. package/dist/cjs/scalar.js +9 -0
  39. package/dist/cjs/units/absolute.js +8 -8
  40. package/dist/cjs/units/angle.js +5 -5
  41. package/dist/cjs/units/container.js +7 -7
  42. package/dist/cjs/units/font-relative.js +13 -13
  43. package/dist/cjs/units/frequency.js +3 -3
  44. package/dist/cjs/units/grid.js +2 -2
  45. package/dist/cjs/units/index.js +9 -9
  46. package/dist/cjs/units/percent.js +4 -4
  47. package/dist/cjs/units/resolution.js +4 -4
  48. package/dist/cjs/units/time.js +3 -3
  49. package/dist/cjs/units/viewport-dynamic.js +7 -7
  50. package/dist/cjs/units/viewport-large.js +7 -7
  51. package/dist/cjs/units/viewport-small.js +7 -7
  52. package/dist/cjs/units/viewport.js +7 -7
  53. package/dist/esm/color/formats/display-p3/display-p3.d.ts +10 -0
  54. package/dist/esm/color/formats/display-p3/display-p3.d.ts.map +1 -0
  55. package/dist/esm/color/formats/display-p3/display-p3.js +22 -0
  56. package/dist/esm/color/formats/escalate.d.ts +10 -0
  57. package/dist/esm/color/formats/escalate.d.ts.map +1 -0
  58. package/dist/esm/color/formats/escalate.js +37 -0
  59. package/dist/esm/color/formats/hex/hex.d.ts +9 -0
  60. package/dist/esm/color/formats/hex/hex.d.ts.map +1 -0
  61. package/dist/esm/color/formats/hex/hex.js +25 -0
  62. package/dist/esm/color/formats/hexAlpha/hexAlpha.d.ts +9 -0
  63. package/dist/esm/color/formats/hexAlpha/hexAlpha.d.ts.map +1 -0
  64. package/dist/esm/color/formats/hexAlpha/hexAlpha.js +22 -0
  65. package/dist/esm/color/formats/hsl/hsl.d.ts +8 -0
  66. package/dist/esm/color/formats/hsl/hsl.d.ts.map +1 -0
  67. package/dist/esm/color/formats/hsl/hsl.js +20 -0
  68. package/dist/esm/color/formats/hwb/hwb.d.ts +9 -0
  69. package/dist/esm/color/formats/hwb/hwb.d.ts.map +1 -0
  70. package/dist/esm/color/formats/hwb/hwb.js +21 -0
  71. package/dist/esm/color/formats/index.d.ts +24 -0
  72. package/dist/esm/color/formats/index.d.ts.map +1 -0
  73. package/dist/esm/color/formats/index.js +32 -0
  74. package/dist/esm/color/formats/internals.d.ts +35 -0
  75. package/dist/esm/color/formats/internals.d.ts.map +1 -0
  76. package/dist/esm/color/formats/internals.js +78 -0
  77. package/dist/esm/color/formats/lab/lab.d.ts +9 -0
  78. package/dist/esm/color/formats/lab/lab.d.ts.map +1 -0
  79. package/dist/esm/color/formats/lab/lab.js +21 -0
  80. package/dist/esm/color/formats/lch/lch.d.ts +8 -0
  81. package/dist/esm/color/formats/lch/lch.d.ts.map +1 -0
  82. package/dist/esm/color/formats/lch/lch.js +20 -0
  83. package/dist/esm/color/formats/oklab/oklab.d.ts +9 -0
  84. package/dist/esm/color/formats/oklab/oklab.d.ts.map +1 -0
  85. package/dist/esm/color/formats/oklab/oklab.js +21 -0
  86. package/dist/esm/color/formats/oklch/oklch.d.ts +13 -0
  87. package/dist/esm/color/formats/oklch/oklch.d.ts.map +1 -0
  88. package/dist/esm/color/formats/oklch/oklch.js +25 -0
  89. package/dist/esm/color/formats/resolve.d.ts +15 -0
  90. package/dist/esm/color/formats/resolve.d.ts.map +1 -0
  91. package/dist/esm/color/formats/resolve.js +12 -0
  92. package/dist/esm/color/formats/rgb/rgb.d.ts +11 -0
  93. package/dist/esm/color/formats/rgb/rgb.d.ts.map +1 -0
  94. package/dist/esm/color/formats/rgb/rgb.js +26 -0
  95. package/dist/esm/color/formats/rgba/rgba.d.ts +9 -0
  96. package/dist/esm/color/formats/rgba/rgba.d.ts.map +1 -0
  97. package/dist/esm/color/formats/rgba/rgba.js +24 -0
  98. package/dist/esm/color/formats/types.d.ts +48 -0
  99. package/dist/esm/color/formats/types.d.ts.map +1 -0
  100. package/dist/esm/color/formats/types.js +7 -0
  101. package/dist/esm/color/index.d.ts +81 -0
  102. package/dist/esm/color/index.d.ts.map +1 -0
  103. package/dist/esm/color/index.js +609 -0
  104. package/dist/esm/color/types.d.ts +294 -0
  105. package/dist/esm/color/types.d.ts.map +1 -0
  106. package/dist/esm/color/types.js +1 -0
  107. package/dist/esm/core.d.ts +76 -270
  108. package/dist/esm/core.d.ts.map +1 -1
  109. package/dist/esm/core.js +5 -7
  110. package/dist/esm/corpus.d.ts +26 -0
  111. package/dist/esm/corpus.d.ts.map +1 -0
  112. package/dist/esm/corpus.js +37 -0
  113. package/dist/esm/css-values/cssValues.d.ts +60 -0
  114. package/dist/esm/css-values/cssValues.d.ts.map +1 -0
  115. package/dist/esm/css-values/cssValues.js +74 -0
  116. package/dist/esm/css-values/index.d.ts +6 -0
  117. package/dist/esm/css-values/index.d.ts.map +1 -0
  118. package/dist/esm/css-values/index.js +12 -0
  119. package/dist/esm/css-values/multi.d.ts +188 -0
  120. package/dist/esm/css-values/multi.d.ts.map +1 -0
  121. package/dist/esm/css-values/multi.js +281 -0
  122. package/dist/esm/css-values/propertyMap.d.ts +39 -0
  123. package/dist/esm/css-values/propertyMap.d.ts.map +1 -0
  124. package/dist/esm/css-values/propertyMap.js +1 -0
  125. package/dist/esm/css-values/spec.d.ts +36 -0
  126. package/dist/esm/css-values/spec.d.ts.map +1 -0
  127. package/dist/esm/css-values/spec.js +194 -0
  128. package/dist/esm/default.d.ts +267 -0
  129. package/dist/esm/default.d.ts.map +1 -0
  130. package/dist/esm/default.js +14 -0
  131. package/dist/esm/factory.d.ts +1 -1
  132. package/dist/esm/factory.d.ts.map +1 -1
  133. package/dist/esm/factory.js +3 -3
  134. package/dist/esm/float.d.ts +35 -0
  135. package/dist/esm/float.d.ts.map +1 -0
  136. package/dist/esm/float.js +104 -0
  137. package/dist/esm/index.d.ts +11 -9
  138. package/dist/esm/index.d.ts.map +1 -1
  139. package/dist/esm/index.js +19 -9
  140. package/dist/esm/integer.d.ts +36 -0
  141. package/dist/esm/integer.d.ts.map +1 -0
  142. package/dist/esm/integer.js +108 -0
  143. package/dist/esm/internal/buildMeasurementCreationError.tests.d.ts +1 -1
  144. package/dist/esm/internal/buildMeasurementCreationError.tests.d.ts.map +1 -1
  145. package/dist/esm/internal/createCoreApi.d.ts +9 -1
  146. package/dist/esm/internal/createCoreApi.d.ts.map +1 -1
  147. package/dist/esm/internal/createCoreApi.js +103 -38
  148. package/dist/esm/internal/createUnitsApi.d.ts +1 -1
  149. package/dist/esm/internal/createUnitsApi.d.ts.map +1 -1
  150. package/dist/esm/internal/errors.d.ts +3 -3
  151. package/dist/esm/internal/errors.d.ts.map +1 -1
  152. package/dist/esm/internal/errors.js +13 -14
  153. package/dist/esm/internal/toPlainDecimal.d.ts +2 -0
  154. package/dist/esm/internal/toPlainDecimal.d.ts.map +1 -0
  155. package/dist/esm/internal/toPlainDecimal.js +27 -0
  156. package/dist/esm/measurements.d.ts +16 -0
  157. package/dist/esm/measurements.d.ts.map +1 -0
  158. package/dist/esm/measurements.js +25 -0
  159. package/dist/esm/ratio.d.ts +14 -5
  160. package/dist/esm/ratio.d.ts.map +1 -1
  161. package/dist/esm/ratio.js +57 -22
  162. package/dist/esm/scalar.d.ts +14 -0
  163. package/dist/esm/scalar.d.ts.map +1 -0
  164. package/dist/esm/scalar.js +5 -0
  165. package/dist/esm/units/absolute.d.ts +1 -1
  166. package/dist/esm/units/absolute.d.ts.map +1 -1
  167. package/dist/esm/units/absolute.js +1 -1
  168. package/dist/esm/units/angle.d.ts +1 -1
  169. package/dist/esm/units/angle.d.ts.map +1 -1
  170. package/dist/esm/units/angle.js +1 -1
  171. package/dist/esm/units/container.d.ts +1 -1
  172. package/dist/esm/units/container.d.ts.map +1 -1
  173. package/dist/esm/units/container.js +1 -1
  174. package/dist/esm/units/font-relative.d.ts +1 -1
  175. package/dist/esm/units/font-relative.d.ts.map +1 -1
  176. package/dist/esm/units/font-relative.js +1 -1
  177. package/dist/esm/units/frequency.d.ts +1 -1
  178. package/dist/esm/units/frequency.d.ts.map +1 -1
  179. package/dist/esm/units/frequency.js +1 -1
  180. package/dist/esm/units/grid.d.ts +1 -1
  181. package/dist/esm/units/grid.d.ts.map +1 -1
  182. package/dist/esm/units/grid.js +1 -1
  183. package/dist/esm/units/index.d.ts +9 -9
  184. package/dist/esm/units/index.d.ts.map +1 -1
  185. package/dist/esm/units/index.js +9 -9
  186. package/dist/esm/units/percent.d.ts +1 -1
  187. package/dist/esm/units/percent.d.ts.map +1 -1
  188. package/dist/esm/units/percent.js +1 -1
  189. package/dist/esm/units/resolution.d.ts +1 -1
  190. package/dist/esm/units/resolution.d.ts.map +1 -1
  191. package/dist/esm/units/resolution.js +1 -1
  192. package/dist/esm/units/time.d.ts +1 -1
  193. package/dist/esm/units/time.d.ts.map +1 -1
  194. package/dist/esm/units/time.js +1 -1
  195. package/dist/esm/units/viewport-dynamic.d.ts +1 -1
  196. package/dist/esm/units/viewport-dynamic.d.ts.map +1 -1
  197. package/dist/esm/units/viewport-dynamic.js +1 -1
  198. package/dist/esm/units/viewport-large.d.ts +1 -1
  199. package/dist/esm/units/viewport-large.d.ts.map +1 -1
  200. package/dist/esm/units/viewport-large.js +1 -1
  201. package/dist/esm/units/viewport-small.d.ts +1 -1
  202. package/dist/esm/units/viewport-small.d.ts.map +1 -1
  203. package/dist/esm/units/viewport-small.js +1 -1
  204. package/dist/esm/units/viewport.d.ts +1 -1
  205. package/dist/esm/units/viewport.d.ts.map +1 -1
  206. package/dist/esm/units/viewport.js +1 -1
  207. package/package.json +55 -13
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AAEvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AAIvB,cAAc,WAAW,CAAC;AAM1B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,KAAK,IAAI,UAAU,EACxB,KAAK,WAAW,EAChB,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EACf,KAAK,KAAK,EACV,UAAU,EACV,OAAO,IAAI,YAAY,EACvB,KAAK,aAAa,EAClB,UAAU,EACV,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,oBAAoB,GAC1B,MAAM,SAAS,CAAC;AACjB,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}
package/dist/esm/index.js CHANGED
@@ -1,14 +1,24 @@
1
1
  export * from './core';
2
- export * from './units/percent';
2
+ // The bare default-instance helpers (`m`, refinements, unit-helper builders,
3
+ // error-config accessors) come from the single construction path in `./default`,
4
+ // which assembles them via `createCalipers()` at its defaults.
5
+ export * from './default';
6
+ // The native colour input, alongside `m()` / `r()` / `i()` / `f()`. The full value
7
+ // surface also lives at the `./color` subpath (for bundler/node16 consumers); the root
8
+ // re-exports it too so classic-resolution consumers (e.g. @css-bookends/color) can reach
9
+ // it without a subpath. The lower-level value primitives are color-prefixed (and
10
+ // `resolve` is re-exported as `resolveColor`) to avoid colliding with calipers' own names.
11
+ export { color, colorFormats, createColor, defaultColorConfig, defaultFormatPriority, defineColorSpace, parseColor, resolve as resolveColor, storeColor, } from './color';
3
12
  export * from './units/absolute';
4
- export * from './units/font-relative';
5
- export * from './units/viewport';
6
- export * from './units/viewport-small';
7
- export * from './units/viewport-large';
8
- export * from './units/viewport-dynamic';
9
- export * from './units/container';
10
13
  export * from './units/angle';
11
- export * from './units/time';
14
+ export * from './units/container';
15
+ export * from './units/font-relative';
12
16
  export * from './units/frequency';
13
- export * from './units/resolution';
14
17
  export * from './units/grid';
18
+ export * from './units/percent';
19
+ export * from './units/resolution';
20
+ export * from './units/time';
21
+ export * from './units/viewport';
22
+ export * from './units/viewport-dynamic';
23
+ export * from './units/viewport-large';
24
+ export * from './units/viewport-small';
@@ -0,0 +1,36 @@
1
+ import { type Scalar } from './scalar';
2
+ export type IntegerConstraints = {
3
+ min?: number;
4
+ max?: number;
5
+ };
6
+ export type IntegerOptions = IntegerConstraints & {
7
+ context?: string;
8
+ };
9
+ export interface IInteger {
10
+ css: () => string;
11
+ toString: () => string;
12
+ valueOf: () => number;
13
+ value: () => number;
14
+ constraints: () => IntegerConstraints;
15
+ withValue: (value: number) => IInteger;
16
+ add: (delta: Scalar) => IInteger;
17
+ subtract: (delta: Scalar) => IInteger;
18
+ multiply: (factor: Scalar) => IInteger;
19
+ divide: (divisor: Scalar) => IInteger;
20
+ clamp: (min: number, max: number) => IInteger;
21
+ }
22
+ /**
23
+ * Create a typed integer (a finite whole number) with optional range
24
+ * constraints. Operations re-validate against the same constraints, so a
25
+ * result that is no longer an integer (or falls out of range) throws. That is
26
+ * how integer-ness survives arithmetic.
27
+ */
28
+ export declare function i(value: number, options?: IntegerOptions): IInteger;
29
+ /**
30
+ * Bind a set of integer constraints once and reuse the bound factory, the
31
+ * scalar analogue of `makeUnitHelper`. For example, a font-weight value is
32
+ * `hardenInteger({ min: 1, max: 1000 })`.
33
+ */
34
+ export declare const hardenInteger: (constraints?: IntegerConstraints) => (value: number, context?: string) => IInteger;
35
+ export declare const isInteger: (value: unknown) => value is IInteger;
36
+ //# sourceMappingURL=integer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integer.d.ts","sourceRoot":"","sources":["../../src/integer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAY,MAAM,UAAU,CAAC;AAEjD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,kBAAkB,CAAC;IACtC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,QAAQ,CAAC;IACvC,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,QAAQ,CAAC;IACjC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,QAAQ,CAAC;IACtC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,QAAQ,CAAC;IACvC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,QAAQ,CAAC;IACtC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,QAAQ,CAAC;CAC/C;AAgHD;;;;;GAKG;AACH,wBAAgB,CAAC,CACf,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,cAAmB,GAC3B,QAAQ,CAEV;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACvB,cAAa,kBAAuB,MACpC,OAAO,MAAM,EAAE,UAAU,MAAM,KAAG,QACkB,CAAC;AAExD,eAAO,MAAM,SAAS,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,QACtB,CAAC"}
@@ -0,0 +1,108 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _IntegerImpl_instances, _IntegerImpl_value, _IntegerImpl_min, _IntegerImpl_max, _IntegerImpl_context, _IntegerImpl_options;
13
+ import { toPlainDecimal } from './internal/toPlainDecimal';
14
+ import { toNumber } from './scalar';
15
+ const suffix = (context) => context ? ` [${context}]` : '';
16
+ const coerce = (value) => toNumber(value);
17
+ class IntegerImpl {
18
+ constructor(value, options = {}) {
19
+ _IntegerImpl_instances.add(this);
20
+ _IntegerImpl_value.set(this, void 0);
21
+ _IntegerImpl_min.set(this, void 0);
22
+ _IntegerImpl_max.set(this, void 0);
23
+ _IntegerImpl_context.set(this, void 0);
24
+ const { min, max, context } = options;
25
+ if (min !== undefined && max !== undefined && min > max) {
26
+ throw new Error(`i: min (${min}) must be <= max (${max})${suffix(context)}`);
27
+ }
28
+ if (!Number.isFinite(value)) {
29
+ throw new Error(`i: expected a finite number (got ${value})${suffix(context)}`);
30
+ }
31
+ if (!Number.isInteger(value)) {
32
+ throw new Error(`i: expected an integer (got ${value})${suffix(context)}`);
33
+ }
34
+ if (min !== undefined && value < min) {
35
+ throw new Error(`i: ${value} is below the minimum ${min}${suffix(context)}`);
36
+ }
37
+ if (max !== undefined && value > max) {
38
+ throw new Error(`i: ${value} is above the maximum ${max}${suffix(context)}`);
39
+ }
40
+ __classPrivateFieldSet(this, _IntegerImpl_value, value, "f");
41
+ __classPrivateFieldSet(this, _IntegerImpl_min, min, "f");
42
+ __classPrivateFieldSet(this, _IntegerImpl_max, max, "f");
43
+ __classPrivateFieldSet(this, _IntegerImpl_context, context, "f");
44
+ }
45
+ value() {
46
+ return __classPrivateFieldGet(this, _IntegerImpl_value, "f");
47
+ }
48
+ valueOf() {
49
+ return __classPrivateFieldGet(this, _IntegerImpl_value, "f");
50
+ }
51
+ constraints() {
52
+ return { min: __classPrivateFieldGet(this, _IntegerImpl_min, "f"), max: __classPrivateFieldGet(this, _IntegerImpl_max, "f") };
53
+ }
54
+ css() {
55
+ return toPlainDecimal(__classPrivateFieldGet(this, _IntegerImpl_value, "f"));
56
+ }
57
+ toString() {
58
+ return this.css();
59
+ }
60
+ withValue(value) {
61
+ return new IntegerImpl(value, __classPrivateFieldGet(this, _IntegerImpl_instances, "m", _IntegerImpl_options).call(this));
62
+ }
63
+ add(delta) {
64
+ return this.withValue(__classPrivateFieldGet(this, _IntegerImpl_value, "f") + coerce(delta));
65
+ }
66
+ subtract(delta) {
67
+ return this.withValue(__classPrivateFieldGet(this, _IntegerImpl_value, "f") - coerce(delta));
68
+ }
69
+ multiply(factor) {
70
+ return this.withValue(__classPrivateFieldGet(this, _IntegerImpl_value, "f") * coerce(factor));
71
+ }
72
+ divide(divisor) {
73
+ const numeric = coerce(divisor);
74
+ if (numeric === 0) {
75
+ throw new Error(`i: cannot divide ${__classPrivateFieldGet(this, _IntegerImpl_value, "f")} by zero${suffix(__classPrivateFieldGet(this, _IntegerImpl_context, "f"))}`);
76
+ }
77
+ const result = __classPrivateFieldGet(this, _IntegerImpl_value, "f") / numeric;
78
+ if (!Number.isFinite(result)) {
79
+ throw new Error(`i: non-finite result dividing ${__classPrivateFieldGet(this, _IntegerImpl_value, "f")} by ${numeric}${suffix(__classPrivateFieldGet(this, _IntegerImpl_context, "f"))}`);
80
+ }
81
+ return this.withValue(result);
82
+ }
83
+ clamp(min, max) {
84
+ if (min > max) {
85
+ throw new Error(`i.clamp: min (${min}) must be <= max (${max})`);
86
+ }
87
+ return this.withValue(Math.min(max, Math.max(min, __classPrivateFieldGet(this, _IntegerImpl_value, "f"))));
88
+ }
89
+ }
90
+ _IntegerImpl_value = new WeakMap(), _IntegerImpl_min = new WeakMap(), _IntegerImpl_max = new WeakMap(), _IntegerImpl_context = new WeakMap(), _IntegerImpl_instances = new WeakSet(), _IntegerImpl_options = function _IntegerImpl_options() {
91
+ return { min: __classPrivateFieldGet(this, _IntegerImpl_min, "f"), max: __classPrivateFieldGet(this, _IntegerImpl_max, "f"), context: __classPrivateFieldGet(this, _IntegerImpl_context, "f") };
92
+ };
93
+ /**
94
+ * Create a typed integer (a finite whole number) with optional range
95
+ * constraints. Operations re-validate against the same constraints, so a
96
+ * result that is no longer an integer (or falls out of range) throws. That is
97
+ * how integer-ness survives arithmetic.
98
+ */
99
+ export function i(value, options = {}) {
100
+ return new IntegerImpl(value, options);
101
+ }
102
+ /**
103
+ * Bind a set of integer constraints once and reuse the bound factory, the
104
+ * scalar analogue of `makeUnitHelper`. For example, a font-weight value is
105
+ * `hardenInteger({ min: 1, max: 1000 })`.
106
+ */
107
+ export const hardenInteger = (constraints = {}) => (value, context) => new IntegerImpl(value, { ...constraints, context });
108
+ export const isInteger = (value) => value instanceof IntegerImpl;
@@ -1,3 +1,3 @@
1
- export { buildMeasurementCreationError } from './buildMeasurementCreationError';
2
1
  export type { MeasurementCreationErrorPayload } from './buildMeasurementCreationError';
2
+ export { buildMeasurementCreationError } from './buildMeasurementCreationError';
3
3
  //# sourceMappingURL=buildMeasurementCreationError.tests.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"buildMeasurementCreationError.tests.d.ts","sourceRoot":"","sources":["../../../src/internal/buildMeasurementCreationError.tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAChF,YAAY,EAAE,+BAA+B,EAAE,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"buildMeasurementCreationError.tests.d.ts","sourceRoot":"","sources":["../../../src/internal/buildMeasurementCreationError.tests.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,+BAA+B,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC"}
@@ -1,6 +1,6 @@
1
+ import type { GreaterOrEqualToZeroBrand, IMeasurement, InRangeBrand, InscribedMeasurement, MeasurementRefinement, SmallerOrEqualToZeroBrand, UnitAssertion, UnitGuard, UnitHelper } from '../core';
1
2
  import { type UnitDefinitionRecord, type UnitHelperName } from '../unitDefinitions';
2
3
  import { type ErrorConfigStore } from './errors';
3
- import type { InscribedMeasurement, IMeasurement, UnitAssertion, UnitGuard, UnitHelper } from '../core';
4
4
  type MeasurementCreateOptions<Unit extends string> = {
5
5
  unit?: Unit;
6
6
  context?: string;
@@ -277,6 +277,14 @@ export declare const createCoreApi: (errorStore: ErrorConfigStore) => {
277
277
  };
278
278
  readonly assertUnit: <Unit extends string>(measurement: IMeasurement<Unit>, expectedUnit: string, context?: string) => void;
279
279
  readonly assertCondition: (condition: boolean | (() => boolean), message: string) => void;
280
+ readonly makeMeasurementRefinement: <B>(spec: {
281
+ predicate: (value: number) => boolean;
282
+ message: (measurement: IMeasurement) => string;
283
+ defaultFallback?: number;
284
+ }) => MeasurementRefinement<B>;
285
+ readonly nonNegative: MeasurementRefinement<GreaterOrEqualToZeroBrand>;
286
+ readonly nonPositive: MeasurementRefinement<SmallerOrEqualToZeroBrand>;
287
+ readonly inRange: <Min extends number, Max extends number>(min: Min, max: Max) => MeasurementRefinement<InRangeBrand<Min, Max>>;
280
288
  readonly getErrorConfig: () => Required<import("./errors").ErrorConfig>;
281
289
  readonly setErrorConfig: (next: import("./errors").ErrorConfig) => void;
282
290
  };
@@ -1 +1 @@
1
- {"version":3,"file":"createCoreApi.d.ts","sourceRoot":"","sources":["../../../src/internal/createCoreApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EACV,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,SAAS,EACT,UAAU,EACX,MAAM,SAAS,CAAC;AAGjB,KAAK,wBAAwB,CAAC,IAAI,SAAS,MAAM,IAAI;IACnD,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AA8BF,eAAO,MAAM,aAAa,GAAI,YAAY,gBAAgB;;gBAwQtC,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC;gBAE5C,MAAM,WACJ;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,GAC5B,oBAAoB,CAAC,IAAI,CAAC;SAClB,IAAI,SAAS,MAAM,SACrB,MAAM,QACP,IAAI,YACA,MAAM,GACf,oBAAoB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;SAC7B,IAAI,SAAS,MAAM,SACrB,MAAM,WACJ,wBAAwB,CAAC,IAAI,CAAC,GACtC,oBAAoB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;;gCAhBnC,OAAO,KACT,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC;mCAlQC,IAAI,SAAS,MAAM,QACxC,YAAY,CAAC,IAAI,CAAC,SACjB,YAAY,CAAC,IAAI,CAAC,WAChB,MAAM,KACd,IAAI;8BA0YiB,IAAI,SAAS,MAAM,KACtC,YAAY,CAAC,IAAI,CAAC,KAClB,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAC7B,YAAY,CAAC,IAAI,CAAC;8BAKG,IAAI,SAAS,MAAM,KACtC,YAAY,CAAC,IAAI,CAAC,KAClB,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAC7B,YAAY,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAlEG,IAAI,SAAS,MAAM,QACnC,IAAI,KACT,UAAU,CAAC,IAAI,CAAC;4CAImB,IAAI,SAAS,cAAc,QACzD,IAAI,KACT,UAAU,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;6BAS1B,CAAC,SAAS,UAAU,UACjC,CAAC,KACR,SAAS,CAAC,CAAC,CAAC;8BAKS,CAAC,SAAS,UAAU,UAClC,CAAC,KACR,aAAa,CAAC,CAAC,CAAC;+BAmBd,OAAO,KACT,CAAC,IAAI;QAAE,GAAG,EAAE,MAAM,MAAM,CAAA;KAAE;0BAyBT,IAAI,SAAS,MAAM,eACxB,YAAY,CAAC,IAAI,CAAC,gBACjB,MAAM,YACV,MAAM;0CAIL,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,WAC3B,MAAM,KACd,IAAI;;;CA8BR,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC"}
1
+ {"version":3,"file":"createCoreApi.d.ts","sourceRoot":"","sources":["../../../src/internal/createCoreApi.ts"],"names":[],"mappings":"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"}
@@ -9,35 +9,11 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
+ import { toNumber } from '../scalar';
12
13
  import { UNIT_DEFINITIONS, } from '../unitDefinitions';
13
14
  import { buildMeasurementCreationError } from './buildMeasurementCreationError';
14
- import { createErrorHelpers, } from './errors';
15
- // JS stringifies numbers in exponential form once the magnitude is >= 1e21 or
16
- // < 1e-6 (e.g. "1e+21", "1e-7"). CSS output must never contain that, so we
17
- // expand the exponent into a plain decimal by shifting the decimal point on the
18
- // digit string. This is string manipulation on the same digits, so it does not
19
- // re-introduce floating-point error.
20
- const toPlainDecimal = (value) => {
21
- const text = `${value}`;
22
- if (!text.includes('e') && !text.includes('E')) {
23
- return text;
24
- }
25
- const [mantissa, exponentText] = text.toLowerCase().split('e');
26
- const exponent = Number(exponentText);
27
- const negative = mantissa.startsWith('-');
28
- const unsigned = negative ? mantissa.slice(1) : mantissa;
29
- const [intDigits, fracDigits = ''] = unsigned.split('.');
30
- const digits = intDigits + fracDigits;
31
- const pointFromLeft = intDigits.length + exponent;
32
- const sign = negative ? '-' : '';
33
- if (pointFromLeft <= 0) {
34
- return `${sign}0.${'0'.repeat(-pointFromLeft)}${digits}`;
35
- }
36
- if (pointFromLeft >= digits.length) {
37
- return `${sign}${digits}${'0'.repeat(pointFromLeft - digits.length)}`;
38
- }
39
- return `${sign}${digits.slice(0, pointFromLeft)}.${digits.slice(pointFromLeft)}`;
40
- };
15
+ import { createErrorHelpers } from './errors';
16
+ import { toPlainDecimal } from './toPlainDecimal';
41
17
  export const createCoreApi = (errorStore) => {
42
18
  var _Measurement_instances, _a, _Measurement_value, _Measurement_unit, _Measurement_clone;
43
19
  const { throwHelperError, throwMeasurementMethodError } = createErrorHelpers(errorStore);
@@ -47,7 +23,10 @@ export const createCoreApi = (errorStore) => {
47
23
  if (leftUnit !== rightUnit) {
48
24
  throwHelperError({
49
25
  operation: 'css-calipers.assertMatchingUnits',
50
- params: [left, right],
26
+ params: [
27
+ left,
28
+ right,
29
+ ],
51
30
  message: `measurement unit mismatch: ${leftUnit} vs ${rightUnit}`,
52
31
  context,
53
32
  details: { code: 'CALIPERS_E_UNIT_MISMATCH' },
@@ -153,18 +132,20 @@ export const createCoreApi = (errorStore) => {
153
132
  return __classPrivateFieldGet(this, _Measurement_instances, "m", _Measurement_clone).call(this, next);
154
133
  }
155
134
  multiply(factor) {
156
- if (factor === 1)
135
+ const numericFactor = toNumber(factor);
136
+ if (numericFactor === 1)
157
137
  return this;
158
- if (factor === 0)
138
+ if (numericFactor === 0)
159
139
  return new _a(0, __classPrivateFieldGet(this, _Measurement_unit, "f"));
160
- if (factor === -1)
140
+ if (numericFactor === -1)
161
141
  return new _a(-__classPrivateFieldGet(this, _Measurement_value, "f"), __classPrivateFieldGet(this, _Measurement_unit, "f"));
162
- return __classPrivateFieldGet(this, _Measurement_instances, "m", _Measurement_clone).call(this, __classPrivateFieldGet(this, _Measurement_value, "f") * factor);
142
+ return __classPrivateFieldGet(this, _Measurement_instances, "m", _Measurement_clone).call(this, __classPrivateFieldGet(this, _Measurement_value, "f") * numericFactor);
163
143
  }
164
144
  divide(divisor) {
165
- if (divisor === 1)
145
+ const numericDivisor = toNumber(divisor);
146
+ if (numericDivisor === 1)
166
147
  return this;
167
- if (divisor === 0) {
148
+ if (numericDivisor === 0) {
168
149
  throwMeasurementMethodError({
169
150
  operation: 'css-calipers.Measurement.divide',
170
151
  caller: this,
@@ -173,7 +154,7 @@ export const createCoreApi = (errorStore) => {
173
154
  details: { code: 'CALIPERS_E_DIVIDE_BY_ZERO' },
174
155
  });
175
156
  }
176
- const result = __classPrivateFieldGet(this, _Measurement_value, "f") / divisor;
157
+ const result = __classPrivateFieldGet(this, _Measurement_value, "f") / numericDivisor;
177
158
  if (!Number.isFinite(result)) {
178
159
  throwMeasurementMethodError({
179
160
  operation: 'css-calipers.Measurement.divide',
@@ -195,6 +176,8 @@ export const createCoreApi = (errorStore) => {
195
176
  return shouldNegate ? __classPrivateFieldGet(this, _Measurement_instances, "m", _Measurement_clone).call(this, -__classPrivateFieldGet(this, _Measurement_value, "f")) : this;
196
177
  }
197
178
  absolute() {
179
+ // Math.abs is always >= 0, so the result is hardened to NonNegativeMeasurement
180
+ // (the governing rule: a runtime restriction must also harden the type).
198
181
  return __classPrivateFieldGet(this, _Measurement_instances, "m", _Measurement_clone).call(this, Math.abs(__classPrivateFieldGet(this, _Measurement_value, "f")));
199
182
  }
200
183
  round(precision = 0) {
@@ -218,7 +201,10 @@ export const createCoreApi = (errorStore) => {
218
201
  throwMeasurementMethodError({
219
202
  operation: 'css-calipers.Measurement.clamp',
220
203
  caller: this,
221
- params: [min, max],
204
+ params: [
205
+ min,
206
+ max,
207
+ ],
222
208
  message: 'clamp: expected finite bounds',
223
209
  details: { code: 'CALIPERS_E_CLAMP_NONFINITE_BOUNDS' },
224
210
  });
@@ -227,7 +213,10 @@ export const createCoreApi = (errorStore) => {
227
213
  throwMeasurementMethodError({
228
214
  operation: 'css-calipers.Measurement.clamp',
229
215
  caller: this,
230
- params: [min, max],
216
+ params: [
217
+ min,
218
+ max,
219
+ ],
231
220
  message: `clamp: min (${min.css()}) must be <= max (${max.css()})`,
232
221
  details: { code: 'CALIPERS_E_CLAMP_INVALID_RANGE' },
233
222
  });
@@ -299,7 +288,11 @@ export const createCoreApi = (errorStore) => {
299
288
  if (!guard(value)) {
300
289
  throwHelperError({
301
290
  operation: 'css-calipers.makeUnitAssert',
302
- params: isMeasurement(value) ? [value] : [],
291
+ params: isMeasurement(value)
292
+ ? [
293
+ value,
294
+ ]
295
+ : [],
303
296
  message: `Expected unit "${helper.unit}".`,
304
297
  context,
305
298
  details: { code: 'CALIPERS_E_ASSERT_UNIT' },
@@ -333,6 +326,74 @@ export const createCoreApi = (errorStore) => {
333
326
  });
334
327
  }
335
328
  };
329
+ // Value-constraint refinements. One factory builds the quartet (is / ensure / check /
330
+ // hardenWith) from a numeric predicate and narrows to a constraint brand. The brand is
331
+ // additive over `IMeasurement` and is dropped by arithmetic (which can cross a bound),
332
+ // so a derived result must be re-checked. `nonNegative` / `nonPositive` / `inRange(...)`
333
+ // are the built-ins.
334
+ const makeMeasurementRefinement = (spec) => {
335
+ const is = (measurement) => spec.predicate(measurement.getValue());
336
+ const ensure = (measurement, context) => {
337
+ if (!is(measurement)) {
338
+ throwHelperError({
339
+ operation: 'css-calipers.refinement.ensure',
340
+ params: [
341
+ measurement,
342
+ ],
343
+ message: spec.message(measurement),
344
+ context,
345
+ details: { code: 'CALIPERS_E_CONSTRAINT' },
346
+ });
347
+ }
348
+ // A negated generic type-guard does not narrow the fall-through to `M & B`, so the
349
+ // brand cast is necessary here (the runtime check above guarantees it holds).
350
+ return measurement;
351
+ };
352
+ const check = (measurement) => is(measurement)
353
+ ? { ok: true, value: measurement }
354
+ : {
355
+ ok: false,
356
+ value: measurement,
357
+ error: spec.message(measurement),
358
+ };
359
+ const hardenWith = (measurement, fallback) => {
360
+ if (is(measurement))
361
+ return measurement;
362
+ if (fallback !== undefined)
363
+ return fallback;
364
+ const { defaultFallback } = spec;
365
+ if (defaultFallback !== undefined) {
366
+ return createMeasurement(defaultFallback, measurement.getUnit());
367
+ }
368
+ return throwHelperError({
369
+ operation: 'css-calipers.refinement.hardenWith',
370
+ params: [
371
+ measurement,
372
+ ],
373
+ message: 'no fallback provided and this refinement has no default fallback',
374
+ details: { code: 'CALIPERS_E_CONSTRAINT' },
375
+ });
376
+ };
377
+ return { is, ensure, check, hardenWith };
378
+ };
379
+ const nonNegative = makeMeasurementRefinement({
380
+ predicate: (value) => value >= 0,
381
+ message: (measurement) => `expected a measurement >= 0 (got ${measurement.css()})`,
382
+ defaultFallback: 0,
383
+ });
384
+ const nonPositive = makeMeasurementRefinement({
385
+ predicate: (value) => value <= 0,
386
+ message: (measurement) => `expected a measurement <= 0 (got ${measurement.css()})`,
387
+ defaultFallback: 0,
388
+ });
389
+ const inRange = (min, max) => {
390
+ assertCondition(min <= max, `inRange: min (${min}) must be <= max (${max})`);
391
+ return makeMeasurementRefinement({
392
+ predicate: (value) => value >= min && value <= max,
393
+ message: (measurement) => `expected a measurement in [${min}, ${max}] (got ${measurement.css()})`,
394
+ defaultFallback: min,
395
+ });
396
+ };
336
397
  return {
337
398
  m,
338
399
  isMeasurement,
@@ -347,6 +408,10 @@ export const createCoreApi = (errorStore) => {
347
408
  hasCssMethod,
348
409
  assertUnit,
349
410
  assertCondition,
411
+ makeMeasurementRefinement,
412
+ nonNegative,
413
+ nonPositive,
414
+ inRange,
350
415
  getErrorConfig: errorStore.getErrorConfig,
351
416
  setErrorConfig: errorStore.setErrorConfig,
352
417
  };
@@ -1,4 +1,4 @@
1
- import type { UnitHelper, UnitGuard, UnitAssertion } from '../core';
1
+ import type { UnitAssertion, UnitGuard, UnitHelper } from '../core';
2
2
  import type { UnitDefinitionRecord, UnitHelperName } from '../unitDefinitions';
3
3
  import type { CoreApi } from './createCoreApi';
4
4
  type UnitHelpersMap = {
@@ -1 +1 @@
1
- {"version":3,"file":"createUnitsApi.d.ts","sourceRoot":"","sources":["../../../src/internal/createUnitsApi.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,KAAK,cAAc,GAAG;KACnB,CAAC,IAAI,cAAc,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CACnE,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG;IACtC,oBAAoB,EAAE,SAAS,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC5D,wBAAwB,EAAE,aAAa,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;CACrE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,OAAO,KAAG,QAmB9C,CAAC"}
1
+ {"version":3,"file":"createUnitsApi.d.ts","sourceRoot":"","sources":["../../../src/internal/createUnitsApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,KAAK,cAAc,GAAG;KACnB,CAAC,IAAI,cAAc,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CACnE,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG;IACtC,oBAAoB,EAAE,SAAS,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC5D,wBAAwB,EAAE,aAAa,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;CACrE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,OAAO,KAAG,QAiB9C,CAAC"}
@@ -1,12 +1,12 @@
1
- import type { IMeasurement } from "../core";
2
- export type ErrorCode = "CALIPERS_E_NONFINITE" | "CALIPERS_E_UNIT_MISMATCH" | "CALIPERS_E_ASSERT_UNIT" | "CALIPERS_E_ASSERT_CONDITION" | "CALIPERS_E_ASSERT_PREDICATE" | "CALIPERS_E_DIVIDE_BY_ZERO" | "CALIPERS_E_NONFINITE_RESULT" | "CALIPERS_E_CLAMP_NONFINITE_BOUNDS" | "CALIPERS_E_CLAMP_INVALID_RANGE";
1
+ import type { IMeasurement } from '../core';
2
+ export type ErrorCode = 'CALIPERS_E_NONFINITE' | 'CALIPERS_E_UNIT_MISMATCH' | 'CALIPERS_E_ASSERT_UNIT' | 'CALIPERS_E_ASSERT_CONDITION' | 'CALIPERS_E_ASSERT_PREDICATE' | 'CALIPERS_E_CONSTRAINT' | 'CALIPERS_E_DIVIDE_BY_ZERO' | 'CALIPERS_E_NONFINITE_RESULT' | 'CALIPERS_E_CLAMP_NONFINITE_BOUNDS' | 'CALIPERS_E_CLAMP_INVALID_RANGE';
3
3
  export interface ErrorDetails {
4
4
  code?: ErrorCode;
5
5
  helper?: string;
6
6
  inputSummary?: string;
7
7
  stackHint?: string;
8
8
  }
9
- export type StackHintMode = "auto" | "on" | "off";
9
+ export type StackHintMode = 'auto' | 'on' | 'off';
10
10
  export interface ErrorConfig {
11
11
  stackHints?: StackHintMode;
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/internal/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,SAAS,GACjB,sBAAsB,GACtB,0BAA0B,GAC1B,wBAAwB,GACxB,6BAA6B,GAC7B,6BAA6B,GAC7B,2BAA2B,GAC3B,6BAA6B,GAC7B,mCAAmC,GACnC,gCAAgC,CAAC;AAErC,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,CAAC;AAElD,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC5C,cAAc,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;CAC7C,CAAC;AAEF,MAAM,WAAW,6BAA6B;IAC5C,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7B,kEAAkE;IAClE,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;IAC/B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;IAC/B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAQD,eAAO,MAAM,sBAAsB,GACjC,UAAS,WAAgB,KACxB,gBAWF,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,WAAW,KAAG,IAElD,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,QAAQ,CAAC,WAAW,CAAgB,CAAC;AAEvE,eAAO,MAAM,kBAAkB,GAAI,OAAO,gBAAgB;uCAIjD,6BAA6B,KACjC,KAAK;4BAeuB,kBAAkB,KAAG,KAAK;CAgB1D,CAAC;AA4DF,mFAAmF;AACnF,eAAO,MAAM,2BAA2B,GACtC,KAAK,6BAA6B,KACjC,KAWF,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,GAAI,KAAK,kBAAkB,KAAG,KAW1D,CAAC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/internal/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,SAAS,GACjB,sBAAsB,GACtB,0BAA0B,GAC1B,wBAAwB,GACxB,6BAA6B,GAC7B,6BAA6B,GAC7B,uBAAuB,GACvB,2BAA2B,GAC3B,6BAA6B,GAC7B,mCAAmC,GACnC,gCAAgC,CAAC;AAErC,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,CAAC;AAElD,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC5C,cAAc,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;CAC7C,CAAC;AAEF,MAAM,WAAW,6BAA6B;IAC5C,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7B,kEAAkE;IAClE,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;IAC/B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;IAC/B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAQD,eAAO,MAAM,sBAAsB,GACjC,UAAS,WAAgB,KACxB,gBAWF,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,WAAW,KAAG,IAElD,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,QAAQ,CAAC,WAAW,CACzC,CAAC;AAEd,eAAO,MAAM,kBAAkB,GAAI,OAAO,gBAAgB;uCAIjD,6BAA6B,KACjC,KAAK;4BAeuB,kBAAkB,KAAG,KAAK;CAgB1D,CAAC;AA6DF,mFAAmF;AACnF,eAAO,MAAM,2BAA2B,GACtC,KAAK,6BAA6B,KACjC,KAWF,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,GAAI,KAAK,kBAAkB,KAAG,KAW1D,CAAC"}
@@ -1,5 +1,5 @@
1
1
  const DEFAULT_ERROR_CONFIG = {
2
- stackHints: "auto",
2
+ stackHints: 'auto',
3
3
  };
4
4
  let errorConfig = { ...DEFAULT_ERROR_CONFIG };
5
5
  export const createErrorConfigStore = (initial = {}) => {
@@ -44,18 +44,17 @@ export const createErrorHelpers = (store) => {
44
44
  };
45
45
  const isProductionEnv = () => {
46
46
  var _a;
47
- if (typeof globalThis === "undefined")
47
+ if (typeof globalThis === 'undefined')
48
48
  return false;
49
- const maybeProcess = globalThis
50
- .process;
51
- return ((_a = maybeProcess === null || maybeProcess === void 0 ? void 0 : maybeProcess.env) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === "production";
49
+ const maybeProcess = globalThis.process;
50
+ return ((_a = maybeProcess === null || maybeProcess === void 0 ? void 0 : maybeProcess.env) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === 'production';
52
51
  };
53
52
  const shouldIncludeStackHint = (override, config = errorConfig) => {
54
53
  if (override === false)
55
54
  return false;
56
- if (config.stackHints === "off")
55
+ if (config.stackHints === 'off')
57
56
  return false;
58
- if (config.stackHints === "on")
57
+ if (config.stackHints === 'on')
59
58
  return true;
60
59
  if (override === true)
61
60
  return !isProductionEnv();
@@ -63,7 +62,7 @@ const shouldIncludeStackHint = (override, config = errorConfig) => {
63
62
  };
64
63
  const formatDetailBlock = (details) => {
65
64
  if (!details)
66
- return "";
65
+ return '';
67
66
  const parts = [];
68
67
  if (details.code)
69
68
  parts.push(`code=${details.code}`);
@@ -73,7 +72,7 @@ const formatDetailBlock = (details) => {
73
72
  parts.push(`inputs=${details.inputSummary}`);
74
73
  if (details.stackHint)
75
74
  parts.push(`stack=${details.stackHint}`);
76
- return parts.length > 0 ? ` [${parts.join(" | ")}]` : "";
75
+ return parts.length > 0 ? ` [${parts.join(' | ')}]` : '';
77
76
  };
78
77
  const formatErrorMessage = (operation, message, context, details) => {
79
78
  const core = `${operation}: ${message}`;
@@ -85,17 +84,17 @@ const extractStackHint = (stack) => {
85
84
  if (!stack)
86
85
  return undefined;
87
86
  const lines = stack
88
- .split("\n")
87
+ .split('\n')
89
88
  .map((line) => line.trim())
90
89
  .filter(Boolean)
91
90
  .slice(1);
92
91
  if (lines.length === 0)
93
92
  return undefined;
94
- const filtered = lines.filter((line) => !line.includes("/src/internal/errors") &&
95
- !line.includes("throwHelperError") &&
96
- !line.includes("throwMeasurementMethodError"));
93
+ const filtered = lines.filter((line) => !line.includes('/src/internal/errors') &&
94
+ !line.includes('throwHelperError') &&
95
+ !line.includes('throwMeasurementMethodError'));
97
96
  const hint = (_a = filtered[0]) !== null && _a !== void 0 ? _a : lines[0];
98
- return hint.replace(/^at\s+/, "");
97
+ return hint.replace(/^at\s+/, '');
99
98
  };
100
99
  /** Throw an Error for a Measurement instance method using a structured context. */
101
100
  export const throwMeasurementMethodError = (ctx) => {
@@ -0,0 +1,2 @@
1
+ export declare const toPlainDecimal: (value: number) => string;
2
+ //# sourceMappingURL=toPlainDecimal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toPlainDecimal.d.ts","sourceRoot":"","sources":["../../../src/internal/toPlainDecimal.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MA2B9C,CAAC"}
@@ -0,0 +1,27 @@
1
+ // JS stringifies numbers in exponential form once the magnitude is >= 1e21 or
2
+ // < 1e-6 (e.g. "1e+21", "1e-7"). CSS output must never contain that, so we
3
+ // expand the exponent into a plain decimal by shifting the decimal point on the
4
+ // digit string. This is string manipulation on the same digits, so it does not
5
+ // re-introduce floating-point error. Shared by the measurement core and the
6
+ // scalar (float / integer) primitives so every `.css()` renders the same way.
7
+ export const toPlainDecimal = (value) => {
8
+ const text = `${value}`;
9
+ if (!text.includes('e') && !text.includes('E')) {
10
+ return text;
11
+ }
12
+ const [mantissa, exponentText,] = text.toLowerCase().split('e');
13
+ const exponent = Number(exponentText);
14
+ const negative = mantissa.startsWith('-');
15
+ const unsigned = negative ? mantissa.slice(1) : mantissa;
16
+ const [intDigits, fracDigits = '',] = unsigned.split('.');
17
+ const digits = intDigits + fracDigits;
18
+ const pointFromLeft = intDigits.length + exponent;
19
+ const sign = negative ? '-' : '';
20
+ if (pointFromLeft <= 0) {
21
+ return `${sign}0.${'0'.repeat(-pointFromLeft)}${digits}`;
22
+ }
23
+ if (pointFromLeft >= digits.length) {
24
+ return `${sign}${digits}${'0'.repeat(pointFromLeft - digits.length)}`;
25
+ }
26
+ return `${sign}${digits.slice(0, pointFromLeft)}.${digits.slice(pointFromLeft)}`;
27
+ };
@@ -0,0 +1,16 @@
1
+ export * from './core';
2
+ export * from './default';
3
+ export * from './units/absolute';
4
+ export * from './units/angle';
5
+ export * from './units/container';
6
+ export * from './units/font-relative';
7
+ export * from './units/frequency';
8
+ export * from './units/grid';
9
+ export * from './units/percent';
10
+ export * from './units/resolution';
11
+ export * from './units/time';
12
+ export * from './units/viewport';
13
+ export * from './units/viewport-dynamic';
14
+ export * from './units/viewport-large';
15
+ export * from './units/viewport-small';
16
+ //# sourceMappingURL=measurements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measurements.d.ts","sourceRoot":"","sources":["../../src/measurements.ts"],"names":[],"mappings":"AAQA,cAAc,QAAQ,CAAC;AAGvB,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC"}