<commit_before>var semver = Npm.require("semver");
var JSON5 = Npm.require("json5");
/**
 * A compiler that can be instantiated with features and used inside
 * Plugin.registerCompiler
 * @param {Object} extraFeatures The same object that getDefaultOptions takes
 */
BabelCompiler = function BabelCompiler(extraFeatures) {
  this.extraFeatures = extraFeatures;
  this._babelrcCache = null;
  this._babelrcWarnings = Object.create(null);
  this.cacheDirectory = null;
};

var BCp = BabelCompiler.prototype;
var excludedFileExtensionPattern = /\.(es5|min)\.js$/i;
var hasOwn = Object.prototype.hasOwnProperty;

// There's no way to tell the current Meteor version, but we can infer
// whether it's Meteor 1.4.4 or earlier by checking the Node version.
var isMeteorPre144 = semver.lt(process.version, "4.8.1");

BCp.processFilesForTarget = function (inputFiles) {
  var compiler = this;

  // Reset this cache for each batch processed.
  this._babelrcCache = null;

  inputFiles.forEach(function (inputFile) {
    if (inputFile.supportsLazyCompilation) {
      inputFile.addJavaScript({
        path: inputFile.getPathInPackage(),
        bare: !! inputFile.getFileOptions().bare
      }, function () {
        return compiler.processOneFileForTarget(inputFile);
      });
    } else {
      var toBeAdded = compiler.processOneFileForTarget(inputFile);
      if (toBeAdded) {
        inputFile.addJavaScript(toBeAdded);
      }
    }
  });
};

// Returns an object suitable for passing to inputFile.addJavaScript, or
// null to indicate there was an error, and nothing should be added.
BCp.processOneFileForTarget = function (inputFile, source) {
  this._babelrcCache = this._babelrcCache || Object.create(null);

  if (typeof source !== "string") {
    // Other compiler plugins can call processOneFileForTarget with a
    // source string that's different from inputFile.getContentsAsString()
    // if they've already done some processing.
    source = inputFile.getContentsAsString();
  }

  var packageName = inputFile.getPackageName();
  var inputFilePath = inputFile.getPathInPackage();
  var outputFilePath = inputFilePath;
  var fileOptions = inputFile.getFileOptions();
  var toBeAdded = {
    sourcePath: inputFilePath,
    path: outputFilePath,
    data: source,
    hash: inputFile.getSourceHash(),
    sourceMap: null,
    bare: !! fileOptions.bare
  };

  // If you need to exclude a specific file within a package from Babel
  // compilation, pass the { transpile: false } options to api.addFiles
  // when you add that file.
  if (fileOptions.transpile !== false &&
      // Bare files should not be transpiled by Babel, because they do not
      // have access to CommonJS APIs like `require`, `module`, `exports`.
      ! toBeAdded.bare &&
      // If you need to exclude a specific file within an app from Babel
      // compilation, give it the following file extension: .es5.js
      ! isInputFilePathExcluded(inputFilePath)) {
    var extraFeatures = Object.assign({}, this.extraFeatures);
    var arch = inputFile.getArch();

    if (arch.startsWith("os.")) {
      // Start with a much simpler set of Babel presets and plugins if
      // we're compiling for Node 8.
      extraFeatures.nodeMajorVersion = parseInt(process.versions.node, 10);
    } else if (arch === "web.browser") {
      extraFeatures.modernBrowsers = true;
    }

    if (! extraFeatures.hasOwnProperty("jscript")) {
      // Perform some additional transformations to improve compatibility
      // in older browsers (e.g. wrapping named function expressions, per
      // http://kiro.me/blog/nfe_dilemma.html).
      extraFeatures.jscript = true;
    }

    var babelOptions = Babel.getDefaultOptions(extraFeatures);
    babelOptions.caller = { name: "meteor", arch };

    const cacheOptions = {
      cacheDirectory: this.cacheDirectory,
      cacheDeps: {
        sourceHash: toBeAdded.hash,
      },
    };

    this.inferExtraBabelOptions(
      inputFile,
      babelOptions,
      cacheOptions.cacheDeps,
    );

    babelOptions.sourceMaps = true;
    babelOptions.filename =
      babelOptions.sourceFileName = packageName
      ? "packages/" + packageName + "/" + inputFilePath
      : inputFilePath;

    try {
      var result = profile('Babel.compile', function () {
        return Babel.compile(source, babelOptions, cacheOptions);
      });
    } catch (e) {
      if (e.loc) {
        // Error is from @babel/parser.
        inputFile.error({
          message: e.message,
          line: e.loc.line,
          column: e.loc.column,
        });
      } else {
        // Error is from a Babel transform, with line/column information
        // embedded in e.message.
        inputFile.error(e);
      }

      return null;
    }

    if (isMeteorPre144) {
      // Versions of meteor-tool earlier than 1.4.4 do not understand that
      // module.importSync is synonymous with the deprecated module.import
      // and thus fail to register dependencies for importSync calls.
      // This string replacement may seem a bit hacky, but it will tide us
      // over until everyone has updated to Meteor 1.4.4.
      // https://github.com/meteor/meteor/issues/8572
      result.code = result.code.replace(
        /\bmodule\.importSync\b/g,
        "module.import"
      );
    }

    toBeAdded.data = result.code;
    toBeAdded.hash = result.hash;

    // The babelOptions.sourceMapTarget option was deprecated in Babel
    // 7.0.0-beta.41: https://github.com/babel/babel/pull/7500
    result.map.file = babelOptions.filename + ".map";

    toBeAdded.sourceMap = result.map;
  }

  return toBeAdded;
};

function isInputFilePathExcluded(path) {
  if (excludedFileExtensionPattern.test(path)) {
    return true;
  }

  const parts = path.split("/");
  const nmi = parts.lastIndexOf("node_modules");
  if (nmi >= 0) {
    const part1 = parts[nmi + 1];
    // We trust that any code related to @babel/runtime has already been
    // compiled adequately. The @babel/runtime/helpers/typeof module is a
    // good example of why double-compilation is risky for these packages,
    // since it uses native typeof syntax to implement its polyfill for
    // Symbol-aware typeof, so compiling it again would cause the
    // generated code to try to require itself. In general, compiling code
    // more than once with Babel should be safe (just unnecessary), except
    // for code that Babel itself relies upon at runtime. Finally, if this
    // hard-coded list of package names proves to be incomplete, we can
    // always add to it (or even replace it completely) by releasing a new
    // version of the babel-compiler package.
    if (part1 === "@babel" ||
        part1 === "core-js" ||
        part1 === "regenerator-runtime") {
      return true;
    }
  }

  return false;
}

BCp.setDiskCacheDirectory = function (cacheDir) {
  this.cacheDirectory = cacheDir;
};

function profile(name, func) {
  if (typeof Profile !== 'undefined') {
    return Profile.time(name, func);
  } else {
    return func();
  }
};

BCp.inferExtraBabelOptions = function (inputFile, babelOptions, cacheDeps) {
  if (! inputFile.require ||
      ! inputFile.findControlFile ||
      ! inputFile.readAndWatchFile) {
    return false;
  }

  return (
    // If a .babelrc exists, it takes precedence over package.json.
    this._inferFromBabelRc(inputFile, babelOptions, cacheDeps) ||
    this._inferFromPackageJson(inputFile, babelOptions, cacheDeps)
  );
};

BCp._inferFromBabelRc = function (inputFile, babelOptions, cacheDeps) {
  var babelrcPath = inputFile.findControlFile(".babelrc");
  if (babelrcPath) {
    if (! hasOwn.call(this._babelrcCache, babelrcPath)) {
      try {
        this._babelrcCache[babelrcPath] = {
          controlFilePath: babelrcPath,
          controlFileData: JSON5.parse(
            inputFile.readAndWatchFile(babelrcPath)),
          deps: Object.create(null),
        };
      } catch (e) {
        if (e instanceof SyntaxError) {
          e.message = ".babelrc is not a valid JSON5 file: " + e.message;
        }
        throw e;
      }
    }

    const cacheEntry = this._babelrcCache[babelrcPath];

    if (this._inferHelper(inputFile, cacheEntry)) {
      merge(babelOptions, cacheEntry, "presets");
      merge(babelOptions, cacheEntry, "plugins");
      Object.assign(cacheDeps, cacheEntry.deps);
      return true;
    }
  }
};

BCp._inferFromPackageJson = function (inputFile, babelOptions, cacheDeps) {
  var pkgJsonPath = inputFile.findControlFile("package.json");
  if (pkgJsonPath) {
    const cacheEntry = hasOwn.call(this._babelrcCache, pkgJsonPath)
      ? this._babelrcCache[pkgJsonPath]
      : this._babelrcCache[pkgJsonPath] = {
          controlFilePath: pkgJsonPath,
          controlFileData: JSON.parse(
            inputFile.readAndWatchFile(pkgJsonPath)
          ).babel || null,
          deps: Object.create(null),
        };

    if (this._inferHelper(inputFile, cacheEntry)) {
      merge(babelOptions, cacheEntry, "presets");
      merge(babelOptions, cacheEntry, "plugins");
      Object.assign(cacheDeps, cacheEntry.deps);
      return true;
    }
  }
};

