VaKeR CYBER ARMY
Logo of a company Server : Apache/2.4.41 (Ubuntu)
System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.33
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Directory :  /var/www/html/libs/absol-full/dist/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /var/www/html/libs/absol-full/dist/js/mdls__absol-acomp__js__ExpressionInput.js
/*** module: node_modules/absol-acomp/js/ExpressionInput.js ***/
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _ACore = _interopRequireWildcard(require("../ACore"));

require("../css/expressioninput.css");

var _DelaySignal = _interopRequireDefault(require("absol/src/HTML5/DelaySignal"));

var _keyboard = require("absol/src/Input/keyboard");

var _stringMatching = require("absol/src/String/stringMatching");

var _PositionTracker = _interopRequireDefault(require("./PositionTracker"));

var _utils = require("./utils");

var _Dom = require("absol/src/HTML5/Dom");

var _SCGrammar = _interopRequireDefault(require("absol/src/SCLang/SCGrammar"));

var _DPParser = _interopRequireDefault(require("absol/src/Pharse/DPParser"));

var _DPParseInstance = require("absol/src/Pharse/DPParseInstance");

var _Follower = _interopRequireDefault(require("./Follower"));

var _EventEmitter = require("absol/src/HTML5/EventEmitter");

var _AElement = _interopRequireDefault(require("absol/src/HTML5/AElement"));

var _ResizeSystem = _interopRequireDefault(require("absol/src/HTML5/ResizeSystem"));

var _Array = require("absol/src/DataStructure/Array");




/***
 * @extends PositionTracker
 * @constructor
 */
function ExpressionInput() {
  this.domSignal = new _DelaySignal.default();
  this.$rangeCtn = (0, _ACore.$)('.as-expression-input-range-ctn', this);
  this.$content = (0, _ACore.$)('.as-expression-input-content', this);
  this.$iconCtn = (0, _ACore.$)('.as-expression-input-icon-ctn', this); // this.$forground = $('.as-expression-input-foreground', this);

  /**
   *
   * @type {null|AElement}
   */

  this.$icon = null;
  this.$alertIcon = (0, _ACore.$)('.mdi.mdi-alert-circle', this.$iconCtn);
  this.engine = new EIEngine(this);
  this.userActionCtrl = new EIUserActionController(this); // this.selection = new EISelection(this);

  this.autoCompleteCtrl = new EIAutoCompleteController(this);
  this.undoMgn = new EIUndoManager(this);
  this.cmdTool = new EICommandTool(this);
  this._icon = null;
  /****
   * @name value
   * @type {string}
   * @memberOf ExpressionInput#
   */

  /**
   * @type {{variables: string[], functions: string[], sampleJS?:{getFunctions: function(): string[], getVariables: function(): string[]}}}
   * @memberOf ExpressionInput#
   * @name autocomplete
   */

  /**
   * @type {*}
   * @memberOf ExpressionInput#
   * @name icon
   */
}

ExpressionInput.tag = 'ExpressionInput'.toLowerCase();

ExpressionInput.render = function () {
  return (0, _ACore._)({
    tag: _PositionTracker.default,
    extendEvent: ['stopchange', 'blur', 'focus'],
    class: ['as-expression-input'],
    child: [{
      class: 'as-expression-input-icon-ctn',
      child: ['span.mdi.mdi-alert-circle']
    }, {
      class: 'as-expression-input-content',
      attr: {
        contenteditable: 'true',
        spellcheck: 'false'
      }
    } //,
    // { class: 'as-expression-input-range-ctn' },
    ]
  });
};

ExpressionInput.prototype.requestUpdateSize = function () {
  if (this.cmdTool && this.cmdTool.$ctn && this.cmdTool.$ctn.parentElement) {
    this.cmdTool.$ctn.updatePosition();
  }
};

ExpressionInput.prototype.notifySizeCanBeChanged = function () {
  var bound = this.getBoundingClientRect();

  if (!this._prevSize || this._prevSize.width !== bound.width || this._prevSize.height !== bound.height) {
    _ResizeSystem.default.updateUp(this, true);
  }

  this._prevSize = {
    width: bound.width,
    height: bound.height
  };
};

ExpressionInput.prototype.revokeResource = function () {
  (0, _utils.revokeResource)(this.engine);
  (0, _utils.revokeResource)(this.autoCompleteCtrl);
  (0, _utils.revokeResource)(this.undoMgn);
  (0, _utils.revokeResource)(this.cmdTool);
  (0, _utils.revokeResource)(this.domSignal);
};

ExpressionInput.prototype.focus = function () {
  this.$content.focus();
  this.engine.setSelectedPosition(this.engine.value.length);
};

ExpressionInput.property = {};
ExpressionInput.property.readOnly = {
  set: function (value) {
    if (value) {
      this.addClass('as-read-only');
      this.$content.removeAttribute('contenteditable');
    } else {
      this.removeClass('as-read-only');

      if (!this.hasClass('as-disabled')) {
        this.$content.setAttribute('contenteditable', 'true');
      }
    }
  },
  get: function () {
    return this.hasClass('as-read-only');
  }
};
ExpressionInput.property.disabled = {
  set: function (value) {
    if (value) {
      this.addClass('as-disabled');
      this.$content.removeAttribute('contenteditable');
    } else {
      this.removeClass('as-disabled');

      if (!this.hasClass('as-read-only')) {
        this.$content.setAttribute('contenteditable', 'true');
      }
    }
  },
  get: function () {
    return this.hasClass('as-disabled');
  }
};
ExpressionInput.property.value = {
  get: function () {
    return this.engine.value;
  },
  set: function (value) {
    this.engine.value = value;
    this.undoMgn.reset();
  }
};
ExpressionInput.property.icon = {
  /**
   * @this ExpressionInput
   * @param value
   */
  set: function (value) {
    if (this.$icon) this.$icon.remove();
    this.$iconCtn.clearChild();
    var elt;

    if ((0, _Dom.isDomNode)(value)) {
      if (value.parentElt) value = value.cloneNode(true);
      elt = value;
    } else if (value && (typeof value === 'string' || typeof value === 'object')) {
      if (value === 'default') value = 'span.mdi.mdi-equal';
      elt = (0, _ACore._)(value);
    }

    if (elt) {
      this.$iconCtn.addChild(elt);
      this.$icon = elt;
      this.addClass('as-has-icon');
    } else {
      this.$icon = null;
      value = null;
      this.removeClass('as-has-icon');
    }

    this._icon = value;
  },
  get: function () {
    return this._icon;
  }
};
/***
 * @memberOf ExpressionInput#
 * @type {{}}
 */

ExpressionInput.eventHandler = {};

_ACore.default.install(ExpressionInput);

var _default = ExpressionInput;
/**
 *
 * @param {ExpressionInput} elt
 * @constructor
 */

exports.default = _default;

function EIUserActionController(elt) {
  this.elt = elt;
  this.$content = elt.$content;
  this._stopChangeTO = -1;
  /**
   *
   * @type {EIEngine}
   */

  this.engine = elt.engine;

  for (var key in this) {
    if (key.startsWith('ev_')) {
      this[key] = this[key].bind(this);
    }
  }

  this.elt.on('stopchange', () => {
    this.elt.undoMgn.commit();
    this.elt.engine.highlightError();
  });
  this.$content.on({
    cut: this.ev_cut,
    blur: this.ev_blur,
    focus: this.ev_focus,
    paste: this.ev_paste,
    keydown: this.ev_keydown
  });
}

EIUserActionController.prototype.delayNotifyStopChange = function () {
  if (this._stopChangeTO > 0) {
    clearTimeout(this._stopChangeTO);
  }

  this._stopChangeTO = setTimeout(function () {
    this._stopChangeTO = -1;
    this.elt.emit('stopchange', {}, this.elt);
  }.bind(this), 200);
};

EIUserActionController.prototype.ev_keydown = function (event) {
  var key = (0, _keyboard.keyboardEventToKeyBindingIdent)(event);

  if (key.match(/^[a-zA-Z0-9]$/)) {
    this.elt.engine.requestRedrawTokens();
    setTimeout(() => {
      this.elt.autoCompleteCtrl.openDropdownIfNeed();

      if (this.elt.autoCompleteCtrl.isOpen) {
        this.elt.autoCompleteCtrl.updateDropDownContent();
      }
    }, 200);
  } else if (key === 'enter') {
    event.preventDefault();

    if (this.elt.autoCompleteCtrl.isSelecting()) {
      this.elt.autoCompleteCtrl.applySelectingSuggestion();
    } else {
      this.engine.breakLine();
    }
  } else if (key === 'arrowleft' || key === 'arrowright' || key.match(/^[^a-zA-Z0-9]$/)) {
    this.elt.autoCompleteCtrl.closeDropdownIfNeed();
  } else if (key === 'arrowup' || key === 'arrowdown') {
    if (this.elt.autoCompleteCtrl.isSelecting()) {
      event.preventDefault();
      this.elt.autoCompleteCtrl.moveSelectingSuggestion(key === 'arrowup' ? 'up' : 'down');
    }
  } else if (key === 'ctrl-space') {
    this.engine.redrawTokens();
    this.elt.autoCompleteCtrl.openDropdown();
  } else if (key === 'escape') {
    if (this.elt.autoCompleteCtrl.isOpen) {
      this.elt.autoCompleteCtrl.closeDropdown();
      event.preventDefault();
    }
  } else if (key === 'ctrl-z') {
    event.preventDefault();
    this.elt.undoMgn.undo();
  } else if (key === 'ctrl-y') {
    event.preventDefault();
    this.elt.undoMgn.redo();
  } else if (event.ctrlKey && event.key === 'X' || !event.ctrlKey && event.key.length === 1 || event.key === 'Delete' || event.key === 'Backspace') {
    this.elt.engine.requestRedrawTokens();
    setTimeout(() => {
      this.elt.autoCompleteCtrl.openDropdownIfNeed();

      if (this.elt.autoCompleteCtrl.isOpen) {
        this.elt.autoCompleteCtrl.updateDropDownContent();
      }
    }, 200);
  }

  this.delayNotifyStopChange();
  setTimeout(() => {
    this.elt.notifySizeCanBeChanged();
  }, 1);
};

