System.register(['reactive-jsx', './html.js', './graphics.js', 'src/client/viewnav.js', 'src/client/layout.js', 'src/components/widgets/lively-window.js', 'src/client/morphic/snapping.js', 'src/client/info.js', 'src/external/lodash/lodash.js', 'src/client/rasterize.js', 'src/client/favorites.js', 'src/client/vivide/utils.js', 'src/client/vivide/scripts/loading.js'], function (_export, _context) {
  "use strict";

  var _attributeStringLiteral, _childElement, _children, _attributeExpression, _attributes, _element, _addSourceLocation, html, pt, ViewNav, Layout, Windows, Grid, Info, _, Rasterize, Favorites, applicationFolder, createView;

  return {
    setters: [function (_reactiveJsx) {
      _attributeStringLiteral = _reactiveJsx.attributeStringLiteral;
      _childElement = _reactiveJsx.childElement;
      _children = _reactiveJsx.children;
      _attributeExpression = _reactiveJsx.attributeExpression;
      _attributes = _reactiveJsx.attributes;
      _element = _reactiveJsx.element;
      _addSourceLocation = _reactiveJsx.addSourceLocation;
    }, function (_htmlJs) {
      html = _htmlJs.default;
    }, function (_graphicsJs) {
      pt = _graphicsJs.pt;
    }, function (_srcClientViewnavJs) {
      ViewNav = _srcClientViewnavJs.default;
    }, function (_srcClientLayoutJs) {
      Layout = _srcClientLayoutJs.default;
    }, function (_srcComponentsWidgetsLivelyWindowJs) {
      Windows = _srcComponentsWidgetsLivelyWindowJs.default;
    }, function (_srcClientMorphicSnappingJs) {
      Grid = _srcClientMorphicSnappingJs.Grid;
    }, function (_srcClientInfoJs) {
      Info = _srcClientInfoJs.default;
    }, function (_srcExternalLodashLodashJs) {
      _ = _srcExternalLodashLodashJs;
    }, function (_srcClientRasterizeJs) {
      Rasterize = _srcClientRasterizeJs.default;
    }, function (_srcClientFavoritesJs) {
      Favorites = _srcClientFavoritesJs.default;
    }, function (_srcClientVivideUtilsJs) {
      applicationFolder = _srcClientVivideUtilsJs.applicationFolder;
    }, function (_srcClientVivideScriptsLoadingJs) {
      createView = _srcClientVivideScriptsLoadingJs.createView;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._src_client_contextmenu_js = _recorder_._src_client_contextmenu_js || {};
      Object.defineProperty(_recorder_._src_client_contextmenu_js, 'html', {
        get() {
          return html;
        },

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        enumerable: true,
        configurable: true
      });


      // import lively from './lively.js'; #TODO resinsert after we support cycles again

      class ContextMenu {

        constructor(target, optItems) {
          this.target = target;
          this.items = optItems;
        }

        openIn(container, evt, target, worldContext) {
          return ContextMenu.openIn(container, evt, target, worldContext, this.items);
        }

        static hide() {
          if (this.menu) this.menu.remove();
          lively.removeEventListener("contextMenu", document.documentElement);
          delete this.menu;
        }

        static visible() {
          return this.menu && this.menu.parentElement;
        }

        static openComponentInWindow(name, evt, worldContext, extent) {
          this.hide();
          return lively.openComponentInWindow(name, lively.getPosition(evt), extent, worldContext).then(comp => {
            if (extent) {
              lively.setExtent(comp.parentElement, extent);
            }
            comp.focus();
            return comp;
          });
        }

        static get windowExtentOffeset() {
          return pt(2, 21);
        }

        static async openInWindow(comp) {
          // wrap an existing component in a window
          var pos = lively.getPosition(comp);
          var w = await _addSourceLocation(lively.create("lively-window"), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
            end: {
              column: 48,
              line: 68
            },
            start: {
              column: 18,
              line: 68
            }
          });
          lively.setGlobalPosition(w, lively.getGlobalPosition(comp));
          w.appendChild(comp);
          lively.setPosition(comp, pt(0, 0));
          lively.setExtent(w, lively.getExtent(comp).addPt(this.windowExtentOffeset));
          comp.style.position = "";
          comp.style.width = "100%";
          comp.style.height = "100%";
          if (comp.id) w.setAttribute("title", comp.id);
          return w;
        }

        static async stripWindow(comp, evt) {
          var w = comp.parentElement;
          if (w.localName !== "lively-window") {
            throw new Error("Could not strip window, because there is none");
          }
          var extent = lively.getExtent(w).subPt(this.windowExtentOffeset);
          w.parentElement.appendChild(comp);
          lively.setGlobalPosition(comp, lively.getGlobalPosition(w));
          lively.setExtent(comp, extent.addPt(this.windowExtentOffeset));
          w.remove();
          return comp;
        }

        // #important
        static targetMenuItems(target) {
          var wasEditable = target.contentEditable == "true";
          var wasDisabled = target.disabled == "true";
          var targetInWindow = target.parentElement && target.parentElement.tagName == 'LIVELY-WINDOW';
          return [["show", () => {
            this.hide();
            lively.showElement(target);
          }, "", '<i class="fa fa-eye" aria-hidden="true"></i>'], ["open halo", [["self", () => {
            lively.showHalo(target);
          }], ["parents", lively.allParents(target, [], true).map(ea => [lively.elementToCSSName(ea), () => {
            lively.showHalo(ea);
          }])], ["children", Array.from(target.childNodes).map(ea => [lively.elementToCSSName(ea), () => {
            lively.showHalo(ea);
          }])]], "", '<i class="fa fa-search" aria-hidden="true"></i>'], ["browse template source", evt => {
            this.hide();
            lively.showSource(target, evt);
          }, "", '<i class="fa fa-file-image-o" aria-hidden="true"></i>'], ["browse class source", evt => {
            this.hide();
            lively.showClassSource(target, evt);
          }, "", '<i class="fa fa-file-code-o" aria-hidden="true"></i>'],
          // ["trace", (evt) => {
          //    System.import("src/client/tracer.js").then(tracer => {
          //      tracer.default.traceObject(target);
          //    });
          //    this.hide();
          // }],
          ["remove", () => {
            target.remove();
            this.hide();
          }, "", '<i class="fa fa-trash-o" aria-hidden="true"></i>'], ["go back", () => {
            target.parentElement.insertBefore(target, target.parentElement.childNodes[0]);
            this.hide();
          }, "", '<i class="fa fa-backward" aria-hidden="true"></i>'], ["come forward", () => {
            target.parentElement.appendChild(target);
            this.hide();
          }, "", '<i class="fa fa-forward" aria-hidden="true"></i>'], ["make space", () => {
            Layout.makeLocalSpace(target);
            this.hide();
          }, "", '<i class="fa fa-file-code-o" aria-hidden="true"></i>'], [wasEditable ? "make uneditable" : "make editable", () => {
            this.hide();
            target.contentEditable = !wasEditable;
          }, "", '<i class="fa fa-pencil" aria-hidden="true"></i>'], [wasDisabled ? "enable" : "disable", () => {
            this.hide();
            target.disabled = !wasDisabled;
          }, "", '<i class="fa fa-bolt" aria-hidden="true"></i>'], [targetInWindow ? "strip window" : "open in window", evt => {
            this.hide();
            targetInWindow ? ContextMenu.stripWindow(target, evt) : ContextMenu.openInWindow(target, evt);
          }, "", '<i class="fa fa-window-restore" aria-hidden="true"></i>'], ["edit", async () => {
            if (target instanceof Image) {
              var url = target.getAttribute("src");
              if (url.match(/^data\:/)) {
                var editor = await lively.openComponentInWindow("lively-image-editor");
                editor.setTarget(target);
              } else {
                lively.openBrowser(url, true);
              }
            } else {
              lively.openInspector(target);
            }
          }, "", '<i class="fa fa-file-image-o" aria-hidden="true"></i>'], target.localName == "lively-file" ? ["become content", async () => {
            if (target.url && target.name.match(/\.png$/)) {
              var element = await _element('img', _attributes(_attributeExpression('id', target.name)), _children(), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
                end: {
                  column: 63,
                  line: 199
                },
                start: {
                  column: 35,
                  line: 199
                }
              });
              element.src = target.url;
              target.parentElement.appendChild(element);
              lively.setPosition(element, lively.getPosition(target));
              target.remove();
            } else {
              lively.notify("not supported");
            }
          }, "", '<i class="fa fa-file-image-o" aria-hidden="true"></i>'] : ["become file", async () => {
            if (target.src) {
              var name = this.id || (await lively.prompt("convert to file named: ", "newfile.png"));
              var element = await _element('lively-file', _attributes(_attributeExpression('name', name)), _children(), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
                end: {
                  column: 74,
                  line: 213
                },
                start: {
                  column: 35,
                  line: 213
                }
              });
              target.parentElement.appendChild(element);

              element.setAttribute("url", (await lively.files.readBlobAsDataURL((await fetch(target.src).then(r => r.blob())))));
              lively.setPosition(element, lively.getPosition(target));

              target.remove();
            } else {
              lively.notify("not supported");
            }
          }, "", '<i class="fa fa-file-image-o" aria-hidden="true"></i>'], ["save as png ...", async () => {
            var previewAttrName = "data-lively-preview-src";
            var url = target.getAttribute(previewAttrName);
            if (!url) {
              var name = target.id || target.textContent.slice(0, 30) || target.tagName.toLowerCase();
              url = lively4url + "/" + name + ".png";
            }
            url = await lively.prompt("save as png", url);
            if (url) {
              target.setAttribute(previewAttrName, url);
              if (target instanceof Image) {
                await lively.files.copyURLtoURL(target.src, url);
              } else {
                await Rasterize.elementToURL(target, url);
              }
              lively.notify("saved image to ", url, 10, () => {
                lively.openBrowser(url);
              });
            }
          }, "", '<i class="fa fa-file-image-o" aria-hidden="true"></i>'], ["save as...", async () => {
            var partName = target.getAttribute("data-lively-part-name") || target.id || "element";
            var name = await lively.prompt("save element as: ", `src/parts/${partName}.html`);
            if (!name) return;
            // var name = "foo.html"
            var url = name;

            if (!url.match(/https?:\/\//)) {
              if (url.match(/^[a-zA-Z0-9]+\:/)) {
                // url = lively.swxURL(url)
              } else {
                url = lively4url + "/" + url;
              }
            }
            var source = "";
            if (name.match(/\.html$/)) {
              source = target.outerHTML;
            } else if (name.match(/\.svg/)) {
              var element = target.querySelector("svg");
              if (!element) throw new Error("Could not find SVG elment in target");
              var extent = lively.getExtent(element);
              var tmp = _addSourceLocation(document.createElement("div"), {
                file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
                end: {
                  column: 49,
                  line: 272
                },
                start: {
                  column: 20,
                  line: 272
                }
              });
              tmp.innerHTML = element.outerHTML;
              tmp.querySelector("svg").setAttribute("width", extent.x);
              tmp.querySelector("svg").setAttribute("height", extent.y);
              source = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' + tmp.innerHTML;
            } else if (name.match(/\.png/)) {
              if (target.tagName == "IMG") element = target;else target.querySelector("img");
              if (!element) throw new Error("Could not find img elment in target");
              // var extent = lively.getExtent(element)
              // var tmp = document.createElement("div")
              // tmp.innerHTML = element.outerHTML
              source = await fetch(element.src).then(r => r.blob());
            } else {
              // fall back to text
              source = target.outerText;
            }
            await lively.files.saveFile(url, source);
            lively.notify("saved ", name, 10, () => {
              lively.openBrowser(url);
            });
          }, "", '<i class="fa fa-file-o" aria-hidden="true"></i>']];
        }

        static openCenteredAt(morph, worldContext, evt) {
          worldContext.appendChild(morph);
          lively.setGlobalPosition(morph, pt(evt.clientX, evt.clientY).subPt(lively.getExtent(morph).scaleBy(0.5)));
        }

        static preferenceEntry(preferenceKey) {
          let enabledIcon = function (enabled) {
            return enabled ? '<i class="fa fa-check-square-o" aria-hidden="true"></i>' : '<i class="fa fa-square-o" aria-hidden="true"></i>';
          };

          return [lively.preferences.shortDescription(preferenceKey), (evt, item) => {
            evt.stopPropagation();
            evt.preventDefault();

            if (lively.preferences.get(preferenceKey)) {
              lively.preferences.disable(preferenceKey);
            } else {
              lively.preferences.enable(preferenceKey);
            }
            item.querySelector(".icon").innerHTML = enabledIcon(lively.preferences.get(preferenceKey));
          }, "", enabledIcon(lively.preferences.get(preferenceKey))];
        }

        // #important
        static worldMenuItems(worldContext) {
          var items = [["Workspace", evt => {
            this.hide();
            lively.openWorkspace("", evt.clientX && lively.getPosition(evt), worldContext);
          }, "CMD+K", '<i class="fa fa-window-maximize" aria-hidden="true"></i>'], ["Browse/Edit", async evt => {
            var container = _.last(document.querySelectorAll("lively-container"));
            this.openComponentInWindow("lively-container", evt, worldContext, pt(1210, 700)).then(comp => {
              if (container) comp.followPath("" + container.getURL());else comp.followPath(lively4url + "/");
            });
          }, "CMD+SHIFT+B", '<i class="fa fa-cogs" aria-hidden="true"></i>'],
          // ["File Editor", evt => this.openComponentInWindow("lively-editor", evt)],
          // ["File Browser", evt => this.openComponentInWindow("lively-file-browser", evt)],
          ["Component Bin", evt => this.openComponentInWindow("lively-component-bin", evt, worldContext, pt(950, 660)), "CMD+O", '<i class="fa fa-th" aria-hidden="true"></i>'], ["Insert", [["Text", evt => {
            var morph = _addSourceLocation(document.createElement("div"), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
              end: {
                column: 52,
                line: 354
              },
              start: {
                column: 23,
                line: 354
              }
            });
            morph.classList.add("lively-text");

            morph.innerHTML = "Hello";
            morph.contentEditable = true;
            morph.style.width = "100px";
            worldContext.appendChild(morph);
            this.openCenteredAt(morph, worldContext, evt);
            lively.hand.startGrabbing(morph, evt);
            if (worldContext === document.body) {
              morph.classList.add("lively-content");
            }
            this.hide();
          }, "", '<i class="fa fa-font" aria-hidden="true"></i>'], ["Rectangle", evt => {
            var morph = _addSourceLocation(document.createElement("div"), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
              end: {
                column: 52,
                line: 369
              },
              start: {
                column: 23,
                line: 369
              }
            });
            morph.style.width = "200px";
            morph.style.height = "100px";
            morph.style.border = "1px solid black";

            this.openCenteredAt(morph, worldContext, evt
            // morph.style.backgroundColor = "blue";
            );if (worldContext === document.body) {
              morph.classList.add("lively-content");
            }
            morph.style.backgroundColor = 'rgba(40,40,80,0.5)';
            lively.hand.startGrabbing(morph, evt);

            this.hide();
          }, "", '<i class="fa fa-square-o" aria-hidden="true"></i>'], ["Slider", async evt => {
            var morph = _addSourceLocation(document.createElement("input"), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
              end: {
                column: 54,
                line: 386
              },
              start: {
                column: 23,
                line: 386
              }
            });
            morph.setAttribute('type', 'range');

            worldContext.appendChild(morph);
            this.openCenteredAt(morph, worldContext, evt);
            lively.hand.startGrabbing(morph, evt);
            if (worldContext === document.body) {
              morph.classList.add("lively-content");
            }
            this.hide();
          }, "", '<i class="fa fa-sliders" aria-hidden="true"></i>'], ["Drawing", async evt => {
            var morph = _addSourceLocation(document.createElement("lively-drawboard"), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
              end: {
                column: 65,
                line: 398
              },
              start: {
                column: 23,
                line: 398
              }
            });
            morph.setAttribute("width", "400px");
            morph.setAttribute("height", "400px");
            await lively.components.openIn(worldContext, morph);

            this.openCenteredAt(morph, worldContext, evt);
            lively.hand.startGrabbing(morph, evt
            // morph.style.backgroundColor = "blue";
            );if (worldContext === document.body) {
              morph.classList.add("lively-content");
            }
            morph.style.backgroundColor = 'rgb(255,250,205)';
            this.hide();
          }, "", '<i class="fa fa-pencil-square-o" aria-hidden="true"></i>'], ["Button", async evt => {
            var morph = await lively.openPart("button");
            this.openCenteredAt(morph, worldContext, evt);
            lively.hand.startGrabbing(morph, evt
            // morph.style.backgroundColor = "blue";
            );if (worldContext === document.body) {
              morph.classList.add("lively-content");
            }
            this.hide();
          }], ["Path", async evt => {
            var morph = await lively.openPart("path");
            this.openCenteredAt(morph, worldContext, evt);
            lively.hand.startGrabbing(morph, evt);
            morph.classList.add("lively-content");
            this.hide();
          }]]], ["Tools", [
          // ["Services", evt => this.openComponentInWindow("lively-services", evt)],
          // ["Terminal", evt => this.openComponentInWindow("lively-terminal", evt)],
          ["Inspector", evt => lively.openInspector(document.body)], ["Console", evt => this.openComponentInWindow("lively-console", evt, worldContext), "CMD+J", '<i class="fa fa-terminal" aria-hidden="true"></i>'], ["Search", evt => this.openComponentInWindow("lively-search", evt, worldContext), "CMD+SHIFT+F", '<i class="fa fa-search" aria-hidden="true"></i>'],
          // ['Debugger', evt => lively.openDebugger().then( cmp), 
          //   "", '<i class="fa fa-chrome" aria-hidden="true"></i>'],
          ["Test Runner", evt => this.openComponentInWindow("lively-testrunner", evt, worldContext), "", '<i class="fa fa-check-square-o" aria-hidden="true"></i>'], ["Drawboard", evt => this.openComponentInWindow("lively-drawboard", evt, worldContext), "", '<i class="fa fa-pencil-square-o" aria-hidden="true"></i>'], ["Storage Setup", evt => this.openComponentInWindow("lively-filesystems", evt, worldContext), "", '<i class="fa fa-cloud" aria-hidden="true"></i>'], ["Graph Control", evt => this.openComponentInWindow("graph-control", evt, worldContext), "Ctrl+Alt+G", '<i class="fa fa-globe" aria-hidden="true"></i>'], ["Diary", async evt => {
            const diary = await this.openComponentInWindow("research-diary", evt, worldContext);
            diary.selectFirstEntry();
          }, "Ctrl+Alt+D", '<i class="fa fa-book" aria-hidden="true"></i>'], ["Quicklinks", async evt => {
            var morph = await lively.openPart("quicklinks");
            lively.setPosition(morph, lively.pt(0, 0), "fixed");
            this.hide();
          }], ["X-Ray", async evt => {
            var morph = await lively.openPart("WorldMirror");
            lively.setGlobalPosition(morph, lively.getPosition(evt));
            this.hide();
          }, undefined, '<i class="fa fa-tv" aria-hidden="true"></i>'], ["X-Ray Events", async evt => {
            var morph = await lively.openPart("XRayEvents");
            lively.setGlobalPosition(morph, lively.getPosition(evt));
            this.hide();
          }, undefined, '<i class="fa fa-tv" aria-hidden="true"></i>'], ["JSX-Ray ", async evt => {
            const jsxRay = await _addSourceLocation(lively.create("jsx-ray", document.body), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
              end: {
                column: 71,
                line: 471
              },
              start: {
                column: 32,
                line: 471
              }
            });
            lively.setGlobalPosition(jsxRay, lively.getPosition(evt));
            this.hide();
          }, undefined, '<i class="fa fa-tv" aria-hidden="true"></i>'], ["AST Explorer", evt => this.openComponentInWindow("lively-ast-explorer", evt, worldContext), undefined, '<i class="fa fa-tree" aria-hidden="true"></i>'], ["Invalidate caches", async evt => {
            lively4invalidateFileCaches();
          }], ["Terminal", evt => this.openComponentInWindow("lively-xterm", evt, worldContext), "", '<i class="fa fa-terminal" aria-hidden="true"></i>'], ["Chrome Service-Workers", async evt => {
            // does not work... security?
            // window.open("chrome://inspect/#service-workers")
            // fuck it... just display it... better that nothing
            var workspace = await lively.openWorkspace("chrome://inspect/#service-workers");
            workspace.parentElement.setAttribute("title", "open this in a tab...");
            workspace.mode = "text";
          }], ["Handwriting", async evt => {
            var morph = await this.openComponentInWindow("lively-handwriting", evt, worldContext);

            lively.setExtent(morph.parentElement, lively.getExtent(morph).addPt(pt(0, 20))
            // lively.setPosition(morph, lively.pt(0,0), "fixed")
            // morph.style.bottom = "0px"
            // morph.style.right= "0px"
            );this.hide();
          }], ["Change Graph", async evt => {
            lively.openBrowser(lively4url + "/doc/files/changesgraph.md");
            this.hide();
          }], ["BP2019 Workspace", async evt => {
            const workspace = await this.openComponentInWindow("bp2019-workspace", evt, worldContext);
          }, "", '<i class="fa fa-terminal" aria-hidden="true"></i>'], ["MLE IDE", evt => {
            this.openComponentInWindow("lively-mle-ide", evt, worldContext).then(w => {
              w.parentNode.style.height = "100vh";w.parentNode.style.width = "100vw";lively.setGlobalPosition(w.parentNode, [0, 0]);
            });
          }, "", '<i class="fa fa-database" aria-hidden="true"></i>']], undefined, '<i class="fa fa-wrench" aria-hidden="true"></i>'], ["Server", [["Invalidate Transpiled Files", async evt => {

            const FilesCaches = await System.import("src/client/files-caches.js");
            var list = await FilesCaches.invalidateTranspiledFiles();
            var workspace = await lively.openWorkspace("" + list);
            workspace.parentElement.setAttribute("title", "Purged Transpiled Files");
            workspace.mode = "text";
          }], ["Purged Transpiled Files WARNING! SLOW!", async evt => {

            const FilesCaches = await System.import("src/client/files-caches.js");
            var list = await FilesCaches.purgeTranspiledFiles();
            var workspace = await lively.openWorkspace("" + list.join("\n"));
            workspace.parentElement.setAttribute("title", "Purged Transpiled Files");
            workspace.mode = "text";
          }], ["Update Cached Bootfiles", async evt => {

            const FilesCaches = await System.import("src/client/files-caches.js");
            var list = await FilesCaches.updateCachedFilesList();
            lively.openBrowser(lively4url + "/.lively4bootfilelist", true);
          }]], undefined, '<i class="fa fa-wrench" aria-hidden="true"></i>'], ["Favorites", Favorites.get().then(urls => {
            return urls.map(url => [url.replace(/\/index.md$/i, '').replace(/.*\//i, ''), // only files names
            async evt => {
              const comp = await this.openComponentInWindow("lively-container", evt, worldContext, pt(1000, 600));
              return comp.editFile(url);
            }, _element('span', _attributes(_attributeExpression('click', function (event) {
              const li = lively.query(this, 'li');
              if (li) {
                li.remove();
              }
              event.stopPropagation();
              Favorites.remove(url);
            })), _children(_childElement(_element('i', _attributes(_attributeStringLiteral('class', 'fa fa-close'), _attributeStringLiteral('aria-hidden', 'true')), _children(), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
              end: {
                column: 63,
                line: 549
              },
              start: {
                column: 17,
                line: 549
              }
            }))), {
              file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
              end: {
                column: 70,
                line: 549
              },
              start: {
                column: 14,
                line: 544
              }
            }), undefined]);
          }), undefined, '<i class="fa fa-star" aria-hidden="true"></i>'], ["Parts", fetch(lively4url + "/src/parts", {
            method: "OPTIONS"
          }).then(r => r.json()).then(json => json.contents.filter(ea => ea.name.match(/\.html/)).map(ea => {
            var partName = "" + ea.name.replace(/\.html/, "");
            return [partName, async evt => {
              var morph = await lively.openPart(partName);
              lively.setGlobalPosition(morph, lively.getPosition(evt));
              lively.hand.startGrabbing(morph, evt);
              morph.classList.add("lively-content");
              this.hide();
            }];
          }).concat([["Vivide Applications", lively.files.statFile(applicationFolder).then(r => (JSON.parse(r).contents || []).filter(({ type }) => type === 'file').map(({ name }) => [name.split('.')[0], async () => {
            const content = JSON.parse((await lively.files.loadFile(applicationFolder + name)));
            const n = name.split('.')[0];
            await createView(content, false, true, n);
          }]))]])), undefined, '<i class="fa fa-th-large" aria-hidden="true"></i>'], ["Windows", Windows.allWindows().map(ea => ["" + ea.getAttribute("title"), () => lively.gotoWindow(ea), _element('span', _attributes(_attributeExpression('click', function (event) {
            ea.remove();
            const li = lively.query(this, 'li');
            if (li) {
              li.remove();
            }
            event.stopPropagation();
          })), _children(_childElement(_element('i', _attributes(_attributeStringLiteral('class', 'fa fa-close'), _attributeStringLiteral('aria-hidden', 'true')), _children(), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
            end: {
              column: 59,
              line: 591
            },
            start: {
              column: 13,
              line: 591
            }
          }))), {
            file: 'https://lively-kernel.org/lively4/lively4-bp2019/src/client/contextmenu.js',
            end: {
              column: 66,
              line: 591
            },
            start: {
              column: 11,
              line: 584
            }
          }), ea.getAttribute("icon")]).concat([["Close all", async () => {
            if (await lively.confirm('Close all windows?')) {
              document.body.querySelectorAll('lively-window').forEach(w => w.remove());
            }
          }]]), undefined, '<i class="fa fa-window-restore" aria-hidden="true"></i>'], ["View", [["Reset View", () => ViewNav.resetView(), "", '<i class="fa fa-window-restore" aria-hidden="true"></i>'], !document.webkitIsFullScreen ? ["Enter Fullscreen", () => {
            document.documentElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
          }, "F11", '<i class="fa fa-arrows-alt" aria-hidden="true"></i>'] : ["Leave Fullscreen", () => document.webkitCancelFullScreen(), "F11", '<i class="fa fa-times-circle-o" aria-hidden="true"></i>'], ["Gather Windows", () => {
            var pos = pt(0, 0);
            _.sortBy(worldContext.querySelectorAll(":scope > lively-window"), ea => {
              return getComputedStyle(ea).zIndex;
            }).forEach(ea => {
              lively.setPosition(ea, pos);
              pos = pos.addPt(pt(20, 20));
            });
          }, "", '<i class="fa fa-window-restore" aria-hidden="true"></i>'], ["Explode Windows", () => {
            Layout.expandUntilNoIntersectionsExplosion();
          }, "", '<i class="fa fa-window-restore" aria-hidden="true"></i>'], ["Show Windows", () => {
            var pos = pt(0, 0);
            var windowsByWidth = _.groupBy(document.body.querySelectorAll("lively-window"), ea => ea.clientWidth);
            Object.keys(windowsByWidth).forEach(width => {
              windowsByWidth[width].forEach(ea => {
                lively.setPosition(ea, pos);
                pos = pos.addPt(pt(0, Math.max(lively.getExtent(ea).y, 50) + 10));
              });
              pos = pt(pos.x + Math.min(1000, Number(width)), 0);
            });
          }, "", '<i class="fa fa-window-restore" aria-hidden="true"></i>'], ["Snap All to Grid Now", () => {
            Grid.snapAllTopLevelContent();
          }, "", '<i class="fa fa-th" aria-hidden="true"></i>']]], ["Documentation", [["Keyboard Shortcuts", () => {
            lively.openBrowser(lively4url + "/doc/manual/shortcuts.md");
          }, "", '<i class="fa fa-file-text-o" aria-hidden="true"></i>'], ["Devdocs.io", evt => {
            this.openComponentInWindow("lively-help", evt, worldContext);
          }, "CMD+H", '<i class="fa fa-book" aria-hidden="true"></i>'], ["Docs", evt => {
            this.openComponentInWindow("lively-container", evt, worldContext).then(comp => {
              comp.followPath(lively4url + "/doc/index.md");
            });
          }, "", '<i class="fa fa-file-text-o" aria-hidden="true"></i>'], ["Vivide CheatSheet", evt => {
            this.openComponentInWindow("lively-container", evt, worldContext).then(comp => {
              comp.followPath(lively4url + "/src/client/vivide/cheatsheet.md");
            });
          }, undefined, '<i class="fa fa-inbox" aria-hidden="true"></i>'], ["Vivide Scripts", evt => this.openComponentInWindow("lively-container", evt, worldContext).then(comp => comp.followPath(lively4url + "/src/client/vivide/scripts/index.md")), /* shortcut info */undefined, "<i class='fa fa-wrench' aria-hidden='true'></i>"], ["Journal", evt => {
            this.openComponentInWindow("lively-container", evt, worldContext, pt(1000, 600)).then(comp => {
              comp.followPath(lively4url + "/doc/journal/index.md");
            });
          }, "", '<i class="fa fa-file-text-o" aria-hidden="true"></i>'], ["Issues", evt => {
            window.open("https://github.com/LivelyKernel/lively4-core/issues");
          }, undefined, '<i class="fa fa-bug" aria-hidden="true"></i>'], ["Project Board", evt => {
            window.open("https://github.com/LivelyKernel/lively4-core/projects/1");
          }, undefined, '<i class="fa fa-bug" aria-hidden="true"></i>'], ["Module Info", () => {
            Info.showModuleInfo();
          }, undefined, '<i class="fa fa-info" aria-hidden="true"></i>']]], ["Preferences", lively.preferences.listBooleans().map(ea => this.preferenceEntry(ea))], ["Sync Github", evt => this.openComponentInWindow("lively-sync", evt, worldContext, pt(800, 500)), "CMD+SHIFT+G", '<i class="fa fa-github" aria-hidden="true"></i>']];

          if (worldContext !== document.body) {
            items.push(...[["save as ..", () => {
              if (worldContext.onSaveAs) worldContext.onSaveAs();else html.saveCurrentPageAs();
            }], ["Save", () => {
              if (worldContext.onSave) worldContext.onSave();else html.saveCurrentPage();
            }, "CMD+S", '<i class="fa fa-cloud-upload" aria-hidden="true"></i>']]);
          }

          return items;
        }

        static items(target, worldContext = document.body) {
          console.log("[context menu] " + worldContext);
          if (target) {
            return this.targetMenuItems(target);
          } else {
            return this.worldMenuItems(worldContext);
          }
        }

        static openIn(container, evt, target, worldContext, optItems) {
          this.hide();
          this.firstEvent = evt;

          var menu = lively.components.createComponent("lively-menu");
          return lively.components.openIn(container, menu).then(() => {
            if (this.menu) this.menu.remove();
            this.menu = menu;
            if (evt) {
              lively.setGlobalPosition(menu, pt(evt.clientX, evt.clientY));
            }
            // menu.focus()
            lively.focusWithoutScroll(menu);
            menu.openOn(optItems || this.items(target, worldContext), evt

            // defere event registration to prevent closing the menu as it was opened
            );setTimeout(() => {
              lively.addEventListener("contextMenu", document.documentElement, "click", () => {
                this.hide();
              });
            }, 0);

            return menu;
          });
        }
      }

      _export('default', ContextMenu);

      Object.defineProperty(_recorder_._src_client_contextmenu_js, 'ContextMenu', {
        get() {
          return ContextMenu;
        },

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

          return true;
        },

        enumerable: true,
        configurable: true
      });
      if (self.lively && lively.contextmenu) {
        lively.contextmenu = ContextMenu; // make it live...
      }
    }
  };
});