BCp._inferHelper = function (inputFile, cacheEntry) {
  if (! cacheEntry.controlFileData) {
    return false;
  }

  if (hasOwn.call(cacheEntry, "finalInferHelperResult")) {
    // We've already run _inferHelper and populated
    // cacheEntry.{presets,plugins}, so we can return early here.
    return cacheEntry.finalInferHelperResult;
  }

  var compiler = this;

  function walkBabelRC(obj, path) {
    if (obj && typeof obj === "object") {
      const copy = Object.create(null);

      path = path || [];
      const index = path.length;

      if (obj.presets) {
        path[index] = "presets";
        copy.presets = walkHelper(obj.presets, path);
      }

      if (obj.plugins) {
        path[index] = "plugins";
        copy.plugins = walkHelper(obj.plugins, path);
      }

      path.pop();

      return copy;
    }

    return obj;
  }

  function walkHelper(list, path) {
    const copy = [];

    list.forEach(function (pluginOrPreset) {
      const res = resolveHelper(pluginOrPreset, path);
      if (res) {
        copy.push(res);
      }
    });

    return copy;
  }

  function resolveHelper(value, path) {
    if (value) {
      if (typeof value === "function") {
        // The value has already been resolved to a plugin function.
        return value;
      }

      if (Array.isArray(value)) {
        // The value is a [plugin, options] pair.
        const res = resolveHelper(value[0], path);
        if (res) {
          const copy = value.slice(0);
          copy[0] = res;
          return copy;
        }

      } else if (typeof value === "string") {
        // The value is a string that we need to require.
        const result = requireWithPath(value, path);
        if (result && result.module) {
          cacheEntry.deps[result.name] = result.version;
          return walkBabelRC(result.module, path);
        }

      } else if (typeof value === "object") {
        // The value is a { presets?, plugins? } preset object.
        return walkBabelRC(value, path);
      }
    }

    return null;
  }

  function requireWithPath(id, path) {
    const prefixes = [];
    const lastInPath = path[path.length - 1];
    if (lastInPath === "presets") {
      prefixes.push("@babel/preset-", "babel-preset-");
    } else if (lastInPath === "plugins") {
      prefixes.push("@babel/plugin-", "babel-plugin-");
    }

    // Try without a prefix if the prefixes fail.
    prefixes.push("");

    try {
      return requireWithPrefixes(
        inputFile, id, prefixes,
        cacheEntry.controlFilePath
      );
    } catch (e) {
      if (e.code !== "MODULE_NOT_FOUND") {
        throw e;
      }

      if (! hasOwn.call(compiler._babelrcWarnings, id)) {
        compiler._babelrcWarnings[id] = cacheEntry.controlFilePath;

        console.error(
          "Warning: unable to resolve " +
            JSON.stringify(id) +
            " in " + path.join(".") +
            " of " + cacheEntry.controlFilePath + ", due to:"
        );

        console.error(e.stack || e);
      }

      return null;
    }
  }

  const { controlFileData } = cacheEntry;
  const clean = walkBabelRC(controlFileData);
  merge(cacheEntry, clean, "presets");
  merge(cacheEntry, clean, "plugins");

  if (controlFileData &&
      controlFileData.env) {
    const envKey =
      process.env.BABEL_ENV ||
      process.env.NODE_ENV ||
      "development";

    const clean = walkBabelRC(controlFileData.env[envKey]);

    if (clean) {
      merge(cacheEntry, clean, "presets");
      merge(cacheEntry, clean, "plugins");
    }
  }

  return cacheEntry.finalInferHelperResult =
    !! (cacheEntry.presets ||
        cacheEntry.plugins);
};

function merge(babelOptions, babelrc, name) {
  if (babelrc[name]) {
    var list = babelOptions[name] || [];
    babelOptions[name] = list;
    list.push.apply(list, babelrc[name]);
  }
}

const forbiddenPresetNames = new Set([
  // Since Meteor always includes babel-preset-meteor automatically, it's
  // likely a mistake for that preset to appear in a custom .babelrc
  // file. Previously we recommended that developers simply remove the
  // preset (e.g. #9631), but we can easily just ignore it by returning
  // null here, which seems like a better solution since it allows the
  // same .babelrc file to be used for other purposes, such as running
  // tests with a testing tool that needs to compile application code the
  // same way Meteor does.
  "babel-preset-meteor",
  // Similar reasoning applies to these commonly misused Babel presets:
  "@babel/preset-env",
  "@babel/preset-react",
]);

function requireWithPrefixes(inputFile, id, prefixes, controlFilePath) {
  var isTopLevel = "./".indexOf(id.charAt(0)) < 0;
  var presetOrPlugin;
  var presetOrPluginMeta;

  if (isTopLevel) {
    var presetOrPluginId;

    var found = prefixes.some(function (prefix) {
      try {
        // Call inputFile.resolve here rather than inputFile.require so
        // that the import doesn't fail due to missing transitive
        // dependencies imported by the preset or plugin.
        if (inputFile.resolve(prefix + id, controlFilePath)) {
          presetOrPluginId = prefix + id;
        }

        presetOrPluginMeta = inputFile.require(
          packageNameFromTopLevelModuleId(prefix + id) + "/package.json",
          controlFilePath
        );

        return true;

      } catch (e) {
        if (e.code !== "MODULE_NOT_FOUND") {
          throw e;
        }

        return false;
      }
    });

    if (found) {
      if (forbiddenPresetNames.has(presetOrPluginMeta.name)) {
        return null;
      }

      presetOrPlugin = inputFile.require(
        presetOrPluginId,
        controlFilePath
      );
    }

  } else {
    // If the identifier is not top-level, but relative or absolute,
    // then it will be required as-is, so that you can implement your
    // own Babel plugins locally, rather than always using plugins
    // installed from npm.
    presetOrPlugin = inputFile.require(id, controlFilePath);

    // Note that inputFile.readAndWatchFileWithHash converts module
    // identifers to OS-specific paths if necessary.
    var absId = inputFile.resolve(id, controlFilePath);
    var info = inputFile.readAndWatchFileWithHash(absId);

    presetOrPluginMeta = {
      name: absId,
      version: info.hash
    };
  }

  if (presetOrPlugin &&
      presetOrPluginMeta) {
    return {
      name: presetOrPluginMeta.name,
      version: presetOrPluginMeta.version,
      module: presetOrPlugin.__esModule
        ? presetOrPlugin.default
        : presetOrPlugin
    };
  }

  return null;
}

// react-hot-loader/babel => react-hot-loader
// @babel/preset-env/lib/index.js => @babel/preset-env
function packageNameFromTopLevelModuleId(id) {
  const parts = id.split("/", 2);
  if (parts[0].charAt(0) === "@") {
    return parts.join("/");
  }
  return parts[0];
}
<commit_msg>Compile import/export syntax in @babel/runtime-related modules.<commit_after>var semver = Npm.require("semver");
var JSON5 = Npm.require("json5");
/**
 * A compiler that can be instantiated with features and used inside
 * Plugin.registerCompiler
 * @param {Object} extraFeatures The same object that getDefaultOptions takes
 */
BabelCompiler = function BabelCompiler(extraFeatures) {
  this.extraFeatures = extraFeatures;
  this._babelrcCache = null;
  this._babelrcWarnings = Object.create(null);
  this.cacheDirectory = null;
};

var BCp = BabelCompiler.prototype;
var excludedFileExtensionPattern = /\.(es5|min)\.js$/i;
var hasOwn = Object.prototype.hasOwnProperty;

// There's no way to tell the current Meteor version, but we can infer
// whether it's Meteor 1.4.4 or earlier by checking the Node version.
var isMeteorPre144 = semver.lt(process.version, "4.8.1");

BCp.processFilesForTarget = function (inputFiles) {
  var compiler = this;

  // Reset this cache for each batch processed.
  this._babelrcCache = null;

  inputFiles.forEach(function (inputFile) {
    if (inputFile.supportsLazyCompilation) {
      inputFile.addJavaScript({
        path: inputFile.getPathInPackage(),
        bare: !! inputFile.getFileOptions().bare
      }, function () {
        return compiler.processOneFileForTarget(inputFile);
      });
    } else {
      var toBeAdded = compiler.processOneFileForTarget(inputFile);
      if (toBeAdded) {
        inputFile.addJavaScript(toBeAdded);
      }
    }
  });
};

