System.register(["reactive-jsx", "src/client/graphics.js", "src/components/halo/lively-halo.js", "src/client/svg.js", "utils", "src/client/morphic/snapping.js", "src/client/morphic/event-helpers.js"], function (_export, _context) {
  "use strict";

  var _addSourceLocation, pt, Halo, SVG, debounce, Grid, events, HaloService, Graffle, __SystemJSRewritingHack;
  _export("default", void 0);
  return {
    setters: [function (_reactiveJsx) {
      _addSourceLocation = _reactiveJsx.addSourceLocation;
    }, function (_srcClientGraphicsJs) {
      pt = _srcClientGraphicsJs.pt;
    }, function (_srcComponentsHaloLivelyHaloJs) {
      Halo = _srcComponentsHaloLivelyHaloJs.default;
      HaloService = _srcComponentsHaloLivelyHaloJs.default;
    }, function (_srcClientSvgJs) {
      SVG = _srcClientSvgJs.default;
    }, function (_utils) {
      debounce = _utils.debounce;
    }, function (_srcClientMorphicSnappingJs) {
      Grid = _srcClientMorphicSnappingJs.Grid;
    }, function (_srcClientMorphicEventHelpersJs) {
      events = _srcClientMorphicEventHelpersJs;
    }],
    execute: function () {
      __SystemJSRewritingHack = {};
      _recorder_._https__lively_kernel_org_lively4_lively4_ansgar_src_client_graffle_js = _recorder_._https__lively_kernel_org_lively4_lively4_ansgar_src_client_graffle_js || {};
      Object.defineProperty(_recorder_._https__lively_kernel_org_lively4_lively4_ansgar_src_client_graffle_js, "pt", {
        get() {
          return pt;
        },
        set(thisIsVererySecretVariableName) {
          pt = thisIsVererySecretVariableName;
          return true;
        },
        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._https__lively_kernel_org_lively4_lively4_ansgar_src_client_graffle_js, "Halo", {
        get() {
          return Halo;
        },
        set(thisIsVererySecretVariableName) {
          Halo = thisIsVererySecretVariableName;
          return true;
        },
        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._https__lively_kernel_org_lively4_lively4_ansgar_src_client_graffle_js, "SVG", {
        get() {
          return SVG;
        },
        set(thisIsVererySecretVariableName) {
          SVG = thisIsVererySecretVariableName;
          return true;
        },
        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._https__lively_kernel_org_lively4_lively4_ansgar_src_client_graffle_js, "debounce", {
        get() {
          return debounce;
        },
        set(thisIsVererySecretVariableName) {
          debounce = thisIsVererySecretVariableName;
          return true;
        },
        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._https__lively_kernel_org_lively4_lively4_ansgar_src_client_graffle_js, "Grid", {
        get() {
          return Grid;
        },
        set(thisIsVererySecretVariableName) {
          Grid = thisIsVererySecretVariableName;
          return true;
        },
        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._https__lively_kernel_org_lively4_lively4_ansgar_src_client_graffle_js, "events", {
        get() {
          return events;
        },
        set(thisIsVererySecretVariableName) {
          events = thisIsVererySecretVariableName;
          return true;
        },
        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._https__lively_kernel_org_lively4_lively4_ansgar_src_client_graffle_js, "HaloService", {
        get() {
          return HaloService;
        },
        set(thisIsVererySecretVariableName) {
          HaloService = thisIsVererySecretVariableName;
          return true;
        },
        enumerable: true,
        configurable: true
      });
      _export("default", Graffle = class Graffle {
        // Graffle.keysDown 
        static load() {
          var _context2;
          lively.removeEventListener("Graffle", document.body);
          lively.removeEventListener("Graffle", document);
          lively.addEventListener("Graffle", document.body, "keydown", evt => {
            this.onKeyDown(evt);
          }, true);
          lively.addEventListener("Graffle", document.body, "keyup", evt => {
            this.onKeyUp(evt);
          }, true);
          lively.removeEventListener("GraffleMouse", document.documentElement);
          lively.addEventListener("GraffleMouse", document.documentElement, "pointerdown", evt => {
            this.onMouseDown(evt);
          }, true);
          lively.addEventListener("GraffleMouse", document.documentElement, "pointermove", evt => {
            this.onMouseMove(evt);
          });
          lively.addEventListener("GraffleMouse", document.documentElement, "pointerup", evt => {
            this.onMouseUp(evt);
          });
          lively.addEventListener("Graffle", document, "selectionchange", evt => {
            this.onSelectionHide(evt);
          });
          lively.addEventListener("Graffle", document, "selectionchange", (_context2 = evt => {
            this.onSelectionChange(evt);
          }, debounce).call(_context2, 600));
          this.keysDown = {};
        }
        static async showStyleBalloon(target) {
          if (!target) {
            return;
          }
          // console.log("show balloon " + target)
          // lively.showElement(target)
          if (!lively.styleBalloon) {
            lively.styleBalloon = await lively.openPart("formatting");
            lively.styleBalloon.style.zIndex = 500;
          }
          document.body.appendChild(lively.styleBalloon);
          // lively.showElement(lively.styleBalloon)

          // console.log("pos " + lively.getClientBounds(target).bottomLeft())
          lively.setClientPosition(lively.styleBalloon, lively.getClientBounds(target).bottomLeft());
        }
        static async hideStyleBalloon() {
          // console.log("hide balloon")
          if (lively.styleBalloon) {
            lively.styleBalloon.remove();

            // lively.styleBalloon = null; // for developing
          }
        }

        static onSelectionHide(evt) {
          // var selection = window.getSelection()
          // if (!document.activeElement || !document.activeElement.isContentEditable) {
          //   if (document.activeElement === document.body) {
          //     this.hideStyleBalloon() 
          //   }
          // } else if (!selection.anchorNode || !selection.isCollapsed) {
          //   this.hideStyleBalloon() 
          // }
          this.hideStyleBalloon();
        }
        static onSelectionChange(evt) {
          var selection = window.getSelection();
          if (!document.activeElement || !document.activeElement.isContentEditable) {
            return;
          }
          if (document.activeElement.shadowRoot) {
            selection = document.activeElement.shadowRoot.getSelection();
          }
          if (selection.anchorNode && !selection.isCollapsed) {
            var element = selection.getRangeAt(0).endContainer.parentElement;
            while (["SPAN", "FONT", "A", "B", "I"].includes(element.tagName)) {
              element = element.parentElement;
            }
            this.showStyleBalloon(element);
          }
        }
        static async onKeyDown(evt) {
          if (!lively.preferences.get("GraffleMode")) return;
          if (!lively.isGlobalKeyboardFocusElement(evt.composedPath()[0])) return;
          var key = String.fromCharCode(evt.keyCode);

          // console.log("" + Date.now() + " down " + key + " " +  evt.altKey)

          this.keysDown[key] = true;
          if (this.specialKeyDown() && !(evt.ctrlKey || evt.metaKey)) {
            lively.selection.disabled = true;
            if (!evt.ctrlKey && !evt.altKey && !evt.altKey) {
              // console.log('disable ' + evt.keyCode)
              evt.stopPropagation();
              evt.preventDefault();
            }
            var hand = await lively.ensureHand();
            if (hand) {
              hand.style.visibility = "visible";
              var info = "";
              // #KeyboardShortcut HOLD-S+Drag create shape
              if (this.keysDown["S"]) {
                info = "shape";
              }
              // #KeyboardShortcut HOLD-C+Drag create connector
              if (this.keysDown["C"]) {
                info = "connect";
              }
              // #KeyboardShortcut HOLD-T+Drag create text
              if (this.keysDown["T"]) {
                info = "text";
              }
              // #KeyboardShortcut HOLD-D+Drag create svg path
              if (this.keysDown["D"]) {
                info = "draw";
              }
              // #KeyboardShortcut HOLD-F+Drag create freehand drawing
              if (this.keysDown["F"]) {
                info = "freehand";
              }
              if (hand.info) hand.info.textContent = info;
              hand.info.style.userSelect = "none";
            }
          }
        }
        static changeFontSize(element, factor) {
          if (element) {
            var fontSize = element.style.fontSize;
            if (!fontSize || !fontSize.match(/%$/)) {
              fontSize = "100%";
            }
            fontSize = "" + Math.round(Number(fontSize.replace(/%/, "")) * factor) + "%";
            element.style.fontSize = fontSize;
            // lively.notify("font size: " +  element.style.fontSize)
          }
        }

        static changeCurrentFontSize(factor) {
          var range = window.getSelection().getRangeAt(0);
          var element = range.commonAncestorContainer.parentElement;
          var oldSize = element.style.fontSize;

          // make a new region 
          document.execCommand("styleWithCSS", true, true);
          document.execCommand("fontSize", true, 1);
          element = window.getSelection().getRangeAt(0).commonAncestorContainer.parentElement;
          element.style.fontSize = oldSize.match("%$") ? oldSize : "100%";
          this.changeFontSize(element, factor);
        }
        static changeTextColor() {
          var color = "orange"; // #TODO make this interactive... 
          var element = window.getSelection().getRangeAt(0).startContainer.parentElement;
          if (element.style.color == color) {
            color = "black"; // TODO how can we unset a color? 
          }

          document.execCommand("styleWithCSS", true, true);
          document.execCommand("foreColor", true, color);
        }
        static changeHiliteColor() {
          var color = "yellow"; // #TODO make this interactive... 
          var element = window.getSelection().getRangeAt(0).startContainer.parentElement;
          if (element.style.color == color) {
            color = "transparent"; // TODO how can we unset a color? 
          }

          document.execCommand("styleWithCSS", true, true);
          document.execCommand("hiliteColor", true, color);
        }
        static async onKeyUp(evt) {
          var key = String.fromCharCode(evt.keyCode);
          this.keysDown[key] = false;

          // console.log("" + Date.now() + " up " + key + " " +  evt.altKey)

          if (key == "D" || key == "C") {
            this.currentPath = null;
            HaloService.showHaloItems();
          }
          lively.selection.disabled = false;
          var hand = await lively.ensureHand();
          if (hand) {
            hand.style.visibility = "hidden";
            if (hand.info) hand.info.textContent = "";
          }
          // if (this.lastElement)
          //   this.lastElement.focus(); // no, we can focus.... and continue typing

          if (evt.altKey && evt.keyCode == 187 /* + */) {
            this.changeCurrentFontSize(1.1);
          }
          if (evt.altKey && evt.keyCode == 189 /* - */) {
            this.changeCurrentFontSize(0.9);
          }
          if (evt.altKey && key == "C") {
            this.changeTextColor();
          }
          if (evt.altKey && key == "H") {
            this.changeHiliteColor();
          }
        }
        static specialKeyDown() {
          return this.keysDown["S"] || this.keysDown["T"] || this.keysDown["C"] || this.keysDown["D"] || this.keysDown["F"];
        }
        static eventPosition(evt) {
          return pt(evt.clientX, evt.clientY);
        }
        static async startShapeDrawing(evt) {
          var shape = _addSourceLocation(document.createElement("div"), {
            file: 'no_file_given',
            end: {
              column: 45,
              line: 236
            },
            start: {
              column: 16,
              line: 236
            }
          });
          shape.style.backgroundColor = "lightgray";
          shape.style.border = "1px solid gray";
          this.openAsLivelyContent(shape, evt);
          return shape;
        }
        static async startTextDrawing(evt) {
          var text = _addSourceLocation(document.createElement("div"), {
            file: 'no_file_given',
            end: {
              column: 44,
              line: 244
            },
            start: {
              column: 15,
              line: 244
            }
          });
          text.textContent = "";
          text.classList.add("lively-text");

          // #TODO move this to CSS as defaults?
          text.style.width = "auto";
          text.style.height = "auto";
          text.style.whiteSpace = "nowrap";
          text.style.padding = "3px";
          text.contentEditable = true;
          this.openAsLivelyContent(text, evt);
          return text;
        }
        static async onMouseDown(evt) {
          if (!this.specialKeyDown()) return;
          evt.stopPropagation();
          evt.preventDefault();
          document.documentElement.style.touchAction = "none";
          this.ensureTargetContainer(evt);
          if (this.keysDown["S"]) {
            await this.startShapeDrawing(evt);
          } else if (this.keysDown["T"]) {
            await this.startTextDrawing(evt);
          } else if (this.keysDown["C"]) {
            await this.startConnectorDrawing(evt);
          } else if (this.keysDown["D"]) {
            await this.startPathDrawing(evt);
          } else if (this.keysDown["F"]) {
            await this.startFreehandDrawing(evt);
          }
        }
        static async startConnectorDrawing(evt) {
          var connector = _addSourceLocation(document.createElement("lively-connector"), {
            file: 'no_file_given',
            end: {
              column: 62,
              line: 279
            },
            start: {
              column: 20,
              line: 279
            }
          });
          await lively.components.openIn(this.targetContainer, connector);

          // var connector = await (<lively-connector></lively-connector>)
          // var connector = await lively.create(lively-connector, this.targetContainer)

          lively.setClientPosition(connector, pt(evt.clientX, evt.clientY));
          window.that = connector;
          HaloService.showHalos(connector);
          let cp = lively.halo.ensureControlPoint(connector.getPath(), 1, true);
          this.currentControlPoint = cp;
          cp.setVerticePosition(pt(0, 0));
          cp.start(evt, connector);
          this.currentPath = connector;
          this.openAsLivelyContent(connector, evt);
          if (cp.targetElement) {
            connector.connectFrom(cp.targetElement);
          }
          connector.connectTo(lively.hand);
          return connector;
        }
        static async startFreehandDrawing(evt) {
          var freehand = await _addSourceLocation(lively.create("lively-drawboard"), {
            file: 'no_file_given',
            end: {
              column: 58,
              line: 302
            },
            start: {
              column: 25,
              line: 302
            }
          });
          freehand.freehand();
          this.currentFreehand = freehand;
          this.openAsLivelyContent(freehand, evt);
          lively.setExtent(freehand, pt(100, 100));
          freehand.onPointerDown(evt);
          return freehand;
        }
        static async startPathDrawing(evt) {
          var continueDrawing = true && this.currentPath;
          if (!this.currentPath) {
            var path = await lively.openPart("path", this.targetContainer);
            this.currentPath = path;
            window.that = path;
            this.openAsLivelyContent(path, evt);
            // split position in global and local part to snap locally...
            var offset = lively.getClientPosition(path.parentElement);
            var pos = pt(evt.clientX, evt.clientY).subPt(offset);
            if (!evt.ctrlKey) {
              pos = Grid.snapPt(pos, 10, 5);
            }
            HaloService.showHalos(path);
            lively.setPosition(path, pos);
          }
          var svgPath = this.currentPath.querySelector("path");
          var vertices = SVG.getPathVertices(svgPath);
          let cp = lively.halo.ensureControlPoint(svgPath, vertices.length - 1);
          this.currentControlPoint = cp;
          if (continueDrawing) {
            cp.addControlPoint();
          } else {
            cp.setVerticePosition(pt(0, 0));
          }
          cp.start(evt, this.currentPath);
          if (continueDrawing) {
            cp.eventOffset = this.lastMouseUpPos; // #ContinueHere 
          }

          return path;
        }
        static openAsLivelyContent(div, evt) {
          div.classList.add("lively-content");
          this.currentElement = div;
          this.targetContainer.appendChild(div);
          var pos = this.eventPosition(evt);
          lively.setClientPosition(div, pos);
          this.lastMouseDown = pos;
          return div;
        }
        static ensureTargetContainer(evt) {
          var targetContainer = evt.composedPath().find(ea => ea.localName == "lively-figure");
          if (!targetContainer) {
            targetContainer = evt.composedPath().find(ea => ea.tagName == "LIVELY-CONTAINER");
          }
          if (targetContainer) {
            lively.showElement(targetContainer);
            this.targetContainer = targetContainer;
          } else {
            this.targetContainer = document.body;
          }
        }
        static onMouseMove(evt) {
          if (this.specialKeyDown()) {
            lively.setClientPosition(lively.hand, pt(evt.clientX - 2, evt.clientY - 2));
          }
          if (this.currentControlPoint) {
            this.currentControlPoint.move(evt);
          }
          if (this.currentFreehand) {
            this.currentFreehand.onPointerMove(evt);
          }
          if (!this.lastMouseDown || !this.currentElement) return;
          var extent = this.eventPosition(evt).subPt(this.lastMouseDown);
          if (!this.currentPath && !this.currentFreehand) {
            lively.setExtent(this.currentElement, extent);
          }
        }
        static onMouseUp(evt) {
          if (!evt) return;
          this.lastMouseUpPos = lively.getPosition(evt);
          if (this.currentControlPoint) {
            this.currentControlPoint.stop(evt);
            if (!this.keysDown["T"]) {
              HaloService.hideHaloItems();
            }
          }
          if (this.currentFreehand) {
            this.currentFreehand.onPointerUp(evt);
            var svg = this.currentFreehand.get("#svg");
            var path = svg.querySelector("path");
            var bounds = SVG.childBounds(svg);
            var p1 = lively.getClientPosition(this.currentFreehand);
            if (!bounds) return;
            var p2 = pt(bounds.x, bounds.y);
            var delta = p2.subPt(p1);
            lively.moveBy(this.currentFreehand, delta);
            lively.moveBy(path, delta.scaleBy(-1));
            lively.setExtent(this.currentFreehand, pt(bounds.width, bounds.height));
            this.currentFreehand = null;
            this.currentElement = null;
            // lively.showElement(svg)

            // lively.setClientPosition(this.currentFreehand, bounds.topLeft())
            // lively.setExtent(this.currentFreehand, pt(bounds.width, bounds.height))
          } else if (this.currentElement) {
            if (this.currentElement.classList.contains("lively-text")) {
              if (!this.keysDown["T"]) {
                this.currentElement.focus();
              }
            }
            this.lastMouseDown = null;
            this.currentElement = null;
            this.lastElement = this.currentElement;
            document.documentElement.style.touchAction = "";
          } else {
            this.lastElement = null;
          }
          this.currentControlPoint = null;
          this.currentConnectFrom = null;
        }
      });
      Object.defineProperty(_recorder_._https__lively_kernel_org_lively4_lively4_ansgar_src_client_graffle_js, "Graffle", {
        get() {
          return Graffle;
        },
        set(thisIsVererySecretVariableName) {
          _export("default", Graffle = thisIsVererySecretVariableName);
          return true;
        },
        enumerable: true,
        configurable: true
      });
      Graffle.load();
    }
  };
});