EIUserActionController.prototype.ev_paste = function (event) {
  var paste = (event.clipboardData || window.clipboardData).getData('text');
  paste = paste.replace(/[\r\n]+/g, ' ');
  event.preventDefault();
  var pos = this.elt.engine.getSelectPosition();
  if (!pos || !paste) return;
  var value = this.elt.value;
  this.elt.engine.value = value.substring(0, pos.start) + paste + value.substring(pos.end);
  this.elt.engine.setSelectedPosition(pos.start + paste.length);
  this.elt.engine.highlightError();
  this.elt.notifySizeCanBeChanged();
};

EIUserActionController.prototype.ev_cut = function (event) {
  this.elt.domSignal.emit('redrawTokens');
  this.delayNotifyStopChange();
  this.elt.notifySizeCanBeChanged();
};

EIUserActionController.prototype.ev_focus = function (event) {
  this.elt.engine.clearErrorHighlight();
  setTimeout(function () {
    //todo
    this.elt.engine.getSelectPosition();
  }.bind(this), 100);
};

EIUserActionController.prototype.ev_blur = function (event) {
  this.elt.engine.highlightError();
};

EIUserActionController.prototype.ev_dragInit = function (event) {};
/**
 *
 * @param {ExpressionInput} elt
 * @constructor
 */


function EIEngine(elt) {
  this.elt = elt;
  this.lastSelectedPosition = {
    start: 0,
    end: 0,
    direction: 'forward'
  };
  this.$content = elt.$content;
  /**
   *
   * @type {null|Range}
   */

  this.range = null;
  this.elt.domSignal.on('redrawTokens', this.redrawTokens.bind(this));

  for (var key in this) {
    if (key.startsWith('ev_')) {
      this[key] = this[key].bind(this);
    }
  }

  this._isListenSelectionChange = false;
  this.$content.on('focus', this.ev_focus);
}

EIEngine.prototype.ev_focus = function () {
  if (!this._isListenSelectionChange) {
    document.addEventListener('selectionchange', this.ev_range);
    this._isListenSelectionChange = true;
  }
};

EIEngine.prototype.ev_range = function () {
  if (!this.elt.isDescendantOf(document.body)) {
    document.removeEventListener('selectionchange', this.ev_range);
    this._isListenSelectionChange = false;
  }

  this.updateRange();
};

EIEngine.prototype.revokeResource = function () {
  if (this._isListenSelectionChange) {
    document.removeEventListener('selectionchange', this.ev_range);
    this._isListenSelectionChange = false;
  }
};

EIEngine.prototype.requestRedrawTokens = function () {
  this.elt.domSignal.emit('redrawTokens');
};

EIEngine.prototype.highlightError = function () {
  var elt = this.elt;
  var contentElt = this.$content;
  var value = elt.value.trim();
  var it = EIParser.parse(value, 'exp');
  var i,
      notSkipCount = 0;
  var tokenErrorIdx = -1;

  if (value && it.error) {
    elt.addClass('as-error');
    elt.attr('title', it.error.message);
    tokenErrorIdx = it.error.tokenIdx;
  } else {
    elt.removeClass('as-error');
  }

  for (i = 0; i < contentElt.childNodes.length; ++i) {
    //todo: fix conflict (run before redraw)
    if (contentElt.childNodes[i].getAttribute && contentElt.childNodes[i].classList.contains('as-token') && contentElt.childNodes[i].getAttribute('data-type') !== 'skip') {
      if (notSkipCount === tokenErrorIdx) {
        contentElt.childNodes[i].classList.add('as-unexpected-token');
      } else {
        contentElt.childNodes[i].classList.remove('as-unexpected-token');
      }

      notSkipCount++;
    }
  }
};

EIEngine.prototype.clearErrorHighlight = function () {
  var contentElt = this.$content;

  for (var i = 0; i < contentElt.length; ++i) {
    if (contentElt.childNodes[i].classList.contains('as-token') && contentElt.childNodes[i].getAttribute('data-type') !== 'skip') {
      contentElt.childNodes[i].classList.remove('as-unexpected-token');
    }
  }
};

EIEngine.prototype.drawTokensContent = function () {
  var selectedPos = this.getSelectPosition();
  var value = this.value;
  var tokens = EIParser.tokenizer.tokenize(value);
  var tokenEltChain = Array.prototype.slice.call(this.$content.childNodes);

  while (tokenEltChain[tokenEltChain.length - 1] && tokenEltChain[tokenEltChain.length - 1].tagName === 'BR') {
    tokenEltChain.pop();
  }

  var leftPassed = 0;

  while (leftPassed < tokenEltChain.length && leftPassed < tokens.length) {
    if (!tokenEltChain[leftPassed].firstChild || !tokenEltChain[leftPassed].classList.contains('as-token') || tokens[leftPassed].content !== tokenEltChain[leftPassed].firstChild.data) break;

    if (!tokenEltChain[leftPassed].token || tokenEltChain[leftPassed].getAttribute('data-type') !== tokens[leftPassed].type) {
      tokenEltChain[leftPassed].setAttribute('data-type', tokens[leftPassed].type);
    }

    leftPassed++;
  }

  var rightPassed = 0;

  while (rightPassed < tokenEltChain.length && rightPassed < tokens.length) {
    if (!tokenEltChain[tokenEltChain.length - 1 - rightPassed].firstChild || !tokenEltChain[tokenEltChain.length - 1 - rightPassed].classList.contains('as-token') || tokens[tokens.length - 1 - rightPassed].content !== tokenEltChain[tokenEltChain.length - 1 - rightPassed].firstChild.data) break;

    if (tokenEltChain[tokenEltChain.length - 1 - rightPassed].getAttribute('data-type') !== tokens[tokens.length - 1 - rightPassed].type) {
      tokenEltChain[tokenEltChain.length - 1 - rightPassed].setAttribute('data-type', tokens[tokens.length - 1 - rightPassed].type);
    }

    rightPassed++;
  }

  var beforeToken;

  if (leftPassed + rightPassed < Math.max(tokenEltChain.length, tokens.length)) {
    beforeToken = tokenEltChain[tokenEltChain.length - rightPassed];
    tokenEltChain.splice(leftPassed, tokenEltChain.length - leftPassed - rightPassed).forEach(function (elt) {
      elt.remove();
    });
    tokens.slice(leftPassed, tokens.length - rightPassed).forEach(function (token) {
      var tokenElt = this.makeTokenElt(token);

      if (beforeToken) {
        this.$content.addChildBefore(tokenElt, beforeToken);
      } else {
        this.$content.addChild(tokenElt);
      }
    }.bind(this));
  }

  if (selectedPos) this.setSelectedPosition(selectedPos);
};

EIEngine.prototype.updateTokenExType = function () {
  /**
   * @type {HTMLElement[]}
   */
  var tokenEltChain = Array.prototype.slice.call(this.$content.childNodes);
  var token, nextToken;
  var i, j;

  for (i = 0; i < tokenEltChain.length; ++i) {
    token = tokenEltChain[i];
    if (this.isTextNode(token)) continue;

    if (token.innerText === "true" || token.innerText === "false") {
      token.setAttribute('data-ex-type', 'boolean');
    } else if (token.getAttribute('data-type') === 'word') {
      j = i + 1;
      nextToken = tokenEltChain[i + 1];

      while (nextToken) {
        if (nextToken.getAttribute('data-type') === 'symbol' && nextToken.innerText === '(') {
          token.setAttribute('data-ex-type', 'function');
          break;
        } else if (nextToken.getAttribute('data-type') === 'skip') {
          nextToken = tokenEltChain[++j];
        } else {
          break;
        }
      }
    } else {
      token.removeAttribute('data-ex-type');
    }
  }
};

EIEngine.prototype.redrawTokens = function () {
  this.drawTokensContent();
  this.updateTokenExType();
  this.elt.notifySizeCanBeChanged();
};
/**
 *
 * @param {{type: string, content: string}} token
 * @returns {*}
 */


EIEngine.prototype.makeTokenElt = function (token) {
  if (token.content === '\n') return (0, _ACore._)('br');
  return (0, _ACore._)({
    tag: 'span',
    class: ['as-token'],
    attr: {
      'data-type': token.type
    },
    child: {
      text: token.content
    }
  });
};