// Returns an object suitable for passing to inputFile.addJavaScript, or
// null to indicate there was an error, and nothing should be added.
BCp.processOneFileForTarget = function (inputFile, source) {
  this._babelrcCache = this._babelrcCache || Object.create(null);

  if (typeof source !== "string") {
    // Other compiler plugins can call processOneFileForTarget with a
    // source string that's different from inputFile.getContentsAsString()
    // if they've already done some processing.
    source = inputFile.getContentsAsString();
  }

  var packageName = inputFile.getPackageName();
  var inputFilePath = inputFile.getPathInPackage();
  var outputFilePath = inputFilePath;
  var fileOptions = inputFile.getFileOptions();
  var toBeAdded = {
    sourcePath: inputFilePath,
    path: outputFilePath,
    data: source,
    hash: inputFile.getSourceHash(),
    sourceMap: null,
    bare: !! fileOptions.bare
  };

  // If you need to exclude a specific file within a package from Babel
  // compilation, pass the { transpile: false } options to api.addFiles
  // when you add that file.
  if (fileOptions.transpile !== false &&
      // Bare files should not be transpiled by Babel, because they do not
      // have access to CommonJS APIs like `require`, `module`, `exports`.
      ! toBeAdded.bare &&
      // If you need to exclude a specific file within an app from Babel
      // compilation, give it the following file extension: .es5.js
      ! excludedFileExtensionPattern.test(inputFilePath)) {

    const extraFeatures = { ...this.extraFeatures };
    const arch = inputFile.getArch();

    if (arch.startsWith("os.")) {
      // Start with a much simpler set of Babel presets and plugins if
      // we're compiling for Node 8.
      extraFeatures.nodeMajorVersion = parseInt(process.versions.node, 10);
    } else if (arch === "web.browser") {
      extraFeatures.modernBrowsers = true;
    }

    if (! extraFeatures.hasOwnProperty("jscript")) {
      // Perform some additional transformations to improve compatibility
      // in older browsers (e.g. wrapping named function expressions, per
      // http://kiro.me/blog/nfe_dilemma.html).
      extraFeatures.jscript = true;
    }

    if (shouldCompileModulesOnly(inputFilePath)) {
      // Modules like @babel/runtime/helpers/esm/typeof.js need to be
      // compiled to support ECMAScript modules syntax, but should *not*
      // be compiled in any other way (for more explanation, see my longer
      // comment in shouldCompileModulesOnly).
      extraFeatures.compileModulesOnly = true;
    }

    var babelOptions = Babel.getDefaultOptions(extraFeatures);
    babelOptions.caller = { name: "meteor", arch };

    const cacheOptions = {
      cacheDirectory: this.cacheDirectory,
      cacheDeps: {
        sourceHash: toBeAdded.hash,
      },
    };

    this.inferExtraBabelOptions(
      inputFile,
      babelOptions,
      cacheOptions.cacheDeps,
    );

    babelOptions.sourceMaps = true;
    babelOptions.filename =
      babelOptions.sourceFileName = packageName
      ? "packages/" + packageName + "/" + inputFilePath
      : inputFilePath;

    try {
      var result = profile('Babel.compile', function () {
        return Babel.compile(source, babelOptions, cacheOptions);
      });
    } catch (e) {
      if (e.loc) {
        // Error is from @babel/parser.
        inputFile.error({
          message: e.message,
          line: e.loc.line,
          column: e.loc.column,
        });
      } else {
        // Error is from a Babel transform, with line/column information
        // embedded in e.message.
        inputFile.error(e);
      }

      return null;
    }

    if (isMeteorPre144) {
      // Versions of meteor-tool earlier than 1.4.4 do not understand that
      // module.importSync is synonymous with the deprecated module.import
      // and thus fail to register dependencies for importSync calls.
      // This string replacement may seem a bit hacky, but it will tide us
      // over until everyone has updated to Meteor 1.4.4.
      // https://github.com/meteor/meteor/issues/8572
      result.code = result.code.replace(
        /\bmodule\.importSync\b/g,
        "module.import"
      );
    }

    toBeAdded.data = result.code;
    toBeAdded.hash = result.hash;

    // The babelOptions.sourceMapTarget option was deprecated in Babel
    // 7.0.0-beta.41: https://github.com/babel/babel/pull/7500
    result.map.file = babelOptions.filename + ".map";

    toBeAdded.sourceMap = result.map;
  }

  return toBeAdded;
};

function shouldCompileModulesOnly(path) {
  const parts = path.split("/");
  const nmi = parts.lastIndexOf("node_modules");
  if (nmi >= 0) {
    const part1 = parts[nmi + 1];
    // We trust that any code related to @babel/runtime has already been
    // compiled adequately. The @babel/runtime/helpers/typeof module is a
    // good example of why double-compilation is risky for these packages,
    // since it uses native typeof syntax to implement its polyfill for
    // Symbol-aware typeof, so compiling it again would cause the
    // generated code to try to require itself. In general, compiling code
    // more than once with Babel should be safe (just unnecessary), except
    // for code that Babel itself relies upon at runtime. Finally, if this
    // hard-coded list of package names proves to be incomplete, we can
    // always add to it (or even replace it completely) by releasing a new
    // version of the babel-compiler package.
    if (part1 === "@babel" ||
        part1 === "core-js" ||
        part1 === "regenerator-runtime") {
      return true;
    }
  }

  return false;
}

BCp.setDiskCacheDirectory = function (cacheDir) {
  this.cacheDirectory = cacheDir;
};

function profile(name, func) {
  if (typeof Profile !== 'undefined') {
    return Profile.time(name, func);
  } else {
    return func();
  }
};

BCp.inferExtraBabelOptions = function (inputFile, babelOptions, cacheDeps) {
  if (! inputFile.require ||
      ! inputFile.findControlFile ||
      ! inputFile.readAndWatchFile) {
    return false;
  }

  return (
    // If a .babelrc exists, it takes precedence over package.json.
    this._inferFromBabelRc(inputFile, babelOptions, cacheDeps) ||
    this._inferFromPackageJson(inputFile, babelOptions, cacheDeps)
  );
};

BCp._inferFromBabelRc = function (inputFile, babelOptions, cacheDeps) {
  var babelrcPath = inputFile.findControlFile(".babelrc");
  if (babelrcPath) {
    if (! hasOwn.call(this._babelrcCache, babelrcPath)) {
      try {
        this._babelrcCache[babelrcPath] = {
          controlFilePath: babelrcPath,
          controlFileData: JSON5.parse(
            inputFile.readAndWatchFile(babelrcPath)),
          deps: Object.create(null),
        };
      } catch (e) {
        if (e instanceof SyntaxError) {
          e.message = ".babelrc is not a valid JSON5 file: " + e.message;
        }
        throw e;
      }
    }

    const cacheEntry = this._babelrcCache[babelrcPath];

    if (this._inferHelper(inputFile, cacheEntry)) {
      merge(babelOptions, cacheEntry, "presets");
      merge(babelOptions, cacheEntry, "plugins");
      Object.assign(cacheDeps, cacheEntry.deps);
      return true;
    }
  }
};

BCp._inferFromPackageJson = function (inputFile, babelOptions, cacheDeps) {
  var pkgJsonPath = inputFile.findControlFile("package.json");
  if (pkgJsonPath) {
    const cacheEntry = hasOwn.call(this._babelrcCache, pkgJsonPath)
      ? this._babelrcCache[pkgJsonPath]
      : this._babelrcCache[pkgJsonPath] = {
          controlFilePath: pkgJsonPath,
          controlFileData: JSON.parse(
            inputFile.readAndWatchFile(pkgJsonPath)
          ).babel || null,
          deps: Object.create(null),
        };

    if (this._inferHelper(inputFile, cacheEntry)) {
      merge(babelOptions, cacheEntry, "presets");
      merge(babelOptions, cacheEntry, "plugins");
      Object.assign(cacheDeps, cacheEntry.deps);
      return true;
    }
  }
};

