@px-petals/roku.motion-web 0.0.0-stage → 1.1.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 (99) hide show
  1. package/LICENSE +201 -0
  2. package/audio/audio.cues.js +27 -0
  3. package/audio/audio.js +259 -0
  4. package/bands/bands.js +392 -0
  5. package/bundle/bundle.fonts.js +55 -0
  6. package/bundle/bundle.js +131 -0
  7. package/focus/focus.direction.js +46 -0
  8. package/focus/focus.dom.js +158 -0
  9. package/focus/focus.js +277 -0
  10. package/focus/focus.tree.js +146 -0
  11. package/hit/hit.geometry.js +113 -0
  12. package/hit/hit.js +129 -0
  13. package/list/list.flex.js +181 -0
  14. package/list/list.items.js +80 -0
  15. package/list/list.js +518 -0
  16. package/lottie/lottie.js +124 -0
  17. package/lottie/lottie.layers.js +416 -0
  18. package/lottie/lottie.paint.js +238 -0
  19. package/lottie/lottie.paths.js +474 -0
  20. package/lottie/lottie.props.js +265 -0
  21. package/lottie/lottie.shapes.js +259 -0
  22. package/mixer/mixer.js +307 -0
  23. package/mixer/mixer.mix.js +107 -0
  24. package/mixer/mixer.stage.js +431 -0
  25. package/motion/motion.convert.js +404 -0
  26. package/motion/motion.flow.js +421 -0
  27. package/motion/motion.keys.js +150 -0
  28. package/motion/motion.machine.js +382 -0
  29. package/motion/motion.nested.js +345 -0
  30. package/motion/motion.values.js +368 -0
  31. package/motion.js +1155 -0
  32. package/package.json +47 -4
  33. package/player/overlay/overlay.js +325 -0
  34. package/player/overlay/overlay.layout.js +208 -0
  35. package/player/player.fit.js +101 -0
  36. package/player/player.js +421 -0
  37. package/player/player.raster.js +127 -0
  38. package/pointer/pointer.js +292 -0
  39. package/readme.md +345 -0
  40. package/script/luau/lib/base/base.js +202 -0
  41. package/script/luau/lib/base/base.table.js +189 -0
  42. package/script/luau/lib/lib.args.js +152 -0
  43. package/script/luau/lib/lib.js +23 -0
  44. package/script/luau/lib/math/math.bit32.js +144 -0
  45. package/script/luau/lib/math/math.js +288 -0
  46. package/script/luau/lib/math/math.vector.js +125 -0
  47. package/script/luau/lib/string/string.format.js +143 -0
  48. package/script/luau/lib/string/string.js +160 -0
  49. package/script/luau/lib/string/string.pattern.js +505 -0
  50. package/script/luau/load/load.js +362 -0
  51. package/script/luau/load/load.ops.js +79 -0
  52. package/script/luau/luau.convert.js +259 -0
  53. package/script/luau/luau.js +132 -0
  54. package/script/luau/luau.md +111 -0
  55. package/script/luau/vm/vm.js +167 -0
  56. package/script/luau/vm/vm.meta.js +401 -0
  57. package/script/luau/vm/vm.num.js +236 -0
  58. package/script/luau/vm/vm.run.js +842 -0
  59. package/script/luau/vm/vm.value.js +406 -0
  60. package/script/play/play.js +199 -0
  61. package/script/play/play.objects.js +295 -0
  62. package/script/play/play.scope.js +91 -0
  63. package/script/rive/api/api.statics.js +31 -0
  64. package/script/rive/api/api.type.js +188 -0
  65. package/script/rive/api/artboard/artboard.js +89 -0
  66. package/script/rive/api/assets/assets.js +72 -0
  67. package/script/rive/api/data/data.value.js +99 -0
  68. package/script/rive/api/draw/draw.contours.js +163 -0
  69. package/script/rive/api/draw/draw.measure.js +196 -0
  70. package/script/rive/api/draw/draw.paint.js +235 -0
  71. package/script/rive/api/draw/draw.path.js +153 -0
  72. package/script/rive/api/draw/draw.renderer.js +117 -0
  73. package/script/rive/api/math/math.color.js +96 -0
  74. package/script/rive/api/math/math.mat2d.js +180 -0
  75. package/script/rive/api/math/math.vector.js +121 -0
  76. package/script/rive/api/media/media.audio.js +113 -0
  77. package/script/rive/api/media/media.draw.js +73 -0
  78. package/script/rive/api/media/media.image.js +61 -0
  79. package/script/rive/api/media/media.mesh.js +50 -0
  80. package/script/rive/api/pointer/pointer.event.js +64 -0
  81. package/script/rive/api/pointer/pointer.route.js +69 -0
  82. package/script/rive/api/text/text.font.js +129 -0
  83. package/script/rive/api/text/text.js +278 -0
  84. package/script/rive/api/text/text.layout.js +259 -0
  85. package/script/rive/context/context.js +76 -0
  86. package/script/rive/context/context.memory.js +196 -0
  87. package/script/rive/context/context.viewmodel.js +302 -0
  88. package/script/rive/context/lists/lists.js +160 -0
  89. package/script/rive/context/lists/lists.values.js +281 -0
  90. package/script/rive/host/host.globals.js +44 -0
  91. package/script/rive/host/host.js +533 -0
  92. package/script/rive/host/host.node.js +45 -0
  93. package/script/rive/rive.js +23 -0
  94. package/script/rive/rive.md +180 -0
  95. package/script/script.js +11 -0
  96. package/skin/skin.deform.js +514 -0
  97. package/skin/skin.ik.js +260 -0
  98. package/skin/skin.js +297 -0
  99. package/README.md +0 -3