EIEngine.prototype.insertText = function (text) {
  var lastPos = this.getSelectPosition();
  var value;

  if (this.lastSelectedPosition) {
    value = this.elt.value;
    this.value = value.substring(0, lastPos.start) + text + value.substring(lastPos.end);
    this.lastSelectedPosition = Object.assign({
      direction: 'forward',
      start: lastPos.start + text.length,
      end: lastPos.start + text.length
    });

    if (document.activeElement === this.elt.$content) {
      this.setSelectedPosition(this.lastSelectedPosition);
    }
  } else this.appendText(text);

  this.elt.userActionCtrl.delayNotifyStopChange();
};

EIEngine.prototype.appendText = function (text) {
  var newValue = this.value + text;
  this.value = newValue;

  if (document.activeElement === this.$content) {
    this.setSelectedPosition(newValue.length);
  }

  this.elt.userActionCtrl.delayNotifyStopChange();
};

EIEngine.prototype.isValidRange = function (range) {
  return _AElement.default.prototype.isDescendantOf.call(range.startContainer, this.$content) && _AElement.default.prototype.isDescendantOf.call(range.endContainer, this.$content);
};

EIEngine.prototype.updateRange = function () {
  var sel = window.getSelection();
  var range;

  for (var i = 0; i < sel.rangeCount; ++i) {
    range = sel.getRangeAt(i);
    if (this.isValidRange(range)) this.range = range;
  }
};

EIEngine.prototype.isTextNode = function (node) {
  return node.nodeType === Node.TEXT_NODE;
};

EIEngine.prototype.isWordToken = function (node) {
  if (this.isTextNode(node)) return false;
  return node.getAttribute('data-type') === 'word';
};

EIEngine.prototype.isSymbolToken = function (node) {
  if (this.isTextNode(node)) return false;
  return node.getAttribute('data-type') === 'symbol';
};

EIEngine.prototype.isMemberSymbolToken = function (node) {
  return this.isSymbolToken(node) && node.innerText === '->';
};

EIEngine.prototype.isSkipToken = function (node) {
  if (this.isTextNode(node)) return false;
  return node.getAttribute('data-type') === 'skip';
};

EIEngine.prototype.getRange = function () {
  this.updateRange();
  return this.range;
};
/**
 *
 * @param {Range} range
 */


EIEngine.prototype.setRange = function (range) {
  this.range = range;
  var sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
};

EIEngine.prototype.childIndexOf = function (node) {
  if (!node.parentElement) return 0;
  return Array.prototype.indexOf.call(node.parentElement.childNodes, node);
};

EIEngine.prototype.lcaOf = function (nd1, nd2) {
  var track1 = [];
  var track2 = [];
  var rootNode = this.elt;

  while (nd1 && nd1 !== rootNode) {
    track1.unshift(nd1);
    nd1 = nd1.parentElement;
  }

  while (nd2 && nd2 !== rootNode) {
    track2.unshift(nd2);
    nd2 = nd2.parentElement;
  }

  var res = null;

  for (var i = 0; i < track1.length && i < track2.length; ++i) {
    if (track1[i] === track2[i]) res = track1[i];else break;
  }

  return res;
};

EIEngine.prototype.trimLeft = function (nd, ofs) {
  if (this.isTextNode(nd)) {
    nd.data = nd.data.substring(ofs);
  } else {
    for (var i = 0; i < ofs; ++i) {
      nd.removeChild(nd.firstChild);
    }
  }
};

EIEngine.prototype.trimRight = function (nd, ofs) {
  if (this.isTextNode(nd)) {
    nd.data = nd.data.substring(0, ofs);
  } else {
    while (nd.childNodes.length > ofs) {
      nd.removeChild(nd.lastChild);
    }
  }
};

EIEngine.prototype.breakTextNode = function (textNode, offset) {
  var parent = (0, _ACore.$)(textNode.parentElement);
  var text = textNode.data;
  var newTextNode = (0, _ACore._)({
    text: text.substring(offset)
  });
  textNode.data = text.substring(0, offset);
  parent.addChildAfter(newTextNode, textNode);
  return newTextNode;
};

EIEngine.prototype.breakElement = function (elt, offset) {
  var parent = (0, _ACore.$)(elt.parentElement);
  var newElt = elt.cloneNode(false);
  var rightChildren = Array.prototype.slice.call(elt.childNodes, offset);

  for (var i = 0; i < rightChildren.length; ++i) {
    newElt.appendChild(rightChildren[i]);
  }

  parent.addChildAfter(newElt, elt);
  return newElt;
};

EIEngine.prototype.breakNode = function (node, offset) {
  if (this.isTextNode(node)) {
    return this.breakTextNode(node, offset);
  } else {
    return this.breakElement(node, offset);
  }
};

EIEngine.prototype.breakLine = function () {
  var range = this.getRange();
  if (!range) return;
  var startCtn = range.startContainer;
  var endCtn = range.endContainer;
  var startOfs = range.startOffset;
  var endOfs = range.endOffset;
  var newNd;
  var lcaNd = this.lcaOf(startCtn, endCtn);

  while (startCtn !== lcaNd) {
    this.trimRight(startCtn, startOfs);
    startOfs = this.childIndexOf(startCtn) + 1;
    startCtn = startCtn.parentElement;
  }

  while (endCtn !== lcaNd) {
    this.trimLeft(endCtn, endOfs);
    endOfs = this.childIndexOf(endCtn);
    endCtn = endCtn.parentElement;
  }

  if (this.isTextNode(startCtn)) {
    newNd = startCtn.parentElement.cloneNode(false);
    newNd.appendChild((0, _ACore._)({
      text: startCtn.data.substring(0, startOfs)
    }));
    startCtn.parentElement.parentElement.insertBefore(newNd, startCtn.parentElement);
    startCtn.data = startCtn.data.substring(endOfs);
    newNd = (0, _ACore._)('br');
    startCtn.parentElement.parentElement.insertBefore(newNd, startCtn.parentElement);
    startCtn = newNd.parentElement;
    startOfs = this.childIndexOf(newNd) + 1;
    endCtn = startCtn;
    endOfs = startOfs;
  } else if (startCtn === this.$content) {
    Array.prototype.slice.call(startCtn.childNodes, startOfs, endOfs - 1).forEach(nd => nd.remove());
    newNd = (0, _ACore._)('br');
    startCtn.insertBefore(newNd, startCtn.childNodes[startOfs]);
    endOfs = startOfs + 1;
    startOfs = endOfs;
  } else {
    endCtn = this.breakElement(startCtn, startOfs);
    endOfs -= startCtn;

    if (endOfs >= 0) {
      newNd = this.breakElement(endCtn, endOfs);
      endCtn.remove();
      endCtn = newNd;
      endOfs = 0;
    }

    newNd = (0, _ACore._)('br');
    endCtn.parentElement.insertBefore(newNd, endCtn);
    startCtn = newNd.parentElement;
    startOfs = this.childIndexOf(newNd) + 1;
    endCtn = startCtn;
    endOfs = startOfs;
  }

  var childNodes = Array.prototype.slice.call(this.$content.childNodes);
  var nd;

  for (var i = 0; i < childNodes.length; ++i) {
    nd = childNodes[i];
    if (nd.tagName === 'BR') continue;

    if (this.stringOf(nd).length === 0) {
      if (_AElement.default.prototype.isDescendantOf.call(startCtn, nd)) {
        startCtn = this.$content;
        startOfs = this.childIndexOf(nd);
      }

      if (_AElement.default.prototype.isDescendantOf.call(endCtn, nd)) {
        endCtn = this.$content;
        endOfs = this.childIndexOf(nd);
      }

      nd.remove();
    }
  }

  range = document.createRange();
  range.setStart(startCtn, startOfs);
  range.setEnd(endCtn, endOfs);
  this.setRange(range);
};

EIEngine.prototype.domRange2SelectPosition = function (range) {
  var sel = window.getSelection();
  if (!range) return null;
  var direction = 'forward';
  if (!range) return null;
  var cmpPosition = sel.anchorNode.compareDocumentPosition(sel.focusNode);

  if (cmpPosition === 4) {
    direction = 'forward';
  } else if (cmpPosition === 2) {
    direction = 'backward';
  } else if (!cmpPosition && sel.anchorOffset > sel.focusOffset || cmpPosition === Node.DOCUMENT_POSITION_PRECEDING) {
    direction = 'backward';
  }

  var startOffset = this.getPosition(range.startContainer, range.startOffset);
  var endOffset = this.getPosition(range.endContainer, range.endOffset);
  if (isNaN(startOffset)) return null;
  return {
    start: startOffset,
    end: endOffset,
    direction: direction,
    startCtn: range.startContainer,
    startOffset: range.startOffset,
    endCtn: range.endContainer,
    endOffset: range.endOffset
  };
};

EIEngine.prototype.getSelectPosition = function () {
  var range = this.getRange();
  this.lastSelectedPosition = this.domRange2SelectPosition(range) || this.lastSelectedPosition;
  return this.lastSelectedPosition;
};
/**
 *
 * @param  {null|number|{start: number, end: number}=}pos
 */


