System.register(['plugin-babel', './workspaces.js'], function (_export, _context) {
  "use strict";

  var babelTranslate, workspaces;
  return {
    setters: [function (_pluginBabel) {
      babelTranslate = _pluginBabel.translate;
    }, function (_workspacesJs) {
      workspaces = _workspacesJs;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._src_client_workspace_loader_js = _recorder_._src_client_workspace_loader_js || {};
      Object.defineProperty(_recorder_._src_client_workspace_loader_js, 'translate', {
        get() {
          return translate;
        },

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

          return true;
        },

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

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

          return true;
        },

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

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

          return true;
        },

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

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

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

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

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

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

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

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

        enumerable: true,
        configurable: true
      });


      const WORKSPACE_REGEX = /^\/?workspace(async)?(js)?:/;

      Object.defineProperty(_recorder_._src_client_workspace_loader_js, 'WORKSPACE_REGEX', {
        get() {
          return WORKSPACE_REGEX;
        },

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

        enumerable: true,
        configurable: true
      });
      function parseId(load) {
        return decodeURI(load.name.replace(WORKSPACE_REGEX, ''));
      }

      function isWorkspace(load) {
        return load.name.match(WORKSPACE_REGEX);
      }

      async function locate(load) {
        // does the resolving relative workspace urls belong here? 
        // it does not seem to work, but we have to do it here... because of transitive relative urls... etc... and we do want to get the same reference of existing modules...

        // console.log('WORKSPACE LOADER locate', load.address);

        if (isWorkspace(load)) {
          var id = parseId(load);
          var m = id.match(/^([^/]+\/)(.*)$/);
          var baseId = m[1];
          var targetModule = m[2];

          if (targetModule.match(/\.js$/)) {
            return new URL(lively4url).protocol + "//" + targetModule; // we stripped the HTTP(S) earlier...
          }
        }
        return;
      }

      _export('locate', locate);

      async function fetch(load, fetch) {
        // console.log('WORKSPACE LOADER fetch', load.address);
        if (isWorkspace(load)) {
          var id = parseId(load);
          // console.log(`fetch workspace code for id: ${id}`);
          var code = workspaces.getCode(load.name);

          if (!code) {
            // we have a relative url that resolved to a real url...


            if (!load.address.match(WORKSPACE_REGEX)) {
              return fetch.call(this, load);
            }
          }

          if (!code) {
            throw new Error("workspace loader: no code for " + id);
          }

          // console.log('Found code', code)
          return Promise.resolve(code);
        } else if (load.name.endsWith('.js')) {
          return fetch.call(this, load);
        } else {
          throw new Error('unknown type of code evaluation: ' + load.name);
        }
      }

      _export('fetch', fetch);

      function translate(...args) {
        // console.log('translate', ...args);
        var result = babelTranslate.apply(this, args);
        return result;
      }

      _export('translate', translate);
    }
  };
});