1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', { value: true });
|
4 |
|
5 | var xbrief = require('xbrief');
|
6 | var veho = require('veho');
|
7 | var crostab = require('crostab');
|
8 | var borel = require('borel');
|
9 | var hatsuMatrix = require('hatsu-matrix');
|
10 |
|
11 | function _defineProperty(obj, key, value) {
|
12 | if (key in obj) {
|
13 | Object.defineProperty(obj, key, {
|
14 | value: value,
|
15 | enumerable: true,
|
16 | configurable: true,
|
17 | writable: true
|
18 | });
|
19 | } else {
|
20 | obj[key] = value;
|
21 | }
|
22 |
|
23 | return obj;
|
24 | }
|
25 |
|
26 | const _d_2 = '2-digit',
|
27 | _num = 'numeric';
|
28 | const confDate = {
|
29 | year: _d_2,
|
30 | month: _d_2,
|
31 | day: _d_2
|
32 | },
|
33 | confTime = {
|
34 | hour: _num,
|
35 | minute: _num,
|
36 | second: _num,
|
37 | hour12: false
|
38 | };
|
39 | class Fm {}
|
40 |
|
41 | _defineProperty(Fm, "Day", new Intl.DateTimeFormat(undefined, confDate));
|
42 |
|
43 | _defineProperty(Fm, "Time", new Intl.DateTimeFormat(undefined, confTime));
|
44 |
|
45 | _defineProperty(Fm, "DayTime", new Intl.DateTimeFormat(undefined, { ...confDate,
|
46 | ...confTime
|
47 | }));
|
48 |
|
49 | const padMilli = ms => {
|
50 | ms = '' + ms;
|
51 | return ms.length > 2 ? ms : ('00' + ms).slice(-3);
|
52 | };
|
53 |
|
54 | const {
|
55 | Time
|
56 | } = Fm;
|
57 | const format = Time.format.bind(Time);
|
58 | class ETA {
|
59 | constructor() {
|
60 | this.t = new Date();
|
61 | }
|
62 |
|
63 | ini(msg = '') {
|
64 | return `[${format(this.t)}] [Ini 0ms] ${msg}`;
|
65 | }
|
66 |
|
67 | split() {
|
68 | const cur = new Date(),
|
69 | df = cur - this.t;
|
70 | this.t = cur;
|
71 | return df;
|
72 | }
|
73 |
|
74 | lap(msg = '') {
|
75 | return `[${format(this.t)}] [Lap ${this.split()}ms] ${msg}`;
|
76 | }
|
77 |
|
78 | end(msg = '') {
|
79 | return `[${format(this.t)}] [End ${this.split()}ms] ${msg}`;
|
80 | }
|
81 |
|
82 | }
|
83 |
|
84 |
|
85 |
|
86 | class GP {
|
87 | |
88 |
|
89 |
|
90 |
|
91 |
|
92 | static roughly(date = new Date()) {
|
93 | return Fm.Time.format(date);
|
94 | }
|
95 | |
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 | static time(date = new Date()) {
|
103 | return `${Fm.Time.format(date)}.${padMilli(date.getMilliseconds())}`;
|
104 | }
|
105 |
|
106 | static vec(date = new Date()) {
|
107 | return [date.getFullYear(), date.getMonth() + 1, date.getDate()];
|
108 | }
|
109 |
|
110 | static y4md(date = new Date(), de = '-') {
|
111 | return [String(date.getFullYear()).padStart(4, '0'), String(date.getMonth() + 1).padStart(2, '0'),
|
112 | String(date.getDate()).padStart(2, '0')].join(de);
|
113 | }
|
114 |
|
115 | static mdy(date = new Date()) {
|
116 | return Fm.Day.format(date);
|
117 | }
|
118 |
|
119 | static dateTime(date = new Date()) {
|
120 | return Fm.DayTime.format(date);
|
121 | }
|
122 | |
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 | static roughlyNow() {
|
130 | return Fm.Time.format(new Date());
|
131 | }
|
132 | |
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 | static now() {
|
140 | let d = new Date();
|
141 | return `${Fm.Time.format(d)}.${padMilli(d.getMilliseconds())}`;
|
142 | }
|
143 | |
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 | static year() {
|
150 | return new Date().getFullYear();
|
151 | }
|
152 | |
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 | static todayVec() {
|
159 | const td = new Date();
|
160 |
|
161 | return [td.getFullYear(), td.getMonth() + 1, td.getDate()];
|
162 | }
|
163 | |
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 | static today(de = '-') {
|
171 | const td = new Date();
|
172 | return [String(td.getFullYear()).padStart(4, '0'), String(td.getMonth() + 1).padStart(2, '0'),
|
173 | String(td.getDate()).padStart(2, '0')].join(de);
|
174 | }
|
175 | |
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 |
|
182 | static todayMDY() {
|
183 | return Fm.Day.format(new Date());
|
184 | }
|
185 | |
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 | static present() {
|
193 | return Fm.DayTime.format(new Date());
|
194 | }
|
195 |
|
196 | }
|
197 |
|
198 | const _reh = (r, func, params) => {
|
199 | for (--r; r > 0; r--) func.apply(null, params);
|
200 |
|
201 | return func.apply(null, params);
|
202 | };
|
203 |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 | class Chrono {
|
209 | |
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 | static rehearsalRest(repeat, func, ...params) {
|
217 | for (--repeat; repeat > 0; repeat--) func.call(null, ...params);
|
218 |
|
219 | return func.call(null, ...params);
|
220 | }
|
221 | |
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 |
|
228 |
|
229 |
|
230 | static rehearsalArgs(repeat, func, params) {
|
231 | for (--repeat; repeat > 0; repeat--) func.call(null, params);
|
232 |
|
233 | return func.call(null, params);
|
234 | }
|
235 | |
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 | static crossByRepeatsAndFuncs({
|
246 | repeatList,
|
247 | funcList,
|
248 | params = []
|
249 | }) {
|
250 | const eta = new ETA();
|
251 | const [side, banner] = [repeatList, Object.keys(funcList)];
|
252 | const [ht, wd] = [side.length, banner.length];
|
253 | const [lapseX, valueRow] = [veho.Mx.ini(ht, wd, (i, j) => 0), veho.Ar.ini(wd, () => null)];
|
254 | eta.ini();
|
255 |
|
256 | for (let [x, repeat] of Object.entries(repeatList)) {
|
257 | var _ref, _Object$keys;
|
258 |
|
259 | _ref = `[${GP.now()}] [${x}] (${repeat}): repeat for each of [${(_Object$keys = Object.keys(funcList), xbrief.ArrX.hBrief(_Object$keys))}]`, console.log(_ref);
|
260 | eta.split();
|
261 |
|
262 | for (let [y, func] of Object.values(funcList).entries()) {
|
263 | valueRow[y] = _reh(repeat, func, params);
|
264 | lapseX[x][y] = eta.split();
|
265 | }
|
266 | }
|
267 |
|
268 | return new crostab.CrosTab(side, banner, lapseX, 'repeat #').unshiftRow('result', valueRow);
|
269 | }
|
270 | |
271 |
|
272 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 | static strategies({
|
282 | repeat,
|
283 | paramsList,
|
284 | funcList,
|
285 | config = {
|
286 | showAverage: true,
|
287 | showParamsValues: false
|
288 | }
|
289 | }) {
|
290 | var _lapse$columns$map$ma;
|
291 |
|
292 | const eta = new ETA(),
|
293 | [side, banner] = [Object.keys(paramsList), Object.keys(funcList)],
|
294 | [ht, wd] = [side.length, banner.length],
|
295 | [lapseX, valueX] = [veho.Mx.ini(ht, wd, (i, j) => 0), veho.Mx.ini(ht, wd, (i, j) => null)];
|
296 | eta.ini();
|
297 |
|
298 | for (let [x, [label, params]] of Object.entries(paramsList).entries()) {
|
299 | var _ref2;
|
300 |
|
301 | _ref2 = `[${GP.now()}] [${x}] (${label}) tested by each of funcs [${banner}], each repeated * ${repeat}.`, console.log(_ref2);
|
302 | eta.split();
|
303 |
|
304 | for (let [y, func] of Object.values(funcList).entries()) {
|
305 | valueX[x][y] = _reh(repeat, func, params);
|
306 | lapseX[x][y] = eta.split();
|
307 | }
|
308 | }
|
309 |
|
310 | let [lapse, result] = [crostab.CrosTab.from({
|
311 | side,
|
312 | banner,
|
313 | matrix: lapseX,
|
314 | title: 'parameter'
|
315 | }).clone(), crostab.CrosTab.from({
|
316 | side,
|
317 | banner,
|
318 | matrix: valueX,
|
319 | title: 'parameter'
|
320 | }).clone()];
|
321 | if (config.showAverage) lapse.unshiftRow('avg', (_lapse$columns$map$ma = lapse.columns.map(borel.Stat.avg).map(it => it.toFixed()), hatsuMatrix.Visual.vector(_lapse$columns$map$ma)));
|
322 | if (config.showParamsValues) result.unshiftCol('input', Object.values(paramsList));
|
323 | return {
|
324 | lapse,
|
325 | result
|
326 | };
|
327 | }
|
328 |
|
329 | }
|
330 |
|
331 | class Dawdle {
|
332 | static linger(ms, fn, ...args) {
|
333 | return new Promise((pass, veto) => {
|
334 | let st = false,
|
335 | rs;
|
336 | Promise.resolve(fn.apply(null, args)).then(x => st++ ? pass(x) : rs = x, veto);
|
337 | Promise.resolve(Dawdle.timeout(ms)).then(_ => {
|
338 | if (st++) pass(rs);
|
339 | }, veto);
|
340 | });
|
341 | }
|
342 |
|
343 | static timeout(ms) {
|
344 | return new Promise(pass => setTimeout(pass, ms));
|
345 | }
|
346 |
|
347 | }
|
348 |
|
349 | const monthCap = (m, lp) => m !== 0b10 ? 30 + m % 0b10 ^ m >= 0x8 : 28 + lp;
|
350 |
|
351 | const leapYear = y => y % 4 ? false : y % 100 ? true : !(y % 400);
|
352 |
|
353 | const nextMonth = dt => {
|
354 | dt.m += 1;
|
355 |
|
356 | if (dt.m > 12) {
|
357 | dt.y += 1;
|
358 | dt.m = 1;
|
359 | dt.lp = leapYear(dt.y);
|
360 | }
|
361 |
|
362 | dt.cap = monthCap(dt.m, dt.lp);
|
363 | return dt;
|
364 | };
|
365 | const prevMonth = dt => {
|
366 | dt.m -= 1;
|
367 |
|
368 | if (dt.m < 1) {
|
369 | dt.y -= 1;
|
370 | dt.m = 12;
|
371 | dt.lp = leapYear(dt.y);
|
372 | }
|
373 |
|
374 | dt.cap = monthCap(dt.m, dt.lp);
|
375 | return dt;
|
376 | };
|
377 | const yearForth = dt => {
|
378 | let {
|
379 | y,
|
380 | m,
|
381 | d
|
382 | } = dt;
|
383 |
|
384 | while (d >= 365) {
|
385 | d -= 365;
|
386 | if (m <= 2 && leapYear(y++) || m > 2 && leapYear(++y)) d--;
|
387 | }
|
388 |
|
389 | const lp = leapYear(y);
|
390 | return {
|
391 | y,
|
392 | m,
|
393 | d,
|
394 | lp,
|
395 | cap: monthCap(m, lp)
|
396 | };
|
397 | };
|
398 | const yearBack = dt => {
|
399 | let {
|
400 | y,
|
401 | m,
|
402 | d
|
403 | } = dt;
|
404 |
|
405 | while (d <= -365) {
|
406 | d += 365;
|
407 | if (m <= 2 && leapYear(--y) || m > 2 && leapYear(y--)) d++;
|
408 | }
|
409 |
|
410 | const lp = leapYear(y);
|
411 | return {
|
412 | y,
|
413 | m,
|
414 | d,
|
415 | lp,
|
416 | cap: monthCap(m, lp)
|
417 | };
|
418 | };
|
419 | const daysForth = dt => {
|
420 | while (dt.d > dt.cap) {
|
421 | var _dt;
|
422 |
|
423 | dt.d -= dt.cap;
|
424 | _dt = dt, nextMonth(_dt);
|
425 | }
|
426 |
|
427 | return dt;
|
428 | };
|
429 | const daysBack = dt => {
|
430 | dt.cap = 0;
|
431 |
|
432 | while (dt.d < dt.cap) {
|
433 | var _dt2;
|
434 |
|
435 | _dt2 = dt, prevMonth(_dt2);
|
436 | dt.d += dt.cap;
|
437 | }
|
438 |
|
439 | return daysForth(dt);
|
440 | };
|
441 |
|
442 | const endOfMonth = (y, m) => monthCap(m, leapYear(y));
|
443 | const calibre = (y, m, d, hi) => {
|
444 | if (d >= hi) return [y, m, endOfMonth(y, m)];
|
445 | if (d >= 28) return [y, m, Math.min(d, endOfMonth(y, m))];
|
446 | return [y, m, d];
|
447 | };
|
448 |
|
449 | const pad0 = (n, l) => {
|
450 | n = '' + n;
|
451 |
|
452 | while (n.length < l) n = '0' + n;
|
453 |
|
454 | return n;
|
455 | };
|
456 |
|
457 | const joinY4MD = (y, m, d, l = '-') => `${+y < 1000 ? pad0(+y, 4) : +y}${l}${+m < 10 ? pad0(+m, 2) : +m}${l}${+d < 10 ? pad0(+d, 2) : +d}`;
|
458 |
|
459 | const ymdToInt = ([y, m, d]) => ((y & 0xffff) << 9) + ((m & 0xf) << 5) + ((d & 0x1f) << 0);
|
460 |
|
461 | class Y4MD {
|
462 | static now() {
|
463 | return Y4MD.fromDate(new Date());
|
464 | }
|
465 |
|
466 | static fromDate(date = new Date()) {
|
467 | return [date.getFullYear(), date.getMonth() + 1, date.getDate()];
|
468 | }
|
469 |
|
470 | static toDate(ymd) {
|
471 | return new Date(ymd[0], ymd[1] - 1, ymd[2]);
|
472 | }
|
473 |
|
474 | static fromTx(tx) {
|
475 | return [+tx.slice(0, 4), +tx.slice(5, 7), +tx.slice(8, 10)];
|
476 | }
|
477 |
|
478 | static toTx(ymd, de = '-') {
|
479 | return joinY4MD(ymd[0], ymd[1], ymd[2], de);
|
480 | }
|
481 |
|
482 | static belongTo(ymd, lo, hi) {
|
483 | const int = ymdToInt(ymd);
|
484 | return ymdToInt(lo) <= int && int <= ymdToInt(hi);
|
485 | }
|
486 |
|
487 | static addD([y, m, d], days) {
|
488 | let lp = leapYear(y),
|
489 |
|
490 | |
491 |
|
492 |
|
493 |
|
494 | dt = {
|
495 | y,
|
496 | m,
|
497 | d: d + days,
|
498 | lp,
|
499 | cap: monthCap(m, lp)
|
500 | };
|
501 | if (dt.d - 365 > 0) dt = yearForth(dt);
|
502 | if (dt.d + 365 < 0) dt = yearBack(dt);
|
503 | dt = dt.d >= 0 ? daysForth(dt) : daysBack(dt);
|
504 | return [dt.y, dt.m, dt.d];
|
505 | }
|
506 |
|
507 | static addM([y, m, d], months) {
|
508 | let eom = endOfMonth(y, m);
|
509 | let ym = y * 12 + m + months;
|
510 | y = ~~(ym / 12);
|
511 | m = ym % 12;
|
512 |
|
513 | if (m < 1) {
|
514 | y--;
|
515 | m = 12;
|
516 | }
|
517 |
|
518 | return calibre(y, m, d, eom);
|
519 | }
|
520 |
|
521 | static addQ([y, m, d], quarters) {
|
522 | return Y4MD.addM([y, m, d], quarters * 3);
|
523 | }
|
524 |
|
525 | static addY([y, m, d], years) {
|
526 | return calibre(y + years, m, d, endOfMonth(y, m));
|
527 | }
|
528 |
|
529 | static seasonLoHi([y, m]) {
|
530 | let hi = ~~((m - 1) / 3 + 1) * 3;
|
531 | return [[y, hi - 2, 1], [y, hi, endOfMonth(y, hi)]];
|
532 | }
|
533 |
|
534 | static monthLoHi([y, m]) {
|
535 | return [[y, m, 1], [y, m, endOfMonth(y, m)]];
|
536 | }
|
537 |
|
538 | }
|
539 |
|
540 | exports.Chrono = Chrono;
|
541 | exports.Dawdle = Dawdle;
|
542 | exports.ETA = ETA;
|
543 | exports.GP = GP;
|
544 | exports.Y4MD = Y4MD;
|