EIEngine.prototype.setSelectedPosition = function (pos) {
  var start;
  var end;

  if (typeof pos === "number") {
    start = pos;
    end = pos;
  } else if (pos === null) {
    return;
  } else {
    start = pos.start;
    end = pos.end;
  }

  var startCtn, startOfs, endCtn, endOfs;
  var text;
  text = '';

  var visit = nd => {
    var prevText = text;
    var parent = nd.parentElement;

    if (this.isTextNode(nd)) {
      text += nd.data;

      if (text.length > start && prevText.length <= start) {
        startCtn = nd;
        startOfs = start - prevText.length;
      }

      if (text.length > end && prevText.length <= end) {
        endCtn = nd;
        endOfs = end - prevText.length;
      }
    } else if (nd.tagName === 'BR' && parent && parent.lastChild !== nd) {
      text += '\n';

      if (text.length > start && prevText.length <= start) {
        startCtn = parent;
        startOfs = this.childIndexOf(nd);
      }

      if (text.length > end && prevText.length <= end) {
        endCtn = parent;
        endOfs = this.childIndexOf(nd);
      }
    } else {
      for (var i = 0; i < nd.childNodes.length; ++i) {
        visit(nd.childNodes[i]);
      }
    }
  };

  visit(this.$content);

  if (!startCtn) {
    startCtn = this.$content;
    startOfs = this.$content.childNodes.length;
  }

  if (!endCtn) {
    endCtn = startCtn;
    endOfs = startOfs;
  }

  var range = document.createRange();
  range.setStart(startCtn, startOfs);
  range.setEnd(endCtn, endOfs);
  this.setRange(range);
};

EIEngine.prototype.getPosition = function (node, offset) {
  var text = '';
  var found = false;

  var visit = nd => {
    var i;
    if (found) return;

    if (nd === node) {
      if (this.isTextNode(nd)) {
        text += nd.data.substring(0, offset);
      } else {
        for (i = 0; i < nd.childNodes.length && i < offset; ++i) {
          visit(nd.childNodes[i]);
        }
      }

      found = true;
      return;
    }

    var parent = nd.parentElement;

    if (nd.tagName === 'BR' && parent && parent.lastChild !== nd) {
      text += '\n';
    }

    if (this.isTextNode(nd)) {
      text += nd.data;
    } else {
      for (i = 0; i < nd.childNodes.length && !found; ++i) {
        visit(nd.childNodes[i]);
      }
    }
  };

  visit(this.$content);
  return text.length;
};

EIEngine.prototype.stringOf = function (node) {
  if (!node) return '';

  if (node.nodeType === 3) {
    return node.data;
  }

  var res = '';
  var parent = node.parentElement;

  if ((node.tagName === 'BR' || node.tagName === 'br') && parent && parent.lastChild !== node) {
    return '\n';
  } else if ((node.tagName === 'DIV' || node.tagName === 'div') && parent && parent.firstChild !== node) {
    res += '\n';
  }

  return res + Array.prototype.map.call(node.childNodes, (cNode, index, arr) => {
    return this.stringOf(cNode, node);
  }).join('');
};
/**
 *
 * @param offset
 * @returns {AElement}
 */


EIEngine.prototype.tokenAt = function (offset) {
  var l = 0;
  var res = null;
  var nd, i;

  for (i = 0; i < this.$content.childNodes.length; ++i) {
    nd = this.$content.childNodes[i];
    l += this.stringOf(nd).length;

    if (l > offset || i + 1 === this.$content.childNodes.length && l === offset) {
      res = nd;
      break;
    }
  }

  return res;
};
/**
 *
 * @param {AElement}token
 * @returns {AElement}
 */


EIEngine.prototype.findPrefixWordTokenOf = function (token) {
  if (!token) return null;
  if (!this.isWordToken(token) && this.stringOf(token) !== '->') return null;
  var temp = token;
  var prefixStartElt = null;
  var state = this.isWordToken(temp) ? 0 : 1; //0: after is word, 1: symbol

  temp = temp.previousSibling;

  while (temp) {
    if (this.isSkipToken(temp)) {
      temp = temp.previousSibling;
      continue;
    }

    if (state === 0) {
      if (this.stringOf(temp) === '->') {
        state = 1;
      } else break;
    } else {
      if (this.isWordToken(temp)) {
        prefixStartElt = temp;
        state = 0;
      } else break;
    }

    temp = temp.previousSibling;
  }

  return prefixStartElt || null;
}; //
// EIEngine.prototype.selectCurrentMemberExpression = function () {
//     var rage = this.getRange();
//     if (!rage) return;
//     var startCtn = rage.startContainer;
//     var endCtn = rage.endContainer;
//     var startOfs = rage.startOffset;
//     var endOfs = rage.endOffset;
//
// };


Object.defineProperty(EIEngine.prototype, 'value', {
  get: function () {
    return Array.prototype.map.call(this.$content.childNodes, nd => this.stringOf(nd)).join('');
  },
  set: function (value) {
    var tokens = EIParser.tokenizer.tokenize(value || '');
    this.$content.clearChild().addChild(tokens.map(function (token) {
      return this.makeTokenElt(token);
    }.bind(this)));
    this.updateTokenExType();
    this.lastSelectedPosition = {
      start: value.length,
      end: value.length,
      direction: 'forward'
    };
  }
});
/**
 *
 * @param {ExpressionInput} elt
 * @constructor
 */

function EIUndoManager(elt) {
  this.elt = elt;
  this.reset();
}
/**
 *
 * @returns {boolean} is changed value and commit success
 */


EIUndoManager.prototype.commit = function () {
  var text = this.elt.value;
  var range = this.elt.engine.getSelectPosition() || {
    start: text.length,
    end: text.length
  };
  var curValue = this.stack[this.idx].value;
  if (curValue === text) return false;
  var newItem = {
    value: text,
    range: {
      start: range.start,
      end: range.end,
      direction: range.direction || 'forward'
    }
  };

  while (this.stack.length > this.idx + 1) {
    this.stack.pop();
  }

  this.idx = this.stack.length;
  this.stack.push(newItem);
  return true;
};

EIUndoManager.prototype.reset = function () {
  var value = this.elt.value;
  this.stack = [{
    value: value,
    range: {
      start: value.length,
      end: value.length,
      direction: "forward"
    }
  }];
  this.idx = 0;
};

EIUndoManager.prototype.undo = function () {
  if (this.idx <= 0) return;
  this.idx--;
  var item = this.stack[this.idx];
  this.elt.engine.value = item.value;
  this.elt.engine.setSelectedPosition(item.range);
};

EIUndoManager.prototype.redo = function () {
  if (this.idx + 1 >= this.stack.length) return;
  this.idx++;
  var item = this.stack[this.idx];
  this.elt.engine.value = item.value;
  this.elt.engine.setSelectedPosition(item.range);
};
/**
 *
 * @param {ExpressionInput} elt
 * @constructor
 */


function EIAutoCompleteController(elt) {
  this.elt = elt;
  this.$content = elt.$content;
  this.$tokenTarget = null;

  for (var key in this) {
    if (key.startsWith('ev_')) {
      this[key] = this[key].bind(this);
    }
  }

  this.rawSuggestionCache = {
    value: null,
    time: 0
  };
  /**
   *
   * @type {EISuggestionList |null}
   */

  this.$suggestionList = null;
  this.query = null;
  this.isOpen = false;
  this.dropIsDown = true;
}

EIAutoCompleteController.prototype.revokeResource = function () {};

EIAutoCompleteController.prototype.openDropdownIfNeed = function () {
  if (this.isOpen) return;
  var query = this.getCurrentSearch();

  if (query && query.value && query.value.trim()) {
    this.openDropdown();
  }
};
/**
 *
 */


EIAutoCompleteController.prototype.openDropdown = function () {
  if (this.isOpen) {
    this.updateDropDownContent();
    return;
  }

  if (!this.hasSuggestions()) return;
  this.isOpen = true;
  this.dropIsDown = true;

  if (!this.$suggestionList) {
    this.$suggestionList = (0, _ACore._)({
      tag: EISuggestionList,
      style: {
        top: '10px',
        left: '10px',
        position: 'fixed'
      },
      on: {
        select: event => {
          this.applySuggestion(event.data);
          this.closeDropdown();
        }
      }
    });
  }

  this.$suggestionList.addTo(this.elt);
  var zIndex = (0, _utils.findMaxZIndex)(this.elt) + 1;
  this.$suggestionList.addStyle('z-index', zIndex + '');
  this.$suggestionList.reset();
  this.elt.startTrackPosition(); // this.$dropDown.addTo(this.elt);

  this.$tokenTarget = null;
  this.updateDropDownContent();
  this.updateDropDownPosition();
  setTimeout(() => {
    document.addEventListener('click', this.ev_clickOut);
  }, 200);
};

EIAutoCompleteController.prototype.closeDropdown = function () {
  if (!this.isOpen) return;
  this.isOpen = false;
  this.elt.stopTrackPosition();
  this.$suggestionList.remove();
  document.removeEventListener('click', this.ev_clickOut);
};
/**
 *
 * @returns {null|{prefix: string, value, tokenElt: HTMLElement, prefixStartElt: HTMLElement}}
 */