BCp._inferHelper = function (inputFile, cacheEntry) {
  if (! cacheEntry.controlFileData) {
    return false;
  }

  if (hasOwn.call(cacheEntry, "finalInferHelperResult")) {
    // We've already run _inferHelper and populated
    // cacheEntry.{presets,plugins}, so we can return early here.
    return cacheEntry.finalInferHelperResult;
  }

  var compiler = this;

  function walkBabelRC(obj, path) {
    if (obj && typeof obj === "object") {
      const copy = Object.create(null);

      path = path || [];
      const index = path.length;

      if (obj.presets) {
        path[index] = "presets";
        copy.presets = walkHelper(obj.presets, path);
      }

      if (obj.plugins) {
        path[index] = "plugins";
        copy.plugins = walkHelper(obj.plugins, path);
      }

      path.pop();

      return copy;
    }

    return obj;
  }

  function walkHelper(list, path) {
    const copy = [];

    list.forEach(function (pluginOrPreset) {
      const res = resolveHelper(pluginOrPreset, path);
      if (res) {
        copy.push(res);
      }
    });

    return copy;
  }

  function resolveHelper(value, path) {
    if (value) {
      if (typeof value === "function") {
        // The value has already been resolved to a plugin function.
        return value;
      }

      if (Array.isArray(value)) {
        // The value is a [plugin, options] pair.
        const res = resolveHelper(value[0], path);
        if (res) {
          const copy = value.slice(0);
          copy[0] = res;
          return copy;
        }

      } else if (typeof value === "string") {
        // The value is a string that we need to require.
        const result = requireWithPath(value, path);
        if (result && result.module) {
          cacheEntry.deps[result.name] = result.version;
          return walkBabelRC(result.module, path);
        }

      } else if (typeof value === "object") {
        // The value is a { presets?, plugins? } preset object.
        return walkBabelRC(value, path);
      }
    }

    return null;
  }

  function requireWithPath(id, path) {
    const prefixes = [];
    const lastInPath = path[path.length - 1];
    if (lastInPath === "presets") {
      prefixes.push("@babel/preset-", "babel-preset-");
    } else if (lastInPath === "plugins") {
      prefixes.push("@babel/plugin-", "babel-plugin-");
    }

    // Try without a prefix if the prefixes fail.
    prefixes.push("");

    try {
      return requireWithPrefixes(
        inputFile, id, prefixes,
        cacheEntry.controlFilePath
      );
    } catch (e) {
      if (e.code !== "MODULE_NOT_FOUND") {
        throw e;
      }

      if (! hasOwn.call(compiler._babelrcWarnings, id)) {
        compiler._babelrcWarnings[id] = cacheEntry.controlFilePath;

        console.error(
          "Warning: unable to resolve " +
            JSON.stringify(id) +
            " in " + path.join(".") +
            " of " + cacheEntry.controlFilePath + ", due to:"
        );

        console.error(e.stack || e);
      }

      return null;
    }
  }

  const { controlFileData } = cacheEntry;
  const clean = walkBabelRC(controlFileData);
  merge(cacheEntry, clean, "presets");
  merge(cacheEntry, clean, "plugins");

  if (controlFileData &&
      controlFileData.env) {
    const envKey =
      process.env.BABEL_ENV ||
      process.env.NODE_ENV ||
      "development";

    const clean = walkBabelRC(controlFileData.env[envKey]);

    if (clean) {
      merge(cacheEntry, clean, "presets");
      merge(cacheEntry, clean, "plugins");
    }
  }

  return cacheEntry.finalInferHelperResult =
    !! (cacheEntry.presets ||
        cacheEntry.plugins);
};

function merge(babelOptions, babelrc, name) {
  if (babelrc[name]) {
    var list = babelOptions[name] || [];
    babelOptions[name] = list;
    list.push.apply(list, babelrc[name]);
  }
}

const forbiddenPresetNames = new Set([
  // Since Meteor always includes babel-preset-meteor automatically, it's
  // likely a mistake for that preset to appear in a custom .babelrc
  // file. Previously we recommended that developers simply remove the
  // preset (e.g. #9631), but we can easily just ignore it by returning
  // null here, which seems like a better solution since it allows the
  // same .babelrc file to be used for other purposes, such as running
  // tests with a testing tool that needs to compile application code the
  // same way Meteor does.
  "babel-preset-meteor",
  // Similar reasoning applies to these commonly misused Babel presets:
  "@babel/preset-env",
  "@babel/preset-react",
]);

function requireWithPrefixes(inputFile, id, prefixes, controlFilePath) {
  var isTopLevel = "./".indexOf(id.charAt(0)) < 0;
  var presetOrPlugin;
  var presetOrPluginMeta;

  if (isTopLevel) {
    var presetOrPluginId;

    var found = prefixes.some(function (prefix) {
      try {
        // Call inputFile.resolve here rather than inputFile.require so
        // that the import doesn't fail due to missing transitive
        // dependencies imported by the preset or plugin.
        if (inputFile.resolve(prefix + id, controlFilePath)) {
          presetOrPluginId = prefix + id;
        }

        presetOrPluginMeta = inputFile.require(
          packageNameFromTopLevelModuleId(prefix + id) + "/package.json",
          controlFilePath
        );

        return true;

      } catch (e) {
        if (e.code !== "MODULE_NOT_FOUND") {
          throw e;
        }

        return false;
      }
    });

    if (found) {
      if (forbiddenPresetNames.has(presetOrPluginMeta.name)) {
        return null;
      }

      presetOrPlugin = inputFile.require(
        presetOrPluginId,
        controlFilePath
      );
    }

  } else {
    // If the identifier is not top-level, but relative or absolute,
    // then it will be required as-is, so that you can implement your
    // own Babel plugins locally, rather than always using plugins
    // installed from npm.
    presetOrPlugin = inputFile.require(id, controlFilePath);

    // Note that inputFile.readAndWatchFileWithHash converts module
    // identifers to OS-specific paths if necessary.
    var absId = inputFile.resolve(id, controlFilePath);
    var info = inputFile.readAndWatchFileWithHash(absId);

    presetOrPluginMeta = {
      name: absId,
      version: info.hash
    };
  }

  if (presetOrPlugin &&
      presetOrPluginMeta) {
    return {
      name: presetOrPluginMeta.name,
      version: presetOrPluginMeta.version,
      module: presetOrPlugin.__esModule
        ? presetOrPlugin.default
        : presetOrPlugin
    };
  }

  return null;
}

// react-hot-loader/babel => react-hot-loader
// @babel/preset-env/lib/index.js => @babel/preset-env
function packageNameFromTopLevelModuleId(id) {
  const parts = id.split("/", 2);
  if (parts[0].charAt(0) === "@") {
    return parts.join("/");
  }
  return parts[0];
}
<|endoftext|>


<commit_before><commit_msg>Add methods (lCFirst, uCFirst)<commit_after><|endoftext|>


<commit_before>'use strict';

var {
  StyleSheet,
  Image,
  Text,
  View,
} = React;

var FBLogin = require('react-native-facebook-login');
var FBLoginMock = require('./facebook/FBLoginMock.js');
var FBLoginManager = require('NativeModules').FBLoginManager;

var FB_PHOTO_WIDTH = 200;

var Login = React.createClass({
  getInitialState: function(){
    return {
      user: null,
    };
  },

  componentWillMount: function(){
    this.updateView();
  },

  updateView: function(){
    var _this = this;
    FBLoginManager.getCredentials(function(error, credentials){
      if (!error) {
        _this.setState({ user : credentials });
      } else {
        _this.setState({ user : null });
      }
    });
  },

  render: function() {
    var _this = this;
    var user = this.state.user;

    return (
      <View style={styles.loginContainer}>

        { user && <Photo user={user} /> }
        { user && <Info user={user} /> }

        <FBLogin style={{ marginBottom: 10, }}
          permissions={["email","user_friends"]}
          onLogin={function(data){
            console.log("Logged in!");
            console.log(data);
            _this.setState({ user : data.credentials });
          }}
          onLogout={function(){
            console.log("Logged out.");
            _this.setState({ user : null });
          }}
          onLoginFound={function(data){
            console.log("Existing login found.");
            console.log(data);
            _this.setState({ user : data.credentials });
          }}
          onLoginNotFound={function(){
            console.log("No user logged in.");
            _this.setState({ user : null });
          }}
          onError={function(data){
            console.log("ERROR");
            console.log(data);
          }}
          onCancel={function(){
            console.log("User cancelled.");
          }}
          onPermissionsMissing={function(data){
            console.log("Check permissions!");
            console.log(data);
          }}
        />

        <Text>{ user ? user.token : "N/A" }</Text>
      </View>
    );
  }
});

var Photo = React.createClass({
  propTypes: {
    user: React.PropTypes.object.isRequired,
  },

  getInitialState: function(){
    return {
      photo: null,
    };
  },

  componentWillMount: function(){
    var _this = this;
    var user = this.props.user;
    var api = `https://graph.facebook.com/v2.3/${user.userId}/picture?width=${FB_PHOTO_WIDTH}&redirect=false&access_token=${user.token}`;

    fetch(api)
      .then((response) => response.json())
      .then((responseData) => {
        _this.setState({
          photo : {
            url : responseData.data.url,
            height: responseData.data.height,
            width: responseData.data.width,
          },
        });
      })
      .done();
  },

  render: function(){
    var photo = this.state.photo;

    return (
      <View style={styles.bottomBump}>

        <Image
          style={photo &&
            {
              height: photo.height,
              width: photo.width,
            }
          }
          source={{uri: photo && photo.url}}
        />
      </View>
    );
  }
});