@@ -0,0 +1,288 @@
1
+ /**
2
+ * The `math` library, and `os`. Functions ES5 lacks (`sinh`, `log10`, `sign`,
3
+ * ...) are written out, because the oldest browsers this runs in lack them.
4
+ */
5
+
6
+ import { LuaTable } from '../../vm/vm.value.js'
7
+ import { sign, trunc } from '../../vm/vm.num.js'
8
+ import { argError, checkInt, checkNumber, optNumber, register } from '../lib.args.js'
9
+
10
+ /**
11
+ * @param {number} x
12
+ * @returns {number}
13
+ */
14
+ function sinh(x) {
15
+ return (Math.exp(x) - Math.exp(-x)) / 2
16
+ }
17
+
18
+ /**
19
+ * @param {number} x
20
+ * @returns {number}
21
+ */
22
+ function cosh(x) {
23
+ return (Math.exp(x) + Math.exp(-x)) / 2
24
+ }
25
+
26
+ /**
27
+ * @param {number} x
28
+ * @returns {number}
29
+ */
30
+ function tanh(x) {
31
+ if (x > 20) return 1
32
+ if (x < -20) return -1
33
+ const a = Math.exp(2 * x)
34
+ return (a - 1) / (a + 1)
35
+ }
36
+
37
+ /**
38
+ * The log of x in base `b`, exact where x is a power of b.
39
+ *
40
+ * @param {number} x
41
+ * @param {number} lnb the natural log of the base
42
+ * @param {number} b
43
+ * @returns {number}
44
+ */
45
+ function logBase(x, lnb, b) {
46
+ const r = Math.log(x) / lnb
47
+ const rounded = Math.round(r)
48
+ return Math.abs(r - rounded) < 1e-9 && Math.pow(b, rounded) === x ? rounded : r
49
+ }
50
+
51
+ /**
52
+ * A small deterministic generator (mulberry32), 32 bits of state.
53
+ *
54
+ * @param {number} seed
55
+ */
56
+ function makeRandom(seed) {
57
+ let state = seed >>> 0
58
+ return function () {
59
+ state = (state + 0x6d2b79f5) >>> 0
60
+ let t = state
61
+ t = Math.imul(t ^ (t >>> 15), t | 1)
62
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61)
63
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296
64
+ }
65
+ }
66
+
67
+ /**
68
+ * @param {import('../../vm/vm.js').VM} vm
69
+ * @param {LuaTable} G
70
+ */
71
+ export function installMath(vm, G) {
72
+ const math = new LuaTable()
73
+ G.set('math', math)
74
+ let random = makeRandom(0x2545f491)
75
+
76
+ /**
77
+ * One-argument functions.
78
+ *
79
+ * @param {string} name
80
+ * @param {(x: number) => number} f
81
+ */
82
+ const unary = function (name, f) {
83
+ math.set(name, vm.native('math.' + name, function (vm2, args) {
84
+ return f(checkNumber(args, 0, name))
85
+ }))
86
+ }
87
+
88
+ unary('abs', Math.abs)
89
+ unary('acos', Math.acos)
90
+ unary('asin', Math.asin)
91
+ unary('atan', Math.atan)
92
+ unary('ceil', Math.ceil)
93
+ unary('cos', Math.cos)
94
+ unary('cosh', cosh)
95
+ unary('deg', function (x) { return x * (180 / Math.PI) })
96
+ unary('exp', Math.exp)
97
+ unary('floor', Math.floor)
98
+ unary('log10', function (x) { return logBase(x, Math.LN10, 10) })
99
+ unary('rad', function (x) { return x * (Math.PI / 180) })
100
+ unary('sin', Math.sin)
101
+ unary('sinh', sinh)
102
+ unary('sqrt', Math.sqrt)
103
+ unary('tan', Math.tan)
104
+ unary('tanh', tanh)
105
+ unary('sign', sign)
106
+ unary('round', function (x) { return x < 0 ? -Math.floor(-x + 0.5) : Math.floor(x + 0.5) })
107
+ unary('isnan', function (x) { return /** @type {any} */ (x !== x) })
108
+ unary('isinf', function (x) { return /** @type {any} */ (x === Infinity || x === -Infinity) })
109
+ unary('isfinite', function (x) { return /** @type {any} */ (x === x && x !== Infinity && x !== -Infinity) })
110
+
111
+ register(math, {
112
+ atan2(vm, args) {
113
+ return Math.atan2(checkNumber(args, 0, 'atan2'), checkNumber(args, 1, 'atan2'))
114
+ },
115
+
116
+ fmod(vm, args) {
117
+ return checkNumber(args, 0, 'fmod') % checkNumber(args, 1, 'fmod')
118
+ },
119
+
120
+ frexp(vm, args) {
121
+ const x = checkNumber(args, 0, 'frexp')
122
+ if (x === 0 || x !== x || x === Infinity || x === -Infinity) return [ x, 0 ]
123
+ let e = Math.max(-1023, Math.floor(logBase(Math.abs(x), Math.LN2, 2)) + 1)
124
+ let m = x * Math.pow(2, -e)
125
+ while (Math.abs(m) < 0.5) {
126
+ m *= 2
127
+ e--
128
+ }
129
+ while (Math.abs(m) >= 1) {
130
+ m /= 2
131
+ e++
132
+ }
133
+ return [ m, e ]
134
+ },
135
+
136
+ ldexp(vm, args) {
137
+ return checkNumber(args, 0, 'ldexp') * Math.pow(2, checkInt(args, 1, 'ldexp'))
138
+ },
139
+
140
+ log(vm, args) {
141
+ const x = checkNumber(args, 0, 'log')
142
+ if (args[1] === undefined) return Math.log(x)
143
+ const b = checkNumber(args, 1, 'log')
144
+ if (b === 2) return logBase(x, Math.LN2, 2)
145
+ if (b === 10) return logBase(x, Math.LN10, 10)
146
+ return Math.log(x) / Math.log(b)
147
+ },
148
+
149
+ max(vm, args) {
150
+ let m = checkNumber(args, 0, 'max')
151
+ for (let i = 1; i < args.length; i++) {
152
+ const v = checkNumber(args, i, 'max')
153
+ if (v > m) m = v
154
+ }
155
+ return m
156
+ },
157
+
158
+ min(vm, args) {
159
+ let m = checkNumber(args, 0, 'min')
160
+ for (let i = 1; i < args.length; i++) {
161
+ const v = checkNumber(args, i, 'min')
162
+ if (v < m) m = v
163
+ }
164
+ return m
165
+ },
166
+
167
+ modf(vm, args) {
168
+ const x = checkNumber(args, 0, 'modf')
169
+ const whole = trunc(x)
170
+ return [ whole, x - whole ]
171
+ },
172
+
173
+ pow(vm, args) {
174
+ return Math.pow(checkNumber(args, 0, 'pow'), checkNumber(args, 1, 'pow'))
175
+ },
176
+
177
+ clamp(vm, args) {
178
+ const v = checkNumber(args, 0, 'clamp')
179
+ const lo = checkNumber(args, 1, 'clamp')
180
+ const hi = checkNumber(args, 2, 'clamp')
181
+ if (lo > hi) throw argError(3, 'clamp', 'max must be greater than min')
182
+ return v < lo ? lo : v > hi ? hi : v
183
+ },
184
+
185
+ lerp(vm, args) {
186
+ const a = checkNumber(args, 0, 'lerp')
187
+ const b = checkNumber(args, 1, 'lerp')
188
+ const t = checkNumber(args, 2, 'lerp')
189
+ return t === 1 ? b : a + (b - a) * t
190
+ },
191
+
192
+ random(vm, args) {
193
+ const r = random()
194
+ if (args.length === 0) return r
195
+ const lo = args.length === 1 ? 1 : checkInt(args, 0, 'random')
196
+ const hi = checkInt(args, args.length === 1 ? 0 : 1, 'random')
197
+ if (lo > hi) throw argError(args.length === 1 ? 1 : 2, 'random', 'interval is empty')
198
+ return lo + Math.floor(r * (hi - lo + 1))
199
+ },
200
+
201
+ randomseed(vm, args) {
202
+ random = makeRandom(checkInt(args, 0, 'randomseed'))
203
+ return []
204
+ },
205
+
206
+ noise(vm, args) {
207
+ return noise(checkNumber(args, 0, 'noise'), optNumber(args, 1, 'noise', 0), optNumber(args, 2, 'noise', 0))
208
+ },
209
+ }, 'math.')
210
+
211
+ math.set('pi', Math.PI)
212
+ math.set('huge', Infinity)
213
+
214
+ // os
215
+ const os = new LuaTable()
216
+ G.set('os', os)
217
+ register(os, {
218
+ clock() {
219
+ return now() / 1000
220
+ },
221
+ time() {
222
+ return Math.floor(Date.now() / 1000)
223
+ },
224
+ }, 'os.')
225
+ }
226
+
227
+ /** @returns {number} milliseconds, from a clock that only moves forward where the host has one */
228
+ function now() {
229
+ const perf = typeof performance !== 'undefined' ? performance : null
230
+ return perf !== null && typeof perf.now === 'function' ? perf.now() : Date.now()
231
+ }
232
+
233
+ /**
234
+ * Perlin gradient noise in 1 to 3 dimensions, in about -1..1.
235
+ *
236
+ * @param {number} x
237
+ * @param {number} y
238
+ * @param {number} z
239
+ * @returns {number}
240
+ */
241
+ function noise(x, y, z) {
242
+ const xi = Math.floor(x)
243
+ const yi = Math.floor(y)
244
+ const zi = Math.floor(z)
245
+ const xf = x - xi
246
+ const yf = y - yi
247
+ const zf = z - zi
248
+ /** @param {number} t */
249
+ const fade = function (t) { return t * t * t * (t * (t * 6 - 15) + 10) }
250
+ /**
251
+ * @param {number} a
252
+ * @param {number} b
253
+ * @param {number} c
254
+ */
255
+ const hash = function (a, b, c) {
256
+ let h = Math.imul(a, 374761393) + Math.imul(b, 668265263) + Math.imul(c, 1274126177)
257
+ h = Math.imul(h ^ (h >>> 13), 1274126177)
258
+ return (h ^ (h >>> 16)) & 15
259
+ }
260
+ /**
261
+ * @param {number} h
262
+ * @param {number} dx
263
+ * @param {number} dy
264
+ * @param {number} dz
265
+ */
266
+ const grad = function (h, dx, dy, dz) {
267
+ const u = h < 8 ? dx : dy
268
+ const v = h < 4 ? dy : h === 12 || h === 14 ? dx : dz
269
+ return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v)
270
+ }
271
+ const u = fade(xf)
272
+ const v = fade(yf)
273
+ const w = fade(zf)
274
+ /**
275
+ * @param {number} a
276
+ * @param {number} b
277
+ * @param {number} t
278
+ */
279
+ const lerp = function (a, b, t) { return a + (b - a) * t }
280
+ const c = function (/** @type {number} */ dx, /** @type {number} */ dy, /** @type {number} */ dz) {
281
+ return grad(hash(xi + dx, yi + dy, zi + dz), xf - dx, yf - dy, zf - dz)
282
+ }
283
+ return lerp(
284
+ lerp(lerp(c(0, 0, 0), c(1, 0, 0), u), lerp(c(0, 1, 0), c(1, 1, 0), u), v),
285
+ lerp(lerp(c(0, 0, 1), c(1, 0, 1), u), lerp(c(0, 1, 1), c(1, 1, 1), u), v),
286
+ w,
287
+ )
288
+ }
@@ -0,0 +1,125 @@
1
+ /**
2
+ * The `vector` library: the three-component vector value's functions.
3
+ */
4
+
5
+ import { LuaTable, Vector, fround } from '../../vm/vm.value.js'
6
+ import { sign } from '../../vm/vm.num.js'
7
+ import { checkNumber, register, typeError } from '../lib.args.js'
8
+
9
+ /**
10
+ * @param {any[]} args
11
+ * @param {number} i
12
+ * @param {string} name
13
+ * @returns {Vector}
14
+ */
15
+ function checkVector(args, i, name) {
16
+ const v = args[i]
17
+ if (!(v instanceof Vector)) throw typeError(args, i, name, 'vector')
18
+ return v
19
+ }
20
+
21
+ /**
22
+ * @param {Vector} v
23
+ * @returns {number}
24
+ */
25
+ function magnitude(v) {
26
+ return fround(Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z))
27
+ }
28
+
29
+ /**
30
+ * @param {import('../../vm/vm.js').VM} vm
31
+ * @param {LuaTable} G
32
+ */
33
+ export function installVector(vm, G) {
34
+ const lib = new LuaTable()
35
+ G.set('vector', lib)
36
+
37
+ /**
38
+ * A function of one vector that maps each component.
39
+ *
40
+ * @param {string} name
41
+ * @param {(n: number) => number} f
42
+ */
43
+ const mapped = function (name, f) {
44
+ lib.set(name, vm.native('vector.' + name, function (vm2, args) {
45
+ const v = checkVector(args, 0, name)
46
+ return new Vector(f(v.x), f(v.y), f(v.z))
47
+ }))
48
+ }
49
+ mapped('floor', Math.floor)
50
+ mapped('ceil', Math.ceil)
51
+ mapped('abs', Math.abs)
52
+ mapped('sign', sign)
53
+
54
+ register(lib, {
55
+ create(vm, args) {
56
+ return new Vector(checkNumber(args, 0, 'create'), checkNumber(args, 1, 'create'), args[2] === undefined ? 0 : checkNumber(args, 2, 'create'))
57
+ },
58
+
59
+ magnitude(vm, args) {
60
+ return magnitude(checkVector(args, 0, 'magnitude'))
61
+ },
62
+
63
+ normalize(vm, args) {
64
+ const v = checkVector(args, 0, 'normalize')
65
+ const m = magnitude(v)
66
+ return new Vector(v.x / m, v.y / m, v.z / m)
67
+ },
68
+
69
+ dot(vm, args) {
70
+ const a = checkVector(args, 0, 'dot')
71
+ const b = checkVector(args, 1, 'dot')
72
+ return fround(a.x * b.x + a.y * b.y + a.z * b.z)
73
+ },
74
+
75
+ cross(vm, args) {
76
+ const a = checkVector(args, 0, 'cross')
77
+ const b = checkVector(args, 1, 'cross')
78
+ return new Vector(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x)
79
+ },
80
+
81
+ angle(vm, args) {
82
+ const a = checkVector(args, 0, 'angle')
83
+ const b = checkVector(args, 1, 'angle')
84
+ const cx = a.y * b.z - a.z * b.y
85
+ const cy = a.z * b.x - a.x * b.z
86
+ const cz = a.x * b.y - a.y * b.x
87
+ return Math.atan2(Math.sqrt(cx * cx + cy * cy + cz * cz), a.x * b.x + a.y * b.y + a.z * b.z)
88
+ },
89
+
90
+ clamp(vm, args) {
91
+ const v = checkVector(args, 0, 'clamp')
92
+ const lo = checkVector(args, 1, 'clamp')
93
+ const hi = checkVector(args, 2, 'clamp')
94
+ return new Vector(Math.min(Math.max(v.x, lo.x), hi.x), Math.min(Math.max(v.y, lo.y), hi.y), Math.min(Math.max(v.z, lo.z), hi.z))
95
+ },
96
+
97
+ min(vm, args) {
98
+ let r = checkVector(args, 0, 'min')
99
+ for (let i = 1; i < args.length; i++) {
100
+ const v = checkVector(args, i, 'min')
101
+ r = new Vector(Math.min(r.x, v.x), Math.min(r.y, v.y), Math.min(r.z, v.z))
102
+ }
103
+ return r
104
+ },
105
+
106
+ max(vm, args) {
107
+ let r = checkVector(args, 0, 'max')
108
+ for (let i = 1; i < args.length; i++) {
109
+ const v = checkVector(args, i, 'max')
110
+ r = new Vector(Math.max(r.x, v.x), Math.max(r.y, v.y), Math.max(r.z, v.z))
111
+ }
112
+ return r
113
+ },
114
+
115
+ lerp(vm, args) {
116
+ const a = checkVector(args, 0, 'lerp')
117
+ const b = checkVector(args, 1, 'lerp')
118
+ const t = checkNumber(args, 2, 'lerp')
119
+ return new Vector(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t)
120
+ },
121
+ }, 'vector.')
122
+
123
+ lib.set('zero', new Vector(0, 0, 0))
124
+ lib.set('one', new Vector(1, 1, 1))
125
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * `string.format`: C's printf conversions as Lua uses them.
3
+ */
4
+
5
+ import { fail } from '../../vm/vm.value.js'
6
+ import { formatE, formatF, formatG, repeat, trunc } from '../../vm/vm.num.js'
7
+ import { checkNumber, checkString } from '../lib.args.js'
8
+
9
+ const SPEC = /^%([-+ #0]*)(\d*)(?:\.(\d*))?([a-zA-Z%])/
10
+
11
+ /**
12
+ * Pads `body` (with its sign or prefix split off) to `width`.
13
+ *
14
+ * @param {string} sign '-', '+', ' ', a `0x` prefix or ''
15
+ * @param {string} body
16
+ * @param {number} width
17
+ * @param {string} flags
18
+ * @param {boolean} zeroOk whether the 0 flag pads with zeros here
19
+ * @returns {string}
20
+ */
21
+ function pad(sign, body, width, flags, zeroOk) {
22
+ const n = width - sign.length - body.length
23
+ if (n <= 0) return sign + body
24
+ if (flags.indexOf('-') >= 0) return sign + body + repeat(' ', n)
25
+ if (flags.indexOf('0') >= 0 && zeroOk) return sign + repeat('0', n) + body
26
+ return repeat(' ', n) + sign + body
27
+ }
28
+
29
+ /**
30
+ * @param {string} s
31
+ * @returns {string} s as a Lua string literal that reads back as s (`%q`)
32
+ */
33
+ function quote(s) {
34
+ let out = '"'
35
+ for (let i = 0; i < s.length; i++) {
36
+ const c = s.charCodeAt(i)
37
+ const ch = s.charAt(i)
38
+ if (ch === '"' || ch === '\\') out += '\\' + ch
39
+ else if (c === 10) out += '\\\n'
40
+ else if (c === 13) out += '\\r'
41
+ else if (c === 0) out += '\\000'
42
+ else out += ch
43
+ }
44
+ return out + '"'
45
+ }
46
+
47
+ /**
48
+ * @param {import('../../vm/vm.js').VM} vm
49
+ * @param {any[]} args the format string, then the values
50
+ * @returns {string}
51
+ */
52
+ export function format(vm, args) {
53
+ const fmt = checkString(args, 0, 'format')
54
+ let out = ''
55
+ let arg = 0
56
+ let i = 0
57
+ while (i < fmt.length) {
58
+ const pct = fmt.indexOf('%', i)
59
+ if (pct < 0) {
60
+ out += fmt.substring(i)
61
+ break
62
+ }
63
+ out += fmt.substring(i, pct)
64
+ const m = SPEC.exec(fmt.substring(pct))
65
+ if (m === null) throw fail("invalid option '%" + fmt.charAt(pct + 1) + "' to 'format'")
66
+ i = pct + m[0].length
67
+ const flags = m[1]
68
+ const width = m[2] === '' ? 0 : parseInt(m[2], 10)
69
+ const hasPrecision = m[3] !== undefined
70
+ const precision = hasPrecision ? (m[3] === '' ? 0 : parseInt(m[3], 10)) : -1
71
+ const conv = m[4]
72
+ if (conv === '%') {
73
+ out += '%'
74
+ continue
75
+ }
76
+ arg++
77
+ if (arg >= args.length) throw fail('missing argument #' + (arg + 1))
78
+ const signOf = function (/** @type {boolean} */ negative) {
79
+ return negative ? '-' : flags.indexOf('+') >= 0 ? '+' : flags.indexOf(' ') >= 0 ? ' ' : ''
80
+ }
81
+ switch (conv) {
82
+ case 'd':
83
+ case 'i':
84
+ case 'u': {
85
+ const n = trunc(checkNumber(args, arg, 'format'))
86
+ let body = String(Math.abs(n))
87
+ if (hasPrecision) while (body.length < precision) body = '0' + body
88
+ out += pad(signOf(n < 0), body, width, flags, !hasPrecision)
89
+ break
90
+ }
91
+ case 'c':
92
+ out += pad('', String.fromCharCode(trunc(checkNumber(args, arg, 'format')) & 255), width, flags, false)
93
+ break
94
+ case 'x':
95
+ case 'X':
96
+ case 'o': {
97
+ let n = trunc(checkNumber(args, arg, 'format'))
98
+ if (n < 0) n += 4294967296
99
+ let body = n.toString(conv === 'o' ? 8 : 16)
100
+ if (conv === 'X') body = body.toUpperCase()
101
+ if (hasPrecision) while (body.length < precision) body = '0' + body
102
+ const prefix = flags.indexOf('#') >= 0 && n !== 0 ? (conv === 'o' ? '0' : conv === 'x' ? '0x' : '0X') : ''
103
+ out += pad(prefix, body, width, flags, !hasPrecision)
104
+ break
105
+ }
106
+ case 'e':
107
+ case 'E':
108
+ case 'f':
109
+ case 'F':
110
+ case 'g':
111
+ case 'G': {
112
+ const n = checkNumber(args, arg, 'format')
113
+ const upper = conv === 'E' || conv === 'G' || conv === 'F'
114
+ const alt = flags.indexOf('#') >= 0
115
+ const finite = n === n && n !== Infinity && n !== -Infinity
116
+ const neg = n < 0 || (n === 0 && 1 / n < 0)
117
+ let body
118
+ if (!finite) body = n !== n ? 'nan' : 'inf'
119
+ else {
120
+ const p = hasPrecision ? precision : 6
121
+ const a = Math.abs(n)
122
+ const lower = conv.toLowerCase()
123
+ body = lower === 'e' ? formatE(a, p, alt) : lower === 'f' ? formatF(a, p, alt) : formatG(a, p, alt)
124
+ }
125
+ if (upper) body = body.toUpperCase()
126
+ out += pad(signOf(neg), body, width, flags, finite)
127
+ break
128
+ }
129
+ case 'q':
130
+ out += quote(checkString(args, arg, 'format'))
131
+ break
132
+ case 's': {
133
+ let s = checkString(args, arg, 'format')
134
+ if (hasPrecision) s = s.substring(0, precision)
135
+ out += pad('', s, width, flags, false)
136
+ break
137
+ }
138
+ default:
139
+ throw fail("invalid option '%" + conv + "' to 'format'")
140
+ }
141
+ }
142
+ return out
143
+ }