@enmaq/mdgl 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -0
- package/dist/browser.d.ts +3 -0
- package/dist/browser.js +10 -0
- package/dist/browser.mjs +1489 -0
- package/dist/dom.d.ts +25 -0
- package/dist/dom.js +206 -0
- package/dist/index.js +1 -1
- package/dist/parse.js +2 -1
- package/dist/player.d.ts +2 -0
- package/dist/player.js +77 -0
- package/mdgl.css +52 -0
- package/package.json +23 -6
package/dist/browser.mjs
ADDED
|
@@ -0,0 +1,1489 @@
|
|
|
1
|
+
// src/unicode-tables.ts
|
|
2
|
+
var GCB = [0, 9, 3, 10, 10, 2, 11, 12, 3, 13, 13, 1, 14, 31, 3, 127, 159, 3, 173, 173, 3, 768, 879, 4, 1155, 1161, 4, 1425, 1469, 4, 1471, 1471, 4, 1473, 1474, 4, 1476, 1477, 4, 1479, 1479, 4, 1536, 1541, 0, 1552, 1562, 4, 1564, 1564, 3, 1611, 1631, 4, 1648, 1648, 4, 1750, 1756, 4, 1757, 1757, 0, 1759, 1764, 4, 1767, 1768, 4, 1770, 1773, 4, 1807, 1807, 0, 1809, 1809, 4, 1840, 1866, 4, 1958, 1968, 4, 2027, 2035, 4, 2045, 2045, 4, 2070, 2073, 4, 2075, 2083, 4, 2085, 2087, 4, 2089, 2093, 4, 2137, 2139, 4, 2192, 2193, 0, 2200, 2207, 4, 2250, 2273, 4, 2274, 2274, 0, 2275, 2306, 4, 2307, 2307, 7, 2362, 2362, 4, 2363, 2363, 7, 2364, 2364, 4, 2366, 2368, 7, 2369, 2376, 4, 2377, 2380, 7, 2381, 2381, 4, 2382, 2383, 7, 2385, 2391, 4, 2402, 2403, 4, 2433, 2433, 4, 2434, 2435, 7, 2492, 2492, 4, 2494, 2494, 4, 2495, 2496, 7, 2497, 2500, 4, 2503, 2504, 7, 2507, 2508, 7, 2509, 2509, 4, 2519, 2519, 4, 2530, 2531, 4, 2558, 2558, 4, 2561, 2562, 4, 2563, 2563, 7, 2620, 2620, 4, 2622, 2624, 7, 2625, 2626, 4, 2631, 2632, 4, 2635, 2637, 4, 2641, 2641, 4, 2672, 2673, 4, 2677, 2677, 4, 2689, 2690, 4, 2691, 2691, 7, 2748, 2748, 4, 2750, 2752, 7, 2753, 2757, 4, 2759, 2760, 4, 2761, 2761, 7, 2763, 2764, 7, 2765, 2765, 4, 2786, 2787, 4, 2810, 2815, 4, 2817, 2817, 4, 2818, 2819, 7, 2876, 2876, 4, 2878, 2879, 4, 2880, 2880, 7, 2881, 2884, 4, 2887, 2888, 7, 2891, 2892, 7, 2893, 2893, 4, 2901, 2903, 4, 2914, 2915, 4, 2946, 2946, 4, 3006, 3006, 4, 3007, 3007, 7, 3008, 3008, 4, 3009, 3010, 7, 3014, 3016, 7, 3018, 3020, 7, 3021, 3021, 4, 3031, 3031, 4, 3072, 3072, 4, 3073, 3075, 7, 3076, 3076, 4, 3132, 3132, 4, 3134, 3136, 4, 3137, 3140, 7, 3142, 3144, 4, 3146, 3149, 4, 3157, 3158, 4, 3170, 3171, 4, 3201, 3201, 4, 3202, 3203, 7, 3260, 3260, 4, 3262, 3262, 7, 3263, 3263, 4, 3264, 3265, 7, 3266, 3266, 4, 3267, 3268, 7, 3270, 3270, 4, 3271, 3272, 7, 3274, 3275, 7, 3276, 3277, 4, 3285, 3286, 4, 3298, 3299, 4, 3315, 3315, 7, 3328, 3329, 4, 3330, 3331, 7, 3387, 3388, 4, 3390, 3390, 4, 3391, 3392, 7, 3393, 3396, 4, 3398, 3400, 7, 3402, 3404, 7, 3405, 3405, 4, 3406, 3406, 0, 3415, 3415, 4, 3426, 3427, 4, 3457, 3457, 4, 3458, 3459, 7, 3530, 3530, 4, 3535, 3535, 4, 3536, 3537, 7, 3538, 3540, 4, 3542, 3542, 4, 3544, 3550, 7, 3551, 3551, 4, 3570, 3571, 7, 3633, 3633, 4, 3635, 3635, 7, 3636, 3642, 4, 3655, 3662, 4, 3761, 3761, 4, 3763, 3763, 7, 3764, 3772, 4, 3784, 3790, 4, 3864, 3865, 4, 3893, 3893, 4, 3895, 3895, 4, 3897, 3897, 4, 3902, 3903, 7, 3953, 3966, 4, 3967, 3967, 7, 3968, 3972, 4, 3974, 3975, 4, 3981, 3991, 4, 3993, 4028, 4, 4038, 4038, 4, 4141, 4144, 4, 4145, 4145, 7, 4146, 4151, 4, 4153, 4154, 4, 4155, 4156, 7, 4157, 4158, 4, 4182, 4183, 7, 4184, 4185, 4, 4190, 4192, 4, 4209, 4212, 4, 4226, 4226, 4, 4228, 4228, 7, 4229, 4230, 4, 4237, 4237, 4, 4253, 4253, 4, 4352, 4447, 8, 4448, 4519, 9, 4520, 4607, 10, 4957, 4959, 4, 5906, 5908, 4, 5909, 5909, 7, 5938, 5939, 4, 5940, 5940, 7, 5970, 5971, 4, 6002, 6003, 4, 6068, 6069, 4, 6070, 6070, 7, 6071, 6077, 4, 6078, 6085, 7, 6086, 6086, 4, 6087, 6088, 7, 6089, 6099, 4, 6109, 6109, 4, 6155, 6157, 4, 6158, 6158, 3, 6159, 6159, 4, 6277, 6278, 4, 6313, 6313, 4, 6432, 6434, 4, 6435, 6438, 7, 6439, 6440, 4, 6441, 6443, 7, 6448, 6449, 7, 6450, 6450, 4, 6451, 6456, 7, 6457, 6459, 4, 6679, 6680, 4, 6681, 6682, 7, 6683, 6683, 4, 6741, 6741, 7, 6742, 6742, 4, 6743, 6743, 7, 6744, 6750, 4, 6752, 6752, 4, 6754, 6754, 4, 6757, 6764, 4, 6765, 6770, 7, 6771, 6780, 4, 6783, 6783, 4, 6832, 6862, 4, 6912, 6915, 4, 6916, 6916, 7, 6964, 6970, 4, 6971, 6971, 7, 6972, 6972, 4, 6973, 6977, 7, 6978, 6978, 4, 6979, 6980, 7, 7019, 7027, 4, 7040, 7041, 4, 7042, 7042, 7, 7073, 7073, 7, 7074, 7077, 4, 7078, 7079, 7, 7080, 7081, 4, 7082, 7082, 7, 7083, 7085, 4, 7142, 7142, 4, 7143, 7143, 7, 7144, 7145, 4, 7146, 7148, 7, 7149, 7149, 4, 7150, 7150, 7, 7151, 7153, 4, 7154, 7155, 7, 7204, 7211, 7, 7212, 7219, 4, 7220, 7221, 7, 7222, 7223, 4, 7376, 7378, 4, 7380, 7392, 4, 7393, 7393, 7, 7394, 7400, 4, 7405, 7405, 4, 7412, 7412, 4, 7415, 7415, 7, 7416, 7417, 4, 7616, 7679, 4, 8203, 8203, 3, 8204, 8204, 4, 8205, 8205, 5, 8206, 8207, 3, 8232, 8238, 3, 8288, 8303, 3, 8400, 8432, 4, 11503, 11505, 4, 11647, 11647, 4, 11744, 11775, 4, 12330, 12335, 4, 12441, 12442, 4, 42607, 42610, 4, 42612, 42621, 4, 42654, 42655, 4, 42736, 42737, 4, 43010, 43010, 4, 43014, 43014, 4, 43019, 43019, 4, 43043, 43044, 7, 43045, 43046, 4, 43047, 43047, 7, 43052, 43052, 4, 43136, 43137, 7, 43188, 43203, 7, 43204, 43205, 4, 43232, 43249, 4, 43263, 43263, 4, 43302, 43309, 4, 43335, 43345, 4, 43346, 43347, 7, 43360, 43388, 8, 43392, 43394, 4, 43395, 43395, 7, 43443, 43443, 4, 43444, 43445, 7, 43446, 43449, 4, 43450, 43451, 7, 43452, 43453, 4, 43454, 43456, 7, 43493, 43493, 4, 43561, 43566, 4, 43567, 43568, 7, 43569, 43570, 4, 43571, 43572, 7, 43573, 43574, 4, 43587, 43587, 4, 43596, 43596, 4, 43597, 43597, 7, 43644, 43644, 4, 43696, 43696, 4, 43698, 43700, 4, 43703, 43704, 4, 43710, 43711, 4, 43713, 43713, 4, 43755, 43755, 7, 43756, 43757, 4, 43758, 43759, 7, 43765, 43765, 7, 43766, 43766, 4, 44003, 44004, 7, 44005, 44005, 4, 44006, 44007, 7, 44008, 44008, 4, 44009, 44010, 7, 44012, 44012, 7, 44013, 44013, 4, 44032, 44032, 11, 44033, 44059, 12, 44060, 44060, 11, 44061, 44087, 12, 44088, 44088, 11, 44089, 44115, 12, 44116, 44116, 11, 44117, 44143, 12, 44144, 44144, 11, 44145, 44171, 12, 44172, 44172, 11, 44173, 44199, 12, 44200, 44200, 11, 44201, 44227, 12, 44228, 44228, 11, 44229, 44255, 12, 44256, 44256, 11, 44257, 44283, 12, 44284, 44284, 11, 44285, 44311, 12, 44312, 44312, 11, 44313, 44339, 12, 44340, 44340, 11, 44341, 44367, 12, 44368, 44368, 11, 44369, 44395, 12, 44396, 44396, 11, 44397, 44423, 12, 44424, 44424, 11, 44425, 44451, 12, 44452, 44452, 11, 44453, 44479, 12, 44480, 44480, 11, 44481, 44507, 12, 44508, 44508, 11, 44509, 44535, 12, 44536, 44536, 11, 44537, 44563, 12, 44564, 44564, 11, 44565, 44591, 12, 44592, 44592, 11, 44593, 44619, 12, 44620, 44620, 11, 44621, 44647, 12, 44648, 44648, 11, 44649, 44675, 12, 44676, 44676, 11, 44677, 44703, 12, 44704, 44704, 11, 44705, 44731, 12, 44732, 44732, 11, 44733, 44759, 12, 44760, 44760, 11, 44761, 44787, 12, 44788, 44788, 11, 44789, 44815, 12, 44816, 44816, 11, 44817, 44843, 12, 44844, 44844, 11, 44845, 44871, 12, 44872, 44872, 11, 44873, 44899, 12, 44900, 44900, 11, 44901, 44927, 12, 44928, 44928, 11, 44929, 44955, 12, 44956, 44956, 11, 44957, 44983, 12, 44984, 44984, 11, 44985, 45011, 12, 45012, 45012, 11, 45013, 45039, 12, 45040, 45040, 11, 45041, 45067, 12, 45068, 45068, 11, 45069, 45095, 12, 45096, 45096, 11, 45097, 45123, 12, 45124, 45124, 11, 45125, 45151, 12, 45152, 45152, 11, 45153, 45179, 12, 45180, 45180, 11, 45181, 45207, 12, 45208, 45208, 11, 45209, 45235, 12, 45236, 45236, 11, 45237, 45263, 12, 45264, 45264, 11, 45265, 45291, 12, 45292, 45292, 11, 45293, 45319, 12, 45320, 45320, 11, 45321, 45347, 12, 45348, 45348, 11, 45349, 45375, 12, 45376, 45376, 11, 45377, 45403, 12, 45404, 45404, 11, 45405, 45431, 12, 45432, 45432, 11, 45433, 45459, 12, 45460, 45460, 11, 45461, 45487, 12, 45488, 45488, 11, 45489, 45515, 12, 45516, 45516, 11, 45517, 45543, 12, 45544, 45544, 11, 45545, 45571, 12, 45572, 45572, 11, 45573, 45599, 12, 45600, 45600, 11, 45601, 45627, 12, 45628, 45628, 11, 45629, 45655, 12, 45656, 45656, 11, 45657, 45683, 12, 45684, 45684, 11, 45685, 45711, 12, 45712, 45712, 11, 45713, 45739, 12, 45740, 45740, 11, 45741, 45767, 12, 45768, 45768, 11, 45769, 45795, 12, 45796, 45796, 11, 45797, 45823, 12, 45824, 45824, 11, 45825, 45851, 12, 45852, 45852, 11, 45853, 45879, 12, 45880, 45880, 11, 45881, 45907, 12, 45908, 45908, 11, 45909, 45935, 12, 45936, 45936, 11, 45937, 45963, 12, 45964, 45964, 11, 45965, 45991, 12, 45992, 45992, 11, 45993, 46019, 12, 46020, 46020, 11, 46021, 46047, 12, 46048, 46048, 11, 46049, 46075, 12, 46076, 46076, 11, 46077, 46103, 12, 46104, 46104, 11, 46105, 46131, 12, 46132, 46132, 11, 46133, 46159, 12, 46160, 46160, 11, 46161, 46187, 12, 46188, 46188, 11, 46189, 46215, 12, 46216, 46216, 11, 46217, 46243, 12, 46244, 46244, 11, 46245, 46271, 12, 46272, 46272, 11, 46273, 46299, 12, 46300, 46300, 11, 46301, 46327, 12, 46328, 46328, 11, 46329, 46355, 12, 46356, 46356, 11, 46357, 46383, 12, 46384, 46384, 11, 46385, 46411, 12, 46412, 46412, 11, 46413, 46439, 12, 46440, 46440, 11, 46441, 46467, 12, 46468, 46468, 11, 46469, 46495, 12, 46496, 46496, 11, 46497, 46523, 12, 46524, 46524, 11, 46525, 46551, 12, 46552, 46552, 11, 46553, 46579, 12, 46580, 46580, 11, 46581, 46607, 12, 46608, 46608, 11, 46609, 46635, 12, 46636, 46636, 11, 46637, 46663, 12, 46664, 46664, 11, 46665, 46691, 12, 46692, 46692, 11, 46693, 46719, 12, 46720, 46720, 11, 46721, 46747, 12, 46748, 46748, 11, 46749, 46775, 12, 46776, 46776, 11, 46777, 46803, 12, 46804, 46804, 11, 46805, 46831, 12, 46832, 46832, 11, 46833, 46859, 12, 46860, 46860, 11, 46861, 46887, 12, 46888, 46888, 11, 46889, 46915, 12, 46916, 46916, 11, 46917, 46943, 12, 46944, 46944, 11, 46945, 46971, 12, 46972, 46972, 11, 46973, 46999, 12, 47e3, 47e3, 11, 47001, 47027, 12, 47028, 47028, 11, 47029, 47055, 12, 47056, 47056, 11, 47057, 47083, 12, 47084, 47084, 11, 47085, 47111, 12, 47112, 47112, 11, 47113, 47139, 12, 47140, 47140, 11, 47141, 47167, 12, 47168, 47168, 11, 47169, 47195, 12, 47196, 47196, 11, 47197, 47223, 12, 47224, 47224, 11, 47225, 47251, 12, 47252, 47252, 11, 47253, 47279, 12, 47280, 47280, 11, 47281, 47307, 12, 47308, 47308, 11, 47309, 47335, 12, 47336, 47336, 11, 47337, 47363, 12, 47364, 47364, 11, 47365, 47391, 12, 47392, 47392, 11, 47393, 47419, 12, 47420, 47420, 11, 47421, 47447, 12, 47448, 47448, 11, 47449, 47475, 12, 47476, 47476, 11, 47477, 47503, 12, 47504, 47504, 11, 47505, 47531, 12, 47532, 47532, 11, 47533, 47559, 12, 47560, 47560, 11, 47561, 47587, 12, 47588, 47588, 11, 47589, 47615, 12, 47616, 47616, 11, 47617, 47643, 12, 47644, 47644, 11, 47645, 47671, 12, 47672, 47672, 11, 47673, 47699, 12, 47700, 47700, 11, 47701, 47727, 12, 47728, 47728, 11, 47729, 47755, 12, 47756, 47756, 11, 47757, 47783, 12, 47784, 47784, 11, 47785, 47811, 12, 47812, 47812, 11, 47813, 47839, 12, 47840, 47840, 11, 47841, 47867, 12, 47868, 47868, 11, 47869, 47895, 12, 47896, 47896, 11, 47897, 47923, 12, 47924, 47924, 11, 47925, 47951, 12, 47952, 47952, 11, 47953, 47979, 12, 47980, 47980, 11, 47981, 48007, 12, 48008, 48008, 11, 48009, 48035, 12, 48036, 48036, 11, 48037, 48063, 12, 48064, 48064, 11, 48065, 48091, 12, 48092, 48092, 11, 48093, 48119, 12, 48120, 48120, 11, 48121, 48147, 12, 48148, 48148, 11, 48149, 48175, 12, 48176, 48176, 11, 48177, 48203, 12, 48204, 48204, 11, 48205, 48231, 12, 48232, 48232, 11, 48233, 48259, 12, 48260, 48260, 11, 48261, 48287, 12, 48288, 48288, 11, 48289, 48315, 12, 48316, 48316, 11, 48317, 48343, 12, 48344, 48344, 11, 48345, 48371, 12, 48372, 48372, 11, 48373, 48399, 12, 48400, 48400, 11, 48401, 48427, 12, 48428, 48428, 11, 48429, 48455, 12, 48456, 48456, 11, 48457, 48483, 12, 48484, 48484, 11, 48485, 48511, 12, 48512, 48512, 11, 48513, 48539, 12, 48540, 48540, 11, 48541, 48567, 12, 48568, 48568, 11, 48569, 48595, 12, 48596, 48596, 11, 48597, 48623, 12, 48624, 48624, 11, 48625, 48651, 12, 48652, 48652, 11, 48653, 48679, 12, 48680, 48680, 11, 48681, 48707, 12, 48708, 48708, 11, 48709, 48735, 12, 48736, 48736, 11, 48737, 48763, 12, 48764, 48764, 11, 48765, 48791, 12, 48792, 48792, 11, 48793, 48819, 12, 48820, 48820, 11, 48821, 48847, 12, 48848, 48848, 11, 48849, 48875, 12, 48876, 48876, 11, 48877, 48903, 12, 48904, 48904, 11, 48905, 48931, 12, 48932, 48932, 11, 48933, 48959, 12, 48960, 48960, 11, 48961, 48987, 12, 48988, 48988, 11, 48989, 49015, 12, 49016, 49016, 11, 49017, 49043, 12, 49044, 49044, 11, 49045, 49071, 12, 49072, 49072, 11, 49073, 49099, 12, 49100, 49100, 11, 49101, 49127, 12, 49128, 49128, 11, 49129, 49155, 12, 49156, 49156, 11, 49157, 49183, 12, 49184, 49184, 11, 49185, 49211, 12, 49212, 49212, 11, 49213, 49239, 12, 49240, 49240, 11, 49241, 49267, 12, 49268, 49268, 11, 49269, 49295, 12, 49296, 49296, 11, 49297, 49323, 12, 49324, 49324, 11, 49325, 49351, 12, 49352, 49352, 11, 49353, 49379, 12, 49380, 49380, 11, 49381, 49407, 12, 49408, 49408, 11, 49409, 49435, 12, 49436, 49436, 11, 49437, 49463, 12, 49464, 49464, 11, 49465, 49491, 12, 49492, 49492, 11, 49493, 49519, 12, 49520, 49520, 11, 49521, 49547, 12, 49548, 49548, 11, 49549, 49575, 12, 49576, 49576, 11, 49577, 49603, 12, 49604, 49604, 11, 49605, 49631, 12, 49632, 49632, 11, 49633, 49659, 12, 49660, 49660, 11, 49661, 49687, 12, 49688, 49688, 11, 49689, 49715, 12, 49716, 49716, 11, 49717, 49743, 12, 49744, 49744, 11, 49745, 49771, 12, 49772, 49772, 11, 49773, 49799, 12, 49800, 49800, 11, 49801, 49827, 12, 49828, 49828, 11, 49829, 49855, 12, 49856, 49856, 11, 49857, 49883, 12, 49884, 49884, 11, 49885, 49911, 12, 49912, 49912, 11, 49913, 49939, 12, 49940, 49940, 11, 49941, 49967, 12, 49968, 49968, 11, 49969, 49995, 12, 49996, 49996, 11, 49997, 50023, 12, 50024, 50024, 11, 50025, 50051, 12, 50052, 50052, 11, 50053, 50079, 12, 50080, 50080, 11, 50081, 50107, 12, 50108, 50108, 11, 50109, 50135, 12, 50136, 50136, 11, 50137, 50163, 12, 50164, 50164, 11, 50165, 50191, 12, 50192, 50192, 11, 50193, 50219, 12, 50220, 50220, 11, 50221, 50247, 12, 50248, 50248, 11, 50249, 50275, 12, 50276, 50276, 11, 50277, 50303, 12, 50304, 50304, 11, 50305, 50331, 12, 50332, 50332, 11, 50333, 50359, 12, 50360, 50360, 11, 50361, 50387, 12, 50388, 50388, 11, 50389, 50415, 12, 50416, 50416, 11, 50417, 50443, 12, 50444, 50444, 11, 50445, 50471, 12, 50472, 50472, 11, 50473, 50499, 12, 50500, 50500, 11, 50501, 50527, 12, 50528, 50528, 11, 50529, 50555, 12, 50556, 50556, 11, 50557, 50583, 12, 50584, 50584, 11, 50585, 50611, 12, 50612, 50612, 11, 50613, 50639, 12, 50640, 50640, 11, 50641, 50667, 12, 50668, 50668, 11, 50669, 50695, 12, 50696, 50696, 11, 50697, 50723, 12, 50724, 50724, 11, 50725, 50751, 12, 50752, 50752, 11, 50753, 50779, 12, 50780, 50780, 11, 50781, 50807, 12, 50808, 50808, 11, 50809, 50835, 12, 50836, 50836, 11, 50837, 50863, 12, 50864, 50864, 11, 50865, 50891, 12, 50892, 50892, 11, 50893, 50919, 12, 50920, 50920, 11, 50921, 50947, 12, 50948, 50948, 11, 50949, 50975, 12, 50976, 50976, 11, 50977, 51003, 12, 51004, 51004, 11, 51005, 51031, 12, 51032, 51032, 11, 51033, 51059, 12, 51060, 51060, 11, 51061, 51087, 12, 51088, 51088, 11, 51089, 51115, 12, 51116, 51116, 11, 51117, 51143, 12, 51144, 51144, 11, 51145, 51171, 12, 51172, 51172, 11, 51173, 51199, 12, 51200, 51200, 11, 51201, 51227, 12, 51228, 51228, 11, 51229, 51255, 12, 51256, 51256, 11, 51257, 51283, 12, 51284, 51284, 11, 51285, 51311, 12, 51312, 51312, 11, 51313, 51339, 12, 51340, 51340, 11, 51341, 51367, 12, 51368, 51368, 11, 51369, 51395, 12, 51396, 51396, 11, 51397, 51423, 12, 51424, 51424, 11, 51425, 51451, 12, 51452, 51452, 11, 51453, 51479, 12, 51480, 51480, 11, 51481, 51507, 12, 51508, 51508, 11, 51509, 51535, 12, 51536, 51536, 11, 51537, 51563, 12, 51564, 51564, 11, 51565, 51591, 12, 51592, 51592, 11, 51593, 51619, 12, 51620, 51620, 11, 51621, 51647, 12, 51648, 51648, 11, 51649, 51675, 12, 51676, 51676, 11, 51677, 51703, 12, 51704, 51704, 11, 51705, 51731, 12, 51732, 51732, 11, 51733, 51759, 12, 51760, 51760, 11, 51761, 51787, 12, 51788, 51788, 11, 51789, 51815, 12, 51816, 51816, 11, 51817, 51843, 12, 51844, 51844, 11, 51845, 51871, 12, 51872, 51872, 11, 51873, 51899, 12, 51900, 51900, 11, 51901, 51927, 12, 51928, 51928, 11, 51929, 51955, 12, 51956, 51956, 11, 51957, 51983, 12, 51984, 51984, 11, 51985, 52011, 12, 52012, 52012, 11, 52013, 52039, 12, 52040, 52040, 11, 52041, 52067, 12, 52068, 52068, 11, 52069, 52095, 12, 52096, 52096, 11, 52097, 52123, 12, 52124, 52124, 11, 52125, 52151, 12, 52152, 52152, 11, 52153, 52179, 12, 52180, 52180, 11, 52181, 52207, 12, 52208, 52208, 11, 52209, 52235, 12, 52236, 52236, 11, 52237, 52263, 12, 52264, 52264, 11, 52265, 52291, 12, 52292, 52292, 11, 52293, 52319, 12, 52320, 52320, 11, 52321, 52347, 12, 52348, 52348, 11, 52349, 52375, 12, 52376, 52376, 11, 52377, 52403, 12, 52404, 52404, 11, 52405, 52431, 12, 52432, 52432, 11, 52433, 52459, 12, 52460, 52460, 11, 52461, 52487, 12, 52488, 52488, 11, 52489, 52515, 12, 52516, 52516, 11, 52517, 52543, 12, 52544, 52544, 11, 52545, 52571, 12, 52572, 52572, 11, 52573, 52599, 12, 52600, 52600, 11, 52601, 52627, 12, 52628, 52628, 11, 52629, 52655, 12, 52656, 52656, 11, 52657, 52683, 12, 52684, 52684, 11, 52685, 52711, 12, 52712, 52712, 11, 52713, 52739, 12, 52740, 52740, 11, 52741, 52767, 12, 52768, 52768, 11, 52769, 52795, 12, 52796, 52796, 11, 52797, 52823, 12, 52824, 52824, 11, 52825, 52851, 12, 52852, 52852, 11, 52853, 52879, 12, 52880, 52880, 11, 52881, 52907, 12, 52908, 52908, 11, 52909, 52935, 12, 52936, 52936, 11, 52937, 52963, 12, 52964, 52964, 11, 52965, 52991, 12, 52992, 52992, 11, 52993, 53019, 12, 53020, 53020, 11, 53021, 53047, 12, 53048, 53048, 11, 53049, 53075, 12, 53076, 53076, 11, 53077, 53103, 12, 53104, 53104, 11, 53105, 53131, 12, 53132, 53132, 11, 53133, 53159, 12, 53160, 53160, 11, 53161, 53187, 12, 53188, 53188, 11, 53189, 53215, 12, 53216, 53216, 11, 53217, 53243, 12, 53244, 53244, 11, 53245, 53271, 12, 53272, 53272, 11, 53273, 53299, 12, 53300, 53300, 11, 53301, 53327, 12, 53328, 53328, 11, 53329, 53355, 12, 53356, 53356, 11, 53357, 53383, 12, 53384, 53384, 11, 53385, 53411, 12, 53412, 53412, 11, 53413, 53439, 12, 53440, 53440, 11, 53441, 53467, 12, 53468, 53468, 11, 53469, 53495, 12, 53496, 53496, 11, 53497, 53523, 12, 53524, 53524, 11, 53525, 53551, 12, 53552, 53552, 11, 53553, 53579, 12, 53580, 53580, 11, 53581, 53607, 12, 53608, 53608, 11, 53609, 53635, 12, 53636, 53636, 11, 53637, 53663, 12, 53664, 53664, 11, 53665, 53691, 12, 53692, 53692, 11, 53693, 53719, 12, 53720, 53720, 11, 53721, 53747, 12, 53748, 53748, 11, 53749, 53775, 12, 53776, 53776, 11, 53777, 53803, 12, 53804, 53804, 11, 53805, 53831, 12, 53832, 53832, 11, 53833, 53859, 12, 53860, 53860, 11, 53861, 53887, 12, 53888, 53888, 11, 53889, 53915, 12, 53916, 53916, 11, 53917, 53943, 12, 53944, 53944, 11, 53945, 53971, 12, 53972, 53972, 11, 53973, 53999, 12, 54e3, 54e3, 11, 54001, 54027, 12, 54028, 54028, 11, 54029, 54055, 12, 54056, 54056, 11, 54057, 54083, 12, 54084, 54084, 11, 54085, 54111, 12, 54112, 54112, 11, 54113, 54139, 12, 54140, 54140, 11, 54141, 54167, 12, 54168, 54168, 11, 54169, 54195, 12, 54196, 54196, 11, 54197, 54223, 12, 54224, 54224, 11, 54225, 54251, 12, 54252, 54252, 11, 54253, 54279, 12, 54280, 54280, 11, 54281, 54307, 12, 54308, 54308, 11, 54309, 54335, 12, 54336, 54336, 11, 54337, 54363, 12, 54364, 54364, 11, 54365, 54391, 12, 54392, 54392, 11, 54393, 54419, 12, 54420, 54420, 11, 54421, 54447, 12, 54448, 54448, 11, 54449, 54475, 12, 54476, 54476, 11, 54477, 54503, 12, 54504, 54504, 11, 54505, 54531, 12, 54532, 54532, 11, 54533, 54559, 12, 54560, 54560, 11, 54561, 54587, 12, 54588, 54588, 11, 54589, 54615, 12, 54616, 54616, 11, 54617, 54643, 12, 54644, 54644, 11, 54645, 54671, 12, 54672, 54672, 11, 54673, 54699, 12, 54700, 54700, 11, 54701, 54727, 12, 54728, 54728, 11, 54729, 54755, 12, 54756, 54756, 11, 54757, 54783, 12, 54784, 54784, 11, 54785, 54811, 12, 54812, 54812, 11, 54813, 54839, 12, 54840, 54840, 11, 54841, 54867, 12, 54868, 54868, 11, 54869, 54895, 12, 54896, 54896, 11, 54897, 54923, 12, 54924, 54924, 11, 54925, 54951, 12, 54952, 54952, 11, 54953, 54979, 12, 54980, 54980, 11, 54981, 55007, 12, 55008, 55008, 11, 55009, 55035, 12, 55036, 55036, 11, 55037, 55063, 12, 55064, 55064, 11, 55065, 55091, 12, 55092, 55092, 11, 55093, 55119, 12, 55120, 55120, 11, 55121, 55147, 12, 55148, 55148, 11, 55149, 55175, 12, 55176, 55176, 11, 55177, 55203, 12, 55216, 55238, 9, 55243, 55291, 10, 64286, 64286, 4, 65024, 65039, 4, 65056, 65071, 4, 65279, 65279, 3, 65438, 65439, 4, 65520, 65531, 3, 66045, 66045, 4, 66272, 66272, 4, 66422, 66426, 4, 68097, 68099, 4, 68101, 68102, 4, 68108, 68111, 4, 68152, 68154, 4, 68159, 68159, 4, 68325, 68326, 4, 68900, 68903, 4, 69291, 69292, 4, 69373, 69375, 4, 69446, 69456, 4, 69506, 69509, 4, 69632, 69632, 7, 69633, 69633, 4, 69634, 69634, 7, 69688, 69702, 4, 69744, 69744, 4, 69747, 69748, 4, 69759, 69761, 4, 69762, 69762, 7, 69808, 69810, 7, 69811, 69814, 4, 69815, 69816, 7, 69817, 69818, 4, 69821, 69821, 0, 69826, 69826, 4, 69837, 69837, 0, 69888, 69890, 4, 69927, 69931, 4, 69932, 69932, 7, 69933, 69940, 4, 69957, 69958, 7, 70003, 70003, 4, 70016, 70017, 4, 70018, 70018, 7, 70067, 70069, 7, 70070, 70078, 4, 70079, 70080, 7, 70082, 70083, 0, 70089, 70092, 4, 70094, 70094, 7, 70095, 70095, 4, 70188, 70190, 7, 70191, 70193, 4, 70194, 70195, 7, 70196, 70196, 4, 70197, 70197, 7, 70198, 70199, 4, 70206, 70206, 4, 70209, 70209, 4, 70367, 70367, 4, 70368, 70370, 7, 70371, 70378, 4, 70400, 70401, 4, 70402, 70403, 7, 70459, 70460, 4, 70462, 70462, 4, 70463, 70463, 7, 70464, 70464, 4, 70465, 70468, 7, 70471, 70472, 7, 70475, 70477, 7, 70487, 70487, 4, 70498, 70499, 7, 70502, 70508, 4, 70512, 70516, 4, 70709, 70711, 7, 70712, 70719, 4, 70720, 70721, 7, 70722, 70724, 4, 70725, 70725, 7, 70726, 70726, 4, 70750, 70750, 4, 70832, 70832, 4, 70833, 70834, 7, 70835, 70840, 4, 70841, 70841, 7, 70842, 70842, 4, 70843, 70844, 7, 70845, 70845, 4, 70846, 70846, 7, 70847, 70848, 4, 70849, 70849, 7, 70850, 70851, 4, 71087, 71087, 4, 71088, 71089, 7, 71090, 71093, 4, 71096, 71099, 7, 71100, 71101, 4, 71102, 71102, 7, 71103, 71104, 4, 71132, 71133, 4, 71216, 71218, 7, 71219, 71226, 4, 71227, 71228, 7, 71229, 71229, 4, 71230, 71230, 7, 71231, 71232, 4, 71339, 71339, 4, 71340, 71340, 7, 71341, 71341, 4, 71342, 71343, 7, 71344, 71349, 4, 71350, 71350, 7, 71351, 71351, 4, 71453, 71455, 4, 71458, 71461, 4, 71462, 71462, 7, 71463, 71467, 4, 71724, 71726, 7, 71727, 71735, 4, 71736, 71736, 7, 71737, 71738, 4, 71984, 71984, 4, 71985, 71989, 7, 71991, 71992, 7, 71995, 71996, 4, 71997, 71997, 7, 71998, 71998, 4, 71999, 71999, 0, 72e3, 72e3, 7, 72001, 72001, 0, 72002, 72002, 7, 72003, 72003, 4, 72145, 72147, 7, 72148, 72151, 4, 72154, 72155, 4, 72156, 72159, 7, 72160, 72160, 4, 72164, 72164, 7, 72193, 72202, 4, 72243, 72248, 4, 72249, 72249, 7, 72250, 72250, 0, 72251, 72254, 4, 72263, 72263, 4, 72273, 72278, 4, 72279, 72280, 7, 72281, 72283, 4, 72324, 72329, 0, 72330, 72342, 4, 72343, 72343, 7, 72344, 72345, 4, 72751, 72751, 7, 72752, 72758, 4, 72760, 72765, 4, 72766, 72766, 7, 72767, 72767, 4, 72850, 72871, 4, 72873, 72873, 7, 72874, 72880, 4, 72881, 72881, 7, 72882, 72883, 4, 72884, 72884, 7, 72885, 72886, 4, 73009, 73014, 4, 73018, 73018, 4, 73020, 73021, 4, 73023, 73029, 4, 73030, 73030, 0, 73031, 73031, 4, 73098, 73102, 7, 73104, 73105, 4, 73107, 73108, 7, 73109, 73109, 4, 73110, 73110, 7, 73111, 73111, 4, 73459, 73460, 4, 73461, 73462, 7, 73472, 73473, 4, 73474, 73474, 0, 73475, 73475, 7, 73524, 73525, 7, 73526, 73530, 4, 73534, 73535, 7, 73536, 73536, 4, 73537, 73537, 7, 73538, 73538, 4, 78896, 78911, 3, 78912, 78912, 4, 78919, 78933, 4, 92912, 92916, 4, 92976, 92982, 4, 94031, 94031, 4, 94033, 94087, 7, 94095, 94098, 4, 94180, 94180, 4, 94192, 94193, 7, 113821, 113822, 4, 113824, 113827, 3, 118528, 118573, 4, 118576, 118598, 4, 119141, 119141, 4, 119142, 119142, 7, 119143, 119145, 4, 119149, 119149, 7, 119150, 119154, 4, 119155, 119162, 3, 119163, 119170, 4, 119173, 119179, 4, 119210, 119213, 4, 119362, 119364, 4, 121344, 121398, 4, 121403, 121452, 4, 121461, 121461, 4, 121476, 121476, 4, 121499, 121503, 4, 121505, 121519, 4, 122880, 122886, 4, 122888, 122904, 4, 122907, 122913, 4, 122915, 122916, 4, 122918, 122922, 4, 123023, 123023, 4, 123184, 123190, 4, 123566, 123566, 4, 123628, 123631, 4, 124140, 124143, 4, 125136, 125142, 4, 125252, 125258, 4, 127462, 127487, 6, 127995, 127999, 4, 917504, 917535, 3, 917536, 917631, 4, 917632, 917759, 3, 917760, 917999, 4, 918e3, 921599, 3];
|
|
3
|
+
var EXT_PICT = [169, 169, 0, 174, 174, 0, 8252, 8252, 0, 8265, 8265, 0, 8482, 8482, 0, 8505, 8505, 0, 8596, 8601, 0, 8617, 8618, 0, 8986, 8987, 0, 9e3, 9e3, 0, 9096, 9096, 0, 9167, 9167, 0, 9193, 9203, 0, 9208, 9210, 0, 9410, 9410, 0, 9642, 9643, 0, 9654, 9654, 0, 9664, 9664, 0, 9723, 9726, 0, 9728, 9733, 0, 9735, 9746, 0, 9748, 9861, 0, 9872, 9989, 0, 9992, 10002, 0, 10004, 10004, 0, 10006, 10006, 0, 10013, 10013, 0, 10017, 10017, 0, 10024, 10024, 0, 10035, 10036, 0, 10052, 10052, 0, 10055, 10055, 0, 10060, 10060, 0, 10062, 10062, 0, 10067, 10069, 0, 10071, 10071, 0, 10083, 10087, 0, 10133, 10135, 0, 10145, 10145, 0, 10160, 10160, 0, 10175, 10175, 0, 10548, 10549, 0, 11013, 11015, 0, 11035, 11036, 0, 11088, 11088, 0, 11093, 11093, 0, 12336, 12336, 0, 12349, 12349, 0, 12951, 12951, 0, 12953, 12953, 0, 126976, 127231, 0, 127245, 127247, 0, 127279, 127279, 0, 127340, 127345, 0, 127358, 127359, 0, 127374, 127374, 0, 127377, 127386, 0, 127405, 127461, 0, 127489, 127503, 0, 127514, 127514, 0, 127535, 127535, 0, 127538, 127546, 0, 127548, 127551, 0, 127561, 127994, 0, 128e3, 128317, 0, 128326, 128591, 0, 128640, 128767, 0, 128884, 128895, 0, 128981, 129023, 0, 129036, 129039, 0, 129096, 129103, 0, 129114, 129119, 0, 129160, 129167, 0, 129198, 129279, 0, 129292, 129338, 0, 129340, 129349, 0, 129351, 129791, 0, 130048, 131069, 0];
|
|
4
|
+
var WIDE = [4352, 4447, 0, 8986, 8987, 0, 9001, 9002, 0, 9193, 9196, 0, 9200, 9200, 0, 9203, 9203, 0, 9725, 9726, 0, 9748, 9749, 0, 9800, 9811, 0, 9855, 9855, 0, 9875, 9875, 0, 9889, 9889, 0, 9898, 9899, 0, 9917, 9918, 0, 9924, 9925, 0, 9934, 9934, 0, 9940, 9940, 0, 9962, 9962, 0, 9970, 9971, 0, 9973, 9973, 0, 9978, 9978, 0, 9981, 9981, 0, 9989, 9989, 0, 9994, 9995, 0, 10024, 10024, 0, 10060, 10060, 0, 10062, 10062, 0, 10067, 10069, 0, 10071, 10071, 0, 10133, 10135, 0, 10160, 10160, 0, 10175, 10175, 0, 11035, 11036, 0, 11088, 11088, 0, 11093, 11093, 0, 11904, 11929, 0, 11931, 12019, 0, 12032, 12245, 0, 12272, 12283, 0, 12288, 12350, 0, 12353, 12438, 0, 12441, 12543, 0, 12549, 12591, 0, 12593, 12686, 0, 12688, 12771, 0, 12784, 12830, 0, 12832, 12871, 0, 12880, 19903, 0, 19968, 42124, 0, 42128, 42182, 0, 43360, 43388, 0, 44032, 55203, 0, 63744, 64255, 0, 65040, 65049, 0, 65072, 65106, 0, 65108, 65126, 0, 65128, 65131, 0, 65281, 65376, 0, 65504, 65510, 0, 94176, 94180, 0, 94192, 94193, 0, 94208, 100343, 0, 100352, 101589, 0, 101632, 101640, 0, 110576, 110579, 0, 110581, 110587, 0, 110589, 110590, 0, 110592, 110882, 0, 110898, 110898, 0, 110928, 110930, 0, 110933, 110933, 0, 110948, 110951, 0, 110960, 111355, 0, 126980, 126980, 0, 127183, 127183, 0, 127374, 127374, 0, 127377, 127386, 0, 127488, 127490, 0, 127504, 127547, 0, 127552, 127560, 0, 127568, 127569, 0, 127584, 127589, 0, 127744, 127776, 0, 127789, 127797, 0, 127799, 127868, 0, 127870, 127891, 0, 127904, 127946, 0, 127951, 127955, 0, 127968, 127984, 0, 127988, 127988, 0, 127992, 128062, 0, 128064, 128064, 0, 128066, 128252, 0, 128255, 128317, 0, 128331, 128334, 0, 128336, 128359, 0, 128378, 128378, 0, 128405, 128406, 0, 128420, 128420, 0, 128507, 128591, 0, 128640, 128709, 0, 128716, 128716, 0, 128720, 128722, 0, 128725, 128727, 0, 128732, 128735, 0, 128747, 128748, 0, 128756, 128764, 0, 128992, 129003, 0, 129008, 129008, 0, 129292, 129338, 0, 129340, 129349, 0, 129351, 129535, 0, 129648, 129660, 0, 129664, 129672, 0, 129680, 129725, 0, 129727, 129733, 0, 129742, 129755, 0, 129760, 129768, 0, 129776, 129784, 0, 131072, 196605, 0, 196608, 262141, 0];
|
|
5
|
+
var MARK = [768, 879, 0, 1155, 1161, 0, 1425, 1469, 0, 1471, 1471, 0, 1473, 1474, 0, 1476, 1477, 0, 1479, 1479, 0, 1552, 1562, 0, 1611, 1631, 0, 1648, 1648, 0, 1750, 1756, 0, 1759, 1764, 0, 1767, 1768, 0, 1770, 1773, 0, 1809, 1809, 0, 1840, 1866, 0, 1958, 1968, 0, 2027, 2035, 0, 2045, 2045, 0, 2070, 2073, 0, 2075, 2083, 0, 2085, 2087, 0, 2089, 2093, 0, 2137, 2139, 0, 2200, 2207, 0, 2250, 2273, 0, 2275, 2307, 0, 2362, 2364, 0, 2366, 2383, 0, 2385, 2391, 0, 2402, 2403, 0, 2433, 2435, 0, 2492, 2492, 0, 2494, 2500, 0, 2503, 2504, 0, 2507, 2509, 0, 2519, 2519, 0, 2530, 2531, 0, 2558, 2558, 0, 2561, 2563, 0, 2620, 2620, 0, 2622, 2626, 0, 2631, 2632, 0, 2635, 2637, 0, 2641, 2641, 0, 2672, 2673, 0, 2677, 2677, 0, 2689, 2691, 0, 2748, 2748, 0, 2750, 2757, 0, 2759, 2761, 0, 2763, 2765, 0, 2786, 2787, 0, 2810, 2815, 0, 2817, 2819, 0, 2876, 2876, 0, 2878, 2884, 0, 2887, 2888, 0, 2891, 2893, 0, 2901, 2903, 0, 2914, 2915, 0, 2946, 2946, 0, 3006, 3010, 0, 3014, 3016, 0, 3018, 3021, 0, 3031, 3031, 0, 3072, 3076, 0, 3132, 3132, 0, 3134, 3140, 0, 3142, 3144, 0, 3146, 3149, 0, 3157, 3158, 0, 3170, 3171, 0, 3201, 3203, 0, 3260, 3260, 0, 3262, 3268, 0, 3270, 3272, 0, 3274, 3277, 0, 3285, 3286, 0, 3298, 3299, 0, 3315, 3315, 0, 3328, 3331, 0, 3387, 3388, 0, 3390, 3396, 0, 3398, 3400, 0, 3402, 3405, 0, 3415, 3415, 0, 3426, 3427, 0, 3457, 3459, 0, 3530, 3530, 0, 3535, 3540, 0, 3542, 3542, 0, 3544, 3551, 0, 3570, 3571, 0, 3633, 3633, 0, 3636, 3642, 0, 3655, 3662, 0, 3761, 3761, 0, 3764, 3772, 0, 3784, 3790, 0, 3864, 3865, 0, 3893, 3893, 0, 3895, 3895, 0, 3897, 3897, 0, 3902, 3903, 0, 3953, 3972, 0, 3974, 3975, 0, 3981, 3991, 0, 3993, 4028, 0, 4038, 4038, 0, 4139, 4158, 0, 4182, 4185, 0, 4190, 4192, 0, 4194, 4196, 0, 4199, 4205, 0, 4209, 4212, 0, 4226, 4237, 0, 4239, 4239, 0, 4250, 4253, 0, 4957, 4959, 0, 5906, 5909, 0, 5938, 5940, 0, 5970, 5971, 0, 6002, 6003, 0, 6068, 6099, 0, 6109, 6109, 0, 6155, 6157, 0, 6159, 6159, 0, 6277, 6278, 0, 6313, 6313, 0, 6432, 6443, 0, 6448, 6459, 0, 6679, 6683, 0, 6741, 6750, 0, 6752, 6780, 0, 6783, 6783, 0, 6832, 6862, 0, 6912, 6916, 0, 6964, 6980, 0, 7019, 7027, 0, 7040, 7042, 0, 7073, 7085, 0, 7142, 7155, 0, 7204, 7223, 0, 7376, 7378, 0, 7380, 7400, 0, 7405, 7405, 0, 7412, 7412, 0, 7415, 7417, 0, 7616, 7679, 0, 8400, 8432, 0, 11503, 11505, 0, 11647, 11647, 0, 11744, 11775, 0, 12330, 12335, 0, 12441, 12442, 0, 42607, 42610, 0, 42612, 42621, 0, 42654, 42655, 0, 42736, 42737, 0, 43010, 43010, 0, 43014, 43014, 0, 43019, 43019, 0, 43043, 43047, 0, 43052, 43052, 0, 43136, 43137, 0, 43188, 43205, 0, 43232, 43249, 0, 43263, 43263, 0, 43302, 43309, 0, 43335, 43347, 0, 43392, 43395, 0, 43443, 43456, 0, 43493, 43493, 0, 43561, 43574, 0, 43587, 43587, 0, 43596, 43597, 0, 43643, 43645, 0, 43696, 43696, 0, 43698, 43700, 0, 43703, 43704, 0, 43710, 43711, 0, 43713, 43713, 0, 43755, 43759, 0, 43765, 43766, 0, 44003, 44010, 0, 44012, 44013, 0, 64286, 64286, 0, 65024, 65039, 0, 65056, 65071, 0, 66045, 66045, 0, 66272, 66272, 0, 66422, 66426, 0, 68097, 68099, 0, 68101, 68102, 0, 68108, 68111, 0, 68152, 68154, 0, 68159, 68159, 0, 68325, 68326, 0, 68900, 68903, 0, 69291, 69292, 0, 69373, 69375, 0, 69446, 69456, 0, 69506, 69509, 0, 69632, 69634, 0, 69688, 69702, 0, 69744, 69744, 0, 69747, 69748, 0, 69759, 69762, 0, 69808, 69818, 0, 69826, 69826, 0, 69888, 69890, 0, 69927, 69940, 0, 69957, 69958, 0, 70003, 70003, 0, 70016, 70018, 0, 70067, 70080, 0, 70089, 70092, 0, 70094, 70095, 0, 70188, 70199, 0, 70206, 70206, 0, 70209, 70209, 0, 70367, 70378, 0, 70400, 70403, 0, 70459, 70460, 0, 70462, 70468, 0, 70471, 70472, 0, 70475, 70477, 0, 70487, 70487, 0, 70498, 70499, 0, 70502, 70508, 0, 70512, 70516, 0, 70709, 70726, 0, 70750, 70750, 0, 70832, 70851, 0, 71087, 71093, 0, 71096, 71104, 0, 71132, 71133, 0, 71216, 71232, 0, 71339, 71351, 0, 71453, 71467, 0, 71724, 71738, 0, 71984, 71989, 0, 71991, 71992, 0, 71995, 71998, 0, 72e3, 72e3, 0, 72002, 72003, 0, 72145, 72151, 0, 72154, 72160, 0, 72164, 72164, 0, 72193, 72202, 0, 72243, 72249, 0, 72251, 72254, 0, 72263, 72263, 0, 72273, 72283, 0, 72330, 72345, 0, 72751, 72758, 0, 72760, 72767, 0, 72850, 72871, 0, 72873, 72886, 0, 73009, 73014, 0, 73018, 73018, 0, 73020, 73021, 0, 73023, 73029, 0, 73031, 73031, 0, 73098, 73102, 0, 73104, 73105, 0, 73107, 73111, 0, 73459, 73462, 0, 73472, 73473, 0, 73475, 73475, 0, 73524, 73530, 0, 73534, 73538, 0, 78912, 78912, 0, 78919, 78933, 0, 92912, 92916, 0, 92976, 92982, 0, 94031, 94031, 0, 94033, 94087, 0, 94095, 94098, 0, 94180, 94180, 0, 94192, 94193, 0, 113821, 113822, 0, 118528, 118573, 0, 118576, 118598, 0, 119141, 119145, 0, 119149, 119154, 0, 119163, 119170, 0, 119173, 119179, 0, 119210, 119213, 0, 119362, 119364, 0, 121344, 121398, 0, 121403, 121452, 0, 121461, 121461, 0, 121476, 121476, 0, 121499, 121503, 0, 121505, 121519, 0, 122880, 122886, 0, 122888, 122904, 0, 122907, 122913, 0, 122915, 122916, 0, 122918, 122922, 0, 123023, 123023, 0, 123184, 123190, 0, 123566, 123566, 0, 123628, 123631, 0, 124140, 124143, 0, 125136, 125142, 0, 125252, 125258, 0, 917760, 917999, 0];
|
|
6
|
+
var IGNORABLE = [173, 173, 0, 847, 847, 0, 1564, 1564, 0, 4447, 4448, 0, 6068, 6069, 0, 6155, 6159, 0, 8203, 8207, 0, 8234, 8238, 0, 8288, 8303, 0, 12644, 12644, 0, 65024, 65039, 0, 65279, 65279, 0, 65440, 65440, 0, 65520, 65528, 0, 113824, 113827, 0, 119155, 119162, 0, 917504, 921599, 0];
|
|
7
|
+
var VS16_BASE = [35, 35, 0, 42, 42, 0, 48, 57, 0, 169, 169, 0, 174, 174, 0, 8252, 8252, 0, 8265, 8265, 0, 8482, 8482, 0, 8505, 8505, 0, 8596, 8601, 0, 8617, 8618, 0, 8986, 8987, 0, 9e3, 9e3, 0, 9167, 9167, 0, 9193, 9194, 0, 9197, 9199, 0, 9201, 9203, 0, 9208, 9210, 0, 9410, 9410, 0, 9642, 9643, 0, 9654, 9654, 0, 9664, 9664, 0, 9723, 9726, 0, 9728, 9732, 0, 9742, 9742, 0, 9745, 9745, 0, 9748, 9749, 0, 9752, 9752, 0, 9757, 9757, 0, 9760, 9760, 0, 9762, 9763, 0, 9766, 9766, 0, 9770, 9770, 0, 9774, 9775, 0, 9784, 9786, 0, 9792, 9792, 0, 9794, 9794, 0, 9800, 9811, 0, 9823, 9824, 0, 9827, 9827, 0, 9829, 9830, 0, 9832, 9832, 0, 9851, 9851, 0, 9854, 9855, 0, 9874, 9879, 0, 9881, 9881, 0, 9883, 9884, 0, 9888, 9889, 0, 9895, 9895, 0, 9898, 9899, 0, 9904, 9905, 0, 9917, 9918, 0, 9924, 9925, 0, 9928, 9928, 0, 9935, 9935, 0, 9937, 9937, 0, 9939, 9940, 0, 9961, 9962, 0, 9968, 9973, 0, 9975, 9978, 0, 9981, 9981, 0, 9986, 9986, 0, 9992, 9993, 0, 9996, 9997, 0, 9999, 9999, 0, 10002, 10002, 0, 10004, 10004, 0, 10006, 10006, 0, 10013, 10013, 0, 10017, 10017, 0, 10035, 10036, 0, 10052, 10052, 0, 10055, 10055, 0, 10067, 10067, 0, 10071, 10071, 0, 10083, 10084, 0, 10145, 10145, 0, 10548, 10549, 0, 11013, 11015, 0, 11035, 11036, 0, 11088, 11088, 0, 11093, 11093, 0, 12336, 12336, 0, 12349, 12349, 0, 12951, 12951, 0, 12953, 12953, 0, 126980, 126980, 0, 127344, 127345, 0, 127358, 127359, 0, 127490, 127490, 0, 127514, 127514, 0, 127535, 127535, 0, 127543, 127543, 0, 127757, 127759, 0, 127765, 127765, 0, 127772, 127772, 0, 127777, 127777, 0, 127780, 127788, 0, 127798, 127798, 0, 127864, 127864, 0, 127869, 127869, 0, 127891, 127891, 0, 127894, 127895, 0, 127897, 127899, 0, 127902, 127903, 0, 127911, 127911, 0, 127916, 127918, 0, 127938, 127938, 0, 127940, 127940, 0, 127942, 127942, 0, 127946, 127950, 0, 127956, 127968, 0, 127981, 127981, 0, 127987, 127987, 0, 127989, 127989, 0, 127991, 127991, 0, 128008, 128008, 0, 128021, 128021, 0, 128031, 128031, 0, 128038, 128038, 0, 128063, 128063, 0, 128065, 128066, 0, 128070, 128073, 0, 128077, 128078, 0, 128083, 128083, 0, 128106, 128106, 0, 128125, 128125, 0, 128163, 128163, 0, 128176, 128176, 0, 128179, 128179, 0, 128187, 128187, 0, 128191, 128191, 0, 128203, 128203, 0, 128218, 128218, 0, 128223, 128223, 0, 128228, 128230, 0, 128234, 128237, 0, 128247, 128247, 0, 128249, 128251, 0, 128253, 128253, 0, 128264, 128264, 0, 128269, 128269, 0, 128274, 128275, 0, 128329, 128330, 0, 128336, 128359, 0, 128367, 128368, 0, 128371, 128377, 0, 128391, 128391, 0, 128394, 128397, 0, 128400, 128400, 0, 128421, 128421, 0, 128424, 128424, 0, 128433, 128434, 0, 128444, 128444, 0, 128450, 128452, 0, 128465, 128467, 0, 128476, 128478, 0, 128481, 128481, 0, 128483, 128483, 0, 128488, 128488, 0, 128495, 128495, 0, 128499, 128499, 0, 128506, 128506, 0, 128528, 128528, 0, 128647, 128647, 0, 128653, 128653, 0, 128657, 128657, 0, 128660, 128660, 0, 128664, 128664, 0, 128685, 128685, 0, 128690, 128690, 0, 128697, 128698, 0, 128700, 128700, 0, 128715, 128715, 0, 128717, 128719, 0, 128736, 128741, 0, 128745, 128745, 0, 128752, 128752, 0, 128755, 128755, 0];
|
|
8
|
+
|
|
9
|
+
// src/unicode.ts
|
|
10
|
+
function lookup(t, cp) {
|
|
11
|
+
let lo = 0, hi = t.length / 3 - 1;
|
|
12
|
+
while (lo <= hi) {
|
|
13
|
+
const m = lo + hi >> 1, s = t[3 * m];
|
|
14
|
+
if (cp < s) hi = m - 1;
|
|
15
|
+
else if (cp > t[3 * m + 1]) lo = m + 1;
|
|
16
|
+
else return t[3 * m + 2];
|
|
17
|
+
}
|
|
18
|
+
return -1;
|
|
19
|
+
}
|
|
20
|
+
var [PREPEND, CR, LF, CONTROL, EXTEND, ZWJ, RI, SPACING, L, V, T, LV, LVT] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
|
21
|
+
var OTHER = 13;
|
|
22
|
+
function graphemeRanges(s) {
|
|
23
|
+
const out = [];
|
|
24
|
+
let start = 0, prev = -1, ri = 0, pict = 0;
|
|
25
|
+
for (let i = 0; i < s.length; ) {
|
|
26
|
+
const cp = s.codePointAt(i);
|
|
27
|
+
const n = cp > 65535 ? 2 : 1;
|
|
28
|
+
const g0 = lookup(GCB, cp), g = g0 < 0 ? OTHER : g0, ep = lookup(EXT_PICT, cp) >= 0;
|
|
29
|
+
if (prev >= 0) {
|
|
30
|
+
let brk;
|
|
31
|
+
if (prev === CR && g === LF) brk = false;
|
|
32
|
+
else if (prev === CONTROL || prev === CR || prev === LF || g === CONTROL || g === CR || g === LF) brk = true;
|
|
33
|
+
else if (prev === L && (g === L || g === V || g === LV || g === LVT)) brk = false;
|
|
34
|
+
else if ((prev === LV || prev === V) && (g === V || g === T)) brk = false;
|
|
35
|
+
else if ((prev === LVT || prev === T) && g === T) brk = false;
|
|
36
|
+
else if (g === EXTEND || g === ZWJ || g === SPACING || prev === PREPEND) brk = false;
|
|
37
|
+
else if (pict === 2 && ep) brk = false;
|
|
38
|
+
else if (prev === RI && g === RI) brk = ri % 2 === 0;
|
|
39
|
+
else brk = true;
|
|
40
|
+
if (brk) {
|
|
41
|
+
out.push([start, i]);
|
|
42
|
+
start = i;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (prev < 0 || start === i) {
|
|
46
|
+
ri = 0;
|
|
47
|
+
pict = 0;
|
|
48
|
+
}
|
|
49
|
+
ri = g === RI ? ri + 1 : 0;
|
|
50
|
+
pict = ep ? 1 : g === EXTEND && pict === 1 ? 1 : g === ZWJ && pict === 1 ? 2 : 0;
|
|
51
|
+
prev = g;
|
|
52
|
+
i += n;
|
|
53
|
+
}
|
|
54
|
+
if (s.length) out.push([start, s.length]);
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
function graphemes(s) {
|
|
58
|
+
return graphemeRanges(s).map(([a, b]) => s.slice(a, b));
|
|
59
|
+
}
|
|
60
|
+
function graphemeCount(s) {
|
|
61
|
+
return graphemeRanges(s).length;
|
|
62
|
+
}
|
|
63
|
+
var isMark = (cp) => lookup(MARK, cp) >= 0;
|
|
64
|
+
var isWide = (cp) => lookup(WIDE, cp) >= 0;
|
|
65
|
+
var isIgnorable = (cp) => lookup(IGNORABLE, cp) >= 0;
|
|
66
|
+
var CF = /^\p{Cf}$/u;
|
|
67
|
+
var first = (cluster) => {
|
|
68
|
+
const cps = Array.from(cluster);
|
|
69
|
+
return cps.find((c) => !isMark(c.codePointAt(0))) ?? cps[0];
|
|
70
|
+
};
|
|
71
|
+
function clusterWidth(cluster) {
|
|
72
|
+
const cps = Array.from(cluster, (c) => c.codePointAt(0));
|
|
73
|
+
if (cps.every((c) => isMark(c) || isIgnorable(c) || CF.test(String.fromCodePoint(c)))) return 0;
|
|
74
|
+
const f = first(cluster).codePointAt(0);
|
|
75
|
+
if (isWide(f) || lookup(GCB, f) === RI) return 2;
|
|
76
|
+
const i = cps.indexOf(f);
|
|
77
|
+
if (cps[i + 1] === 65039 && lookup(VS16_BASE, f) >= 0) return 2;
|
|
78
|
+
return 1;
|
|
79
|
+
}
|
|
80
|
+
function cellRune(cluster) {
|
|
81
|
+
if (clusterWidth(cluster) === 2) return "\uFFFD";
|
|
82
|
+
const r = Array.from(cluster).find((c) => !isMark(c.codePointAt(0)));
|
|
83
|
+
return r ?? " ";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/parse.ts
|
|
87
|
+
var utf8 = new TextEncoder();
|
|
88
|
+
var MAX_INPUT = 256 * 1024;
|
|
89
|
+
var MAX_LINE = 16384;
|
|
90
|
+
var bytes = (s) => utf8.encode(s).length;
|
|
91
|
+
var SyntaxErr = class {
|
|
92
|
+
constructor(d) {
|
|
93
|
+
this.d = d;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
var SIMPLE_ESC = { a: "\x07", b: "\b", f: "\f", n: "\n", r: "\r", t: " ", v: "\v", "\\": "\\", '"': '"' };
|
|
97
|
+
var isDigit = (c) => c >= "0" && c <= "9";
|
|
98
|
+
var isIdStart = (c) => /[A-Za-z_]/.test(c);
|
|
99
|
+
var isIdChar = (c) => /[A-Za-z0-9_]/.test(c);
|
|
100
|
+
var hex = (s) => /^[0-9a-fA-F]+$/.test(s);
|
|
101
|
+
function decimalToNs(tok) {
|
|
102
|
+
const [w, f = ""] = tok.split(".");
|
|
103
|
+
const frac = (f + "0000000000").slice(0, 10);
|
|
104
|
+
let ns = Number(w || "0") * 1e9 + Number(frac.slice(0, 9)) + (frac[9] >= "5" ? 1 : 0);
|
|
105
|
+
return ns;
|
|
106
|
+
}
|
|
107
|
+
var Cur = class {
|
|
108
|
+
constructor(s, line2) {
|
|
109
|
+
this.s = s;
|
|
110
|
+
this.line = line2;
|
|
111
|
+
this.i = 0;
|
|
112
|
+
}
|
|
113
|
+
col(at = this.i) {
|
|
114
|
+
return bytes(this.s.slice(0, at)) + 1;
|
|
115
|
+
}
|
|
116
|
+
err(msg, at = this.i) {
|
|
117
|
+
throw new SyntaxErr({ line: this.line, col: this.col(at), message: msg });
|
|
118
|
+
}
|
|
119
|
+
ws() {
|
|
120
|
+
while (this.i < this.s.length && (this.s[this.i] === " " || this.s[this.i] === " ")) this.i++;
|
|
121
|
+
}
|
|
122
|
+
eof() {
|
|
123
|
+
return this.i >= this.s.length;
|
|
124
|
+
}
|
|
125
|
+
peek() {
|
|
126
|
+
return this.s[this.i] ?? "";
|
|
127
|
+
}
|
|
128
|
+
eat(c) {
|
|
129
|
+
if (this.s.startsWith(c, this.i)) {
|
|
130
|
+
this.i += c.length;
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
expect(c) {
|
|
136
|
+
this.ws();
|
|
137
|
+
if (!this.eat(c)) this.err(this.eof() ? `unexpected end of line, expected ${JSON.stringify(c)}` : `expected ${JSON.stringify(c)} but found ${JSON.stringify(this.peek())}`);
|
|
138
|
+
}
|
|
139
|
+
ident(what = "identifier") {
|
|
140
|
+
this.ws();
|
|
141
|
+
if (!isIdStart(this.peek())) this.err(this.eof() ? `unexpected end of line, expected ${what}` : `unexpected character ${JSON.stringify(this.peek())}`);
|
|
142
|
+
const st = this.i;
|
|
143
|
+
while (isIdChar(this.peek())) this.i++;
|
|
144
|
+
return this.s.slice(st, this.i);
|
|
145
|
+
}
|
|
146
|
+
/** unsigned decimal; returns raw text */
|
|
147
|
+
unsigned() {
|
|
148
|
+
const st = this.i;
|
|
149
|
+
let n = 0;
|
|
150
|
+
while (isDigit(this.peek())) {
|
|
151
|
+
this.i++;
|
|
152
|
+
n++;
|
|
153
|
+
}
|
|
154
|
+
if (this.peek() === ".") {
|
|
155
|
+
this.i++;
|
|
156
|
+
while (isDigit(this.peek())) {
|
|
157
|
+
this.i++;
|
|
158
|
+
n++;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (n === 0) this.err("expected number", st);
|
|
162
|
+
return this.s.slice(st, this.i);
|
|
163
|
+
}
|
|
164
|
+
number() {
|
|
165
|
+
this.ws();
|
|
166
|
+
const st = this.i;
|
|
167
|
+
let neg = false;
|
|
168
|
+
if (this.peek() === "+" || this.peek() === "-") {
|
|
169
|
+
neg = this.peek() === "-";
|
|
170
|
+
this.i++;
|
|
171
|
+
}
|
|
172
|
+
const u = this.unsigned();
|
|
173
|
+
if (this.peek() === "e" || this.peek() === "E") this.err("exponents are not allowed", this.i);
|
|
174
|
+
return neg ? -Number(u) : Number(u);
|
|
175
|
+
}
|
|
176
|
+
string() {
|
|
177
|
+
this.ws();
|
|
178
|
+
const st = this.i;
|
|
179
|
+
if (!this.eat('"')) this.err("expected string");
|
|
180
|
+
let out = "";
|
|
181
|
+
for (; ; ) {
|
|
182
|
+
if (this.eof()) this.err("unterminated string", st);
|
|
183
|
+
const c = this.s[this.i];
|
|
184
|
+
if (c === '"') {
|
|
185
|
+
this.i++;
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
if (c !== "\\") {
|
|
189
|
+
out += c;
|
|
190
|
+
this.i++;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const eAt = this.i;
|
|
194
|
+
this.i++;
|
|
195
|
+
const e = this.s[this.i] ?? "";
|
|
196
|
+
if (e in SIMPLE_ESC) {
|
|
197
|
+
out += SIMPLE_ESC[e];
|
|
198
|
+
this.i++;
|
|
199
|
+
} else if (e === "x" || e === "u" || e === "U") {
|
|
200
|
+
const n = e === "x" ? 2 : e === "u" ? 4 : 8;
|
|
201
|
+
const h = this.s.slice(this.i + 1, this.i + 1 + n);
|
|
202
|
+
if (h.length !== n || !hex(h)) this.err("invalid escape in string", eAt);
|
|
203
|
+
const cp = parseInt(h, 16);
|
|
204
|
+
if (e !== "x" && (cp > 1114111 || cp >= 55296 && cp < 57344)) this.err("invalid escape in string", eAt);
|
|
205
|
+
out += e === "x" ? String.fromCharCode(cp) : String.fromCodePoint(cp);
|
|
206
|
+
this.i += 1 + n;
|
|
207
|
+
} else if (e >= "0" && e <= "7") {
|
|
208
|
+
const o = this.s.slice(this.i, this.i + 3);
|
|
209
|
+
if (!/^[0-7]{3}$/.test(o) || parseInt(o, 8) > 255) this.err("invalid escape in string", eAt);
|
|
210
|
+
out += String.fromCharCode(parseInt(o, 8));
|
|
211
|
+
this.i += 3;
|
|
212
|
+
} else this.err("invalid escape in string", eAt);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
coord() {
|
|
216
|
+
this.ws();
|
|
217
|
+
const c = this.peek();
|
|
218
|
+
if (isIdStart(c)) {
|
|
219
|
+
const at = this.i;
|
|
220
|
+
const name = this.ident();
|
|
221
|
+
if (!["center", "left", "right", "top", "bottom"].includes(name)) this.err(`unknown anchor ${JSON.stringify(name)}`, at);
|
|
222
|
+
let offset = 0;
|
|
223
|
+
this.ws();
|
|
224
|
+
if (this.peek() === "+" || this.peek() === "-") {
|
|
225
|
+
const neg = this.peek() === "-";
|
|
226
|
+
this.i++;
|
|
227
|
+
this.ws();
|
|
228
|
+
offset = Number(this.unsigned());
|
|
229
|
+
if (neg) offset = -offset;
|
|
230
|
+
}
|
|
231
|
+
return { kind: "anchor", name, offset };
|
|
232
|
+
}
|
|
233
|
+
const value = this.number();
|
|
234
|
+
const percent = this.eat("%");
|
|
235
|
+
return { kind: "num", value, percent };
|
|
236
|
+
}
|
|
237
|
+
point() {
|
|
238
|
+
this.ws();
|
|
239
|
+
const col = this.col();
|
|
240
|
+
this.expect("(");
|
|
241
|
+
const x = this.coord();
|
|
242
|
+
this.expect(",");
|
|
243
|
+
const y = this.coord();
|
|
244
|
+
this.expect(")");
|
|
245
|
+
return { x, y, col };
|
|
246
|
+
}
|
|
247
|
+
value() {
|
|
248
|
+
this.ws();
|
|
249
|
+
const st = this.i;
|
|
250
|
+
const c = this.peek();
|
|
251
|
+
if (c === "(") {
|
|
252
|
+
const value = this.point();
|
|
253
|
+
return { kind: "point", value, raw: this.s.slice(st, this.i) };
|
|
254
|
+
}
|
|
255
|
+
if (c === '"') {
|
|
256
|
+
const value = this.string();
|
|
257
|
+
return { kind: "string", value, raw: this.s.slice(st, this.i) };
|
|
258
|
+
}
|
|
259
|
+
if (c === "+" || c === "-" || c === "." || isDigit(c)) {
|
|
260
|
+
const value = this.number();
|
|
261
|
+
const sst = this.i;
|
|
262
|
+
while (/[A-Za-z]/.test(this.peek())) this.i++;
|
|
263
|
+
return { kind: "number", value, suffix: this.s.slice(sst, this.i), raw: this.s.slice(st, this.i) };
|
|
264
|
+
}
|
|
265
|
+
if (isIdStart(c)) {
|
|
266
|
+
this.ident();
|
|
267
|
+
while (this.peek() === "-" && isIdStart(this.s[this.i + 1] ?? "")) {
|
|
268
|
+
this.i++;
|
|
269
|
+
this.ident();
|
|
270
|
+
}
|
|
271
|
+
return { kind: "keyword", value: this.s.slice(st, this.i), raw: this.s.slice(st, this.i) };
|
|
272
|
+
}
|
|
273
|
+
return this.err(this.eof() ? "unexpected end of line, expected value" : `unexpected character ${JSON.stringify(c)}`);
|
|
274
|
+
}
|
|
275
|
+
end() {
|
|
276
|
+
this.ws();
|
|
277
|
+
if (!this.eof()) this.err(`unexpected character ${JSON.stringify(this.peek())}`);
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
function parseShape(c) {
|
|
281
|
+
const at = c.i;
|
|
282
|
+
const kind = c.ident("shape");
|
|
283
|
+
c.expect("(");
|
|
284
|
+
if (kind === "text") {
|
|
285
|
+
const text = c.string();
|
|
286
|
+
let big = false;
|
|
287
|
+
c.ws();
|
|
288
|
+
if (c.eat(",")) {
|
|
289
|
+
const w = c.ident();
|
|
290
|
+
if (w !== "big") c.err(`unknown text option ${JSON.stringify(w)}`);
|
|
291
|
+
big = true;
|
|
292
|
+
}
|
|
293
|
+
c.expect(")");
|
|
294
|
+
return { kind, text, big };
|
|
295
|
+
}
|
|
296
|
+
if (kind === "circle") {
|
|
297
|
+
const radius = c.number();
|
|
298
|
+
c.expect(")");
|
|
299
|
+
return { kind, radius };
|
|
300
|
+
}
|
|
301
|
+
if (kind === "rect") {
|
|
302
|
+
const width = c.number();
|
|
303
|
+
c.expect(",");
|
|
304
|
+
const height = c.number();
|
|
305
|
+
const s = { kind, width, height };
|
|
306
|
+
const seen = /* @__PURE__ */ new Set();
|
|
307
|
+
for (c.ws(); c.eat(","); c.ws()) {
|
|
308
|
+
const kat = c.i;
|
|
309
|
+
const k = c.ident();
|
|
310
|
+
if (k !== "border" && k !== "title") c.err(`unknown rect argument ${JSON.stringify(k)}`, kat);
|
|
311
|
+
if (seen.has(k)) c.err(`duplicate rect argument ${k}`, kat);
|
|
312
|
+
seen.add(k);
|
|
313
|
+
c.expect("=");
|
|
314
|
+
if (k === "title") s.title = c.string();
|
|
315
|
+
else {
|
|
316
|
+
c.ws();
|
|
317
|
+
const v = c.ident();
|
|
318
|
+
if (v !== "square" && v !== "round") c.err(`unknown border ${JSON.stringify(v)}`);
|
|
319
|
+
s.border = v;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
c.expect(")");
|
|
323
|
+
return s;
|
|
324
|
+
}
|
|
325
|
+
if (kind === "cube") {
|
|
326
|
+
let size;
|
|
327
|
+
let style;
|
|
328
|
+
for (let first2 = true; ; first2 = false) {
|
|
329
|
+
c.ws();
|
|
330
|
+
if (!first2 && !c.eat(",")) break;
|
|
331
|
+
const kat = c.i;
|
|
332
|
+
c.ws();
|
|
333
|
+
const k = c.ident();
|
|
334
|
+
c.expect("=");
|
|
335
|
+
if (k === "size") {
|
|
336
|
+
if (size !== void 0) c.err("duplicate cube argument size", kat);
|
|
337
|
+
size = c.number();
|
|
338
|
+
} else if (k === "style") {
|
|
339
|
+
if (style !== void 0) c.err("duplicate cube argument style", kat);
|
|
340
|
+
c.ws();
|
|
341
|
+
style = c.ident();
|
|
342
|
+
if (style !== "wire") c.err("cube style must be wire");
|
|
343
|
+
} else c.err(`unknown cube argument ${JSON.stringify(k)}`, kat);
|
|
344
|
+
}
|
|
345
|
+
c.expect(")");
|
|
346
|
+
if (size === void 0) c.err("cube requires size", at);
|
|
347
|
+
return { kind, size, style };
|
|
348
|
+
}
|
|
349
|
+
return c.err(`unknown shape ${JSON.stringify(kind)}`, at);
|
|
350
|
+
}
|
|
351
|
+
function parseActor(c, line2, col) {
|
|
352
|
+
const name = c.ident("actor name");
|
|
353
|
+
c.expect("=");
|
|
354
|
+
c.ws();
|
|
355
|
+
const shape = parseShape(c);
|
|
356
|
+
c.ws();
|
|
357
|
+
const kw = c.i;
|
|
358
|
+
if (c.ident('"at"') !== "at") c.err('expected "at"', kw);
|
|
359
|
+
const at = c.point();
|
|
360
|
+
const a = { kind: "actor", line: line2, col, name, shape, at };
|
|
361
|
+
const seen = /* @__PURE__ */ new Set();
|
|
362
|
+
for (c.ws(); !c.eof(); c.ws()) {
|
|
363
|
+
const kat = c.i;
|
|
364
|
+
const k = c.ident();
|
|
365
|
+
if (!["color", "parent", "z", "anchor"].includes(k)) c.err(`unknown actor attribute ${JSON.stringify(k)}`, kat);
|
|
366
|
+
if (seen.has(k)) c.err(`duplicate actor attribute ${k}`, kat);
|
|
367
|
+
seen.add(k);
|
|
368
|
+
c.expect("=");
|
|
369
|
+
c.ws();
|
|
370
|
+
if (k === "z") a.z = c.number();
|
|
371
|
+
else if (k === "anchor") a.anchor = c.point();
|
|
372
|
+
else a[k] = c.ident();
|
|
373
|
+
}
|
|
374
|
+
return a;
|
|
375
|
+
}
|
|
376
|
+
function parseAction(c, line2, col) {
|
|
377
|
+
c.ws();
|
|
378
|
+
const tat = c.i;
|
|
379
|
+
const t0 = c.unsigned();
|
|
380
|
+
const tok = c.eat("s") ? t0 : t0;
|
|
381
|
+
const timeNs = decimalToNs(tok);
|
|
382
|
+
if (!(timeNs >= 0) || timeNs > 1e15) c.err("time out of range", tat);
|
|
383
|
+
c.expect(":");
|
|
384
|
+
const actor = c.ident("actor name");
|
|
385
|
+
c.expect(".");
|
|
386
|
+
const verb = c.ident("action verb");
|
|
387
|
+
c.expect("(");
|
|
388
|
+
const args = [];
|
|
389
|
+
c.ws();
|
|
390
|
+
for (let first2 = true; ; first2 = false) {
|
|
391
|
+
c.ws();
|
|
392
|
+
if (first2 && c.peek() === ")") c.err("expected argument");
|
|
393
|
+
if (!first2 && !c.eat(",")) break;
|
|
394
|
+
c.ws();
|
|
395
|
+
const kcol = c.col();
|
|
396
|
+
const key = c.ident("argument");
|
|
397
|
+
c.ws();
|
|
398
|
+
if (c.eat("=")) args.push({ key, value: c.value(), col: kcol });
|
|
399
|
+
else args.push({ key, col: kcol });
|
|
400
|
+
}
|
|
401
|
+
c.expect(")");
|
|
402
|
+
return { kind: "action", line: line2, col, timeNs, actor, verb, args };
|
|
403
|
+
}
|
|
404
|
+
function parse(source) {
|
|
405
|
+
if (typeof source !== "string") throw new TypeError("mdgl.parse: source must be a string");
|
|
406
|
+
const doc = { statements: [] };
|
|
407
|
+
if (bytes(source) > MAX_INPUT) {
|
|
408
|
+
doc.inputError = { line: 1, col: 1, message: "input exceeds 256 KiB" };
|
|
409
|
+
return doc;
|
|
410
|
+
}
|
|
411
|
+
const lines = source.split("\n");
|
|
412
|
+
for (let i = 0; i < lines.length; i++) {
|
|
413
|
+
const n = i + 1;
|
|
414
|
+
if (bytes(lines[i]) > MAX_LINE) {
|
|
415
|
+
doc.inputError = { line: n, col: 1, message: "line exceeds 16 KiB" };
|
|
416
|
+
return doc;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
for (let i = 0; i < lines.length; i++) {
|
|
420
|
+
const n = i + 1;
|
|
421
|
+
const raw = lines[i].endsWith("\r") ? lines[i].slice(0, -1) : lines[i];
|
|
422
|
+
const c = new Cur(raw, n);
|
|
423
|
+
c.ws();
|
|
424
|
+
if (c.eof() || c.peek() === "#") continue;
|
|
425
|
+
const col = c.col();
|
|
426
|
+
try {
|
|
427
|
+
if (c.peek() === "@") {
|
|
428
|
+
c.i++;
|
|
429
|
+
doc.statements.push(parseAction(c, n, col));
|
|
430
|
+
c.end();
|
|
431
|
+
continue;
|
|
432
|
+
}
|
|
433
|
+
const at = c.i;
|
|
434
|
+
const head = c.ident("statement");
|
|
435
|
+
if (head === "mdgl") {
|
|
436
|
+
c.ws();
|
|
437
|
+
const ok = raw.slice(c.i).trim() === "0.1";
|
|
438
|
+
c.i = raw.length;
|
|
439
|
+
doc.statements.push({ kind: "version", line: n, col, ok });
|
|
440
|
+
} else if (head === "scene") {
|
|
441
|
+
const attrs = [];
|
|
442
|
+
for (c.ws(); !c.eof(); c.ws()) {
|
|
443
|
+
const acol = c.col();
|
|
444
|
+
const key = c.ident("scene attribute");
|
|
445
|
+
c.expect("=");
|
|
446
|
+
const st = c.i;
|
|
447
|
+
while (!c.eof() && c.peek() !== " " && c.peek() !== " ") c.i++;
|
|
448
|
+
if (c.i === st) c.err("expected scene attribute value");
|
|
449
|
+
attrs.push({ key, value: raw.slice(st, c.i), col: acol });
|
|
450
|
+
}
|
|
451
|
+
doc.statements.push({ kind: "scene", line: n, col, attrs });
|
|
452
|
+
} else if (head === "actor") {
|
|
453
|
+
doc.statements.push(parseActor(c, n, col));
|
|
454
|
+
c.end();
|
|
455
|
+
} else doc.statements.push({ kind: "unknown", line: n, col });
|
|
456
|
+
} catch (e) {
|
|
457
|
+
if (e instanceof SyntaxErr) {
|
|
458
|
+
doc.syntax = e.d;
|
|
459
|
+
return doc;
|
|
460
|
+
}
|
|
461
|
+
throw e;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return doc;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// src/check.ts
|
|
468
|
+
var MAX_ACTORS = 64;
|
|
469
|
+
var MAX_ACTIONS = 1024;
|
|
470
|
+
var MAX_NS = 6e10;
|
|
471
|
+
var SCENE_KEYS = ["width", "height", "period", "repeat", "fallback", "fps"];
|
|
472
|
+
var COLORS = ["normal", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "accent"];
|
|
473
|
+
var EASES = ["linear", "ease", "ease-in", "ease-out", "ease-in-out", "bounce"];
|
|
474
|
+
var VERBS = ["fade", "move", "scale", "color", "type", "blink", "wipe", "slide", "rotate"];
|
|
475
|
+
var PROP = { fade: "opacity", blink: "opacity", move: "position", slide: "position", scale: "scale", color: "color", type: "reveal", wipe: "reveal", rotate: "rotation" };
|
|
476
|
+
var Stop = class {
|
|
477
|
+
constructor(d) {
|
|
478
|
+
this.d = d;
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
var q = (s) => JSON.stringify(s);
|
|
482
|
+
function lev(a, b) {
|
|
483
|
+
const p = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
484
|
+
for (let i = 1; i <= a.length; i++) {
|
|
485
|
+
let prev = p[0];
|
|
486
|
+
p[0] = i;
|
|
487
|
+
for (let j = 1; j <= b.length; j++) {
|
|
488
|
+
const t = p[j];
|
|
489
|
+
p[j] = Math.min(p[j] + 1, p[j - 1] + 1, prev + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
490
|
+
prev = t;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return p[b.length];
|
|
494
|
+
}
|
|
495
|
+
function suggest(name, cands) {
|
|
496
|
+
let best, bd = 3;
|
|
497
|
+
for (const c of [...cands].sort()) {
|
|
498
|
+
const d = lev(name, c);
|
|
499
|
+
if (d <= 2 && d < bd) {
|
|
500
|
+
best = c;
|
|
501
|
+
bd = d;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
return best === void 0 ? "" : `; did you mean ${q(best)}?`;
|
|
505
|
+
}
|
|
506
|
+
function checkScene(sc) {
|
|
507
|
+
const fail = (m) => {
|
|
508
|
+
throw new Stop({ line: sc.line, col: sc.col, message: m });
|
|
509
|
+
};
|
|
510
|
+
const v = /* @__PURE__ */ new Map();
|
|
511
|
+
for (const a of sc.attrs) {
|
|
512
|
+
if (!SCENE_KEYS.includes(a.key)) fail(`unknown scene attribute ${q(a.key)}${suggest(a.key, SCENE_KEYS)}`);
|
|
513
|
+
if (v.has(a.key)) fail(`duplicate scene attribute ${q(a.key)}`);
|
|
514
|
+
v.set(a.key, a.value);
|
|
515
|
+
}
|
|
516
|
+
for (const k of ["width", "height", "fallback"]) if (!v.has(k)) fail(`missing scene attribute ${k}`);
|
|
517
|
+
const int = (k, lo, hi, def) => {
|
|
518
|
+
const s = v.get(k) ?? def;
|
|
519
|
+
if (s === void 0 || !/^[0-9]{1,9}$/.test(s) || Number(s) < lo || Number(s) > hi) fail(`${k} must be an integer in ${lo}..${hi}`);
|
|
520
|
+
return Number(s);
|
|
521
|
+
};
|
|
522
|
+
const width = int("width", 1, 200), height = int("height", 1, 60), fps = int("fps", 1, 30, "30");
|
|
523
|
+
let period;
|
|
524
|
+
if (v.has("period")) {
|
|
525
|
+
const m = /^((?:[0-9]+\.?[0-9]*|\.[0-9]+))s?$/.exec(v.get("period"));
|
|
526
|
+
period = m ? decimalToNs(m[1]) : NaN;
|
|
527
|
+
if (!(period > 0) || period > MAX_NS) fail("period must be positive seconds up to 60");
|
|
528
|
+
}
|
|
529
|
+
let repeat = 1;
|
|
530
|
+
const r = v.get("repeat");
|
|
531
|
+
if (r === "infinite") repeat = Infinity;
|
|
532
|
+
else if (r !== void 0) repeat = int("repeat", 1, 1e3);
|
|
533
|
+
if (repeat !== 1 && period === void 0) fail("repeat requires explicit period");
|
|
534
|
+
const f = v.get("fallback");
|
|
535
|
+
let fallback;
|
|
536
|
+
if (f === "start" || f === "end") fallback = { kind: f };
|
|
537
|
+
else {
|
|
538
|
+
const m = /^@((?:[0-9]+\.?[0-9]*|\.[0-9]+))s?$/.exec(f);
|
|
539
|
+
if (!m) return fail("fallback must be start, end or @time");
|
|
540
|
+
fallback = { kind: "at", ns: decimalToNs(m[1]) };
|
|
541
|
+
}
|
|
542
|
+
return { line: sc.line, width, height, fps, period, repeat, fallback, duration: period ?? 0 };
|
|
543
|
+
}
|
|
544
|
+
function checkCoord(c, axis, fail) {
|
|
545
|
+
if (c.kind === "num") {
|
|
546
|
+
if (!Number.isFinite(c.value) || Math.abs(c.value) > 1e4) fail("coordinate out of range");
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
const ok = axis === "x" ? ["center", "left", "right"] : ["center", "top", "bottom"];
|
|
550
|
+
if (!ok.includes(c.name)) fail(`anchor ${c.name} is not valid on the ${axis} axis`);
|
|
551
|
+
if (Math.abs(c.offset) > 1e4) fail("coordinate out of range");
|
|
552
|
+
}
|
|
553
|
+
function checkPoint(p, fail) {
|
|
554
|
+
checkCoord(p.x, "x", fail);
|
|
555
|
+
checkCoord(p.y, "y", fail);
|
|
556
|
+
}
|
|
557
|
+
function checkActor(a, names) {
|
|
558
|
+
const fail = (m) => {
|
|
559
|
+
throw new Stop({ line: a.line, col: a.col, message: m });
|
|
560
|
+
};
|
|
561
|
+
if (names.has(a.name)) fail(`duplicate actor ${a.name}`);
|
|
562
|
+
const s = a.shape;
|
|
563
|
+
const pos = (n, what, max = 200) => {
|
|
564
|
+
if (!(n > 0 && n <= max)) fail(`${what} must be greater than 0 and at most ${max}`);
|
|
565
|
+
};
|
|
566
|
+
const label = (t, what) => {
|
|
567
|
+
if (/[\x00-\x1f\x7f-\x9f]/.test(t)) fail(`${what} must not contain tabs, newlines or control characters`);
|
|
568
|
+
if (graphemeCount(t) > 1024) fail(`${what} exceeds 1024 grapheme clusters`);
|
|
569
|
+
};
|
|
570
|
+
if (s.kind === "text") label(s.text, "text");
|
|
571
|
+
else if (s.kind === "rect") {
|
|
572
|
+
pos(s.width, "rect width");
|
|
573
|
+
pos(s.height, "rect height");
|
|
574
|
+
if (s.title !== void 0) label(s.title, "title");
|
|
575
|
+
} else if (s.kind === "circle") {
|
|
576
|
+
if (!(s.radius > 0 && s.radius <= 100)) fail("circle radius must be positive and <=100");
|
|
577
|
+
} else pos(s.size, "cube size");
|
|
578
|
+
checkPoint(a.at, fail);
|
|
579
|
+
if (a.anchor) checkPoint(a.anchor, fail);
|
|
580
|
+
if (a.color !== void 0 && !COLORS.includes(a.color)) fail(`unknown color ${q(a.color)}${suggest(a.color, COLORS)}`);
|
|
581
|
+
if (a.z !== void 0 && !Number.isInteger(a.z)) fail("z must be an integer");
|
|
582
|
+
}
|
|
583
|
+
function checkParents(actors) {
|
|
584
|
+
const by = new Map(actors.map((a) => [a.name, a]));
|
|
585
|
+
for (const a of actors) {
|
|
586
|
+
if (a.parent !== void 0 && !by.has(a.parent)) throw new Stop({ line: a.line, col: a.col, message: `unknown parent ${q(a.parent)}${suggest(a.parent, [...by.keys()])}` });
|
|
587
|
+
}
|
|
588
|
+
for (const a of actors) {
|
|
589
|
+
const seen = /* @__PURE__ */ new Set();
|
|
590
|
+
for (let c = a; c; c = c.parent === void 0 ? void 0 : by.get(c.parent)) {
|
|
591
|
+
if (seen.has(c.name)) {
|
|
592
|
+
if (c === a) throw new Stop({ line: a.line, col: a.col, message: `parent cycle involving ${a.name}` });
|
|
593
|
+
break;
|
|
594
|
+
}
|
|
595
|
+
seen.add(c.name);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
function checkAction(a, actors) {
|
|
600
|
+
const fail = (m) => {
|
|
601
|
+
throw new Stop({ line: a.line, col: a.col, message: m });
|
|
602
|
+
};
|
|
603
|
+
const actor = actors.get(a.actor);
|
|
604
|
+
if (!actor) return fail(`unknown actor ${q(a.actor)}${suggest(a.actor, [...actors.keys()])}`);
|
|
605
|
+
if (!VERBS.includes(a.verb)) return fail(`unknown action ${q(a.verb)}${suggest(a.verb, VERBS)}`);
|
|
606
|
+
if (a.timeNs > MAX_NS) fail("action time must be at most 60 seconds");
|
|
607
|
+
const allowed = {
|
|
608
|
+
fade: ["in", "out", "dur", "ease"],
|
|
609
|
+
move: ["to", "dur", "ease"],
|
|
610
|
+
scale: ["to", "dur", "ease"],
|
|
611
|
+
color: ["to", "dur", "ease"],
|
|
612
|
+
type: ["per_char"],
|
|
613
|
+
blink: ["times", "dur"],
|
|
614
|
+
wipe: ["in", "out", "dur", "ease"],
|
|
615
|
+
slide: ["in", "out", "to", "dur", "ease"],
|
|
616
|
+
rotate: ["x", "y", "z", "dur", "ease"]
|
|
617
|
+
};
|
|
618
|
+
const args = /* @__PURE__ */ new Map();
|
|
619
|
+
for (const g of a.args) {
|
|
620
|
+
if (!allowed[a.verb].includes(g.key)) fail(`unknown argument ${q(g.key)} for ${a.verb}${suggest(g.key, allowed[a.verb])}`);
|
|
621
|
+
if (args.has(g.key)) fail(`duplicate argument ${g.key}`);
|
|
622
|
+
args.set(g.key, g);
|
|
623
|
+
}
|
|
624
|
+
const need = (k) => {
|
|
625
|
+
const g = args.get(k);
|
|
626
|
+
if (!g) return fail(`${a.verb} requires ${k}`);
|
|
627
|
+
if (!g.value) return fail(`${k} requires a value`);
|
|
628
|
+
return g.value;
|
|
629
|
+
};
|
|
630
|
+
const flag = (k) => {
|
|
631
|
+
const g = args.get(k);
|
|
632
|
+
if (g && g.value) fail(`${k} takes no value`);
|
|
633
|
+
return !!g;
|
|
634
|
+
};
|
|
635
|
+
const seconds = (k, v, what) => {
|
|
636
|
+
if (v.kind !== "number" || !(v.suffix === "" || v.suffix === "s") || v.value < 0 || !/^[+]?[0-9.]+s?$/.test(v.raw)) return fail(`${what} must be positive seconds`);
|
|
637
|
+
const ns = decimalToNs(v.raw.replace(/^\+/, "").replace(/s$/, ""));
|
|
638
|
+
if (!(ns > 0)) return fail(`${what} must be positive`);
|
|
639
|
+
if (ns > MAX_NS) fail(`${what} must be at most 60 seconds`);
|
|
640
|
+
return ns;
|
|
641
|
+
};
|
|
642
|
+
let durNs = 0;
|
|
643
|
+
if (a.verb !== "type") {
|
|
644
|
+
if (a.verb === "rotate" || a.verb === "fade" || a.verb === "move" || a.verb === "scale" || a.verb === "color" || a.verb === "wipe" || a.verb === "slide" || a.verb === "blink") durNs = seconds("dur", need("dur"), "dur");
|
|
645
|
+
}
|
|
646
|
+
const ease = args.get("ease");
|
|
647
|
+
if (ease) {
|
|
648
|
+
const e = need("ease");
|
|
649
|
+
if (e.kind !== "keyword" || !EASES.includes(e.value)) fail(`unknown ease ${q(e.raw)}${suggest(e.raw, EASES)}`);
|
|
650
|
+
}
|
|
651
|
+
const inout = () => {
|
|
652
|
+
const i = flag("in"), o = flag("out");
|
|
653
|
+
if (i === o) fail(`${a.verb} requires exactly one of in or out`);
|
|
654
|
+
};
|
|
655
|
+
const num2 = (k, lo, msg) => {
|
|
656
|
+
const v = need(k);
|
|
657
|
+
if (v.kind !== "number" || v.suffix !== "") fail(`${k} must be a number`);
|
|
658
|
+
const n = v.value;
|
|
659
|
+
if (!lo(n)) fail(msg);
|
|
660
|
+
return n;
|
|
661
|
+
};
|
|
662
|
+
switch (a.verb) {
|
|
663
|
+
case "fade":
|
|
664
|
+
inout();
|
|
665
|
+
break;
|
|
666
|
+
case "wipe":
|
|
667
|
+
inout();
|
|
668
|
+
break;
|
|
669
|
+
case "move": {
|
|
670
|
+
const v = need("to");
|
|
671
|
+
if (v.kind !== "point") fail("to must be a point");
|
|
672
|
+
checkPoint(v.value, fail);
|
|
673
|
+
break;
|
|
674
|
+
}
|
|
675
|
+
case "scale":
|
|
676
|
+
num2("to", (n) => n > 0 && n <= 16, "scale must be greater than 0 and at most 16");
|
|
677
|
+
break;
|
|
678
|
+
case "color": {
|
|
679
|
+
const v = need("to");
|
|
680
|
+
if (v.kind !== "keyword" || !COLORS.includes(v.value)) fail(`unknown color ${q(v.raw)}${suggest(v.raw, COLORS)}`);
|
|
681
|
+
break;
|
|
682
|
+
}
|
|
683
|
+
case "blink":
|
|
684
|
+
num2("times", (n) => Number.isInteger(n) && n > 0, "times must be a positive integer");
|
|
685
|
+
break;
|
|
686
|
+
case "slide": {
|
|
687
|
+
inout();
|
|
688
|
+
const v = need("to");
|
|
689
|
+
if (v.kind !== "keyword" || !["left", "right", "top", "bottom"].includes(v.value)) fail("slide to must be left, right, top or bottom");
|
|
690
|
+
break;
|
|
691
|
+
}
|
|
692
|
+
case "rotate": {
|
|
693
|
+
if (actor.shape.kind !== "cube") fail("rotate is only valid on cube actors");
|
|
694
|
+
if (!["x", "y", "z"].some((k) => args.has(k))) fail("rotate requires at least one of x, y, z");
|
|
695
|
+
for (const k of ["x", "y", "z"]) {
|
|
696
|
+
if (!args.has(k)) continue;
|
|
697
|
+
const v = need(k);
|
|
698
|
+
if (v.kind !== "number" || !["", "deg", "rad"].includes(v.suffix)) fail(`${k} must be an angle in degrees or radians`);
|
|
699
|
+
const deg2 = v.kind === "number" ? v.suffix === "rad" ? v.value * 180 / Math.PI : v.value : 0;
|
|
700
|
+
if (Math.abs(deg2) > 1e4) fail("rotation out of range");
|
|
701
|
+
}
|
|
702
|
+
break;
|
|
703
|
+
}
|
|
704
|
+
case "type": {
|
|
705
|
+
const sh = actor.shape;
|
|
706
|
+
if (sh.kind !== "text") return fail("type is only valid on text actors");
|
|
707
|
+
const per = seconds("per_char", need("per_char"), "per_char");
|
|
708
|
+
durNs = per * graphemeCount(sh.text);
|
|
709
|
+
break;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
const endNs = a.timeNs + durNs;
|
|
713
|
+
if (endNs > MAX_NS) fail("action end must be at most 60 seconds");
|
|
714
|
+
return { ...a, beginNs: a.timeNs, endNs, property: PROP[a.verb], durNs };
|
|
715
|
+
}
|
|
716
|
+
function checkDocument(doc) {
|
|
717
|
+
const stop = (d) => ({ ok: false, diagnostics: [d] });
|
|
718
|
+
if (doc.inputError) return stop(doc.inputError);
|
|
719
|
+
let scene;
|
|
720
|
+
let sawAction = false, sawContent = false;
|
|
721
|
+
const actors = [];
|
|
722
|
+
const names = /* @__PURE__ */ new Map();
|
|
723
|
+
const actions = [];
|
|
724
|
+
let parentsChecked = false;
|
|
725
|
+
try {
|
|
726
|
+
for (const s of doc.statements) {
|
|
727
|
+
const fail = (m) => {
|
|
728
|
+
throw new Stop({ line: s.line, col: s.col, message: m });
|
|
729
|
+
};
|
|
730
|
+
switch (s.kind) {
|
|
731
|
+
case "version":
|
|
732
|
+
if (sawContent || !s.ok) fail("expected initial mdgl 0.1");
|
|
733
|
+
break;
|
|
734
|
+
case "unknown":
|
|
735
|
+
fail("unsupported statement (expected mdgl, scene, actor or @)");
|
|
736
|
+
break;
|
|
737
|
+
case "scene":
|
|
738
|
+
if (scene) fail("duplicate scene");
|
|
739
|
+
sawContent = true;
|
|
740
|
+
scene = checkScene(s);
|
|
741
|
+
break;
|
|
742
|
+
case "actor":
|
|
743
|
+
sawContent = true;
|
|
744
|
+
if (!scene) fail("scene must precede actors");
|
|
745
|
+
if (sawAction) fail("actors must precede actions");
|
|
746
|
+
if (actors.length >= MAX_ACTORS) fail("actor limit 64 exceeded");
|
|
747
|
+
checkActor(s, new Set(names.keys()));
|
|
748
|
+
actors.push(s);
|
|
749
|
+
names.set(s.name, s);
|
|
750
|
+
break;
|
|
751
|
+
case "action": {
|
|
752
|
+
sawContent = true;
|
|
753
|
+
if (!scene) fail("scene must precede actions");
|
|
754
|
+
if (!parentsChecked) {
|
|
755
|
+
checkParents(actors);
|
|
756
|
+
parentsChecked = true;
|
|
757
|
+
}
|
|
758
|
+
sawAction = true;
|
|
759
|
+
if (actions.length >= MAX_ACTIONS) fail("action limit 1024 exceeded");
|
|
760
|
+
const ca = checkAction(s, names);
|
|
761
|
+
for (const p of actions) {
|
|
762
|
+
if (p.actor === ca.actor && p.property === ca.property && p.beginNs < ca.endNs && ca.beginNs < p.endNs) fail(`overlapping ${ca.property} actions on ${ca.actor}`);
|
|
763
|
+
}
|
|
764
|
+
actions.push(ca);
|
|
765
|
+
break;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
if (!parentsChecked) checkParents(actors);
|
|
770
|
+
if (doc.syntax) throw new Stop(doc.syntax);
|
|
771
|
+
if (!scene) throw new Stop({ line: 1, col: 1, message: "missing scene" });
|
|
772
|
+
const end = actions.reduce((m, a) => Math.max(m, a.endNs), 0);
|
|
773
|
+
scene.duration = scene.period ?? end;
|
|
774
|
+
if (scene.fallback.kind === "at" && scene.fallback.ns > scene.duration) throw new Stop({ line: scene.line, col: 1, message: "fallback time exceeds the simple duration" });
|
|
775
|
+
return { ok: true, doc: { scene, actors, actions } };
|
|
776
|
+
} catch (e) {
|
|
777
|
+
if (e instanceof Stop) return stop(e.d);
|
|
778
|
+
throw e;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
function parseChecked(source) {
|
|
782
|
+
return checkDocument(parse(source));
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// src/eval.ts
|
|
786
|
+
var I4 = () => [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
787
|
+
var mul = (a, b) => {
|
|
788
|
+
const o = new Array(16).fill(0);
|
|
789
|
+
for (let c = 0; c < 4; c++) for (let r = 0; r < 4; r++) for (let k = 0; k < 4; k++) o[c * 4 + r] += a[k * 4 + r] * b[c * 4 + k];
|
|
790
|
+
return o;
|
|
791
|
+
};
|
|
792
|
+
var trans = (x, y, z) => {
|
|
793
|
+
const m = I4();
|
|
794
|
+
m[12] = x;
|
|
795
|
+
m[13] = y;
|
|
796
|
+
m[14] = z;
|
|
797
|
+
return m;
|
|
798
|
+
};
|
|
799
|
+
var scaleM = (s) => {
|
|
800
|
+
const m = I4();
|
|
801
|
+
m[0] = s;
|
|
802
|
+
m[5] = s;
|
|
803
|
+
m[10] = s;
|
|
804
|
+
return m;
|
|
805
|
+
};
|
|
806
|
+
var rotM = (xd, yd, zd) => {
|
|
807
|
+
const [x, y, z] = [xd, yd, zd].map((d) => d * Math.PI / 180);
|
|
808
|
+
const [cx, sx, cy, sy, cz, sz] = [Math.cos(x), Math.sin(x), Math.cos(y), Math.sin(y), Math.cos(z), Math.sin(z)];
|
|
809
|
+
const rows = [
|
|
810
|
+
[cy * cz, -cy * sz, sy, 0],
|
|
811
|
+
[cx * sz + sx * sy * cz, cx * cz - sx * sy * sz, -sx * cy, 0],
|
|
812
|
+
[sx * sz - cx * sy * cz, sx * cz + cx * sy * sz, cx * cy, 0],
|
|
813
|
+
[0, 0, 0, 1]
|
|
814
|
+
];
|
|
815
|
+
const m = new Array(16);
|
|
816
|
+
for (let r = 0; r < 4; r++) for (let c = 0; c < 4; c++) m[c * 4 + r] = rows[r][c];
|
|
817
|
+
return m;
|
|
818
|
+
};
|
|
819
|
+
var xf = (m, v) => {
|
|
820
|
+
const o = [0, 0, 0, 0];
|
|
821
|
+
for (let r = 0; r < 4; r++) o[r] = m[r] * v[0] + m[4 + r] * v[1] + m[8 + r] * v[2] + m[12 + r];
|
|
822
|
+
return o;
|
|
823
|
+
};
|
|
824
|
+
var rnd = (v) => v < 0 ? -Math.floor(-v + 0.5) : Math.floor(v + 0.5);
|
|
825
|
+
function bezier(x1, y1, x2, y2) {
|
|
826
|
+
const cx = (s) => 3 * (1 - s) * (1 - s) * s * x1 + 3 * (1 - s) * s * s * x2 + s * s * s;
|
|
827
|
+
const cy = (s) => 3 * (1 - s) * (1 - s) * s * y1 + 3 * (1 - s) * s * s * y2 + s * s * s;
|
|
828
|
+
return (u) => {
|
|
829
|
+
if (u <= 0) return 0;
|
|
830
|
+
if (u >= 1) return 1;
|
|
831
|
+
let lo = 0, hi = 1;
|
|
832
|
+
for (let i = 0; i < 80; i++) {
|
|
833
|
+
const m = (lo + hi) / 2;
|
|
834
|
+
if (cx(m) < u) lo = m;
|
|
835
|
+
else hi = m;
|
|
836
|
+
}
|
|
837
|
+
return cy((lo + hi) / 2);
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
var bounce = (u) => {
|
|
841
|
+
const n1 = 7.5625, d1 = 2.75;
|
|
842
|
+
if (u < 1 / d1) return n1 * u * u;
|
|
843
|
+
if (u < 2 / d1) {
|
|
844
|
+
u -= 1.5 / d1;
|
|
845
|
+
return n1 * u * u + 0.75;
|
|
846
|
+
}
|
|
847
|
+
if (u < 2.5 / d1) {
|
|
848
|
+
u -= 2.25 / d1;
|
|
849
|
+
return n1 * u * u + 0.9375;
|
|
850
|
+
}
|
|
851
|
+
u -= 2.625 / d1;
|
|
852
|
+
return n1 * u * u + 0.984375;
|
|
853
|
+
};
|
|
854
|
+
var EASE = {
|
|
855
|
+
linear: (u) => u,
|
|
856
|
+
ease: bezier(0.25, 0.1, 0.25, 1),
|
|
857
|
+
"ease-in": bezier(0.42, 0, 1, 1),
|
|
858
|
+
"ease-out": bezier(0, 0, 0.58, 1),
|
|
859
|
+
"ease-in-out": bezier(0.42, 0, 0.58, 1),
|
|
860
|
+
bounce
|
|
861
|
+
};
|
|
862
|
+
var RGB = {
|
|
863
|
+
normal: [255, 255, 255],
|
|
864
|
+
white: [255, 255, 255],
|
|
865
|
+
black: [0, 0, 0],
|
|
866
|
+
red: [255, 0, 0],
|
|
867
|
+
green: [0, 255, 0],
|
|
868
|
+
yellow: [255, 255, 0],
|
|
869
|
+
blue: [0, 0, 255],
|
|
870
|
+
magenta: [255, 0, 255],
|
|
871
|
+
cyan: [0, 255, 255],
|
|
872
|
+
accent: [0, 255, 255]
|
|
873
|
+
};
|
|
874
|
+
var hex2 = (n) => n.toString(16).padStart(2, "0");
|
|
875
|
+
function blend(fg, alpha, bg) {
|
|
876
|
+
if (alpha >= 1) return fg;
|
|
877
|
+
const s = RGB[fg] ?? RGB.normal;
|
|
878
|
+
let d = [0, 0, 0];
|
|
879
|
+
if (bg !== "") {
|
|
880
|
+
if (bg[0] === "#") d = [1, 3, 5].map((i) => parseInt(bg.slice(i, i + 2), 16));
|
|
881
|
+
else d = RGB[bg] ?? [0, 0, 0];
|
|
882
|
+
}
|
|
883
|
+
return "#" + [0, 1, 2].map((i) => hex2(Math.max(0, Math.min(255, Math.floor(s[i] * alpha + d[i] * (1 - alpha) + 0.5))))).join("");
|
|
884
|
+
}
|
|
885
|
+
function sizeOf(sh) {
|
|
886
|
+
if (sh.kind === "text") {
|
|
887
|
+
const g = graphemes(sh.text);
|
|
888
|
+
return [g.length, 1, g];
|
|
889
|
+
}
|
|
890
|
+
if (sh.kind === "rect") return [sh.width, sh.height, []];
|
|
891
|
+
if (sh.kind === "circle") return [2 * sh.radius, 2 * sh.radius, []];
|
|
892
|
+
return [sh.size, sh.size, []];
|
|
893
|
+
}
|
|
894
|
+
function compileDocument(doc) {
|
|
895
|
+
const by = /* @__PURE__ */ new Map();
|
|
896
|
+
const actors = doc.actors.map((a, index) => {
|
|
897
|
+
const [w, h, clusters] = sizeOf(a.shape);
|
|
898
|
+
const act = { name: a.name, index, z: a.z ?? 0, parent: null, shape: a.shape, w, h, clusters, atPoint: a.at, anchorPoint: a.anchor, color: a.color ?? "normal", acts: [] };
|
|
899
|
+
by.set(a.name, act);
|
|
900
|
+
return act;
|
|
901
|
+
});
|
|
902
|
+
doc.actors.forEach((a, i) => {
|
|
903
|
+
if (a.parent !== void 0) actors[i].parent = by.get(a.parent);
|
|
904
|
+
});
|
|
905
|
+
const sorted = [...doc.actions].sort((p, q2) => p.beginNs - q2.beginNs);
|
|
906
|
+
for (const a of sorted) by.get(a.actor).acts.push(a);
|
|
907
|
+
const s = doc.scene;
|
|
908
|
+
const order = [...actors].sort((p, q2) => p.z - q2.z || p.index - q2.index);
|
|
909
|
+
return { width: s.width, height: s.height, fps: s.fps, durationNs: s.duration, periodNs: s.period, repeat: s.repeat, fallback: s.fallback, actors, order };
|
|
910
|
+
}
|
|
911
|
+
function compile(source) {
|
|
912
|
+
const r = parseChecked(source);
|
|
913
|
+
return r.ok ? { ok: true, scene: compileDocument(r.doc) } : { ok: false, diagnostics: r.diagnostics };
|
|
914
|
+
}
|
|
915
|
+
var arg = (a, k) => a.args.find((g) => g.key === k)?.value;
|
|
916
|
+
var has = (a, k) => a.args.some((g) => g.key === k);
|
|
917
|
+
var secs = (v) => decimalToNs(v.raw.replace(/^\+/, "").replace(/s$/, ""));
|
|
918
|
+
var num = (v) => v.value;
|
|
919
|
+
var deg = (v) => {
|
|
920
|
+
const n = v;
|
|
921
|
+
return n.suffix === "rad" ? n.value * 180 / Math.PI : n.value;
|
|
922
|
+
};
|
|
923
|
+
function coord(c, size, box, anchorNames) {
|
|
924
|
+
if (c.kind === "num") return c.percent ? c.value / 100 * (box - size) : c.value;
|
|
925
|
+
const rem = box - size;
|
|
926
|
+
const base = c.name === anchorNames[0] ? 0 : c.name === anchorNames[1] ? rem : rem / 2;
|
|
927
|
+
return base + c.offset;
|
|
928
|
+
}
|
|
929
|
+
var resolve = (p, w, h, bw, bh) => [coord(p.x, w, bw, ["left", "right"]), coord(p.y, h, bh, ["top", "bottom"])];
|
|
930
|
+
function evalActor(sc, a, T2) {
|
|
931
|
+
const box = a.parent ? [a.parent.w, a.parent.h] : [sc.width, sc.height];
|
|
932
|
+
const [x0, y0] = resolve(a.atPoint, a.w, a.h, box[0], box[1]);
|
|
933
|
+
const st = { opacity: 1, x: x0, y: y0, scale: 1, color: a.color, reveal: 1, count: null, rot: [0, 0, 0] };
|
|
934
|
+
const done = {};
|
|
935
|
+
for (const ac of a.acts) {
|
|
936
|
+
const b = ac.beginNs, e = ac.endNs, dur = ac.durNs;
|
|
937
|
+
const started = T2 >= b, over = T2 >= e;
|
|
938
|
+
const ease = EASE[arg(ac, "ease")?.value ?? "linear"];
|
|
939
|
+
const p = started && !over && dur > 0 ? ease((T2 - b) / dur) : over ? 1 : 0;
|
|
940
|
+
const prop = ac.property;
|
|
941
|
+
if (done[prop]) continue;
|
|
942
|
+
if (T2 < b && !(ac.verb === "fade" || ac.verb === "wipe" || ac.verb === "type" || ac.verb === "slide")) {
|
|
943
|
+
done[prop] = true;
|
|
944
|
+
continue;
|
|
945
|
+
}
|
|
946
|
+
switch (ac.verb) {
|
|
947
|
+
case "fade": {
|
|
948
|
+
const inn = has(ac, "in");
|
|
949
|
+
st.opacity = over ? inn ? 1 : 0 : !started ? inn ? 0 : st.opacity : inn ? p : 1 - p;
|
|
950
|
+
break;
|
|
951
|
+
}
|
|
952
|
+
case "blink": {
|
|
953
|
+
if (started && !over) {
|
|
954
|
+
const half = dur / (2 * num(arg(ac, "times")));
|
|
955
|
+
if (Math.floor((T2 - b) / half) % 2 === 1) st.opacity = 0;
|
|
956
|
+
}
|
|
957
|
+
break;
|
|
958
|
+
}
|
|
959
|
+
case "wipe": {
|
|
960
|
+
const inn = has(ac, "in");
|
|
961
|
+
st.count = null;
|
|
962
|
+
st.reveal = over ? inn ? 1 : 0 : !started ? inn ? 0 : st.reveal : inn ? p : st.reveal * (1 - p);
|
|
963
|
+
break;
|
|
964
|
+
}
|
|
965
|
+
case "type": {
|
|
966
|
+
const per = secs(arg(ac, "per_char"));
|
|
967
|
+
st.count = over ? a.clusters.length : !started ? 0 : Math.min(a.clusters.length, Math.floor((T2 - b) / per));
|
|
968
|
+
st.reveal = 1;
|
|
969
|
+
break;
|
|
970
|
+
}
|
|
971
|
+
case "move": {
|
|
972
|
+
const [tx, ty] = resolve(arg(ac, "to").value, a.w, a.h, box[0], box[1]);
|
|
973
|
+
if (over) {
|
|
974
|
+
st.x = tx;
|
|
975
|
+
st.y = ty;
|
|
976
|
+
} else {
|
|
977
|
+
st.x += (tx - st.x) * p;
|
|
978
|
+
st.y += (ty - st.y) * p;
|
|
979
|
+
}
|
|
980
|
+
break;
|
|
981
|
+
}
|
|
982
|
+
case "slide": {
|
|
983
|
+
const edge = arg(ac, "to").value;
|
|
984
|
+
const inn = has(ac, "in");
|
|
985
|
+
let ex = st.x, ey = st.y;
|
|
986
|
+
if (edge === "left") ex = -a.w;
|
|
987
|
+
else if (edge === "right") ex = box[0];
|
|
988
|
+
else if (edge === "top") ey = -a.h;
|
|
989
|
+
else ey = box[1];
|
|
990
|
+
if (inn) {
|
|
991
|
+
if (over) {
|
|
992
|
+
} else {
|
|
993
|
+
st.x = ex + (st.x - ex) * p;
|
|
994
|
+
st.y = ey + (st.y - ey) * p;
|
|
995
|
+
}
|
|
996
|
+
} else if (over) {
|
|
997
|
+
st.x = ex;
|
|
998
|
+
st.y = ey;
|
|
999
|
+
} else if (started) {
|
|
1000
|
+
st.x += (ex - st.x) * p;
|
|
1001
|
+
st.y += (ey - st.y) * p;
|
|
1002
|
+
}
|
|
1003
|
+
break;
|
|
1004
|
+
}
|
|
1005
|
+
case "scale": {
|
|
1006
|
+
const t = num(arg(ac, "to"));
|
|
1007
|
+
st.scale = over ? t : st.scale + (t - st.scale) * p;
|
|
1008
|
+
break;
|
|
1009
|
+
}
|
|
1010
|
+
case "color": {
|
|
1011
|
+
const t = arg(ac, "to").value;
|
|
1012
|
+
if (over || p >= 0.5) st.color = t;
|
|
1013
|
+
break;
|
|
1014
|
+
}
|
|
1015
|
+
case "rotate": {
|
|
1016
|
+
["x", "y", "z"].forEach((k, i) => {
|
|
1017
|
+
if (has(ac, k)) {
|
|
1018
|
+
const t = deg(arg(ac, k));
|
|
1019
|
+
st.rot[i] = over ? t : st.rot[i] + (t - st.rot[i]) * p;
|
|
1020
|
+
}
|
|
1021
|
+
});
|
|
1022
|
+
break;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
if (T2 < b) done[prop] = true;
|
|
1026
|
+
}
|
|
1027
|
+
return st;
|
|
1028
|
+
}
|
|
1029
|
+
var BIT = [[1, 8], [2, 16], [4, 32], [64, 128]];
|
|
1030
|
+
var Grid = class {
|
|
1031
|
+
constructor(w, h) {
|
|
1032
|
+
this.w = w;
|
|
1033
|
+
this.h = h;
|
|
1034
|
+
this.cells = Array.from({ length: h }, () => Array.from({ length: w }, () => ({ r: " ", fg: "normal", bg: "" })));
|
|
1035
|
+
}
|
|
1036
|
+
put(col, row, r, color2, alpha) {
|
|
1037
|
+
if (col < 0 || row < 0 || col >= this.w || row >= this.h || r === " " || alpha <= 0) return;
|
|
1038
|
+
const c = this.cells[row][col];
|
|
1039
|
+
const dest = c.r !== " " ? c.fg : c.bg;
|
|
1040
|
+
c.r = r;
|
|
1041
|
+
c.fg = alpha >= 1 ? color2 : blend(color2, alpha, dest);
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
var q9 = (v) => Math.round(v * 1e9) / 1e9;
|
|
1045
|
+
function worldMatrices(sc, T2) {
|
|
1046
|
+
const out = /* @__PURE__ */ new Map();
|
|
1047
|
+
const get = (a) => {
|
|
1048
|
+
const hit = out.get(a);
|
|
1049
|
+
if (hit) return hit;
|
|
1050
|
+
const st = evalActor(sc, a, T2);
|
|
1051
|
+
const par = a.parent ? get(a.parent) : null;
|
|
1052
|
+
let ax = a.w / 2, ay = a.h / 2;
|
|
1053
|
+
if (a.anchorPoint) {
|
|
1054
|
+
ax = coord(a.anchorPoint.x, 0, a.w, ["left", "right"]);
|
|
1055
|
+
ay = coord(a.anchorPoint.y, 0, a.h, ["top", "bottom"]);
|
|
1056
|
+
}
|
|
1057
|
+
let local = mul(trans(st.x + ax, -2 * (st.y + ay), 0), mul(rotM(st.rot[0], st.rot[1], st.rot[2]), mul(scaleM(st.scale), trans(-ax, 2 * ay, 0))));
|
|
1058
|
+
if (par) local = mul(par.m, local);
|
|
1059
|
+
const fr = st.count !== null ? a.clusters.length ? st.count / a.clusters.length : 1 : st.reveal;
|
|
1060
|
+
const r = { m: local, st, alpha: st.opacity * (par ? par.alpha : 1), frac: fr * (par ? par.frac : 1), ax, ay };
|
|
1061
|
+
out.set(a, r);
|
|
1062
|
+
return r;
|
|
1063
|
+
};
|
|
1064
|
+
for (const a of sc.actors) get(a);
|
|
1065
|
+
return out;
|
|
1066
|
+
}
|
|
1067
|
+
function toCell(m, cx, cy) {
|
|
1068
|
+
const p = xf(m, [cx, -2 * cy, 0]);
|
|
1069
|
+
return [p[0], -p[1] / 2];
|
|
1070
|
+
}
|
|
1071
|
+
var dotOf = (col, row) => [2 * col - 0.5, 4 * row - 0.5];
|
|
1072
|
+
function line(dots, W, H, a, b) {
|
|
1073
|
+
let x0 = q9(a[0]), y0 = q9(a[1]), x1 = q9(b[0]), y1 = q9(b[1]);
|
|
1074
|
+
let t0 = 0, t1 = 1;
|
|
1075
|
+
const dx0 = x1 - x0, dy0 = y1 - y0;
|
|
1076
|
+
for (const [p, qd] of [[-dx0, x0], [dx0, 2 * W - 1 - x0], [-dy0, y0], [dy0, 4 * H - 1 - y0]]) {
|
|
1077
|
+
if (p === 0) {
|
|
1078
|
+
if (qd < 0) return;
|
|
1079
|
+
continue;
|
|
1080
|
+
}
|
|
1081
|
+
const r = qd / p;
|
|
1082
|
+
if (p < 0) {
|
|
1083
|
+
if (r > t1) return;
|
|
1084
|
+
if (r > t0) t0 = r;
|
|
1085
|
+
} else {
|
|
1086
|
+
if (r < t0) return;
|
|
1087
|
+
if (r < t1) t1 = r;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
[x0, y0, x1, y1] = [x0 + dx0 * t0, y0 + dy0 * t0, x0 + dx0 * t1, y0 + dy0 * t1];
|
|
1091
|
+
const n = Math.min(800, Math.max(1, Math.ceil(Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0)))));
|
|
1092
|
+
for (let i = 0; i <= n; i++) {
|
|
1093
|
+
const t = i / n;
|
|
1094
|
+
const dx = Math.round(x0 + (x1 - x0) * t), dy = Math.round(y0 + (y1 - y0) * t);
|
|
1095
|
+
if (dx >= 0 && dy >= 0 && dx < W * 2 && dy < H * 4) dots.add(dy * W * 2 + dx);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
function paintDots(g, dots, color2, alpha) {
|
|
1099
|
+
const bits = /* @__PURE__ */ new Map();
|
|
1100
|
+
for (const d of dots) {
|
|
1101
|
+
const dy = Math.floor(d / (g.w * 2)), dx = d % (g.w * 2);
|
|
1102
|
+
const key = Math.floor(dy / 4) * g.w + Math.floor(dx / 2);
|
|
1103
|
+
bits.set(key, (bits.get(key) ?? 0) | BIT[dy % 4][dx % 2]);
|
|
1104
|
+
}
|
|
1105
|
+
for (const [key, b] of bits) g.put(key % g.w, Math.floor(key / g.w), String.fromCodePoint(10240 + b), color2, alpha);
|
|
1106
|
+
}
|
|
1107
|
+
function clipLine(p0, p1) {
|
|
1108
|
+
let t0 = 0, t1 = 1;
|
|
1109
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
1110
|
+
for (const sgn of [1, -1]) {
|
|
1111
|
+
const d0 = p0[3] - sgn * p0[axis], d1 = p1[3] - sgn * p1[axis];
|
|
1112
|
+
if (d0 < 0 && d1 < 0) return null;
|
|
1113
|
+
if (d0 < 0) t0 = Math.max(t0, d0 / (d0 - d1));
|
|
1114
|
+
else if (d1 < 0) t1 = Math.min(t1, d0 / (d0 - d1));
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
if (t0 > t1) return null;
|
|
1118
|
+
const at = (t) => p0.map((v, i) => v + (p1[i] - v) * t);
|
|
1119
|
+
return [at(t0), at(t1)];
|
|
1120
|
+
}
|
|
1121
|
+
function renderActor(sc, g, a, w) {
|
|
1122
|
+
const color2 = w.st.color, alpha = w.alpha;
|
|
1123
|
+
if (alpha <= 0 || w.frac <= 0 && a.shape.kind !== "text") return;
|
|
1124
|
+
const sh = a.shape;
|
|
1125
|
+
if (sh.kind === "text") {
|
|
1126
|
+
const n = a.clusters.length;
|
|
1127
|
+
const shown = w.st.count !== null ? Math.min(w.st.count, Math.floor(w.frac * n + 1e-9) === n ? n : Math.floor(w.frac * n + 1e-9)) : Math.floor(w.frac * n + 1e-9);
|
|
1128
|
+
const cnt = w.st.count !== null && w.frac >= 1 ? w.st.count : shown;
|
|
1129
|
+
for (let i = 0; i < Math.min(cnt, n); i++) {
|
|
1130
|
+
const [c, r] = toCell(w.m, i, 0);
|
|
1131
|
+
g.put(rnd(c), rnd(r), cellRune(a.clusters[i]), color2, alpha);
|
|
1132
|
+
}
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
const dots = /* @__PURE__ */ new Set();
|
|
1136
|
+
const cellToDot = (cx, cy) => {
|
|
1137
|
+
const [c, r] = toCell(w.m, cx, cy);
|
|
1138
|
+
return dotOf(c, r);
|
|
1139
|
+
};
|
|
1140
|
+
const dotThrough = (dx, dy) => cellToDot((dx + 0.5) / 2, (dy + 0.5) / 4);
|
|
1141
|
+
const clipX = w.frac < 1 ? w.frac * 2 * a.w : Infinity;
|
|
1142
|
+
if (sh.kind === "rect") {
|
|
1143
|
+
const W = 2 * sh.width - 1, H = 4 * sh.height - 1;
|
|
1144
|
+
const corners = [[0, 0], [W, 0], [W, H], [0, H]];
|
|
1145
|
+
for (let i = 0; i < 4; i++) line(dots, g.w, g.h, dotThrough(...corners[i]), dotThrough(...corners[(i + 1) % 4]));
|
|
1146
|
+
} else if (sh.kind === "circle") {
|
|
1147
|
+
const rx = 2 * sh.radius - 0.5, ry = 4 * sh.radius - 0.5;
|
|
1148
|
+
let prev = dotThrough(2 * rx, ry);
|
|
1149
|
+
for (let k = 1; k <= 720; k++) {
|
|
1150
|
+
const t = k * Math.PI / 360;
|
|
1151
|
+
const lx = rx + rx * Math.cos(t), ly = ry + ry * Math.sin(t);
|
|
1152
|
+
const cur = dotThrough(lx, ly);
|
|
1153
|
+
if (lx <= clipX) line(dots, g.w, g.h, prev, cur);
|
|
1154
|
+
prev = cur;
|
|
1155
|
+
}
|
|
1156
|
+
} else {
|
|
1157
|
+
cubeDots(dots, g, a, sh.size, w.m);
|
|
1158
|
+
}
|
|
1159
|
+
paintDots(g, dots, color2, alpha);
|
|
1160
|
+
if (sh.kind === "rect" && sh.title) {
|
|
1161
|
+
const t = graphemes(sh.title);
|
|
1162
|
+
for (let i = 0; i < Math.min(t.length, sh.width - 2); i++) {
|
|
1163
|
+
const [c, r] = toCell(w.m, 1 + i, 0);
|
|
1164
|
+
g.put(rnd(c), rnd(r), cellRune(t[i]), color2, alpha);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
function cubeDots(dots, g, a, size, M) {
|
|
1169
|
+
const n = size;
|
|
1170
|
+
const verts = [];
|
|
1171
|
+
for (const dx of [0, 1]) for (const dy of [0, 1]) for (const dz of [0, 1]) verts.push([n / 2 + (dx ? n / 2 : -n / 2), -n + (dy ? n / 2 : -n / 2), dz ? n / 2 : -n / 2]);
|
|
1172
|
+
const centre = xf(M, [n / 2, -n, 0]);
|
|
1173
|
+
const tm = trans(-centre[0], -centre[1], -(centre[2] + 3 * n));
|
|
1174
|
+
const fov = 50 * Math.PI / 180, qq = 1 / Math.tan(fov / 2), asp = n / (2 * n), near = 0.1, far = 1e3;
|
|
1175
|
+
const P = [qq / asp, 0, 0, 0, 0, qq, 0, 0, 0, 0, -(far + near) / (far - near), -1, 0, 0, -2 * far * near / (far - near), 0];
|
|
1176
|
+
const PV = mul(P, tm);
|
|
1177
|
+
const clip = verts.map((v) => xf(PV, xf(M, v).slice(0, 3)));
|
|
1178
|
+
const [ccol, crow] = (() => {
|
|
1179
|
+
const p = centre;
|
|
1180
|
+
return [p[0], -p[1] / 2];
|
|
1181
|
+
})();
|
|
1182
|
+
const left = ccol - n / 2, top = crow - n / 2;
|
|
1183
|
+
const edges = [];
|
|
1184
|
+
for (let i = 0; i < 8; i++) for (const bit of [1, 2, 4]) if (!(i & bit)) edges.push([i, i | bit]);
|
|
1185
|
+
for (const [i, j] of edges) {
|
|
1186
|
+
const c = clipLine(clip[i], clip[j]);
|
|
1187
|
+
if (!c) continue;
|
|
1188
|
+
const pr = c.map((p) => {
|
|
1189
|
+
const ndcX = p[0] / p[3], ndcY = p[1] / p[3];
|
|
1190
|
+
const col = left + (ndcX + 1) * n / 2, row = top + (1 - ndcY) * n / 2;
|
|
1191
|
+
return dotOf(col, row);
|
|
1192
|
+
});
|
|
1193
|
+
line(dots, g.w, g.h, pr[0], pr[1]);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
function compose(sc, T2, W, H) {
|
|
1197
|
+
const g = new Grid(Math.min(W, sc.width), Math.min(H, sc.height));
|
|
1198
|
+
const full = new Grid(sc.width, sc.height);
|
|
1199
|
+
const wm = worldMatrices(sc, T2);
|
|
1200
|
+
for (const a of sc.order) renderActor(sc, full, a, wm.get(a));
|
|
1201
|
+
for (let r = 0; r < g.h; r++) for (let c = 0; c < g.w; c++) g.cells[r][c] = full.cells[r][c];
|
|
1202
|
+
return g;
|
|
1203
|
+
}
|
|
1204
|
+
function frameNs(sc, tNs, width = sc.width, height = sc.height) {
|
|
1205
|
+
const D = sc.durationNs;
|
|
1206
|
+
let local = tNs, done = D === 0;
|
|
1207
|
+
if (D > 0) {
|
|
1208
|
+
const total = sc.repeat === Infinity ? Infinity : D * sc.repeat;
|
|
1209
|
+
if (tNs >= total) {
|
|
1210
|
+
local = D;
|
|
1211
|
+
done = true;
|
|
1212
|
+
} else {
|
|
1213
|
+
local = tNs % D;
|
|
1214
|
+
}
|
|
1215
|
+
} else local = 0;
|
|
1216
|
+
const g = compose(sc, local, width, height);
|
|
1217
|
+
return { width: g.w, height: g.h, cells: g.cells, done };
|
|
1218
|
+
}
|
|
1219
|
+
function fallbackFrame(sc, width = sc.width, height = sc.height) {
|
|
1220
|
+
const f = sc.fallback;
|
|
1221
|
+
const T2 = f.kind === "start" ? 0 : f.kind === "end" ? Infinity : f.ns;
|
|
1222
|
+
const g = compose(sc, T2, width, height);
|
|
1223
|
+
return { width: g.w, height: g.h, cells: g.cells };
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
// src/dom.ts
|
|
1227
|
+
var MDGL_COLORS = ["normal", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "accent"];
|
|
1228
|
+
var owners = /* @__PURE__ */ new WeakMap();
|
|
1229
|
+
function color(value, background = false) {
|
|
1230
|
+
if (/^#[0-9a-f]{6}$/i.test(value)) return value;
|
|
1231
|
+
if (MDGL_COLORS.includes(value)) return `var(--mdgl-${value})`;
|
|
1232
|
+
return background ? "transparent" : "var(--mdgl-normal)";
|
|
1233
|
+
}
|
|
1234
|
+
function paint(pre, frame) {
|
|
1235
|
+
const doc = pre.ownerDocument;
|
|
1236
|
+
const fragment = doc.createDocumentFragment();
|
|
1237
|
+
frame.cells.forEach((row, y) => {
|
|
1238
|
+
let x = 0;
|
|
1239
|
+
while (x < row.length) {
|
|
1240
|
+
const first2 = row[x];
|
|
1241
|
+
let text = first2.r;
|
|
1242
|
+
let end = x + 1;
|
|
1243
|
+
while (end < row.length && row[end].fg === first2.fg && row[end].bg === first2.bg) text += row[end++].r;
|
|
1244
|
+
const span = doc.createElement("span");
|
|
1245
|
+
span.textContent = text;
|
|
1246
|
+
span.dataset.mdglFg = first2.fg;
|
|
1247
|
+
span.dataset.mdglBg = first2.bg;
|
|
1248
|
+
span.style.color = color(first2.fg);
|
|
1249
|
+
span.style.backgroundColor = color(first2.bg, true);
|
|
1250
|
+
fragment.appendChild(span);
|
|
1251
|
+
x = end;
|
|
1252
|
+
}
|
|
1253
|
+
if (y + 1 < frame.height) fragment.appendChild(doc.createTextNode("\n"));
|
|
1254
|
+
});
|
|
1255
|
+
pre.replaceChildren(fragment);
|
|
1256
|
+
}
|
|
1257
|
+
function cap(value, fallback, ceiling, name) {
|
|
1258
|
+
if (value === void 0) return fallback;
|
|
1259
|
+
if (!Number.isFinite(value) || value < 1) throw new Error(`${name} must be a finite number >= 1`);
|
|
1260
|
+
return Math.min(Math.floor(value), ceiling);
|
|
1261
|
+
}
|
|
1262
|
+
function renderToElement(el, source, opts = {}) {
|
|
1263
|
+
owners.get(el)?.stop();
|
|
1264
|
+
const doc = el.ownerDocument;
|
|
1265
|
+
const win = doc.defaultView;
|
|
1266
|
+
const pre = doc.createElement("pre");
|
|
1267
|
+
pre.className = "mdgl-frame";
|
|
1268
|
+
pre.setAttribute("aria-live", "off");
|
|
1269
|
+
el.replaceChildren(pre);
|
|
1270
|
+
let error = null;
|
|
1271
|
+
let stopped = false, paused = opts.autoplay === false, finished = false, started = false;
|
|
1272
|
+
let request = null;
|
|
1273
|
+
let media;
|
|
1274
|
+
let reduced = opts.reducedMotion === true;
|
|
1275
|
+
let elapsed = 0, origin = 0, lastPaint = -Infinity;
|
|
1276
|
+
let resume = () => {
|
|
1277
|
+
};
|
|
1278
|
+
let mediaChange = () => {
|
|
1279
|
+
};
|
|
1280
|
+
const now = () => win?.performance.now() ?? 0;
|
|
1281
|
+
const cancel = () => {
|
|
1282
|
+
if (request !== null) win?.cancelAnimationFrame(request);
|
|
1283
|
+
request = null;
|
|
1284
|
+
};
|
|
1285
|
+
const stop = () => {
|
|
1286
|
+
stopped = true;
|
|
1287
|
+
cancel();
|
|
1288
|
+
media?.removeEventListener("change", mediaChange);
|
|
1289
|
+
if (owners.get(el) === handle) owners.delete(el);
|
|
1290
|
+
};
|
|
1291
|
+
const handle = {
|
|
1292
|
+
stop,
|
|
1293
|
+
pause() {
|
|
1294
|
+
if (stopped || paused) return;
|
|
1295
|
+
if (!reduced && !finished) elapsed = Math.max(elapsed, now() - origin);
|
|
1296
|
+
paused = true;
|
|
1297
|
+
cancel();
|
|
1298
|
+
},
|
|
1299
|
+
play() {
|
|
1300
|
+
if (stopped || !paused) return;
|
|
1301
|
+
paused = false;
|
|
1302
|
+
try {
|
|
1303
|
+
resume();
|
|
1304
|
+
} catch (e) {
|
|
1305
|
+
fail(e instanceof Error ? e.message : String(e));
|
|
1306
|
+
}
|
|
1307
|
+
},
|
|
1308
|
+
destroy() {
|
|
1309
|
+
stop();
|
|
1310
|
+
pre.remove();
|
|
1311
|
+
},
|
|
1312
|
+
get error() {
|
|
1313
|
+
return error;
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
owners.set(el, handle);
|
|
1317
|
+
const fail = (message) => {
|
|
1318
|
+
error = message;
|
|
1319
|
+
stop();
|
|
1320
|
+
pre.classList.add("mdgl-error");
|
|
1321
|
+
pre.textContent = `${source}
|
|
1322
|
+
|
|
1323
|
+
MDGL: ${message}`;
|
|
1324
|
+
try {
|
|
1325
|
+
opts.onError?.(message);
|
|
1326
|
+
} catch {
|
|
1327
|
+
}
|
|
1328
|
+
};
|
|
1329
|
+
try {
|
|
1330
|
+
const maxCells = cap(opts.maxCells, 12e3, 12e3, "maxCells");
|
|
1331
|
+
const maxFps = cap(opts.maxFps, 30, 60, "maxFps");
|
|
1332
|
+
const result = compile(source);
|
|
1333
|
+
if (!result.ok) {
|
|
1334
|
+
fail(result.diagnostics.map((d) => `${d.line}:${d.col}: ${d.message}`).join("\n"));
|
|
1335
|
+
return handle;
|
|
1336
|
+
}
|
|
1337
|
+
const scene = result.scene;
|
|
1338
|
+
if (scene.width * scene.height > maxCells) {
|
|
1339
|
+
fail(`stage has ${scene.width * scene.height} cells; maxCells is ${maxCells}`);
|
|
1340
|
+
return handle;
|
|
1341
|
+
}
|
|
1342
|
+
for (const name of MDGL_COLORS) {
|
|
1343
|
+
const value = opts.palette?.[name];
|
|
1344
|
+
if (value !== void 0) pre.style.setProperty(`--mdgl-${name}`, value);
|
|
1345
|
+
}
|
|
1346
|
+
if (opts.reducedMotion === void 0 && win?.matchMedia) {
|
|
1347
|
+
media = win.matchMedia("(prefers-reduced-motion: reduce)");
|
|
1348
|
+
reduced = media.matches;
|
|
1349
|
+
}
|
|
1350
|
+
reduced || (reduced = !win?.requestAnimationFrame);
|
|
1351
|
+
const interval = 1e3 / Math.min(scene.fps, maxFps);
|
|
1352
|
+
const draw = (time) => {
|
|
1353
|
+
const frame = frameNs(scene, Math.min(Number.MAX_SAFE_INTEGER, Math.floor(time * 1e6)));
|
|
1354
|
+
paint(pre, frame);
|
|
1355
|
+
finished = frame.done === true;
|
|
1356
|
+
lastPaint = time;
|
|
1357
|
+
started = true;
|
|
1358
|
+
};
|
|
1359
|
+
const tick = () => {
|
|
1360
|
+
request = null;
|
|
1361
|
+
if (stopped || paused || reduced || finished) return;
|
|
1362
|
+
try {
|
|
1363
|
+
elapsed = Math.max(elapsed, now() - origin);
|
|
1364
|
+
if (elapsed - lastPaint + 1e-7 >= interval) draw(elapsed);
|
|
1365
|
+
if (!finished) request = win.requestAnimationFrame(tick);
|
|
1366
|
+
} catch (e) {
|
|
1367
|
+
fail(e instanceof Error ? e.message : String(e));
|
|
1368
|
+
}
|
|
1369
|
+
};
|
|
1370
|
+
resume = () => {
|
|
1371
|
+
if (stopped || reduced || paused || finished) return;
|
|
1372
|
+
if (!started) draw(elapsed);
|
|
1373
|
+
if (finished) return;
|
|
1374
|
+
origin = now() - elapsed;
|
|
1375
|
+
if (request === null) request = win.requestAnimationFrame(tick);
|
|
1376
|
+
};
|
|
1377
|
+
mediaChange = () => {
|
|
1378
|
+
if (stopped) return;
|
|
1379
|
+
try {
|
|
1380
|
+
const next = media.matches;
|
|
1381
|
+
if (next === reduced) return;
|
|
1382
|
+
if (!paused && !finished && !reduced) elapsed = Math.max(elapsed, now() - origin);
|
|
1383
|
+
reduced = next;
|
|
1384
|
+
cancel();
|
|
1385
|
+
if (reduced) paint(pre, fallbackFrame(scene));
|
|
1386
|
+
else if (started || !paused) {
|
|
1387
|
+
draw(elapsed);
|
|
1388
|
+
resume();
|
|
1389
|
+
}
|
|
1390
|
+
} catch (e) {
|
|
1391
|
+
fail(e instanceof Error ? e.message : String(e));
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
1394
|
+
media?.addEventListener("change", mediaChange);
|
|
1395
|
+
if (reduced || paused) paint(pre, fallbackFrame(scene));
|
|
1396
|
+
else {
|
|
1397
|
+
draw(0);
|
|
1398
|
+
resume();
|
|
1399
|
+
}
|
|
1400
|
+
} catch (e) {
|
|
1401
|
+
fail(e instanceof Error ? e.message : String(e));
|
|
1402
|
+
}
|
|
1403
|
+
return handle;
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
// src/player.ts
|
|
1407
|
+
function registerMDGLPlayer() {
|
|
1408
|
+
if (typeof customElements === "undefined" || typeof HTMLElement === "undefined") return;
|
|
1409
|
+
if (customElements.get("mdgl-player")) return;
|
|
1410
|
+
class MDGLPlayer extends HTMLElement {
|
|
1411
|
+
constructor() {
|
|
1412
|
+
super(...arguments);
|
|
1413
|
+
this.revision = 0;
|
|
1414
|
+
this.queued = false;
|
|
1415
|
+
}
|
|
1416
|
+
static get observedAttributes() {
|
|
1417
|
+
return ["src", "reduced-motion", "max-cells", "max-fps"];
|
|
1418
|
+
}
|
|
1419
|
+
/** Use this property for programmatic inline-source updates after connection. */
|
|
1420
|
+
get source() {
|
|
1421
|
+
return this.inline ?? this.textContent ?? "";
|
|
1422
|
+
}
|
|
1423
|
+
set source(value) {
|
|
1424
|
+
this.inline = value;
|
|
1425
|
+
this.schedule();
|
|
1426
|
+
}
|
|
1427
|
+
connectedCallback() {
|
|
1428
|
+
this.schedule();
|
|
1429
|
+
}
|
|
1430
|
+
disconnectedCallback() {
|
|
1431
|
+
this.revision++;
|
|
1432
|
+
this.pending?.abort();
|
|
1433
|
+
this.playback?.stop();
|
|
1434
|
+
}
|
|
1435
|
+
attributeChangedCallback() {
|
|
1436
|
+
this.schedule();
|
|
1437
|
+
}
|
|
1438
|
+
schedule() {
|
|
1439
|
+
this.revision++;
|
|
1440
|
+
this.pending?.abort();
|
|
1441
|
+
this.playback?.stop();
|
|
1442
|
+
if (this.queued) return;
|
|
1443
|
+
this.queued = true;
|
|
1444
|
+
queueMicrotask(() => {
|
|
1445
|
+
this.queued = false;
|
|
1446
|
+
if (this.isConnected) void this.load();
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1449
|
+
async load() {
|
|
1450
|
+
if (this.inline === void 0) this.inline = this.textContent ?? "";
|
|
1451
|
+
const revision = this.revision;
|
|
1452
|
+
const src = this.getAttribute("src");
|
|
1453
|
+
let source = this.inline;
|
|
1454
|
+
try {
|
|
1455
|
+
if (src !== null) {
|
|
1456
|
+
const url = new URL(src, this.ownerDocument.baseURI);
|
|
1457
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") throw new Error("src must use HTTP or HTTPS");
|
|
1458
|
+
this.pending = new AbortController();
|
|
1459
|
+
const response = await fetch(url.href, { signal: this.pending.signal });
|
|
1460
|
+
if (!response.ok) throw new Error(`src request failed (${response.status})`);
|
|
1461
|
+
source = await response.text();
|
|
1462
|
+
}
|
|
1463
|
+
if (revision !== this.revision || !this.isConnected) return;
|
|
1464
|
+
this.playback = renderToElement(this, source, {
|
|
1465
|
+
reducedMotion: this.hasAttribute("reduced-motion") ? this.getAttribute("reduced-motion") !== "false" : void 0,
|
|
1466
|
+
maxCells: this.hasAttribute("max-cells") ? Number(this.getAttribute("max-cells")) : void 0,
|
|
1467
|
+
maxFps: this.hasAttribute("max-fps") ? Number(this.getAttribute("max-fps")) : void 0
|
|
1468
|
+
});
|
|
1469
|
+
} catch (e) {
|
|
1470
|
+
if (revision !== this.revision || !this.isConnected) return;
|
|
1471
|
+
const pre = this.ownerDocument.createElement("pre");
|
|
1472
|
+
pre.className = "mdgl-frame mdgl-error";
|
|
1473
|
+
pre.textContent = `${this.inline}
|
|
1474
|
+
|
|
1475
|
+
MDGL: ${e instanceof Error ? e.message : String(e)}`;
|
|
1476
|
+
this.replaceChildren(pre);
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
customElements.define("mdgl-player", MDGLPlayer);
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
// src/browser.ts
|
|
1484
|
+
registerMDGLPlayer();
|
|
1485
|
+
export {
|
|
1486
|
+
MDGL_COLORS,
|
|
1487
|
+
registerMDGLPlayer,
|
|
1488
|
+
renderToElement
|
|
1489
|
+
};
|