EIAutoCompleteController.prototype.getCurrentSearch = function () {
  var engine = this.elt.engine;
  var pos = this.elt.engine.getSelectPosition();
  if (!pos) return null; //all

  var tokenElt = this.elt.engine.tokenAt(pos.start);
  if (!tokenElt) return null;

  if (!engine.isWordToken(tokenElt)) {
    tokenElt = tokenElt.previousSibling;
  }

  if (!tokenElt) return null;
  var temp = tokenElt;

  while (temp) {
    if (engine.isSymbolToken(temp)) {
      if (engine.stringOf(temp) === '->') {
        tokenElt = temp;
      } else {
        break;
      }
    } else if (engine.isSkipToken(temp)) {} else if (engine.isWordToken(temp)) {
      tokenElt = temp;
    }

    temp = temp.nextSibling;
  }

  if (!engine.isWordToken(tokenElt) && !engine.isMemberSymbolToken(tokenElt)) return null;
  var res = {
    prefix: '',
    value: '',
    tokenElt: null,
    prefixStartElt: null
  };
  temp = tokenElt;
  var prefixStartElt = engine.findPrefixWordTokenOf(tokenElt);
  res.value = engine.stringOf(tokenElt);
  res.tokenElt = tokenElt;

  if (prefixStartElt) {
    res.prefixStartElt = prefixStartElt;
    temp = prefixStartElt;

    while (temp !== tokenElt) {
      if (engine.isSkipToken(temp)) {
        temp = temp.nextSibling;
        continue;
      }

      res.prefix += engine.stringOf(temp);
      temp = temp.nextSibling;
    }
  }

  return res;
};

EIAutoCompleteController.prototype.getCurrentText = function () {
  var pos = this.elt.engine.getSelectPosition();
  if (!pos) return '';
  var res = {
    value: '',
    tokenElt: null
  };
  var tokenElt = this.elt.engine.tokenAt(pos.start);

  if (!tokenElt || !tokenElt.getAttribute || tokenElt.getAttribute('data-type') !== 'word') {
    res.tokenElt = tokenElt;
    res.value = '';
    tokenElt = null;
  }

  if (!tokenElt && pos && pos.start > 0) {
    tokenElt = this.elt.engine.tokenAt(pos.start - 1);
  }

  if (tokenElt && tokenElt.getAttribute && tokenElt.getAttribute('data-type') === 'word') {
    res.value = tokenElt.innerText;
    res.tokenElt = tokenElt;
  }

  console.log(res);
  return res;
};

EIAutoCompleteController.prototype.updateDropDownContent = function () {
  if (!this.isOpen) return;
  this.query = this.getCurrentSearch();
  this.$suggestionList.data = this.getSuggestionTree(this.query);
  this.$suggestionList.selectMaxScoreItem();
  this.updateDropDownPosition();
};

EIAutoCompleteController.prototype.updateDropDownPosition = function () {
  if (!this.isOpen) return;
  var bound;
  var targetELt = this.query && this.query.tokenElt;
  var range = this.elt.engine.getRange();
  var selected = this.elt.engine.getSelectPosition();
  var dropBound = this.$suggestionList.getBoundingClientRect();

  if (targetELt) {
    bound = targetELt.getBoundingClientRect();
  }

  if (!bound) {
    bound = range.getBoundingClientRect();
    if (!bound.width || !bound.height) bound = null;
  }

  if (!bound && selected) {
    targetELt = this.elt.engine.tokenAt(selected.start);

    if (targetELt) {
      bound = targetELt.getBoundingClientRect();
    }
  }

  if (!bound) {
    bound = this.elt.$content.getBoundingClientRect();
  }

  var screenHeight = (0, _Dom.getScreenSize)().height;
  var aTop = bound.top - 10;
  var aBottom = screenHeight - bound.bottom - 10;
  var contentHeight = this.$suggestionList.scrollHeight;

  if (this.dropIsDown) {
    if (aBottom < contentHeight && aBottom <= aTop) {
      this.dropIsDown = false;
    }
  } else {
    if (aTop < contentHeight && aTop <= aBottom) {
      this.dropIsDown = true;
    }
  }

  var screenSize = (0, _Dom.getScreenSize)();
  this.$suggestionList.addStyle('left', Math.max(0, Math.min(bound.left, screenSize.width - dropBound.width)) + 'px');
  this.$suggestionList.addStyle('max-height', this.dropIsDown ? aBottom + 'px' : aTop + 'px');
  var listBound;

  if (this.dropIsDown) {
    this.$suggestionList.addStyle('top', bound.bottom + 'px');
  } else {
    listBound = this.$suggestionList.getBoundingClientRect();
    this.$suggestionList.addStyle('top', bound.top - listBound.height + 'px');
  }
};

EIAutoCompleteController.prototype.getRawSuggestion = function () {
  var now = Date.now();

  if (now - this.rawSuggestionCache.time < 3000) {
    return this.rawSuggestionCache.value;
  }

  var variables = [];
  var functions = [];
  var temp;

  if (this.elt.autocomplete) {
    temp = this.elt.autocomplete.variables;
    if (typeof temp === "function") temp = temp();

    if (Array.isArray(temp)) {
      temp = temp.filter(x => typeof x === 'string');
      variables = variables.concat(temp);
    }

    temp = this.elt.autocomplete.functions;
    if (typeof temp === "function") temp = temp();

    if (Array.isArray(temp)) {
      temp = temp.filter(x => typeof x === 'string');
      functions = functions.concat(temp);
    }

    if (this.elt.sampleJS && typeof this.elt.sampleJS.getFunctions === "function") {
      temp = this.elt.sampleJS.getFunctions();

      if (Array.isArray(temp)) {
        temp = temp.filter(x => typeof x === 'string');
        functions = functions.concat(temp);
      }
    }
  }

  variables = (0, _Array.arrayUnique)(variables);
  functions = (0, _Array.arrayUnique)(functions);
  this.rawSuggestionCache.value = {
    variables: variables,
    functions: functions
  };
  this.rawSuggestionCache.time = now;
  return this.rawSuggestionCache.value;
};

EIAutoCompleteController.prototype.hasSuggestions = function () {
  var rawSuggestions = this.getRawSuggestion();
  return rawSuggestions.variables.length > 0 || rawSuggestions.functions.length > 0;
};
/**
 *
 * @param {string} text
 * @param {string} prefix
 */


EIAutoCompleteController.prototype.getSuggestionList = function (text, prefix) {
  var res = [];
  prefix = prefix || '';
  text = text || '';
  text = text.toLowerCase();
  var rawSuggestion = this.getRawSuggestion();
  var variables = rawSuggestion.variables;
  var functions = rawSuggestion.functions;
  var i;
  var itemText, score;

  for (i = 0; i < variables.length; ++i) {
    itemText = variables[i];
    score = (0, _stringMatching.phraseMatch)(itemText.toLowerCase(), text);
    res.push({
      text: itemText,
      score: score,
      type: 'variable'
    });
  }

  for (i = 0; i < functions.length; ++i) {
    itemText = functions[i];
    score = (0, _stringMatching.phraseMatch)(itemText.toLowerCase(), text);
    res.push({
      text: itemText,
      score: score,
      type: 'function'
    });
  }

  res.sort(function (a, b) {
    if (a.score === b.score) {
      return a.text > b.text ? 1 : -1;
    }

    return b.score - a.score;
  });
  if (text) res = res.filter(x => x.score > 0);
  return res;
};

EIAutoCompleteController.prototype.computeScore = function (queryWords, itemWords) {
  if (queryWords.length === 0) return 1;
  queryWords = queryWords.map(x => x.toLowerCase());
  itemWords = itemWords.map(x => x.toLowerCase());
  var score = 0;
  var wordScore = 1 / queryWords.length;
  var i, j;

  for (i = 0; i < queryWords.length && i < itemWords.length; ++i) {
    if (queryWords[i] === itemWords[i]) {
      score += wordScore;
    } else {
      score += wordScore * (0, _stringMatching.wordLike)(queryWords[i], itemWords[i]);
    }
  }

  var qDict = queryWords.reduce((ac, cr) => {
    ac[cr] = true;
    return ac;
  }, {});
  var iDict = itemWords.reduce((ac, cr) => {
    ac[cr] = true;
    return ac;
  }, {});
  var bestMatch, bestWord, curWordScore;
  queryWords = Object.keys(qDict);
  itemWords = Object.keys(iDict);

  for (i = 0; i < queryWords.length; ++i) {
    bestMatch = 0;
    bestWord = '';

    for (j = 0; j < itemWords.length; ++j) {
      if (queryWords[i] === itemWords[j]) {
        bestMatch = wordScore;
        bestWord = itemWords[j];
        break;
      } else {
        curWordScore = wordScore * (0, _stringMatching.wordLike)(queryWords[i], itemWords[j]);

        if (curWordScore > bestMatch) {
          bestMatch = curWordScore;
          bestWord = itemWords[j];
        }
      }
    }

    if (bestWord) {
      iDict[bestWord] = false;
      score += bestMatch;
    }
  }

  return score;
};