var Info = React.createClass({
  propTypes: {
    user: React.PropTypes.object.isRequired,
  },

  getInitialState: function(){
    return {
      info: null,
    };
  },

  componentWillMount: function(){
    var _this = this;
    var user = this.props.user;
    var api = `https://graph.facebook.com/v2.3/${user.userId}?fields=name,email&access_token=${user.token}`;

    fetch(api)
      .then((response) => response.json())
      .then((responseData) => {
        _this.setState({
          info : {
            name : responseData.name,
            email: responseData.email,
          },
        });
      })
      .done();
  },

  render: function(){
    var info = this.state.info;

    return (
      <View style={styles.bottomBump}>
        <Text>{ info && this.props.user.userId }</Text>
        <Text>{ info && info.name }</Text>
        <Text>{ info && info.email }</Text>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  loginContainer: {
    marginTop: 150,

    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  bottomBump: {
    marginBottom: 15,
  },
});

module.exports = Login;
<commit_msg>set state on events<commit_after>'use strict';

var {
  StyleSheet,
  Image,
  Text,
  View,
} = React;

var FBLogin = require('react-native-facebook-login');
var FBLoginMock = require('./facebook/FBLoginMock.js');
var FBLoginManager = require('NativeModules').FBLoginManager;

var FB_PHOTO_WIDTH = 200;

var Login = React.createClass({
  getInitialState: function(){
    return {
      user: null,
    };
  },

  render: function() {
    var _this = this;
    var user = this.state.user;

    return (
      <View style={styles.loginContainer}>

        { user && <Photo user={user} /> }
        { user && <Info user={user} /> }

        <FBLogin style={{ marginBottom: 10, }}
          permissions={["email","user_friends"]}
          onLogin={function(data){
            console.log("Logged in!");
            console.log(data);
            _this.setState({ user : data.credentials });
          }}
          onLogout={function(){
            console.log("Logged out.");
            _this.setState({ user : null });
          }}
          onLoginFound={function(data){
            console.log("Existing login found.");
            console.log(data);
            _this.setState({ user : data.credentials });
          }}
          onLoginNotFound={function(){
            console.log("No user logged in.");
            _this.setState({ user : null });
          }}
          onError={function(data){
            console.log("ERROR");
            console.log(data);
          }}
          onCancel={function(){
            console.log("User cancelled.");
          }}
          onPermissionsMissing={function(data){
            console.log("Check permissions!");
            console.log(data);
          }}
        />

        <Text>{ user ? user.token : "N/A" }</Text>
      </View>
    );
  }
});

var Photo = React.createClass({
  propTypes: {
    user: React.PropTypes.object.isRequired,
  },

  getInitialState: function(){
    return {
      photo: null,
    };
  },

  componentWillMount: function(){
    var _this = this;
    var user = this.props.user;
    var api = `https://graph.facebook.com/v2.3/${user.userId}/picture?width=${FB_PHOTO_WIDTH}&redirect=false&access_token=${user.token}`;

    fetch(api)
      .then((response) => response.json())
      .then((responseData) => {
        _this.setState({
          photo : {
            url : responseData.data.url,
            height: responseData.data.height,
            width: responseData.data.width,
          },
        });
      })
      .done();
  },

  render: function(){
    var photo = this.state.photo;

    return (
      <View style={styles.bottomBump}>

        <Image
          style={photo &&
            {
              height: photo.height,
              width: photo.width,
            }
          }
          source={{uri: photo && photo.url}}
        />
      </View>
    );
  }
});

var Info = React.createClass({
  propTypes: {
    user: React.PropTypes.object.isRequired,
  },

  getInitialState: function(){
    return {
      info: null,
    };
  },

  componentWillMount: function(){
    var _this = this;
    var user = this.props.user;
    var api = `https://graph.facebook.com/v2.3/${user.userId}?fields=name,email&access_token=${user.token}`;

    fetch(api)
      .then((response) => response.json())
      .then((responseData) => {
        _this.setState({
          info : {
            name : responseData.name,
            email: responseData.email,
          },
        });
      })
      .done();
  },

  render: function(){
    var info = this.state.info;

    return (
      <View style={styles.bottomBump}>
        <Text>{ info && this.props.user.userId }</Text>
        <Text>{ info && info.name }</Text>
        <Text>{ info && info.email }</Text>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  loginContainer: {
    marginTop: 150,

    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  bottomBump: {
    marginBottom: 15,
  },
});

module.exports = Login;
<|endoftext|>


<commit_before>// Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= pkg.name %> <%= pkg.version %>
'use strict';
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var mountFolder = function (connect, dir) {
    return connect.static(require('path').resolve(dir));
};

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
    // load all grunt tasks
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    // configurable paths
    var yeomanConfig = {
        app: 'app',
        dist: 'dist'
    };

    grunt.initConfig({
        yeoman: yeomanConfig,
        watch: {
            coffee: {
                files: ['scripts/{,*/}*.coffee'],
                tasks: ['coffee:dist']
            },
            coffeeTest: {
                files: ['test/spec/{,*/}*.coffee'],
                tasks: ['coffee:test']
            },
            compass: {
                files: ['styles/{,*/}*.{scss,sass}'],
                tasks: ['compass:server']
            },
            livereload: {
                files: [
                    '{,*/}*.html',
                    '{.tmp,}/styles/{,*/}*.css',
                    '{.tmp,}/scripts/{,*/}*.js',
                    'images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
                ],
                tasks: ['livereload']
            }
        },
        connect: {
            options: {
                port: 8888,
                // change this to '0.0.0.0' to access the server from outside
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    middleware: function (connect) {
                        return [
                            lrSnippet,
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, '')
                        ];
                    }
                }
            },
            test: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, 'test')
                        ];
                    }
                }
            },
            dist: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, 'dist')
                        ];
                    }
                }
            }
        },
        open: {
            server: {
                path: 'http://localhost:<%= connect.options.port %>'
            }
        },
        clean: {
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '.tmp',
                        'build/*',
                        '!build/.git*'
                    ]
                }]
            },
            server: '.tmp'
        },
        requirejs: {
            dist: {
                options: {
                    name: 'app',
                    baseUrl: '.tmp/scripts',
                    mainConfigFile: 'scripts/config.js',
                    out: 'build/scripts/config.js',
                    removeCombined: false
                }
            }
        },
        coffee: {
            dist: {
                files: [{
                    // rather than compiling multiple files here you should
                    // require them into your main .coffee file
                    expand: true,
                    cwd: 'scripts',
                    src: '{,*/}*.coffee',
                    dest: '.tmp/scripts',
                    ext: '.js'
                }]
            },
        },
        cssmin: {
            dist: {
                files: {
                    'build/styles/main.css': [
                        '.tmp/styles/{,*/}*.css',
                        'styles/{,*/}*.css'
                    ]
                }
            }
        },
        copy: {
            js: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: 'scripts',
                    dest: '.tmp/scripts',
                    src: [
                        '{,*/}*.js',
                    ]
                }]
            },
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    dest: 'build',
                    src: [
                        '*.{ico,txt,html}',
                        '.htaccess',
                        'images/{,*/}*.{webp,gif}',
                        'styles/fonts/*',
                    ]
                },
                {
                    expand: true,
                    dot: true,
                    dest: 'build/scripts/<%= bowerDirectory %>',
                    cwd: 'scripts/<%= bowerDirectory %>',
                    src: [
                        'modernizr/modernizr.js',
                        'requirejs/require.js'
                    ]
                }]
            }
        },
        symlink: {
            js: {
                dest: '.tmp/scripts/<%= bowerDirectory %>',
                src: 'scripts/<%= bowerDirectory %>',
                options: {type: 'dir'}
            }
        },
        concurrent: {
            server: [
                'compass:server'
            ],
            test: [
                'compass'
            ],
            dist: [
                'compass:dist',
                // 'imagemin',
                // 'svgmin',
                // 'htmlmin'
            ]
        },
        compass: {
            options: {
                sassDir: 'styles',
                cssDir: '.tmp/styles',
                imagesDir: 'images',
                javascriptsDir: 'scripts',
                fontsDir: 'styles/fonts',
                importPath: 'scripts/<%= bowerDirectory %>',
                httpImagesPath: '/images',
                httpGeneratedImagesPath: '/images',
                relativeAssets: false
            },
            dist: {},
            server: {
                options: {
                    debugInfo: true
                }
            }
        },
    });

    grunt.registerTask('server', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'coffee',
            'concurrent:server',
            'livereload-start',
            'connect:livereload',
            // 'open',
            'watch'
        ]);
    });

    grunt.registerTask('build', [
        'clean:dist',
        'coffee:dist',
        'copy:js',
        'symlink:js',
        'concurrent:dist',
        'requirejs:dist',
        'cssmin',
        'copy:dist'
    ]);
};
<commit_msg>Change build to dist. Make sure build handles nested directories.<commit_after>// Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= pkg.name %> <%= pkg.version %>
'use strict';
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var mountFolder = function (connect, dir) {
    return connect.static(require('path').resolve(dir));
};

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
    // load all grunt tasks
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    // configurable paths
    var yeomanConfig = {
        app: 'app',
        dist: 'dist'
    };

    grunt.initConfig({
        yeoman: yeomanConfig,
        watch: {
            coffee: {
                files: ['scripts/{,**/}*.coffee'],
                tasks: ['coffee:dist']
            },
            coffeeTest: {
                files: ['test/spec/{,**/}*.coffee'],
                tasks: ['coffee:test']
            },
            compass: {
                files: ['styles/{,**/}*.{scss,sass}'],
                tasks: ['compass:server']
            },
            livereload: {
                files: [
                    '{,**/}*.html',
                    '{.tmp,}/styles/{,**/}*.css',
                    '{.tmp,}/scripts/{,**/}*.js',
                    'images/{,**/}*.{png,jpg,jpeg,gif,webp,svg}'
                ],
                tasks: ['livereload']
            }
        },
        connect: {
            options: {
                port: 8888,
                // change this to '0.0.0.0' to access the server from outside
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    middleware: function (connect) {
                        return [
                            lrSnippet,
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, '')
                        ];
                    }
                }
            },
            test: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, 'test')
                        ];
                    }
                }
            },
            dist: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, 'dist')
                        ];
                    }
                }
            }
        },
        open: {
            server: {
                path: 'http://localhost:<%= connect.options.port %>'
            }
        },
        clean: {
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '.tmp',
                        'dist/*',
                        '!dist/.git*'
                    ]
                }]
            },
            server: '.tmp'
        },
        requirejs: {
            dist: {
                options: {
                    name: 'app',
                    baseUrl: '.tmp/scripts',
                    mainConfigFile: 'scripts/config.js',
                    out: 'dist/scripts/config.js',
                    removeCombined: false
                }
            }
        },
        coffee: {
            dist: {
                files: [{
                    // rather than compiling multiple files here you should
                    // require them into your main .coffee file
                    expand: true,
                    cwd: 'scripts',
                    src: '{,**/}*.coffee',
                    dest: '.tmp/scripts',
                    ext: '.js'
                }]
            },
        },
        cssmin: {
            dist: {
                files: {
                    'dist/styles/main.css': [
                        '.tmp/styles/{,**/}*.css',
                        'styles/{,**/}*.css'
                    ]
                }
            }
        },
        copy: {
            js: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: 'scripts',
                    dest: '.tmp/scripts',
                    src: [
                        '{,**/}*.js',
                    ]
                }]
            },
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    dest: 'dist',
                    src: [
                        '*.{ico,txt,html}',
                        '.htaccess',
                        'images/{,**/}*.{webp,gif}',
                        'styles/fonts/*',
                    ]
                },
                {
                    expand: true,
                    dot: true,
                    dest: 'dist/scripts/<%= bowerDirectory %>',
                    cwd: 'scripts/<%= bowerDirectory %>',
                    src: [
                        'modernizr/modernizr.js',
                        'requirejs/require.js'
                    ]
                }]
            }
        },
        symlink: {
            js: {
                dest: '.tmp/scripts/<%= bowerDirectory %>',
                src: 'scripts/<%= bowerDirectory %>',
                options: {type: 'dir'}
            }
        },
        concurrent: {
            server: [
                'compass:server'
            ],
            test: [
                'compass'
            ],
            dist: [
                'compass:dist',
                // 'imagemin',
                // 'svgmin',
                // 'htmlmin'
            ]
        },
        compass: {
            options: {
                sassDir: 'styles',
                cssDir: '.tmp/styles',
                imagesDir: 'images',
                javascriptsDir: 'scripts',
                fontsDir: 'styles/fonts',
                importPath: 'scripts/<%= bowerDirectory %>',
                httpImagesPath: '/images',
                httpGeneratedImagesPath: '/images',
                relativeAssets: false
            },
            dist: {},
            server: {
                options: {
                    debugInfo: true
                }
            }
        },
    });

    grunt.registerTask('server', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'coffee',
            'concurrent:server',
            'livereload-start',
            'connect:livereload',
            // 'open',
            'watch'
        ]);
    });

    grunt.registerTask('build', [
        'clean:dist',
        'coffee:dist',
        'copy:js',
        'symlink:js',
        'concurrent:dist',
        'requirejs:dist',
        'cssmin',
        'copy:dist'
    ]);
};
<|endoftext|>


