@xpadev-net/niconicomments 0.2.61 → 0.2.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/bundle.d.ts +1644 -600
  2. package/dist/bundle.js +2120 -560
  3. package/package.json +17 -17
package/dist/bundle.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- niconicomments.js v0.2.61
2
+ niconicomments.js v0.2.63
3
3
  (c) 2021 xpadev-net https://xpadev.net
4
4
  Released under the MIT License.
5
5
  */
@@ -38,7 +38,7 @@
38
38
  plugins = input;
39
39
  };
40
40
 
41
- var index$3 = /*#__PURE__*/Object.freeze({
41
+ var index$4 = /*#__PURE__*/Object.freeze({
42
42
  __proto__: null,
43
43
  get imageCache () { return imageCache; },
44
44
  get nicoScripts () { return nicoScripts; },
@@ -124,7 +124,7 @@
124
124
  }
125
125
  NotImplementedError.prototype.name = "NotImplementedError";
126
126
 
127
- var index$2 = /*#__PURE__*/Object.freeze({
127
+ var index$3 = /*#__PURE__*/Object.freeze({
128
128
  __proto__: null,
129
129
  CanvasRenderingContext2DError: CanvasRenderingContext2DError,
130
130
  InvalidFormatError: InvalidFormatError,
@@ -132,7 +132,7 @@
132
132
  NotImplementedError: NotImplementedError
133
133
  });
134
134
 
135
- const ArrayPush = (array, key, push) => {
135
+ const arrayPush = (array, key, push) => {
136
136
  if (!array) {
137
137
  array = {};
138
138
  }
@@ -141,7 +141,7 @@
141
141
  }
142
142
  array[Number(key)]?.push(push);
143
143
  };
144
- const ArrayEqual = (a, b) => {
144
+ const arrayEqual = (a, b) => {
145
145
  if (a.length !== b.length)
146
146
  return false;
147
147
  for (let i = 0, n = a.length; i < n; ++i) {
@@ -206,6 +206,1449 @@
206
206
  : config.contextStrokeColor).join(",")},${config.contextStrokeOpacity})`;
207
207
  };
208
208
 
209
+ function _iterableToArrayLimit(r, l) {
210
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
211
+ if (null != t) {
212
+ var e,
213
+ n,
214
+ i,
215
+ u,
216
+ a = [],
217
+ f = !0,
218
+ o = !1;
219
+ try {
220
+ if (i = (t = t.call(r)).next, 0 === l) {
221
+ if (Object(t) !== t) return;
222
+ f = !1;
223
+ } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
224
+ } catch (r) {
225
+ o = !0, n = r;
226
+ } finally {
227
+ try {
228
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
229
+ } finally {
230
+ if (o) throw n;
231
+ }
232
+ }
233
+ return a;
234
+ }
235
+ }
236
+ function ownKeys(e, r) {
237
+ var t = Object.keys(e);
238
+ if (Object.getOwnPropertySymbols) {
239
+ var o = Object.getOwnPropertySymbols(e);
240
+ r && (o = o.filter(function (r) {
241
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
242
+ })), t.push.apply(t, o);
243
+ }
244
+ return t;
245
+ }
246
+ function _objectSpread2(e) {
247
+ for (var r = 1; r < arguments.length; r++) {
248
+ var t = null != arguments[r] ? arguments[r] : {};
249
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
250
+ _defineProperty(e, r, t[r]);
251
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
252
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
253
+ });
254
+ }
255
+ return e;
256
+ }
257
+ function _typeof(o) {
258
+ "@babel/helpers - typeof";
259
+
260
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
261
+ return typeof o;
262
+ } : function (o) {
263
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
264
+ }, _typeof(o);
265
+ }
266
+ function _classCallCheck(instance, Constructor) {
267
+ if (!(instance instanceof Constructor)) {
268
+ throw new TypeError("Cannot call a class as a function");
269
+ }
270
+ }
271
+ function _defineProperties(target, props) {
272
+ for (var i = 0; i < props.length; i++) {
273
+ var descriptor = props[i];
274
+ descriptor.enumerable = descriptor.enumerable || false;
275
+ descriptor.configurable = true;
276
+ if ("value" in descriptor) descriptor.writable = true;
277
+ Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
278
+ }
279
+ }
280
+ function _createClass(Constructor, protoProps, staticProps) {
281
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
282
+ if (staticProps) _defineProperties(Constructor, staticProps);
283
+ Object.defineProperty(Constructor, "prototype", {
284
+ writable: false
285
+ });
286
+ return Constructor;
287
+ }
288
+ function _defineProperty(obj, key, value) {
289
+ key = _toPropertyKey(key);
290
+ if (key in obj) {
291
+ Object.defineProperty(obj, key, {
292
+ value: value,
293
+ enumerable: true,
294
+ configurable: true,
295
+ writable: true
296
+ });
297
+ } else {
298
+ obj[key] = value;
299
+ }
300
+ return obj;
301
+ }
302
+ function _inherits(subClass, superClass) {
303
+ if (typeof superClass !== "function" && superClass !== null) {
304
+ throw new TypeError("Super expression must either be null or a function");
305
+ }
306
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
307
+ constructor: {
308
+ value: subClass,
309
+ writable: true,
310
+ configurable: true
311
+ }
312
+ });
313
+ Object.defineProperty(subClass, "prototype", {
314
+ writable: false
315
+ });
316
+ if (superClass) _setPrototypeOf(subClass, superClass);
317
+ }
318
+ function _getPrototypeOf(o) {
319
+ _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
320
+ return o.__proto__ || Object.getPrototypeOf(o);
321
+ };
322
+ return _getPrototypeOf(o);
323
+ }
324
+ function _setPrototypeOf(o, p) {
325
+ _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
326
+ o.__proto__ = p;
327
+ return o;
328
+ };
329
+ return _setPrototypeOf(o, p);
330
+ }
331
+ function _isNativeReflectConstruct() {
332
+ if (typeof Reflect === "undefined" || !Reflect.construct) return false;
333
+ if (Reflect.construct.sham) return false;
334
+ if (typeof Proxy === "function") return true;
335
+ try {
336
+ Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
337
+ return true;
338
+ } catch (e) {
339
+ return false;
340
+ }
341
+ }
342
+ function _construct(Parent, args, Class) {
343
+ if (_isNativeReflectConstruct()) {
344
+ _construct = Reflect.construct.bind();
345
+ } else {
346
+ _construct = function _construct(Parent, args, Class) {
347
+ var a = [null];
348
+ a.push.apply(a, args);
349
+ var Constructor = Function.bind.apply(Parent, a);
350
+ var instance = new Constructor();
351
+ if (Class) _setPrototypeOf(instance, Class.prototype);
352
+ return instance;
353
+ };
354
+ }
355
+ return _construct.apply(null, arguments);
356
+ }
357
+ function _isNativeFunction(fn) {
358
+ try {
359
+ return Function.toString.call(fn).indexOf("[native code]") !== -1;
360
+ } catch (e) {
361
+ return typeof fn === "function";
362
+ }
363
+ }
364
+ function _wrapNativeSuper(Class) {
365
+ var _cache = typeof Map === "function" ? new Map() : undefined;
366
+ _wrapNativeSuper = function _wrapNativeSuper(Class) {
367
+ if (Class === null || !_isNativeFunction(Class)) return Class;
368
+ if (typeof Class !== "function") {
369
+ throw new TypeError("Super expression must either be null or a function");
370
+ }
371
+ if (typeof _cache !== "undefined") {
372
+ if (_cache.has(Class)) return _cache.get(Class);
373
+ _cache.set(Class, Wrapper);
374
+ }
375
+ function Wrapper() {
376
+ return _construct(Class, arguments, _getPrototypeOf(this).constructor);
377
+ }
378
+ Wrapper.prototype = Object.create(Class.prototype, {
379
+ constructor: {
380
+ value: Wrapper,
381
+ enumerable: false,
382
+ writable: true,
383
+ configurable: true
384
+ }
385
+ });
386
+ return _setPrototypeOf(Wrapper, Class);
387
+ };
388
+ return _wrapNativeSuper(Class);
389
+ }
390
+ function _assertThisInitialized(self) {
391
+ if (self === void 0) {
392
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
393
+ }
394
+ return self;
395
+ }
396
+ function _possibleConstructorReturn(self, call) {
397
+ if (call && (typeof call === "object" || typeof call === "function")) {
398
+ return call;
399
+ } else if (call !== void 0) {
400
+ throw new TypeError("Derived constructors may only return object or undefined");
401
+ }
402
+ return _assertThisInitialized(self);
403
+ }
404
+ function _createSuper(Derived) {
405
+ var hasNativeReflectConstruct = _isNativeReflectConstruct();
406
+ return function _createSuperInternal() {
407
+ var Super = _getPrototypeOf(Derived),
408
+ result;
409
+ if (hasNativeReflectConstruct) {
410
+ var NewTarget = _getPrototypeOf(this).constructor;
411
+ result = Reflect.construct(Super, arguments, NewTarget);
412
+ } else {
413
+ result = Super.apply(this, arguments);
414
+ }
415
+ return _possibleConstructorReturn(this, result);
416
+ };
417
+ }
418
+ function _slicedToArray(arr, i) {
419
+ return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
420
+ }
421
+ function _arrayWithHoles(arr) {
422
+ if (Array.isArray(arr)) return arr;
423
+ }
424
+ function _unsupportedIterableToArray(o, minLen) {
425
+ if (!o) return;
426
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
427
+ var n = Object.prototype.toString.call(o).slice(8, -1);
428
+ if (n === "Object" && o.constructor) n = o.constructor.name;
429
+ if (n === "Map" || n === "Set") return Array.from(o);
430
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
431
+ }
432
+ function _arrayLikeToArray(arr, len) {
433
+ if (len == null || len > arr.length) len = arr.length;
434
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
435
+ return arr2;
436
+ }
437
+ function _nonIterableRest() {
438
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
439
+ }
440
+ function _createForOfIteratorHelper(o, allowArrayLike) {
441
+ var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
442
+ if (!it) {
443
+ if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
444
+ if (it) o = it;
445
+ var i = 0;
446
+ var F = function () {};
447
+ return {
448
+ s: F,
449
+ n: function () {
450
+ if (i >= o.length) return {
451
+ done: true
452
+ };
453
+ return {
454
+ done: false,
455
+ value: o[i++]
456
+ };
457
+ },
458
+ e: function (e) {
459
+ throw e;
460
+ },
461
+ f: F
462
+ };
463
+ }
464
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
465
+ }
466
+ var normalCompletion = true,
467
+ didErr = false,
468
+ err;
469
+ return {
470
+ s: function () {
471
+ it = it.call(o);
472
+ },
473
+ n: function () {
474
+ var step = it.next();
475
+ normalCompletion = step.done;
476
+ return step;
477
+ },
478
+ e: function (e) {
479
+ didErr = true;
480
+ err = e;
481
+ },
482
+ f: function () {
483
+ try {
484
+ if (!normalCompletion && it.return != null) it.return();
485
+ } finally {
486
+ if (didErr) throw err;
487
+ }
488
+ }
489
+ };
490
+ }
491
+ function _toPrimitive(input, hint) {
492
+ if (typeof input !== "object" || input === null) return input;
493
+ var prim = input[Symbol.toPrimitive];
494
+ if (prim !== undefined) {
495
+ var res = prim.call(input, hint || "default");
496
+ if (typeof res !== "object") return res;
497
+ throw new TypeError("@@toPrimitive must return a primitive value.");
498
+ }
499
+ return (hint === "string" ? String : Number)(input);
500
+ }
501
+ function _toPropertyKey(arg) {
502
+ var key = _toPrimitive(arg, "string");
503
+ return typeof key === "symbol" ? key : String(key);
504
+ }
505
+
506
+ // src/error/ValiError/ValiError.ts
507
+ var ValiError = /*#__PURE__*/function (_Error) {
508
+ _inherits(ValiError, _Error);
509
+ var _super = _createSuper(ValiError);
510
+ /**
511
+ * Creates a Valibot error with useful information.
512
+ *
513
+ * @param issues The error issues.
514
+ */
515
+ function ValiError(issues) {
516
+ var _this;
517
+ _classCallCheck(this, ValiError);
518
+ _this = _super.call(this, issues[0].message);
519
+ _defineProperty(_assertThisInitialized(_this), "issues", void 0);
520
+ _this.name = "ValiError";
521
+ _this.issues = issues;
522
+ return _this;
523
+ }
524
+ return _createClass(ValiError);
525
+ }( /*#__PURE__*/_wrapNativeSuper(Error));
526
+
527
+ // src/utils/getIssues/getIssues.ts
528
+ function getIssues(issues) {
529
+ return {
530
+ issues: issues
531
+ };
532
+ }
533
+
534
+ // src/utils/getOutput/getOutput.ts
535
+ function getOutput(output) {
536
+ return {
537
+ output: output
538
+ };
539
+ }
540
+
541
+ // src/utils/executePipe/utils/getIssue/getIssue.ts
542
+ function getIssue(info, issue) {
543
+ return {
544
+ reason: info === null || info === void 0 ? void 0 : info.reason,
545
+ validation: issue.validation,
546
+ origin: (info === null || info === void 0 ? void 0 : info.origin) || "value",
547
+ message: issue.message,
548
+ input: issue.input,
549
+ path: issue.path,
550
+ abortEarly: info === null || info === void 0 ? void 0 : info.abortEarly,
551
+ abortPipeEarly: info === null || info === void 0 ? void 0 : info.abortPipeEarly,
552
+ skipPipe: info === null || info === void 0 ? void 0 : info.skipPipe
553
+ };
554
+ }
555
+
556
+ // src/utils/executePipe/utils/getPipeInfo/getPipeInfo.ts
557
+ function getPipeInfo(info, reason) {
558
+ return {
559
+ reason: reason,
560
+ origin: info === null || info === void 0 ? void 0 : info.origin,
561
+ abortEarly: info === null || info === void 0 ? void 0 : info.abortEarly,
562
+ abortPipeEarly: info === null || info === void 0 ? void 0 : info.abortPipeEarly,
563
+ skipPipe: info === null || info === void 0 ? void 0 : info.skipPipe
564
+ };
565
+ }
566
+
567
+ // src/utils/executePipe/executePipe.ts
568
+ function executePipe(input, pipe, parseInfo, reason) {
569
+ if (!pipe || !pipe.length || parseInfo !== null && parseInfo !== void 0 && parseInfo.skipPipe) {
570
+ return getOutput(input);
571
+ }
572
+ var pipeInfo;
573
+ var issues;
574
+ var output = input;
575
+ var _iterator = _createForOfIteratorHelper(pipe),
576
+ _step;
577
+ try {
578
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
579
+ var action = _step.value;
580
+ var result = action(output);
581
+ if (result.issues) {
582
+ pipeInfo = pipeInfo || getPipeInfo(parseInfo, reason);
583
+ var _iterator2 = _createForOfIteratorHelper(result.issues),
584
+ _step2;
585
+ try {
586
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
587
+ var issueInfo = _step2.value;
588
+ var issue = getIssue(pipeInfo, issueInfo);
589
+ issues ? issues.push(issue) : issues = [issue];
590
+ }
591
+ } catch (err) {
592
+ _iterator2.e(err);
593
+ } finally {
594
+ _iterator2.f();
595
+ }
596
+ if (pipeInfo.abortEarly || pipeInfo.abortPipeEarly) {
597
+ break;
598
+ }
599
+ } else {
600
+ output = result.output;
601
+ }
602
+ }
603
+ } catch (err) {
604
+ _iterator.e(err);
605
+ } finally {
606
+ _iterator.f();
607
+ }
608
+ return issues ? getIssues(issues) : getOutput(output);
609
+ }
610
+ function getDefaultArgs(arg1, arg2) {
611
+ return Array.isArray(arg1) ? [void 0, arg1] : [arg1, arg2];
612
+ }
613
+
614
+ // src/utils/getErrorMessage/getErrorMessage.ts
615
+ function getErrorMessage(error) {
616
+ return typeof error === "function" ? error() : error;
617
+ }
618
+
619
+ // src/utils/getPipeIssues/getPipeIssues.ts
620
+ function getPipeIssues(validation, error, input) {
621
+ return getIssues([{
622
+ validation: validation,
623
+ message: getErrorMessage(error),
624
+ input: input
625
+ }]);
626
+ }
627
+
628
+ // src/utils/getRestAndDefaultArgs/getRestAndDefaultArgs.ts
629
+ function getRestAndDefaultArgs(arg1, arg2, arg3) {
630
+ if (!arg1 || _typeof(arg1) === "object" && !Array.isArray(arg1)) {
631
+ var _getDefaultArgs = getDefaultArgs(arg2, arg3),
632
+ _getDefaultArgs2 = _slicedToArray(_getDefaultArgs, 2),
633
+ error2 = _getDefaultArgs2[0],
634
+ pipe2 = _getDefaultArgs2[1];
635
+ return [arg1, error2, pipe2];
636
+ }
637
+ var _getDefaultArgs3 = getDefaultArgs(arg1, arg2),
638
+ _getDefaultArgs4 = _slicedToArray(_getDefaultArgs3, 2),
639
+ error = _getDefaultArgs4[0],
640
+ pipe = _getDefaultArgs4[1];
641
+ return [void 0, error, pipe];
642
+ }
643
+
644
+ // src/utils/getSchemaIssues/getSchemaIssues.ts
645
+ function getSchemaIssues(info, reason, validation, error, input, issues) {
646
+ return {
647
+ issues: [{
648
+ reason: reason,
649
+ validation: validation,
650
+ origin: (info === null || info === void 0 ? void 0 : info.origin) || "value",
651
+ message: getErrorMessage(error),
652
+ input: input,
653
+ issues: issues,
654
+ abortEarly: info === null || info === void 0 ? void 0 : info.abortEarly,
655
+ abortPipeEarly: info === null || info === void 0 ? void 0 : info.abortPipeEarly,
656
+ skipPipe: info === null || info === void 0 ? void 0 : info.skipPipe
657
+ }]
658
+ };
659
+ }
660
+ function is(schema, input) {
661
+ return !schema._parse(input, {
662
+ abortEarly: true
663
+ }).issues;
664
+ }
665
+
666
+ // src/schemas/array/array.ts
667
+ function array(item, arg2, arg3) {
668
+ var _getDefaultArgs5 = getDefaultArgs(arg2, arg3),
669
+ _getDefaultArgs6 = _slicedToArray(_getDefaultArgs5, 2),
670
+ error = _getDefaultArgs6[0],
671
+ pipe = _getDefaultArgs6[1];
672
+ return {
673
+ /**
674
+ * The schema type.
675
+ */
676
+ type: "array",
677
+ /**
678
+ * The item schema.
679
+ */
680
+ item: item,
681
+ /**
682
+ * Whether it's async.
683
+ */
684
+ async: false,
685
+ /**
686
+ * Parses unknown input based on its schema.
687
+ *
688
+ * @param input The input to be parsed.
689
+ * @param info The parse info.
690
+ *
691
+ * @returns The parsed output.
692
+ */
693
+ _parse: function _parse(input, info) {
694
+ if (!Array.isArray(input)) {
695
+ return getSchemaIssues(info, "type", "array", error || "Invalid type", input);
696
+ }
697
+ var issues;
698
+ var output = [];
699
+ for (var key = 0; key < input.length; key++) {
700
+ var value2 = input[key];
701
+ var result = item._parse(value2, info);
702
+ if (result.issues) {
703
+ var pathItem = {
704
+ type: "array",
705
+ input: input,
706
+ key: key,
707
+ value: value2
708
+ };
709
+ var _iterator3 = _createForOfIteratorHelper(result.issues),
710
+ _step3;
711
+ try {
712
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
713
+ var _issues;
714
+ var issue = _step3.value;
715
+ if (issue.path) {
716
+ issue.path.unshift(pathItem);
717
+ } else {
718
+ issue.path = [pathItem];
719
+ }
720
+ (_issues = issues) === null || _issues === void 0 || _issues.push(issue);
721
+ }
722
+ } catch (err) {
723
+ _iterator3.e(err);
724
+ } finally {
725
+ _iterator3.f();
726
+ }
727
+ if (!issues) {
728
+ issues = result.issues;
729
+ }
730
+ if (info !== null && info !== void 0 && info.abortEarly) {
731
+ break;
732
+ }
733
+ } else {
734
+ output.push(result.output);
735
+ }
736
+ }
737
+ return issues ? getIssues(issues) : executePipe(output, pipe, info, "array");
738
+ }
739
+ };
740
+ }
741
+
742
+ // src/schemas/boolean/boolean.ts
743
+ function _boolean(arg1, arg2) {
744
+ var _getDefaultArgs17 = getDefaultArgs(arg1, arg2),
745
+ _getDefaultArgs18 = _slicedToArray(_getDefaultArgs17, 2),
746
+ error = _getDefaultArgs18[0],
747
+ pipe = _getDefaultArgs18[1];
748
+ return {
749
+ /**
750
+ * The schema type.
751
+ */
752
+ type: "boolean",
753
+ /**
754
+ * Whether it's async.
755
+ */
756
+ async: false,
757
+ /**
758
+ * Parses unknown input based on its schema.
759
+ *
760
+ * @param input The input to be parsed.
761
+ * @param info The parse info.
762
+ *
763
+ * @returns The parsed output.
764
+ */
765
+ _parse: function _parse(input, info) {
766
+ if (typeof input !== "boolean") {
767
+ return getSchemaIssues(info, "type", "boolean", error || "Invalid type", input);
768
+ }
769
+ return executePipe(input, pipe, info, "boolean");
770
+ }
771
+ };
772
+ }
773
+
774
+ // src/schemas/intersect/utils/mergeOutputs/mergeOutputs.ts
775
+ function mergeOutputs(output1, output2) {
776
+ if (_typeof(output1) === _typeof(output2)) {
777
+ if (output1 === output2 || output1 instanceof Date && output2 instanceof Date && +output1 === +output2) {
778
+ return getOutput(output1);
779
+ }
780
+ if (Array.isArray(output1) && Array.isArray(output2)) {
781
+ if (output1.length === output2.length) {
782
+ var array2 = [];
783
+ for (var index = 0; index < output1.length; index++) {
784
+ var result = mergeOutputs(output1[index], output2[index]);
785
+ if (result.invalid) {
786
+ return result;
787
+ }
788
+ array2.push(result.output);
789
+ }
790
+ return getOutput(array2);
791
+ }
792
+ return {
793
+ invalid: true
794
+ };
795
+ }
796
+ if (output1 && output2 && output1.constructor === Object && output2.constructor === Object) {
797
+ var object2 = _objectSpread2(_objectSpread2({}, output1), output2);
798
+ for (var key in output1) {
799
+ if (key in output2) {
800
+ var _result = mergeOutputs(output1[key], output2[key]);
801
+ if (_result.invalid) {
802
+ return _result;
803
+ }
804
+ object2[key] = _result.output;
805
+ }
806
+ }
807
+ return getOutput(object2);
808
+ }
809
+ }
810
+ return {
811
+ invalid: true
812
+ };
813
+ }
814
+
815
+ // src/schemas/intersect/intersect.ts
816
+ function intersect(options, error) {
817
+ return {
818
+ /**
819
+ * The schema type.
820
+ */
821
+ type: "intersect",
822
+ /**
823
+ * The intersect options.
824
+ */
825
+ options: options,
826
+ /**
827
+ * Whether it's async.
828
+ */
829
+ async: false,
830
+ /**
831
+ * Parses unknown input based on its schema.
832
+ *
833
+ * @param input The input to be parsed.
834
+ * @param info The parse info.
835
+ *
836
+ * @returns The parsed output.
837
+ */
838
+ _parse: function _parse(input, info) {
839
+ var issues;
840
+ var outputs;
841
+ var _iterator5 = _createForOfIteratorHelper(options),
842
+ _step5;
843
+ try {
844
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
845
+ var schema = _step5.value;
846
+ var _result2 = schema._parse(input, info);
847
+ if (_result2.issues) {
848
+ if (issues) {
849
+ var _iterator6 = _createForOfIteratorHelper(_result2.issues),
850
+ _step6;
851
+ try {
852
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
853
+ var issue = _step6.value;
854
+ issues.push(issue);
855
+ }
856
+ } catch (err) {
857
+ _iterator6.e(err);
858
+ } finally {
859
+ _iterator6.f();
860
+ }
861
+ } else {
862
+ issues = _result2.issues;
863
+ }
864
+ if (info !== null && info !== void 0 && info.abortEarly) {
865
+ break;
866
+ }
867
+ } else {
868
+ if (outputs) {
869
+ outputs.push(_result2.output);
870
+ } else {
871
+ outputs = [_result2.output];
872
+ }
873
+ }
874
+ }
875
+ } catch (err) {
876
+ _iterator5.e(err);
877
+ } finally {
878
+ _iterator5.f();
879
+ }
880
+ if (issues) {
881
+ return getIssues(issues);
882
+ }
883
+ var output = outputs[0];
884
+ for (var index = 1; index < outputs.length; index++) {
885
+ var result = mergeOutputs(output, outputs[index]);
886
+ if (result.invalid) {
887
+ return getSchemaIssues(info, "type", "intersect", error || "Invalid type", input);
888
+ }
889
+ output = result.output;
890
+ }
891
+ return getOutput(output);
892
+ }
893
+ };
894
+ }
895
+
896
+ // src/schemas/literal/literal.ts
897
+ function literal(literal2, error) {
898
+ return {
899
+ /**
900
+ * The schema type.
901
+ */
902
+ type: "literal",
903
+ /**
904
+ * The literal value.
905
+ */
906
+ literal: literal2,
907
+ /**
908
+ * Whether it's async.
909
+ */
910
+ async: false,
911
+ /**
912
+ * Parses unknown input based on its schema.
913
+ *
914
+ * @param input The input to be parsed.
915
+ * @param info The parse info.
916
+ *
917
+ * @returns The parsed output.
918
+ */
919
+ _parse: function _parse(input, info) {
920
+ if (input !== literal2) {
921
+ return getSchemaIssues(info, "type", "literal", error || "Invalid type", input);
922
+ }
923
+ return getOutput(input);
924
+ }
925
+ };
926
+ }
927
+
928
+ // src/schemas/nullable/nullable.ts
929
+ function nullable(wrapped, default_) {
930
+ return {
931
+ /**
932
+ * The schema type.
933
+ */
934
+ type: "nullable",
935
+ /**
936
+ * The wrapped schema.
937
+ */
938
+ wrapped: wrapped,
939
+ /**
940
+ * Returns the default value.
941
+ */
942
+ getDefault: function getDefault() {
943
+ return typeof default_ === "function" ? default_() : default_;
944
+ },
945
+ /**
946
+ * Whether it's async.
947
+ */
948
+ async: false,
949
+ /**
950
+ * Parses unknown input based on its schema.
951
+ *
952
+ * @param input The input to be parsed.
953
+ * @param info The parse info.
954
+ *
955
+ * @returns The parsed output.
956
+ */
957
+ _parse: function _parse(input, info) {
958
+ if (input === null) {
959
+ var override = this.getDefault();
960
+ if (override === void 0) {
961
+ return getOutput(input);
962
+ }
963
+ input = override;
964
+ }
965
+ return wrapped._parse(input, info);
966
+ }
967
+ };
968
+ }
969
+
970
+ // src/schemas/number/number.ts
971
+ function number(arg1, arg2) {
972
+ var _getDefaultArgs33 = getDefaultArgs(arg1, arg2),
973
+ _getDefaultArgs34 = _slicedToArray(_getDefaultArgs33, 2),
974
+ error = _getDefaultArgs34[0],
975
+ pipe = _getDefaultArgs34[1];
976
+ return {
977
+ /**
978
+ * The schema type.
979
+ */
980
+ type: "number",
981
+ /**
982
+ * Whether it's async.
983
+ */
984
+ async: false,
985
+ /**
986
+ * Parses unknown input based on its schema.
987
+ *
988
+ * @param input The input to be parsed.
989
+ * @param info The parse info.
990
+ *
991
+ * @returns The parsed output.
992
+ */
993
+ _parse: function _parse(input, info) {
994
+ if (typeof input !== "number" || isNaN(input)) {
995
+ return getSchemaIssues(info, "type", "number", error || "Invalid type", input);
996
+ }
997
+ return executePipe(input, pipe, info, "number");
998
+ }
999
+ };
1000
+ }
1001
+
1002
+ // src/schemas/object/object.ts
1003
+ function object(entries, arg2, arg3, arg4) {
1004
+ var _getRestAndDefaultArg = getRestAndDefaultArgs(arg2, arg3, arg4),
1005
+ _getRestAndDefaultArg2 = _slicedToArray(_getRestAndDefaultArg, 3),
1006
+ rest = _getRestAndDefaultArg2[0],
1007
+ error = _getRestAndDefaultArg2[1],
1008
+ pipe = _getRestAndDefaultArg2[2];
1009
+ var cachedEntries;
1010
+ return {
1011
+ /**
1012
+ * The schema type.
1013
+ */
1014
+ type: "object",
1015
+ /**
1016
+ * The entries schema.
1017
+ */
1018
+ entries: entries,
1019
+ /**
1020
+ * The rest schema.
1021
+ */
1022
+ rest: rest,
1023
+ /**
1024
+ * Whether it's async.
1025
+ */
1026
+ async: false,
1027
+ /**
1028
+ * Parses unknown input based on its schema.
1029
+ *
1030
+ * @param input The input to be parsed.
1031
+ * @param info The parse info.
1032
+ *
1033
+ * @returns The parsed output.
1034
+ */
1035
+ _parse: function _parse(input, info) {
1036
+ if (!input || _typeof(input) !== "object") {
1037
+ return getSchemaIssues(info, "type", "object", error || "Invalid type", input);
1038
+ }
1039
+ cachedEntries = cachedEntries || Object.entries(entries);
1040
+ var issues;
1041
+ var output = {};
1042
+ var _iterator11 = _createForOfIteratorHelper(cachedEntries),
1043
+ _step11;
1044
+ try {
1045
+ for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
1046
+ var _step11$value = _slicedToArray(_step11.value, 2),
1047
+ _key3 = _step11$value[0],
1048
+ schema = _step11$value[1];
1049
+ var _value = input[_key3];
1050
+ var _result3 = schema._parse(_value, info);
1051
+ if (_result3.issues) {
1052
+ var _pathItem = {
1053
+ type: "object",
1054
+ input: input,
1055
+ key: _key3,
1056
+ value: _value
1057
+ };
1058
+ var _iterator13 = _createForOfIteratorHelper(_result3.issues),
1059
+ _step13;
1060
+ try {
1061
+ for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
1062
+ var _issues7;
1063
+ var _issue2 = _step13.value;
1064
+ if (_issue2.path) {
1065
+ _issue2.path.unshift(_pathItem);
1066
+ } else {
1067
+ _issue2.path = [_pathItem];
1068
+ }
1069
+ (_issues7 = issues) === null || _issues7 === void 0 || _issues7.push(_issue2);
1070
+ }
1071
+ } catch (err) {
1072
+ _iterator13.e(err);
1073
+ } finally {
1074
+ _iterator13.f();
1075
+ }
1076
+ if (!issues) {
1077
+ issues = _result3.issues;
1078
+ }
1079
+ if (info !== null && info !== void 0 && info.abortEarly) {
1080
+ break;
1081
+ }
1082
+ } else if (_result3.output !== void 0 || _key3 in input) {
1083
+ output[_key3] = _result3.output;
1084
+ }
1085
+ }
1086
+ } catch (err) {
1087
+ _iterator11.e(err);
1088
+ } finally {
1089
+ _iterator11.f();
1090
+ }
1091
+ if (rest && !(info !== null && info !== void 0 && info.abortEarly && issues)) {
1092
+ for (var key in input) {
1093
+ if (!(key in entries)) {
1094
+ var value2 = input[key];
1095
+ var result = rest._parse(value2, info);
1096
+ if (result.issues) {
1097
+ var pathItem = {
1098
+ type: "object",
1099
+ input: input,
1100
+ key: key,
1101
+ value: value2
1102
+ };
1103
+ var _iterator12 = _createForOfIteratorHelper(result.issues),
1104
+ _step12;
1105
+ try {
1106
+ for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
1107
+ var _issues6;
1108
+ var issue = _step12.value;
1109
+ if (issue.path) {
1110
+ issue.path.unshift(pathItem);
1111
+ } else {
1112
+ issue.path = [pathItem];
1113
+ }
1114
+ (_issues6 = issues) === null || _issues6 === void 0 || _issues6.push(issue);
1115
+ }
1116
+ } catch (err) {
1117
+ _iterator12.e(err);
1118
+ } finally {
1119
+ _iterator12.f();
1120
+ }
1121
+ if (!issues) {
1122
+ issues = result.issues;
1123
+ }
1124
+ if (info !== null && info !== void 0 && info.abortEarly) {
1125
+ break;
1126
+ }
1127
+ } else {
1128
+ output[key] = result.output;
1129
+ }
1130
+ }
1131
+ }
1132
+ }
1133
+ return issues ? getIssues(issues) : executePipe(output, pipe, info, "object");
1134
+ }
1135
+ };
1136
+ }
1137
+
1138
+ // src/schemas/optional/optional.ts
1139
+ function optional(wrapped, default_) {
1140
+ return {
1141
+ /**
1142
+ * The schema type.
1143
+ */
1144
+ type: "optional",
1145
+ /**
1146
+ * The wrapped schema.
1147
+ */
1148
+ wrapped: wrapped,
1149
+ /**
1150
+ * Returns the default value.
1151
+ */
1152
+ getDefault: function getDefault() {
1153
+ return typeof default_ === "function" ? default_() : default_;
1154
+ },
1155
+ /**
1156
+ * Whether it's async.
1157
+ */
1158
+ async: false,
1159
+ /**
1160
+ * Parses unknown input based on its schema.
1161
+ *
1162
+ * @param input The input to be parsed.
1163
+ * @param info The parse info.
1164
+ *
1165
+ * @returns The parsed output.
1166
+ */
1167
+ _parse: function _parse(input, info) {
1168
+ if (input === void 0) {
1169
+ var override = this.getDefault();
1170
+ if (override === void 0) {
1171
+ return getOutput(input);
1172
+ }
1173
+ input = override;
1174
+ }
1175
+ return wrapped._parse(input, info);
1176
+ }
1177
+ };
1178
+ }
1179
+
1180
+ // src/schemas/string/string.ts
1181
+ function string(arg1, arg2) {
1182
+ var _getDefaultArgs37 = getDefaultArgs(arg1, arg2),
1183
+ _getDefaultArgs38 = _slicedToArray(_getDefaultArgs37, 2),
1184
+ error = _getDefaultArgs38[0],
1185
+ pipe = _getDefaultArgs38[1];
1186
+ return {
1187
+ /**
1188
+ * The schema type.
1189
+ */
1190
+ type: "string",
1191
+ /**
1192
+ * Whether it's async.
1193
+ */
1194
+ async: false,
1195
+ /**
1196
+ * Parses unknown input based on its schema.
1197
+ *
1198
+ * @param input The input to be parsed.
1199
+ * @param info The parse info.
1200
+ *
1201
+ * @returns The parsed output.
1202
+ */
1203
+ _parse: function _parse(input, info) {
1204
+ if (typeof input !== "string") {
1205
+ return getSchemaIssues(info, "type", "string", error || "Invalid type", input);
1206
+ }
1207
+ return executePipe(input, pipe, info, "string");
1208
+ }
1209
+ };
1210
+ }
1211
+
1212
+ // src/schemas/record/utils/getRecordArgs/getRecordArgs.ts
1213
+ function getRecordArgs(arg1, arg2, arg3, arg4) {
1214
+ if (_typeof(arg2) === "object" && !Array.isArray(arg2)) {
1215
+ var _getDefaultArgs41 = getDefaultArgs(arg3, arg4),
1216
+ _getDefaultArgs42 = _slicedToArray(_getDefaultArgs41, 2),
1217
+ error2 = _getDefaultArgs42[0],
1218
+ pipe2 = _getDefaultArgs42[1];
1219
+ return [arg1, arg2, error2, pipe2];
1220
+ }
1221
+ var _getDefaultArgs43 = getDefaultArgs(arg2, arg3),
1222
+ _getDefaultArgs44 = _slicedToArray(_getDefaultArgs43, 2),
1223
+ error = _getDefaultArgs44[0],
1224
+ pipe = _getDefaultArgs44[1];
1225
+ return [string(), arg1, error, pipe];
1226
+ }
1227
+
1228
+ // src/schemas/record/values.ts
1229
+ var BLOCKED_KEYS = ["__proto__", "prototype", "constructor"];
1230
+
1231
+ // src/schemas/record/record.ts
1232
+ function record(arg1, arg2, arg3, arg4) {
1233
+ var _getRecordArgs = getRecordArgs(arg1, arg2, arg3, arg4),
1234
+ _getRecordArgs2 = _slicedToArray(_getRecordArgs, 4),
1235
+ key = _getRecordArgs2[0],
1236
+ value2 = _getRecordArgs2[1],
1237
+ error = _getRecordArgs2[2],
1238
+ pipe = _getRecordArgs2[3];
1239
+ return {
1240
+ /**
1241
+ * The schema type.
1242
+ */
1243
+ type: "record",
1244
+ /**
1245
+ * The key schema.
1246
+ */
1247
+ key: key,
1248
+ /**
1249
+ * The value schema.
1250
+ */
1251
+ value: value2,
1252
+ /**
1253
+ * Whether it's async.
1254
+ */
1255
+ async: false,
1256
+ /**
1257
+ * Parses unknown input based on its schema.
1258
+ *
1259
+ * @param input The input to be parsed.
1260
+ * @param info The parse info.
1261
+ *
1262
+ * @returns The parsed output.
1263
+ */
1264
+ _parse: function _parse(input, info) {
1265
+ if (!input || _typeof(input) !== "object") {
1266
+ return getSchemaIssues(info, "type", "record", error || "Invalid type", input);
1267
+ }
1268
+ var issues;
1269
+ var output = {};
1270
+ for (var _i = 0, _Object$entries = Object.entries(input); _i < _Object$entries.length; _i++) {
1271
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
1272
+ inputKey = _Object$entries$_i[0],
1273
+ inputValue = _Object$entries$_i[1];
1274
+ if (!BLOCKED_KEYS.includes(inputKey)) {
1275
+ var pathItem = void 0;
1276
+ var keyResult = key._parse(inputKey, {
1277
+ origin: "key",
1278
+ abortEarly: info === null || info === void 0 ? void 0 : info.abortEarly,
1279
+ abortPipeEarly: info === null || info === void 0 ? void 0 : info.abortPipeEarly,
1280
+ skipPipe: info === null || info === void 0 ? void 0 : info.skipPipe
1281
+ });
1282
+ if (keyResult.issues) {
1283
+ pathItem = {
1284
+ type: "record",
1285
+ input: input,
1286
+ key: inputKey,
1287
+ value: inputValue
1288
+ };
1289
+ var _iterator16 = _createForOfIteratorHelper(keyResult.issues),
1290
+ _step16;
1291
+ try {
1292
+ for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
1293
+ var _issues10;
1294
+ var issue = _step16.value;
1295
+ issue.path = [pathItem];
1296
+ (_issues10 = issues) === null || _issues10 === void 0 || _issues10.push(issue);
1297
+ }
1298
+ } catch (err) {
1299
+ _iterator16.e(err);
1300
+ } finally {
1301
+ _iterator16.f();
1302
+ }
1303
+ if (!issues) {
1304
+ issues = keyResult.issues;
1305
+ }
1306
+ if (info !== null && info !== void 0 && info.abortEarly) {
1307
+ break;
1308
+ }
1309
+ }
1310
+ var valueResult = value2._parse(inputValue, info);
1311
+ if (valueResult.issues) {
1312
+ pathItem = pathItem || {
1313
+ type: "record",
1314
+ input: input,
1315
+ key: inputKey,
1316
+ value: inputValue
1317
+ };
1318
+ var _iterator17 = _createForOfIteratorHelper(valueResult.issues),
1319
+ _step17;
1320
+ try {
1321
+ for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
1322
+ var _issues11;
1323
+ var _issue3 = _step17.value;
1324
+ if (_issue3.path) {
1325
+ _issue3.path.unshift(pathItem);
1326
+ } else {
1327
+ _issue3.path = [pathItem];
1328
+ }
1329
+ (_issues11 = issues) === null || _issues11 === void 0 || _issues11.push(_issue3);
1330
+ }
1331
+ } catch (err) {
1332
+ _iterator17.e(err);
1333
+ } finally {
1334
+ _iterator17.f();
1335
+ }
1336
+ if (!issues) {
1337
+ issues = valueResult.issues;
1338
+ }
1339
+ if (info !== null && info !== void 0 && info.abortEarly) {
1340
+ break;
1341
+ }
1342
+ }
1343
+ if (!keyResult.issues && !valueResult.issues) {
1344
+ output[keyResult.output] = valueResult.output;
1345
+ }
1346
+ }
1347
+ }
1348
+ return issues ? getIssues(issues) : executePipe(output, pipe, info, "record");
1349
+ }
1350
+ };
1351
+ }
1352
+
1353
+ // src/schemas/union/union.ts
1354
+ function union(options, error) {
1355
+ return {
1356
+ /**
1357
+ * The schema type.
1358
+ */
1359
+ type: "union",
1360
+ /**
1361
+ * The union options.
1362
+ */
1363
+ options: options,
1364
+ /**
1365
+ * Whether it's async.
1366
+ */
1367
+ async: false,
1368
+ /**
1369
+ * Parses unknown input based on its schema.
1370
+ *
1371
+ * @param input The input to be parsed.
1372
+ * @param info The parse info.
1373
+ *
1374
+ * @returns The parsed output.
1375
+ */
1376
+ _parse: function _parse(input, info) {
1377
+ var issues;
1378
+ var output;
1379
+ var _iterator26 = _createForOfIteratorHelper(options),
1380
+ _step26;
1381
+ try {
1382
+ for (_iterator26.s(); !(_step26 = _iterator26.n()).done;) {
1383
+ var schema = _step26.value;
1384
+ var result = schema._parse(input, info);
1385
+ if (result.issues) {
1386
+ if (issues) {
1387
+ var _iterator27 = _createForOfIteratorHelper(result.issues),
1388
+ _step27;
1389
+ try {
1390
+ for (_iterator27.s(); !(_step27 = _iterator27.n()).done;) {
1391
+ var issue = _step27.value;
1392
+ issues.push(issue);
1393
+ }
1394
+ } catch (err) {
1395
+ _iterator27.e(err);
1396
+ } finally {
1397
+ _iterator27.f();
1398
+ }
1399
+ } else {
1400
+ issues = result.issues;
1401
+ }
1402
+ } else {
1403
+ output = [result.output];
1404
+ break;
1405
+ }
1406
+ }
1407
+ } catch (err) {
1408
+ _iterator26.e(err);
1409
+ } finally {
1410
+ _iterator26.f();
1411
+ }
1412
+ return output ? getOutput(output[0]) : getSchemaIssues(info, "type", "union", error || "Invalid type", input, issues);
1413
+ }
1414
+ };
1415
+ }
1416
+
1417
+ // src/schemas/unknown/unknown.ts
1418
+ function unknown() {
1419
+ var pipe = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
1420
+ return {
1421
+ /**
1422
+ * The schema type.
1423
+ */
1424
+ type: "unknown",
1425
+ /**
1426
+ * Whether it's async.
1427
+ */
1428
+ async: false,
1429
+ /**
1430
+ * Parses unknown input based on its schema.
1431
+ *
1432
+ * @param input The input to be parsed.
1433
+ * @param info The parse info.
1434
+ *
1435
+ * @returns The parsed output.
1436
+ */
1437
+ _parse: function _parse(input, info) {
1438
+ return executePipe(input, pipe, info, "unknown");
1439
+ }
1440
+ };
1441
+ }
1442
+
1443
+ // src/methods/omit/omit.ts
1444
+ function omit(schema, keys, arg3, arg4, arg5) {
1445
+ var _getRestAndDefaultArg13 = getRestAndDefaultArgs(arg3, arg4, arg5),
1446
+ _getRestAndDefaultArg14 = _slicedToArray(_getRestAndDefaultArg13, 3),
1447
+ rest = _getRestAndDefaultArg14[0],
1448
+ error = _getRestAndDefaultArg14[1],
1449
+ pipe = _getRestAndDefaultArg14[2];
1450
+ return object(Object.entries(schema.entries).reduce(function (entries, _ref24) {
1451
+ var _ref25 = _slicedToArray(_ref24, 2),
1452
+ key = _ref25[0],
1453
+ schema2 = _ref25[1];
1454
+ return keys.includes(key) ? entries : _objectSpread2(_objectSpread2({}, entries), {}, _defineProperty({}, key, schema2));
1455
+ }, {}), rest, error, pipe);
1456
+ }
1457
+
1458
+ // src/methods/parse/parse.ts
1459
+ function parse(schema, input, info) {
1460
+ var result = schema._parse(input, info);
1461
+ if (result.issues) {
1462
+ throw new ValiError(result.issues);
1463
+ }
1464
+ return result.output;
1465
+ }
1466
+
1467
+ // src/methods/safeParse/safeParse.ts
1468
+ function safeParse(schema, input, info) {
1469
+ var result = schema._parse(input, info);
1470
+ return result.issues ? {
1471
+ success: false,
1472
+ error: new ValiError(result.issues),
1473
+ issues: result.issues
1474
+ } : {
1475
+ success: true,
1476
+ data: result.output,
1477
+ output: result.output
1478
+ };
1479
+ }
1480
+
1481
+ // src/validations/custom/custom.ts
1482
+ function custom(requirement, error) {
1483
+ return function (input) {
1484
+ return !requirement(input) ? getPipeIssues("custom", error || "Invalid input", input) : getOutput(input);
1485
+ };
1486
+ }
1487
+
1488
+ // src/validations/notValue/notValue.ts
1489
+ function notValue(requirement, error) {
1490
+ return function (input) {
1491
+ return input === requirement ? getPipeIssues("not_value", error || "Invalid value", input) : getOutput(input);
1492
+ };
1493
+ }
1494
+
1495
+ // src/validations/regex/regex.ts
1496
+ function regex(requirement, error) {
1497
+ return function (input) {
1498
+ return !requirement.test(input) ? getPipeIssues("regex", error || "Invalid regex", input) : getOutput(input);
1499
+ };
1500
+ }
1501
+
1502
+ const ZHTML5Fonts = union([
1503
+ literal("gothic"),
1504
+ literal("mincho"),
1505
+ literal("defont"),
1506
+ ]);
1507
+
1508
+ const ZFormattedComment = object({
1509
+ id: optional(number(), 0),
1510
+ vpos: optional(number(), 0),
1511
+ content: optional(string(), ""),
1512
+ date: optional(number(), 0),
1513
+ date_usec: optional(number(), 0),
1514
+ owner: optional(_boolean(), false),
1515
+ premium: optional(_boolean(), false),
1516
+ mail: optional(array(string()), []),
1517
+ user_id: optional(number(), 0),
1518
+ layer: optional(number(), -1),
1519
+ is_my_post: optional(_boolean(), false),
1520
+ });
1521
+ const ZFormattedLegacyComment = omit(ZFormattedComment, [
1522
+ "layer",
1523
+ "user_id",
1524
+ "is_my_post",
1525
+ ]);
1526
+
1527
+ const ZApiChat = object({
1528
+ thread: optional(string(), ""),
1529
+ no: optional(number(), 0),
1530
+ vpos: number(),
1531
+ date: optional(number(), 0),
1532
+ date_usec: optional(number(), 0),
1533
+ nicoru: optional(number(), 0),
1534
+ premium: optional(number(), 0),
1535
+ anonymity: optional(number(), 0),
1536
+ user_id: optional(string(), ""),
1537
+ mail: optional(string(), ""),
1538
+ content: string(),
1539
+ deleted: optional(number(), 0),
1540
+ });
1541
+ const ZRawApiResponse = union([
1542
+ object({ chat: ZApiChat }),
1543
+ record(string([notValue("chat")]), unknown()),
1544
+ ]);
1545
+ const ZApiPing = object({
1546
+ content: string(),
1547
+ });
1548
+ const ZApiThread = object({
1549
+ resultcode: number(),
1550
+ thread: string(),
1551
+ server_time: number(),
1552
+ ticket: string(),
1553
+ revision: number(),
1554
+ });
1555
+ const ZApiLeaf = object({
1556
+ thread: string(),
1557
+ count: number(),
1558
+ });
1559
+ const ZApiGlobalNumRes = object({
1560
+ thread: string(),
1561
+ num_res: number(),
1562
+ });
1563
+
1564
+ const ZOwnerComment = object({
1565
+ time: string(),
1566
+ command: string(),
1567
+ comment: string(),
1568
+ });
1569
+
1570
+ const ZV1Comment = object({
1571
+ id: string(),
1572
+ no: number(),
1573
+ vposMs: number(),
1574
+ body: string(),
1575
+ commands: array(string()),
1576
+ userId: string(),
1577
+ isPremium: _boolean(),
1578
+ score: number(),
1579
+ postedAt: string(),
1580
+ nicoruCount: number(),
1581
+ nicoruId: nullable(string()),
1582
+ source: string(),
1583
+ isMyPost: _boolean(),
1584
+ });
1585
+ const ZV1Thread = object({
1586
+ id: unknown(),
1587
+ fork: string(),
1588
+ commentCount: optional(number(), 0),
1589
+ comments: array(ZV1Comment),
1590
+ });
1591
+
1592
+ const ZCommentFont = union([
1593
+ literal("defont"),
1594
+ literal("mincho"),
1595
+ literal("gothic"),
1596
+ literal("gulim"),
1597
+ literal("simsun"),
1598
+ ]);
1599
+ const ZCommentFlashFont = union([
1600
+ literal("defont"),
1601
+ literal("gulim"),
1602
+ literal("simsun"),
1603
+ ]);
1604
+ const ZCommentContentItemSpacer = object({
1605
+ type: literal("spacer"),
1606
+ char: string(),
1607
+ charWidth: number(),
1608
+ isButton: optional(_boolean()),
1609
+ font: optional(ZCommentFlashFont),
1610
+ count: number(),
1611
+ });
1612
+ const ZCommentContentItemText = object({
1613
+ type: literal("text"),
1614
+ content: string(),
1615
+ slicedContent: array(string()),
1616
+ isButton: optional(_boolean()),
1617
+ font: optional(ZCommentFlashFont),
1618
+ width: optional(array(number())),
1619
+ });
1620
+ const ZCommentContentItem = union([
1621
+ ZCommentContentItemSpacer,
1622
+ ZCommentContentItemText,
1623
+ ]);
1624
+ const ZCommentMeasuredContentItemText = intersect([
1625
+ ZCommentContentItem,
1626
+ object({
1627
+ width: array(number()),
1628
+ }),
1629
+ ]);
1630
+ const ZCommentMeasuredContentItem = union([
1631
+ ZCommentMeasuredContentItemText,
1632
+ ZCommentContentItemSpacer,
1633
+ ]);
1634
+ const ZCommentSize = union([
1635
+ literal("big"),
1636
+ literal("medium"),
1637
+ literal("small"),
1638
+ ]);
1639
+ const ZCommentLoc = union([
1640
+ literal("ue"),
1641
+ literal("naka"),
1642
+ literal("shita"),
1643
+ ]);
1644
+ const ZMeasureInput = object({
1645
+ font: ZCommentFont,
1646
+ content: array(ZCommentContentItem),
1647
+ lineHeight: number(),
1648
+ charSize: number(),
1649
+ lineCount: number(),
1650
+ });
1651
+
209
1652
  const colors = {
210
1653
  white: "#FFFFFF",
211
1654
  red: "#FF0000",
@@ -246,79 +1689,18 @@
246
1689
  const isObject = (i) => typeof i === "object";
247
1690
  const typeGuard = {
248
1691
  formatted: {
249
- comment: (i) => objectVerify(i, [
250
- "id",
251
- "vpos",
252
- "content",
253
- "date",
254
- "date_usec",
255
- "owner",
256
- "premium",
257
- "mail",
258
- "user_id",
259
- "layer",
260
- "is_my_post",
261
- ]),
262
- comments: (i) => {
263
- if (typeof i !== "object")
264
- return false;
265
- for (const item of i) {
266
- if (!typeGuard.formatted.comment(item))
267
- return false;
268
- }
269
- return true;
270
- },
271
- legacyComment: (i) => objectVerify(i, [
272
- "id",
273
- "vpos",
274
- "content",
275
- "date",
276
- "owner",
277
- "premium",
278
- "mail",
279
- ]),
280
- legacyComments: (i) => {
281
- if (typeof i !== "object")
282
- return false;
283
- for (const item of i) {
284
- if (!typeGuard.formatted.legacyComment(item))
285
- return false;
286
- }
287
- return true;
288
- },
1692
+ comment: (i) => is(ZFormattedComment, i),
1693
+ comments: (i) => is(array(ZFormattedComment), i),
1694
+ legacyComment: (i) => is(ZFormattedLegacyComment, i),
1695
+ legacyComments: (i) => is(array(ZFormattedLegacyComment), i),
289
1696
  },
290
1697
  legacy: {
291
- rawApiResponses: (i) => {
292
- if (typeof i !== "object")
293
- return false;
294
- for (const itemWrapper of i) {
295
- for (const key of Object.keys(itemWrapper)) {
296
- const item = itemWrapper[key];
297
- if (!item)
298
- continue;
299
- if (!(typeGuard.legacy.apiChat(item) ||
300
- typeGuard.legacy.apiGlobalNumRes(item) ||
301
- typeGuard.legacy.apiLeaf(item) ||
302
- typeGuard.legacy.apiPing(item) ||
303
- typeGuard.legacy.apiThread(item))) {
304
- return false;
305
- }
306
- }
307
- }
308
- return true;
309
- },
310
- apiChat: (i) => typeof i === "object" &&
311
- objectVerify(i, ["content", "date", "no", "thread", "vpos"]),
312
- apiGlobalNumRes: (i) => objectVerify(i, ["num_res", "thread"]),
313
- apiLeaf: (i) => objectVerify(i, ["count", "thread"]),
314
- apiPing: (i) => objectVerify(i, ["content"]),
315
- apiThread: (i) => objectVerify(i, [
316
- "resultcode",
317
- "revision",
318
- "server_time",
319
- "thread",
320
- "ticket",
321
- ]),
1698
+ rawApiResponses: (i) => is(array(ZRawApiResponse), i),
1699
+ apiChat: (i) => is(ZApiChat, i),
1700
+ apiGlobalNumRes: (i) => is(ZApiGlobalNumRes, i),
1701
+ apiLeaf: (i) => is(ZApiLeaf, i),
1702
+ apiPing: (i) => is(ZApiPing, i),
1703
+ apiThread: (i) => is(ZApiThread, i),
322
1704
  },
323
1705
  xmlDocument: (i) => {
324
1706
  if (!i.documentElement ||
@@ -335,91 +1717,59 @@
335
1717
  return true;
336
1718
  },
337
1719
  legacyOwner: {
338
- comments: (i) => {
339
- if (typeof i !== "string")
340
- return false;
341
- const lists = i.split("\n");
342
- for (const list of lists) {
343
- if (list.split(":").length < 3) {
344
- return false;
1720
+ comments: (i) => is(string([
1721
+ custom((i) => {
1722
+ const lists = i.split(/\r\n|\r|\n/);
1723
+ for (const list of lists) {
1724
+ if (list.split(":").length < 3) {
1725
+ return false;
1726
+ }
345
1727
  }
346
- }
347
- return true;
348
- },
1728
+ return true;
1729
+ }),
1730
+ ]), i),
349
1731
  },
350
1732
  owner: {
351
- comment: (i) => objectVerify(i, ["time", "command", "comment"]),
352
- comments: (i) => {
353
- if (typeof i !== "object")
354
- return false;
355
- for (const item of i) {
356
- if (!typeGuard.owner.comment(item))
357
- return false;
358
- }
359
- return true;
360
- },
1733
+ comment: (i) => is(ZOwnerComment, i),
1734
+ comments: (i) => is(array(ZOwnerComment), i),
361
1735
  },
362
1736
  v1: {
363
- comment: (i) => objectVerify(i, [
364
- "id",
365
- "no",
366
- "vposMs",
367
- "body",
368
- "commands",
369
- "userId",
370
- "isPremium",
371
- "score",
372
- "postedAt",
373
- "nicoruCount",
374
- "nicoruId",
375
- "source",
376
- "isMyPost",
377
- ]),
378
- thread: (i) => {
379
- if (!objectVerify(i, ["id", "fork", "commentCount", "comments"]))
380
- return false;
381
- for (const value of i.comments) {
382
- if (!typeGuard.v1.comment(value))
383
- return false;
384
- }
385
- return true;
386
- },
387
- threads: (i) => {
388
- if (typeof i !== "object")
389
- return false;
390
- for (const item of i) {
391
- if (!typeGuard.v1.thread(item))
392
- return false;
393
- }
394
- return true;
395
- },
1737
+ comment: (i) => is(ZV1Comment, i),
1738
+ comments: (i) => is(array(ZV1Comment), i),
1739
+ thread: (i) => is(ZV1Thread, i),
1740
+ threads: (i) => is(array(ZV1Thread), i),
396
1741
  },
397
1742
  nicoScript: {
398
1743
  range: {
399
- target: (i) => typeof i === "string" &&
400
- !!RegExp(/^(?:\u6295?\u30b3\u30e1|\u5168)$/).exec(i),
1744
+ target: (i) => is(string([regex(/^(?:\u6295?\u30b3\u30e1|\u5168)$/)]), i),
401
1745
  },
402
1746
  replace: {
403
- range: (i) => typeof i === "string" && !!RegExp(/^[\u5358\u5168]$/).exec(i),
404
- target: (i) => typeof i === "string" &&
405
- !!RegExp(/^(?:\u30b3\u30e1|\u6295\u30b3\u30e1|\u5168|\u542b\u3080|\u542b\u307e\u306a\u3044)$/).exec(i),
406
- condition: (i) => typeof i === "string" &&
407
- !!RegExp(/^(?:\u90e8\u5206\u4e00\u81f4|\u5b8c\u5168\u4e00\u81f4)$/).exec(i),
1747
+ range: (i) => is(string([regex(/^[\u5358\u5168]$/)]), i),
1748
+ target: (i) => is(string([
1749
+ regex(/^(?:\u30b3\u30e1|\u6295\u30b3\u30e1|\u5168|\u542b\u3080|\u542b\u307e\u306a\u3044)$/),
1750
+ ]), i),
1751
+ condition: (i) => is(string([
1752
+ regex(/^(?:\u90e8\u5206\u4e00\u81f4|\u5b8c\u5168\u4e00\u81f4)$/),
1753
+ ]), i),
408
1754
  },
409
1755
  },
410
1756
  comment: {
411
- font: (i) => typeof i === "string" && !!RegExp(/^(?:gothic|mincho|defont)$/).exec(i),
412
- loc: (i) => typeof i === "string" && !!RegExp(/^(?:ue|naka|shita)$/).exec(i),
413
- size: (i) => typeof i === "string" && !!RegExp(/^(?:big|medium|small)$/).exec(i),
1757
+ font: (i) => is(ZCommentFont, i),
1758
+ loc: (i) => is(ZCommentLoc, i),
1759
+ size: (i) => is(ZCommentSize, i),
414
1760
  command: {
415
- key: (i) => typeof i === "string" &&
416
- !!RegExp(/^(?:full|ender|_live|invisible)$/).exec(i),
1761
+ key: (i) => is(union([
1762
+ literal("full"),
1763
+ literal("ender"),
1764
+ literal("_live"),
1765
+ literal("invisible"),
1766
+ ]), i),
417
1767
  },
418
- color: (i) => typeof i === "string" && Object.keys(colors).includes(i),
419
- colorCode: (i) => typeof i === "string" &&
420
- !!RegExp(/^#(?:[0-9a-z]{3}|[0-9a-z]{6})$/).exec(i),
421
- colorCodeAllowAlpha: (i) => typeof i === "string" &&
422
- !!RegExp(/^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/).exec(i),
1768
+ color: (i) => is(string([custom((i) => Object.keys(colors).includes(i))]), i),
1769
+ colorCode: (i) => is(string([regex(/^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6})$/)]), i),
1770
+ colorCodeAllowAlpha: (i) => is(string([
1771
+ regex(/^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/),
1772
+ ]), i),
423
1773
  },
424
1774
  config: {
425
1775
  initOptions: (item) => {
@@ -452,25 +1802,18 @@
452
1802
  },
453
1803
  },
454
1804
  internal: {
455
- CommentMeasuredContentItem: (i) => objectVerify(i, ["content", "slicedContent", "width"]),
456
- CommentMeasuredContentItemArray: (i) => Array.isArray(i) &&
457
- i.every(typeGuard.internal.CommentMeasuredContentItem),
1805
+ CommentMeasuredContentItem: (i) => is(ZCommentMeasuredContentItem, i),
1806
+ CommentMeasuredContentItemArray: (i) => is(array(ZCommentMeasuredContentItem), i),
458
1807
  MultiConfigItem: (i) => typeof i === "object" && objectVerify(i, ["html5", "flash"]),
459
- HTML5Fonts: (i) => i === "defont" || i === "mincho" || i === "gothic",
460
- MeasureInput: (i) => objectVerify(i, [
461
- "font",
462
- "content",
463
- "lineHeight",
464
- "charSize",
465
- "lineCount",
466
- ]),
1808
+ HTML5Fonts: (i) => is(ZHTML5Fonts, i),
1809
+ MeasureInput: (i) => is(ZMeasureInput, i),
467
1810
  },
468
1811
  };
469
1812
  const objectVerify = (item, keys) => {
470
1813
  if (typeof item !== "object" || !item)
471
1814
  return false;
472
1815
  for (const key of keys) {
473
- if (!Object.prototype.hasOwnProperty.call(item, key))
1816
+ if (!Object.hasOwn(item, key))
474
1817
  return false;
475
1818
  }
476
1819
  return true;
@@ -576,12 +1919,12 @@
576
1919
  };
577
1920
  const parseBrackets = (input) => {
578
1921
  const content = input.split(""), result = [];
579
- let quote = "", last_i = "", string = "";
1922
+ let quote = "", lastChar = "", string = "";
580
1923
  for (const i of content) {
581
1924
  if (RegExp(/^["'\u300c]$/).exec(i) && quote === "") {
582
1925
  quote = i;
583
1926
  }
584
- else if (RegExp(/^["']$/).exec(i) && quote === i && last_i !== "\\") {
1927
+ else if (RegExp(/^["']$/).exec(i) && quote === i && lastChar !== "\\") {
585
1928
  result.push(string.replaceAll("\\n", "\n"));
586
1929
  quote = "";
587
1930
  string = "";
@@ -600,7 +1943,7 @@
600
1943
  else {
601
1944
  string += i;
602
1945
  }
603
- last_i = i;
1946
+ lastChar = i;
604
1947
  }
605
1948
  result.push(string);
606
1949
  return result;
@@ -798,11 +2141,11 @@
798
2141
  result.fillColor ??= fillColor;
799
2142
  return;
800
2143
  }
801
- if (typeGuard.comment.loc(command)) {
2144
+ if (is(ZCommentLoc, command)) {
802
2145
  result.loc ??= command;
803
2146
  return;
804
2147
  }
805
- if (result.size === undefined && typeGuard.comment.size(command)) {
2148
+ if (result.size === undefined && is(ZCommentSize, command)) {
806
2149
  result.size = command;
807
2150
  result.fontSize = getConfig(config.fontSize, isFlash)[command].default;
808
2151
  return;
@@ -816,7 +2159,7 @@
816
2159
  result.color ??= colorCode[0].toUpperCase();
817
2160
  return;
818
2161
  }
819
- if (typeGuard.comment.font(command)) {
2162
+ if (is(ZCommentFont, command)) {
820
2163
  result.font ??= command;
821
2164
  return;
822
2165
  }
@@ -876,10 +2219,10 @@
876
2219
  }
877
2220
  for (let j = 0; j < comment.long; j++) {
878
2221
  const vpos = comment.vpos + j;
879
- ArrayPush(timeline, vpos, comment);
2222
+ arrayPush(timeline, vpos, comment);
880
2223
  if (j > comment.long - 20)
881
2224
  continue;
882
- ArrayPush(collision, vpos, comment);
2225
+ arrayPush(collision, vpos, comment);
883
2226
  }
884
2227
  comment.posY = posY;
885
2228
  };
@@ -890,26 +2233,25 @@
890
2233
  return (comment.height - config.canvasHeight) / -2;
891
2234
  }
892
2235
  let posY = 0;
893
- let isChanged = true, count = 0;
894
- while (isChanged && count < 10) {
2236
+ let isChanged = true;
2237
+ while (isChanged) {
895
2238
  isChanged = false;
896
- count++;
897
2239
  for (let j = beforeVpos, n = comment.long + 125; j < n; j++) {
898
2240
  const vpos = comment.vpos + j;
899
- const left_pos = getPosX(comment.comment, vpos);
2241
+ const leftPos = getPosX(comment.comment, vpos);
900
2242
  let isBreak = false;
901
- if (left_pos + comment.width >= config.collisionRange.right &&
902
- left_pos <= config.collisionRange.right) {
2243
+ if (leftPos + comment.width >= config.collisionRange.right &&
2244
+ leftPos <= config.collisionRange.right) {
903
2245
  const result = getPosY(posY, comment, collision.right[vpos]);
904
2246
  posY = result.currentPos;
905
- isChanged = result.isChanged;
2247
+ isChanged ||= result.isChanged;
906
2248
  isBreak = result.isBreak;
907
2249
  }
908
- if (left_pos + comment.width >= config.collisionRange.left &&
909
- left_pos <= config.collisionRange.left) {
2250
+ if (leftPos + comment.width >= config.collisionRange.left &&
2251
+ leftPos <= config.collisionRange.left) {
910
2252
  const result = getPosY(posY, comment, collision.left[vpos]);
911
2253
  posY = result.currentPos;
912
- isChanged = result.isChanged;
2254
+ isChanged ||= result.isChanged;
913
2255
  isBreak = result.isBreak;
914
2256
  }
915
2257
  if (isBreak)
@@ -920,21 +2262,23 @@
920
2262
  })();
921
2263
  for (let j = beforeVpos, n = comment.long + 125; j < n; j++) {
922
2264
  const vpos = comment.vpos + j;
923
- const left_pos = getPosX(comment.comment, vpos);
924
- ArrayPush(timeline, vpos, comment);
925
- if (left_pos + comment.width >= config.collisionRange.right &&
926
- left_pos <= config.collisionRange.right) {
927
- ArrayPush(collision.right, vpos, comment);
2265
+ const leftPos = getPosX(comment.comment, vpos);
2266
+ arrayPush(timeline, vpos, comment);
2267
+ if (leftPos + comment.width + config.collisionPadding >=
2268
+ config.collisionRange.right &&
2269
+ leftPos <= config.collisionRange.right) {
2270
+ arrayPush(collision.right, vpos, comment);
928
2271
  }
929
- if (left_pos + comment.width >= config.collisionRange.left &&
930
- left_pos <= config.collisionRange.left) {
931
- ArrayPush(collision.left, vpos, comment);
2272
+ if (leftPos + comment.width + config.collisionPadding >=
2273
+ config.collisionRange.left &&
2274
+ leftPos <= config.collisionRange.left) {
2275
+ arrayPush(collision.left, vpos, comment);
932
2276
  }
933
2277
  }
934
2278
  comment.posY = posY;
935
2279
  };
936
- const getPosY = (currentPos, targetComment, collision) => {
937
- let isChanged = false, isBreak = false;
2280
+ const getPosY = (currentPos, targetComment, collision, isChanged = false) => {
2281
+ let isBreak = false;
938
2282
  if (!collision)
939
2283
  return { currentPos, isChanged, isBreak };
940
2284
  for (const collisionItem of collision) {
@@ -961,6 +2305,7 @@
961
2305
  isBreak = true;
962
2306
  break;
963
2307
  }
2308
+ return getPosY(currentPos, targetComment, collision, true);
964
2309
  }
965
2310
  }
966
2311
  return { currentPos, isChanged, isBreak };
@@ -984,12 +2329,12 @@
984
2329
  switch (font) {
985
2330
  case "gulim":
986
2331
  case "simsun":
987
- return config.font[font].replace("[size]", `${size}`);
2332
+ return config.fonts.flash[font].replace("[size]", `${size}`);
988
2333
  case "gothic":
989
2334
  case "mincho":
990
- return `${config.fonts[font].weight} ${size}px ${config.fonts[font].font}`;
2335
+ return `${config.fonts.html5[font].weight} ${size}px ${config.fonts.html5[font].font}`;
991
2336
  default:
992
- return `${config.fonts.defont.weight} ${size}px ${config.fonts.defont.font}`;
2337
+ return `${config.fonts.html5.defont.weight} ${size}px ${config.fonts.html5.defont.font}`;
993
2338
  }
994
2339
  };
995
2340
 
@@ -1026,7 +2371,7 @@
1026
2371
  const index = {};
1027
2372
  return comments.filter((comment) => {
1028
2373
  const key = `${comment.content}@@${[...comment.mail]
1029
- .sort()
2374
+ .sort((a, b) => a.localeCompare(b))
1030
2375
  .filter((e) => !RegExp(/@[\d.]+|184|device:.+|patissier|ca/).exec(e))
1031
2376
  .join("")}`, lastComment = index[key];
1032
2377
  if (lastComment === undefined) {
@@ -1151,10 +2496,18 @@
1151
2496
  for (const line of lines) {
1152
2497
  const lineContent = parseLine(line);
1153
2498
  const firstContent = lineContent[0];
1154
- if (firstContent?.font) {
2499
+ const defaultFont = firstContent?.font;
2500
+ if (defaultFont) {
1155
2501
  results.push(...lineContent.map((val) => {
1156
- if (!val.font) {
1157
- val.font = firstContent.font;
2502
+ val.font ??= defaultFont;
2503
+ if (val.type === "spacer") {
2504
+ const spacer = config.compatSpacer.flash[val.char];
2505
+ if (!spacer)
2506
+ return val;
2507
+ const width = spacer[val.font];
2508
+ if (!width)
2509
+ return val;
2510
+ val.charWidth = width;
1158
2511
  }
1159
2512
  return val;
1160
2513
  }));
@@ -1170,24 +2523,51 @@
1170
2523
  const lineContent = [];
1171
2524
  for (const part of parts) {
1172
2525
  if (part.match(/[ -~。-゚]+/g) !== null) {
1173
- lineContent.push({ content: part, slicedContent: part.split("\n") });
2526
+ addPartToResult(lineContent, part, "defont");
1174
2527
  continue;
1175
2528
  }
1176
2529
  parseFullWidthPart(part, lineContent);
1177
2530
  }
1178
2531
  return lineContent;
1179
2532
  };
2533
+ const addPartToResult = (lineContent, part, font) => {
2534
+ if (part === "")
2535
+ return;
2536
+ for (const key of Object.keys(config.compatSpacer.flash)) {
2537
+ const spacerWidth = config.compatSpacer.flash[key]?.[font ?? "defont"];
2538
+ if (!spacerWidth)
2539
+ continue;
2540
+ const compatIndex = part.indexOf(key);
2541
+ if (compatIndex >= 0) {
2542
+ addPartToResult(lineContent, part.slice(0, compatIndex), font);
2543
+ let i = compatIndex;
2544
+ for (; i < part.length && part[i] === key; i++) {
2545
+ }
2546
+ lineContent.push({
2547
+ type: "spacer",
2548
+ char: key,
2549
+ charWidth: spacerWidth,
2550
+ font,
2551
+ count: i - compatIndex,
2552
+ });
2553
+ addPartToResult(lineContent, part.slice(i), font);
2554
+ return;
2555
+ }
2556
+ }
2557
+ lineContent.push({
2558
+ type: "text",
2559
+ content: part,
2560
+ slicedContent: part.split("\n"),
2561
+ font,
2562
+ });
2563
+ };
1180
2564
  const parseFullWidthPart = (part, lineContent) => {
1181
2565
  const index = getFlashFontIndex(part);
1182
2566
  if (index.length === 0) {
1183
- lineContent.push({ content: part, slicedContent: part.split("\n") });
2567
+ addPartToResult(lineContent, part);
1184
2568
  }
1185
2569
  else if (index.length === 1 && index[0]) {
1186
- lineContent.push({
1187
- content: part,
1188
- slicedContent: part.split("\n"),
1189
- font: getFlashFontName(index[0].font),
1190
- });
2570
+ addPartToResult(lineContent, part, getFlashFontName(index[0].font));
1191
2571
  }
1192
2572
  else {
1193
2573
  parseMultiFontFullWidthPart(part, index, lineContent);
@@ -1195,59 +2575,36 @@
1195
2575
  };
1196
2576
  const parseMultiFontFullWidthPart = (part, index, lineContent) => {
1197
2577
  index.sort(nativeSort((val) => val.index));
1198
- if (config.FlashMode === "xp") {
2578
+ if (config.flashMode === "xp") {
1199
2579
  let offset = 0;
1200
2580
  for (let i = 1, n = index.length; i < n; i++) {
1201
2581
  const currentVal = index[i], lastVal = index[i - 1];
1202
2582
  if (currentVal === undefined || lastVal === undefined)
1203
2583
  continue;
1204
2584
  const content = part.slice(offset, currentVal.index);
1205
- lineContent.push({
1206
- content: content,
1207
- slicedContent: content.split("\n"),
1208
- font: getFlashFontName(lastVal.font),
1209
- });
2585
+ addPartToResult(lineContent, content, getFlashFontName(lastVal.font));
1210
2586
  offset = currentVal.index;
1211
2587
  }
1212
2588
  const val = index[index.length - 1];
1213
2589
  if (val) {
1214
2590
  const content = part.slice(offset);
1215
- lineContent.push({
1216
- content: content,
1217
- slicedContent: content.split("\n"),
1218
- font: getFlashFontName(val.font),
1219
- });
2591
+ addPartToResult(lineContent, content, getFlashFontName(val.font));
1220
2592
  }
1221
2593
  return;
1222
2594
  }
1223
2595
  const firstVal = index[0], secondVal = index[1];
1224
2596
  if (!firstVal || !secondVal) {
1225
- lineContent.push({
1226
- content: part,
1227
- slicedContent: part.split("\n"),
1228
- });
2597
+ addPartToResult(lineContent, part);
1229
2598
  return;
1230
2599
  }
1231
2600
  if (firstVal.font !== "gothic") {
1232
- lineContent.push({
1233
- content: part,
1234
- slicedContent: part.split("\n"),
1235
- font: getFlashFontName(firstVal.font),
1236
- });
2601
+ addPartToResult(lineContent, part, getFlashFontName(firstVal.font));
1237
2602
  return;
1238
2603
  }
1239
2604
  const firstContent = part.slice(0, secondVal.index);
1240
2605
  const secondContent = part.slice(secondVal.index);
1241
- lineContent.push({
1242
- content: firstContent,
1243
- slicedContent: firstContent.split("\n"),
1244
- font: getFlashFontName(firstVal.font),
1245
- });
1246
- lineContent.push({
1247
- content: secondContent,
1248
- slicedContent: secondContent.split("\n"),
1249
- font: getFlashFontName(secondVal.font),
1250
- });
2606
+ addPartToResult(lineContent, firstContent, getFlashFontName(firstVal.font));
2607
+ addPartToResult(lineContent, secondContent, getFlashFontName(secondVal.font));
1251
2608
  };
1252
2609
  const getButtonParts = (comment) => {
1253
2610
  let leftParts = undefined;
@@ -1256,12 +2613,16 @@
1256
2613
  const lineOffset = comment.lineOffset;
1257
2614
  const lineHeight = comment.fontSize * comment.lineHeight;
1258
2615
  const offsetKey = comment.resizedY ? "resized" : "default";
1259
- const offsetY = config.commentYPaddingTop[offsetKey] +
2616
+ const offsetY = config.flashCommentYPaddingTop[offsetKey] +
1260
2617
  comment.fontSize *
1261
2618
  comment.lineHeight *
1262
- config.commentYOffset[comment.size][offsetKey];
2619
+ config.flashCommentYOffset[comment.size][offsetKey];
1263
2620
  let leftOffset = 0, lineCount = 0, isLastButton = false;
1264
2621
  for (const item of comment.content) {
2622
+ if (item.type === "spacer") {
2623
+ leftOffset += item.count * comment.fontSize * item.charWidth;
2624
+ continue;
2625
+ }
1265
2626
  const lines = item.slicedContent;
1266
2627
  for (let j = 0, n = lines.length; j < n; j++) {
1267
2628
  const line = lines[j];
@@ -1360,39 +2721,75 @@
1360
2721
  TypeGuardError.prototype.name = "TypeGuardError";
1361
2722
 
1362
2723
  const getLineHeight = (fontSize, isFlash, resized = false) => {
1363
- const lineCounts = getConfig(config.lineCounts, isFlash), CommentStageSize = getConfig(config.CommentStageSize, isFlash), lineHeight = CommentStageSize.height / lineCounts.doubleResized[fontSize], defaultLineCount = lineCounts.default[fontSize];
2724
+ const lineCounts = getConfig(config.html5LineCounts, isFlash), commentStageSize = getConfig(config.commentStageSize, isFlash), lineHeight = commentStageSize.height / lineCounts.doubleResized[fontSize], defaultLineCount = lineCounts.default[fontSize];
1364
2725
  if (resized) {
1365
2726
  const resizedLineCount = lineCounts.resized[fontSize];
1366
- return ((CommentStageSize.height -
2727
+ return ((commentStageSize.height -
1367
2728
  lineHeight * (defaultLineCount / resizedLineCount)) /
1368
2729
  (resizedLineCount - 1));
1369
2730
  }
1370
- return (CommentStageSize.height - lineHeight) / (defaultLineCount - 1);
2731
+ return (commentStageSize.height - lineHeight) / (defaultLineCount - 1);
1371
2732
  };
1372
2733
  const getCharSize = (fontSize, isFlash) => {
1373
- const lineCounts = getConfig(config.lineCounts, isFlash), CommentStageSize = getConfig(config.CommentStageSize, isFlash);
1374
- return CommentStageSize.height / lineCounts.doubleResized[fontSize];
2734
+ const lineCounts = getConfig(config.html5LineCounts, isFlash), commentStageSize = getConfig(config.commentStageSize, isFlash);
2735
+ return commentStageSize.height / lineCounts.doubleResized[fontSize];
1375
2736
  };
1376
- const measure = (comment, context) => {
1377
- const width = measureWidth(comment, context);
2737
+ const measure = (comment, renderer) => {
2738
+ const width = measureWidth(comment, renderer);
1378
2739
  return {
1379
2740
  ...width,
1380
2741
  height: comment.lineHeight * (comment.lineCount - 1) + comment.charSize,
1381
2742
  };
1382
2743
  };
1383
- const measureWidth = (comment, context) => {
2744
+ const addHTML5PartToResult = (lineContent, part, font) => {
2745
+ if (part === "")
2746
+ return;
2747
+ font ??= "defont";
2748
+ for (const key of Object.keys(config.compatSpacer.html5)) {
2749
+ const spacerWidth = config.compatSpacer.html5[key]?.[font];
2750
+ if (!spacerWidth)
2751
+ continue;
2752
+ const compatIndex = part.indexOf(key);
2753
+ if (compatIndex >= 0) {
2754
+ addHTML5PartToResult(lineContent, part.slice(0, compatIndex), font);
2755
+ let i = compatIndex;
2756
+ for (; i < part.length && part[i] === key; i++) {
2757
+ }
2758
+ lineContent.push({
2759
+ type: "spacer",
2760
+ char: key,
2761
+ charWidth: spacerWidth,
2762
+ count: i - compatIndex,
2763
+ });
2764
+ addHTML5PartToResult(lineContent, part.slice(i), font);
2765
+ return;
2766
+ }
2767
+ }
2768
+ lineContent.push({
2769
+ type: "text",
2770
+ content: part,
2771
+ slicedContent: part.split("\n"),
2772
+ });
2773
+ };
2774
+ const measureWidth = (comment, renderer) => {
1384
2775
  const { fontSize, scale } = getFontSizeAndScale(comment.charSize), lineWidth = [], itemWidth = [];
1385
- context.font = parseFont(comment.font, fontSize);
2776
+ renderer.setFont(parseFont(comment.font, fontSize));
1386
2777
  let currentWidth = 0;
1387
2778
  for (const item of comment.content) {
2779
+ if (item.type === "spacer") {
2780
+ currentWidth += item.count * fontSize * item.charWidth;
2781
+ itemWidth.push([item.count * fontSize * item.charWidth]);
2782
+ lineWidth.push(Math.ceil(currentWidth * scale));
2783
+ continue;
2784
+ }
1388
2785
  const lines = item.content.split("\n");
1389
- context.font = parseFont(item.font ?? comment.font, fontSize);
2786
+ renderer.setFont(parseFont(item.font ?? comment.font, fontSize));
1390
2787
  const width = [];
1391
2788
  for (let j = 0, n = lines.length; j < n; j++) {
1392
2789
  const line = lines[j];
1393
2790
  if (line === undefined)
1394
2791
  throw new TypeGuardError();
1395
- const measure = context.measureText(line);
2792
+ const measure = renderer.measureText(line);
1396
2793
  currentWidth += measure.width;
1397
2794
  width.push(measure.width);
1398
2795
  if (j < lines.length - 1) {
@@ -1411,12 +2808,12 @@
1411
2808
  };
1412
2809
  const getFontSizeAndScale = (charSize) => {
1413
2810
  charSize *= 0.8;
1414
- if (charSize < config.minFontSize) {
2811
+ if (charSize < config.html5MinFontSize) {
1415
2812
  if (charSize >= 1)
1416
2813
  charSize = Math.floor(charSize);
1417
2814
  return {
1418
- scale: charSize / config.minFontSize,
1419
- fontSize: config.minFontSize,
2815
+ scale: charSize / config.html5MinFontSize,
2816
+ fontSize: config.html5MinFontSize,
1420
2817
  };
1421
2818
  }
1422
2819
  return {
@@ -1425,10 +2822,11 @@
1425
2822
  };
1426
2823
  };
1427
2824
 
1428
- var index$1 = /*#__PURE__*/Object.freeze({
2825
+ var index$2 = /*#__PURE__*/Object.freeze({
1429
2826
  __proto__: null,
1430
- ArrayEqual: ArrayEqual,
1431
- ArrayPush: ArrayPush,
2827
+ addHTML5PartToResult: addHTML5PartToResult,
2828
+ arrayEqual: arrayEqual,
2829
+ arrayPush: arrayPush,
1432
2830
  buildAtButtonComment: buildAtButtonComment,
1433
2831
  changeCALayer: changeCALayer,
1434
2832
  getButtonParts: getButtonParts,
@@ -1457,21 +2855,8 @@
1457
2855
  processMovableComment: processMovableComment
1458
2856
  });
1459
2857
 
1460
- const generateCanvas = () => {
1461
- return document.createElement("canvas");
1462
- };
1463
- const getContext = (canvas) => {
1464
- const context = canvas.getContext("2d");
1465
- if (!context)
1466
- throw new CanvasRenderingContext2DError();
1467
- return context;
1468
- };
1469
- const drawImage = (targetContext, sourceImage, x, y) => {
1470
- targetContext.drawImage(sourceImage, x, y);
1471
- };
1472
-
1473
2858
  class BaseComment {
1474
- context;
2859
+ renderer;
1475
2860
  cacheKey;
1476
2861
  comment;
1477
2862
  pos;
@@ -1479,16 +2864,13 @@
1479
2864
  pluginName = "BaseComment";
1480
2865
  image;
1481
2866
  buttonImage;
1482
- constructor(comment, context) {
1483
- this.context = context;
2867
+ constructor(comment, renderer) {
2868
+ this.renderer = renderer;
1484
2869
  this.posY = 0;
1485
2870
  this.pos = { x: 0, y: 0 };
1486
2871
  comment.content = comment.content.replace(/\t/g, "\u2003\u2003");
1487
2872
  this.comment = this.convertComment(comment);
1488
- this.cacheKey =
1489
- JSON.stringify(this.comment.content) +
1490
- `@@${this.pluginName}@@` +
1491
- [...this.comment.mail].sort().join(",");
2873
+ this.cacheKey = this.getCacheKey();
1492
2874
  }
1493
2875
  get invisible() {
1494
2876
  return this.comment.invisible;
@@ -1569,48 +2951,44 @@
1569
2951
  this.image = this.getTextImage();
1570
2952
  }
1571
2953
  if (this.image) {
1572
- this.context.save();
2954
+ this.renderer.save();
1573
2955
  if (this.comment._live) {
1574
- this.context.globalAlpha = config.contextFillLiveOpacity;
2956
+ this.renderer.setGlobalAlpha(config.contextFillLiveOpacity);
1575
2957
  }
1576
2958
  else {
1577
- this.context.globalAlpha = 1;
2959
+ this.renderer.setGlobalAlpha(1);
1578
2960
  }
1579
2961
  if (this.comment.button && !this.comment.button.hidden) {
1580
2962
  const button = this.getButtonImage(posX, posY, cursor);
1581
- button && drawImage(this.context, button, posX, posY);
2963
+ button && this.renderer.drawImage(button, posX, posY);
1582
2964
  }
1583
- drawImage(this.context, this.image, posX, posY);
1584
- this.context.restore();
2965
+ this.renderer.drawImage(this.image, posX, posY);
2966
+ this.renderer.restore();
1585
2967
  }
1586
2968
  }
1587
2969
  _drawRectColor(posX, posY) {
1588
2970
  if (this.comment.wakuColor) {
1589
- this.context.save();
1590
- this.context.strokeStyle = this.comment.wakuColor;
1591
- this.context.strokeRect(posX, posY, this.comment.width, this.comment.height);
1592
- this.context.restore();
2971
+ this.renderer.save();
2972
+ this.renderer.setStrokeStyle(this.comment.wakuColor);
2973
+ this.renderer.strokeRect(posX, posY, this.comment.width, this.comment.height);
2974
+ this.renderer.restore();
1593
2975
  }
1594
2976
  }
1595
2977
  _drawBackgroundColor(posX, posY) {
1596
2978
  if (this.comment.fillColor) {
1597
- this.context.save();
1598
- this.context.fillStyle = this.comment.fillColor;
1599
- this.context.fillRect(posX, posY, this.comment.width, this.comment.height);
1600
- this.context.restore();
2979
+ this.renderer.save();
2980
+ this.renderer.setFillStyle(this.comment.fillColor);
2981
+ this.renderer.fillRect(posX, posY, this.comment.width, this.comment.height);
2982
+ this.renderer.restore();
1601
2983
  }
1602
2984
  }
1603
2985
  _drawDebugInfo(posX, posY) {
1604
2986
  if (isDebug) {
1605
- this.context.save();
1606
- const font = this.context.font;
1607
- const fillStyle = this.context.fillStyle;
1608
- this.context.font = parseFont("defont", 30);
1609
- this.context.fillStyle = "#ff00ff";
1610
- this.context.fillText(this.comment.mail.join(","), posX, posY + 30);
1611
- this.context.font = font;
1612
- this.context.fillStyle = fillStyle;
1613
- this.context.restore();
2987
+ this.renderer.save();
2988
+ this.renderer.setFont(parseFont("defont", 30));
2989
+ this.renderer.setFillStyle("#ff00ff");
2990
+ this.renderer.fillText(this.comment.mail.join(","), posX, posY + 30);
2991
+ this.renderer.restore();
1614
2992
  }
1615
2993
  }
1616
2994
  _drawCollision(posX, posY, showCollision) {
@@ -1631,6 +3009,7 @@
1631
3009
  }, this.comment.long * 10 + config.cacheAge);
1632
3010
  clearTimeout(cache.timeout);
1633
3011
  cache.timeout = setTimeout(() => {
3012
+ imageCache[this.cacheKey]?.image.destroy();
1634
3013
  delete imageCache[this.cacheKey];
1635
3014
  }, this.comment.long * 10 + config.cacheAge);
1636
3015
  return cache.image;
@@ -1657,14 +3036,6 @@
1657
3036
  image,
1658
3037
  };
1659
3038
  }
1660
- createCanvas() {
1661
- const image = generateCanvas();
1662
- const context = getContext(image);
1663
- return {
1664
- image,
1665
- context,
1666
- };
1667
- }
1668
3039
  getButtonImage(posX, posY, cursor) {
1669
3040
  console.error("getButtonImage method is not implemented", posX, posY, cursor);
1670
3041
  throw new NotImplementedError(this.pluginName, "getButtonImage");
@@ -1673,6 +3044,11 @@
1673
3044
  console.error("isHovered method is not implemented", posX, posY, cursor);
1674
3045
  throw new NotImplementedError(this.pluginName, "getButtonImage");
1675
3046
  }
3047
+ getCacheKey() {
3048
+ return (JSON.stringify(this.comment.content) +
3049
+ `@@${this.pluginName}@@` +
3050
+ [...this.comment.mail].sort((a, b) => a.localeCompare(b)).join(","));
3051
+ }
1676
3052
  }
1677
3053
 
1678
3054
  const drawLeftBorder = (context, left, top, width, height, radius) => {
@@ -1712,13 +3088,10 @@
1712
3088
  _globalScale;
1713
3089
  pluginName = "FlashComment";
1714
3090
  buttonImage;
1715
- buttonContext;
1716
- constructor(comment, context) {
1717
- super(comment, context);
3091
+ constructor(comment, renderer) {
3092
+ super(comment, renderer);
1718
3093
  this._globalScale ??= getConfig(config.commentScale, true);
1719
- const button = this.createCanvas();
1720
- this.buttonImage = button.image;
1721
- this.buttonContext = button.context;
3094
+ this.buttonImage = renderer.getCanvas();
1722
3095
  }
1723
3096
  get content() {
1724
3097
  return this.comment.rawContent;
@@ -1737,10 +3110,7 @@
1737
3110
  comment.font = val.font;
1738
3111
  }
1739
3112
  this.comment = this.getCommentSize(comment);
1740
- this.cacheKey =
1741
- JSON.stringify(this.comment.content) +
1742
- `@@${this.pluginName}@@` +
1743
- [...this.comment.mail].sort((a, b) => a.localeCompare(b)).join(",");
3113
+ this.cacheKey = this.getCacheKey();
1744
3114
  delete this.image;
1745
3115
  }
1746
3116
  convertComment(comment) {
@@ -1764,14 +3134,14 @@
1764
3134
  content: [],
1765
3135
  };
1766
3136
  }
1767
- this.context.save();
1768
- this.context.font = parseFont(parsedData.font, parsedData.fontSize);
3137
+ this.renderer.save();
3138
+ this.renderer.setFont(parseFont(parsedData.font, parsedData.fontSize));
1769
3139
  const measure = this.measureText({ ...parsedData, scale: 1 });
1770
3140
  if (options.scale !== 1 && parsedData.layer === -1) {
1771
3141
  measure.height *= options.scale;
1772
3142
  measure.width *= options.scale;
1773
3143
  }
1774
- this.context.restore();
3144
+ this.renderer.restore();
1775
3145
  if (parsedData.button && !parsedData.button.hidden) {
1776
3146
  measure.width += getConfig(config.atButtonPadding, true) * 4;
1777
3147
  }
@@ -1818,12 +3188,12 @@
1818
3188
  ]
1819
3189
  : parseContent(input);
1820
3190
  const lineCount = (input.match(/\n/g)?.length ?? 0) + 1;
1821
- const lineOffset = (input.match(new RegExp(config.FlashScriptChar.super, "g"))?.length ??
3191
+ const lineOffset = (input.match(new RegExp(config.flashScriptChar.super, "g"))?.length ??
1822
3192
  0) *
1823
3193
  -1 *
1824
- config.scriptCharOffset +
1825
- (input.match(new RegExp(config.FlashScriptChar.sub, "g"))?.length ?? 0) *
1826
- config.scriptCharOffset;
3194
+ config.flashScriptCharOffset +
3195
+ (input.match(new RegExp(config.flashScriptChar.sub, "g"))?.length ?? 0) *
3196
+ config.flashScriptCharOffset;
1827
3197
  return {
1828
3198
  content,
1829
3199
  lineCount,
@@ -1831,51 +3201,41 @@
1831
3201
  };
1832
3202
  }
1833
3203
  measureText(comment) {
1834
- const configLineHeight = getConfig(config.lineHeight, true), configFontSize = getConfig(config.fontSize, true);
1835
- const lineCount = comment.lineCount;
3204
+ const configLineHeight = getConfig(config.lineHeight, true), configFontSize = getConfig(config.fontSize, true)[comment.size], configStageSize = getConfig(config.commentStageSize, true);
3205
+ const defaultFontSize = configFontSize.default;
1836
3206
  comment.lineHeight ??= configLineHeight[comment.size].default;
3207
+ const widthLimit = configStageSize[comment.full ? "fullWidth" : "width"];
3208
+ const { scaleX, width, height } = this._measureContent(comment);
3209
+ let scale = 1;
1837
3210
  if (isLineBreakResize(comment)) {
1838
- comment.fontSize = configFontSize[comment.size].resized;
1839
- comment.lineHeight = configLineHeight[comment.size].resized;
1840
3211
  comment.resized = true;
1841
3212
  comment.resizedY = true;
1842
- this.context.font = parseFont(comment.font, comment.fontSize);
1843
- }
1844
- const { width_arr, spacedWidth_arr } = this._measureContent(comment);
1845
- const leadLine = (function () {
1846
- let max = 0, index = -1;
1847
- spacedWidth_arr.forEach((val, i) => {
1848
- if (max < val) {
1849
- max = val;
1850
- index = i;
3213
+ const lineBreakScale = config.flashLineBreakScale[comment.size];
3214
+ const scaledWidth = width * lineBreakScale;
3215
+ if (comment.loc !== "naka" &&
3216
+ this._isDoubleResize(scaledWidth, widthLimit, comment.size, comment.lineCount, comment.full)) {
3217
+ if (scaledWidth > widthLimit) {
3218
+ const resizedFontSize = Math.round((widthLimit / scaledWidth) * defaultFontSize);
3219
+ const resizeRate = (resizedFontSize + 1) / (defaultFontSize + 1);
3220
+ scale *= resizeRate;
1851
3221
  }
1852
- });
1853
- return { max, index };
1854
- })();
1855
- const width = leadLine.max;
1856
- const scaleX = leadLine.max / (width_arr[leadLine.index] ?? 1);
1857
- const width_max = width * comment.scale;
1858
- const height = (comment.fontSize * comment.lineHeight * lineCount +
1859
- config.commentYPaddingTop[comment.resizedY ? "resized" : "default"]) *
1860
- comment.scale;
1861
- if (comment.loc !== "naka") {
1862
- const widthLimit = getConfig(config.CommentStageSize, true)[comment.full ? "fullWidth" : "width"];
1863
- if (width_max > widthLimit && !comment.resizedX) {
1864
- comment.fontSize = configFontSize[comment.size].default;
1865
- comment.lineHeight = configLineHeight[comment.size].default;
1866
- comment.scale = widthLimit / width_max;
1867
- comment.resizedX = true;
1868
- comment.resized = true;
1869
- return this.measureText(comment);
3222
+ }
3223
+ else {
3224
+ scale *= lineBreakScale;
1870
3225
  }
1871
3226
  }
3227
+ else if (comment.loc !== "naka" && width > widthLimit) {
3228
+ const resizeRate = (Math.round((widthLimit / width) * defaultFontSize) + 1) /
3229
+ (defaultFontSize + 1);
3230
+ scale *= resizeRate;
3231
+ }
3232
+ comment.scale = scale;
1872
3233
  if (!typeGuard.internal.CommentMeasuredContentItemArray(comment.content)) {
1873
3234
  throw new TypeGuardError();
1874
3235
  }
1875
3236
  return {
1876
- width: width_max,
1877
3237
  charSize: 0,
1878
- height: height,
3238
+ height: height * scale,
1879
3239
  resized: !!comment.resized,
1880
3240
  fontSize: comment.fontSize,
1881
3241
  lineHeight: comment.lineHeight,
@@ -1883,75 +3243,134 @@
1883
3243
  resizedX: !!comment.resizedX,
1884
3244
  resizedY: !!comment.resizedY,
1885
3245
  scale: comment.scale,
1886
- scaleX,
3246
+ scaleX: scaleX,
3247
+ width: width * scale,
1887
3248
  };
1888
3249
  }
3250
+ _isDoubleResize(width, widthLimit, size, lineCount, isFull) {
3251
+ if (width < widthLimit * 0.9 || widthLimit * 1.1 < width)
3252
+ return width > widthLimit;
3253
+ if (size === "big") {
3254
+ if (8 <= lineCount &&
3255
+ lineCount <= 14 &&
3256
+ !isFull &&
3257
+ widthLimit * 0.99 < width)
3258
+ return true;
3259
+ if (width <= widthLimit)
3260
+ return false;
3261
+ if (16 <= lineCount && width * 0.95 < widthLimit)
3262
+ return true;
3263
+ if (isFull) {
3264
+ if (width * 0.95 < widthLimit)
3265
+ return false;
3266
+ return width > widthLimit;
3267
+ }
3268
+ return true;
3269
+ }
3270
+ if (width <= widthLimit)
3271
+ return false;
3272
+ if (((size === "medium" && 25 <= lineCount) ||
3273
+ (size === "small" && 38 <= lineCount)) &&
3274
+ width * 0.95 < widthLimit)
3275
+ return false;
3276
+ return widthLimit < width;
3277
+ }
1889
3278
  _measureContent(comment) {
1890
- const width_arr = [], spacedWidth_arr = [];
3279
+ const widthArr = [], spacedWidthArr = [];
1891
3280
  let currentWidth = 0, spacedWidth = 0;
1892
3281
  for (const item of comment.content) {
3282
+ if (item.type === "spacer") {
3283
+ spacedWidth +=
3284
+ item.count * item.charWidth * comment.fontSize +
3285
+ Math.max(item.count - 1, 0) * config.flashLetterSpacing;
3286
+ currentWidth += item.count * item.charWidth * comment.fontSize;
3287
+ widthArr.push(currentWidth);
3288
+ spacedWidthArr.push(spacedWidth);
3289
+ continue;
3290
+ }
1893
3291
  const lines = item.content.split("\n");
1894
3292
  const widths = [];
1895
- this.context.font = parseFont(item.font ?? comment.font, comment.fontSize);
3293
+ this.renderer.setFont(parseFont(item.font ?? comment.font, comment.fontSize));
1896
3294
  for (let i = 0, n = lines.length; i < n; i++) {
1897
3295
  const value = lines[i];
1898
3296
  if (value === undefined)
1899
3297
  continue;
1900
- const measure = this.context.measureText(value);
3298
+ const measure = this.renderer.measureText(value);
1901
3299
  currentWidth += measure.width;
1902
3300
  spacedWidth +=
1903
- measure.width + Math.max(value.length - 1, 0) * config.letterSpacing;
3301
+ measure.width +
3302
+ Math.max(value.length - 1, 0) * config.flashLetterSpacing;
1904
3303
  widths.push(measure.width);
1905
3304
  if (i < lines.length - 1) {
1906
- width_arr.push(currentWidth);
1907
- spacedWidth_arr.push(spacedWidth);
3305
+ widthArr.push(currentWidth);
3306
+ spacedWidthArr.push(spacedWidth);
1908
3307
  spacedWidth = 0;
1909
3308
  currentWidth = 0;
1910
3309
  }
1911
3310
  }
1912
- width_arr.push(currentWidth);
1913
- spacedWidth_arr.push(spacedWidth);
3311
+ widthArr.push(currentWidth);
3312
+ spacedWidthArr.push(spacedWidth);
1914
3313
  item.width = widths;
1915
3314
  }
1916
- return { width_arr, spacedWidth_arr };
3315
+ const leadLine = (function () {
3316
+ let max = 0, index = -1;
3317
+ spacedWidthArr.forEach((val, i) => {
3318
+ if (max < val) {
3319
+ max = val;
3320
+ index = i;
3321
+ }
3322
+ });
3323
+ return { max, index };
3324
+ })();
3325
+ const scaleX = leadLine.max / (widthArr[leadLine.index] ?? 1);
3326
+ const width = leadLine.max * comment.scale;
3327
+ const height = (comment.fontSize * (comment.lineHeight ?? 0) * comment.lineCount +
3328
+ config.flashCommentYPaddingTop[comment.resizedY ? "resized" : "default"]) *
3329
+ comment.scale;
3330
+ return { scaleX, width, height };
1917
3331
  }
1918
3332
  _drawCollision(posX, posY, showCollision) {
1919
3333
  if (showCollision) {
1920
- this.context.save();
1921
- this.context.strokeStyle = "rgba(255,0,255,1)";
1922
- this.context.strokeRect(posX, posY, this.comment.width, this.comment.height);
3334
+ this.renderer.save();
3335
+ this.renderer.setStrokeStyle("rgba(255,0,255,1)");
3336
+ this.renderer.strokeRect(posX, posY, this.comment.width, this.comment.height);
1923
3337
  for (let i = 0, n = this.comment.lineCount; i < n; i++) {
1924
3338
  const linePosY = ((i + 1) * (this.comment.fontSize * this.comment.lineHeight) +
1925
- config.commentYPaddingTop[this.comment.resizedY ? "resized" : "default"]) *
3339
+ config.flashCommentYPaddingTop[this.comment.resizedY ? "resized" : "default"]) *
1926
3340
  this.comment.scale;
1927
- this.context.strokeStyle = `rgba(255,255,0,0.25)`;
1928
- this.context.strokeRect(posX, posY + linePosY * this._globalScale, this.comment.width, this.comment.fontSize *
3341
+ this.renderer.setStrokeStyle(`rgba(255,255,0,0.25)`);
3342
+ this.renderer.strokeRect(posX, posY + linePosY * this._globalScale, this.comment.width, this.comment.fontSize *
1929
3343
  this.comment.lineHeight *
1930
3344
  -1 *
1931
3345
  this._globalScale *
1932
3346
  this.comment.scale *
1933
3347
  (this.comment.layer === -1 ? options.scale : 1));
1934
3348
  }
1935
- this.context.restore();
3349
+ this.renderer.restore();
1936
3350
  }
1937
3351
  }
1938
3352
  _generateTextImage() {
1939
- const { image, context } = this.createCanvas();
1940
- this._setupCanvas(image, context);
3353
+ const renderer = this.renderer.getCanvas();
3354
+ this._setupCanvas(renderer);
1941
3355
  const atButtonPadding = getConfig(config.atButtonPadding, true);
1942
3356
  const lineOffset = this.comment.lineOffset;
1943
3357
  const lineHeight = this.comment.fontSize * this.comment.lineHeight;
1944
3358
  const offsetKey = this.comment.resizedY ? "resized" : "default";
1945
- const offsetY = config.commentYPaddingTop[offsetKey] +
3359
+ const offsetY = config.flashCommentYPaddingTop[offsetKey] +
1946
3360
  this.comment.fontSize *
1947
3361
  this.comment.lineHeight *
1948
- config.commentYOffset[this.comment.size][offsetKey];
3362
+ config.flashCommentYOffset[this.comment.size][offsetKey];
1949
3363
  let lastFont = this.comment.font, leftOffset = 0, lineCount = 0, isLastButton = false;
1950
3364
  for (const item of this.comment.content) {
3365
+ if (item.type === "spacer") {
3366
+ leftOffset += item.count * item.charWidth * this.comment.fontSize;
3367
+ isLastButton = !!item.isButton;
3368
+ continue;
3369
+ }
1951
3370
  const font = item.font ?? this.comment.font;
1952
3371
  if (lastFont !== font) {
1953
3372
  lastFont = font;
1954
- context.font = parseFont(font, this.comment.fontSize);
3373
+ renderer.setFont(parseFont(font, this.comment.fontSize));
1955
3374
  }
1956
3375
  const lines = item.slicedContent;
1957
3376
  for (let lineIndex = 0, lineLength = lines.length; lineIndex < lineLength; lineIndex++) {
@@ -1965,42 +3384,45 @@
1965
3384
  ((!isLastButton && item.isButton) || (isLastButton && !item.isButton))) {
1966
3385
  leftOffset += atButtonPadding * 2;
1967
3386
  }
1968
- context.strokeText(line, leftOffset, posY);
1969
- context.fillText(line, leftOffset, posY);
3387
+ renderer.strokeText(line, leftOffset, posY);
3388
+ renderer.fillText(line, leftOffset, posY);
3389
+ leftOffset += partWidth;
1970
3390
  if (lineIndex < lineLength - 1) {
1971
3391
  leftOffset = 0;
1972
3392
  lineCount += 1;
1973
- continue;
1974
3393
  }
1975
- leftOffset += partWidth;
1976
3394
  }
1977
3395
  isLastButton = !!item.isButton;
1978
3396
  }
1979
- return image;
3397
+ return renderer;
1980
3398
  }
1981
3399
  getButtonImage(posX, posY, cursor) {
1982
3400
  if (!this.comment.button || this.comment.button.hidden)
1983
3401
  return undefined;
1984
- const { image, context } = this._setupCanvas(this.buttonImage, this.buttonContext);
3402
+ const { renderer } = this._setupCanvas(this.buttonImage);
1985
3403
  const parts = this.comment.buttonObjects;
1986
3404
  if (!parts)
1987
3405
  return undefined;
1988
3406
  const atButtonRadius = getConfig(config.atButtonRadius, true);
1989
3407
  const isHover = this.isHovered(cursor, posX, posY);
1990
- context.save();
1991
- context.strokeStyle =
1992
- this.comment.button.limit < 1
1993
- ? "#777777"
1994
- : isHover
1995
- ? this.comment.color
1996
- : "white";
1997
- drawLeftBorder(context, parts.left.left, parts.left.top, parts.left.width, parts.left.height, atButtonRadius);
3408
+ renderer.save();
3409
+ const getStrokeStyle = () => {
3410
+ if (isHover) {
3411
+ return this.comment.color;
3412
+ }
3413
+ if (this.comment.button && this.comment.button.limit < 1) {
3414
+ return "#777777";
3415
+ }
3416
+ return "white";
3417
+ };
3418
+ renderer.setStrokeStyle(getStrokeStyle());
3419
+ drawLeftBorder(renderer, parts.left.left, parts.left.top, parts.left.width, parts.left.height, atButtonRadius);
1998
3420
  for (const part of parts.middle) {
1999
- drawMiddleBorder(context, part.left, part.top, part.width, part.height);
3421
+ drawMiddleBorder(renderer, part.left, part.top, part.width, part.height);
2000
3422
  }
2001
- drawRightBorder(context, parts.right.right, parts.right.top, parts.right.height, atButtonRadius);
2002
- context.restore();
2003
- return image;
3423
+ drawRightBorder(renderer, parts.right.right, parts.right.top, parts.right.height, atButtonRadius);
3424
+ renderer.restore();
3425
+ return renderer;
2004
3426
  }
2005
3427
  isHovered(_cursor, _posX, _posY) {
2006
3428
  if (!_cursor || !this.comment.buttonObjects)
@@ -2034,22 +3456,18 @@
2034
3456
  }
2035
3457
  return (between(cursor.x, posX + right.right - atButtonPadding, posX + right.right + getConfig(config.contextLineWidth, true) / 2) && between(cursor.y, posY + right.top, posY + right.top + right.height));
2036
3458
  }
2037
- _setupCanvas(image, context) {
3459
+ _setupCanvas(renderer) {
2038
3460
  const atButtonPadding = getConfig(config.atButtonPadding, true);
2039
- image.width = this.comment.width;
2040
- image.height =
2041
- this.comment.height + (this.comment.button ? atButtonPadding * 2 : 0);
2042
- context.strokeStyle = getStrokeColor(this.comment);
2043
- context.fillStyle = this.comment.color;
2044
- context.textAlign = "start";
2045
- context.textBaseline = "alphabetic";
2046
- context.lineWidth = getConfig(config.contextLineWidth, true);
2047
- context.font = parseFont(this.comment.font, this.comment.fontSize);
3461
+ renderer.setSize(this.comment.width, this.comment.height + (this.comment.button ? atButtonPadding * 2 : 0));
3462
+ renderer.setStrokeStyle(getStrokeColor(this.comment));
3463
+ renderer.setFillStyle(this.comment.color);
3464
+ renderer.setLineWidth(getConfig(config.contextLineWidth, true));
3465
+ renderer.setFont(parseFont(this.comment.font, this.comment.fontSize));
2048
3466
  const scale = this._globalScale *
2049
3467
  this.comment.scale *
2050
3468
  (this.comment.layer === -1 ? options.scale : 1);
2051
- context.scale(scale * this.comment.scaleX, scale);
2052
- return { image, context };
3469
+ renderer.setScale(scale * this.comment.scaleX, scale);
3470
+ return { renderer };
2053
3471
  }
2054
3472
  }
2055
3473
 
@@ -2072,10 +3490,7 @@
2072
3490
  lineOffset,
2073
3491
  };
2074
3492
  this.comment = this.getCommentSize(comment);
2075
- this.cacheKey =
2076
- JSON.stringify(this.comment.content) +
2077
- `@@${this.pluginName}@@` +
2078
- [...this.comment.mail].sort().join(",");
3493
+ this.cacheKey = this.getCacheKey();
2079
3494
  delete this.image;
2080
3495
  }
2081
3496
  convertComment(comment) {
@@ -2083,7 +3498,6 @@
2083
3498
  }
2084
3499
  getCommentSize(parsedData) {
2085
3500
  if (parsedData.invisible) {
2086
- this.context.restore();
2087
3501
  return {
2088
3502
  ...parsedData,
2089
3503
  height: 0,
@@ -2099,15 +3513,15 @@
2099
3513
  scale: 1,
2100
3514
  };
2101
3515
  }
2102
- this.context.save();
2103
- this.context.font = parseFont(parsedData.font, parsedData.fontSize);
3516
+ this.renderer.save();
3517
+ this.renderer.setFont(parseFont(parsedData.font, parsedData.fontSize));
2104
3518
  const measure = this.measureText({ ...parsedData, scale: 1 });
2105
3519
  if (options.scale !== 1 && parsedData.layer === -1) {
2106
3520
  measure.height *= options.scale;
2107
3521
  measure.width *= options.scale;
2108
3522
  measure.fontSize *= options.scale;
2109
3523
  }
2110
- this.context.restore();
3524
+ this.renderer.restore();
2111
3525
  return {
2112
3526
  ...parsedData,
2113
3527
  height: measure.height,
@@ -2125,7 +3539,7 @@
2125
3539
  }
2126
3540
  parseCommandAndNicoscript(comment) {
2127
3541
  const data = parseCommandAndNicoScript(comment);
2128
- const { content, lineCount, lineOffset } = this.parseContent(comment.content);
3542
+ const { content, lineCount, lineOffset } = this.parseContent(comment.content, data.font);
2129
3543
  return {
2130
3544
  ...comment,
2131
3545
  rawContent: comment.content,
@@ -2135,15 +3549,10 @@
2135
3549
  lineOffset,
2136
3550
  };
2137
3551
  }
2138
- parseContent(input) {
3552
+ parseContent(input, font) {
2139
3553
  const content = [];
2140
- content.push({
2141
- content: input,
2142
- slicedContent: input.split("\n"),
2143
- });
2144
- const lineCount = content.reduce((pv, val) => {
2145
- return pv + (val.content.match(/\n/g)?.length ?? 0);
2146
- }, 1);
3554
+ addHTML5PartToResult(content, input, font ?? "defont");
3555
+ const lineCount = input.split("\n").length;
2147
3556
  const lineOffset = 0;
2148
3557
  return {
2149
3558
  content,
@@ -2159,7 +3568,7 @@
2159
3568
  if (!comment.charSize)
2160
3569
  comment.charSize = charSize;
2161
3570
  comment.fontSize = comment.charSize * 0.8;
2162
- this.context.font = parseFont(comment.font, comment.fontSize);
3571
+ this.renderer.setFont(parseFont(comment.font, comment.fontSize));
2163
3572
  if (isLineBreakResize(comment)) {
2164
3573
  comment.fontSize = configFontSize[comment.size].resized;
2165
3574
  const lineHeight = getLineHeight(comment.size, false, true);
@@ -2171,7 +3580,7 @@
2171
3580
  const { width, height, itemWidth } = this._measureComment(comment);
2172
3581
  for (let i = 0, n = comment.content.length; i < n; i++) {
2173
3582
  const item = comment.content[i];
2174
- if (!item || !itemWidth)
3583
+ if (item?.type !== "text" || !itemWidth)
2175
3584
  continue;
2176
3585
  item.width = itemWidth[i];
2177
3586
  }
@@ -2194,17 +3603,17 @@
2194
3603
  };
2195
3604
  }
2196
3605
  _measureComment(comment) {
2197
- const widthLimit = getConfig(config.CommentStageSize, false)[comment.full ? "fullWidth" : "width"];
3606
+ const widthLimit = getConfig(config.commentStageSize, false)[comment.full ? "fullWidth" : "width"];
2198
3607
  if (!typeGuard.internal.MeasureInput(comment))
2199
3608
  throw new TypeGuardError();
2200
- const measureResult = measure(comment, this.context);
3609
+ const measureResult = measure(comment, this.renderer);
2201
3610
  if (comment.loc !== "naka" && measureResult.width > widthLimit) {
2202
3611
  return this._processResizeX(comment, measureResult.width);
2203
3612
  }
2204
3613
  return measureResult;
2205
3614
  }
2206
3615
  _processResizeX(comment, width) {
2207
- const widthLimit = getConfig(config.CommentStageSize, false)[comment.full ? "fullWidth" : "width"];
3616
+ const widthLimit = getConfig(config.commentStageSize, false)[comment.full ? "fullWidth" : "width"];
2208
3617
  const lineHeight = getLineHeight(comment.size, false);
2209
3618
  const charSize = getCharSize(comment.size, false);
2210
3619
  const scale = widthLimit / width;
@@ -2215,14 +3624,14 @@
2215
3624
  _comment.fontSize = _comment.charSize * 0.8;
2216
3625
  if (!typeGuard.internal.MeasureInput(_comment))
2217
3626
  throw new TypeGuardError();
2218
- let result = measure(_comment, this.context);
3627
+ let result = measure(_comment, this.renderer);
2219
3628
  if (result.width > widthLimit) {
2220
3629
  while (result.width >= widthLimit) {
2221
3630
  const originalCharSize = _comment.charSize;
2222
3631
  _comment.charSize -= 1;
2223
3632
  _comment.lineHeight *= _comment.charSize / originalCharSize;
2224
3633
  _comment.fontSize = _comment.charSize * 0.8;
2225
- result = measure(_comment, this.context);
3634
+ result = measure(_comment, this.renderer);
2226
3635
  }
2227
3636
  }
2228
3637
  else {
@@ -2233,7 +3642,7 @@
2233
3642
  _comment.charSize += 1;
2234
3643
  _comment.lineHeight *= _comment.charSize / originalCharSize;
2235
3644
  _comment.fontSize = _comment.charSize * 0.8;
2236
- result = measure(_comment, this.context);
3645
+ result = measure(_comment, this.renderer);
2237
3646
  }
2238
3647
  _comment = lastComment;
2239
3648
  }
@@ -2249,54 +3658,54 @@
2249
3658
  comment.fontSize = (comment.charSize ?? 0) * 0.8;
2250
3659
  if (!typeGuard.internal.MeasureInput(comment))
2251
3660
  throw new TypeGuardError();
2252
- return measure(comment, this.context);
3661
+ return measure(comment, this.renderer);
2253
3662
  }
2254
3663
  _drawCollision(posX, posY, showCollision) {
2255
3664
  if (showCollision) {
2256
- this.context.save();
3665
+ this.renderer.save();
2257
3666
  const scale = getConfig(config.commentScale, false);
2258
- this.context.strokeStyle = "rgba(0,255,255,1)";
2259
- this.context.strokeRect(posX, posY, this.comment.width, this.comment.height);
3667
+ this.renderer.setStrokeStyle("rgba(0,255,255,1)");
3668
+ this.renderer.strokeRect(posX, posY, this.comment.width, this.comment.height);
2260
3669
  for (let i = 0, n = this.comment.lineCount; i < n; i++) {
2261
3670
  if (!typeGuard.internal.HTML5Fonts(this.comment.font))
2262
3671
  throw new TypeGuardError();
2263
3672
  const linePosY = (this.comment.lineHeight * (i + 1) +
2264
3673
  (this.comment.charSize - this.comment.lineHeight) / 2 +
2265
3674
  this.comment.lineHeight * -0.16 +
2266
- (config.fonts[this.comment.font]?.offset || 0)) *
3675
+ (config.fonts.html5[this.comment.font]?.offset || 0)) *
2267
3676
  scale;
2268
- this.context.strokeStyle = "rgba(255,255,0,0.5)";
2269
- this.context.strokeRect(posX, posY + linePosY, this.comment.width, this.comment.fontSize * -1 * scale);
3677
+ this.renderer.setStrokeStyle("rgba(255,255,0,0.5)");
3678
+ this.renderer.strokeRect(posX, posY + linePosY, this.comment.width, this.comment.fontSize * -1 * scale);
2270
3679
  }
2271
- this.context.restore();
3680
+ this.renderer.restore();
2272
3681
  }
2273
3682
  }
2274
3683
  _generateTextImage() {
2275
3684
  const { fontSize, scale } = getFontSizeAndScale(this.comment.charSize);
2276
3685
  const paddingTop = (10 - scale * 10) *
2277
- ((this.comment.lineCount + 1) / config.hiResCommentCorrection);
3686
+ ((this.comment.lineCount + 1) / config.html5HiResCommentCorrection);
2278
3687
  const drawScale = getConfig(config.commentScale, false) *
2279
3688
  scale *
2280
3689
  (this.comment.layer === -1 ? options.scale : 1);
2281
- const { image, context } = this.createCanvas();
2282
- image.width = this.comment.width + 2 * 2 * this.comment.charSize;
2283
- image.height =
2284
- this.comment.height +
2285
- (((paddingTop + 1) * this.comment.lineHeight) / scale) * drawScale;
2286
- context.strokeStyle = getStrokeColor(this.comment);
2287
- context.fillStyle = this.comment.color;
2288
- context.textAlign = "start";
2289
- context.textBaseline = "alphabetic";
2290
- context.lineWidth = getConfig(config.contextLineWidth, false);
2291
- context.font = parseFont(this.comment.font, fontSize);
2292
- context.scale(drawScale, drawScale);
3690
+ const image = this.renderer.getCanvas();
3691
+ image.setSize(this.comment.width + 2 * 2 * this.comment.charSize, this.comment.height +
3692
+ (((paddingTop + 1) * this.comment.lineHeight) / scale) * drawScale);
3693
+ image.setStrokeStyle(getStrokeColor(this.comment));
3694
+ image.setFillStyle(this.comment.color);
3695
+ image.setLineWidth(getConfig(config.contextLineWidth, false));
3696
+ image.setFont(parseFont(this.comment.font, fontSize));
3697
+ image.setScale(drawScale);
2293
3698
  let lineCount = 0;
2294
3699
  if (!typeGuard.internal.HTML5Fonts(this.comment.font))
2295
3700
  throw new TypeGuardError();
2296
3701
  const offsetY = (this.comment.charSize - this.comment.lineHeight) / 2 +
2297
3702
  this.comment.lineHeight * -0.16 +
2298
- (config.fonts[this.comment.font]?.offset || 0);
3703
+ (config.fonts.html5[this.comment.font]?.offset || 0);
2299
3704
  for (const item of this.comment.content) {
3705
+ if (item?.type === "spacer") {
3706
+ lineCount += item.count * item.charWidth * this.comment.fontSize;
3707
+ continue;
3708
+ }
2300
3709
  const lines = item.slicedContent;
2301
3710
  for (let j = 0, n = lines.length; j < n; j++) {
2302
3711
  const line = lines[j];
@@ -2304,8 +3713,8 @@
2304
3713
  continue;
2305
3714
  const posY = (this.comment.lineHeight * (lineCount + 1 + paddingTop) + offsetY) /
2306
3715
  scale;
2307
- context.strokeText(line, 0, posY);
2308
- context.fillText(line, 0, posY);
3716
+ image.strokeText(line, 0, posY);
3717
+ image.fillText(line, 0, posY);
2309
3718
  lineCount += 1;
2310
3719
  }
2311
3720
  }
@@ -2319,7 +3728,7 @@
2319
3728
  }
2320
3729
  }
2321
3730
 
2322
- var index = /*#__PURE__*/Object.freeze({
3731
+ var index$1 = /*#__PURE__*/Object.freeze({
2323
3732
  __proto__: null,
2324
3733
  BaseComment: BaseComment,
2325
3734
  FlashComment: FlashComment,
@@ -2500,7 +3909,7 @@
2500
3909
  html5: 1920 / 683,
2501
3910
  flash: 1920 / 683,
2502
3911
  },
2503
- CommentStageSize: {
3912
+ commentStageSize: {
2504
3913
  html5: {
2505
3914
  width: 512,
2506
3915
  fullWidth: 683,
@@ -2542,7 +3951,7 @@
2542
3951
  },
2543
3952
  },
2544
3953
  },
2545
- lineCounts: {
3954
+ html5LineCounts: {
2546
3955
  default: {
2547
3956
  big: 8.4,
2548
3957
  medium: 13.1,
@@ -2559,9 +3968,15 @@
2559
3968
  small: 16.6,
2560
3969
  },
2561
3970
  },
2562
- hiResCommentCorrection: 20,
2563
- minFontSize: 10,
2564
- fonts: fonts[platform],
3971
+ html5HiResCommentCorrection: 20,
3972
+ html5MinFontSize: 10,
3973
+ fonts: {
3974
+ html5: fonts[platform],
3975
+ flash: {
3976
+ gulim: `normal 600 [size]px gulim, ${fonts[platform].gothic.font}, Arial`,
3977
+ simsun: `normal 400 [size]px simsun, batang, "PMingLiU", MingLiU-ExtB, ${fonts[platform].mincho.font}, Arial`,
3978
+ },
3979
+ },
2565
3980
  fpsInterval: 500,
2566
3981
  cacheAge: 2000,
2567
3982
  canvasWidth: 1920,
@@ -2572,6 +3987,7 @@
2572
3987
  left: 235,
2573
3988
  right: 1685,
2574
3989
  },
3990
+ collisionPadding: 5,
2575
3991
  sameCARange: 3600,
2576
3992
  sameCAGap: 100,
2577
3993
  sameCAMinScore: 10,
@@ -2579,20 +3995,16 @@
2579
3995
  plugins: [],
2580
3996
  flashThreshold: 1499871600,
2581
3997
  flashChar: {
2582
- gulim: "[\u0126\u0127\u0132\u0133\u0138\u013f\u0140\u0149-\u014b\u0166\u0167\u02d0\u02da\u2074\u207f\u2081-\u2084\u2113\u2153\u2154\u215c-\u215e\u2194\u2195\u223c\u249c-\u24b5\u24d0-\u24e9\u25a3-\u25a9\u25b6\u25b7\u25c0\u25c1\u25c8\u25d0\u25d1\u260e\u260f\u261c\u261e\u2660\u2661\u2663-\u2665\u2667-\u2669\u266c\u3131-\u316e\u3200-\u321c\u3260-\u327b\u3380-\u3384\u3388-\u338d\u3390-\u339b\u339f\u33a0\u33a2-\u33ca\u33cf\u33d0\u33d3\u33d6\u33d8\u33db-\u33dd\uf900-\uf928\uf92a-\uf994\uf996\ufa0b\uffe6]",
3998
+ gulim: "[\u0126\u0127\u0132\u0133\u0138\u013f\u0140\u0149-\u014b\u0166\u0167\u02d0\u02da\u2074\u207f\u2081-\u2084\u2113\u2153\u2154\u215c-\u215e\u2194\u2195\u223c\u249c-\u24b5\u24d0-\u24e9\u25a3-\u25a9\u25b6\u25b7\u25c0\u25c1\u25c8\u25d0\u25d1\u260e\u260f\u261c\u261e\u2660\u2661\u2663-\u2665\u2667-\u2669\u266c\u3131-\u316e\u3200-\u321c\u3260-\u327b\u3380-\u3384\u3388-\u338d\u3390-\u339b\u339f\u33a0\u33a2-\u33ca\u33cf\u33d0\u33d3\u33d6\u33d8\u33db-\u33dd\uac00-\ud7a3\uf900-\uf928\uf92a-\uf994\uf996\ufa0b\uffe6]",
2583
3999
  simsunStrong: "[\u01ce\u01d0\u01d2\u01d4\u01d6\u01d8\u01da\u01dc\u0251\u0261\u02ca\u02cb\u2016\u2035\u216a\u216b\u2223\u2236\u2237\u224c\u226e\u226f\u2295\u2483-\u249b\u2504-\u250b\u256d-\u2573\u2581-\u2583\u2585-\u2587\u2589-\u258b\u258d-\u258f\u2594\u2595\u25e2-\u25e5\u2609\u3016\u3017\u301e\u3021-\u3029\u3105-\u3129\u3220-\u3229\u32a3\u33ce\u33d1\u33d2\u33d5\ue758-\ue864\ufa0c\ufa0d\ufe30\ufe31\ufe33-\ufe44\ufe49-\ufe52\ufe54-\ufe57\ufe59-\ufe66\ufe68-\ufe6b]",
2584
4000
  simsunWeak: "[\u02c9\u2105\u2109\u2196-\u2199\u220f\u2215\u2248\u2264\u2265\u2299\u2474-\u2482\u250d\u250e\u2511\u2512\u2515\u2516\u2519\u251a\u251e\u251f\u2521\u2522\u2526\u2527\u2529\u252a\u252d\u252e\u2531\u2532\u2535\u2536\u2539\u253a\u253d\u253e\u2540\u2541\u2543-\u254a\u2550-\u256c\u2584\u2588\u258c\u2593]",
2585
- gothic: "[\u03fb\uff9f]",
4001
+ gothic: "[\u03fb\uff9f\u30fb]",
2586
4002
  },
2587
- FlashMode: "vista",
2588
- FlashScriptChar: {
4003
+ flashMode: "vista",
4004
+ flashScriptChar: {
2589
4005
  super: "[\u00aa\u00b2\u00b3\u00b9\u00ba\u02b0\u02b2\u02b3\u02b7\u02b8\u02e1-\u02e3\u0304\u1d2c-\u1d43\u1d45-\u1d61\u1d9b-\u1da1\u1da3-\u1dbf\u2070\u2071\u2074-\u207f\u2c7d]",
2590
4006
  sub: "[\u0320\u1d62-\u1d6a\u2080-\u208e\u2090-\u209c\u2c7c]",
2591
4007
  },
2592
- font: {
2593
- gulim: 'normal 600 [size]px gulim, "Microsoft JhengHei UI", Arial, "MS Pゴシック", "MS PGothic", MSPGothic, MS-PGothic',
2594
- simsun: 'normal 400 [size]px simsun, "游明朝体", "游明朝", "Yu Mincho", YuMincho, yumincho, YuMin-Medium',
2595
- },
2596
4008
  lineHeight: {
2597
4009
  small: {
2598
4010
  default: 18 / 15,
@@ -2607,26 +4019,17 @@
2607
4019
  resized: 24 / 19.5,
2608
4020
  },
2609
4021
  },
2610
- doubleResizeMaxWidth: {
2611
- full: 1200,
2612
- normal: 960,
2613
- },
2614
- commentYPaddingTop: {
4022
+ flashCommentYPaddingTop: {
2615
4023
  default: 5,
2616
4024
  resized: 3,
2617
4025
  },
2618
- commentYMarginBottom: {
2619
- small: 0.24,
2620
- medium: 0.28,
2621
- big: 0.24,
2622
- },
2623
- commentYOffset: {
4026
+ flashCommentYOffset: {
2624
4027
  small: { default: -0.2, resized: -0.2 },
2625
4028
  medium: { default: -0.2, resized: -0.2 },
2626
4029
  big: { default: -0.2, resized: -0.2 },
2627
4030
  },
2628
- letterSpacing: 1,
2629
- scriptCharOffset: 0.12,
4031
+ flashLetterSpacing: 1,
4032
+ flashScriptCharOffset: 0.12,
2630
4033
  commentLimit: undefined,
2631
4034
  hideCommentOrder: "asc",
2632
4035
  lineBreakCount: {
@@ -2643,6 +4046,50 @@
2643
4046
  nakaCommentSpeedOffset: 0.95,
2644
4047
  atButtonPadding: 5,
2645
4048
  atButtonRadius: 7,
4049
+ flashDoubleResizeHeights: {
4050
+ big: {
4051
+ 9: 392,
4052
+ 10: 384,
4053
+ 11: 389,
4054
+ 12: 388,
4055
+ 13: 381,
4056
+ 14: 381,
4057
+ 15: 384,
4058
+ },
4059
+ },
4060
+ flashLineBreakScale: {
4061
+ small: 0.557,
4062
+ medium: 0.519,
4063
+ big: 0.535,
4064
+ },
4065
+ compatSpacer: {
4066
+ flash: {
4067
+ "\u3000": {
4068
+ simsun: 0.98,
4069
+ defont: 0.645,
4070
+ gulim: 0.95,
4071
+ },
4072
+ "\u00a0": {
4073
+ simsun: 0.25,
4074
+ },
4075
+ "\u0020": {
4076
+ defont: 0.3,
4077
+ },
4078
+ "\u2001": {
4079
+ defont: 0.95,
4080
+ },
4081
+ "\u2004": {
4082
+ defont: 1.6,
4083
+ },
4084
+ "\u2007": {
4085
+ defont: 1.6,
4086
+ },
4087
+ "\u202a": {
4088
+ defont: 0.59,
4089
+ },
4090
+ },
4091
+ html5: {},
4092
+ },
2646
4093
  };
2647
4094
  updateConfig(defaultConfig);
2648
4095
  };
@@ -2754,32 +4201,44 @@
2754
4201
 
2755
4202
  const convert2formattedComment = (data, type) => {
2756
4203
  let result = [];
4204
+ try {
4205
+ result = parseComments(data, type);
4206
+ }
4207
+ catch (e) {
4208
+ if (e instanceof ValiError) {
4209
+ console.error("", e.issues);
4210
+ }
4211
+ }
4212
+ return sort(result);
4213
+ };
4214
+ const parseComments = (data, type) => {
2757
4215
  if (type === "empty" && data === undefined) {
2758
4216
  return [];
2759
4217
  }
2760
4218
  else if ((type === "XMLDocument" || type === "niconicome") &&
2761
4219
  typeGuard.xmlDocument(data)) {
2762
- result = fromXMLDocument(data);
4220
+ return fromXMLDocument(data);
2763
4221
  }
2764
- else if (type === "formatted" && typeGuard.formatted.legacyComments(data)) {
2765
- result = fromFormatted(data);
4222
+ else if (type === "formatted") {
4223
+ return fromFormatted(parse(array(ZFormattedComment), data));
2766
4224
  }
2767
- else if (type === "legacy" && typeGuard.legacy.rawApiResponses(data)) {
2768
- result = fromLegacy(data);
4225
+ else if (type === "legacy") {
4226
+ return fromLegacy(parse(array(ZRawApiResponse), data));
2769
4227
  }
2770
- else if (type === "legacyOwner" && typeGuard.legacyOwner.comments(data)) {
2771
- result = fromLegacyOwner(data);
4228
+ else if (type === "legacyOwner") {
4229
+ if (!typeGuard.legacyOwner.comments(data))
4230
+ throw new InvalidFormatError();
4231
+ return fromLegacyOwner(data);
2772
4232
  }
2773
- else if (type === "owner" && typeGuard.owner.comments(data)) {
2774
- result = fromOwner(data);
4233
+ else if (type === "owner") {
4234
+ return fromOwner(parse(array(ZOwnerComment), data));
2775
4235
  }
2776
- else if (type === "v1" && typeGuard.v1.threads(data)) {
2777
- result = fromV1(data);
4236
+ else if (type === "v1") {
4237
+ return fromV1(parse(array(ZV1Thread), data));
2778
4238
  }
2779
4239
  else {
2780
4240
  throw new InvalidFormatError();
2781
4241
  }
2782
- return sort(result);
2783
4242
  };
2784
4243
  const fromXMLDocument = (data) => {
2785
4244
  const data_ = [], userList = [];
@@ -2820,24 +4279,15 @@
2820
4279
  return data_;
2821
4280
  };
2822
4281
  const fromFormatted = (data) => {
2823
- return data.map((comment) => {
2824
- if (!typeGuard.formatted.comment(comment)) {
2825
- return {
2826
- ...comment,
2827
- layer: -1,
2828
- user_id: 0,
2829
- is_my_post: false,
2830
- };
2831
- }
2832
- return comment;
2833
- });
4282
+ return data;
2834
4283
  };
2835
4284
  const fromLegacy = (data) => {
2836
4285
  const data_ = [], userList = [];
2837
- for (const val of data) {
2838
- if (!typeGuard.legacy.apiChat(val.chat))
4286
+ for (const _val of data) {
4287
+ const val = safeParse(ZApiChat, _val.chat);
4288
+ if (!val.success)
2839
4289
  continue;
2840
- const value = val.chat;
4290
+ const value = val.output;
2841
4291
  if (value.deleted !== 1) {
2842
4292
  const tmpParam = {
2843
4293
  id: value.no,
@@ -2990,8 +4440,8 @@
2990
4440
  });
2991
4441
  return data;
2992
4442
  };
2993
- const time2vpos = (time_str) => {
2994
- const time = RegExp(/^(?:(\d+):(\d+)\.(\d+)|(\d+):(\d+)|(\d+)\.(\d+)|(\d+))$/).exec(time_str);
4443
+ const time2vpos = (input) => {
4444
+ const time = RegExp(/^(?:(\d+):(\d+)\.(\d+)|(\d+):(\d+)|(\d+)\.(\d+)|(\d+))$/).exec(input);
2995
4445
  if (time) {
2996
4446
  if (time[1] !== undefined &&
2997
4447
  time[2] !== undefined &&
@@ -3019,6 +4469,125 @@
3019
4469
  default: convert2formattedComment
3020
4470
  });
3021
4471
 
4472
+ class CanvasRenderer {
4473
+ canvas;
4474
+ video;
4475
+ context;
4476
+ constructor(canvas, video) {
4477
+ this.canvas = canvas ?? document.createElement("canvas");
4478
+ const context = this.canvas.getContext("2d");
4479
+ if (!context)
4480
+ throw new CanvasRenderingContext2DError();
4481
+ this.context = context;
4482
+ this.context.textAlign = "start";
4483
+ this.context.textBaseline = "alphabetic";
4484
+ this.video = video;
4485
+ }
4486
+ drawVideo(enableLegacyPip) {
4487
+ if (this.video) {
4488
+ let scale;
4489
+ const height = this.canvas.height / this.video.videoHeight, width = this.canvas.width / this.video.videoWidth;
4490
+ if (enableLegacyPip ? height > width : height < width) {
4491
+ scale = width;
4492
+ }
4493
+ else {
4494
+ scale = height;
4495
+ }
4496
+ const offsetX = (this.canvas.width - this.video.videoWidth * scale) * 0.5, offsetY = (this.canvas.height - this.video.videoHeight * scale) * 0.5;
4497
+ this.context.drawImage(this.video, offsetX, offsetY, this.video.videoWidth * scale, this.video.videoHeight * scale);
4498
+ }
4499
+ }
4500
+ getFont() {
4501
+ return this.context.font;
4502
+ }
4503
+ getFillStyle() {
4504
+ return this.context.fillStyle;
4505
+ }
4506
+ setScale(scale, arg1) {
4507
+ this.context.scale(scale, arg1 ?? scale);
4508
+ }
4509
+ drawImage(image, x, y, width, height) {
4510
+ if (width === undefined || height === undefined)
4511
+ this.context.drawImage(image.canvas, x, y);
4512
+ else
4513
+ this.context.drawImage(image.canvas, x, y, width, height);
4514
+ }
4515
+ fillRect(x, y, width, height) {
4516
+ this.context.fillRect(x, y, width, height);
4517
+ }
4518
+ strokeRect(x, y, width, height) {
4519
+ this.context.strokeRect(x, y, width, height);
4520
+ }
4521
+ fillText(text, x, y) {
4522
+ this.context.fillText(text, x, y);
4523
+ }
4524
+ strokeText(text, x, y) {
4525
+ this.context.strokeText(text, x, y);
4526
+ }
4527
+ quadraticCurveTo(cpx, cpy, x, y) {
4528
+ this.context.quadraticCurveTo(cpx, cpy, x, y);
4529
+ }
4530
+ clearRect(x, y, width, height) {
4531
+ this.context.clearRect(x, y, width, height);
4532
+ }
4533
+ setFont(font) {
4534
+ this.context.font = font;
4535
+ }
4536
+ setFillStyle(color) {
4537
+ this.context.fillStyle = color;
4538
+ }
4539
+ setStrokeStyle(color) {
4540
+ this.context.strokeStyle = color;
4541
+ }
4542
+ setLineWidth(width) {
4543
+ this.context.lineWidth = width;
4544
+ }
4545
+ setGlobalAlpha(alpha) {
4546
+ this.context.globalAlpha = alpha;
4547
+ }
4548
+ setSize(width, height) {
4549
+ this.canvas.width = width;
4550
+ this.canvas.height = height;
4551
+ }
4552
+ getSize() {
4553
+ return { width: this.canvas.width, height: this.canvas.height };
4554
+ }
4555
+ measureText(text) {
4556
+ return this.context.measureText(text);
4557
+ }
4558
+ beginPath() {
4559
+ this.context.beginPath();
4560
+ }
4561
+ closePath() {
4562
+ this.context.closePath();
4563
+ }
4564
+ moveTo(x, y) {
4565
+ this.context.moveTo(x, y);
4566
+ }
4567
+ lineTo(x, y) {
4568
+ this.context.lineTo(x, y);
4569
+ }
4570
+ stroke() {
4571
+ this.context.stroke();
4572
+ }
4573
+ save() {
4574
+ this.context.save();
4575
+ }
4576
+ restore() {
4577
+ this.context.restore();
4578
+ }
4579
+ getCanvas() {
4580
+ return new CanvasRenderer();
4581
+ }
4582
+ destroy() {
4583
+ }
4584
+ }
4585
+
4586
+ var index = /*#__PURE__*/Object.freeze({
4587
+ __proto__: null,
4588
+ CanvasRenderer: CanvasRenderer
4589
+ });
4590
+
3022
4591
  const createCommentInstance = (comment, context) => {
3023
4592
  for (const plugin of config.commentPlugins) {
3024
4593
  if (plugin.condition(comment)) {
@@ -3037,14 +4606,15 @@
3037
4606
 
3038
4607
  var internal = /*#__PURE__*/Object.freeze({
3039
4608
  __proto__: null,
3040
- comments: index,
3041
- contexts: index$3,
4609
+ comments: index$1,
4610
+ contexts: index$4,
3042
4611
  definition: definition,
3043
- errors: index$2,
4612
+ errors: index$3,
3044
4613
  eventHandler: eventHandler,
3045
4614
  inputParser: inputParser,
4615
+ renderer: index,
3046
4616
  typeGuard: typeGuard$1,
3047
- utils: index$1
4617
+ utils: index$2
3048
4618
  });
3049
4619
 
3050
4620
  class NiconiComments {
@@ -3052,11 +4622,9 @@
3052
4622
  showCollision;
3053
4623
  showFPS;
3054
4624
  showCommentCount;
3055
- video;
3056
4625
  lastVpos;
3057
- canvas;
4626
+ renderer;
3058
4627
  collision;
3059
- context;
3060
4628
  timeline;
3061
4629
  static typeGuard = typeGuard;
3062
4630
  static default = NiconiComments;
@@ -3065,7 +4633,7 @@
3065
4633
  class: FlashComment,
3066
4634
  };
3067
4635
  static internal = internal;
3068
- constructor(canvas, data, initOptions = {}) {
4636
+ constructor(renderer, data, initOptions = {}) {
3069
4637
  const constructorStart = performance.now();
3070
4638
  initConfig();
3071
4639
  if (!typeGuard.config.initOptions(initOptions))
@@ -3075,11 +4643,14 @@
3075
4643
  setIsDebug(options.debug);
3076
4644
  resetImageCache();
3077
4645
  resetNicoScripts();
3078
- this.canvas = canvas;
3079
- this.context = getContext(canvas);
3080
- this.context.textAlign = "start";
3081
- this.context.textBaseline = "alphabetic";
3082
- this.context.lineWidth = getConfig(config.contextLineWidth, false);
4646
+ if (renderer instanceof HTMLCanvasElement) {
4647
+ renderer = new CanvasRenderer(renderer, options.video);
4648
+ }
4649
+ else if (options.video) {
4650
+ console.warn("options.video is ignored because renderer is not HTMLCanvasElement");
4651
+ }
4652
+ this.renderer = renderer;
4653
+ this.renderer.setLineWidth(getConfig(config.contextLineWidth, false));
3083
4654
  let formatType = options.format;
3084
4655
  if (options.formatted) {
3085
4656
  console.warn("Deprecated: options.formatted is no longer recommended. Please use options.format. https://xpadev-net.github.io/niconicomments/#p_format");
@@ -3094,7 +4665,6 @@
3094
4665
  options.mode = "html5";
3095
4666
  }
3096
4667
  const parsedData = convert2formattedComment(data, formatType);
3097
- this.video = options.video ?? undefined;
3098
4668
  this.showCollision = options.showCollision;
3099
4669
  this.showFPS = options.showFPS;
3100
4670
  this.showCommentCount = options.showCommentCount;
@@ -3116,7 +4686,7 @@
3116
4686
  rawData = changeCALayer(rawData);
3117
4687
  }
3118
4688
  let instances = rawData.reduce((pv, val) => {
3119
- pv.push(createCommentInstance(val, this.context));
4689
+ pv.push(createCommentInstance(val, this.renderer));
3120
4690
  return pv;
3121
4691
  }, []);
3122
4692
  this.getCommentPos(instances);
@@ -3124,7 +4694,7 @@
3124
4694
  const plugins = [];
3125
4695
  for (const plugin of config.plugins) {
3126
4696
  try {
3127
- const canvas = generateCanvas();
4697
+ const canvas = this.renderer.getCanvas();
3128
4698
  const pluginInstance = new plugin(canvas, instances);
3129
4699
  plugins.push({
3130
4700
  canvas,
@@ -3176,7 +4746,7 @@
3176
4746
  }
3177
4747
  addComments(...rawComments) {
3178
4748
  const comments = rawComments.reduce((pv, val) => {
3179
- pv.push(createCommentInstance(val, this.context));
4749
+ pv.push(createCommentInstance(val, this.renderer));
3180
4750
  return pv;
3181
4751
  }, []);
3182
4752
  for (const plugin of plugins) {
@@ -3211,19 +4781,20 @@
3211
4781
  ?.length === 0) {
3212
4782
  const current = timelineRange.filter((item) => item.loc !== "naka"), last = this.timeline[this.lastVpos]?.filter((item) => item.loc !== "naka") ??
3213
4783
  [];
3214
- if (ArrayEqual(current, last))
4784
+ if (arrayEqual(current, last))
3215
4785
  return false;
3216
4786
  }
3217
- this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
4787
+ const size = this.renderer.getSize();
4788
+ this.renderer.clearRect(0, 0, size.width, size.height);
3218
4789
  this.lastVpos = vpos;
3219
4790
  this._drawVideo();
3220
4791
  for (const plugin of plugins) {
3221
4792
  try {
3222
4793
  plugin.instance.draw?.(vpos);
3223
- this.context.drawImage(plugin.canvas, 0, 0);
4794
+ this.renderer.drawImage(plugin.canvas, 0, 0);
3224
4795
  }
3225
4796
  catch (e) {
3226
- console.error(`Failed to draw comments`);
4797
+ console.error(`Failed to draw comments`, e);
3227
4798
  }
3228
4799
  }
3229
4800
  this._drawCollision(vpos);
@@ -3234,18 +4805,7 @@
3234
4805
  return true;
3235
4806
  }
3236
4807
  _drawVideo() {
3237
- if (this.video) {
3238
- let scale;
3239
- const height = this.canvas.height / this.video.videoHeight, width = this.canvas.width / this.video.videoWidth;
3240
- if (this.enableLegacyPiP ? height > width : height < width) {
3241
- scale = width;
3242
- }
3243
- else {
3244
- scale = height;
3245
- }
3246
- const offsetX = (this.canvas.width - this.video.videoWidth * scale) * 0.5, offsetY = (this.canvas.height - this.video.videoHeight * scale) * 0.5;
3247
- this.context.drawImage(this.video, offsetX, offsetY, this.video.videoWidth * scale, this.video.videoHeight * scale);
3248
- }
4808
+ this.renderer.drawVideo(this.enableLegacyPiP);
3249
4809
  }
3250
4810
  _drawComments(timelineRange, vpos, cursor) {
3251
4811
  if (timelineRange) {
@@ -3268,44 +4828,44 @@
3268
4828
  }
3269
4829
  _drawCollision(vpos) {
3270
4830
  if (this.showCollision) {
3271
- this.context.save();
4831
+ this.renderer.save();
3272
4832
  const leftCollision = this.collision.left[vpos], rightCollision = this.collision.right[vpos];
3273
- this.context.fillStyle = "red";
4833
+ this.renderer.setFillStyle("red");
3274
4834
  if (leftCollision) {
3275
4835
  for (const comment of leftCollision) {
3276
- this.context.fillRect(config.collisionRange.left, comment.posY, getConfig(config.contextLineWidth, comment.flash), comment.height);
4836
+ this.renderer.fillRect(config.collisionRange.left, comment.posY, getConfig(config.contextLineWidth, comment.flash), comment.height);
3277
4837
  }
3278
4838
  }
3279
4839
  if (rightCollision) {
3280
4840
  for (const comment of rightCollision) {
3281
- this.context.fillRect(config.collisionRange.right, comment.posY, getConfig(config.contextLineWidth, comment.flash) * -1, comment.height);
4841
+ this.renderer.fillRect(config.collisionRange.right, comment.posY, getConfig(config.contextLineWidth, comment.flash) * -1, comment.height);
3282
4842
  }
3283
4843
  }
3284
- this.context.restore();
4844
+ this.renderer.restore();
3285
4845
  }
3286
4846
  }
3287
4847
  _drawFPS(drawCanvasStart) {
3288
4848
  if (this.showFPS) {
3289
- this.context.save();
3290
- this.context.font = parseFont("defont", 60);
3291
- this.context.fillStyle = "#00FF00";
3292
- this.context.strokeStyle = `rgba(${hex2rgb(config.contextStrokeColor).join(",")},${config.contextStrokeOpacity})`;
4849
+ this.renderer.save();
4850
+ this.renderer.setFont(parseFont("defont", 60));
4851
+ this.renderer.setFillStyle("#00FF00");
4852
+ this.renderer.setStrokeStyle(`rgba(${hex2rgb(config.contextStrokeColor).join(",")},${config.contextStrokeOpacity})`);
3293
4853
  const drawTime = Math.floor(performance.now() - drawCanvasStart);
3294
4854
  const fps = Math.floor(1000 / (drawTime === 0 ? 1 : drawTime));
3295
- this.context.strokeText(`FPS:${fps}(${drawTime}ms)`, 100, 100);
3296
- this.context.fillText(`FPS:${fps}(${drawTime}ms)`, 100, 100);
3297
- this.context.restore();
4855
+ this.renderer.strokeText(`FPS:${fps}(${drawTime}ms)`, 100, 100);
4856
+ this.renderer.fillText(`FPS:${fps}(${drawTime}ms)`, 100, 100);
4857
+ this.renderer.restore();
3298
4858
  }
3299
4859
  }
3300
4860
  _drawCommentCount(count) {
3301
4861
  if (this.showCommentCount) {
3302
- this.context.save();
3303
- this.context.font = parseFont("defont", 60);
3304
- this.context.fillStyle = "#00FF00";
3305
- this.context.strokeStyle = `rgba(${hex2rgb(config.contextStrokeColor).join(",")},${config.contextStrokeOpacity})`;
3306
- this.context.strokeText(`Count:${count ?? 0}`, 100, 200);
3307
- this.context.fillText(`Count:${count ?? 0}`, 100, 200);
3308
- this.context.restore();
4862
+ this.renderer.save();
4863
+ this.renderer.setFont(parseFont("defont", 60));
4864
+ this.renderer.setFillStyle("#00FF00");
4865
+ this.renderer.setStrokeStyle(`rgba(${hex2rgb(config.contextStrokeColor).join(",")},${config.contextStrokeOpacity})`);
4866
+ this.renderer.strokeText(`Count:${count ?? 0}`, 100, 200);
4867
+ this.renderer.fillText(`Count:${count ?? 0}`, 100, 200);
4868
+ this.renderer.restore();
3309
4869
  }
3310
4870
  }
3311
4871
  addEventListener(eventName, handler) {
@@ -3315,7 +4875,8 @@
3315
4875
  removeHandler(eventName, handler);
3316
4876
  }
3317
4877
  clear() {
3318
- this.context.clearRect(0, 0, config.canvasWidth, config.canvasHeight);
4878
+ const size = this.renderer.getSize();
4879
+ this.renderer.clearRect(0, 0, size.width, size.height);
3319
4880
  }
3320
4881
  click(vpos, pos) {
3321
4882
  const _comments = this.timeline[vpos];
@@ -3325,7 +4886,6 @@
3325
4886
  for (const comment of comments) {
3326
4887
  if (comment.isHovered(pos)) {
3327
4888
  const newComment = buildAtButtonComment(comment.comment, vpos);
3328
- console.log(newComment);
3329
4889
  if (!newComment)
3330
4890
  continue;
3331
4891
  this.addComments(newComment);