EIAutoCompleteController.prototype.getSuggestionTree = function (query) {
  var splitWords = text => text.split(/[^a-zA-Z0-9_$]+/).filter(x => x.length > 0);

  var queryWords = query ? splitWords(query.prefix + ' ' + query.value) : [];
  var rawSuggestion = this.getRawSuggestion();
  var variables = rawSuggestion.variables;
  var functions = rawSuggestion.functions;
  var items = [];
  var item;
  var i;

  for (i = 0; i < variables.length; ++i) {
    items.push({
      text: variables[i],
      type: 'variable',
      words: splitWords(variables[i])
    });
  }

  for (i = 0; i < functions.length; ++i) {
    items.push({
      text: functions[i],
      type: 'function',
      words: splitWords(functions[i])
    });
  }

  var min = Infinity,
      max = -Infinity;

  for (i = 0; i < items.length; ++i) {
    item = items[i];
    item.score = this.computeScore(queryWords, item.words);
    if (item.score < min) min = item.score;
    if (item.score > max) max = item.score;
  }

  var idx;

  if (query) {
    for (i = 0; i < items.length; ++i) {
      item = items[i];
      idx = item.text.toLowerCase().indexOf(query.value.toLowerCase());
      if (idx >= 0) item.score = max - idx / 1000;
    }
  }

  items.sort((a, b) => b.score - a.score);
  var mid = (max + min) / 2;
  items = items.filter(x => x.score >= mid);
  var trees = [];
  var nodeDict = {
    "*": {
      text: "",
      children: trees
    }
  };
  items.forEach(item => {
    var words = item.words;
    var k;
    var key = '';
    var nd;
    var parent = nodeDict['*'];

    for (k = 0; k < words.length; ++k) {
      if (k > 0) key += '->';
      key += words[k];
      nd = nodeDict[key];

      if (!nd) {
        nd = {
          text: words[k],
          children: [],
          key: key,
          score: 0
        };
        nodeDict[key] = nd;
        parent.children.push(nd);
      }

      parent = nd;
    }

    parent.item = item;
    parent.score = item.score;
  });
  return trees;
};

EIAutoCompleteController.prototype.applySuggestion = function (suggestion) {
  var engine = this.elt.engine;
  var query = this.query;
  var key = suggestion.key;
  var words = key.split('->');
  var startToken = query && query.prefixStartElt;
  var endToken = query && query.tokenElt;
  startToken = startToken || endToken;
  var range;
  var rangeStartCtn, rangeStartOffset, rangeEndCtn, rangeEndOffset;
  var i, tokenElt;
  var oldValue, newValue;
  var selected;

  if (startToken && endToken && engine.isWordToken(startToken) && (engine.isWordToken(endToken) || engine.stringOf(endToken) === '->')) {
    for (i = 0; i < words.length; ++i) {
      if (i > 0) {
        tokenElt = engine.makeTokenElt({
          type: 'symbol',
          content: '->'
        });
        this.elt.$content.insertBefore(tokenElt, startToken);
      }

      tokenElt = engine.makeTokenElt({
        type: 'word',
        content: words[i]
      });
      this.elt.$content.insertBefore(tokenElt, startToken);

      if (i + 1 === words.length) {
        rangeStartCtn = this.elt.$content;
        rangeStartOffset = engine.childIndexOf(tokenElt) + 1;
        rangeEndCtn = rangeStartCtn;
        rangeEndOffset = rangeStartOffset;
      }
    }

    while (startToken !== endToken) {
      tokenElt = startToken.nextSibling;
      startToken.remove();
      startToken = tokenElt;
    }

    endToken.remove();
    range = document.createRange();
    range.setStart(rangeStartCtn, rangeStartOffset);
    range.setEnd(rangeEndCtn, rangeEndOffset);
    engine.setRange(range);
  } else {
    oldValue = this.elt.value;
    selected = engine.getSelectPosition();
    newValue = oldValue.substring(0, selected.start) + key + oldValue.substring(selected.end);
    this.elt.engine.value = newValue;
    this.elt.engine.setSelectedPosition(selected.start + key.length);
  }

  engine.updateTokenExType();
};

EIAutoCompleteController.prototype.isSelecting = function () {
  return this.isOpen && this.$suggestionList && this.$suggestionList.$selectedNode && true;
};

EIAutoCompleteController.prototype.applySelectingSuggestion = function () {
  if (this.isSelecting()) {
    this.applySuggestion(this.$suggestionList.$selectedNode.data); //todo
    // this.applySuggestion(this.$item[this.selectedIdx].getAttribute('data-suggestion'));

    this.closeDropdown();
  }
};

EIAutoCompleteController.prototype.closeDropdownIfNeed = function () {
  setTimeout(() => {
    var text = this.getCurrentText();
    this.$tokenTarget = text && text.tokenElt;

    if (this.isOpen) {
      if (!this.$tokenTarget || this.$tokenTarget.getAttribute('data-type') !== 'word') {
        this.closeDropdown();
      }
    }
  }, 5);
};
/**
 *
 * @param {"down"|"up"} direction
 * @returns {boolean}
 */


EIAutoCompleteController.prototype.moveSelectingSuggestion = function (direction) {
  if (direction !== 'down' && direction !== 'up') return false;
  if (!this.hasSuggestions()) return false;

  if (this.isSelecting()) {
    if (direction === 'down') {
      return this.$suggestionList.moveToNextSuggestion();
    } else {
      return this.$suggestionList.moveToPrevSuggestion();
    }
  }
};

EIAutoCompleteController.prototype.ev_positionChange = function (event) {
  if (!this.elt.isDescendantOf(document.body)) {
    this.elt.stopTrackPosition();
    return;
  } //todo

};

EIAutoCompleteController.prototype.ev_clickOut = function (event) {
  if ((0, _EventEmitter.hitElement)(this.$suggestionList, event)) return;
  this.closeDropdown();
};
/**
 *
 * @param {ExpressionInput} elt
 * @constructor
 */


function EICommandTool(elt) {
  this.elt = elt;

  for (var key in this) {
    if (key.startsWith('ev_')) {
      this[key] = this[key].bind(this);
    }
  }

  this.isOpen = false;
  this.$ctn = (0, _ACore._)({
    tag: _Follower.default,
    class: 'as-ei-command-tool',
    props: {
      anchor: [6, 1]
    },
    child: [// {
    //     tag: 'button',
    //     class: 'as-transparent-button',
    //     child: 'span.mdi.mdi-function-variant',
    //     attr: {
    //         title: 'Insert [Ctrl + I]'
    //     },
    // },
    {
      tag: 'button',
      class: 'as-transparent-button',
      child: 'span.mdi.mdi-magnify',
      attr: {
        title: 'Hint [Ctrl + Space]'
      },
      on: {
        click: () => {
          this.elt.autoCompleteCtrl.openDropdown();
          this.elt.engine.setSelectedPosition(this.elt.engine.lastSelectedPosition);
        }
      }
    }]
  });
  this.elt.$content.on('focus', this.ev_focus);
}

EICommandTool.prototype.open = function () {
  if (this.isOpen) return;
  this.elt.emit('focus', {
    type: 'focus',
    originalEvent: event,
    target: this.elt
  }, this.elt);
  if (this.elt.autoCompleteCtrl.getSuggestionList().length === 0) return;
  this.isOpen = true;
  this.$ctn.addTo(this.elt);
  this.$ctn.followTarget = this.elt;
  var zIndex = (0, _utils.findMaxZIndex)(this.elt) + 1;
  this.$ctn.addStyle('z-index', zIndex);
  document.addEventListener('click', this.ev_clickOut);
};

EICommandTool.prototype.close = function () {
  if (!this.isOpen) return;
  this.isOpen = false;
  this.elt.emit('blur', {
    type: 'blur',
    originalEvent: event,
    target: this.elt
  }, this.elt);
  document.removeEventListener('click', this.ev_clickOut);
  this.$ctn.selfRemove();
};

EICommandTool.prototype.ev_focus = function (event) {
  this.open();
};

EICommandTool.prototype.ev_clickOut = function (ev) {
  if ((0, _EventEmitter.hitElement)(this.elt, ev)) return;
  this.close();
};

EICommandTool.prototype.revokeResource = function () {
  this.elt.$content.on('focus', this.ev_focus);
  this.close();
};
/**
 * @extends {AElement}
 * @constructor
 */


function EISuggestionList() {
  /**
   *
   * @type {EISuggestionNode}
   */
  this.$selectedNode = null;
  this._data = [];
  this.$children = [];
}

EISuggestionList.prototype.reset = function () {//todo: select first suggestion
};

EISuggestionList.prototype.moveToNextSuggestion = function () {
  if (this.$selectedNode) {
    return this.selectElt(this.$selectedNode.nextSibling || this.childNodes[0]);
  } else {
    return this.selectElt(this.$children[0]);
  }
};

EISuggestionList.prototype.moveToPrevSuggestion = function () {
  if (this.$selectedNode) {
    return this.selectElt(this.$selectedNode.previousSibling || this.lastChild);
  } else {
    return this.selectElt(this.lastChild);
  }
};

EISuggestionList.render = function () {
  return (0, _ACore._)({
    extendEvent: ['select'],
    class: ['am-select-tree-leaf-box-list', 'as-bscroller', 'as-dropdown-box-common-style', 'as-ei-suggestion-list']
  });
};

