System.register(['lang', './utils.js', 'src/client/reactive/active-expression/active-expression.js', 'systemjs-babel-build', 'babel-plugin-syntax-jsx', 'babel-plugin-syntax-do-expressions', 'babel-plugin-syntax-function-bind', 'babel-plugin-syntax-async-generators', 'src/client/bound-eval.js', 'active-expression-rewriting'], function (_export, _context) {
  "use strict";

  var extend, AExprRegistry, babelDefault, jsx, doExpressions, functionBind, asyncGenerators, boundEval, aexpr;
  return {
    setters: [function (_lang) {}, function (_utilsJs) {
      extend = _utilsJs.extend;
    }, function (_srcClientReactiveActiveExpressionActiveExpressionJs) {
      AExprRegistry = _srcClientReactiveActiveExpressionActiveExpressionJs.AExprRegistry;
    }, function (_systemjsBabelBuild) {
      babelDefault = _systemjsBabelBuild.default;
    }, function (_babelPluginSyntaxJsx) {
      jsx = _babelPluginSyntaxJsx.default;
    }, function (_babelPluginSyntaxDoExpressions) {
      doExpressions = _babelPluginSyntaxDoExpressions.default;
    }, function (_babelPluginSyntaxFunctionBind) {
      functionBind = _babelPluginSyntaxFunctionBind.default;
    }, function (_babelPluginSyntaxAsyncGenerators) {
      asyncGenerators = _babelPluginSyntaxAsyncGenerators.default;
    }, function (_srcClientBoundEvalJs) {
      boundEval = _srcClientBoundEvalJs.default;
    }, function (_activeExpressionRewriting) {
      aexpr = _activeExpressionRewriting.default;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._src_client_lang_lang_ext_js = _recorder_._src_client_lang_lang_ext_js || {};
      Object.defineProperty(_recorder_._src_client_lang_lang_ext_js, 'extend', {
        get() {
          return extend;
        },

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

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

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

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

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

        enumerable: true,
        configurable: true
      });

      const babel = babelDefault.babel;

      Object.defineProperty(_recorder_._src_client_lang_lang_ext_js, 'babel', {
        get() {
          return babel;
        },

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

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

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

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

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

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

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

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

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

        enumerable: true,
        configurable: true
      });

      const SYNTAX_PLUGINS = [jsx, doExpressions, functionBind, asyncGenerators];

      Object.defineProperty(_recorder_._src_client_lang_lang_ext_js, 'SYNTAX_PLUGINS', {
        get() {
          return SYNTAX_PLUGINS;
        },

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

        enumerable: true,
        configurable: true
      });
      const filename = "tempfile.js";
      Object.defineProperty(_recorder_._src_client_lang_lang_ext_js, 'filename', {
        get() {
          return filename;
        },

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

        enumerable: true,
        configurable: true
      });
      const BABEL_CONFIG_DEFAULT = {
        babelrc: false,
        plugins: SYNTAX_PLUGINS,
        presets: [],
        filename: filename,
        sourceFileName: filename,
        moduleIds: false,
        sourceMaps: true,
        // inputSourceMap: load.metadata.sourceMap,
        compact: false,
        comments: true,
        code: true,
        ast: true,
        resolveModuleSource: undefined
      };

      Object.defineProperty(_recorder_._src_client_lang_lang_ext_js, 'BABEL_CONFIG_DEFAULT', {
        get() {
          return BABEL_CONFIG_DEFAULT;
        },

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

        enumerable: true,
        configurable: true
      });
      extend(Object.prototype, {

        dependentAExprs() {
          return AExprRegistry.allAsArray().filter(ae => {
            if (!ae.supportsDependencies()) {
              return false;
            }

            const dependencies = ae.dependencies().all();
            return dependencies.find(dep => {
              const desc = dep.getAsDependencyDescription();
              return desc.object === this || desc.value === this || desc.scope === this;
            });
          });
        },

        transformAsAST(fullPluginOrVisitor) {
          const iteratorPlugin = fullPluginOrVisitor instanceof Function ? fullPluginOrVisitor :
          // only got the visitor: need to bridge to a plugin function as expected by babel
          () => ({ visitor: fullPluginOrVisitor });

          const babelConfig = Object.assign({}, BABEL_CONFIG_DEFAULT, {
            plugins: [...SYNTAX_PLUGINS, iteratorPlugin]
          });

          return babel.transformFromAst(this, undefined, babelConfig);
        },

        // using `babel.traverse` also allows for wild cards to match AST nodes
        traverseAsAST(visitor) {
          return babel.traverse(this, visitor);
        }

      });

      /*MD
      ## STRING
      MD*/

      Object.defineProperty(_recorder_._src_client_lang_lang_ext_js, 'boundEval', {
        get() {
          return boundEval;
        },

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

        enumerable: true,
        configurable: true
      });


      extend(String.prototype, {

        toAST() {
          return babel.transform(this, BABEL_CONFIG_DEFAULT).ast;
        },

        /**
         * @example providing a visitor object
         * var ids = [];
         * `let x = 0, y = x +2;`.transformAsAST({
         *   Identifier(path) {
         *     ids.push(path.node.name);
         *   }
         * });
         * ids;
         * 
         * @example providing a full-fledged plugin function
         * var ids = [];
         * `let x = 0, y = x +2;`.transformAsAST(({ types: t, template, traverse }) => ({
         *   visitor: {
         *     Identifier(path) {
         *       ids.push(path.node.name);
         *     }
         *   }
         * }));
         * ids;
         */
        transformAsAST(fullPluginOrVisitor) {
          return this.toAST().transformAsAST(fullPluginOrVisitor);
        },

        /*
         * @example printing all node types found in source code
         * `var a = 42, b = 423; lively::foo`.traverseAsAST({
         *    enter(path) {
         *      lively.notify(path.node.type)
         *    }
         *  });
         */
        traverseAsAST(visitor) {
          return this.toAST().traverseAsAST(visitor);
        },

        async boundEval(thisReference, targetModule) {
          const result = await boundEval(this, thisReference, targetModule);
          if (result.isError) {
            throw result.value;
          } else {
            return result.value;
          }
        }

      });

      /*MD
      ## FUNCTION
      MD*/
      Object.defineProperty(_recorder_._src_client_lang_lang_ext_js, 'aexpr', {
        get() {
          return aexpr;
        },

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

        enumerable: true,
        configurable: true
      });


      const aexprByFunction = new WeakMap();

      Object.defineProperty(_recorder_._src_client_lang_lang_ext_js, 'aexprByFunction', {
        get() {
          return aexprByFunction;
        },

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

        enumerable: true,
        configurable: true
      });
      extend(Function.prototype, {

        asAExpr() {
          return aexprByFunction.getOrCreate(this, () => aexpr(this));
        },

        onChange(callback) {
          return this.asAExpr().onChange(callback);
        },

        onBecomeTrue(callback) {
          return this.asAExpr().onBecomeTrue(callback);
        },

        onBecomeFalse(callback) {
          return this.asAExpr().onBecomeFalse(callback);
        }

      });
    }
  };
});