<commit_before>'use strict';
var $ = document.querySelector.bind(document);
var $$ = document.querySelectorAll.bind(document);
var prime_table = [2];

function construct_prime_table() {
    for (var i = 3; i < 300; i += 2)
        if (bigInt(i).isPrime()) {
            prime_table.push(i);
        }
}
construct_prime_table();

function fac_math(fac) {
    return Object.entries(fac).map(a =>
        String(a[0]) + (a[1] == 1 ? "" : `^{${a[1]}}`)
    ).join(' \\cdot ')
}

function semi_factorization(n0, primes = prime_table) {
    var n = bigInt(n0);
    var i = 0;
    var rtn = {};
    if (n.eq(1)) {
        return {
            1: 1
        }
    }
    while (i < primes.length) {
        var r = n.divmod(primes[i]);
        if (r.remainder.eq(0)) {
            rtn[primes[i]] = (rtn[[primes[i]]] || 0) + 1;
            n = r.quotient;
            if (n.eq(1))
                break;
        } else {
            i += 1;
        }
    }
    if (n.gt(1)) {
        rtn[n] = 1;
    }
    return rtn;
}
var Fractran = {
    parse_input(input_number) {
        var text = input_number.replace(/[*\s]+/g, '*')
        var nums = text.split('*');
        var factors = nums.map(
            s => {
                var v1 = /^[123456789]\d*\^[123456789]\d*$/.test(s);
                var v2 = /^[123456789]\d*$/.test(s);
                if (v1) {
                    var a = s.split('^');
                    return bigInt(a[0]).pow(a[1]);
                }
                if (v2) {
                    return bigInt(s);
                }
            })
        return factors.reduce((a, b) => a.times(b), bigInt(1))
    },
    check_input_error(input_number) {
        var text = input_number.replace(/[*\s]+/g, '*')
        var nums = text.split('*');
        var errors = nums.filter(
            s => {
                if (s === '') return false;
                if (/^[123456789]\d*\^[123456789]\d*$/.test(s))
                    return false;
                if (/^[123456789]\d*$/.test(s))
                    return false;
                return true;
            })
        return errors;
    },
    check_error(code_text) {
        var fracs_text = code_text.replace(/[,\s]+/g, ',')
        var fracs = fracs_text.split(',');
        var errors = fracs.filter(
            s => {
                var v = /^[123456789]\d*\/[123456789]\d*$/.test(s);
                return !v;
            })
        return errors;
    },
    step(pointer, n, code) {
        if (pointer >= code.length) {
            return [pointer, n, 0, 0]
        }
        var f = code[pointer];
        var p = bigInt(n).times(f[0]);
        var q = bigInt(f[1]);
        var r = bigInt.gcd(p, q);
        p = p.divide(r);
        q = q.divide(r);
        if (q.compare(1) == 0) {
            pointer = 0;
            n = p;
        } else {
            pointer = pointer + 1;
        }
        return [pointer, n, p, q]

    }
}

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