EISuggestionList.prototype.selectElt = function (elt) {
  elt = elt || null;
  if (elt === this.$selectedNode) return false;

  if (this.$selectedNode) {
    this.$selectedNode.removeClass('as-selected');
  }

  this.$selectedNode = elt;

  if (elt) {
    elt.addClass('as-selected');
  }

  if (this.isDescendantOf(document.body)) {
    (0, _utils.vScrollIntoView)(elt);
  }

  return true;
};

EISuggestionList.prototype.selectMaxScoreItem = function () {
  var maxPath = [];
  var maxScore = 0;

  var visit = (nd, path) => {
    if (nd.data.score > maxScore) {
      maxScore = nd.data.score;
      maxPath = path.concat([nd]);
    }

    path.push(nd);
    nd.$children.forEach(child => {
      visit(child, path);
    });
    path.pop();
  };

  this.$children.forEach(node => {
    visit(node, []);
  });
  maxPath.forEach(node => {
    node.open();
  });

  if (maxPath.length > 0) {
    this.selectElt(maxPath[maxPath.length - 1]);
  }
};

EISuggestionList.property = {};
EISuggestionList.property.data = {
  set: function (data) {
    data = data || [];
    this._data = data;
    this.clearChild();
    this.$children = data.map(it => {
      return (0, _ACore._)({
        tag: EISuggestionNode,
        props: {
          data: it
        }
      });
    });
    var viewElements = [];
    this.$children.forEach(function (child) {
      child.getViewElements(viewElements);
    });
    this.addChild(viewElements);
  },
  get: function () {
    return this._data;
  }
};
EISuggestionList.property.selectedSuggestions = {
  get: function () {
    return this.$selectedNode ? this.$selectedNode.data : null;
  }
};
/**
 * @typedef {Object} EISuggestionNodeData
 * @property {string} text
 * @property {string} value
 * @property {string} [desc]
 * @property {string} type
 * @property {boolean} [noSelect]
 * @property {EISuggestionNodeData[]} [children]
 */

/**
 * @extends {AElement}
 * @constructor
 */

function EISuggestionNode() {
  this.$text = (0, _ACore.$)('.as-eisli-text', this);
  this.$desc = (0, _ACore.$)('.as-eisli-desc', this);
  this.$iconCtn = (0, _ACore.$)('.as-eisli-icon-ctn', this);
  this._level = 0;
  this._data = {
    text: '',
    desc: ''
  };
  this.on('click', event => {
    this.parentElement.emit('select', {
      type: 'select',
      originalEvent: event,
      target: this,
      data: this.data
    }, this);
  });
  /**
   *
   * @type {EISuggestionNode[]}
   */

  this.$children = [];
  /**
   * @type {"none"|"open"|"close"}
   * @name status
   * @memberOf EISuggestionNode#
   */

  /**
   * @type {EISuggestionNodeData}
   * @name data
   * @memberOf EISuggestionNode#
   */

  /**
   * @type {number}
   * @name level
   * @memberOf EISuggestionNode#
   */
}

EISuggestionNode.render = function () {
  return (0, _ACore._)({
    class: ['as-ei-suggestion-list-item'],
    child: [{
      class: 'as-eisli-toggler',
      child: 'toggler-ico'
    }, {
      class: 'as-eisli-icon-ctn'
    }, {
      class: 'as-eisli-text',
      child: {
        text: ''
      }
    }, {
      class: 'as-eisli-desc',
      child: {
        text: ''
      }
    }]
  });
};

EISuggestionNode.prototype.getViewElements = function (ac) {
  ac = ac || [];
  ac.push(this);

  if (this.status === 'open') {
    this.$children.forEach(function (child) {
      child.getViewElements(ac);
    });
  }

  return ac;
};

EISuggestionNode.prototype.close = function () {
  if (!this.hasClass(' as-status-open')) return;
  var viewElements = this.getViewElements();
  this.addClass('as-status-close').removeClass('as-status-open');
  viewElements.shift();

  for (var i = 0; i < viewElements.length; ++i) {
    viewElements[i].remove();
  }
};

EISuggestionNode.prototype.open = function () {
  if (!this.hasClass(' as-status-close')) return;
  this.addClass('as-status-open').removeClass('as-status-close');
  var nextSibling = this.nextSibling;
  var viewElements = this.getViewElements();

  for (var i = 0; i < viewElements.length; ++i) {
    this.insertBefore(viewElements[i], nextSibling);
  }
};

EISuggestionNode.property = {};
EISuggestionNode.property.data = {
  /**
   * @this {EISuggestionNode}
   * @param {EISuggestionNodeData} data
   */
  set: function (data) {
    this._data = data || {};
    this.$text.firstChild.data = data.text || '';
    this.$desc.firstChild.data = data.desc || '';

    if (data.noSelect) {
      this.addClass('as-no-select');
    }

    this.$children = (data.children || []).map(childData => {
      return (0, _ACore._)({
        tag: EISuggestionNode,
        props: {
          data: childData,
          level: this.level + 1
        }
      });
    });
    this.$iconCtn.clearChild();

    if (data.item) {
      switch (data.item.type) {
        case 'variable':
          this.$iconCtn.addChild((0, _ACore._)('span.mdi.mdi-variable'));

          if (data.children && data.children.length > 0) {
            this.status = 'open';
          }

          break;

        case 'function':
          this.$iconCtn.addChild((0, _ACore._)('span.mdi.mdi-function'));
          break;
      }
    } else {
      this.status = 'open';
      this.$iconCtn.addChild((0, _ACore._)('span.mdi.mdi-code-json'));
    }
  },
  get: function () {
    return this._data;
  }
};
EISuggestionNode.property.level = {
  set: function (value) {
    this.addStyle('--level', value + '');
    this._level = value;
    this.$children.forEach(child => {
      child.level = value + 1;
    });
  },
  get: function () {
    return this._level;
  }
};
EISuggestionNode.property.status = {
  set: function (value) {
    if (value === 'open') {
      this.addClass('as-status-open').removeClass('as-status-close');
    } else if (value === 'close') {
      this.addClass('as-status-close').removeClass('as-status-open');
    }
  },
  get: function () {
    if (this.hasClass('as-status-open')) return 'open';
    if (this.hasClass('as-status-close')) return 'close';
    return 'none';
  }
};
/*********************************
 * EXPRESSION
 */

