@bpmn-io/form-js-playground 0.10.1 → 0.11.1

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.
@@ -12839,7 +12839,7 @@
12839
12839
  if (arguments.length !== 1) {
12840
12840
  return null;
12841
12841
  }
12842
- return toString(from);
12842
+ return toString$1(from);
12843
12843
  }, ['any']),
12844
12844
  // date(from) => date string
12845
12845
  // date(from) => date and time
@@ -13365,17 +13365,17 @@
13365
13365
  }
13366
13366
  function toKeyString(key) {
13367
13367
  if (typeof key === 'string' && /\W/.test(key)) {
13368
- return toString(key, true);
13368
+ return toString$1(key, true);
13369
13369
  }
13370
13370
  return key;
13371
13371
  }
13372
13372
  function toDeepString(obj) {
13373
- return toString(obj, true);
13373
+ return toString$1(obj, true);
13374
13374
  }
13375
13375
  function escapeStr(str) {
13376
13376
  return str.replace(/("|\\)/g, '\\$1');
13377
13377
  }
13378
- function toString(obj, wrap = false) {
13378
+ function toString$1(obj, wrap = false) {
13379
13379
  var _a, _b, _c, _d;
13380
13380
  const type = getType(obj);
13381
13381
  if (type === 'nil') {
@@ -18241,9 +18241,9 @@
18241
18241
  return value;
18242
18242
  }
18243
18243
 
18244
- /**
18245
- * @typedef {object} Condition
18246
- * @property {string} [hide]
18244
+ /**
18245
+ * @typedef {object} Condition
18246
+ * @property {string} [hide]
18247
18247
  */
18248
18248
 
18249
18249
  class ConditionChecker {
@@ -18252,11 +18252,11 @@
18252
18252
  this._eventBus = eventBus;
18253
18253
  }
18254
18254
 
18255
- /**
18256
- * For given data, remove properties based on condition.
18257
- *
18258
- * @param {Object<string, any>} properties
18259
- * @param {Object<string, any>} data
18255
+ /**
18256
+ * For given data, remove properties based on condition.
18257
+ *
18258
+ * @param {Object<string, any>} properties
18259
+ * @param {Object<string, any>} data
18260
18260
  */
18261
18261
  applyConditions(properties, data = {}) {
18262
18262
  const conditions = this._getConditions();
@@ -18275,13 +18275,13 @@
18275
18275
  return newProperties;
18276
18276
  }
18277
18277
 
18278
- /**
18279
- * Check if given condition is met. Returns null for invalid/missing conditions.
18280
- *
18281
- * @param {string} condition
18282
- * @param {import('../types').Data} [data]
18283
- *
18284
- * @returns {boolean|null}
18278
+ /**
18279
+ * Check if given condition is met. Returns null for invalid/missing conditions.
18280
+ *
18281
+ * @param {string} condition
18282
+ * @param {import('../types').Data} [data]
18283
+ *
18284
+ * @returns {boolean|null}
18285
18285
  */
18286
18286
  check(condition, data = {}) {
18287
18287
  if (!condition) {
@@ -18302,12 +18302,12 @@
18302
18302
  }
18303
18303
  }
18304
18304
 
18305
- /**
18306
- * Check if hide condition is met.
18307
- *
18308
- * @param {Condition} condition
18309
- * @param {Object<string, any>} data
18310
- * @returns {boolean}
18305
+ /**
18306
+ * Check if hide condition is met.
18307
+ *
18308
+ * @param {Condition} condition
18309
+ * @param {Object<string, any>} data
18310
+ * @returns {boolean}
18311
18311
  */
18312
18312
  _checkHideCondition(condition, data) {
18313
18313
  if (!condition.hide) {
@@ -18317,13 +18317,13 @@
18317
18317
  return result === true;
18318
18318
  }
18319
18319
 
18320
- /**
18321
- * Evaluate an expression.
18322
- *
18323
- * @param {string} expression
18324
- * @param {import('../types').Data} [data]
18325
- *
18326
- * @returns {any}
18320
+ /**
18321
+ * Evaluate an expression.
18322
+ *
18323
+ * @param {string} expression
18324
+ * @param {import('../types').Data} [data]
18325
+ *
18326
+ * @returns {any}
18327
18327
  */
18328
18328
  evaluate(expression, data = {}) {
18329
18329
  if (!expression) {
@@ -18828,7 +18828,7 @@
18828
18828
  if (type === 'number') {
18829
18829
  const {
18830
18830
  decimalDigits,
18831
- step
18831
+ increment
18832
18832
  } = field;
18833
18833
  if (value === 'NaN') {
18834
18834
  errors = [...errors, 'Value is not a number.'];
@@ -18836,13 +18836,13 @@
18836
18836
  if (decimalDigits >= 0 && countDecimals$1(value) > decimalDigits) {
18837
18837
  errors = [...errors, 'Value is expected to ' + (decimalDigits === 0 ? 'be an integer' : `have at most ${decimalDigits} decimal digit${decimalDigits > 1 ? 's' : ''}`) + '.'];
18838
18838
  }
18839
- if (step) {
18839
+ if (increment) {
18840
18840
  const bigValue = Big$1(value);
18841
- const bigStep = Big$1(step);
18842
- const offset = bigValue.mod(bigStep);
18841
+ const bigIncrement = Big$1(increment);
18842
+ const offset = bigValue.mod(bigIncrement);
18843
18843
  if (offset.cmp(0) !== 0) {
18844
18844
  const previousValue = bigValue.minus(offset);
18845
- const nextValue = previousValue.plus(bigStep);
18845
+ const nextValue = previousValue.plus(bigIncrement);
18846
18846
  errors = [...errors, `Please select a valid value, the two nearest valid values are ${previousValue} and ${nextValue}.`];
18847
18847
  }
18848
18848
  }
@@ -18857,10 +18857,10 @@
18857
18857
  if (validate.required && (isNil$1(value) || value === '')) {
18858
18858
  errors = [...errors, 'Field is required.'];
18859
18859
  }
18860
- if ('min' in validate && value && value < validate.min) {
18860
+ if ('min' in validate && (value || value === 0) && value < validate.min) {
18861
18861
  errors = [...errors, `Field must have minimum value of ${validate.min}.`];
18862
18862
  }
18863
- if ('max' in validate && value && value > validate.max) {
18863
+ if ('max' in validate && (value || value === 0) && value > validate.max) {
18864
18864
  errors = [...errors, `Field must have maximum value of ${validate.max}.`];
18865
18865
  }
18866
18866
  if ('minLength' in validate && value && value.trim().length < validate.minLength) {
@@ -18928,11 +18928,11 @@
18928
18928
  }
18929
18929
  FormFieldRegistry$1.$inject = ['eventBus'];
18930
18930
 
18931
- /**
18932
- * Retrieve variable names from given FEEL unary test.
18933
- *
18934
- * @param {string} unaryTest
18935
- * @returns {string[]}
18931
+ /**
18932
+ * Retrieve variable names from given FEEL unary test.
18933
+ *
18934
+ * @param {string} unaryTest
18935
+ * @returns {string[]}
18936
18936
  */
18937
18937
  function getVariableNames(unaryTest) {
18938
18938
  const tree = parseUnaryTests(unaryTest);
@@ -18947,11 +18947,11 @@
18947
18947
  return Array.from(variables);
18948
18948
  }
18949
18949
 
18950
- /**
18951
- * Retrieve variable names from given FEEL expression.
18952
- *
18953
- * @param {string} expression
18954
- * @returns {string[]}
18950
+ /**
18951
+ * Retrieve variable names from given FEEL expression.
18952
+ *
18953
+ * @param {string} expression
18954
+ * @returns {string[]}
18955
18955
  */
18956
18956
  function getExpressionVariableNames(expression) {
18957
18957
  const tree = parseExpressions(expression);
@@ -19036,10 +19036,10 @@
19036
19036
  return injector;
19037
19037
  }
19038
19038
 
19039
- /**
19040
- * @param {string?} prefix
19041
- *
19042
- * @returns Element
19039
+ /**
19040
+ * @param {string?} prefix
19041
+ *
19042
+ * @returns Element
19043
19043
  */
19044
19044
  function createFormContainer(prefix = 'fjs') {
19045
19045
  const container = document.createElement('div');
@@ -19069,22 +19069,22 @@
19069
19069
  return `${type}${generateIndexForType(type)}`;
19070
19070
  }
19071
19071
 
19072
- /**
19073
- * @template T
19074
- * @param {T} data
19075
- * @param {(this: any, key: string, value: any) => any} [replacer]
19076
- * @return {T}
19072
+ /**
19073
+ * @template T
19074
+ * @param {T} data
19075
+ * @param {(this: any, key: string, value: any) => any} [replacer]
19076
+ * @return {T}
19077
19077
  */
19078
19078
  function clone(data, replacer) {
19079
19079
  return JSON.parse(JSON.stringify(data, replacer));
19080
19080
  }
19081
19081
 
19082
- /**
19083
- * Parse the schema for input variables a form might make use of
19084
- *
19085
- * @param {any} schema
19086
- *
19087
- * @return {string[]}
19082
+ /**
19083
+ * Parse the schema for input variables a form might make use of
19084
+ *
19085
+ * @param {any} schema
19086
+ *
19087
+ * @return {string[]}
19088
19088
  */
19089
19089
  function getSchemaVariables(schema) {
19090
19090
  if (!schema.components) {
@@ -19132,25 +19132,25 @@
19132
19132
  return isString$3(value) && value.startsWith('=');
19133
19133
  }
19134
19134
  class Importer$1 {
19135
- /**
19136
- * @constructor
19137
- * @param { import('../core').FormFieldRegistry } formFieldRegistry
19138
- * @param { import('../render/FormFields').default } formFields
19135
+ /**
19136
+ * @constructor
19137
+ * @param { import('../core').FormFieldRegistry } formFieldRegistry
19138
+ * @param { import('../render/FormFields').default } formFields
19139
19139
  */
19140
19140
  constructor(formFieldRegistry, formFields) {
19141
19141
  this._formFieldRegistry = formFieldRegistry;
19142
19142
  this._formFields = formFields;
19143
19143
  }
19144
19144
 
19145
- /**
19146
- * Import schema adding `id`, `_parent` and `_path`
19147
- * information to each field and adding it to the
19148
- * form field registry.
19149
- *
19150
- * @param {any} schema
19151
- * @param {any} [data]
19152
- *
19153
- * @return { { warnings: Array<any>, schema: any, data: any } }
19145
+ /**
19146
+ * Import schema adding `id`, `_parent` and `_path`
19147
+ * information to each field and adding it to the
19148
+ * form field registry.
19149
+ *
19150
+ * @param {any} schema
19151
+ * @param {any} [data]
19152
+ *
19153
+ * @return { { warnings: Array<any>, schema: any, data: any } }
19154
19154
  */
19155
19155
  importSchema(schema, data = {}) {
19156
19156
  // TODO: Add warnings - https://github.com/bpmn-io/form-js/issues/289
@@ -19169,11 +19169,11 @@
19169
19169
  }
19170
19170
  }
19171
19171
 
19172
- /**
19173
- * @param {any} formField
19174
- * @param {string} [parentId]
19175
- *
19176
- * @return {any} importedField
19172
+ /**
19173
+ * @param {any} formField
19174
+ * @param {string} [parentId]
19175
+ *
19176
+ * @return {any} importedField
19177
19177
  */
19178
19178
  importFormField(formField, parentId) {
19179
19179
  const {
@@ -19224,10 +19224,10 @@
19224
19224
  });
19225
19225
  }
19226
19226
 
19227
- /**
19228
- * @param {Object} data
19229
- *
19230
- * @return {Object} initializedData
19227
+ /**
19228
+ * @param {Object} data
19229
+ *
19230
+ * @return {Object} initializedData
19231
19231
  */
19232
19232
  initializeFieldValues(data) {
19233
19233
  return this._formFieldRegistry.getAll().reduce((initializedData, formField) => {
@@ -19275,11 +19275,11 @@
19275
19275
 
19276
19276
  const FORM_ELEMENT = document.createElement('form');
19277
19277
 
19278
- /**
19279
- * Sanitize a HTML string and return the cleaned, safe version.
19280
- *
19281
- * @param {string} html
19282
- * @return {string}
19278
+ /**
19279
+ * Sanitize a HTML string and return the cleaned, safe version.
19280
+ *
19281
+ * @param {string} html
19282
+ * @return {string}
19283
19283
  */
19284
19284
  function sanitizeHTML(html) {
19285
19285
  const doc = new DOMParser().parseFromString(`<!DOCTYPE html>\n<html><body><div>${html}`, 'text/html');
@@ -19299,15 +19299,15 @@
19299
19299
  return valid ? src : '';
19300
19300
  }
19301
19301
 
19302
- /**
19303
- * Recursively sanitize a HTML node, potentially
19304
- * removing it, its children or attributes.
19305
- *
19306
- * Inspired by https://github.com/developit/snarkdown/issues/70
19307
- * and https://github.com/cure53/DOMPurify. Simplified
19308
- * for our use-case.
19309
- *
19310
- * @param {Element} node
19302
+ /**
19303
+ * Recursively sanitize a HTML node, potentially
19304
+ * removing it, its children or attributes.
19305
+ *
19306
+ * Inspired by https://github.com/developit/snarkdown/issues/70
19307
+ * and https://github.com/cure53/DOMPurify. Simplified
19308
+ * for our use-case.
19309
+ *
19310
+ * @param {Element} node
19311
19311
  */
19312
19312
  function sanitizeNode(node) {
19313
19313
  // allow text nodes
@@ -19351,13 +19351,13 @@
19351
19351
  }
19352
19352
  }
19353
19353
 
19354
- /**
19355
- * Validates attributes for validity.
19356
- *
19357
- * @param {string} lcTag
19358
- * @param {string} lcName
19359
- * @param {string} value
19360
- * @return {boolean}
19354
+ /**
19355
+ * Validates attributes for validity.
19356
+ *
19357
+ * @param {string} lcTag
19358
+ * @param {string} lcName
19359
+ * @param {string} value
19360
+ * @return {boolean}
19361
19361
  */
19362
19362
  function isValidAttribute(lcTag, lcName, value) {
19363
19363
  // disallow most attributes based on whitelist
@@ -19408,14 +19408,14 @@
19408
19408
  return sanitizeHTML(html);
19409
19409
  }
19410
19410
 
19411
- /**
19412
- * Sanitizes an image source to ensure we only allow for data URI and links
19413
- * that start with http(s).
19414
- *
19415
- * Note: Most browsers anyway do not support script execution in <img> elements.
19416
- *
19417
- * @param {string} src
19418
- * @returns {string}
19411
+ /**
19412
+ * Sanitizes an image source to ensure we only allow for data URI and links
19413
+ * that start with http(s).
19414
+ *
19415
+ * Note: Most browsers anyway do not support script execution in <img> elements.
19416
+ *
19417
+ * @param {string} src
19418
+ * @returns {string}
19419
19419
  */
19420
19420
  function safeImageSource(src) {
19421
19421
  return sanitizeImageSource(src);
@@ -19460,11 +19460,11 @@
19460
19460
  }
19461
19461
  });
19462
19462
 
19463
- /**
19464
- * @param {string} type
19465
- * @param {boolean} [strict]
19466
- *
19467
- * @returns {any}
19463
+ /**
19464
+ * @param {string} type
19465
+ * @param {boolean} [strict]
19466
+ *
19467
+ * @returns {any}
19468
19468
  */
19469
19469
  function getService$2(type, strict) {}
19470
19470
  const FormContext = D$1({
@@ -19588,8 +19588,8 @@
19588
19588
  return getService(type, strict);
19589
19589
  }
19590
19590
 
19591
- /**
19592
- * @enum { String }
19591
+ /**
19592
+ * @enum { String }
19593
19593
  */
19594
19594
  const LOAD_STATES = {
19595
19595
  LOADING: 'loading',
@@ -19597,17 +19597,17 @@
19597
19597
  ERROR: 'error'
19598
19598
  };
19599
19599
 
19600
- /**
19601
- * @typedef {Object} ValuesGetter
19602
- * @property {Object[]} values - The values data
19603
- * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
19600
+ /**
19601
+ * @typedef {Object} ValuesGetter
19602
+ * @property {Object[]} values - The values data
19603
+ * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
19604
19604
  */
19605
19605
 
19606
- /**
19607
- * A hook to load values for single and multiselect components.
19608
- *
19609
- * @param {Object} field - The form field to handle values for
19610
- * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
19606
+ /**
19607
+ * A hook to load values for single and multiselect components.
19608
+ *
19609
+ * @param {Object} field - The form field to handle values for
19610
+ * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
19611
19611
  */
19612
19612
  function useValuesAsync(field) {
19613
19613
  const {
@@ -19939,13 +19939,13 @@
19939
19939
  Checklist.emptyValue = [];
19940
19940
  Checklist.sanitizeValue = sanitizeMultiSelectValue;
19941
19941
 
19942
- /**
19943
- * Check if condition is met with given variables.
19944
- *
19945
- * @param {string | undefined} condition
19946
- * @param {import('../../types').Data} data
19947
- *
19948
- * @returns {boolean} true if condition is met or no condition or condition checker exists
19942
+ /**
19943
+ * Check if condition is met with given variables.
19944
+ *
19945
+ * @param {string | undefined} condition
19946
+ * @param {import('../../types').Data} data
19947
+ *
19948
+ * @returns {boolean} true if condition is met or no condition or condition checker exists
19949
19949
  */
19950
19950
  function useCondition(condition, data) {
19951
19951
  const initialData = useService$2('form')._getState().initialData;
@@ -20065,7 +20065,7 @@
20065
20065
  fillRule: "evenodd",
20066
20066
  clipRule: "evenodd",
20067
20067
  d: "M19 2H9V0H7v2H2a2 2 0 00-2 2v24a2 2 0 002 2h24a2 2 0 002-2V4a2 2 0 00-2-2h-5V0h-2v2zM7 7V4H2v5h24V4h-5v3h-2V4H9v3H7zm-5 4v17h24V11H2z",
20068
- fill: "#000"
20068
+ fill: "currentColor"
20069
20069
  }));
20070
20070
  function InputAdorner(props) {
20071
20071
  const {
@@ -20128,10 +20128,6 @@
20128
20128
 
20129
20129
  // setup flatpickr instance
20130
20130
  y(() => {
20131
- if (disabled) {
20132
- setFlatpickrInstance(null);
20133
- return;
20134
- }
20135
20131
  let config = {
20136
20132
  allowInput: true,
20137
20133
  dateFormat: 'm/d/Y',
@@ -20164,7 +20160,7 @@
20164
20160
  // flatpicker logic that was lost when setting allowInput to true
20165
20161
  instance.config.onOpen = [() => instance.calendarContainer.addEventListener('focusout', onCalendarFocusOut), () => instance.calendarContainer.addEventListener('mousedown', onCalendarMouseDown)];
20166
20162
  instance.config.onClose = [() => instance.calendarContainer.removeEventListener('focusout', onCalendarFocusOut), () => instance.calendarContainer.removeEventListener('mousedown', onCalendarMouseDown)];
20167
- }, [disabled, disallowPassedDates]);
20163
+ }, [disallowPassedDates]);
20168
20164
 
20169
20165
  // onChange is updated dynamically, so not to re-render the flatpicker every time it changes
20170
20166
  y(() => {
@@ -20265,12 +20261,12 @@
20265
20261
  xmlns: "http://www.w3.org/2000/svg"
20266
20262
  }, props), /*#__PURE__*/React.createElement("path", {
20267
20263
  d: "M13 14.41L18.59 20 20 18.59l-5-5.01V5h-2v9.41z",
20268
- fill: "#000"
20264
+ fill: "currentColor"
20269
20265
  }), /*#__PURE__*/React.createElement("path", {
20270
20266
  fillRule: "evenodd",
20271
20267
  clipRule: "evenodd",
20272
20268
  d: "M6.222 25.64A14 14 0 1021.778 2.36 14 14 0 006.222 25.64zM7.333 4.023a12 12 0 1113.334 19.955A12 12 0 017.333 4.022z",
20273
- fill: "#000"
20269
+ fill: "currentColor"
20274
20270
  }));
20275
20271
  function useKeyDownAction(targetKey, action, listenerElement = window) {
20276
20272
  function downHandler({
@@ -20360,6 +20356,7 @@
20360
20356
  ref: dropdownContainer,
20361
20357
  tabIndex: -1,
20362
20358
  class: "fjs-dropdownlist",
20359
+ onMouseDown: e => e.preventDefault(),
20363
20360
  style: {
20364
20361
  maxHeight: height,
20365
20362
  scrollBehavior: smoothScrolling ? 'smooth' : 'auto'
@@ -20371,10 +20368,7 @@
20371
20368
  }),
20372
20369
  onMouseMove: mouseControl ? undefined : e => onMouseMovedInKeyboardMode(e, i),
20373
20370
  onMouseEnter: mouseControl ? () => setFocusedValueIndex(i) : undefined,
20374
- onMouseDown: e => {
20375
- e.preventDefault();
20376
- onValueSelected(v);
20377
- },
20371
+ onMouseDown: e => onValueSelected(v),
20378
20372
  children: getLabel(v)
20379
20373
  });
20380
20374
  }), !values.length && e$1("div", {
@@ -20573,31 +20567,29 @@
20573
20567
  date,
20574
20568
  time
20575
20569
  } = getNullDateTime();
20576
- if (!disabled) {
20577
- switch (subtype) {
20578
- case DATETIME_SUBTYPES.DATE:
20579
- {
20580
- date = new Date(Date.parse(value));
20581
- break;
20582
- }
20583
- case DATETIME_SUBTYPES.TIME:
20584
- {
20585
- time = parseIsoTime(value);
20586
- break;
20587
- }
20588
- case DATETIME_SUBTYPES.DATETIME:
20589
- {
20590
- date = new Date(Date.parse(value));
20591
- time = isValidDate(date) ? 60 * date.getHours() + date.getMinutes() : null;
20592
- break;
20593
- }
20594
- }
20570
+ switch (subtype) {
20571
+ case DATETIME_SUBTYPES.DATE:
20572
+ {
20573
+ date = new Date(Date.parse(value));
20574
+ break;
20575
+ }
20576
+ case DATETIME_SUBTYPES.TIME:
20577
+ {
20578
+ time = parseIsoTime(value);
20579
+ break;
20580
+ }
20581
+ case DATETIME_SUBTYPES.DATETIME:
20582
+ {
20583
+ date = new Date(Date.parse(value));
20584
+ time = isValidDate(date) ? 60 * date.getHours() + date.getMinutes() : null;
20585
+ break;
20586
+ }
20595
20587
  }
20596
20588
  setDateTime({
20597
20589
  date,
20598
20590
  time
20599
20591
  });
20600
- }, [subtype, value, disabled]);
20592
+ }, [subtype, value]);
20601
20593
  const computeAndSetState = A$1(({
20602
20594
  date,
20603
20595
  time
@@ -20714,10 +20706,10 @@
20714
20706
  Datetime.emptyValue = null;
20715
20707
  Datetime.sanitizeValue = sanitizeDateTimePickerValue;
20716
20708
 
20717
- /**
20718
- * This file must not be changed or exchanged.
20719
- *
20720
- * @see http://bpmn.io/license for more information.
20709
+ /**
20710
+ * This file must not be changed or exchanged.
20711
+ *
20712
+ * @see http://bpmn.io/license for more information.
20721
20713
  */
20722
20714
  function Logo() {
20723
20715
  return e$1("svg", {
@@ -20833,10 +20825,10 @@
20833
20825
  });
20834
20826
  }
20835
20827
 
20836
- /**
20837
- *
20838
- * @param {string | undefined} expression
20839
- * @param {import('../../types').Data} data
20828
+ /**
20829
+ *
20830
+ * @param {string | undefined} expression
20831
+ * @param {import('../../types').Data} data
20840
20832
  */
20841
20833
  function useEvaluation(expression, data) {
20842
20834
  const initialData = useService$2('form')._getState().initialData;
@@ -20853,9 +20845,9 @@
20853
20845
  return conditionChecker.evaluate(expression, filteredData);
20854
20846
  }
20855
20847
 
20856
- /**
20857
- *
20858
- * @param {string} value
20848
+ /**
20849
+ *
20850
+ * @param {string} value
20859
20851
  */
20860
20852
  function useExpressionValue(value) {
20861
20853
  const formData = useService$2('form')._getState().data;
@@ -20996,6 +20988,7 @@
20996
20988
  }), [stringValueCache, value, field]);
20997
20989
  const displayValue = d(() => {
20998
20990
  if (value === 'NaN') return 'NaN';
20991
+ if (stringValueCache === '-') return '-';
20999
20992
  return cacheValueMatchesState ? stringValueCache : value || value === 0 ? Big$1(value).toFixed() : '';
21000
20993
  }, [stringValueCache, value, cacheValueMatchesState]);
21001
20994
  const arrowIncrementValue = d(() => {
@@ -21015,6 +21008,10 @@
21015
21008
 
21016
21009
  // treat commas as dots
21017
21010
  stringValue = stringValue.replaceAll(',', '.');
21011
+ if (stringValue === '-') {
21012
+ setStringValueCache('-');
21013
+ return;
21014
+ }
21018
21015
  if (isNaN(Number(stringValue))) {
21019
21016
  setStringValueCache('NaN');
21020
21017
  onChange({
@@ -21591,18 +21588,18 @@
21591
21588
  styles = {},
21592
21589
  ...props
21593
21590
  }) => /*#__PURE__*/React.createElement("svg", _extends$b({
21591
+ xmlns: "http://www.w3.org/2000/svg",
21594
21592
  width: "54",
21595
21593
  height: "54",
21596
- fill: "none",
21597
- xmlns: "http://www.w3.org/2000/svg"
21594
+ fill: "none"
21598
21595
  }, props), /*#__PURE__*/React.createElement("path", {
21599
21596
  fillRule: "evenodd",
21600
21597
  clipRule: "evenodd",
21601
- d: "M19 24h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zm6 18h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zm6-30h-6v6h6V8zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2V8a2 2 0 00-2-2h-6z",
21602
- fill: "#22242A"
21598
+ d: "M18 12h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zM18 36h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zM18 24h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6z",
21599
+ fill: "#161616"
21603
21600
  }), /*#__PURE__*/React.createElement("path", {
21604
- d: "M26 26a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2zm0 16a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2zm0-32a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2z",
21605
- fill: "#22242A"
21601
+ d: "M23 14.5a1 1 0 011-1h19a1 1 0 011 1v1a1 1 0 01-1 1H24a1 1 0 01-1-1v-1zM23 26.5a1 1 0 011-1h19a1 1 0 011 1v1a1 1 0 01-1 1H24a1 1 0 01-1-1v-1zM23 38.5a1 1 0 011-1h19a1 1 0 011 1v1a1 1 0 01-1 1H24a1 1 0 01-1-1v-1z",
21602
+ fill: "#161616"
21606
21603
  }));
21607
21604
  function _extends$a() {
21608
21605
  _extends$a = Object.assign ? Object.assign.bind() : function (target) {
@@ -29668,6 +29665,7 @@
29668
29665
  this.curLine = null;
29669
29666
  this.breakAtStart = 0;
29670
29667
  this.pendingBuffer = 0 /* Buf.No */;
29668
+ this.bufferMarks = [];
29671
29669
  // Set to false directly after a widget that covers the position after it
29672
29670
  this.atCursorPos = true;
29673
29671
  this.openStart = -1;
@@ -29689,7 +29687,7 @@
29689
29687
  }
29690
29688
  return this.curLine;
29691
29689
  }
29692
- flushBuffer(active) {
29690
+ flushBuffer(active = this.bufferMarks) {
29693
29691
  if (this.pendingBuffer) {
29694
29692
  this.curLine.append(wrapMarks(new WidgetBufferView(-1), active), active.length);
29695
29693
  this.pendingBuffer = 0 /* Buf.No */;
@@ -29697,12 +29695,12 @@
29697
29695
  }
29698
29696
 
29699
29697
  addBlockWidget(view) {
29700
- this.flushBuffer([]);
29698
+ this.flushBuffer();
29701
29699
  this.curLine = null;
29702
29700
  this.content.push(view);
29703
29701
  }
29704
29702
  finish(openEnd) {
29705
- if (!openEnd) this.flushBuffer([]);else this.pendingBuffer = 0 /* Buf.No */;
29703
+ if (this.pendingBuffer && openEnd <= this.bufferMarks.length) this.flushBuffer();else this.pendingBuffer = 0 /* Buf.No */;
29706
29704
  if (!this.posCovered()) this.getLine();
29707
29705
  }
29708
29706
  buildText(length, active, openStart) {
@@ -29718,8 +29716,9 @@
29718
29716
  if (lineBreak) {
29719
29717
  if (!this.posCovered()) this.getLine();
29720
29718
  if (this.content.length) this.content[this.content.length - 1].breakAfter = 1;else this.breakAtStart = 1;
29721
- this.flushBuffer([]);
29719
+ this.flushBuffer();
29722
29720
  this.curLine = null;
29721
+ this.atCursorPos = true;
29723
29722
  length--;
29724
29723
  continue;
29725
29724
  } else {
@@ -29757,7 +29756,7 @@
29757
29756
  } else {
29758
29757
  let view = WidgetView.create(deco.widget || new NullWidget("span"), len, len ? 0 : deco.startSide);
29759
29758
  let cursorBefore = this.atCursorPos && !view.isEditable && openStart <= active.length && (from < to || deco.startSide > 0);
29760
- let cursorAfter = !view.isEditable && (from < to || deco.startSide <= 0);
29759
+ let cursorAfter = !view.isEditable && (from < to || openStart > active.length || deco.startSide <= 0);
29761
29760
  let line = this.getLine();
29762
29761
  if (this.pendingBuffer == 2 /* Buf.IfCursor */ && !cursorBefore) this.pendingBuffer = 0 /* Buf.No */;
29763
29762
  this.flushBuffer(active);
@@ -29767,7 +29766,8 @@
29767
29766
  }
29768
29767
  line.append(wrapMarks(view, active), openStart);
29769
29768
  this.atCursorPos = cursorAfter;
29770
- this.pendingBuffer = !cursorAfter ? 0 /* Buf.No */ : from < to ? 1 /* Buf.Yes */ : 2 /* Buf.IfCursor */;
29769
+ this.pendingBuffer = !cursorAfter ? 0 /* Buf.No */ : from < to || openStart > active.length ? 1 /* Buf.Yes */ : 2 /* Buf.IfCursor */;
29770
+ if (this.pendingBuffer) this.bufferMarks = active.slice();
29771
29771
  }
29772
29772
  } else if (this.doc.lineAt(this.pos).from == this.pos) {
29773
29773
  // Line decoration
@@ -33336,7 +33336,6 @@
33336
33336
  margin: 0,
33337
33337
  flexGrow: 2,
33338
33338
  flexShrink: 0,
33339
- minHeight: "100%",
33340
33339
  display: "block",
33341
33340
  whiteSpace: "pre",
33342
33341
  wordWrap: "normal",
@@ -33362,14 +33361,13 @@
33362
33361
  },
33363
33362
  ".cm-line": {
33364
33363
  display: "block",
33365
- padding: "0 2px 0 4px"
33364
+ padding: "0 2px 0 6px"
33366
33365
  },
33367
- ".cm-selectionLayer": {
33368
- zIndex: -1,
33369
- contain: "size style"
33370
- },
33371
- ".cm-selectionBackground": {
33372
- position: "absolute"
33366
+ ".cm-layer": {
33367
+ contain: "size style",
33368
+ "& > *": {
33369
+ position: "absolute"
33370
+ }
33373
33371
  },
33374
33372
  "&light .cm-selectionBackground": {
33375
33373
  background: "#d9d9d9"
@@ -33384,8 +33382,6 @@
33384
33382
  background: "#233"
33385
33383
  },
33386
33384
  ".cm-cursorLayer": {
33387
- zIndex: 100,
33388
- contain: "size style",
33389
33385
  pointerEvents: "none"
33390
33386
  },
33391
33387
  "&.cm-focused .cm-cursorLayer": {
@@ -33409,7 +33405,6 @@
33409
33405
  "100%": {}
33410
33406
  },
33411
33407
  ".cm-cursor, .cm-dropCursor": {
33412
- position: "absolute",
33413
33408
  borderLeft: "1.2px solid black",
33414
33409
  marginLeft: "-0.6px",
33415
33410
  pointerEvents: "none"
@@ -33511,6 +33506,21 @@
33511
33506
  display: "inline-block",
33512
33507
  verticalAlign: "top"
33513
33508
  },
33509
+ ".cm-highlightSpace:before": {
33510
+ content: "attr(data-display)",
33511
+ position: "absolute",
33512
+ pointerEvents: "none",
33513
+ color: "#888"
33514
+ },
33515
+ ".cm-highlightTab": {
33516
+ backgroundImage: `url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="20"><path stroke="%23888" stroke-width="1" fill="none" d="M1 10H196L190 5M190 15L196 10M197 4L197 16"/></svg>')`,
33517
+ backgroundSize: "auto 100%",
33518
+ backgroundPosition: "right 90%",
33519
+ backgroundRepeat: "no-repeat"
33520
+ },
33521
+ ".cm-trailingSpace": {
33522
+ backgroundColor: "#ff332255"
33523
+ },
33514
33524
  ".cm-button": {
33515
33525
  verticalAlign: "middle",
33516
33526
  color: "inherit",
@@ -33817,7 +33827,8 @@
33817
33827
  this.lastChange = 0;
33818
33828
  this.scrollTargets = [];
33819
33829
  this.intersection = null;
33820
- this.resize = null;
33830
+ this.resizeScroll = null;
33831
+ this.resizeContent = null;
33821
33832
  this.intersecting = false;
33822
33833
  this.gapIntersection = null;
33823
33834
  this.gaps = [];
@@ -33850,11 +33861,13 @@
33850
33861
  this.onPrint = this.onPrint.bind(this);
33851
33862
  this.onScroll = this.onScroll.bind(this);
33852
33863
  if (typeof ResizeObserver == "function") {
33853
- this.resize = new ResizeObserver(() => {
33864
+ this.resizeScroll = new ResizeObserver(() => {
33854
33865
  var _a;
33855
33866
  if (((_a = this.view.docView) === null || _a === void 0 ? void 0 : _a.lastUpdate) < Date.now() - 75) this.onResize();
33856
33867
  });
33857
- this.resize.observe(view.scrollDOM);
33868
+ this.resizeScroll.observe(view.scrollDOM);
33869
+ this.resizeContent = new ResizeObserver(() => this.view.requestMeasure());
33870
+ this.resizeContent.observe(view.contentDOM);
33858
33871
  }
33859
33872
  this.addWindowListeners(this.win = view.win);
33860
33873
  this.start();
@@ -34151,11 +34164,12 @@
34151
34164
  win.document.removeEventListener("selectionchange", this.onSelectionChange);
34152
34165
  }
34153
34166
  destroy() {
34154
- var _a, _b, _c;
34167
+ var _a, _b, _c, _d;
34155
34168
  this.stop();
34156
34169
  (_a = this.intersection) === null || _a === void 0 ? void 0 : _a.disconnect();
34157
34170
  (_b = this.gapIntersection) === null || _b === void 0 ? void 0 : _b.disconnect();
34158
- (_c = this.resize) === null || _c === void 0 ? void 0 : _c.disconnect();
34171
+ (_c = this.resizeScroll) === null || _c === void 0 ? void 0 : _c.disconnect();
34172
+ (_d = this.resizeContent) === null || _d === void 0 ? void 0 : _d.disconnect();
34159
34173
  for (let dom of this.scrollTargets) dom.removeEventListener("scroll", this.onScroll);
34160
34174
  this.removeWindowListeners(this.win);
34161
34175
  clearTimeout(this.parentCheck);
@@ -34257,7 +34271,7 @@
34257
34271
  this.scrollDOM.className = "cm-scroller";
34258
34272
  this.scrollDOM.appendChild(this.contentDOM);
34259
34273
  this.announceDOM = document.createElement("div");
34260
- this.announceDOM.style.cssText = "position: absolute; top: -10000px";
34274
+ this.announceDOM.style.cssText = "position: fixed; top: -10000px";
34261
34275
  this.announceDOM.setAttribute("aria-live", "polite");
34262
34276
  this.dom = document.createElement("div");
34263
34277
  this.dom.appendChild(this.announceDOM);
@@ -35285,46 +35299,22 @@
35285
35299
  }
35286
35300
  return fallthrough;
35287
35301
  }
35288
- const CanHidePrimary = !browser.ios; // FIXME test IE
35289
- const selectionConfig = /*@__PURE__*/Facet.define({
35290
- combine(configs) {
35291
- return combineConfig(configs, {
35292
- cursorBlinkRate: 1200,
35293
- drawRangeCursor: true
35294
- }, {
35295
- cursorBlinkRate: (a, b) => Math.min(a, b),
35296
- drawRangeCursor: (a, b) => a || b
35297
- });
35298
- }
35299
- });
35300
- /**
35301
- Returns an extension that hides the browser's native selection and
35302
- cursor, replacing the selection with a background behind the text
35303
- (with the `cm-selectionBackground` class), and the
35304
- cursors with elements overlaid over the code (using
35305
- `cm-cursor-primary` and `cm-cursor-secondary`).
35306
-
35307
- This allows the editor to display secondary selection ranges, and
35308
- tends to produce a type of selection more in line with that users
35309
- expect in a text editor (the native selection styling will often
35310
- leave gaps between lines and won't fill the horizontal space after
35311
- a line when the selection continues past it).
35312
35302
 
35313
- It does have a performance cost, in that it requires an extra DOM
35314
- layout cycle for many updates (the selection is drawn based on DOM
35315
- layout information that's only available after laying out the
35316
- content).
35303
+ /**
35304
+ Implementation of [`LayerMarker`](https://codemirror.net/6/docs/ref/#view.LayerMarker) that creates
35305
+ a rectangle at a given set of coordinates.
35317
35306
  */
35318
- function drawSelection(config = {}) {
35319
- return [selectionConfig.of(config), drawSelectionPlugin, hideNativeSelection, nativeSelectionHidden.of(true)];
35320
- }
35321
- class Piece {
35322
- constructor(left, top, width, height, className) {
35307
+ class RectangleMarker {
35308
+ /**
35309
+ Create a marker with the given class and dimensions. If `width`
35310
+ is null, the DOM element will get no width style.
35311
+ */
35312
+ constructor(className, left, top, width, height) {
35313
+ this.className = className;
35323
35314
  this.left = left;
35324
35315
  this.top = top;
35325
35316
  this.width = width;
35326
35317
  this.height = height;
35327
- this.className = className;
35328
35318
  }
35329
35319
  draw() {
35330
35320
  let elt = document.createElement("div");
@@ -35332,99 +35322,38 @@
35332
35322
  this.adjust(elt);
35333
35323
  return elt;
35334
35324
  }
35325
+ update(elt, prev) {
35326
+ if (prev.className != this.className) return false;
35327
+ this.adjust(elt);
35328
+ return true;
35329
+ }
35335
35330
  adjust(elt) {
35336
35331
  elt.style.left = this.left + "px";
35337
35332
  elt.style.top = this.top + "px";
35338
- if (this.width >= 0) elt.style.width = this.width + "px";
35333
+ if (this.width != null) elt.style.width = this.width + "px";
35339
35334
  elt.style.height = this.height + "px";
35340
35335
  }
35341
35336
  eq(p) {
35342
35337
  return this.left == p.left && this.top == p.top && this.width == p.width && this.height == p.height && this.className == p.className;
35343
35338
  }
35344
- }
35345
- const drawSelectionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
35346
- constructor(view) {
35347
- this.view = view;
35348
- this.rangePieces = [];
35349
- this.cursors = [];
35350
- this.measureReq = {
35351
- read: this.readPos.bind(this),
35352
- write: this.drawSel.bind(this)
35353
- };
35354
- this.selectionLayer = view.scrollDOM.appendChild(document.createElement("div"));
35355
- this.selectionLayer.className = "cm-selectionLayer";
35356
- this.selectionLayer.setAttribute("aria-hidden", "true");
35357
- this.cursorLayer = view.scrollDOM.appendChild(document.createElement("div"));
35358
- this.cursorLayer.className = "cm-cursorLayer";
35359
- this.cursorLayer.setAttribute("aria-hidden", "true");
35360
- view.requestMeasure(this.measureReq);
35361
- this.setBlinkRate();
35362
- }
35363
- setBlinkRate() {
35364
- this.cursorLayer.style.animationDuration = this.view.state.facet(selectionConfig).cursorBlinkRate + "ms";
35365
- }
35366
- update(update) {
35367
- let confChanged = update.startState.facet(selectionConfig) != update.state.facet(selectionConfig);
35368
- if (confChanged || update.selectionSet || update.geometryChanged || update.viewportChanged) this.view.requestMeasure(this.measureReq);
35369
- if (update.transactions.some(tr => tr.scrollIntoView)) this.cursorLayer.style.animationName = this.cursorLayer.style.animationName == "cm-blink" ? "cm-blink2" : "cm-blink";
35370
- if (confChanged) this.setBlinkRate();
35371
- }
35372
- readPos() {
35373
- let {
35374
- state
35375
- } = this.view,
35376
- conf = state.facet(selectionConfig);
35377
- let rangePieces = state.selection.ranges.map(r => r.empty ? [] : measureRange(this.view, r)).reduce((a, b) => a.concat(b));
35378
- let cursors = [];
35379
- for (let r of state.selection.ranges) {
35380
- let prim = r == state.selection.main;
35381
- if (r.empty ? !prim || CanHidePrimary : conf.drawRangeCursor) {
35382
- let piece = measureCursor(this.view, r, prim);
35383
- if (piece) cursors.push(piece);
35384
- }
35385
- }
35386
- return {
35387
- rangePieces,
35388
- cursors
35389
- };
35390
- }
35391
- drawSel({
35392
- rangePieces,
35393
- cursors
35394
- }) {
35395
- if (rangePieces.length != this.rangePieces.length || rangePieces.some((p, i) => !p.eq(this.rangePieces[i]))) {
35396
- this.selectionLayer.textContent = "";
35397
- for (let p of rangePieces) this.selectionLayer.appendChild(p.draw());
35398
- this.rangePieces = rangePieces;
35399
- }
35400
- if (cursors.length != this.cursors.length || cursors.some((c, i) => !c.eq(this.cursors[i]))) {
35401
- let oldCursors = this.cursorLayer.children;
35402
- if (oldCursors.length !== cursors.length) {
35403
- this.cursorLayer.textContent = "";
35404
- for (const c of cursors) this.cursorLayer.appendChild(c.draw());
35405
- } else {
35406
- cursors.forEach((c, idx) => c.adjust(oldCursors[idx]));
35407
- }
35408
- this.cursors = cursors;
35409
- }
35410
- }
35411
- destroy() {
35412
- this.selectionLayer.remove();
35413
- this.cursorLayer.remove();
35414
- }
35415
- });
35416
- const themeSpec = {
35417
- ".cm-line": {
35418
- "& ::selection": {
35419
- backgroundColor: "transparent !important"
35420
- },
35421
- "&::selection": {
35422
- backgroundColor: "transparent !important"
35339
+ /**
35340
+ Create a set of rectangles for the given selection range,
35341
+ assigning them theclass`className`. Will create a single
35342
+ rectangle for empty ranges, and a set of selection-style
35343
+ rectangles covering the range's content (in a bidi-aware
35344
+ way) for non-empty ones.
35345
+ */
35346
+ static forRange(view, className, range) {
35347
+ if (range.empty) {
35348
+ let pos = view.coordsAtPos(range.head, range.assoc || 1);
35349
+ if (!pos) return [];
35350
+ let base = getBase(view);
35351
+ return [new RectangleMarker(className, pos.left - base.left, pos.top - base.top, null, pos.bottom - pos.top)];
35352
+ } else {
35353
+ return rectanglesForRange(view, className, range);
35423
35354
  }
35424
35355
  }
35425
- };
35426
- if (CanHidePrimary) themeSpec[".cm-line"].caretColor = "transparent !important";
35427
- const hideNativeSelection = /*@__PURE__*/Prec.highest( /*@__PURE__*/EditorView.theme(themeSpec));
35356
+ }
35428
35357
  function getBase(view) {
35429
35358
  let rect = view.scrollDOM.getBoundingClientRect();
35430
35359
  let left = view.textDirection == Direction.LTR ? rect.left : rect.right - view.scrollDOM.clientWidth;
@@ -35448,7 +35377,7 @@
35448
35377
  }
35449
35378
  return line;
35450
35379
  }
35451
- function measureRange(view, range) {
35380
+ function rectanglesForRange(view, className, range) {
35452
35381
  if (range.to <= view.viewport.from || range.from >= view.viewport.to) return [];
35453
35382
  let from = Math.max(range.from, view.viewport.from),
35454
35383
  to = Math.min(range.to, view.viewport.to);
@@ -35477,8 +35406,9 @@
35477
35406
  return pieces(top).concat(between).concat(pieces(bottom));
35478
35407
  }
35479
35408
  function piece(left, top, right, bottom) {
35480
- return new Piece(left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */, "cm-selectionBackground");
35409
+ return new RectangleMarker(className, left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */);
35481
35410
  }
35411
+
35482
35412
  function pieces({
35483
35413
  top,
35484
35414
  bottom,
@@ -35536,12 +35466,162 @@
35536
35466
  };
35537
35467
  }
35538
35468
  }
35539
- function measureCursor(view, cursor, primary) {
35540
- let pos = view.coordsAtPos(cursor.head, cursor.assoc || 1);
35541
- if (!pos) return null;
35542
- let base = getBase(view);
35543
- return new Piece(pos.left - base.left, pos.top - base.top, -1, pos.bottom - pos.top, primary ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary");
35469
+ function sameMarker(a, b) {
35470
+ return a.constructor == b.constructor && a.eq(b);
35471
+ }
35472
+ class LayerView {
35473
+ constructor(view, layer) {
35474
+ this.view = view;
35475
+ this.layer = layer;
35476
+ this.drawn = [];
35477
+ this.measureReq = {
35478
+ read: this.measure.bind(this),
35479
+ write: this.draw.bind(this)
35480
+ };
35481
+ this.dom = view.scrollDOM.appendChild(document.createElement("div"));
35482
+ this.dom.classList.add("cm-layer");
35483
+ if (layer.above) this.dom.classList.add("cm-layer-above");
35484
+ if (layer.class) this.dom.classList.add(layer.class);
35485
+ this.dom.setAttribute("aria-hidden", "true");
35486
+ this.setOrder(view.state);
35487
+ view.requestMeasure(this.measureReq);
35488
+ if (layer.mount) layer.mount(this.dom, view);
35489
+ }
35490
+ update(update) {
35491
+ if (update.startState.facet(layerOrder) != update.state.facet(layerOrder)) this.setOrder(update.state);
35492
+ if (this.layer.update(update, this.dom) || update.geometryChanged) update.view.requestMeasure(this.measureReq);
35493
+ }
35494
+ setOrder(state) {
35495
+ let pos = 0,
35496
+ order = state.facet(layerOrder);
35497
+ while (pos < order.length && order[pos] != this.layer) pos++;
35498
+ this.dom.style.zIndex = String((this.layer.above ? 150 : -1) - pos);
35499
+ }
35500
+ measure() {
35501
+ return this.layer.markers(this.view);
35502
+ }
35503
+ draw(markers) {
35504
+ if (markers.length != this.drawn.length || markers.some((p, i) => !sameMarker(p, this.drawn[i]))) {
35505
+ let old = this.dom.firstChild,
35506
+ oldI = 0;
35507
+ for (let marker of markers) {
35508
+ if (marker.update && old && marker.constructor && this.drawn[oldI].constructor && marker.update(old, this.drawn[oldI])) {
35509
+ old = old.nextSibling;
35510
+ oldI++;
35511
+ } else {
35512
+ this.dom.insertBefore(marker.draw(), old);
35513
+ }
35514
+ }
35515
+ while (old) {
35516
+ let next = old.nextSibling;
35517
+ old.remove();
35518
+ old = next;
35519
+ }
35520
+ this.drawn = markers;
35521
+ }
35522
+ }
35523
+ destroy() {
35524
+ if (this.layer.destroy) this.layer.destroy(this.dom, this.view);
35525
+ this.dom.remove();
35526
+ }
35527
+ }
35528
+ const layerOrder = /*@__PURE__*/Facet.define();
35529
+ /**
35530
+ Define a layer.
35531
+ */
35532
+ function layer(config) {
35533
+ return [ViewPlugin.define(v => new LayerView(v, config)), layerOrder.of(config)];
35534
+ }
35535
+ const CanHidePrimary = !browser.ios; // FIXME test IE
35536
+ const selectionConfig = /*@__PURE__*/Facet.define({
35537
+ combine(configs) {
35538
+ return combineConfig(configs, {
35539
+ cursorBlinkRate: 1200,
35540
+ drawRangeCursor: true
35541
+ }, {
35542
+ cursorBlinkRate: (a, b) => Math.min(a, b),
35543
+ drawRangeCursor: (a, b) => a || b
35544
+ });
35545
+ }
35546
+ });
35547
+ /**
35548
+ Returns an extension that hides the browser's native selection and
35549
+ cursor, replacing the selection with a background behind the text
35550
+ (with the `cm-selectionBackground` class), and the
35551
+ cursors with elements overlaid over the code (using
35552
+ `cm-cursor-primary` and `cm-cursor-secondary`).
35553
+
35554
+ This allows the editor to display secondary selection ranges, and
35555
+ tends to produce a type of selection more in line with that users
35556
+ expect in a text editor (the native selection styling will often
35557
+ leave gaps between lines and won't fill the horizontal space after
35558
+ a line when the selection continues past it).
35559
+
35560
+ It does have a performance cost, in that it requires an extra DOM
35561
+ layout cycle for many updates (the selection is drawn based on DOM
35562
+ layout information that's only available after laying out the
35563
+ content).
35564
+ */
35565
+ function drawSelection(config = {}) {
35566
+ return [selectionConfig.of(config), cursorLayer, selectionLayer, hideNativeSelection, nativeSelectionHidden.of(true)];
35544
35567
  }
35568
+ function configChanged(update) {
35569
+ return update.startState.facet(selectionConfig) != update.startState.facet(selectionConfig);
35570
+ }
35571
+ const cursorLayer = /*@__PURE__*/layer({
35572
+ above: true,
35573
+ markers(view) {
35574
+ let {
35575
+ state
35576
+ } = view,
35577
+ conf = state.facet(selectionConfig);
35578
+ let cursors = [];
35579
+ for (let r of state.selection.ranges) {
35580
+ let prim = r == state.selection.main;
35581
+ if (r.empty ? !prim || CanHidePrimary : conf.drawRangeCursor) {
35582
+ let className = prim ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary";
35583
+ let cursor = r.empty ? r : EditorSelection.cursor(r.head, r.head > r.anchor ? -1 : 1);
35584
+ for (let piece of RectangleMarker.forRange(view, className, cursor)) cursors.push(piece);
35585
+ }
35586
+ }
35587
+ return cursors;
35588
+ },
35589
+ update(update, dom) {
35590
+ if (update.transactions.some(tr => tr.scrollIntoView)) dom.style.animationName = dom.style.animationName == "cm-blink" ? "cm-blink2" : "cm-blink";
35591
+ let confChange = configChanged(update);
35592
+ if (confChange) setBlinkRate(update.state, dom);
35593
+ return update.docChanged || update.selectionSet || confChange;
35594
+ },
35595
+ mount(dom, view) {
35596
+ setBlinkRate(view.state, dom);
35597
+ },
35598
+ class: "cm-cursorLayer"
35599
+ });
35600
+ function setBlinkRate(state, dom) {
35601
+ dom.style.animationDuration = state.facet(selectionConfig).cursorBlinkRate + "ms";
35602
+ }
35603
+ const selectionLayer = /*@__PURE__*/layer({
35604
+ above: false,
35605
+ markers(view) {
35606
+ return view.state.selection.ranges.map(r => r.empty ? [] : RectangleMarker.forRange(view, "cm-selectionBackground", r)).reduce((a, b) => a.concat(b));
35607
+ },
35608
+ update(update, dom) {
35609
+ return update.docChanged || update.selectionSet || update.viewportChanged || configChanged(update);
35610
+ },
35611
+ class: "cm-selectionLayer"
35612
+ });
35613
+ const themeSpec = {
35614
+ ".cm-line": {
35615
+ "& ::selection": {
35616
+ backgroundColor: "transparent !important"
35617
+ },
35618
+ "&::selection": {
35619
+ backgroundColor: "transparent !important"
35620
+ }
35621
+ }
35622
+ };
35623
+ if (CanHidePrimary) themeSpec[".cm-line"].caretColor = "transparent !important";
35624
+ const hideNativeSelection = /*@__PURE__*/Prec.highest( /*@__PURE__*/EditorView.theme(themeSpec));
35545
35625
  const setDropCursorPos = /*@__PURE__*/StateEffect.define({
35546
35626
  map(pos, mapping) {
35547
35627
  return pos == null ? null : mapping.mapPos(pos);
@@ -36294,6 +36374,16 @@
36294
36374
  let left = size.width > space.right - space.left ? ltr ? space.left : space.right - size.width : ltr ? Math.min(pos.left - (arrow ? 14 /* Arrow.Offset */ : 0) + offset.x, space.right - width) : Math.max(space.left, pos.left - width + (arrow ? 14 /* Arrow.Offset */ : 0) - offset.x);
36295
36375
  let above = !!tooltip.above;
36296
36376
  if (!tooltip.strictSide && (above ? pos.top - (size.bottom - size.top) - offset.y < space.top : pos.bottom + (size.bottom - size.top) + offset.y > space.bottom) && above == space.bottom - pos.bottom > pos.top - space.top) above = !above;
36377
+ let spaceVert = (above ? pos.top - space.top : space.bottom - pos.bottom) - arrowHeight;
36378
+ if (spaceVert < height && tView.resize !== false) {
36379
+ if (spaceVert < this.view.defaultLineHeight) {
36380
+ dom.style.top = Outside;
36381
+ continue;
36382
+ }
36383
+ dom.style.height = (height = spaceVert) + "px";
36384
+ } else if (dom.style.height) {
36385
+ dom.style.height = "";
36386
+ }
36297
36387
  let top = above ? pos.top - height - arrowHeight - offset.y : pos.bottom + arrowHeight + offset.y;
36298
36388
  let right = left + width;
36299
36389
  if (tView.overlap !== true) for (let r of others) if (r.left < right && r.right > left && r.top < top + height && r.bottom > top) top = above ? r.top - height - 2 - arrowHeight : r.bottom + arrowHeight + 2;
@@ -36334,7 +36424,8 @@
36334
36424
  });
36335
36425
  const baseTheme$6 = /*@__PURE__*/EditorView.baseTheme({
36336
36426
  ".cm-tooltip": {
36337
- zIndex: 100
36427
+ zIndex: 100,
36428
+ boxSizing: "border-box"
36338
36429
  },
36339
36430
  "&light .cm-tooltip": {
36340
36431
  border: "1px solid #bbb",
@@ -40037,6 +40128,7 @@
40037
40128
  maxWidth: "min(700px, 95vw)",
40038
40129
  minWidth: "250px",
40039
40130
  maxHeight: "10em",
40131
+ height: "100%",
40040
40132
  listStyle: "none",
40041
40133
  margin: 0,
40042
40134
  padding: 0,
@@ -40755,7 +40847,7 @@
40755
40847
  /**
40756
40848
  Returns an extension that enables autocompletion.
40757
40849
  */
40758
- function autocompletion$1(config = {}) {
40850
+ function autocompletion$2(config = {}) {
40759
40851
  return [completionState, completionConfig.of(config), completionPlugin, completionKeymapExt, baseTheme$4];
40760
40852
  }
40761
40853
  /**
@@ -42527,6 +42619,17 @@
42527
42619
  key: "Alt-A",
42528
42620
  run: toggleBlockComment
42529
42621
  }].concat(standardKeymap);
42622
+ /**
42623
+ A binding that binds Tab to [`indentMore`](https://codemirror.net/6/docs/ref/#commands.indentMore) and
42624
+ Shift-Tab to [`indentLess`](https://codemirror.net/6/docs/ref/#commands.indentLess).
42625
+ Please see the [Tab example](../../examples/tab/) before using
42626
+ this.
42627
+ */
42628
+ const indentWithTab = {
42629
+ key: "Tab",
42630
+ run: indentMore,
42631
+ shift: indentLess
42632
+ };
42530
42633
 
42531
42634
  function crelt() {
42532
42635
  var elt = arguments[0];
@@ -44672,13 +44775,13 @@
44672
44775
  /**
44673
44776
  * @type {Facet<import('..').Variable[]>} Variable
44674
44777
  */
44675
- const variablesFacet = Facet.define();
44778
+ const variablesFacet$1 = Facet.define();
44676
44779
 
44677
44780
  /**
44678
44781
  * @type {import('@codemirror/autocomplete').CompletionSource}
44679
44782
  */
44680
44783
  var variables = context => {
44681
- const variables = context.state.facet(variablesFacet)[0];
44784
+ const variables = context.state.facet(variablesFacet$1)[0];
44682
44785
  const options = variables.map(v => ({
44683
44786
  label: v.name,
44684
44787
  type: 'variable',
@@ -44711,8 +44814,8 @@
44711
44814
  }
44712
44815
  return result;
44713
44816
  };
44714
- function autocompletion() {
44715
- return [autocompletion$1({
44817
+ function autocompletion$1() {
44818
+ return [autocompletion$2({
44716
44819
  override: [variables, builtins, completeFromList(snippets)]
44717
44820
  })];
44718
44821
  }
@@ -44889,7 +44992,7 @@
44889
44992
  return tooltipContainer.getBoundingClientRect();
44890
44993
  }
44891
44994
  }) : [];
44892
- const extensions = [autocompletionConf.of(variablesFacet.of(variables)), autocompletion(), bracketMatching(), changeHandler, closeBrackets(), indentOnInput(), keyHandler, keymap.of([...defaultKeymap]), language(), linter, lintHandler, tooltipLayout, theme];
44995
+ const extensions = [autocompletionConf.of(variablesFacet$1.of(variables)), autocompletion$1(), bracketMatching(), changeHandler, closeBrackets(), indentOnInput(), keyHandler, keymap.of([...defaultKeymap]), language(), linter, lintHandler, tooltipLayout, theme];
44893
44996
  if (readOnly) {
44894
44997
  extensions.push(EditorView.editable.of(false));
44895
44998
  }
@@ -44956,7 +45059,7 @@
44956
45059
  */
44957
45060
  FeelEditor.prototype.setVariables = function (variables) {
44958
45061
  this._cmEditor.dispatch({
44959
- effects: autocompletionConf.reconfigure(variablesFacet.of(variables))
45062
+ effects: autocompletionConf.reconfigure(variablesFacet$1.of(variables))
44960
45063
  });
44961
45064
  };
44962
45065
 
@@ -46323,10 +46426,10 @@
46323
46426
  return fn.apply(null, args);
46324
46427
  }
46325
46428
 
46326
- /**
46327
- * A factory to create a configurable debouncer.
46328
- *
46329
- * @param {number|boolean} [config=true]
46429
+ /**
46430
+ * A factory to create a configurable debouncer.
46431
+ *
46432
+ * @param {number|boolean} [config=true]
46330
46433
  */
46331
46434
  function DebounceFactory(config = true) {
46332
46435
  const timeout = typeof config === 'number' ? config : config ? 300 : 0;
@@ -46338,11 +46441,11 @@
46338
46441
  }
46339
46442
  DebounceFactory.$inject = ['config.debounce'];
46340
46443
  class FieldFactory {
46341
- /**
46342
- * @constructor
46343
- *
46344
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
46345
- * @param { import('@bpmn-io/form-js-viewer').FormFields } formFields
46444
+ /**
46445
+ * @constructor
46446
+ *
46447
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
46448
+ * @param { import('@bpmn-io/form-js-viewer').FormFields } formFields
46346
46449
  */
46347
46450
  constructor(formFieldRegistry, formFields) {
46348
46451
  this._formFieldRegistry = formFieldRegistry;
@@ -46401,11 +46504,11 @@
46401
46504
  }
46402
46505
  FieldFactory.$inject = ['formFieldRegistry', 'formFields'];
46403
46506
  class FormFieldRegistry extends FormFieldRegistry$1 {
46404
- /**
46405
- * Updates a form fields id.
46406
- *
46407
- * @param {Object} formField
46408
- * @param {string} newId
46507
+ /**
46508
+ * Updates a form fields id.
46509
+ *
46510
+ * @param {Object} formField
46511
+ * @param {string} newId
46409
46512
  */
46410
46513
  updateId(formField, newId) {
46411
46514
  this._validateId(newId);
@@ -46426,13 +46529,13 @@
46426
46529
  }
46427
46530
  }
46428
46531
 
46429
- /**
46430
- * Validate the suitability of the given id and signals a problem
46431
- * with an exception.
46432
- *
46433
- * @param {string} id
46434
- *
46435
- * @throws {Error} if id is empty or already assigned
46532
+ /**
46533
+ * Validate the suitability of the given id and signals a problem
46534
+ * with an exception.
46535
+ *
46536
+ * @param {string} id
46537
+ *
46538
+ * @throws {Error} if id is empty or already assigned
46436
46539
  */
46437
46540
  _validateId(id) {
46438
46541
  if (!id) {
@@ -46444,31 +46547,31 @@
46444
46547
  }
46445
46548
  }
46446
46549
  class Importer {
46447
- /**
46448
- * @constructor
46449
- * @param { import('../core/FormFieldRegistry').default } formFieldRegistry
46450
- * @param { import('../core/FieldFactory').default } fieldFactory
46550
+ /**
46551
+ * @constructor
46552
+ * @param { import('../core/FormFieldRegistry').default } formFieldRegistry
46553
+ * @param { import('../core/FieldFactory').default } fieldFactory
46451
46554
  */
46452
46555
  constructor(formFieldRegistry, fieldFactory) {
46453
46556
  this._formFieldRegistry = formFieldRegistry;
46454
46557
  this._fieldFactory = fieldFactory;
46455
46558
  }
46456
46559
 
46457
- /**
46458
- * Import schema creating fields, attaching additional
46459
- * information to each field and adding fields to the
46460
- * field registry.
46461
- *
46462
- * Additional information attached:
46463
- *
46464
- * * `id` (unless present)
46465
- * * `_parent`
46466
- * * `_path`
46467
- *
46468
- * @param {any} schema
46469
- *
46470
- * @typedef {{ warnings: Error[], schema: any }} ImportResult
46471
- * @returns {ImportResult}
46560
+ /**
46561
+ * Import schema creating fields, attaching additional
46562
+ * information to each field and adding fields to the
46563
+ * field registry.
46564
+ *
46565
+ * Additional information attached:
46566
+ *
46567
+ * * `id` (unless present)
46568
+ * * `_parent`
46569
+ * * `_path`
46570
+ *
46571
+ * @param {any} schema
46572
+ *
46573
+ * @typedef {{ warnings: Error[], schema: any }} ImportResult
46574
+ * @returns {ImportResult}
46472
46575
  */
46473
46576
  importSchema(schema) {
46474
46577
  // TODO: Add warnings
@@ -46485,12 +46588,12 @@
46485
46588
  }
46486
46589
  }
46487
46590
 
46488
- /**
46489
- * @param {{[x: string]: any}} fieldAttrs
46490
- * @param {String} [parentId]
46491
- * @param {number} [index]
46492
- *
46493
- * @return {any} field
46591
+ /**
46592
+ * @param {{[x: string]: any}} fieldAttrs
46593
+ * @param {String} [parentId]
46594
+ * @param {number} [index]
46595
+ *
46596
+ * @return {any} field
46494
46597
  */
46495
46598
  importFormField(fieldAttrs, parentId, index) {
46496
46599
  const {
@@ -46527,11 +46630,11 @@
46527
46630
  return field;
46528
46631
  }
46529
46632
 
46530
- /**
46531
- * @param {Array<any>} components
46532
- * @param {string} parentId
46533
- *
46534
- * @return {Array<any>} imported components
46633
+ /**
46634
+ * @param {Array<any>} components
46635
+ * @param {string} parentId
46636
+ *
46637
+ * @return {Array<any>} imported components
46535
46638
  */
46536
46639
  importFormFields(components, parentId) {
46537
46640
  return components.map((component, index) => {
@@ -46547,11 +46650,11 @@
46547
46650
  drake: null
46548
46651
  });
46549
46652
 
46550
- /**
46551
- * @param {string} type
46552
- * @param {boolean} [strict]
46553
- *
46554
- * @returns {any}
46653
+ /**
46654
+ * @param {string} type
46655
+ * @param {boolean} [strict]
46656
+ *
46657
+ * @returns {any}
46555
46658
  */
46556
46659
  function getService$1(type, strict) {}
46557
46660
  const FormEditorContext = D$1({
@@ -47615,10 +47718,10 @@
47615
47718
  return formField;
47616
47719
  }
47617
47720
  class AddFormFieldHandler {
47618
- /**
47619
- * @constructor
47620
- * @param { import('../../../FormEditor').default } formEditor
47621
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47721
+ /**
47722
+ * @constructor
47723
+ * @param { import('../../../FormEditor').default } formEditor
47724
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47622
47725
  */
47623
47726
  constructor(formEditor, formFieldRegistry) {
47624
47727
  this._formEditor = formEditor;
@@ -47678,10 +47781,10 @@
47678
47781
  }
47679
47782
  AddFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
47680
47783
  class EditFormFieldHandler {
47681
- /**
47682
- * @constructor
47683
- * @param { import('../../../FormEditor').default } formEditor
47684
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47784
+ /**
47785
+ * @constructor
47786
+ * @param { import('../../../FormEditor').default } formEditor
47787
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47685
47788
  */
47686
47789
  constructor(formEditor, formFieldRegistry) {
47687
47790
  this._formEditor = formEditor;
@@ -47743,10 +47846,10 @@
47743
47846
  }
47744
47847
  EditFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
47745
47848
  class MoveFormFieldHandler {
47746
- /**
47747
- * @constructor
47748
- * @param { import('../../../FormEditor').default } formEditor
47749
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47849
+ /**
47850
+ * @constructor
47851
+ * @param { import('../../../FormEditor').default } formEditor
47852
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47750
47853
  */
47751
47854
  constructor(formEditor, formFieldRegistry) {
47752
47855
  this._formEditor = formEditor;
@@ -47822,10 +47925,10 @@
47822
47925
  }
47823
47926
  MoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
47824
47927
  class RemoveFormFieldHandler {
47825
- /**
47826
- * @constructor
47827
- * @param { import('../../../FormEditor').default } formEditor
47828
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47928
+ /**
47929
+ * @constructor
47930
+ * @param { import('../../../FormEditor').default } formEditor
47931
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47829
47932
  */
47830
47933
  constructor(formEditor, formFieldRegistry) {
47831
47934
  this._formEditor = formEditor;
@@ -47884,9 +47987,9 @@
47884
47987
  }
47885
47988
  RemoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
47886
47989
  class UpdateIdClaimHandler {
47887
- /**
47888
- * @constructor
47889
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47990
+ /**
47991
+ * @constructor
47992
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47890
47993
  */
47891
47994
  constructor(formFieldRegistry) {
47892
47995
  this._formFieldRegistry = formFieldRegistry;
@@ -47918,9 +48021,9 @@
47918
48021
  }
47919
48022
  UpdateIdClaimHandler.$inject = ['formFieldRegistry'];
47920
48023
  class UpdateKeyClaimHandler {
47921
- /**
47922
- * @constructor
47923
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
48024
+ /**
48025
+ * @constructor
48026
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
47924
48027
  */
47925
48028
  constructor(formFieldRegistry) {
47926
48029
  this._formFieldRegistry = formFieldRegistry;
@@ -48221,10 +48324,39 @@
48221
48324
  }
48222
48325
  }
48223
48326
  KeyBehavior.$inject = ['eventBus', 'modeling'];
48327
+ class ValidateBehavior extends CommandInterceptor {
48328
+ constructor(eventBus) {
48329
+ super(eventBus);
48330
+
48331
+ /**
48332
+ * Remove custom validation if <validationType> is about to be added.
48333
+ */
48334
+ // @ts-ignore-next-line
48335
+ this.preExecute('formField.edit', function (context) {
48336
+ const {
48337
+ properties
48338
+ } = context;
48339
+ const {
48340
+ validate = {}
48341
+ } = properties;
48342
+ if (validate.validationType) {
48343
+ const newValidate = {
48344
+ ...validate
48345
+ };
48346
+ delete newValidate.minLength;
48347
+ delete newValidate.maxLength;
48348
+ delete newValidate.pattern;
48349
+ properties['validate'] = newValidate;
48350
+ }
48351
+ }, true);
48352
+ }
48353
+ }
48354
+ ValidateBehavior.$inject = ['eventBus'];
48224
48355
  var behaviorModule = {
48225
- __init__: ['idBehavior', 'keyBehavior'],
48356
+ __init__: ['idBehavior', 'keyBehavior', 'validateBehavior'],
48226
48357
  idBehavior: ['type', IdBehavior],
48227
- keyBehavior: ['type', KeyBehavior]
48358
+ keyBehavior: ['type', KeyBehavior],
48359
+ validateBehavior: ['type', ValidateBehavior]
48228
48360
  };
48229
48361
 
48230
48362
  /**
@@ -48806,10 +48938,10 @@
48806
48938
  });
48807
48939
  }
48808
48940
 
48809
- /**
48810
- * Attach the palette to a parent node.
48811
- *
48812
- * @param {HTMLElement} container
48941
+ /**
48942
+ * Attach the palette to a parent node.
48943
+ *
48944
+ * @param {HTMLElement} container
48813
48945
  */
48814
48946
  attachTo(container) {
48815
48947
  if (!container) {
@@ -48829,8 +48961,8 @@
48829
48961
  this._eventBus.fire('palette.attach');
48830
48962
  }
48831
48963
 
48832
- /**
48833
- * Detach the palette from its parent node.
48964
+ /**
48965
+ * Detach the palette from its parent node.
48834
48966
  */
48835
48967
  detach() {
48836
48968
  const parentNode = this._container.parentNode;
@@ -50965,11 +51097,11 @@
50965
51097
  return `bio-properties-panel-${id}`;
50966
51098
  }
50967
51099
 
50968
- /**
50969
- * @param {string} type
50970
- * @param {boolean} [strict]
50971
- *
50972
- * @returns {any}
51100
+ /**
51101
+ * @param {string} type
51102
+ * @param {boolean} [strict]
51103
+ *
51104
+ * @returns {any}
50973
51105
  */
50974
51106
  function getService(type, strict) {}
50975
51107
  const PropertiesPanelContext = D$1({
@@ -51055,8 +51187,8 @@
51055
51187
  }
51056
51188
  };
51057
51189
 
51058
- /**
51059
- * Provide placeholders for empty and multiple state.
51190
+ /**
51191
+ * Provide placeholders for empty and multiple state.
51060
51192
  */
51061
51193
  const PropertiesPanelPlaceholderProvider = {
51062
51194
  getEmpty: () => {
@@ -51126,10 +51258,10 @@
51126
51258
  return getService(type, strict);
51127
51259
  }
51128
51260
 
51129
- /**
51130
- * Retrieve list of variables from the form schema.
51131
- *
51132
- * @returns { string[] } list of variables used in form schema
51261
+ /**
51262
+ * Retrieve list of variables from the form schema.
51263
+ *
51264
+ * @returns { string[] } list of variables used in form schema
51133
51265
  */
51134
51266
  function useVariables() {
51135
51267
  const form = useService('formEditor');
@@ -51926,7 +52058,12 @@
51926
52058
  if (!isValidNumber(value)) return null;
51927
52059
  return value;
51928
52060
  };
51929
- const setValue = value => editField(field, ['increment'], value);
52061
+ const clearLeadingZeroes = value => {
52062
+ if (!value) return value;
52063
+ const trimmed = value.replace(/^0+/g, '');
52064
+ return (trimmed.startsWith('.') ? '0' : '') + trimmed;
52065
+ };
52066
+ const setValue = value => editField(field, ['increment'], clearLeadingZeroes(value));
51930
52067
  const decimalDigitsSet = decimalDigits || decimalDigits === 0;
51931
52068
  return TextfieldEntry({
51932
52069
  debounce,
@@ -52396,14 +52533,14 @@
52396
52533
 
52397
52534
  // helpers //////////
52398
52535
 
52399
- /**
52400
- * Returns copy of object with updated value.
52401
- *
52402
- * @param {Object} properties
52403
- * @param {string} key
52404
- * @param {string} value
52405
- *
52406
- * @returns {Object}
52536
+ /**
52537
+ * Returns copy of object with updated value.
52538
+ *
52539
+ * @param {Object} properties
52540
+ * @param {string} key
52541
+ * @param {string} value
52542
+ *
52543
+ * @returns {Object}
52407
52544
  */
52408
52545
  function updateValue(properties, key, value) {
52409
52546
  return {
@@ -52412,14 +52549,14 @@
52412
52549
  };
52413
52550
  }
52414
52551
 
52415
- /**
52416
- * Returns copy of object with updated key.
52417
- *
52418
- * @param {Object} properties
52419
- * @param {string} oldKey
52420
- * @param {string} newKey
52421
- *
52422
- * @returns {Object}
52552
+ /**
52553
+ * Returns copy of object with updated key.
52554
+ *
52555
+ * @param {Object} properties
52556
+ * @param {string} oldKey
52557
+ * @param {string} newKey
52558
+ *
52559
+ * @returns {Object}
52423
52560
  */
52424
52561
  function updateKey(properties, oldKey, newKey) {
52425
52562
  return Object.entries(properties).reduce((newProperties, entry) => {
@@ -52796,7 +52933,7 @@
52796
52933
  }
52797
52934
  const VALIDATION_TYPE_OPTIONS = {
52798
52935
  custom: {
52799
- value: 'custom',
52936
+ value: undefined,
52800
52937
  label: 'Custom'
52801
52938
  },
52802
52939
  email: {
@@ -52842,6 +52979,7 @@
52842
52979
  component: ValidationType,
52843
52980
  getValue,
52844
52981
  field,
52982
+ editField,
52845
52983
  isEdited: isEdited$1,
52846
52984
  onChange
52847
52985
  });
@@ -52975,10 +53113,10 @@
52975
53113
  return NumberFieldEntry({
52976
53114
  debounce,
52977
53115
  element: field,
52978
- getValue: getValue('min'),
52979
53116
  id,
52980
53117
  label: 'Minimum',
52981
- min: 0,
53118
+ step: 'any',
53119
+ getValue: getValue('min'),
52982
53120
  setValue: onChange('min')
52983
53121
  });
52984
53122
  }
@@ -52993,10 +53131,10 @@
52993
53131
  return NumberFieldEntry({
52994
53132
  debounce,
52995
53133
  element: field,
52996
- getValue: getValue('max'),
52997
53134
  id,
52998
53135
  label: 'Maximum',
52999
- min: 0,
53136
+ step: 'any',
53137
+ getValue: getValue('max'),
53000
53138
  setValue: onChange('max')
53001
53139
  });
53002
53140
  }
@@ -53008,16 +53146,17 @@
53008
53146
  onChange
53009
53147
  } = props;
53010
53148
  const debounce = useService('debounce');
53149
+ const setValue = validationType => {
53150
+ onChange('validationType')(validationType || undefined);
53151
+ };
53011
53152
  return SelectEntry({
53012
53153
  debounce,
53013
53154
  element: field,
53014
53155
  getValue: getValue('validationType'),
53015
53156
  id,
53016
53157
  label: 'Regular expression validation',
53017
- setValue: onChange('validationType'),
53018
- getOptions() {
53019
- return Object.values(VALIDATION_TYPE_OPTIONS);
53020
- }
53158
+ setValue,
53159
+ getOptions: () => Object.values(VALIDATION_TYPE_OPTIONS)
53021
53160
  });
53022
53161
  }
53023
53162
  function ValuesGroups(field, editField) {
@@ -53034,8 +53173,8 @@
53034
53173
  };
53035
53174
  const valuesSourceId = `${fieldId}-valuesSource`;
53036
53175
 
53037
- /**
53038
- * @type {Array<Group|ListGroup>}
53176
+ /**
53177
+ * @type {Array<Group|ListGroup>}
53039
53178
  */
53040
53179
  const groups = [{
53041
53180
  id: valuesSourceId,
@@ -53135,13 +53274,13 @@
53135
53274
 
53136
53275
  // helpers //////////
53137
53276
 
53138
- /**
53139
- * Returns copy of object without key.
53140
- *
53141
- * @param {Object} properties
53142
- * @param {string} oldKey
53143
- *
53144
- * @returns {Object}
53277
+ /**
53278
+ * Returns copy of object without key.
53279
+ *
53280
+ * @param {Object} properties
53281
+ * @param {string} oldKey
53282
+ *
53283
+ * @returns {Object}
53145
53284
  */
53146
53285
  function removeKey(properties, oldKey) {
53147
53286
  return Object.entries(properties).reduce((newProperties, entry) => {
@@ -53231,9 +53370,9 @@
53231
53370
  }, []);
53232
53371
  h(() => {
53233
53372
  const onFieldChanged = () => {
53234
- /**
53235
- * TODO(pinussilvestrus): update with actual updated element,
53236
- * once we have a proper updater/change support
53373
+ /**
53374
+ * TODO(pinussilvestrus): update with actual updated element,
53375
+ * once we have a proper updater/change support
53237
53376
  */
53238
53377
  _update(selection.get() || schema);
53239
53378
  };
@@ -53284,10 +53423,10 @@
53284
53423
  });
53285
53424
  }
53286
53425
 
53287
- /**
53288
- * Attach the properties panel to a parent node.
53289
- *
53290
- * @param {HTMLElement} container
53426
+ /**
53427
+ * Attach the properties panel to a parent node.
53428
+ *
53429
+ * @param {HTMLElement} container
53291
53430
  */
53292
53431
  attachTo(container) {
53293
53432
  if (!container) {
@@ -53307,8 +53446,8 @@
53307
53446
  this._eventBus.fire('propertiesPanel.attach');
53308
53447
  }
53309
53448
 
53310
- /**
53311
- * Detach the properties panel from its parent node.
53449
+ /**
53450
+ * Detach the properties panel from its parent node.
53312
53451
  */
53313
53452
  detach() {
53314
53453
  const parentNode = this._container.parentNode;
@@ -53338,48 +53477,48 @@
53338
53477
  };
53339
53478
  const ids = new Ids([32, 36, 1]);
53340
53479
 
53341
- /**
53342
- * @typedef { import('./types').Injector } Injector
53343
- * @typedef { import('./types').Module } Module
53344
- * @typedef { import('./types').Schema } Schema
53345
- *
53346
- * @typedef { import('./types').FormEditorOptions } FormEditorOptions
53347
- * @typedef { import('./types').FormEditorProperties } FormEditorProperties
53348
- *
53349
- * @typedef { {
53350
- * properties: FormEditorProperties,
53351
- * schema: Schema
53352
- * } } State
53353
- *
53354
- * @typedef { (type:string, priority:number, handler:Function) => void } OnEventWithPriority
53355
- * @typedef { (type:string, handler:Function) => void } OnEventWithOutPriority
53356
- * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
53480
+ /**
53481
+ * @typedef { import('./types').Injector } Injector
53482
+ * @typedef { import('./types').Module } Module
53483
+ * @typedef { import('./types').Schema } Schema
53484
+ *
53485
+ * @typedef { import('./types').FormEditorOptions } FormEditorOptions
53486
+ * @typedef { import('./types').FormEditorProperties } FormEditorProperties
53487
+ *
53488
+ * @typedef { {
53489
+ * properties: FormEditorProperties,
53490
+ * schema: Schema
53491
+ * } } State
53492
+ *
53493
+ * @typedef { (type:string, priority:number, handler:Function) => void } OnEventWithPriority
53494
+ * @typedef { (type:string, handler:Function) => void } OnEventWithOutPriority
53495
+ * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
53357
53496
  */
53358
53497
 
53359
- /**
53360
- * The form editor.
53498
+ /**
53499
+ * The form editor.
53361
53500
  */
53362
53501
  class FormEditor {
53363
- /**
53364
- * @constructor
53365
- * @param {FormEditorOptions} options
53502
+ /**
53503
+ * @constructor
53504
+ * @param {FormEditorOptions} options
53366
53505
  */
53367
53506
  constructor(options = {}) {
53368
- /**
53369
- * @public
53370
- * @type {OnEventType}
53507
+ /**
53508
+ * @public
53509
+ * @type {OnEventType}
53371
53510
  */
53372
53511
  this.on = this._onEvent;
53373
53512
 
53374
- /**
53375
- * @public
53376
- * @type {String}
53513
+ /**
53514
+ * @public
53515
+ * @type {String}
53377
53516
  */
53378
53517
  this._id = ids.next();
53379
53518
 
53380
- /**
53381
- * @private
53382
- * @type {Element}
53519
+ /**
53520
+ * @private
53521
+ * @type {Element}
53383
53522
  */
53384
53523
  this._container = createFormContainer();
53385
53524
  this._container.setAttribute('input-handle-modified-keys', 'z,y');
@@ -53390,15 +53529,15 @@
53390
53529
  properties = {}
53391
53530
  } = options;
53392
53531
 
53393
- /**
53394
- * @private
53395
- * @type {any}
53532
+ /**
53533
+ * @private
53534
+ * @type {any}
53396
53535
  */
53397
53536
  this.exporter = exporter;
53398
53537
 
53399
- /**
53400
- * @private
53401
- * @type {State}
53538
+ /**
53539
+ * @private
53540
+ * @type {State}
53402
53541
  */
53403
53542
  this._state = {
53404
53543
  properties,
@@ -53427,10 +53566,10 @@
53427
53566
  this._detach(false);
53428
53567
  }
53429
53568
 
53430
- /**
53431
- * @param {Schema} schema
53432
- *
53433
- * @return {Promise<{ warnings: Array<any> }>}
53569
+ /**
53570
+ * @param {Schema} schema
53571
+ *
53572
+ * @return {Promise<{ warnings: Array<any> }>}
53434
53573
  */
53435
53574
  importSchema(schema) {
53436
53575
  return new Promise((resolve, reject) => {
@@ -53459,15 +53598,15 @@
53459
53598
  });
53460
53599
  }
53461
53600
 
53462
- /**
53463
- * @returns {Schema}
53601
+ /**
53602
+ * @returns {Schema}
53464
53603
  */
53465
53604
  saveSchema() {
53466
53605
  return this.getSchema();
53467
53606
  }
53468
53607
 
53469
- /**
53470
- * @returns {Schema}
53608
+ /**
53609
+ * @returns {Schema}
53471
53610
  */
53472
53611
  getSchema() {
53473
53612
  const {
@@ -53476,8 +53615,8 @@
53476
53615
  return exportSchema(schema, this.exporter, schemaVersion);
53477
53616
  }
53478
53617
 
53479
- /**
53480
- * @param {Element|string} parentNode
53618
+ /**
53619
+ * @param {Element|string} parentNode
53481
53620
  */
53482
53621
  attachTo(parentNode) {
53483
53622
  if (!parentNode) {
@@ -53495,10 +53634,10 @@
53495
53634
  this._detach();
53496
53635
  }
53497
53636
 
53498
- /**
53499
- * @internal
53500
- *
53501
- * @param {boolean} [emit]
53637
+ /**
53638
+ * @internal
53639
+ *
53640
+ * @param {boolean} [emit]
53502
53641
  */
53503
53642
  _detach(emit = true) {
53504
53643
  const container = this._container,
@@ -53512,9 +53651,9 @@
53512
53651
  parentNode.removeChild(container);
53513
53652
  }
53514
53653
 
53515
- /**
53516
- * @param {any} property
53517
- * @param {any} value
53654
+ /**
53655
+ * @param {any} property
53656
+ * @param {any} value
53518
53657
  */
53519
53658
  setProperty(property, value) {
53520
53659
  const properties = set(this._getState().properties, [property], value);
@@ -53523,21 +53662,21 @@
53523
53662
  });
53524
53663
  }
53525
53664
 
53526
- /**
53527
- * @param {string} type
53528
- * @param {Function} handler
53665
+ /**
53666
+ * @param {string} type
53667
+ * @param {Function} handler
53529
53668
  */
53530
53669
  off(type, handler) {
53531
53670
  this.get('eventBus').off(type, handler);
53532
53671
  }
53533
53672
 
53534
- /**
53535
- * @internal
53536
- *
53537
- * @param {FormEditorOptions} options
53538
- * @param {Element} container
53539
- *
53540
- * @returns {Injector}
53673
+ /**
53674
+ * @internal
53675
+ *
53676
+ * @param {FormEditorOptions} options
53677
+ * @param {Element} container
53678
+ *
53679
+ * @returns {Injector}
53541
53680
  */
53542
53681
  _createInjector(options, container) {
53543
53682
  const {
@@ -53559,22 +53698,22 @@
53559
53698
  }, core, ...modules, ...additionalModules]);
53560
53699
  }
53561
53700
 
53562
- /**
53563
- * @internal
53701
+ /**
53702
+ * @internal
53564
53703
  */
53565
53704
  _emit(type, data) {
53566
53705
  this.get('eventBus').fire(type, data);
53567
53706
  }
53568
53707
 
53569
- /**
53570
- * @internal
53708
+ /**
53709
+ * @internal
53571
53710
  */
53572
53711
  _getState() {
53573
53712
  return this._state;
53574
53713
  }
53575
53714
 
53576
- /**
53577
- * @internal
53715
+ /**
53716
+ * @internal
53578
53717
  */
53579
53718
  _setState(state) {
53580
53719
  this._state = {
@@ -53584,15 +53723,15 @@
53584
53723
  this._emit('changed', this._getState());
53585
53724
  }
53586
53725
 
53587
- /**
53588
- * @internal
53726
+ /**
53727
+ * @internal
53589
53728
  */
53590
53729
  _getModules() {
53591
53730
  return [ModelingModule, EditorActionsModule, KeyboardModule, SelectionModule, PaletteModule, PropertiesPanelModule];
53592
53731
  }
53593
53732
 
53594
- /**
53595
- * @internal
53733
+ /**
53734
+ * @internal
53596
53735
  */
53597
53736
  _onEvent(type, priority, handler) {
53598
53737
  this.get('eventBus').on(type, priority, handler);
@@ -55004,7 +55143,7 @@
55004
55143
  */
55005
55144
  const basicSetup = /*@__PURE__*/(() => [lineNumbers(), highlightActiveLineGutter(), highlightSpecialChars(), history(), foldGutter(), drawSelection(), dropCursor(), EditorState.allowMultipleSelections.of(true), indentOnInput(), syntaxHighlighting(defaultHighlightStyle, {
55006
55145
  fallback: true
55007
- }), bracketMatching(), closeBrackets(), autocompletion$1(), rectangularSelection(), crosshairCursor(), highlightActiveLine(), highlightSelectionMatches(), keymap.of([...closeBracketsKeymap, ...defaultKeymap, ...searchKeymap, ...historyKeymap, ...foldKeymap, ...completionKeymap, ...lintKeymap])])();
55146
+ }), bracketMatching(), closeBrackets(), autocompletion$2(), rectangularSelection(), crosshairCursor(), highlightActiveLine(), highlightSelectionMatches(), keymap.of([...closeBracketsKeymap, ...defaultKeymap, ...searchKeymap, ...historyKeymap, ...foldKeymap, ...completionKeymap, ...lintKeymap])])();
55008
55147
 
55009
55148
  const jsonHighlighting = styleTags({
55010
55149
  String: tags$1.string,
@@ -55095,18 +55234,56 @@
55095
55234
  return new LanguageSupport(jsonLanguage);
55096
55235
  }
55097
55236
 
55237
+ /**
55238
+ * @type {Facet<import('..').Variables>} Variables
55239
+ */
55240
+ const variablesFacet = Facet.define();
55241
+
55242
+ function autocompletion () {
55243
+ return [autocompletion$2({
55244
+ override: [completions]
55245
+ })];
55246
+ }
55247
+ function completions(context) {
55248
+ const variables = context.state.facet(variablesFacet)[0];
55249
+ const options = variables.map(v => ({
55250
+ label: v,
55251
+ type: 'variable'
55252
+ }));
55253
+ let nodeBefore = syntaxTree(context.state).resolve(context.pos, -1);
55254
+
55255
+ // handle inside property name as explicit call
55256
+ if (nodeBefore.type.name === 'PropertyName') {
55257
+ context.explicit = true;
55258
+ }
55259
+ let word = context.matchBefore(/\w*/);
55260
+ if (word.from == word.to && !context.explicit) {
55261
+ return null;
55262
+ }
55263
+ return {
55264
+ from: word.from,
55265
+ options
55266
+ };
55267
+ }
55268
+
55098
55269
  function JSONEditor(options = {}) {
55099
- const emitter = mitt();
55100
55270
  const {
55101
55271
  readonly = false
55102
55272
  } = options;
55273
+ const emitter = mitt();
55103
55274
  let language = new Compartment().of(json());
55104
55275
  let tabSize = new Compartment().of(EditorState.tabSize.of(2));
55276
+
55277
+ /**
55278
+ * @typedef {Array<string>} Variables
55279
+ */
55280
+
55281
+ const autocompletionConf = new Compartment();
55105
55282
  const linterExtension = linter$1(jsonParseLinter());
55106
- function createState(doc, extensions = []) {
55283
+ function createState(doc, extensions = [], variables = []) {
55107
55284
  return EditorState.create({
55108
55285
  doc,
55109
- extensions: [basicSetup, language, tabSize, linterExtension, lintGutter(), ...extensions]
55286
+ extensions: [basicSetup, language, tabSize, linterExtension, lintGutter(), autocompletionConf.of(variablesFacet.of(variables)), autocompletion(), keymap.of([indentWithTab]), ...extensions]
55110
55287
  });
55111
55288
  }
55112
55289
  function createView(readonly) {
@@ -55124,15 +55301,25 @@
55124
55301
  view.setValue = function (value) {
55125
55302
  this.setState(createState(value, [updateListener, editable]));
55126
55303
  };
55304
+ view.setVariables = function (variables) {
55305
+ this.setState(createState(view.state.doc.toString(), [updateListener, editable], variables));
55306
+ };
55127
55307
  return view;
55128
55308
  }
55129
- const view = createView(readonly);
55309
+ const view = this._view = createView(readonly);
55130
55310
  this.setValue = function (value) {
55131
55311
  view.setValue(value);
55132
55312
  };
55133
55313
  this.getValue = function () {
55134
55314
  return view.state.doc.toString();
55135
55315
  };
55316
+
55317
+ /**
55318
+ * @param {Variables} variables
55319
+ */
55320
+ this.setVariables = function (variables) {
55321
+ view.setVariables(variables);
55322
+ };
55136
55323
  this.on = emitter.on;
55137
55324
  this.off = emitter.off;
55138
55325
  this.emit = emitter.emit;
@@ -55181,16 +55368,12 @@
55181
55368
  function PlaygroundRoot(props) {
55182
55369
  const {
55183
55370
  actions: actionsConfig = {},
55184
- editor: editorConfig = {},
55185
55371
  emit,
55186
55372
  exporter: exporterConfig = {}
55187
55373
  } = props;
55188
55374
  const {
55189
55375
  display: displayActions = true
55190
55376
  } = actionsConfig;
55191
- const {
55192
- inlinePropertiesPanel = true
55193
- } = editorConfig;
55194
55377
  const paletteContainerRef = s$1();
55195
55378
  const editorContainerRef = s$1();
55196
55379
  const formContainerRef = s$1();
@@ -55234,11 +55417,11 @@
55234
55417
  }, [props.schema]);
55235
55418
  y(() => {
55236
55419
  const dataEditor = dataEditorRef.current = new JSONEditor({
55237
- value: toJSON(data)
55420
+ value: toString(data)
55238
55421
  });
55239
55422
  const resultView = resultViewRef.current = new JSONEditor({
55240
55423
  readonly: true,
55241
- value: toJSON(resultData)
55424
+ value: toString(resultData)
55242
55425
  });
55243
55426
  const form = formRef.current = new Form();
55244
55427
  const formEditor = formEditorRef.current = new FormEditor({
@@ -55249,7 +55432,7 @@
55249
55432
  parent: paletteContainerRef.current
55250
55433
  },
55251
55434
  propertiesPanel: {
55252
- parent: !inlinePropertiesPanel && propertiesPanelContainerRef.current
55435
+ parent: propertiesPanelContainerRef.current
55253
55436
  },
55254
55437
  exporter: exporterConfig
55255
55438
  });
@@ -55289,16 +55472,25 @@
55289
55472
  };
55290
55473
  }, []);
55291
55474
  y(() => {
55292
- dataEditorRef.current.setValue(toJSON(initialData));
55475
+ dataEditorRef.current.setValue(toString(initialData));
55293
55476
  }, [initialData]);
55294
55477
  y(() => {
55295
- initialSchema && formEditorRef.current.importSchema(initialSchema);
55478
+ if (initialSchema) {
55479
+ formEditorRef.current.importSchema(initialSchema);
55480
+ dataEditorRef.current.setVariables(getSchemaVariables(initialSchema));
55481
+ }
55296
55482
  }, [initialSchema]);
55483
+ y(() => {
55484
+ if (schema && dataContainerRef.current) {
55485
+ const variables = getSchemaVariables(schema);
55486
+ dataEditorRef.current.setVariables(variables);
55487
+ }
55488
+ }, [schema]);
55297
55489
  y(() => {
55298
55490
  schema && formRef.current.importSchema(schema, data);
55299
55491
  }, [schema, data]);
55300
55492
  y(() => {
55301
- resultViewRef.current.setValue(toJSON(resultData));
55493
+ resultViewRef.current.setValue(toString(resultData));
55302
55494
  }, [resultData]);
55303
55495
  y(() => {
55304
55496
  props.onStateChanged({
@@ -55316,9 +55508,7 @@
55316
55508
  setShowEmbed(true);
55317
55509
  }, []);
55318
55510
  return e$1("div", {
55319
- class: classNames('fjs-container', 'fjs-pgl-root', {
55320
- 'fjs-pgl-inline-editor-panel': inlinePropertiesPanel
55321
- }),
55511
+ class: classNames('fjs-container', 'fjs-pgl-root'),
55322
55512
  children: [e$1("div", {
55323
55513
  class: "fjs-pgl-modals",
55324
55514
  children: showEmbed ? e$1(EmbedModal, {
@@ -55357,13 +55547,13 @@
55357
55547
  class: "fjs-pgl-form-container"
55358
55548
  })
55359
55549
  }), e$1(Section, {
55360
- name: "Form Data (Input)",
55550
+ name: "Form Input",
55361
55551
  children: e$1("div", {
55362
55552
  ref: dataContainerRef,
55363
55553
  class: "fjs-pgl-text-container"
55364
55554
  })
55365
55555
  }), e$1(Section, {
55366
- name: "Form Data (Submit)",
55556
+ name: "Form Output",
55367
55557
  children: e$1("div", {
55368
55558
  ref: resultContainerRef,
55369
55559
  class: "fjs-pgl-text-container"
@@ -55378,7 +55568,7 @@
55378
55568
 
55379
55569
  // helpers ///////////////
55380
55570
 
55381
- function toJSON(obj) {
55571
+ function toString(obj) {
55382
55572
  return JSON.stringify(obj, null, ' ');
55383
55573
  }
55384
55574