var app = new Vue({
    el: '#fractran',

    methods: {
        next_step(ms){
            if(this.ispausing){
                return new Promise(r => this.step_r=r)
            }
            return timeout(ms)
        },
        load_example(i) {
            this.pointer = -1;
            if (i >= this.examples.length) return;
            if (i < 0) return;
            var ex = this.examples[i];
            $('#input_input').value = ex.input;
            this.input_changed(ex.input);
            $('#output_base_input').value = ex.output_base;
            this.output_base_changed(ex.output_base);
            this.code_text = ex.code_text;
            if (this.code_mode == 0) {
                $('#code_text').value = ex.code_text;
                this.toggle_code_mode()
            }
        },
        output_base_changed(text) {
            this.output_base = (text.match(/\d+/g) || []).map(s => parseInt(s));
        },
        input_changed(text) {
            this.code_errors = Fractran.check_input_error(text);
            if (this.code_errors.length > 0)
                return false;
            this.input_number = text;
            return true;
        },
        restart(){
            this.isrunning = false;
            this.ispausing = true;

        },
        run_or_pause(){
            if(!this.isrunning){
                this.run(0)
            }
            else{
                this.ispausing = !this.ispausing;
            }

        },
        async run(pausing) {
            this.output_base_changed($('#output_base_input').value);
            if (!this.input_changed($('#input_input').value)) {
                return;
            }
            if (this.code_mode == 0)
                if (!this.toggle_code_mode())
                    return;
            this.isrunning = true;
            this.ispausing = pausing;
            this.output_seq = [];
            var n = Fractran.parse_input(this.input_number);
            var code = this.code_text.match(/[123456789]\d*\/[123456789]\d*/g)
            code = code.map(s => s.split('/').map(n => bigInt(n)));
            this.pointer = 0;
            var pointer = 0,
                n2, p, q
            var skip_count = 0;
            var skip = 0;
            while (this.pointer < code.length) {
                var f = code[pointer];
                [pointer, n2, p, q] = Fractran.step(pointer, n, code);
                var fac_p = null;
                //console.log(pointer, n2.toString(), p.toString(), q.toString())
                this.current_ok = q.compare(1) == 0;
                var in_text = this.current_ok ? "\\in" : "\\not\\in"
                var speedup = this.speedup;
                if (speedup < 0.01) speedup = 1;
                if (speedup >= 20000) {
                    skip = speedup / 10000;
                } else skip = 0;
                if (this.output_base.length > 0 && this.current_ok) {
                    fac_p = semi_factorization(p)
                    if (Object.keys(fac_p).map(s => parseInt(s)).every(k => {
                            return this.output_base.indexOf(k) > -1
                        })) {
                        this.output_seq.push(`${fac_math(fac_p)}`)
                    }
                }
                if (speedup < 10000 || this.current_ok) {
                    if (skip > 0 && skip_count < skip) {
                        skip_count += 1;
                    } else {
                        fac_p = fac_p || semi_factorization(p)
                        var fac_n = semi_factorization(n)
                        var fac_q = semi_factorization(q)
                        var text1 = `${fac_math(fac_n)} `
                        var text2 = `\\times \\frac{${f[0]}}{${f[1]}} = `
                        var text3 = this.current_ok ? fac_math(fac_p) : `\\frac{${fac_math(fac_p)}}{${fac_math(fac_q)}} `
                        var text4 = ` ${in_text} \\mathbb{N}`
                        this.step_text = text1 + text2 + text3 + text4
                        await this.next_step((this.current_ok ? 1000 : 200) / speedup);
                        if(this.isrunning==false)
                            return;
                        skip_count = 0;
                    }
                }

                n = n2;
                this.pointer = pointer
            }
            var fac = semi_factorization(n, prime_table);
            this.step_text = `Output=${fac_math(fac)}`
            this.isrunning = false;
        },
        math: s => katex.renderToString(s),
        toggle_code_mode() {
            if (this.code_mode == 0) {
                var code_text = $('#code_text').value;
                this.code_errors = Fractran.check_error(code_text);
                if (this.code_errors.length > 0)
                    return false;
                this.code_text = code_text;
            }
            app.code_mode = 1 - app.code_mode;
            return true;
        },
        frac_class(i) {
            return {
                code_frac: true,
                frac_passed: this.pointer > i,
                frac_current_ok: this.pointer == i && this.current_ok,
                frac_current_no: this.pointer == i && !this.current_ok
            }
        }

    },
    data: {
        step_r: null,
        isrunning: false,
        ispausing: false,
        code_mode: 0, // 0 Edit code, 1: View code
        code_text: "",
        code_errors: [],
        current_ok: true,
        input_number: "2",
        output_base: [],
        output_seq: [],
        pointer: -1,
        state: 0,
        step_text: "",
        speedup: 1,
        examples: []
    },
    computed: {
        output_seq_math() {
            return this.output_seq.map(s=>katex.renderToString(s)).join(', ')
        },
        output_base_math() {
            var s = this.output_base.map(n => `${n}^{?}`).join(" ");
            return katex.renderToString(s);
        },
        input_math() {
            var n = Fractran.parse_input(this.input_number);
            var fac = semi_factorization(n, prime_table);
            return katex.renderToString( (n.lt(1e10) ? String(n) + "=" :'') + fac_math(fac))
        },
        step_text_math() {
            return katex.renderToString(this.step_text)
        },
        code() {
            return this.code_text.match(/[123456789]\d*\/[123456789]\d*/g)
                .map(s => s.split('/'))
        },
    }
})

async function fetch_examples(file_name) {
    try {
        //app.examples = await (await fetch(file_name)).json()
        app.examples = default_examples;
        app.load_example(0);
    } catch (e) {
        console.log("unable to fetch examples", e)
    }
}

var input_only = (e, chars) => {
    var valid = chars + " \r\n\x00\x08";
    var k = String.fromCharCode(e.which);
    if (e.altKey || e.metaKey || e.ctrlKey)
        return;
    if (valid.indexOf(k) == -1) e.preventDefault();
}

var default_examples = [{
    "title": "3*2",
    "code_text": "455/33 11/13 1/11 3/7 11/2 1/3",
    "input": "2^3 * 3^2",
    "output_base": ""
},
{
    "title": "23+12",
    "code_text": "2/3",
    "input": "2^23 * 3^12",
    "output_base": ""
},
{
    "title": "Generate primes > 1",
    "code_text": "17/91, 78/85, 19/51, 23/38, 29/33, 77/29, 95/23, 77/19, 1/17, 11/13, 13/11, 15/14, 15/2, 55/1",
    "input": "2^1",
    "output_base": "2"
},
{
    "title": "31÷7",
    "code_text": "91/66, 11/13, 1/33, 85/11, 57/119, 17/19, 11/17, 1/3",
    "input": "2^31 * 3^7 * 11",
    "output_base": ""
},
{
    "title": "Hamming weight of 26=0b11010",
    "code_text": "33/20, 5/11, 13/10, 1/5, 2/3, 10/7, 7/2",
    "input": "2^26",
    "output_base": ""
},
{
    "title": "17-5",
    "code_text": "1/6",
    "input": "2^17 * 3^5",
    "output_base": ""
},
{
    "title": "max(4,7)",
    "code_text": "5/6,5/2,5/3",
    "input": "2^4 * 3^7",
    "output_base": ""
},
{
    "title": "6th Fibonacci number",
    "code_text": "385/39, 77/221, 13/11, 1/13, 51/35, 7/3, 13/2, 1/17",
    "input": "2^6 * 17",
    "output_base": ""
}
]
fetch_examples("example.json")<commit_msg>step/pause/play<commit_after>'use strict';
var $ = document.querySelector.bind(document);
var $$ = document.querySelectorAll.bind(document);
var prime_table = [2];

function construct_prime_table() {
    for (var i = 3; i < 300; i += 2)
        if (bigInt(i).isPrime()) {
            prime_table.push(i);
        }
}
construct_prime_table();

function fac_math(fac) {
    return Object.entries(fac).map(a =>
        String(a[0]) + (a[1] == 1 ? "" : `^{${a[1]}}`)
    ).join(' \\cdot ')
}

function semi_factorization(n0, primes = prime_table) {
    var n = bigInt(n0);
    var i = 0;
    var rtn = {};
    if (n.eq(1)) {
        return {
            1: 1
        }
    }
    while (i < primes.length) {
        var r = n.divmod(primes[i]);
        if (r.remainder.eq(0)) {
            rtn[primes[i]] = (rtn[[primes[i]]] || 0) + 1;
            n = r.quotient;
            if (n.eq(1))
                break;
        } else {
            i += 1;
        }
    }
    if (n.gt(1)) {
        rtn[n] = 1;
    }
    return rtn;
}
var Fractran = {
    parse_input(input_number) {
        var text = input_number.replace(/[*\s]+/g, '*')
        var nums = text.split('*');
        var factors = nums.map(
            s => {
                var v1 = /^[123456789]\d*\^[123456789]\d*$/.test(s);
                var v2 = /^[123456789]\d*$/.test(s);
                if (v1) {
                    var a = s.split('^');
                    return bigInt(a[0]).pow(a[1]);
                }
                if (v2) {
                    return bigInt(s);
                }
            })
        return factors.reduce((a, b) => a.times(b), bigInt(1))
    },
    check_input_error(input_number) {
        var text = input_number.replace(/[*\s]+/g, '*')
        var nums = text.split('*');
        var errors = nums.filter(
            s => {
                if (s === '') return false;
                if (/^[123456789]\d*\^[123456789]\d*$/.test(s))
                    return false;
                if (/^[123456789]\d*$/.test(s))
                    return false;
                return true;
            })
        return errors;
    },
    check_error(code_text) {
        var fracs_text = code_text.replace(/[,\s]+/g, ',')
        var fracs = fracs_text.split(',');
        var errors = fracs.filter(
            s => {
                var v = /^[123456789]\d*\/[123456789]\d*$/.test(s);
                return !v;
            })
        return errors;
    },
    step(pointer, n, code) {
        if (pointer >= code.length) {
            return [pointer, n, 0, 0]
        }
        var f = code[pointer];
        var p = bigInt(n).times(f[0]);
        var q = bigInt(f[1]);
        var r = bigInt.gcd(p, q);
        p = p.divide(r);
        q = q.divide(r);
        if (q.compare(1) == 0) {
            pointer = 0;
            n = p;
        } else {
            pointer = pointer + 1;
        }
        return [pointer, n, p, q]

    }
}

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