var rules = [];
var operatorOrder = {
  'NOT': 4,
  '!': 4,
  '*': 5,
  '/': 5,
  'MOD': 5,
  '%': 5,
  '+': 6,
  '-': 6,
  '<': 9,
  '>': 9,
  '<=': 9,
  '>=': 9,
  '==': 9,
  '=': 9,
  '===': 9,
  '!=': 9,
  'AND': 14,
  '&&': 14,
  'OR': 15,
  '||': 15,
  'XOR': 15
};
rules.push({
  target: 'null',
  elements: ['_null'],
  toAST: function (parsedNode) {
    return {
      type: 'NullLiteral'
    };
  }
});
rules.push({
  target: 'ident',
  elements: ['.word'],
  toAST: function (parsedNode) {
    return {
      type: 'Identifier',
      name: parsedNode.children[0].content
    };
  }
});
rules.push({
  target: 'args_list',
  elements: ['exp'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  },
  toASTChain: function (parsedNode) {
    return [(0, _DPParseInstance.parsedNodeToAST)(parsedNode)];
  }
});
rules.push({
  target: 'args_list',
  elements: ['args_list', '_,', 'exp'],
  longestOnly: true,
  ident: 'args_list_rec',
  toASTChain: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToASTChain)(parsedNode.children[0]).concat((0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2]));
  }
});
rules.push({
  target: 'function_callee',
  elements: ['ident'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'function_callee',
  elements: ['mem_exp'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'function_call',
  elements: ['function_callee', '_(', 'args_list', '_)'],
  toAST: function (parsedNode) {
    return {
      type: 'CallExpression',
      arguments: parsedNode.children[2].rule.toASTChain(parsedNode.children[2]),
      callee: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0])
    };
  }
});
rules.push({
  target: 'function_call',
  elements: ['function_callee', '_(', '_)'],
  toAST: function (parsedNode) {
    return {
      type: 'CallExpression',
      arguments: [],
      callee: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0])
    };
  }
});
rules.push({
  target: 'new_expression',
  elements: ['_new', 'function_call'],
  toAST: function (parsedNode) {
    var callAst = (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[1]);
    return {
      type: 'NewExpression',
      arguments: callAst.arguments,
      callee: callAst.callee
    };
  }
});
rules.push({
  target: 'exp',
  elements: ['new_expression'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'exp',
  elements: ['null'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'exp',
  elements: ['ident'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'number',
  elements: ['.number'],
  toAST: function (parsedNode) {
    return {
      type: 'NumericLiteral',
      value: parseFloat(parsedNode.children[0].content)
    };
  }
});
rules.push({
  target: 'string',
  elements: ['.string'],
  toAST: function (parsedNode) {
    var content = parsedNode.children[0].content;
    if (content[0] === "'") content = '"' + content.substring(1, content.length - 1).replace(/["]/g, '\\"') + '"';
    return {
      type: 'StringLiteral',
      value: JSON.parse(content)
    };
  }
});
rules.push({
  target: 'boolean',
  elements: ['_true'],
  toAST: function (parsedNode) {
    return {
      type: 'BooleanLiteral',
      value: true
    };
  }
});
rules.push({
  target: 'boolean',
  elements: ['_false'],
  toAST: function (parsedNode) {
    return {
      type: 'BooleanLiteral',
      value: false
    };
  }
});
rules.push({
  target: 'exp',
  elements: ['number'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'exp',
  elements: ['string'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'exp',
  elements: ['boolean'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
['+', '-', '*', '/', '%', '&&', '||', 'XOR', "=", '==', '===', '!=', '<', '>', '>=', '<='].forEach(function (op) {
  rules.push({
    target: 'bin_op',
    elements: ['_' + op],
    toAST: function (parsedNode) {
      return {
        type: "BinaryOperator",
        content: op
      };
    }
  });
});
var x = Math.m;
rules.push({
  target: 'exp',
  elements: ['exp', 'bin_op', 'exp'],
  // longestOnly: true,//* error when parse return (...)...
  ident: 'bin_op_rec',
  toASTChain: function (parseNode) {
    var res = [];

    if (parseNode.children[0].rule === this) {
      res = res.concat(this.toASTChain(parseNode.children[0]));
    } else {
      res.push((0, _DPParseInstance.parsedNodeToAST)(parseNode.children[0]));
    }

    res.push(parseNode.children[1].children[0]);

    if (parseNode.children[2].rule === this) {
      res = res.concat(this.toASTChain(parseNode.children[2]));
    } else {
      res.push((0, _DPParseInstance.parsedNodeToAST)(parseNode.children[2]));
    }

    return res;
  },
  toAST: function (parsedNode) {
    var chain = this.toASTChain(parsedNode);
    var stack = [];
    var item;
    var newNode;

    while (chain.length > 0) {
      item = chain.shift();

      if (item.content in operatorOrder) {
        while (stack.length >= 3 && operatorOrder[stack[stack.length - 2].content] <= operatorOrder[item.content]) {
          newNode = {
            type: 'BinaryExpression'
          };
          newNode.right = stack.pop();
          newNode.operator = stack.pop();
          newNode.left = stack.pop();
          stack.push(newNode);
        }
      }

      stack.push(item);
    }

    while (stack.length >= 3) {
      newNode = {
        type: 'BinaryExpression'
      };
      newNode.right = stack.pop();
      newNode.operator = stack.pop();
      newNode.left = stack.pop();
      stack.push(newNode);
    }

    return stack.pop();
  }
});
rules.push({
  target: 'exp',
  elements: ['function_call'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'bracket_group',
  elements: ['_(', 'exp', '_)'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[1]);
  }
});
rules.push({
  target: 'exp',
  elements: ['bracket_group'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
}); // rules.push({
//     target: 'exp',
//     elements: ['_(', 'exp', '_)'],
//     toAST: function (parsedNode) {
//         return parsedNodeToAST(parsedNode.children[1]);
//     }
// });

['+', '-', '!'].forEach(function (op) {
  ['number', 'bracket_group', 'ident', 'function_call', 'mem_exp', 'unary_exp'].forEach(function (arg) {
    rules.push({
      target: 'unary_exp',
      elements: ['_' + op, arg],
      toAST: function (parsedNode) {
        return {
          type: 'UnaryExpression',
          argument: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[1]),
          operator: {
            type: 'UnaryOperator',
            content: op
          }
        };
      }
    });
  });
});
rules.push({
  target: 'exp',
  elements: ['unary_exp'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'mem_exp',
  elements: ['ident', '_->', 'ident'],
  toAST: function (parsedNode) {
    return {
      type: "MemberExpression",
      computed: false,
      object: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]),
      property: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])
    };
  }
});
rules.push({
  target: 'mem_exp',
  elements: ['ident', '_[', 'exp', '_]'],
  toAST: function (parsedNode) {
    return {
      type: "MemberExpression",
      computed: true,
      object: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]),
      property: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])
    };
  }
});
rules.push({
  target: 'mem_exp',
  elements: ['new_expression', '_->', 'ident'],
  toAST: function (parsedNode) {
    return {
      type: "MemberExpression",
      computed: false,
      object: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]),
      property: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])
    };
  }
});
rules.push({
  target: 'mem_exp',
  elements: ['new_expression', '_[', 'exp', '_]'],
  toAST: function (parsedNode) {
    return {
      type: "MemberExpression",
      computed: true,
      object: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]),
      property: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])
    };
  }
});
rules.push({
  target: 'mem_exp',
  elements: ['mem_exp', '_->', 'ident'],
  longestOnly: true,
  ident: 'mem_exp_ident_rev',
  toAST: function (parsedNode) {
    return {
      type: "MemberExpression",
      computed: false,
      object: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]),
      property: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])
    };
  }
});
rules.push({
  target: 'mem_exp',
  elements: ['mem_exp', '_[', 'exp', '_]'],
  toAST: function (parsedNode) {
    return {
      type: "MemberExpression",
      computed: true,
      object: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]),
      property: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])
    };
  }
});
rules.push({
  target: 'mem_exp',
  elements: ['bracket_group', '_->', 'ident'],
  toAST: function (parsedNode) {
    return {
      type: "MemberExpression",
      computed: false,
      object: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]),
      property: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])
    };
  }
});
rules.push({
  target: 'mem_exp',
  elements: ['bracket_group', '_[', 'exp', '_]'],
  toAST: function (parsedNode) {
    return {
      type: "MemberExpression",
      computed: true,
      object: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]),
      property: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])
    };
  }
});
rules.push({
  target: 'exp',
  elements: ['mem_exp'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
/**********************************************************************************************************************/

rules.push({
  target: 'object_exp',
  elements: ['_{', '_}'],
  toAST: function (parsedNode) {
    return {
      type: 'ObjectExpression',
      properties: []
    };
  }
});
rules.push({
  target: 'object_exp',
  elements: ['_{', 'object_property_list', '_}'],
  toAST: function (parsedNode) {
    return {
      type: 'ObjectExpression',
      properties: (0, _DPParseInstance.parsedNodeToASTChain)(parsedNode.children[1])
    };
  }
});
rules.push({
  target: 'exp',
  elements: ['object_exp'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'object_property',
  elements: ['ident', '_:', 'exp'],
  toAST: function (parsedNode) {
    return {
      type: 'ObjectProperty',
      key: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]),
      value: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])
    };
  }
});
rules.push({
  target: 'object_property',
  elements: ['string', '_:', 'exp'],
  toAST: function (parsedNode) {
    return {
      type: 'ObjectProperty',
      key: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]),
      value: (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])
    };
  }
});
rules.push({
  target: 'object_property_list',
  elements: ['object_property'],
  toASTChain: function (parsedNode) {
    return [(0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0])];
  }
});
rules.push({
  target: 'object_property_list',
  elements: ['object_property_list', '_,', 'object_property'],
  longestOnly: true,
  ident: 'object_property_list_rec',
  toASTChain: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToASTChain)(parsedNode.children[0]).concat([(0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])]);
  }
});
/**********************************************************************************************************************/

rules.push({
  target: 'exp',
  elements: ['array_exp'],
  toAST: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0]);
  }
});
rules.push({
  target: 'array_exp',
  elements: ['_[', '_]'],
  toAST: function (parsedNode) {
    return {
      type: "ArrayExpression",
      elements: []
    };
  }
});
rules.push({
  target: 'array_exp',
  elements: ['_[', 'array_item_list', '_]'],
  toAST: function (parsedNode) {
    return {
      type: "ArrayExpression",
      elements: (0, _DPParseInstance.parsedNodeToASTChain)(parsedNode.children[1])
    };
  }
});
rules.push({
  target: 'array_item_list',
  elements: ['exp'],
  toASTChain: function (parsedNode) {
    return [(0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[0])];
  }
});
rules.push({
  target: 'array_item_list',
  elements: ['array_item_list', '_,', 'exp'],
  longestOnly: true,
  ident: 'array_item_list_rec',
  toASTChain: function (parsedNode) {
    return (0, _DPParseInstance.parsedNodeToASTChain)(parsedNode.children[0]).concat([(0, _DPParseInstance.parsedNodeToAST)(parsedNode.children[2])]);
  }
});
/**********************************************************************************************************************/

var elementRegexes = [['string', /("(?:[^"\\\n]|\\.)*?")|('(?:[^'\\\n]|\\.)*?')/], ['number', /(\d+([.]\d*)?([eE][+-]?\d+)?|[.]\d+([eE][+-]?\d+)?)/], ['word', /[_a-zA-Z][_a-zA-Z0-9]*/], ['skip', /([\s\r\n])|(\/\/[^\n]*)|(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)/], ['dsymbol', /\+\+|--|==|!=|<=|>=|\|\||&&|->/], ['tsymbol', /\.\.\./], ['symbol', /[^\s_a-zA-Z0-9]/]];
var EIGrammar = {
  elementRegexes: elementRegexes,
  operatorOrder: _SCGrammar.default.operatorOrder,
  rules: rules
};
var EIParser = new _DPParser.default(EIGrammar);

VaKeR 2022