@hufe921/canvas-editor 0.9.120 → 0.9.121

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## [0.9.121](https://github.com/Hufe921/canvas-editor/compare/v0.9.120...v0.9.121) (2025-12-19)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * clear eventbus when destroying editor ([17e7fcd](https://github.com/Hufe921/canvas-editor/commit/17e7fcda00a71e8a4bad8360f8c473f188ba229c))
7
+ * compute position boundary error ([5835396](https://github.com/Hufe921/canvas-editor/commit/58353968376623fcd82a308d8760a2eb449188bf))
8
+ * graffiti mode boundary error ([9781f2d](https://github.com/Hufe921/canvas-editor/commit/9781f2d038d3537fc26bf3cebff0ae452c45b07a))
9
+ * restrict allowed characters in number control #1319 ([9e31b41](https://github.com/Hufe921/canvas-editor/commit/9e31b41720ad5269813db364db3b1c39e9865185)), closes [#1319](https://github.com/Hufe921/canvas-editor/issues/1319)
10
+
11
+
12
+ ### Features
13
+
14
+ * add graffiti mode #992 ([5bd66a6](https://github.com/Hufe921/canvas-editor/commit/5bd66a641031d0390f7d37d50b1210aed9defc7a)), closes [#992](https://github.com/Hufe921/canvas-editor/issues/992)
15
+ * optimize zero width element ascent calculation #1324 ([890b87d](https://github.com/Hufe921/canvas-editor/commit/890b87da4b3c4b80c725e15956e417eef5dce712)), closes [#1324](https://github.com/Hufe921/canvas-editor/issues/1324)
16
+
17
+
18
+
1
19
  ## [0.9.120](https://github.com/Hufe921/canvas-editor/compare/v0.9.119...v0.9.120) (2025-11-28)
2
20
 
3
21
 
@@ -23,7 +23,7 @@ var __publicField = (obj, key, value) => {
23
23
  return value;
24
24
  };
25
25
  var index = "";
26
- const version = "0.9.120";
26
+ const version = "0.9.121";
27
27
  var MaxHeightRatio;
28
28
  (function(MaxHeightRatio2) {
29
29
  MaxHeightRatio2["HALF"] = "half";
@@ -108,6 +108,7 @@ const UNICODE_SYMBOL_REG = new RegExp(`${EMOJI_REG.source}|${SURROGATE_PAIR_REG.
108
108
  const PUNCTUATION_REG = /[、,。?!;:……「」“”‘’*()【】〔〕〖〗〘〙〚〛《》———﹝﹞–—\\/·.,!?;:`~<>()[\]{}'"|]/;
109
109
  const START_LINE_BREAK_REG = new RegExp(`^[${ZERO}
110
110
  ]`);
111
+ const NON_NUMBER_STR_REG = /[^0-9\+\-\.eE,]/;
111
112
  function debounce(func, delay) {
112
113
  let timer;
113
114
  return function(...args) {
@@ -148,7 +149,7 @@ function deepCloneOmitKeys(obj, omitKeys) {
148
149
  Object.keys(obj).forEach((key) => {
149
150
  if (omitKeys.includes(key))
150
151
  return;
151
- return newObj[key] = deepCloneOmitKeys(obj[key], omitKeys);
152
+ newObj[key] = deepCloneOmitKeys(obj[key], omitKeys);
152
153
  });
153
154
  }
154
155
  return newObj;
@@ -165,7 +166,7 @@ function deepClone(obj) {
165
166
  newObj = obj.map((item) => deepClone(item));
166
167
  } else {
167
168
  Object.keys(obj).forEach((key) => {
168
- return newObj[key] = deepClone(obj[key]);
169
+ newObj[key] = deepClone(obj[key]);
169
170
  });
170
171
  }
171
172
  return newObj;
@@ -4112,6 +4113,7 @@ var EditorMode;
4112
4113
  EditorMode2["FORM"] = "form";
4113
4114
  EditorMode2["PRINT"] = "print";
4114
4115
  EditorMode2["DESIGN"] = "design";
4116
+ EditorMode2["GRAFFITI"] = "graffiti";
4115
4117
  })(EditorMode || (EditorMode = {}));
4116
4118
  var EditorZone;
4117
4119
  (function(EditorZone2) {
@@ -4325,6 +4327,10 @@ const defaultBadgeOption = {
4325
4327
  top: 0,
4326
4328
  left: 5
4327
4329
  };
4330
+ const defaultGraffitiOption = {
4331
+ defaultLineColor: "#000000",
4332
+ defaultLineWidth: 2
4333
+ };
4328
4334
  function mergeOption(options = {}) {
4329
4335
  var _a, _b, _c;
4330
4336
  const tableOptions = __spreadValues(__spreadValues({}, defaultTableOption), options.table);
@@ -4347,6 +4353,7 @@ function mergeOption(options = {}) {
4347
4353
  const lineNumberOptions = __spreadValues(__spreadValues({}, defaultLineNumberOption), options.lineNumber);
4348
4354
  const pageBorderOptions = __spreadValues(__spreadValues({}, defaultPageBorderOption), options.pageBorder);
4349
4355
  const badgeOptions = __spreadValues(__spreadValues({}, defaultBadgeOption), options.badge);
4356
+ const graffitiOptions = __spreadValues(__spreadValues({}, defaultGraffitiOption), options.graffiti);
4350
4357
  const modeRuleOption = {
4351
4358
  print: __spreadValues(__spreadValues({}, defaultModeRuleOption.print), (_a = options.modeRule) == null ? void 0 : _a.print),
4352
4359
  readonly: __spreadValues(__spreadValues({}, defaultModeRuleOption.readonly), (_b = options.modeRule) == null ? void 0 : _b.readonly),
@@ -4418,7 +4425,8 @@ function mergeOption(options = {}) {
4418
4425
  lineNumber: lineNumberOptions,
4419
4426
  pageBorder: pageBorderOptions,
4420
4427
  badge: badgeOptions,
4421
- modeRule: modeRuleOption
4428
+ modeRule: modeRuleOption,
4429
+ graffiti: graffitiOptions
4422
4430
  });
4423
4431
  }
4424
4432
  function unzipElementList(elementList) {
@@ -5121,6 +5129,9 @@ function convertRowFlexToJustifyContent(rowFlex) {
5121
5129
  function isTextLikeElement(element) {
5122
5130
  return !element.type || TEXTLIKE_ELEMENT_TYPE.includes(element.type);
5123
5131
  }
5132
+ function isTextElement(element) {
5133
+ return !element.type || element.type === ElementType.TEXT;
5134
+ }
5124
5135
  function getElementListText(elementList) {
5125
5136
  return elementList.filter((el) => isTextLikeElement(el)).map((el) => el.value).join("").replace(new RegExp(ZERO, "g"), "");
5126
5137
  }
@@ -8563,7 +8574,7 @@ class CanvasEvent {
8563
8574
  selection.forEach((s) => {
8564
8575
  painterStyleKeys.forEach((pKey) => {
8565
8576
  const key = pKey;
8566
- s[key] = painterStyle[key];
8577
+ Reflect.set(s, key, painterStyle[key]);
8567
8578
  });
8568
8579
  });
8569
8580
  this.draw.render({ isSetCursor: false });
@@ -8998,7 +9009,6 @@ class Position {
8998
9009
  return { x, y, index: index2 };
8999
9010
  }
9000
9011
  computePositionList() {
9001
- var _a;
9002
9012
  this.positionList = [];
9003
9013
  const innerWidth = this.draw.getInnerWidth();
9004
9014
  const pageRowList = this.draw.getPageRowList();
@@ -9010,7 +9020,9 @@ class Position {
9010
9020
  let startRowIndex = 0;
9011
9021
  for (let i = 0; i < pageRowList.length; i++) {
9012
9022
  const rowList = pageRowList[i];
9013
- const startIndex = (_a = rowList[0]) == null ? void 0 : _a.startIndex;
9023
+ if (!(rowList == null ? void 0 : rowList.length))
9024
+ continue;
9025
+ const startIndex = rowList[0].startIndex;
9014
9026
  this.computePageRowPosition({
9015
9027
  positionList: this.positionList,
9016
9028
  rowList,
@@ -10710,6 +10722,9 @@ class TextParticle {
10710
10722
  this.cacheMeasureText.set(id, textMetrics);
10711
10723
  return textMetrics;
10712
10724
  }
10725
+ getBasisWordBoundingBoxAscent(ctx, font) {
10726
+ return this.measureBasisWord(ctx, font).actualBoundingBoxAscent;
10727
+ }
10713
10728
  complete() {
10714
10729
  this._render();
10715
10730
  this.text = "";
@@ -13641,6 +13656,9 @@ class DateControl {
13641
13656
  }
13642
13657
  class NumberControl extends TextControl {
13643
13658
  setValue(data2, context = {}, options = {}) {
13659
+ if (data2.some((el) => !isTextElement(el) || NON_NUMBER_STR_REG.test(el.value))) {
13660
+ return -1;
13661
+ }
13644
13662
  const elementList = context.elementList || this.control.getElementList();
13645
13663
  const range = context.range || this.control.getRange();
13646
13664
  this.control.shrinkBoundary(context);
@@ -15220,7 +15238,7 @@ function WorkerWrapper$1() {
15220
15238
  objURL && (window.URL || window.webkitURL).revokeObjectURL(objURL);
15221
15239
  }
15222
15240
  }
15223
- const encodedJs = "KCgpPT57dmFyIGZlPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSxUZT1PYmplY3QuZGVmaW5lUHJvcGVydGllczt2YXIgSWU9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnM7dmFyIGFlPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7dmFyIEFlPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksZGU9T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTt2YXIgbmU9KFQsSSxkKT0+SSBpbiBUP2ZlKFQsSSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6ZH0pOlRbSV09ZCxnPShULEkpPT57Zm9yKHZhciBkIGluIEl8fChJPXt9KSlBZS5jYWxsKEksZCkmJm5lKFQsZCxJW2RdKTtpZihhZSlmb3IodmFyIGQgb2YgYWUoSSkpZGUuY2FsbChJLGQpJiZuZShULGQsSVtkXSk7cmV0dXJuIFR9LFg9KFQsSSk9PlRlKFQsSWUoSSkpOyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0Ijt2YXIgVDsoZnVuY3Rpb24oZSl7ZS5IQUxGPSJoYWxmIixlLk9ORV9USElSRD0ib25lLXRoaXJkIixlLlFVQVJURVI9InF1YXJ0ZXIifSkoVHx8KFQ9e30pKTt2YXIgSTsoZnVuY3Rpb24oZSl7ZS5BUkFCSUM9ImFyYWJpYyIsZS5DSElORVNFPSJjaGluZXNlIn0pKEl8fChJPXt9KSk7dmFyIGQ7KGZ1bmN0aW9uKGUpe2UuSU5MSU5FPSJpbmxpbmUiLGUuQkxPQ0s9ImJsb2NrIixlLlNVUlJPVU5EPSJzdXJyb3VuZCIsZS5GTE9BVF9UT1A9ImZsb2F0LXRvcCIsZS5GTE9BVF9CT1RUT009ImZsb2F0LWJvdHRvbSJ9KShkfHwoZD17fSkpO3ZhciBfOyhmdW5jdGlvbihlKXtlLkJFRk9SRT0iYmVmb3JlIixlLkFGVEVSPSJhZnRlciIsZS5PVVRFUl9CRUZPUkU9Im91dGVyLWJlZm9yZSIsZS5PVVRFUl9BRlRFUj0ib3V0ZXItYWZ0ZXIifSkoX3x8KF89e30pKTt2YXIgTTsoZnVuY3Rpb24oZSl7ZS5ST1c9InJvdyIsZS5DT0xVTU49ImNvbHVtbiJ9KShNfHwoTT17fSkpO2NvbnN0IFA9Ilx1MjAwQiI7VC5IQUxGKyIiLDEvMixULk9ORV9USElSRCsiIiwxLzMsVC5RVUFSVEVSKyIiLDEvNDtmdW5jdGlvbiBIKGUpe2lmKHR5cGVvZiBzdHJ1Y3R1cmVkQ2xvbmU9PSJmdW5jdGlvbiIpcmV0dXJuIHN0cnVjdHVyZWRDbG9uZShlKTtpZighZXx8dHlwZW9mIGUhPSJvYmplY3QiKXJldHVybiBlO2xldCBzPXt9O3JldHVybiBBcnJheS5pc0FycmF5KGUpP3M9ZS5tYXAoRT0+SChFKSk6T2JqZWN0LmtleXMoZSkuZm9yRWFjaChFPT5zW0VdPUgoZVtFXSkpLHN9ZnVuY3Rpb24gdyhlLHMpe2NvbnN0IEU9e307Zm9yKGNvbnN0IEEgaW4gZSlzLmluY2x1ZGVzKEEpJiYoRVtBXT1lW0FdKTtyZXR1cm4gRX1mdW5jdGlvbiBsZShlLHMpe3JldHVybiBlLmxlbmd0aCE9PXMubGVuZ3RoPyExOiFlLnNvbWUoRT0+IXMuaW5jbHVkZXMoRSkpfXZhciBsOyhmdW5jdGlvbihlKXtlLlRFWFQ9InRleHQiLGUuSU1BR0U9ImltYWdlIixlLlRBQkxFPSJ0YWJsZSIsZS5IWVBFUkxJTks9Imh5cGVybGluayIsZS5TVVBFUlNDUklQVD0ic3VwZXJzY3JpcHQiLGUuU1VCU0NSSVBUPSJzdWJzY3JpcHQiLGUuU0VQQVJBVE9SPSJzZXBhcmF0b3IiLGUuUEFHRV9CUkVBSz0icGFnZUJyZWFrIixlLkNPTlRST0w9ImNvbnRyb2wiLGUuQVJFQT0iYXJlYSIsZS5DSEVDS0JPWD0iY2hlY2tib3giLGUuUkFESU89InJhZGlvIixlLkxBVEVYPSJsYXRleCIsZS5UQUI9InRhYiIsZS5EQVRFPSJkYXRlIixlLkJMT0NLPSJibG9jayIsZS5USVRMRT0idGl0bGUiLGUuTElTVD0ibGlzdCJ9KShsfHwobD17fSkpO2NvbnN0IHJlPVsicm93RmxleCIsInJvd01hcmdpbiJdLG9lPVsidHlwZSIsImZvbnQiLCJzaXplIiwiYm9sZCIsImNvbG9yIiwiaXRhbGljIiwiaGlnaGxpZ2h0IiwidW5kZXJsaW5lIiwic3RyaWtlb3V0Iiwicm93RmxleCIsInJvd01hcmdpbiIsImRhc2hBcnJheSIsInRyTGlzdCIsInRhYmxlVG9vbERpc2FibGVkIiwiYm9yZGVyVHlwZSIsImJvcmRlckNvbG9yIiwidHJhbnNsYXRlWCIsIndpZHRoIiwiaGVpZ2h0IiwidXJsIiwiY29sZ3JvdXAiLCJ2YWx1ZUxpc3QiLCJjb250cm9sIiwiY2hlY2tib3giLCJyYWRpbyIsImRhdGVGb3JtYXQiLCJibG9jayIsImxldmVsIiwidGl0bGUiLCJsaXN0VHlwZSIsImxpc3RTdHlsZSIsImxpc3RXcmFwIiwiZ3JvdXBJZHMiLCJjb25jZXB0SWQiLCJpbWdEaXNwbGF5IiwiaW1nRmxvYXRQb3NpdGlvbiIsImltZ1Rvb2xEaXNhYmxlZCIsInRleHREZWNvcmF0aW9uIiwiZXh0ZW5zaW9uIiwiZXh0ZXJuYWxJZCIsImFyZWFJZCIsImFyZWEiLCJoaWRlIl0sc2U9WyJjb25jZXB0SWQiLCJleHRlbnNpb24iLCJleHRlcm5hbElkIiwidmVydGljYWxBbGlnbiIsImJhY2tncm91bmRDb2xvciIsImJvcmRlclR5cGVzIiwic2xhc2hUeXBlcyIsImRpc2FibGVkIiwiZGVsZXRhYmxlIl0sY2U9WyJmb250Iiwic2l6ZSIsImJvbGQiLCJoaWdobGlnaHQiLCJpdGFsaWMiLCJzdHJpa2VvdXQiXTtsLlRFWFQsbC5IWVBFUkxJTkssbC5TVUJTQ1JJUFQsbC5TVVBFUlNDUklQVCxsLkNPTlRST0wsbC5EQVRFLGwuSU1BR0UsbC5MQVRFWCxsLkJMT0NLLGwuUEFHRV9CUkVBSyxsLlNFUEFSQVRPUixsLlRBQkxFLGwuVElUTEUsbC5MSVNUO3ZhciBOOyhmdW5jdGlvbihlKXtlLlVMPSJ1bCIsZS5PTD0ib2wifSkoTnx8KE49e30pKTt2YXIgTzsoZnVuY3Rpb24oZSl7ZS5ESVNDPSJkaXNjIixlLkNJUkNMRT0iY2lyY2xlIixlLlNRVUFSRT0ic3F1YXJlIixlLkNIRUNLQk9YPSJjaGVja2JveCJ9KShPfHwoTz17fSkpO3ZhciBiOyhmdW5jdGlvbihlKXtlLkRFQ0lNQUw9ImRlY2ltYWwifSkoYnx8KGI9e30pKTt2YXIgdjsoZnVuY3Rpb24oZSl7ZVtlLkRJU0M9Ty5ESVNDXT0iRElTQyIsZVtlLkNJUkNMRT1PLkNJUkNMRV09IkNJUkNMRSIsZVtlLlNRVUFSRT1PLlNRVUFSRV09IlNRVUFSRSIsZVtlLkRFQ0lNQUw9Yi5ERUNJTUFMXT0iREVDSU1BTCIsZVtlLkNIRUNLQk9YPU8uQ0hFQ0tCT1hdPSJDSEVDS0JPWCJ9KSh2fHwodj17fSkpLE8uRElTQysiIixPLkNJUkNMRSsiIixPLlNRVUFSRSsiIixPLkNIRUNLQk9YKyIiLE4uT0wrIiIsTi5VTCsiIix2LkRJU0MrIiIsdi5DSVJDTEUrIiIsdi5TUVVBUkUrIiIsdi5ERUNJTUFMKyIiLHYuQ0hFQ0tCT1grIiI7dmFyIGY7KGZ1bmN0aW9uKGUpe2UuRklSU1Q9ImZpcnN0IixlLlNFQ09ORD0ic2Vjb25kIixlLlRISVJEPSJ0aGlyZCIsZS5GT1VSVEg9ImZvdXJ0aCIsZS5GSUZUSD0iZmlmdGgiLGUuU0lYVEg9InNpeHRoIn0pKGZ8fChmPXt9KSksZi5GSVJTVCsiIixmLlNFQ09ORCsiIixmLlRISVJEKyIiLGYuRk9VUlRIKyIiLGYuRklGVEgrIiIsZi5TSVhUSCsiIixmLkZJUlNUKyIiLGYuU0VDT05EKyIiLGYuVEhJUkQrIiIsZi5GT1VSVEgrIiIsZi5GSUZUSCsiIixmLlNJWFRIKyIiLGYuRklSU1QsZi5TRUNPTkQsZi5USElSRCxmLkZPVVJUSCxmLkZJRlRILGYuU0lYVEg7dmFyIEs7KGZ1bmN0aW9uKGUpe2UuSUZSQU1FPSJpZnJhbWUiLGUuVklERU89InZpZGVvIn0pKEt8fChLPXt9KSk7dmFyIHo7KGZ1bmN0aW9uKGUpe2UuVEVYVD0idGV4dCIsZS5TRUxFQ1Q9InNlbGVjdCIsZS5DSEVDS0JPWD0iY2hlY2tib3giLGUuUkFESU89InJhZGlvIixlLkRBVEU9ImRhdGUiLGUuTlVNQkVSPSJudW1iZXIifSkoenx8KHo9e30pKTt2YXIgTDsoZnVuY3Rpb24oZSl7ZS5QUkVGSVg9InByZWZpeCIsZS5QT1NURklYPSJwb3N0Zml4IixlLlBSRV9URVhUPSJwcmVUZXh0IixlLlBPU1RfVEVYVD0icG9zdFRleHQiLGUuUExBQ0VIT0xERVI9InBsYWNlaG9sZGVyIixlLlZBTFVFPSJ2YWx1ZSIsZS5DSEVDS0JPWD0iY2hlY2tib3giLGUuUkFESU89InJhZGlvIn0pKEx8fChMPXt9KSk7dmFyIEc7KGZ1bmN0aW9uKGUpe2UuUk9XX1NUQVJUPSJyb3dTdGFydCIsZS5WQUxVRV9TVEFSVD0idmFsdWVTdGFydCJ9KShHfHwoRz17fSkpO3ZhciBZOyhmdW5jdGlvbihlKXtlLkFDVElWRT0iYWN0aXZlIixlLklOQUNUSVZFPSJpbmFjdGl2ZSJ9KShZfHwoWT17fSkpO3ZhciBWOyhmdW5jdGlvbihlKXtlLkNPTVBPTkVOVD0iY29tcG9uZW50IixlLk1FTlU9Im1lbnUiLGUuTUFJTj0ibWFpbiIsZS5GT09URVI9ImZvb3RlciIsZS5DT05URVhUTUVOVT0iY29udGV4dG1lbnUiLGUuUE9QVVA9InBvcHVwIixlLkNBVEFMT0c9ImNhdGFsb2ciLGUuQ09NTUVOVD0iY29tbWVudCJ9KShWfHwoVj17fSkpO3ZhciBROyhmdW5jdGlvbihlKXtlLlBBR0U9InBhZ2UiLGUuVEFCTEU9InRhYmxlIn0pKFF8fChRPXt9KSk7dmFyIFc7KGZ1bmN0aW9uKGUpe2UuRURJVD0iZWRpdCIsZS5DTEVBTj0iY2xlYW4iLGUuUkVBRE9OTFk9InJlYWRvbmx5IixlLkZPUk09ImZvcm0iLGUuUFJJTlQ9InByaW50IixlLkRFU0lHTj0iZGVzaWduIn0pKFd8fChXPXt9KSk7dmFyIHE7KGZ1bmN0aW9uKGUpe2UuSEVBREVSPSJoZWFkZXIiLGUuTUFJTj0ibWFpbiIsZS5GT09URVI9ImZvb3RlciJ9KShxfHwocT17fSkpO3ZhciBaOyhmdW5jdGlvbihlKXtlLlBBR0lORz0icGFnaW5nIixlLkNPTlRJTlVJVFk9ImNvbnRpbnVpdHkifSkoWnx8KFo9e30pKTt2YXIgSjsoZnVuY3Rpb24oZSl7ZS5WRVJUSUNBTD0idmVydGljYWwiLGUuSE9SSVpPTlRBTD0iaG9yaXpvbnRhbCJ9KShKfHwoSj17fSkpO3ZhciBqOyhmdW5jdGlvbihlKXtlLkJSRUFLX0FMTD0iYnJlYWstYWxsIixlLkJSRUFLX1dPUkQ9ImJyZWFrLXdvcmQifSkoanx8KGo9e30pKTt2YXIgJDsoZnVuY3Rpb24oZSl7ZS5TUEVFRD0ic3BlZWQiLGUuQ09NUEFUSUJJTElUWT0iY29tcGF0aWJpbGl0eSJ9KSgkfHwoJD17fSkpO3ZhciBEOyhmdW5jdGlvbihlKXtlLkxFRlQ9ImxlZnQiLGUuQ0VOVEVSPSJjZW50ZXIiLGUuUklHSFQ9InJpZ2h0IixlLkFMSUdOTUVOVD0iYWxpZ25tZW50IixlLkpVU1RJRlk9Imp1c3RpZnkifSkoRHx8KEQ9e30pKTt2YXIgZWU7KGZ1bmN0aW9uKGUpe2UuQUxMPSJhbGwiLGUuRU1QVFk9ImVtcHR5IixlLkVYVEVSTkFMPSJleHRlcm5hbCIsZS5JTlRFUk5BTD0iaW50ZXJuYWwiLGUuREFTSD0iZGFzaCJ9KShlZXx8KGVlPXt9KSk7dmFyIHRlOyhmdW5jdGlvbihlKXtlLlRPUD0idG9wIixlLlJJR0hUPSJyaWdodCIsZS5CT1RUT009ImJvdHRvbSIsZS5MRUZUPSJsZWZ0In0pKHRlfHwodGU9e30pKTt2YXIgaWU7KGZ1bmN0aW9uKGUpe2UuRk9SV0FSRD0iZm9yd2FyZCIsZS5CQUNLPSJiYWNrIn0pKGllfHwoaWU9e30pKTt2YXIgazsoZnVuY3Rpb24oZSl7ZS5DT05UQUlOPSJjb250YWluIixlLkNPVkVSPSJjb3ZlciJ9KShrfHwoaz17fSkpO3ZhciBtOyhmdW5jdGlvbihlKXtlLlJFUEVBVD0icmVwZWF0IixlLk5PX1JFUEVBVD0ibm8tcmVwZWF0IixlLlJFUEVBVF9YPSJyZXBlYXQteCIsZS5SRVBFQVRfWT0icmVwZWF0LXkifSkobXx8KG09e30pKSxrLkNPVkVSLG0uTk9fUkVQRUFUO3ZhciBGOyhmdW5jdGlvbihlKXtlLlRPUD0idG9wIixlLk1JRERMRT0ibWlkZGxlIixlLkJPVFRPTT0iYm90dG9tIn0pKEZ8fChGPXt9KSksRi5CT1RUT00sVC5IQUxGLFQuSEFMRjtjb25zdCB1ZT17UEFHRV9OTzoie3BhZ2VOb30iLFBBR0VfQ09VTlQ6IntwYWdlQ291bnR9In07RC5DRU5URVIsdWUuUEFHRV9OTyxJLkFSQUJJQyxGLkJPVFRPTTt2YXIgeTsoZnVuY3Rpb24oZSl7ZS5URVhUPSJ0ZXh0IixlLklNQUdFPSJpbWFnZSJ9KSh5fHwoeT17fSkpLHkuVEVYVCxJLkFSQUJJQzt2YXIgVTsoZnVuY3Rpb24oZSl7ZS5QQUdFPSJwYWdlIixlLkNPTlRJTlVJVFk9ImNvbnRpbnVpdHkifSkoVXx8KFU9e30pKSxVLkNPTlRJTlVJVFk7ZnVuY3Rpb24gRWUoZSxzKXtjb25zdCBFPU9iamVjdC5rZXlzKGUpLEE9T2JqZWN0LmtleXMocyk7aWYoRS5sZW5ndGghPT1BLmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IFI9MDtSPEUubGVuZ3RoO1IrKyl7Y29uc3QgYT1FW1JdO2lmKGEhPT0idmFsdWUiJiYhKGE9PT0iZ3JvdXBJZHMiJiZBcnJheS5pc0FycmF5KGVbYV0pJiZBcnJheS5pc0FycmF5KHNbYV0pJiZsZShlW2FdLHNbYV0pKSYmZVthXSE9PXNbYV0pcmV0dXJuITF9cmV0dXJuITB9ZnVuY3Rpb24gQihlLHM9e30pe2NvbnN0e2V4dHJhUGlja0F0dHJzOkV9PXMsQT1bLi4ub2VdO0UmJkEucHVzaCguLi5FKTtjb25zdCBSPXt2YWx1ZTplLnZhbHVlPT09UD9gCmA6ZS52YWx1ZX07cmV0dXJuIEEuZm9yRWFjaChhPT57Y29uc3QgcD1lW2FdO3AhPT12b2lkIDAmJihSW2FdPXApfSksUn1mdW5jdGlvbiBoKGUscz17fSl7Y29uc3R7ZXh0cmFQaWNrQXR0cnM6RSxpc0NsYXNzaWZ5QXJlYTpBPSExLGlzQ2xvbmU6Uj0hMH09cyxhPVI/SChlKTplLHA9W107bGV0IGk9MDtmb3IoO2k8YS5sZW5ndGg7KXtsZXQgdD1hW2ldO2lmKGk9PT0wJiZ0LnZhbHVlPT09UCYmIXQubGlzdElkJiYoIXQudHlwZXx8dC50eXBlPT09bC5URVhUKSl7aSsrO2NvbnRpbnVlfWlmKHQuYXJlYUlkKXtjb25zdCBuPXQuYXJlYUlkLHU9dC5hcmVhLGM9W107Zm9yKDtpPGEubGVuZ3RoOyl7Y29uc3Qgbz1hW2ldO2lmKG4hPT1vLmFyZWFJZCl7aS0tO2JyZWFrfWRlbGV0ZSBvLmFyZWEsZGVsZXRlIG8uYXJlYUlkLGMucHVzaChvKSxpKyt9Y29uc3Qgcj1oKGMscyk7aWYoQSl7Y29uc3Qgbz17dHlwZTpsLkFSRUEsdmFsdWU6IiIsYXJlYUlkOm4sYXJlYTp1fTtvLnZhbHVlTGlzdD1yLHQ9b31lbHNle3Auc3BsaWNlKGksMCwuLi5yKTtjb250aW51ZX19ZWxzZSBpZih0LnRpdGxlSWQmJnQubGV2ZWwpe2NvbnN0IG49dC50aXRsZUlkO2lmKG4pe2NvbnN0IHU9dC5sZXZlbCxjPXt0eXBlOmwuVElUTEUsdGl0bGU6dC50aXRsZSx0aXRsZUlkOm4sdmFsdWU6IiIsbGV2ZWw6dX0scj1bXTtmb3IoO2k8YS5sZW5ndGg7KXtjb25zdCBvPWFbaV07aWYobiE9PW8udGl0bGVJZCl7aS0tO2JyZWFrfWRlbGV0ZSBvLmxldmVsLGRlbGV0ZSBvLnRpdGxlLHIucHVzaChvKSxpKyt9Yy52YWx1ZUxpc3Q9aChyLHMpLHQ9Y319ZWxzZSBpZih0Lmxpc3RJZCYmdC5saXN0VHlwZSl7Y29uc3Qgbj10Lmxpc3RJZDtpZihuKXtjb25zdCB1PXQubGlzdFR5cGUsYz10Lmxpc3RTdHlsZSxyPXt0eXBlOmwuTElTVCx2YWx1ZToiIixsaXN0SWQ6bixsaXN0VHlwZTp1LGxpc3RTdHlsZTpjfSxvPVtdO2Zvcig7aTxhLmxlbmd0aDspe2NvbnN0IEM9YVtpXTtpZihuIT09Qy5saXN0SWQpe2ktLTticmVha31kZWxldGUgQy5saXN0VHlwZSxkZWxldGUgQy5saXN0U3R5bGUsby5wdXNoKEMpLGkrK31yLnZhbHVlTGlzdD1oKG8scyksdD1yfX1lbHNlIGlmKHQudHlwZT09PWwuVEFCTEUpe2lmKHQucGFnaW5nSWQpe2xldCBuPWkrMSx1PTA7Zm9yKDtuPGEubGVuZ3RoOyl7Y29uc3QgYz1hW25dO2lmKGMucGFnaW5nSWQ9PT10LnBhZ2luZ0lkKXQuaGVpZ2h0Kz1jLmhlaWdodCx0LnRyTGlzdC5wdXNoKC4uLmMudHJMaXN0KSxuKyssdSsrO2Vsc2UgYnJlYWt9aSs9dX1pZih0LnRyTGlzdClmb3IobGV0IG49MDtuPHQudHJMaXN0Lmxlbmd0aDtuKyspe2NvbnN0IHU9dC50ckxpc3Rbbl07ZGVsZXRlIHUuaWQ7Zm9yKGxldCBjPTA7Yzx1LnRkTGlzdC5sZW5ndGg7YysrKXtjb25zdCByPXUudGRMaXN0W2NdLG89e2NvbHNwYW46ci5jb2xzcGFuLHJvd3NwYW46ci5yb3dzcGFuLHZhbHVlOmgoci52YWx1ZSxYKGcoe30scykse2lzQ2xhc3NpZnlBcmVhOiExfSkpfTtzZS5mb3JFYWNoKEM9Pntjb25zdCBTPXJbQ107UyE9PXZvaWQgMCYmKG9bQ109Uyl9KSx1LnRkTGlzdFtjXT1vfX19ZWxzZSBpZih0LnR5cGU9PT1sLkhZUEVSTElOSyl7Y29uc3Qgbj10Lmh5cGVybGlua0lkO2lmKG4pe2NvbnN0IHU9e3R5cGU6bC5IWVBFUkxJTkssdmFsdWU6IiIsdXJsOnQudXJsfSxjPVtdO2Zvcig7aTxhLmxlbmd0aDspe2NvbnN0IHI9YVtpXTtpZihuIT09ci5oeXBlcmxpbmtJZCl7aS0tO2JyZWFrfWRlbGV0ZSByLnR5cGUsZGVsZXRlIHIudXJsLGMucHVzaChyKSxpKyt9dS52YWx1ZUxpc3Q9aChjLHMpLHQ9dX19ZWxzZSBpZih0LnR5cGU9PT1sLkRBVEUpe2NvbnN0IG49dC5kYXRlSWQ7aWYobil7Y29uc3QgdT17dHlwZTpsLkRBVEUsdmFsdWU6IiIsZGF0ZUZvcm1hdDp0LmRhdGVGb3JtYXR9LGM9W107Zm9yKDtpPGEubGVuZ3RoOyl7Y29uc3Qgcj1hW2ldO2lmKG4hPT1yLmRhdGVJZCl7aS0tO2JyZWFrfWRlbGV0ZSByLnR5cGUsZGVsZXRlIHIuZGF0ZUZvcm1hdCxjLnB1c2gociksaSsrfXUudmFsdWVMaXN0PWgoYyxzKSx0PXV9fWVsc2UgaWYodC5jb250cm9sSWQpe2NvbnN0IG49dC5jb250cm9sSWQ7aWYodC5jb250cm9sQ29tcG9uZW50PT09TC5QUkVGSVgpe2NvbnN0IHU9W107bGV0IGM9ITEscj1pO2Zvcig7cjxhLmxlbmd0aDspe2NvbnN0IG89YVtyXTtpZihuIT09by5jb250cm9sSWQpYnJlYWs7by5jb250cm9sQ29tcG9uZW50PT09TC5WQUxVRSYmKGRlbGV0ZSBvLmNvbnRyb2wsZGVsZXRlIG8uY29udHJvbElkLHUucHVzaChvKSksby5jb250cm9sQ29tcG9uZW50PT09TC5QT1NURklYJiYoYz0hMCkscisrfWlmKGMpe2NvbnN0IG89dyh0LGNlKSxDPWcoZyh7fSx0LmNvbnRyb2wpLG8pLFM9WChnKHt9LHcodCxyZSkpLHt0eXBlOmwuQ09OVFJPTCx2YWx1ZToiIixjb250cm9sOkMsY29udHJvbElkOm59KTtTLmNvbnRyb2wudmFsdWU9aCh1LHMpLHQ9QihTLHtleHRyYVBpY2tBdHRyczpFfSksaSs9ci1pLTF9fWlmKHQuY29udHJvbENvbXBvbmVudCYmKGRlbGV0ZSB0LmNvbnRyb2wsZGVsZXRlIHQuY29udHJvbElkLHQuY29udHJvbENvbXBvbmVudCE9PUwuVkFMVUUmJnQuY29udHJvbENvbXBvbmVudCE9PUwuUFJFX1RFWFQmJnQuY29udHJvbENvbXBvbmVudCE9PUwuUE9TVF9URVhUKSl7aSsrO2NvbnRpbnVlfX1jb25zdCB4PUIodCx7ZXh0cmFQaWNrQXR0cnM6RX0pO2lmKCF0LnR5cGV8fHQudHlwZT09PWwuVEVYVHx8dC50eXBlPT09bC5TVUJTQ1JJUFR8fHQudHlwZT09PWwuU1VQRVJTQ1JJUFQpZm9yKDtpPGEubGVuZ3RoOyl7Y29uc3Qgbj1hW2krMV07aWYoaSsrLG4mJkVlKHgsQihuLHtleHRyYVBpY2tBdHRyczpFfSkpKXtjb25zdCB1PW4udmFsdWU9PT1QP2AKYDpuLnZhbHVlO3gudmFsdWUrPXV9ZWxzZSBicmVha31lbHNlIGkrKztwLnB1c2goeCl9cmV0dXJuIHB9b25tZXNzYWdlPWU9Pntjb25zdCBzPWUuZGF0YSx7b3B0aW9uczpFLGRhdGE6QX09cyx7ZXh0cmFQaWNrQXR0cnM6Uj1bXX09RXx8e30sYT17aGVhZGVyOmgoQS5oZWFkZXIse2V4dHJhUGlja0F0dHJzOlIsaXNDbG9uZTohMX0pLG1haW46aChBLm1haW4se2V4dHJhUGlja0F0dHJzOlIsaXNDbGFzc2lmeUFyZWE6ITAsaXNDbG9uZTohMX0pLGZvb3RlcjpoKEEuZm9vdGVyLHtleHRyYVBpY2tBdHRyczpSLGlzQ2xvbmU6ITF9KX07cG9zdE1lc3NhZ2UoYSl9fSkoKTt9KSgpOwo=";
15241
+ const encodedJs = "KCgpPT57dmFyIGZlPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSxUZT1PYmplY3QuZGVmaW5lUHJvcGVydGllczt2YXIgSWU9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnM7dmFyIGFlPU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7dmFyIEFlPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksZGU9T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTt2YXIgbmU9KFQsSSxkKT0+SSBpbiBUP2ZlKFQsSSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6ZH0pOlRbSV09ZCxnPShULEkpPT57Zm9yKHZhciBkIGluIEl8fChJPXt9KSlBZS5jYWxsKEksZCkmJm5lKFQsZCxJW2RdKTtpZihhZSlmb3IodmFyIGQgb2YgYWUoSSkpZGUuY2FsbChJLGQpJiZuZShULGQsSVtkXSk7cmV0dXJuIFR9LFg9KFQsSSk9PlRlKFQsSWUoSSkpOyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0Ijt2YXIgVDsoZnVuY3Rpb24oZSl7ZS5IQUxGPSJoYWxmIixlLk9ORV9USElSRD0ib25lLXRoaXJkIixlLlFVQVJURVI9InF1YXJ0ZXIifSkoVHx8KFQ9e30pKTt2YXIgSTsoZnVuY3Rpb24oZSl7ZS5BUkFCSUM9ImFyYWJpYyIsZS5DSElORVNFPSJjaGluZXNlIn0pKEl8fChJPXt9KSk7dmFyIGQ7KGZ1bmN0aW9uKGUpe2UuSU5MSU5FPSJpbmxpbmUiLGUuQkxPQ0s9ImJsb2NrIixlLlNVUlJPVU5EPSJzdXJyb3VuZCIsZS5GTE9BVF9UT1A9ImZsb2F0LXRvcCIsZS5GTE9BVF9CT1RUT009ImZsb2F0LWJvdHRvbSJ9KShkfHwoZD17fSkpO3ZhciBfOyhmdW5jdGlvbihlKXtlLkJFRk9SRT0iYmVmb3JlIixlLkFGVEVSPSJhZnRlciIsZS5PVVRFUl9CRUZPUkU9Im91dGVyLWJlZm9yZSIsZS5PVVRFUl9BRlRFUj0ib3V0ZXItYWZ0ZXIifSkoX3x8KF89e30pKTt2YXIgTTsoZnVuY3Rpb24oZSl7ZS5ST1c9InJvdyIsZS5DT0xVTU49ImNvbHVtbiJ9KShNfHwoTT17fSkpO2NvbnN0IFA9Ilx1MjAwQiI7VC5IQUxGKyIiLDEvMixULk9ORV9USElSRCsiIiwxLzMsVC5RVUFSVEVSKyIiLDEvNDtmdW5jdGlvbiBIKGUpe2lmKHR5cGVvZiBzdHJ1Y3R1cmVkQ2xvbmU9PSJmdW5jdGlvbiIpcmV0dXJuIHN0cnVjdHVyZWRDbG9uZShlKTtpZighZXx8dHlwZW9mIGUhPSJvYmplY3QiKXJldHVybiBlO2xldCBzPXt9O3JldHVybiBBcnJheS5pc0FycmF5KGUpP3M9ZS5tYXAoRT0+SChFKSk6T2JqZWN0LmtleXMoZSkuZm9yRWFjaChFPT57c1tFXT1IKGVbRV0pfSksc31mdW5jdGlvbiB3KGUscyl7Y29uc3QgRT17fTtmb3IoY29uc3QgQSBpbiBlKXMuaW5jbHVkZXMoQSkmJihFW0FdPWVbQV0pO3JldHVybiBFfWZ1bmN0aW9uIGxlKGUscyl7cmV0dXJuIGUubGVuZ3RoIT09cy5sZW5ndGg/ITE6IWUuc29tZShFPT4hcy5pbmNsdWRlcyhFKSl9dmFyIGw7KGZ1bmN0aW9uKGUpe2UuVEVYVD0idGV4dCIsZS5JTUFHRT0iaW1hZ2UiLGUuVEFCTEU9InRhYmxlIixlLkhZUEVSTElOSz0iaHlwZXJsaW5rIixlLlNVUEVSU0NSSVBUPSJzdXBlcnNjcmlwdCIsZS5TVUJTQ1JJUFQ9InN1YnNjcmlwdCIsZS5TRVBBUkFUT1I9InNlcGFyYXRvciIsZS5QQUdFX0JSRUFLPSJwYWdlQnJlYWsiLGUuQ09OVFJPTD0iY29udHJvbCIsZS5BUkVBPSJhcmVhIixlLkNIRUNLQk9YPSJjaGVja2JveCIsZS5SQURJTz0icmFkaW8iLGUuTEFURVg9ImxhdGV4IixlLlRBQj0idGFiIixlLkRBVEU9ImRhdGUiLGUuQkxPQ0s9ImJsb2NrIixlLlRJVExFPSJ0aXRsZSIsZS5MSVNUPSJsaXN0In0pKGx8fChsPXt9KSk7Y29uc3QgcmU9WyJyb3dGbGV4Iiwicm93TWFyZ2luIl0sb2U9WyJ0eXBlIiwiZm9udCIsInNpemUiLCJib2xkIiwiY29sb3IiLCJpdGFsaWMiLCJoaWdobGlnaHQiLCJ1bmRlcmxpbmUiLCJzdHJpa2VvdXQiLCJyb3dGbGV4Iiwicm93TWFyZ2luIiwiZGFzaEFycmF5IiwidHJMaXN0IiwidGFibGVUb29sRGlzYWJsZWQiLCJib3JkZXJUeXBlIiwiYm9yZGVyQ29sb3IiLCJ0cmFuc2xhdGVYIiwid2lkdGgiLCJoZWlnaHQiLCJ1cmwiLCJjb2xncm91cCIsInZhbHVlTGlzdCIsImNvbnRyb2wiLCJjaGVja2JveCIsInJhZGlvIiwiZGF0ZUZvcm1hdCIsImJsb2NrIiwibGV2ZWwiLCJ0aXRsZSIsImxpc3RUeXBlIiwibGlzdFN0eWxlIiwibGlzdFdyYXAiLCJncm91cElkcyIsImNvbmNlcHRJZCIsImltZ0Rpc3BsYXkiLCJpbWdGbG9hdFBvc2l0aW9uIiwiaW1nVG9vbERpc2FibGVkIiwidGV4dERlY29yYXRpb24iLCJleHRlbnNpb24iLCJleHRlcm5hbElkIiwiYXJlYUlkIiwiYXJlYSIsImhpZGUiXSxzZT1bImNvbmNlcHRJZCIsImV4dGVuc2lvbiIsImV4dGVybmFsSWQiLCJ2ZXJ0aWNhbEFsaWduIiwiYmFja2dyb3VuZENvbG9yIiwiYm9yZGVyVHlwZXMiLCJzbGFzaFR5cGVzIiwiZGlzYWJsZWQiLCJkZWxldGFibGUiXSxjZT1bImZvbnQiLCJzaXplIiwiYm9sZCIsImhpZ2hsaWdodCIsIml0YWxpYyIsInN0cmlrZW91dCJdO2wuVEVYVCxsLkhZUEVSTElOSyxsLlNVQlNDUklQVCxsLlNVUEVSU0NSSVBULGwuQ09OVFJPTCxsLkRBVEUsbC5JTUFHRSxsLkxBVEVYLGwuQkxPQ0ssbC5QQUdFX0JSRUFLLGwuU0VQQVJBVE9SLGwuVEFCTEUsbC5USVRMRSxsLkxJU1Q7dmFyIE47KGZ1bmN0aW9uKGUpe2UuVUw9InVsIixlLk9MPSJvbCJ9KShOfHwoTj17fSkpO3ZhciBPOyhmdW5jdGlvbihlKXtlLkRJU0M9ImRpc2MiLGUuQ0lSQ0xFPSJjaXJjbGUiLGUuU1FVQVJFPSJzcXVhcmUiLGUuQ0hFQ0tCT1g9ImNoZWNrYm94In0pKE98fChPPXt9KSk7dmFyIGI7KGZ1bmN0aW9uKGUpe2UuREVDSU1BTD0iZGVjaW1hbCJ9KShifHwoYj17fSkpO3ZhciB2OyhmdW5jdGlvbihlKXtlW2UuRElTQz1PLkRJU0NdPSJESVNDIixlW2UuQ0lSQ0xFPU8uQ0lSQ0xFXT0iQ0lSQ0xFIixlW2UuU1FVQVJFPU8uU1FVQVJFXT0iU1FVQVJFIixlW2UuREVDSU1BTD1iLkRFQ0lNQUxdPSJERUNJTUFMIixlW2UuQ0hFQ0tCT1g9Ty5DSEVDS0JPWF09IkNIRUNLQk9YIn0pKHZ8fCh2PXt9KSksTy5ESVNDKyIiLE8uQ0lSQ0xFKyIiLE8uU1FVQVJFKyIiLE8uQ0hFQ0tCT1grIiIsTi5PTCsiIixOLlVMKyIiLHYuRElTQysiIix2LkNJUkNMRSsiIix2LlNRVUFSRSsiIix2LkRFQ0lNQUwrIiIsdi5DSEVDS0JPWCsiIjt2YXIgZjsoZnVuY3Rpb24oZSl7ZS5GSVJTVD0iZmlyc3QiLGUuU0VDT05EPSJzZWNvbmQiLGUuVEhJUkQ9InRoaXJkIixlLkZPVVJUSD0iZm91cnRoIixlLkZJRlRIPSJmaWZ0aCIsZS5TSVhUSD0ic2l4dGgifSkoZnx8KGY9e30pKSxmLkZJUlNUKyIiLGYuU0VDT05EKyIiLGYuVEhJUkQrIiIsZi5GT1VSVEgrIiIsZi5GSUZUSCsiIixmLlNJWFRIKyIiLGYuRklSU1QrIiIsZi5TRUNPTkQrIiIsZi5USElSRCsiIixmLkZPVVJUSCsiIixmLkZJRlRIKyIiLGYuU0lYVEgrIiIsZi5GSVJTVCxmLlNFQ09ORCxmLlRISVJELGYuRk9VUlRILGYuRklGVEgsZi5TSVhUSDt2YXIgSzsoZnVuY3Rpb24oZSl7ZS5JRlJBTUU9ImlmcmFtZSIsZS5WSURFTz0idmlkZW8ifSkoS3x8KEs9e30pKTt2YXIgRzsoZnVuY3Rpb24oZSl7ZS5URVhUPSJ0ZXh0IixlLlNFTEVDVD0ic2VsZWN0IixlLkNIRUNLQk9YPSJjaGVja2JveCIsZS5SQURJTz0icmFkaW8iLGUuREFURT0iZGF0ZSIsZS5OVU1CRVI9Im51bWJlciJ9KShHfHwoRz17fSkpO3ZhciBMOyhmdW5jdGlvbihlKXtlLlBSRUZJWD0icHJlZml4IixlLlBPU1RGSVg9InBvc3RmaXgiLGUuUFJFX1RFWFQ9InByZVRleHQiLGUuUE9TVF9URVhUPSJwb3N0VGV4dCIsZS5QTEFDRUhPTERFUj0icGxhY2Vob2xkZXIiLGUuVkFMVUU9InZhbHVlIixlLkNIRUNLQk9YPSJjaGVja2JveCIsZS5SQURJTz0icmFkaW8ifSkoTHx8KEw9e30pKTt2YXIgejsoZnVuY3Rpb24oZSl7ZS5ST1dfU1RBUlQ9InJvd1N0YXJ0IixlLlZBTFVFX1NUQVJUPSJ2YWx1ZVN0YXJ0In0pKHp8fCh6PXt9KSk7dmFyIFk7KGZ1bmN0aW9uKGUpe2UuQUNUSVZFPSJhY3RpdmUiLGUuSU5BQ1RJVkU9ImluYWN0aXZlIn0pKFl8fChZPXt9KSk7dmFyIFY7KGZ1bmN0aW9uKGUpe2UuQ09NUE9ORU5UPSJjb21wb25lbnQiLGUuTUVOVT0ibWVudSIsZS5NQUlOPSJtYWluIixlLkZPT1RFUj0iZm9vdGVyIixlLkNPTlRFWFRNRU5VPSJjb250ZXh0bWVudSIsZS5QT1BVUD0icG9wdXAiLGUuQ0FUQUxPRz0iY2F0YWxvZyIsZS5DT01NRU5UPSJjb21tZW50In0pKFZ8fChWPXt9KSk7dmFyIFE7KGZ1bmN0aW9uKGUpe2UuUEFHRT0icGFnZSIsZS5UQUJMRT0idGFibGUifSkoUXx8KFE9e30pKTt2YXIgVzsoZnVuY3Rpb24oZSl7ZS5FRElUPSJlZGl0IixlLkNMRUFOPSJjbGVhbiIsZS5SRUFET05MWT0icmVhZG9ubHkiLGUuRk9STT0iZm9ybSIsZS5QUklOVD0icHJpbnQiLGUuREVTSUdOPSJkZXNpZ24iLGUuR1JBRkZJVEk9ImdyYWZmaXRpIn0pKFd8fChXPXt9KSk7dmFyIHE7KGZ1bmN0aW9uKGUpe2UuSEVBREVSPSJoZWFkZXIiLGUuTUFJTj0ibWFpbiIsZS5GT09URVI9ImZvb3RlciJ9KShxfHwocT17fSkpO3ZhciBaOyhmdW5jdGlvbihlKXtlLlBBR0lORz0icGFnaW5nIixlLkNPTlRJTlVJVFk9ImNvbnRpbnVpdHkifSkoWnx8KFo9e30pKTt2YXIgSjsoZnVuY3Rpb24oZSl7ZS5WRVJUSUNBTD0idmVydGljYWwiLGUuSE9SSVpPTlRBTD0iaG9yaXpvbnRhbCJ9KShKfHwoSj17fSkpO3ZhciBqOyhmdW5jdGlvbihlKXtlLkJSRUFLX0FMTD0iYnJlYWstYWxsIixlLkJSRUFLX1dPUkQ9ImJyZWFrLXdvcmQifSkoanx8KGo9e30pKTt2YXIgJDsoZnVuY3Rpb24oZSl7ZS5TUEVFRD0ic3BlZWQiLGUuQ09NUEFUSUJJTElUWT0iY29tcGF0aWJpbGl0eSJ9KSgkfHwoJD17fSkpO3ZhciBEOyhmdW5jdGlvbihlKXtlLkxFRlQ9ImxlZnQiLGUuQ0VOVEVSPSJjZW50ZXIiLGUuUklHSFQ9InJpZ2h0IixlLkFMSUdOTUVOVD0iYWxpZ25tZW50IixlLkpVU1RJRlk9Imp1c3RpZnkifSkoRHx8KEQ9e30pKTt2YXIgZWU7KGZ1bmN0aW9uKGUpe2UuQUxMPSJhbGwiLGUuRU1QVFk9ImVtcHR5IixlLkVYVEVSTkFMPSJleHRlcm5hbCIsZS5JTlRFUk5BTD0iaW50ZXJuYWwiLGUuREFTSD0iZGFzaCJ9KShlZXx8KGVlPXt9KSk7dmFyIHRlOyhmdW5jdGlvbihlKXtlLlRPUD0idG9wIixlLlJJR0hUPSJyaWdodCIsZS5CT1RUT009ImJvdHRvbSIsZS5MRUZUPSJsZWZ0In0pKHRlfHwodGU9e30pKTt2YXIgaWU7KGZ1bmN0aW9uKGUpe2UuRk9SV0FSRD0iZm9yd2FyZCIsZS5CQUNLPSJiYWNrIn0pKGllfHwoaWU9e30pKTt2YXIgazsoZnVuY3Rpb24oZSl7ZS5DT05UQUlOPSJjb250YWluIixlLkNPVkVSPSJjb3ZlciJ9KShrfHwoaz17fSkpO3ZhciBtOyhmdW5jdGlvbihlKXtlLlJFUEVBVD0icmVwZWF0IixlLk5PX1JFUEVBVD0ibm8tcmVwZWF0IixlLlJFUEVBVF9YPSJyZXBlYXQteCIsZS5SRVBFQVRfWT0icmVwZWF0LXkifSkobXx8KG09e30pKSxrLkNPVkVSLG0uTk9fUkVQRUFUO3ZhciBGOyhmdW5jdGlvbihlKXtlLlRPUD0idG9wIixlLk1JRERMRT0ibWlkZGxlIixlLkJPVFRPTT0iYm90dG9tIn0pKEZ8fChGPXt9KSksRi5CT1RUT00sVC5IQUxGLFQuSEFMRjtjb25zdCB1ZT17UEFHRV9OTzoie3BhZ2VOb30iLFBBR0VfQ09VTlQ6IntwYWdlQ291bnR9In07RC5DRU5URVIsdWUuUEFHRV9OTyxJLkFSQUJJQyxGLkJPVFRPTTt2YXIgeTsoZnVuY3Rpb24oZSl7ZS5URVhUPSJ0ZXh0IixlLklNQUdFPSJpbWFnZSJ9KSh5fHwoeT17fSkpLHkuVEVYVCxJLkFSQUJJQzt2YXIgVTsoZnVuY3Rpb24oZSl7ZS5QQUdFPSJwYWdlIixlLkNPTlRJTlVJVFk9ImNvbnRpbnVpdHkifSkoVXx8KFU9e30pKSxVLkNPTlRJTlVJVFk7ZnVuY3Rpb24gRWUoZSxzKXtjb25zdCBFPU9iamVjdC5rZXlzKGUpLEE9T2JqZWN0LmtleXMocyk7aWYoRS5sZW5ndGghPT1BLmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IFI9MDtSPEUubGVuZ3RoO1IrKyl7Y29uc3QgYT1FW1JdO2lmKGEhPT0idmFsdWUiJiYhKGE9PT0iZ3JvdXBJZHMiJiZBcnJheS5pc0FycmF5KGVbYV0pJiZBcnJheS5pc0FycmF5KHNbYV0pJiZsZShlW2FdLHNbYV0pKSYmZVthXSE9PXNbYV0pcmV0dXJuITF9cmV0dXJuITB9ZnVuY3Rpb24gQihlLHM9e30pe2NvbnN0e2V4dHJhUGlja0F0dHJzOkV9PXMsQT1bLi4ub2VdO0UmJkEucHVzaCguLi5FKTtjb25zdCBSPXt2YWx1ZTplLnZhbHVlPT09UD9gCmA6ZS52YWx1ZX07cmV0dXJuIEEuZm9yRWFjaChhPT57Y29uc3QgcD1lW2FdO3AhPT12b2lkIDAmJihSW2FdPXApfSksUn1mdW5jdGlvbiBoKGUscz17fSl7Y29uc3R7ZXh0cmFQaWNrQXR0cnM6RSxpc0NsYXNzaWZ5QXJlYTpBPSExLGlzQ2xvbmU6Uj0hMH09cyxhPVI/SChlKTplLHA9W107bGV0IGk9MDtmb3IoO2k8YS5sZW5ndGg7KXtsZXQgdD1hW2ldO2lmKGk9PT0wJiZ0LnZhbHVlPT09UCYmIXQubGlzdElkJiYoIXQudHlwZXx8dC50eXBlPT09bC5URVhUKSl7aSsrO2NvbnRpbnVlfWlmKHQuYXJlYUlkKXtjb25zdCBuPXQuYXJlYUlkLHU9dC5hcmVhLGM9W107Zm9yKDtpPGEubGVuZ3RoOyl7Y29uc3Qgbz1hW2ldO2lmKG4hPT1vLmFyZWFJZCl7aS0tO2JyZWFrfWRlbGV0ZSBvLmFyZWEsZGVsZXRlIG8uYXJlYUlkLGMucHVzaChvKSxpKyt9Y29uc3Qgcj1oKGMscyk7aWYoQSl7Y29uc3Qgbz17dHlwZTpsLkFSRUEsdmFsdWU6IiIsYXJlYUlkOm4sYXJlYTp1fTtvLnZhbHVlTGlzdD1yLHQ9b31lbHNle3Auc3BsaWNlKGksMCwuLi5yKTtjb250aW51ZX19ZWxzZSBpZih0LnRpdGxlSWQmJnQubGV2ZWwpe2NvbnN0IG49dC50aXRsZUlkO2lmKG4pe2NvbnN0IHU9dC5sZXZlbCxjPXt0eXBlOmwuVElUTEUsdGl0bGU6dC50aXRsZSx0aXRsZUlkOm4sdmFsdWU6IiIsbGV2ZWw6dX0scj1bXTtmb3IoO2k8YS5sZW5ndGg7KXtjb25zdCBvPWFbaV07aWYobiE9PW8udGl0bGVJZCl7aS0tO2JyZWFrfWRlbGV0ZSBvLmxldmVsLGRlbGV0ZSBvLnRpdGxlLHIucHVzaChvKSxpKyt9Yy52YWx1ZUxpc3Q9aChyLHMpLHQ9Y319ZWxzZSBpZih0Lmxpc3RJZCYmdC5saXN0VHlwZSl7Y29uc3Qgbj10Lmxpc3RJZDtpZihuKXtjb25zdCB1PXQubGlzdFR5cGUsYz10Lmxpc3RTdHlsZSxyPXt0eXBlOmwuTElTVCx2YWx1ZToiIixsaXN0SWQ6bixsaXN0VHlwZTp1LGxpc3RTdHlsZTpjfSxvPVtdO2Zvcig7aTxhLmxlbmd0aDspe2NvbnN0IEM9YVtpXTtpZihuIT09Qy5saXN0SWQpe2ktLTticmVha31kZWxldGUgQy5saXN0VHlwZSxkZWxldGUgQy5saXN0U3R5bGUsby5wdXNoKEMpLGkrK31yLnZhbHVlTGlzdD1oKG8scyksdD1yfX1lbHNlIGlmKHQudHlwZT09PWwuVEFCTEUpe2lmKHQucGFnaW5nSWQpe2xldCBuPWkrMSx1PTA7Zm9yKDtuPGEubGVuZ3RoOyl7Y29uc3QgYz1hW25dO2lmKGMucGFnaW5nSWQ9PT10LnBhZ2luZ0lkKXQuaGVpZ2h0Kz1jLmhlaWdodCx0LnRyTGlzdC5wdXNoKC4uLmMudHJMaXN0KSxuKyssdSsrO2Vsc2UgYnJlYWt9aSs9dX1pZih0LnRyTGlzdClmb3IobGV0IG49MDtuPHQudHJMaXN0Lmxlbmd0aDtuKyspe2NvbnN0IHU9dC50ckxpc3Rbbl07ZGVsZXRlIHUuaWQ7Zm9yKGxldCBjPTA7Yzx1LnRkTGlzdC5sZW5ndGg7YysrKXtjb25zdCByPXUudGRMaXN0W2NdLG89e2NvbHNwYW46ci5jb2xzcGFuLHJvd3NwYW46ci5yb3dzcGFuLHZhbHVlOmgoci52YWx1ZSxYKGcoe30scykse2lzQ2xhc3NpZnlBcmVhOiExfSkpfTtzZS5mb3JFYWNoKEM9Pntjb25zdCBTPXJbQ107UyE9PXZvaWQgMCYmKG9bQ109Uyl9KSx1LnRkTGlzdFtjXT1vfX19ZWxzZSBpZih0LnR5cGU9PT1sLkhZUEVSTElOSyl7Y29uc3Qgbj10Lmh5cGVybGlua0lkO2lmKG4pe2NvbnN0IHU9e3R5cGU6bC5IWVBFUkxJTkssdmFsdWU6IiIsdXJsOnQudXJsfSxjPVtdO2Zvcig7aTxhLmxlbmd0aDspe2NvbnN0IHI9YVtpXTtpZihuIT09ci5oeXBlcmxpbmtJZCl7aS0tO2JyZWFrfWRlbGV0ZSByLnR5cGUsZGVsZXRlIHIudXJsLGMucHVzaChyKSxpKyt9dS52YWx1ZUxpc3Q9aChjLHMpLHQ9dX19ZWxzZSBpZih0LnR5cGU9PT1sLkRBVEUpe2NvbnN0IG49dC5kYXRlSWQ7aWYobil7Y29uc3QgdT17dHlwZTpsLkRBVEUsdmFsdWU6IiIsZGF0ZUZvcm1hdDp0LmRhdGVGb3JtYXR9LGM9W107Zm9yKDtpPGEubGVuZ3RoOyl7Y29uc3Qgcj1hW2ldO2lmKG4hPT1yLmRhdGVJZCl7aS0tO2JyZWFrfWRlbGV0ZSByLnR5cGUsZGVsZXRlIHIuZGF0ZUZvcm1hdCxjLnB1c2gociksaSsrfXUudmFsdWVMaXN0PWgoYyxzKSx0PXV9fWVsc2UgaWYodC5jb250cm9sSWQpe2NvbnN0IG49dC5jb250cm9sSWQ7aWYodC5jb250cm9sQ29tcG9uZW50PT09TC5QUkVGSVgpe2NvbnN0IHU9W107bGV0IGM9ITEscj1pO2Zvcig7cjxhLmxlbmd0aDspe2NvbnN0IG89YVtyXTtpZihuIT09by5jb250cm9sSWQpYnJlYWs7by5jb250cm9sQ29tcG9uZW50PT09TC5WQUxVRSYmKGRlbGV0ZSBvLmNvbnRyb2wsZGVsZXRlIG8uY29udHJvbElkLHUucHVzaChvKSksby5jb250cm9sQ29tcG9uZW50PT09TC5QT1NURklYJiYoYz0hMCkscisrfWlmKGMpe2NvbnN0IG89dyh0LGNlKSxDPWcoZyh7fSx0LmNvbnRyb2wpLG8pLFM9WChnKHt9LHcodCxyZSkpLHt0eXBlOmwuQ09OVFJPTCx2YWx1ZToiIixjb250cm9sOkMsY29udHJvbElkOm59KTtTLmNvbnRyb2wudmFsdWU9aCh1LHMpLHQ9QihTLHtleHRyYVBpY2tBdHRyczpFfSksaSs9ci1pLTF9fWlmKHQuY29udHJvbENvbXBvbmVudCYmKGRlbGV0ZSB0LmNvbnRyb2wsZGVsZXRlIHQuY29udHJvbElkLHQuY29udHJvbENvbXBvbmVudCE9PUwuVkFMVUUmJnQuY29udHJvbENvbXBvbmVudCE9PUwuUFJFX1RFWFQmJnQuY29udHJvbENvbXBvbmVudCE9PUwuUE9TVF9URVhUKSl7aSsrO2NvbnRpbnVlfX1jb25zdCB4PUIodCx7ZXh0cmFQaWNrQXR0cnM6RX0pO2lmKCF0LnR5cGV8fHQudHlwZT09PWwuVEVYVHx8dC50eXBlPT09bC5TVUJTQ1JJUFR8fHQudHlwZT09PWwuU1VQRVJTQ1JJUFQpZm9yKDtpPGEubGVuZ3RoOyl7Y29uc3Qgbj1hW2krMV07aWYoaSsrLG4mJkVlKHgsQihuLHtleHRyYVBpY2tBdHRyczpFfSkpKXtjb25zdCB1PW4udmFsdWU9PT1QP2AKYDpuLnZhbHVlO3gudmFsdWUrPXV9ZWxzZSBicmVha31lbHNlIGkrKztwLnB1c2goeCl9cmV0dXJuIHB9b25tZXNzYWdlPWU9Pntjb25zdCBzPWUuZGF0YSx7b3B0aW9uczpFLGRhdGE6QX09cyx7ZXh0cmFQaWNrQXR0cnM6Uj1bXX09RXx8e30sYT17aGVhZGVyOmgoQS5oZWFkZXIse2V4dHJhUGlja0F0dHJzOlIsaXNDbG9uZTohMX0pLG1haW46aChBLm1haW4se2V4dHJhUGlja0F0dHJzOlIsaXNDbGFzc2lmeUFyZWE6ITAsaXNDbG9uZTohMX0pLGZvb3RlcjpoKEEuZm9vdGVyLHtleHRyYVBpY2tBdHRyczpSLGlzQ2xvbmU6ITF9KX07cG9zdE1lc3NhZ2UoYSl9fSkoKTt9KSgpOwo=";
15224
15242
  const blob = typeof window !== "undefined" && window.Blob && new Blob([atob(encodedJs)], { type: "text/javascript;charset=utf-8" });
15225
15243
  function WorkerWrapper() {
15226
15244
  const objURL = blob && (window.URL || window.webkitURL).createObjectURL(blob);
@@ -18522,6 +18540,111 @@ class Badge {
18522
18540
  }
18523
18541
  }
18524
18542
  }
18543
+ class Graffiti {
18544
+ constructor(draw, data2) {
18545
+ __publicField(this, "draw");
18546
+ __publicField(this, "options");
18547
+ __publicField(this, "data");
18548
+ __publicField(this, "pageContainer");
18549
+ __publicField(this, "isDrawing", false);
18550
+ __publicField(this, "startStroke", null);
18551
+ this.draw = draw;
18552
+ this.options = draw.getOptions();
18553
+ this.data = data2 || [];
18554
+ this.pageContainer = draw.getPageContainer();
18555
+ this.register();
18556
+ }
18557
+ register() {
18558
+ this.pageContainer.addEventListener("mousedown", this.start.bind(this));
18559
+ this.pageContainer.addEventListener("mouseup", this.stop.bind(this));
18560
+ this.pageContainer.addEventListener("mouseleave", this.stop.bind(this));
18561
+ this.pageContainer.addEventListener("mousemove", this.drawing.bind(this));
18562
+ }
18563
+ start(evt) {
18564
+ if (!this.draw.isGraffitiMode())
18565
+ return;
18566
+ this.isDrawing = true;
18567
+ this.startStroke = {
18568
+ isBegin: true,
18569
+ lineWidth: this.options.graffiti.defaultLineWidth,
18570
+ lineColor: this.options.graffiti.defaultLineColor,
18571
+ linePoints: [evt.offsetX, evt.offsetY]
18572
+ };
18573
+ }
18574
+ stop() {
18575
+ this.isDrawing = false;
18576
+ }
18577
+ drawing(evt) {
18578
+ var _a;
18579
+ if (!this.isDrawing || !this.draw.isGraffitiMode())
18580
+ return;
18581
+ const { offsetX, offsetY } = evt;
18582
+ const DISTANCE = 2;
18583
+ if (this.startStroke && Math.abs(this.startStroke.linePoints[0] - offsetX) < DISTANCE && Math.abs(this.startStroke.linePoints[1] - offsetY) < DISTANCE) {
18584
+ return;
18585
+ }
18586
+ const pageNo = this.draw.getPageNo();
18587
+ let currentValue = this.data.find((item) => item.pageNo === pageNo);
18588
+ if (this.startStroke) {
18589
+ if (!currentValue) {
18590
+ currentValue = {
18591
+ pageNo,
18592
+ strokes: []
18593
+ };
18594
+ this.data.push(currentValue);
18595
+ }
18596
+ currentValue.strokes.push(this.startStroke);
18597
+ this.startStroke = null;
18598
+ }
18599
+ if (!((_a = currentValue == null ? void 0 : currentValue.strokes) == null ? void 0 : _a.length))
18600
+ return;
18601
+ currentValue.strokes.push({
18602
+ linePoints: [offsetX, offsetY]
18603
+ });
18604
+ this.draw.render({
18605
+ isCompute: false,
18606
+ isSetCursor: false,
18607
+ isSubmitHistory: false
18608
+ });
18609
+ }
18610
+ getValue() {
18611
+ return this.data;
18612
+ }
18613
+ compute() {
18614
+ const pageSize = this.draw.getPageRowList().length;
18615
+ for (let d = this.data.length - 1; d >= 0; d--) {
18616
+ const pageNo = this.data[d].pageNo;
18617
+ if (pageNo > pageSize - 1) {
18618
+ this.data.splice(d, 1);
18619
+ }
18620
+ }
18621
+ }
18622
+ clear() {
18623
+ this.data = [];
18624
+ }
18625
+ render(ctx, pageNo) {
18626
+ var _a;
18627
+ const strokes = (_a = this.data.find((item) => item.pageNo === pageNo)) == null ? void 0 : _a.strokes;
18628
+ if (!(strokes == null ? void 0 : strokes.length))
18629
+ return;
18630
+ const { graffiti: { defaultLineColor, defaultLineWidth }, scale } = this.options;
18631
+ ctx.save();
18632
+ for (let s = 0; s < strokes.length; s++) {
18633
+ const stroke = strokes[s];
18634
+ const { isBegin, lineColor, lineWidth, linePoints } = stroke;
18635
+ if (isBegin) {
18636
+ ctx.strokeStyle = lineColor || defaultLineColor;
18637
+ ctx.lineWidth = (lineWidth || defaultLineWidth) * scale;
18638
+ ctx.beginPath();
18639
+ ctx.moveTo(linePoints[0] * scale, linePoints[1] * scale);
18640
+ } else {
18641
+ ctx.lineTo(linePoints[0] * scale, linePoints[1] * scale);
18642
+ }
18643
+ ctx.stroke();
18644
+ }
18645
+ ctx.restore();
18646
+ }
18647
+ }
18525
18648
  class Draw {
18526
18649
  constructor(rootContainer, options, data2, listener, eventBus, override) {
18527
18650
  __publicField(this, "container");
@@ -18584,6 +18707,7 @@ class Draw {
18584
18707
  __publicField(this, "scrollObserver");
18585
18708
  __publicField(this, "selectionObserver");
18586
18709
  __publicField(this, "imageObserver");
18710
+ __publicField(this, "graffiti");
18587
18711
  __publicField(this, "LETTER_REG");
18588
18712
  __publicField(this, "WORD_LIKE_REG");
18589
18713
  __publicField(this, "rowList");
@@ -18649,6 +18773,7 @@ class Draw {
18649
18773
  this.lineBreakParticle = new LineBreakParticle(this);
18650
18774
  this.control = new Control(this);
18651
18775
  this.pageBorder = new PageBorder(this);
18776
+ this.graffiti = new Graffiti(this, data2.graffiti);
18652
18777
  this.scrollObserver = new ScrollObserver(this);
18653
18778
  this.selectionObserver = new SelectionObserver(this);
18654
18779
  this.imageObserver = new ImageObserver();
@@ -18687,7 +18812,11 @@ class Draw {
18687
18812
  footer: this.footer.getElementList()
18688
18813
  };
18689
18814
  const clonePrintModeData = deepClone(this.printModeData);
18690
- const editorDataKeys = ["header", "main", "footer"];
18815
+ const editorDataKeys = [
18816
+ "header",
18817
+ "main",
18818
+ "footer"
18819
+ ];
18691
18820
  editorDataKeys.forEach((key) => {
18692
18821
  clonePrintModeData[key] = this.control.filterAssistElement(clonePrintModeData[key]);
18693
18822
  });
@@ -18733,6 +18862,7 @@ class Draw {
18733
18862
  return false;
18734
18863
  case EditorMode.READONLY:
18735
18864
  case EditorMode.PRINT:
18865
+ case EditorMode.GRAFFITI:
18736
18866
  return true;
18737
18867
  case EditorMode.FORM:
18738
18868
  return !this.control.getIsRangeWithinControl();
@@ -18765,6 +18895,9 @@ class Draw {
18765
18895
  isPrintMode() {
18766
18896
  return this.mode === EditorMode.PRINT;
18767
18897
  }
18898
+ isGraffitiMode() {
18899
+ return this.mode === EditorMode.GRAFFITI;
18900
+ }
18768
18901
  getOriginalWidth() {
18769
18902
  const { paperDirection, width, height } = this.options;
18770
18903
  return paperDirection === PaperDirection.VERTICAL ? width : height;
@@ -19171,6 +19304,9 @@ class Draw {
19171
19304
  getI18n() {
19172
19305
  return this.i18n;
19173
19306
  }
19307
+ getGraffiti() {
19308
+ return this.graffiti;
19309
+ }
19174
19310
  getRowCount() {
19175
19311
  return this.getRowList().length;
19176
19312
  }
@@ -19367,7 +19503,8 @@ class Draw {
19367
19503
  const data2 = {
19368
19504
  header: this.getHeaderElementList(),
19369
19505
  main: mainElementList,
19370
- footer: this.getFooterElementList()
19506
+ footer: this.getFooterElementList(),
19507
+ graffiti: this.graffiti.getValue()
19371
19508
  };
19372
19509
  return data2;
19373
19510
  }
@@ -19384,7 +19521,8 @@ class Draw {
19384
19521
  }),
19385
19522
  footer: zipElementList(originData.footer, {
19386
19523
  extraPickAttrs
19387
- })
19524
+ }),
19525
+ graffiti: originData.graffiti
19388
19526
  };
19389
19527
  return {
19390
19528
  version,
@@ -19805,7 +19943,7 @@ class Draw {
19805
19943
  if (element.letterSpacing) {
19806
19944
  metrics.width += element.letterSpacing * scale;
19807
19945
  }
19808
- metrics.boundingBoxAscent = (element.value === ZERO ? element.size || defaultSize : fontMetrics.actualBoundingBoxAscent) * scale;
19946
+ metrics.boundingBoxAscent = (element.value === ZERO ? this.textParticle.getBasisWordBoundingBoxAscent(ctx, element.font) : fontMetrics.actualBoundingBoxAscent) * scale;
19809
19947
  metrics.boundingBoxDescent = fontMetrics.actualBoundingBoxDescent * scale;
19810
19948
  if (element.type === ElementType.SUPERSCRIPT) {
19811
19949
  metrics.boundingBoxAscent += metrics.height / 2;
@@ -19933,7 +20071,7 @@ class Draw {
19933
20071
  curRow.width = availableWidth;
19934
20072
  }
19935
20073
  if (curRow.ascent === rowMargin) {
19936
- const boundingBoxDescent = this.textParticle.measureBasisWord(ctx, element.font).actualBoundingBoxAscent;
20074
+ const boundingBoxDescent = this.textParticle.getBasisWordBoundingBoxAscent(ctx, element.font) * scale;
19937
20075
  curRow.ascent += boundingBoxDescent;
19938
20076
  curRow.height += boundingBoxDescent;
19939
20077
  }
@@ -20039,7 +20177,8 @@ class Draw {
20039
20177
  this._drawHighlight(ctx, payload);
20040
20178
  const { scale, table: { tdPadding }, group: group2, lineBreak } = this.options;
20041
20179
  const { rowList, pageNo, elementList, positionList, startIndex, zone: zone2, isDrawLineBreak = !lineBreak.disabled } = payload;
20042
- const isPrintMode = this.mode === EditorMode.PRINT;
20180
+ const isPrintMode = this.isPrintMode();
20181
+ const isGraffitiMode = this.isGraffitiMode();
20043
20182
  const { isCrossRowCol, tableId } = this.range.getRange();
20044
20183
  let index2 = startIndex;
20045
20184
  for (let i = 0; i < rowList.length; i++) {
@@ -20235,7 +20374,7 @@ class Draw {
20235
20374
  this.underline.render(ctx);
20236
20375
  this.strikeout.render(ctx);
20237
20376
  this.group.render(ctx);
20238
- if (!isPrintMode) {
20377
+ if (!isPrintMode && !isGraffitiMode) {
20239
20378
  if (rangeRecord.width && rangeRecord.height) {
20240
20379
  const { x, y, width, height } = rangeRecord;
20241
20380
  this.range.render(ctx, x, y, width, height);
@@ -20332,6 +20471,9 @@ class Draw {
20332
20471
  this.pageBorder.render(ctx);
20333
20472
  }
20334
20473
  this.badge.render(ctx, pageNo);
20474
+ if (this.isGraffitiMode()) {
20475
+ this.graffiti.render(ctx, pageNo);
20476
+ }
20335
20477
  }
20336
20478
  _disconnectLazyRender() {
20337
20479
  var _a;
@@ -20408,13 +20550,16 @@ class Draw {
20408
20550
  this.pageRowList = this._computePageList();
20409
20551
  this.position.computePositionList();
20410
20552
  this.area.compute();
20411
- if (this.mode !== EditorMode.PRINT) {
20553
+ if (!this.isPrintMode()) {
20412
20554
  const searchKeyword = this.search.getSearchKeyword();
20413
20555
  if (searchKeyword) {
20414
20556
  this.search.compute(searchKeyword);
20415
20557
  }
20416
20558
  this.control.computeHighlightList();
20417
20559
  }
20560
+ if (this.isGraffitiMode()) {
20561
+ this.graffiti.compute();
20562
+ }
20418
20563
  }
20419
20564
  this.imageObserver.clearAll();
20420
20565
  this.cursor.recoveryCursor();
@@ -20625,6 +20770,7 @@ class Command {
20625
20770
  __publicField(this, "executeSetAreaValue");
20626
20771
  __publicField(this, "executeSetAreaProperties");
20627
20772
  __publicField(this, "executeLocationArea");
20773
+ __publicField(this, "executeClearGraffiti");
20628
20774
  __publicField(this, "executeAppendElementList");
20629
20775
  __publicField(this, "executeUpdateElementById");
20630
20776
  __publicField(this, "executeDeleteElementById");
@@ -20762,6 +20908,7 @@ class Command {
20762
20908
  this.executeSetAreaValue = adapt.setAreaValue.bind(adapt);
20763
20909
  this.executeSetAreaProperties = adapt.setAreaProperties.bind(adapt);
20764
20910
  this.executeLocationArea = adapt.locationArea.bind(adapt);
20911
+ this.executeClearGraffiti = adapt.clearGraffiti.bind(adapt);
20765
20912
  this.executeInsertElementList = adapt.insertElementList.bind(adapt);
20766
20913
  this.executeAppendElementList = adapt.appendElementList.bind(adapt);
20767
20914
  this.executeUpdateElementById = adapt.updateElementById.bind(adapt);
@@ -21036,7 +21183,7 @@ class CommandAdapt {
21036
21183
  painterStyleKeys.forEach((p) => {
21037
21184
  const key = p;
21038
21185
  if (painterStyle[key] === void 0) {
21039
- painterStyle[key] = s[key];
21186
+ Reflect.set(painterStyle, key, s[key]);
21040
21187
  }
21041
21188
  });
21042
21189
  });
@@ -23042,6 +23189,16 @@ class CommandAdapt {
23042
23189
  isSubmitHistory: false
23043
23190
  });
23044
23191
  }
23192
+ clearGraffiti() {
23193
+ this.draw.getGraffiti().clear();
23194
+ if (this.draw.isGraffitiMode()) {
23195
+ this.draw.render({
23196
+ isCompute: false,
23197
+ isSetCursor: false,
23198
+ isSubmitHistory: false
23199
+ });
23200
+ }
23201
+ }
23045
23202
  }
23046
23203
  class Listener {
23047
23204
  constructor() {
@@ -24142,6 +24299,9 @@ class EventBus {
24142
24299
  const eventSet = this.eventHub.get(eventName);
24143
24300
  return !!eventSet && eventSet.size > 0;
24144
24301
  }
24302
+ dangerouslyClearAll() {
24303
+ this.eventHub.clear();
24304
+ }
24145
24305
  }
24146
24306
  class Override {
24147
24307
  constructor() {
@@ -24165,12 +24325,14 @@ class Editor {
24165
24325
  let headerElementList = [];
24166
24326
  let mainElementList = [];
24167
24327
  let footerElementList = [];
24328
+ let graffitiData = [];
24168
24329
  if (Array.isArray(data2)) {
24169
24330
  mainElementList = data2;
24170
24331
  } else {
24171
24332
  headerElementList = data2.header || [];
24172
24333
  mainElementList = data2.main;
24173
24334
  footerElementList = data2.footer || [];
24335
+ graffitiData = data2.graffiti || [];
24174
24336
  }
24175
24337
  const pageComponentData = [
24176
24338
  headerElementList,
@@ -24190,7 +24352,8 @@ class Editor {
24190
24352
  const draw = new Draw(container, editorOptions, {
24191
24353
  header: headerElementList,
24192
24354
  main: mainElementList,
24193
- footer: footerElementList
24355
+ footer: footerElementList,
24356
+ graffiti: graffitiData
24194
24357
  }, this.listener, this.eventBus, this.override);
24195
24358
  this.command = new Command(new CommandAdapt(draw));
24196
24359
  const contextMenu = new ContextMenu(draw, this.command);
@@ -24204,6 +24367,7 @@ class Editor {
24204
24367
  draw.destroy();
24205
24368
  shortcut.removeEvent();
24206
24369
  contextMenu.removeEvent();
24370
+ this.eventBus.dangerouslyClearAll();
24207
24371
  };
24208
24372
  const plugin = new Plugin(this);
24209
24373
  this.use = plugin.use.bind(plugin);