var app = new Vue({
    el: '#fractran',

    methods: {
        step(){
            if(!this.isrunning){
                this.run(true)
            }
            else{
                if(this.step_resolve){
                    this.step_resolve()
                    this.step_resolve = null;
                }
            }

        },
        next_step(ms){
            if(this.ispausing){
                return new Promise(r => this.step_resolve=r)
            }
            return timeout(ms)
        },
        load_example(i) {
            this.pointer = -1;
            if (i >= this.examples.length) return;
            if (i < 0) return;
            var ex = this.examples[i];
            $('#input_input').value = ex.input;
            this.input_changed(ex.input);
            $('#output_base_input').value = ex.output_base;
            this.output_base_changed(ex.output_base);
            this.code_text = ex.code_text;
            if (this.code_mode == 0) {
                $('#code_text').value = ex.code_text;
                this.toggle_code_mode()
            }
        },
        output_base_changed(text) {
            this.output_base = (text.match(/\d+/g) || []).map(s => parseInt(s));
        },
        input_changed(text) {
            this.code_errors = Fractran.check_input_error(text);
            if (this.code_errors.length > 0)
                return false;
            this.input_number = text;
            return true;
        },
        restart(){
            this.isrunning = false;
            this.ispausing = false;
            if(this.step_resolve){
                this.step_resolve();
                this.step_resolve = null;
            }

        },
        run_or_pause(){
            if(!this.isrunning){
                this.run(false)
            }
            else{
                this.ispausing = !this.ispausing;
                if(!this.ispausing){
                    if(this.step_resolve)
                        this.step_resolve();
                }
            }

        },
        async run(pausing) {
            this.output_base_changed($('#output_base_input').value);
            if (!this.input_changed($('#input_input').value)) {
                return;
            }
            if (this.code_mode == 0)
                if (!this.toggle_code_mode())
                    return;
            this.isrunning = true;
            this.ispausing = pausing;
            this.output_seq = [];
            var n = Fractran.parse_input(this.input_number);
            var code = this.code_text.match(/[123456789]\d*\/[123456789]\d*/g)
            code = code.map(s => s.split('/').map(n => bigInt(n)));
            this.pointer = 0;
            var pointer = 0,
                n2, p, q
            var skip_count = 0;
            var skip = 0;
            while (this.pointer < code.length) {
                var f = code[pointer];
                [pointer, n2, p, q] = Fractran.step(pointer, n, code);
                var fac_p = null;
                //console.log(pointer, n2.toString(), p.toString(), q.toString())
                this.current_ok = q.compare(1) == 0;
                var in_text = this.current_ok ? "\\in" : "\\not\\in"
                var speedup = this.speedup;
                if (speedup < 0.01) speedup = 1;
                if (speedup >= 20000) {
                    skip = speedup / 10000;
                } else skip = 0;
                if (this.output_base.length > 0 && this.current_ok) {
                    fac_p = semi_factorization(p)
                    if (Object.keys(fac_p).map(s => parseInt(s)).every(k => {
                            return this.output_base.indexOf(k) > -1
                        })) {
                        this.output_seq.push(`${fac_math(fac_p)}`)
                    }
                }
                if (speedup < 10000 || this.current_ok) {
                    if (skip > 0 && skip_count < skip) {
                        skip_count += 1;
                    } else {
                        fac_p = fac_p || semi_factorization(p)
                        var fac_n = semi_factorization(n)
                        var fac_q = semi_factorization(q)
                        var text1 = `${fac_math(fac_n)} `
                        var text2 = `\\times \\frac{${f[0]}}{${f[1]}} = `
                        var text3 = this.current_ok ? fac_math(fac_p) : `\\frac{${fac_math(fac_p)}}{${fac_math(fac_q)}} `
                        var text4 = ` ${in_text} \\mathbb{N}`
                        this.step_text = text1 + text2 + text3 + text4
                        await this.next_step((this.current_ok ? 1000 : 200) / speedup);
                        if(this.isrunning==false)
                            return;
                        skip_count = 0;
                    }
                }

                n = n2;
                this.pointer = pointer
            }
            var fac = semi_factorization(n, prime_table);
            this.step_text = `Output=${fac_math(fac)}`
            this.isrunning = false;
        },
        math: s => katex.renderToString(s),
        toggle_code_mode() {
            if (this.code_mode == 0) {
                var code_text = $('#code_text').value;
                this.code_errors = Fractran.check_error(code_text);
                if (this.code_errors.length > 0)
                    return false;
                this.code_text = code_text;
            }
            app.code_mode = 1 - app.code_mode;
            return true;
        },
        frac_class(i) {
            return {
                code_frac: true,
                frac_passed: this.pointer > i,
                frac_current_ok: this.pointer == i && this.current_ok,
                frac_current_no: this.pointer == i && !this.current_ok
            }
        }

    },
    data: {
        step_resolve: null,
        isrunning: false,
        ispausing: false,
        code_mode: 0, // 0 Edit code, 1: View code
        code_text: "",
        code_errors: [],
        current_ok: true,
        input_number: "2",
        output_base: [],
        output_seq: [],
        pointer: -1,
        state: 0,
        step_text: "",
        speedup: 1,
        examples: []
    },
    computed: {
        output_seq_math() {
            return this.output_seq.map(s=>katex.renderToString(s)).join(', ')
        },
        output_base_math() {
            var s = this.output_base.map(n => `${n}^{?}`).join(" ");
            return katex.renderToString(s);
        },
        input_math() {
            var n = Fractran.parse_input(this.input_number);
            var fac = semi_factorization(n, prime_table);
            return katex.renderToString( (n.lt(1e10) ? String(n) + "=" :'') + fac_math(fac))
        },
        step_text_math() {
            return katex.renderToString(this.step_text)
        },
        code() {
            return this.code_text.match(/[123456789]\d*\/[123456789]\d*/g)
                .map(s => s.split('/'))
        },
    }
})

async function fetch_examples(file_name) {
    try {
        //app.examples = await (await fetch(file_name)).json()
        app.examples = default_examples;
        app.load_example(0);
    } catch (e) {
        console.log("unable to fetch examples", e)
    }
}

var input_only = (e, chars) => {
    var valid = chars + " \r\n\x00\x08";
    var k = String.fromCharCode(e.which);
    if (e.altKey || e.metaKey || e.ctrlKey)
        return;
    if (valid.indexOf(k) == -1) e.preventDefault();
}

var default_examples = [{
    "title": "3*2",
    "code_text": "455/33 11/13 1/11 3/7 11/2 1/3",
    "input": "2^3 * 3^2",
    "output_base": ""
},
{
    "title": "23+12",
    "code_text": "2/3",
    "input": "2^23 * 3^12",
    "output_base": ""
},
{
    "title": "Generate primes > 1",
    "code_text": "17/91, 78/85, 19/51, 23/38, 29/33, 77/29, 95/23, 77/19, 1/17, 11/13, 13/11, 15/14, 15/2, 55/1",
    "input": "2^1",
    "output_base": "2"
},
{
    "title": "31÷7",
    "code_text": "91/66, 11/13, 1/33, 85/11, 57/119, 17/19, 11/17, 1/3",
    "input": "2^31 * 3^7 * 11",
    "output_base": ""
},
{
    "title": "Hamming weight of 26=0b11010",
    "code_text": "33/20, 5/11, 13/10, 1/5, 2/3, 10/7, 7/2",
    "input": "2^26",
    "output_base": ""
},
{
    "title": "17-5",
    "code_text": "1/6",
    "input": "2^17 * 3^5",
    "output_base": ""
},
{
    "title": "max(4,7)",
    "code_text": "5/6,5/2,5/3",
    "input": "2^4 * 3^7",
    "output_base": ""
},
{
    "title": "6th Fibonacci number",
    "code_text": "385/39, 77/221, 13/11, 1/13, 51/35, 3/7, 13/2, 1/17",
    "input": "2^6 * 17",
    "output_base": ""
}
]
fetch_examples("example.json")<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { connect } from 'react-redux'
import { Text, ListView, View, TouchableOpacity } from 'react-native'
import { Actions } from 'react-native-router-flux'

import styles from '../styles/stylesheet'
import strings from '../resources/translations'

class StopRequestView extends Component{
  constructor(props) {
    super(props)

    this.state = {
    }
  }

  render() {
    const goBack = () => Actions.pop();

    return (
      <View style={styles.stopRequestStyle}>
      <View>
        <Text style={{fontSize: 20, textAlign: 'center'}}>{this.props.vehicle.type} {this.props.vehicle.line} {strings.stopsAt} {this.props.stop.stopName} ({this.props.stop.stopId})</Text>
        <TouchableOpacity onPress={goBack}>
          <Text style={{color: '#ff0000', textAlign: 'center'}}>{strings.back}</Text>
        </TouchableOpacity>
        </View>
      </View>
    )
  }
}

export default StopRequestView;
<commit_msg>shows the destination of the selected line<commit_after>import React, { Component } from 'react'
import { connect } from 'react-redux'
import { Text, ListView, View, TouchableOpacity } from 'react-native'
import { Actions } from 'react-native-router-flux'

import styles from '../styles/stylesheet'
import strings from '../resources/translations'

class StopRequestView extends Component{
  constructor(props) {
    super(props)

    this.state = {
    }
  }

  render() {
    const goBack = () => Actions.pop();

    const vehicleTypes = 'tram metro train bus ferry'.split(' ')

    return (
      <View style={styles.stopRequestStyle}>
      <View>
        <Text style={{fontSize: 20, textAlign: 'center'}}>{strings[vehicleTypes[this.props.vehicle.vehicle_type]]} {this.props.vehicle.line} to {this.props.vehicle.destination} {strings.stopsAt} {this.props.stop.stopName} ({this.props.stop.stopId})</Text>
        <TouchableOpacity onPress={goBack}>
          <Text style={{color: '#ff0000', textAlign: 'center'}}>{strings.back}</Text>
        </TouchableOpacity>
        </View>
      </View>
    )
  }
}

export default StopRequestView;
<|endoftext|>