System.register(['reactive-jsx', 'src/components/widgets/lively-morph.js', 'src/client/contextmenu.js', 'src/client/sort.js', 'utils', 'src/external/lodash/lodash.js'], function (_export, _context) {
  "use strict";

  var _childExpression, _childElement, _childText, _children, _attributeStringLiteral, _attributes, _element, Morph, ContextMenu, sortAlphaNum, getTempKeyFor, _;

  return {
    setters: [function (_reactiveJsx) {
      _childExpression = _reactiveJsx.childExpression;
      _childElement = _reactiveJsx.childElement;
      _childText = _reactiveJsx.childText;
      _children = _reactiveJsx.children;
      _attributeStringLiteral = _reactiveJsx.attributeStringLiteral;
      _attributes = _reactiveJsx.attributes;
      _element = _reactiveJsx.element;
    }, function (_srcComponentsWidgetsLivelyMorphJs) {
      Morph = _srcComponentsWidgetsLivelyMorphJs.default;
    }, function (_srcClientContextmenuJs) {
      ContextMenu = _srcClientContextmenuJs.default;
    }, function (_srcClientSortJs) {
      sortAlphaNum = _srcClientSortJs.sortAlphaNum;
    }, function (_utils) {
      getTempKeyFor = _utils.getTempKeyFor;
    }, function (_srcExternalLodashLodashJs) {
      _ = _srcExternalLodashLodashJs.default;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._src_components_tools_lively_inspector_js = _recorder_._src_components_tools_lively_inspector_js || {};
      Object.defineProperty(_recorder_._src_components_tools_lively_inspector_js, 'truncateString', {
        get() {
          return truncateString;
        },

        set(thisIsVererySecretVariableName) {
          truncateString = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_tools_lively_inspector_js, 'Morph', {
        get() {
          return Morph;
        },

        set(thisIsVererySecretVariableName) {
          Morph = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_tools_lively_inspector_js, 'ContextMenu', {
        get() {
          return ContextMenu;
        },

        set(thisIsVererySecretVariableName) {
          ContextMenu = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_tools_lively_inspector_js, 'sortAlphaNum', {
        get() {
          return sortAlphaNum;
        },

        set(thisIsVererySecretVariableName) {
          sortAlphaNum = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_tools_lively_inspector_js, 'getTempKeyFor', {
        get() {
          return getTempKeyFor;
        },

        set(thisIsVererySecretVariableName) {
          getTempKeyFor = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._src_components_tools_lively_inspector_js, '_', {
        get() {
          return _;
        },

        set(thisIsVererySecretVariableName) {
          _ = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });


      /**
       * @usage: truncateString("Hello World", 8, "...")
       */
      function truncateString(s = '', length = 30, truncation = '...') {
        return s.length > length ? s.slice(0, length - truncation.length) + truncation : String(s);
      }

      class Inspector extends Morph {

        initialize() {
          if (this.getAttribute("target")) {
            this.inspect(document.querySelector(this.getAttribute("target")));
          }
          // lively.notify("[inspector] intialize");  
          this.get("#editor").enableAutocompletion();

          this.addEventListener('contextmenu', evt => this.onContextMenu(evt), false);
        }

        displayValue(value, expand, name) {
          if (name) {
            let attrValue;
            if (value && typeof value === 'symbol') {
              attrValue = value.toString();
            } else {
              attrValue = JSON.stringify(value).replace(/</g, "&lt;");
            }
            return _element('div', _attributes(_attributeStringLiteral('class', 'element')), _children(_childText('\n        '), _childElement(_element('span', _attributes(_attributeStringLiteral('class', 'attrName')), _children(_childExpression(name), _childText(':')), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 45,
                line: 41
              },
              start: {
                column: 8,
                line: 41
              }
            })), _childText('\n        '), _childElement(_element('span', _attributes(_attributeStringLiteral('class', 'attrValue')), _children(_childExpression(attrValue)), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 50,
                line: 42
              },
              start: {
                column: 8,
                line: 42
              }
            })), _childText('\n      ')), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 12,
                line: 43
              },
              start: {
                column: 13,
                line: 40
              }
            });
          } else {
            return _element('pre', _attributes(), _children(_childExpression(JSON.stringify(value))), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 47,
                line: 45
              },
              start: {
                column: 13,
                line: 45
              }
            });
          }
        }

        onContextMenu(evt) {
          if (this.targetObject && !evt.shiftKey) {
            evt.preventDefault();
            evt.stopPropagation();
            if (this.targetObject instanceof Array) {
              var menu = new ContextMenu(this, [["inspect as table", () => Inspector.inspectArrayAsTable(this.targetObject)]]);
              menu.openIn(document.body, evt, this);
            } else if (this.targetObject.tagName) {
              // for all html elements
              lively.openContextMenu(document.body, evt, this.selection || this.targetObject);
              return true;
            }
            return false;
          }
        }

        /*
         * called, when selecting a subobject 
         */
        onSelect(node, obj) {
          if (this.selectedNode) {
            this.selectedNode.classList.remove("selected");
          }
          this.selectedNode = node;
          this.selectedNode.classList.add("selected");

          this.selection = obj;
          lively.showElement(obj);
          window.that = obj; // #Experimental
          this.get("#editor").doitContext = obj;
          this.dispatchEvent(new CustomEvent("select-object", { detail: { node: node, object: obj } }));
        }

        renderObject(node, obj, expand, name = '') {
          // handle system objects... 
          node.type = "Object";
          node.isExpanded = expand;

          var className = obj.constructor.name;
          if (this.isAstMode() && obj.type) {
            className = obj.type;
          }

          node.innerHTML = '';
          node.appendChild(this.expandTemplate(node));
          node.appendChild(_element('span', _attributes(), _children(_childText('\n      '), _childElement(_element('span', _attributes(_attributeStringLiteral('class', 'attrName expand')), _children(_childText(' '), _childExpression(name)), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 50,
              line: 97
            },
            start: {
              column: 6,
              line: 97
            }
          })), _childElement(_element('span', _attributes(_attributeStringLiteral('class', 'syntax')), _children(_childText(':')), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 79,
              line: 97
            },
            start: {
              column: 50,
              line: 97
            }
          })), _childText(' \n    ')), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 11,
              line: 98
            },
            start: {
              column: 21,
              line: 96
            }
          }));

          if (typeof obj === 'function') {
            //(/</g,"&lt;")
            node.appendChild(_element('span', _attributes(_attributeStringLiteral('class', 'attrValue')), _children(_childText('\u0192')), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 62,
                line: 102
              },
              start: {
                column: 23,
                line: 102
              }
            }));
            node.appendChild(_element('span', _attributes(_attributeStringLiteral('class', '')), _children(_childText(' '), _childExpression(obj.name), _childText(' ')), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 57,
                line: 103
              },
              start: {
                column: 23,
                line: 103
              }
            }));
            node.appendChild(_element('span', _attributes(_attributeStringLiteral('class', '')), _children(_childExpression(truncateString(obj.toString(), 20, '...'))), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 88,
                line: 104
              },
              start: {
                column: 23,
                line: 104
              }
            }));
          } else {
            node.appendChild(_element('a', _attributes(_attributeStringLiteral('id', 'tagname'), _attributeStringLiteral('class', 'tagname')), _children(_childExpression(className)), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 70,
                line: 106
              },
              start: {
                column: 23,
                line: 106
              }
            }));
          }
          node.appendChild(_element('span', _attributes(), _children(_childText('\n      '), _childElement(_element('span', _attributes(_attributeStringLiteral('class', 'syntax')), _children(_childText('{')), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 40,
              line: 109
            },
            start: {
              column: 6,
              line: 109
            }
          })), _childExpression(this.contentTemplate()), _childElement(_element('span', _attributes(_attributeStringLiteral('class', 'syntax')), _children(_childText('}')), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 43,
              line: 111
            },
            start: {
              column: 9,
              line: 111
            }
          })), _childText('\n    ')), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 11,
              line: 112
            },
            start: {
              column: 21,
              line: 108
            }
          }));

          this.attachHandlers(node, obj, name, "renderObject");
          this.renderExpandedProperties(node, obj);
        }

        renderExpandedProperties(node, obj) {
          if (!node.isExpanded) {
            return;
          }

          var contentNode = node.querySelector("#content");

          if (obj.livelyInspect) {
            try {
              obj.livelyInspect(contentNode, this);
            } catch (e) {
              var selection = _element('div', _attributes(_attributeStringLiteral('class', 'element'), _attributeStringLiteral('style', 'color:red')), _children(_childElement(_element('b', _attributes(), _children(_childText('Error in livleyInspect:')), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                end: {
                  column: 93,
                  line: 127
                },
                start: {
                  column: 63,
                  line: 127
                }
              })), _childText(' '), _childExpression(e)), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                end: {
                  column: 103,
                  line: 127
                },
                start: {
                  column: 24,
                  line: 127
                }
              });
              contentNode.appendChild(selection);
            }
            return;
          }

          if (obj && obj[Symbol.iterator]) {
            this.renderIterable(contentNode, obj);
            return;
          }

          contentNode.innerHTML = "";
          this.allKeys(obj).sort(sortAlphaNum).forEach(ea => {
            try {
              var value = obj[ea];
            } catch (e) {
              console.log("[inspector] could not display " + ea + " of " + obj);
              return;
            }
            if (value == null) return;
            var childNode = this.display(value, false, ea, obj);
            if (childNode) contentNode.appendChild(childNode); // force object display 
          });
        }

        displayObject(obj, expand, name) {
          if (!(obj instanceof Object)) {
            return this.displayValue(obj, expand, name); // even when displaying objects.
          }
          // if ((obj instanceof Function)) {
          //   return this.displayFunction(obj, expand, name); // even when displaying objects.
          // }

          var node = _element('div', _attributes(_attributeStringLiteral('class', 'element')), _children(), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 42,
              line: 160
            },
            start: {
              column: 15,
              line: 160
            }
          });
          node.pattern = "NAME " + (name || '').toString();
          node.name = name;
          this.renderObject(node, obj, expand, name);
          return node;
        }

        addVivideSelection(cb, node) {
          const root = node ? node : this.container;
          const atts = root.querySelectorAll('.attrValue');
          for (let i = 0; i < atts.length; i++) {
            const value = atts.item(i).innerHTML;
            atts.item(i).addEventListener('click', () => cb(value.startsWith('"') ? value.slice(1, -1) : value));
          }
        }

        changeAttributeValue(obj, attrName, attrValue) {
          obj.setAttribute(attrName, attrValue);
          lively.notify("edited " + attrName + " to " + attrValue);
        }

        expandTemplate(node) {
          return _element('span', _attributes(_attributeStringLiteral('class', 'syntax')), _children(_childElement(_element('a', _attributes(_attributeStringLiteral('class', 'expand')), _children(_childExpression(node.isExpanded ? _element('span', _attributes(_attributeStringLiteral('style', 'font-size:9pt')), _children(_childText('\u25BC')), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 48,
              line: 183
            },
            start: {
              column: 6,
              line: 183
            }
          }) : _element('span', _attributes(_attributeStringLiteral('style', 'font-size:7pt')), _children(_childText('\u25B6')), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 48,
              line: 184
            },
            start: {
              column: 6,
              line: 184
            }
          }))), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 9,
              line: 185
            },
            start: {
              column: 32,
              line: 182
            }
          }))), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 16,
              line: 185
            },
            start: {
              column: 11,
              line: 182
            }
          });
        }

        contentTemplate(content) {
          return _element('span', _attributes(_attributeStringLiteral('id', 'content')), _children(_childElement(_element('a', _attributes(_attributeStringLiteral('id', 'more'), _attributeStringLiteral('class', 'more')), _children(_childExpression(content ? content : "...")), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 87,
              line: 189
            },
            start: {
              column: 30,
              line: 189
            }
          }))), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 94,
              line: 189
            },
            start: {
              column: 11,
              line: 189
            }
          });
        }

        attachHandlers(node, obj, name, renderCall = "render") {
          node.target = obj;
          // jqyery would make this cleaner here...
          var moreNode = node.querySelector("#more");
          if (moreNode) {
            moreNode.onclick = evt => {
              this[renderCall](node, obj, true, name);
            };
            // #TODO: does not work, ... yet
            moreNode.draggable = "true";
            moreNode.addEventListener('dragstart', evt => {
              evt.dataTransfer.setData("javascript/object", getTempKeyFor(obj));
            });
          }
          node.querySelectorAll(".expand").forEach(expandNode => {
            expandNode.onclick = evt => {
              this[renderCall](node, obj, !node.isExpanded, name);
            };
          });
          const tagNode = node.querySelector("#tagname");
          if (tagNode) tagNode.addEventListener('click', evt => {
            this.onSelect(node, obj);
          });
        }

        renderAttributes(node, obj) {
          function quoteTemplate() {
            return _element('span', _attributes(_attributeStringLiteral('class', 'syntax')), _children(_childText('"')), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 42,
                line: 219
              },
              start: {
                column: 13,
                line: 219
              }
            });
          }

          if (obj.attributes) {
            var attrNode = node.querySelector("#attributes");
            Array.from(obj.attributes).forEach(ea => {
              var value = "" + ea.value;
              var maxvaluelength = 60;
              if (value.length > maxvaluelength) {
                var shortenValue = true;
                value = value.slice(0, maxvaluelength) + "...";
              }
              var eaNode = _element('span', _attributes(), _children(_childText(' '), _childElement(_element('span', _attributes(_attributeStringLiteral('class', 'attrName')), _children(_childExpression(ea.name), _childText('=')), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                end: {
                  column: 68,
                  line: 231
                },
                start: {
                  column: 28,
                  line: 231
                }
              })), _childExpression(quoteTemplate()), _childElement(_element('span', _attributes(_attributeStringLiteral('class', 'attrValue')), _children(_childExpression(value)), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                end: {
                  column: 123,
                  line: 231
                },
                start: {
                  column: 85,
                  line: 231
                }
              })), _childExpression(quoteTemplate())), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                end: {
                  column: 147,
                  line: 231
                },
                start: {
                  column: 21,
                  line: 231
                }
              });
              var valueNode = eaNode.querySelector(".attrValue");
              // Editing of attribute values in inspector
              if (!shortenValue) {
                valueNode.onclick = evt => {
                  eaNode.querySelector(".attrValue").contentEditable = true;
                  return true;
                };
                // accept changes in content editable attribute value
                valueNode.onkeydown = evt => {
                  if (evt.keyCode == 13) {
                    // on enter -> like in input fields
                    valueNode.contentEditable = false;
                    this.changeAttributeValue(obj, ea.name, valueNode.textContent);
                    evt.preventDefault();
                  }
                };
              }
              attrNode.appendChild(eaNode);
            });
          }
        }

        renderHeader(node, obj) {
          node.innerHTML = '';

          if (obj === document) {
            return;
          }

          if (obj instanceof Document) {
            return;
          }

          if (obj instanceof ShadowRoot) {
            node.appendChild(this.expandTemplate(node));
            node.appendChild(_element('a', _attributes(_attributeStringLiteral('id', 'tagname'), _attributeStringLiteral('class', 'tagname')), _children(_childText(' #shadow-root')), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 72,
                line: 268
              },
              start: {
                column: 23,
                line: 268
              }
            }));
            node.appendChild(this.contentTemplate());
            return;
          }

          if (obj instanceof Comment) {
            node.appendChild(_element('a', _attributes(_attributeStringLiteral('id', 'tagname'), _attributeStringLiteral('class', 'tagname')), _children(_childText('&lt!-- ')), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 66,
                line: 274
              },
              start: {
                column: 23,
                line: 274
              }
            }));
            node.appendChild(this.contentTemplate());
            node.appendChild(document.createTextNode(" --&gt"));
            return;
          }

          var tagName = obj.tagName || obj.nodeName;
          var lt = () => _element('span', _attributes(_attributeStringLiteral('class', 'syntax')), _children(_childText('<')), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 51,
              line: 281
            },
            start: {
              column: 19,
              line: 281
            }
          });
          var gt = () => _element('span', _attributes(_attributeStringLiteral('class', 'syntax')), _children(_childText('>')), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 51,
              line: 282
            },
            start: {
              column: 19,
              line: 282
            }
          });
          const showTags = obj.tagName && !obj.livelyIsParentPlaceholder;
          node.appendChild(this.expandTemplate(node));
          if (showTags) {
            node.appendChild(lt());
          }
          node.appendChild(_element('a', _attributes(_attributeStringLiteral('id', 'tagname'), _attributeStringLiteral('class', 'expand tagname')), _children(_childExpression(tagName.toLowerCase())), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 87,
              line: 286
            },
            start: {
              column: 21,
              line: 286
            }
          }));
          node.appendChild(_element('span', _attributes(_attributeStringLiteral('id', 'attributes')), _children(), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 50,
              line: 287
            },
            start: {
              column: 21,
              line: 287
            }
          }));
          if (showTags) {
            node.appendChild(gt());
          }

          node.appendChild(this.contentTemplate(truncateString(obj.textContent, 40, "..")));

          if (showTags) {
            node.appendChild(lt());
            node.appendChild(document.createTextNode("/"));
            node.appendChild(_element('span', _attributes(_attributeStringLiteral('class', 'tagname')), _children(_childExpression(tagName.toLowerCase())), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
              end: {
                column: 75,
                line: 295
              },
              start: {
                column: 23,
                line: 295
              }
            }));
            node.appendChild(gt());
          }

          // if (!node.isAutoExpanded) html = this.expandTemplate({}).outerHTML + html
        }

        renderNode(node, obj, expanded) {
          node.isExpanded = true && expanded;
          if (!obj.textContent || obj.textContent.length < 80) {
            node.isExpanded = true;
            node.isAutoExpanded = true;
          }

          if (expanded === false) {
            node.isExpanded = false; // force colapse 
          }

          this.renderHeader(node, obj);
          this.renderAttributes(node, obj);

          var contentNode = node.querySelector("#content");
          if (!contentNode) return;

          this.attachHandlers(node, obj);

          var expandChildren = obj.livelyIsParentPlaceholder || false;

          if (node.isExpanded) {
            contentNode.innerHTML = "";
            if (obj instanceof Comment) {
              contentNode.innerHTML = obj.textContent.replace(/</, "&lt;").replace(/>/, "&gt;");
            }
            if (obj.shadowRoot) {
              contentNode.appendChild(this.display(obj.shadowRoot, expandChildren, null, obj));
            }
            obj.childNodes.forEach(ea => {
              contentNode.appendChild(this.display(ea, expandChildren, null, obj));
            });

            try {
              var hasProperties = this.allKeys(obj).length > 0;
            } catch (e) {
              console.warn("[inspector] allKeys failed", e);
            }
            if (hasProperties && !obj.livelyIsParentPlaceholder) {
              var props = this.displayObject(obj, false, "#Properties");
              contentNode.appendChild(props);
              if (props.childNodes.length == 0) props.remove // clean up 

              ();
            }

            if (obj.livelyInspect) {
              try {
                obj.livelyInspect(contentNode, this);
              } catch (e) {
                var selection = _element('div', _attributes(_attributeStringLiteral('class', 'element'), _attributeStringLiteral('style', 'color:red')), _children(_childElement(_element('b', _attributes(), _children(_childText('Error in livleyInspect:')), {
                  file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                  end: {
                    column: 95,
                    line: 354
                  },
                  start: {
                    column: 65,
                    line: 354
                  }
                })), _childText(' '), _childExpression(e)), {
                  file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                  end: {
                    column: 105,
                    line: 354
                  },
                  start: {
                    column: 26,
                    line: 354
                  }
                });
                contentNode.appendChild(selection);
              }
            }
          }
        }

        renderText(node, obj, expanded) {
          if (obj.textContent.match(/^[ \n]*$/)) return; // nothing to render here... skip, empty lines or just spaces
          if (obj.textContent && obj.textContent.length > 100) node.innerHTML = "<pre>" + obj.textContent + "</pre>";else {
            console.log("renderText " + obj);
            node.innerHTML = obj.textContent;
            if (obj instanceof Text) {
              node.onclick = evt => {
                node.contentEditable = true;
                return true;
              };
              // accept changes in content editable attribute value
              node.onkeydown = evt => {
                if (evt.keyCode == 13) {
                  // on enter -> like in input fields
                  node.contentEditable = false;
                  obj.textContent = node.textContent;
                  evt.preventDefault();
                }
              };
            }
          }
        }

        displayText(obj, expanded) {
          var node = _element('span', _attributes(_attributeStringLiteral('class', 'element')), _children(), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 44,
              line: 391
            },
            start: {
              column: 15,
              line: 391
            }
          });
          this.render(node, obj, expanded);
          return node;
        }

        findParentNode(obj) {
          try {
            return obj.parentNode || obj.host;
          } catch (e) {
            // we might be in a prototype ... where we should not dare to ask...
          }
        }

        displayNode(obj, expanded, parent) {
          try {
            var node;
            var parentNode = this.findParentNode(obj);
            if (!parent && parentNode) {
              var tmpParent = {
                tagName: "...",
                textContent: "",
                childNodes: [obj],
                livelyIsParentPlaceholder: true
              };
              node = this.displayNode(tmpParent, true, tmpParent);
              var tagNode = node.querySelector("#tagname");
              if (tagNode) tagNode.onclick = evt => {
                this.inspect(parentNode);
              };
              return node;
            } else if (obj.tagName) {
              node = _element('div', _attributes(_attributeStringLiteral('class', 'element tag')), _children(), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                end: {
                  column: 46,
                  line: 423
                },
                start: {
                  column: 15,
                  line: 423
                }
              });
            } else if (obj instanceof ShadowRoot) {
              node = _element('div', _attributes(_attributeStringLiteral('class', 'element shadowroot')), _children(), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                end: {
                  column: 53,
                  line: 425
                },
                start: {
                  column: 15,
                  line: 425
                }
              });
            } else if (obj instanceof Comment) {
              node = _element('div', _attributes(_attributeStringLiteral('class', 'element comment')), _children(), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                end: {
                  column: 50,
                  line: 427
                },
                start: {
                  column: 15,
                  line: 427
                }
              });
            } else if (obj instanceof Node) {
              node = _element('div', _attributes(_attributeStringLiteral('class', 'element')), _children(), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                end: {
                  column: 42,
                  line: 429
                },
                start: {
                  column: 15,
                  line: 429
                }
              });
            } else {
              // Fallback... 
              node = _element('span', _attributes(_attributeStringLiteral('class', 'element')), _children(), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
                end: {
                  column: 44,
                  line: 432
                },
                start: {
                  column: 15,
                  line: 432
                }
              });
            }
            this.render(node, obj, expanded);
            return node;
          } catch (e) {
            debugger;
            // dont't show red notification... because errors are expected sometimes
            console.error(e);
          }
        }

        isNode(obj) {
          if (obj.constructor === HTMLElement) return obj instanceof HTMLElement; // How to deal with META objects...?
          return obj instanceof Node || obj instanceof Object && obj.livelyIsParentPlaceholder;
        }

        render(node, obj, expanded) {
          if (obj instanceof Text) {
            return this.renderText(node, obj, expanded);
          } else if (this.isNode(obj) && node.type != "Object") {
            return this.renderNode(node, obj, expanded);
          } else if (typeof obj == "object") {
            return this.renderObject(node, obj, expanded, node.name);
          } else if (typeof obj == "function") {}
          // return this.renderFunction(node, obj, expanded, name);

          // return this.renderValue(node, obj, expanded, name);
        }

        display(obj, expanded, name, parent) {
          // from most special to general
          if (obj instanceof Text) {
            return this.displayText(obj, expanded, parent);
          } else if (this.isNode(obj)) {
            return this.displayNode(obj, expanded, parent);
          } else if (typeof obj == "object" || typeof obj == "function") {
            return this.displayObject(obj, expanded, name);
          } else {
            return this.displayValue(obj, expanded, name);
          }
        }

        get container() {
          return this.get("#container");
        }

        inspect(obj) {
          if (!obj) {
            return;
          }

          if (obj instanceof HTMLElement) {
            var cssSelector = lively.elementToCSSName(obj);
            this.setAttribute("target", cssSelector);
          }

          if (this.targetObject) {
            var oldViewState = this.getViewState();
          }

          this.targetObject = obj;
          this.get("#editor").doitContext = obj;
          this.container.innerHTML = "";
          // special case for inspecting single dom nodes
          const content = this.display(obj, true, null, null);
          this.container.appendChild(content);
          this.updatePatterns(this.container.childNodes[0]);

          if (oldViewState) {
            this.setViewState(oldViewState);
          }
          return content;
        }

        allKeys(obj) {
          var keys = [];

          if (obj === null || !(typeof obj === 'object' || typeof obj === 'function')) {
            return [];
          }

          if (obj instanceof Response) return lively.allKeys(obj); // #TODO what does it make different?


          var allOwn = Object.getOwnPropertySymbols(obj).concat(Object.getOwnPropertyNames(obj)
          // for(var i in obj) {
          //   if (obj.hasOwnProperty(i) || obj.__lookupGetter__(i)) {
          //     keys.push(i);
          //   }
          // }
          );keys = allOwn;
          if (!this.isAstMode()) {
            if (obj && this.allKeys(obj.__proto__).length > 0) keys.push("__proto__");
          }
          return _.sortBy(keys);
        }

        isAstMode() {
          return this.getAttribute("type") == "ast";
        }

        hideWorkspace() {
          this.container.style.flex = 1;
          this.get("#editor").style.display = "none";
          this.get("lively-separator").style.display = "none";
        }

        showWorkspace() {
          this.container.style.flex = 0.66;
          this.get("#editor").style.display = "block";
          this.get("lively-separator").style.display = "block";
        }

        updatePatterns(node) {
          var obj = node.target;
          if (node.target) {
            if (node.pattern) {
              // do nothing
            } else if (obj.id) {
              node.pattern = "ID " + obj.id;
            } else if (obj instanceof ShadowRoot) {
              node.pattern = "shadow-root";
            } else {
              node.pattern = "tag " + obj.tagName + " " + obj.id;
              // check if siblings have same pattern
            }
            if (node.parentElement) {
              if (_.find(node.parentElement.childNodes, ea => ea && ea !== node && ea.pattern == node.pattern)) {
                node.pattern += " X"; // unique... but repeatable
              }
            }
          } else {
            node.pattern = "NOTARGET";
          }
          // lively.showElement(node).textContent = "U=" + node.pattern
          var content = node.querySelector("#content");
          if (content) content.childNodes.forEach(ea => {
            this.updatePatterns(ea);
          });
        }

        // JSON.stringify(this.getViewState())
        getViewState() {
          return this.captureViewState(this.container.childNodes[0]);
        }

        /*
          this.setViewState( {"children":[{"pattern":"","children":[{"pattern":"shadowRoot","children":[{"pattern":"","children":[]}]},{"pattern":"#Properties","children":[{"pattern":"attributes","children":[]}]}]}]})
        */
        setViewState(state) {
          return this.applyViewState(this.container.childNodes[0], state);
        }

        applyViewState(node, state) {
          // lively.showElement(node).textContent = "P=" + state.pattern

          if (!node.querySelector) return; // text node

          this.expandNode(node);
          var content = node.querySelector("#content");
          if (content) {
            var children = _.filter(content.childNodes, ea => ea.classList.contains("element"));
            state.children.forEach(ea => {
              var child = children.find(c => c.pattern == ea.pattern);
              if (child) this.applyViewState(child, ea);
            });
          }
        }

        expandNode(node) {
          if (node.isExpanded) return;
          this.render(node, node.target, true);
        }

        captureViewState(node) {
          var result = {
            pattern: node.pattern,
            children: [] };

          if (!node.querySelector) return result; // text node

          var content = node.querySelector("#content");
          if (content) {
            _.filter(content.childNodes, ea => ea.isExpanded).forEach(ea => {
              result.children.push(this.captureViewState(ea));
            });
          }
          return result;
        }

        renderIterable(contentNode, obj) {
          if (!contentNode) return;
          contentNode.innerHTML = "";
          var entries = [];
          try {
            entries = obj.entries // illegal invocation?
            ();
          } catch (e) {}
          for (let [key, value] of entries) {
            const node = this.display(value, true, key);
            if (node) contentNode.appendChild(node);
          }
        }

        static inspectArrayAsTable(array) {
          var div = _element('div', _attributes(), _children(), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/components/tools/lively-inspector.js',
            end: {
              column: 25,
              line: 632
            },
            start: {
              column: 14,
              line: 632
            }
          });
          div.innerHTML = "<table>" + lively.allKeys(array[0]).map(key => {
            return "<tr><td><b>" + key + "</b></td>" + array.map(ea => "<td>" + (ea[key] + "").slice(0, 50) + "</td>").join("") + "</tr>";
          }).join("\n") + "</table>";
          div.style.overflow = "auto";
          lively.components.openInWindow(div, undefined, "Inspect Array");
        }

        livelyExample() {
          this.inspect(document.body);
        }

        livelyMigrate(oldInstance) {
          this.inspect(oldInstance.targetObject);
          var viewState = oldInstance.getViewState();
          this.setViewState(viewState);
        }
      }

      _export('default', Inspector);

      Object.defineProperty(_recorder_._src_components_tools_lively_inspector_js, 'Inspector', {
        get() {
          return Inspector;
        },

        set(thisIsVererySecretVariableName) {
          _export('default', Inspector = thisIsVererySecretVariableName);

          return true;
        },

        enumerable: true,
        configurable: true
      });
    }
  };
});