System.register(['reactive-jsx', 'src/client/vivide/vividescript.js', 'src/client/vivide/utils.js'], function (_export, _context) {
  "use strict";

  var _addSourceLocation, Script, scriptFolder, stepFolder, applicationFolder;

  return {
    setters: [function (_reactiveJsx) {
      _addSourceLocation = _reactiveJsx.addSourceLocation;
    }, function (_srcClientVivideVividescriptJs) {
      Script = _srcClientVivideVividescriptJs.default;
    }, function (_srcClientVivideUtilsJs) {
      scriptFolder = _srcClientVivideUtilsJs.scriptFolder;
      stepFolder = _srcClientVivideUtilsJs.stepFolder;
      applicationFolder = _srcClientVivideUtilsJs.applicationFolder;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._src_client_vivide_scripts_loading_js = _recorder_._src_client_vivide_scripts_loading_js || {};
      Object.defineProperty(_recorder_._src_client_vivide_scripts_loading_js, 'getMatches', {
        get() {
          return getMatches;
        },

        set(thisIsVererySecretVariableName) {
          _export('getMatches', getMatches = thisIsVererySecretVariableName);

          return true;
        },

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

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

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

        set(thisIsVererySecretVariableName) {
          _export('getDetails', getDetails = thisIsVererySecretVariableName);

          return true;
        },

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

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

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

        set(thisIsVererySecretVariableName) {
          _export('openFile', openFile = thisIsVererySecretVariableName);

          return true;
        },

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

        set(thisIsVererySecretVariableName) {
          _export('setScript', setScript = thisIsVererySecretVariableName);

          return true;
        },

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

        set(thisIsVererySecretVariableName) {
          _export('createView', createView = thisIsVererySecretVariableName);

          return true;
        },

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

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

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

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

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

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

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

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

        enumerable: true,
        configurable: true
      });


      let autoGenerated = /(.*-template\.js(on)?$)|(.md?$)/;
      Object.defineProperty(_recorder_._src_client_vivide_scripts_loading_js, 'autoGenerated', {
        get() {
          return autoGenerated;
        },

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

        enumerable: true,
        configurable: true
      });
      const folders = [scriptFolder, stepFolder, applicationFolder];

      Object.defineProperty(_recorder_._src_client_vivide_scripts_loading_js, 'folders', {
        get() {
          return folders;
        },

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

        enumerable: true,
        configurable: true
      });
      let allFiles = () => Promise.all(folders.map(folderURL => lively.files.statFile(folderURL).then(j => JSON.parse(j).contents.filter(({ type }) => type === 'file').filter(({ name }) => !autoGenerated.test(name)).map(({ name }) => folderURL + name))));

      _export('allFiles', allFiles);

      Object.defineProperty(_recorder_._src_client_vivide_scripts_loading_js, 'allFiles', {
        get() {
          return allFiles;
        },

        set(thisIsVererySecretVariableName) {
          _export('allFiles', allFiles = thisIsVererySecretVariableName);

          return true;
        },

        enumerable: true,
        configurable: true
      });
      async function createView(content, createEditor = false, createDependents = false, name) {
        const componentWindow = await lively.openComponentInWindow('vivide-view');
        if (!createDependents) componentWindow.input = JSON.parse(content.inputs);
        const script = await Script.fromJSON(content.script, componentWindow);
        componentWindow.myCurrentScript = script;
        const widget = await _addSourceLocation(lively.create(content.widget), {
          file: 'https://lively-kernel.org/lively4/lively4-augment/src/client/vivide/scripts/loading.js',
          end: {
            column: 52,
            line: 20
          },
          start: {
            column: 23,
            line: 20
          }
        });
        widget.setView(componentWindow);
        await componentWindow.scriptGotUpdated();
        if (createEditor) {
          const scriptEditor = await componentWindow.createScriptEditor();
          scriptEditor.setView(componentWindow);
          await scriptEditor.setScript(script);
        }
        if (createDependents) {
          componentWindow.applicationName = name;
          const inputs = await Promise.all(content.inputSources.map(i => createView(i, false, true, name)));
          inputs.forEach(i => i.connectTo(componentWindow));
          const outputs = await Promise.all(content.outputs.map(o => createView(o, false, true, name)));
          outputs.forEach(o => componentWindow.connectTo(o));
          if (content.inputs && content.inputs && content.inputs.length !== 0) {
            componentWindow.newDataFromUpstream(content.inputs);
          }
        }
        return componentWindow;
      }

      _export('createView', createView);

      async function setScript(url, view) {
        const config = await fetch(url).then(f => f.json());
        const widget = await _addSourceLocation(lively.create(config.widget), {
          file: 'https://lively-kernel.org/lively4/lively4-augment/src/client/vivide/scripts/loading.js',
          end: {
            column: 51,
            line: 43
          },
          start: {
            column: 23,
            line: 43
          }
        });
        widget.setView(view);
        const script = await Script.fromJSON(config.script, view);
        view.myCurrentScript = script;
        const scriptEditor = await view.createScriptEditor();
        scriptEditor.setView(view);
        await scriptEditor.setScript(script);
        await view.scriptGotUpdated();
      }

      _export('setScript', setScript);

      async function openFile(file, createEditor, createDependents) {
        const filepath = file.split('/');
        const content = JSON.parse((await lively.files.loadFile(file)));
        const name = filepath[filepath.length - 1].split('.')[0];
        await createView(content, createEditor, createDependents, name);
      }

      _export('openFile', openFile);

      function replace(obj, key, rep = true) {
        return typeof obj[key] === "undefined" ? rep ? `No ${key} provided` : undefined : obj[key];
      }

      function getDetails(file, rep = false) {
        return fetch(file).then(r => r.json()).then(j => ({
          scheme: replace(j, "inScheme", true),
          description: replace(j, "description", rep)
        }));
      }

      _export('getDetails', getDetails);

      function calcScore(scheme, toFit) {
        if (!(scheme && toFit)) return 0;
        if (scheme === toFit) return 100;
        let score = 0;
        Object.keys(toFit).forEach(key => {
          if (scheme[key]) {
            score++;
            if (toFit[key] === scheme[key]) {
              score++;
            }
          }
        });
        return score / Object.keys(toFit).length;
      }

      async function getMatches(scheme, search) {
        const all = await allFiles();
        const details = await Promise.all(all[0].map(f => getDetails(f).then(d => ({ name: f, details: d }))));
        return details.filter(f => search ? f.name.includes(search) : true).sort((a, b) => calcScore(JSON.parse(scheme), b.details.scheme) - calcScore(JSON.parse(scheme), a.details.scheme)).filter((_, i) => i < 3).map(f => ({
          name: f.name.split('/')[f.name.split('/').length - 1].split('.')[0],
          url: f.name
        }));
      }

      _export('getMatches', getMatches);
    }
  };
});