<commit_before>// @flow

const path = require("path"),
  spawn = require("cross-spawn"),
  fs = require("fs-extra"),
  _ = require("lodash"),
  Murmur = require("murmur-hash-js"),
  Compile = require("./Compile.js"),
  Version = require("./version.js"),
  supportsColor = require("supports-color"),
  Runner = require("./runner.js"),
  pipeFilename = require("./pipe-filename.js");

function prepareCompiledJsFile(dest/*:string*/) {
  return Promise.all([
    readUtf8(path.join(__dirname, "..", "templates", "before.js")),
    readUtf8(dest),
    readUtf8(path.join(__dirname, "..", "templates", "after.js"))
  ]).then(([before, content, after]) => {
    return new Promise((resolve, reject) => {
      const finalContent = [
        before,
        "var Elm = (function(module) { ",
        content,
        "return this.Elm;",
        "})({});",
        "var pipeFilename = " + JSON.stringify(pipeFilename) + ";",
        after
      ].join("\n");
      return fs.writeFile(dest, finalContent, (err) => {
        if (err) {
          reject(err);
        } else {
          resolve();
        }
      });
    });
  });
}

function readUtf8(filepath) {
  return new Promise((resolve, reject) => {
    fs.readFile(filepath, {encoding: "utf8"}, (err, contents) =>
      {
        if (err) {
          reject(err);
        } else {
          resolve(contents);
        }
      }
    );
  });
}

function generateElmJson(projectRootDir/*:string*/, testRootDir/*:string*/, pathToElmBinary /*:string*/, filePaths /*:Array<string>*/, hasBeenGivenCustomGlobs /*int*/) {
  const generatedCodeDir = path.resolve(
    path.join(projectRootDir, "elm-stuff", "generated-code", "elm-explorations", "test")
  );
  const elmJsonPath = path.resolve(path.join(projectRootDir, "elm.json"));
  const generatedSrc = path.join(generatedCodeDir, "src");

  var projectElmJson = {};

  try {
    projectElmJson = fs.readJsonSync(elmJsonPath);
  } catch (err) {
    console.error("Error reading elm.json: " + err);
    process.exit(1);
  }
  var isPackageProject = projectElmJson.type === "package";

  // if we were given file globs, we don't need to check the tests/ directory exists
  // this is only for elm applications, which people may need to introduce slowly into their apps
  // for packages, we stick with the existing behaviour and assume tests are in tests/
  if (hasBeenGivenCustomGlobs === false && isPackageProject === false) {
    if (!fs.existsSync(testRootDir)) {
      console.error("Error: " + testRootDir + " does not exist. Please create a tests/ directory in your project root!");
      process.exit(1);
    }

    if (!fs.lstatSync(testRootDir).isDirectory()) {
      console.error("Error: " + testRootDir + " exists, but it is not a directory. Please create a tests/ directory in your project root!");
      process.exit(1);
    }
  }

  fs.mkdirpSync(generatedCodeDir);
  fs.mkdirpSync(generatedSrc);

  var testElmJson = {
    type: "application",
    "source-directories": [], // these are added below
    "elm-version": "0.19.0",
    "dependencies": {
      "direct": {},
      "indirect": {}
    },
    "test-dependencies": {
      "direct": {},
      "indirect": {}
    }
  };

  var nodeTestRunnerElmJsonPath = path.resolve(path.join(__dirname, "..", "elm.json"));
  var nodeTestRunnerElmJson = fs.readJsonSync(nodeTestRunnerElmJsonPath);
  // we want to use the version of elm-explorations/test that the user
  // specifies in their own test-dependencies. everything else needs to
  // be included for the test runner to compile.
  delete nodeTestRunnerElmJson.dependencies.direct['elm-explorations/test'];
  addDirectDependencies(nodeTestRunnerElmJson["dependencies"]["direct"], isPackageProject, testElmJson);
  addIndirectDependencies(nodeTestRunnerElmJson["dependencies"]["indirect"], testElmJson);

  if (isPackageProject) {
    addDirectDependencies(projectElmJson["dependencies"], isPackageProject, testElmJson);
    addDirectDependencies(projectElmJson["test-dependencies"], isPackageProject, testElmJson);
    // package projects don't explicitly list their transitive dependencies,
    // to we have to figure out what they are.  We write the elm.json that
    // we have so far, and run elm to see what it thinks is missing.
    fs.writeFileSync(
      path.join(generatedCodeDir, "elm.json"),
      JSON.stringify(testElmJson, null, 4)
    );
    var missingDeps = askElmForMissingTransitiveDependencies(pathToElmBinary, generatedCodeDir);
    addIndirectDependencies(missingDeps, testElmJson);
  } else {
    addDirectDependencies(projectElmJson["dependencies"]["direct"], isPackageProject, testElmJson);
    addIndirectDependencies(projectElmJson["dependencies"]["indirect"], testElmJson);
    addDirectDependencies(projectElmJson["test-dependencies"]["direct"], isPackageProject, testElmJson);
    addIndirectDependencies(projectElmJson["test-dependencies"]["indirect"], testElmJson);
  }

  // Make all the source-directories absolute, and introduce a new one.
  var projectSourceDirs;
  if (isPackageProject) {
    projectSourceDirs = [ "./src" ];
  } else {
    projectSourceDirs = projectElmJson["source-directories"];
  }
  var sourceDirs = projectSourceDirs.map(
    function(src) {
      return path.resolve(path.join(projectRootDir, src));
    }
  ).concat([testRootDir]);

  testElmJson["source-directories"] = [
    // Include elm-stuff/generated-sources - since we'll be generating sources in there.
    generatedSrc,

    // NOTE: we must include node-test-runner's Elm source as a source-directory
    // instead of adding it as a dependency so that it can include port modules
    path.resolve(path.join(__dirname, "..", "src"))
  ].concat(sourceDirs);

  // When running node-test-runner's own test suite, the node-test-runner/src folder
  // will get added twice: once because it's the source-directory of the packge being tested,
  // and once because elm-test will always add it.
  // To prevent elm from being confused, we need to remove the duplicate when this happens.
  testElmJson["source-directories"] =
    testElmJson["source-directories"].filter(function(value, index, self) {
      return self.indexOf(value) === index;
    });

  // Generate the new elm.json
  fs.writeFileSync(
    path.join(generatedCodeDir, "elm.json"),
    JSON.stringify(testElmJson, null, 4)
  );

  return [generatedCodeDir, generatedSrc, sourceDirs];
}

function addDirectDependencies(deps/*:Object*/, isPackageProject/*:boolean*/, testElmJson/*:Object*/) {
  Object.keys(deps).forEach(function(name) {
    var version = deps[name];
    if (isPackageProject) {
      // Use the lowest version in the range.
      // NOTE: technically this doesn't work if someone does something weird like:
      //
      // "2.0.0 < v < 3.0.0"
      //
      // ...but we're choosing not to support that right now.
      version = version.split(" ")[0];
    }
    if (testElmJson["dependencies"]["direct"].hasOwnProperty(name)) {
      var existingVersion = testElmJson["dependencies"]["direct"][name];

      // If we have a clash, choose the higher of the two versions.
      // This may not work! It's entirely possible that the result won't
      // compile. We're going to try it and see what happens.
      version = Version.getHigherVersion(version, existingVersion);
    }
    testElmJson["dependencies"]["direct"][name] = version;
  });
}

function addIndirectDependencies(deps, testElmJson/*:Object*/) {
  Object.keys(deps).forEach(function(name) {
    if (testElmJson["dependencies"]["direct"].hasOwnProperty(name)) {
      // already a normal dep
    } else {
      var version = deps[name];

      if (testElmJson["dependencies"]["indirect"].hasOwnProperty(name)) {
        var existingVersion = testElmJson["dependencies"]["indirect"][name];

        // If we have a clash, choose the higher of the two versions.
        // This may not work! It's entirely possible that the result won't
        // compile. We're going to try it and see what happens.
        version = Version.getHigherVersion(version, existingVersion);
      }

      testElmJson["dependencies"]["indirect"][name] = version;
    }
  });
}
function askElmForMissingTransitiveDependencies(pathToElmBinary, pathToElmProject) {
  var result = spawn.sync(pathToElmBinary, ["make", "--report=json"], {
    silent: true,
    env: process.env,
    cwd: pathToElmProject
  });

  if (result.stderr == null) {
    console.error("No output received from elm make when searching for indirect dependencies.");
    process.exit(1);
  }

  // TODO: hopefully the next Elm 0.19 beta will print the JSON to stdout instead
  var output = result.stderr.toString();

  // TODO: hopefully the next Elm 0.19 beta will not have this message (only occurs on linux) mixed in with the JSON output
  output = output.replace(/^elm:.*no version information available \(required by elm\)\n/, '');

  var report = JSON.parse(output);
  if (report.type === "error" && report.title === "NO INPUT") {
    // all transtive dependencies are listed already (elm is complaining that we didn't tell it which .elm file to build, which happens after the dependency validations)
    return {};
  } else if (report.type === "error" && report.title === "MISSING DEPENDENCIES") {
    var missingDeps = {};
    // parse the missing dependencies and versions from the error report
    report.message[1].string.replace(/"([^"]*)": "([^"]*)"/g, function(_, name, version) {
      missingDeps[name] = version;
    })
    return missingDeps;
  } else {
    console.error("elm-test internal error: got an unexpected result from 'elm make' when validating transitive dependencies.  Please report this at https://github.com/rtfeldman/node-test-runner/issues");
    process.exit(1);
    return {}; // This makes flow happy because it doesn't know process.exit will stop everything
  }
}

function generateMainModule(fuzz/*:number*/, seed/*:number*/, report/*:string*/, testFilePaths/*:Array<string>*/, tests/*:Array<Object>*/, generatedSrc/*:string*/, processes/*:number*/) {
  // Building things like:
  //
  // import MyTests
  //
  // MyTests.suite
  const imports = _.map(tests, function(test) {
    return "import " + test.name;
  });
  const testList = _.map(tests, function(mod) {
    return (
      '    Test.describe "' +
      mod.name +
      '" [' +
      _.map(mod.tests, function(test) {
        return mod.name + "." + test;
      }).join(",\n    ") +
      "]"
    );
  });

  if (testList.length === 0) {
    const errorMessage =
      testFilePaths.length > 0
        ? "I couldn't find any exposed values of type Test in files matching \"" +
          testFilePaths.toString() +
          '"\n\nMaybe try running elm-test with no arguments?'
        : "I couldn't find any exposed values of type Test in any *.elm files in the tests/ directory of your project's root directory.\n\nTo generate some initial tests to get things going, run elm-test init";

    console.error(errorMessage);
    process.exit(1);
  }

  function sanitizedToString(str) {
    return '"' + str.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"';
  }

  function getReportCode() {
    switch (report) {
      case "json":
        return "JsonReport";
      case "junit":
        return "JUnitReport";
      default:
        if (supportsColor) {
          return "(ConsoleReport UseColor)";
        } else {
          return "(ConsoleReport Monochrome)";
        }
    }
  }

  if (isNaN(seed)) {
    seed = Math.floor(Math.random() * (407199254740991)) + 1000;
  }

  var opts = {
    fuzz: isNaN(fuzz) ? "Nothing" : "Just " + fuzz,
    seed: seed,
    report: getReportCode(),
    paths: testFilePaths.map(sanitizedToString).join(",")
  };

  var optsCode =
    "{ runs = " +
    opts.fuzz +
    ", report = " +
    opts.report +
    ", seed = " +
    opts.seed +
    ", processes = " +
    processes +
    ", paths = [" +
    opts.paths +
    "]}";

  const testFileBody = [
    imports.join("\n"),
    "",
    "import Test.Reporter.Reporter exposing (Report(..))",
    "import Console.Text exposing (UseColor(..))",
    "import Test.Runner.Node",
    "import Test",
    "",
    "main : Test.Runner.Node.TestProgram",
    "main =",
    "    [ " + testList.join(", ") + " ]",
    "        |> Test.concat",
    "        |> Test.Runner.Node.run " + optsCode
  ].join("\n");

  // Generate a filename that incorporates the hash of file contents.
  // This way, if you run e.g. `elm-test Foo.elm` and then `elm-test Bar.elm`
  // and then re-run `elm-test Foo.elm` we still have a cached `Main` for
  // `Foo.elm` (assuming none of its necessary imports have changed - and
  // why would they?) so we don't have to recompile it.
  const salt = Murmur.murmur3(testFileBody);
  const moduleName = "Main" + salt;
  const mainPath = path.join(generatedSrc, "Test", "Generated");
  const mainFile = path.join(mainPath, moduleName + ".elm");
  // We'll be putting the generated Main in something like this:
  //
  // my-project-name/elm-stuff/generated-code/elm-community/elm-test/src/Test/Generated/Main123456.elm
  const testFileContents = [
    "module Test.Generated." + moduleName + " exposing (main)",
    testFileBody
  ].join("\n\n");

  // Make sure src/Test/Generated/ exists so we can write the file there.
  fs.mkdirpSync(mainPath);

  // Always write the file, in order to update its timestamp. This is important,
  // because if we run `elm-make Main123456.elm` and that file's timestamp did
  // not change, elm-make will short-circuit and not recompile *anything* - even
  // if some of Main's dependencies (such as an individual test file) changed.
  fs.writeFileSync(mainFile, testFileContents);

  return mainFile;
}

module.exports = {prepareCompiledJsFile, generateElmJson, generateMainModule};

<commit_msg>Fix incorrect code and comment<commit_after>// @flow

const path = require("path"),
  spawn = require("cross-spawn"),
  fs = require("fs-extra"),
  _ = require("lodash"),
  Murmur = require("murmur-hash-js"),
  Compile = require("./Compile.js"),
  Version = require("./version.js"),
  supportsColor = require("supports-color"),
  Runner = require("./runner.js"),
  pipeFilename = require("./pipe-filename.js");

function prepareCompiledJsFile(dest/*:string*/) {
  return Promise.all([
    readUtf8(path.join(__dirname, "..", "templates", "before.js")),
    readUtf8(dest),
    readUtf8(path.join(__dirname, "..", "templates", "after.js"))
  ]).then(([before, content, after]) => {
    return new Promise((resolve, reject) => {
      const finalContent = [
        before,
        "var Elm = (function(module) { ",
        content,
        "return this.Elm;",
        "})({});",
        "var pipeFilename = " + JSON.stringify(pipeFilename) + ";",
        after
      ].join("\n");
      return fs.writeFile(dest, finalContent, (err) => {
        if (err) {
          reject(err);
        } else {
          resolve();
        }
      });
    });
  });
}

function readUtf8(filepath) {
  return new Promise((resolve, reject) => {
    fs.readFile(filepath, {encoding: "utf8"}, (err, contents) =>
      {
        if (err) {
          reject(err);
        } else {
          resolve(contents);
        }
      }
    );
  });
}

function generateElmJson(projectRootDir/*:string*/, testRootDir/*:string*/, pathToElmBinary /*:string*/, filePaths /*:Array<string>*/, hasBeenGivenCustomGlobs /*int*/) {
  const generatedCodeDir = path.resolve(
    path.join(projectRootDir, "elm-stuff", "generated-code", "elm-explorations", "test")
  );
  const elmJsonPath = path.resolve(path.join(projectRootDir, "elm.json"));
  const generatedSrc = path.join(generatedCodeDir, "src");

  var projectElmJson = {};

  try {
    projectElmJson = fs.readJsonSync(elmJsonPath);
  } catch (err) {
    console.error("Error reading elm.json: " + err);
    process.exit(1);
  }
  var isPackageProject = projectElmJson.type === "package";

  // if we were given file globs, we don't need to check the tests/ directory exists
  // this is only for elm applications, which people may need to introduce slowly into their apps
  // for packages, we stick with the existing behaviour and assume tests are in tests/ so do the check always
  if (hasBeenGivenCustomGlobs === false || isPackageProject === true) {
    if (!fs.existsSync(testRootDir)) {
      console.error("Error: " + testRootDir + " does not exist. Please create a tests/ directory in your project root!");
      process.exit(1);
    }

    if (!fs.lstatSync(testRootDir).isDirectory()) {
      console.error("Error: " + testRootDir + " exists, but it is not a directory. Please create a tests/ directory in your project root!");
      process.exit(1);
    }
  }

  fs.mkdirpSync(generatedCodeDir);
  fs.mkdirpSync(generatedSrc);

  var testElmJson = {
    type: "application",
    "source-directories": [], // these are added below
    "elm-version": "0.19.0",
    "dependencies": {
      "direct": {},
      "indirect": {}
    },
    "test-dependencies": {
      "direct": {},
      "indirect": {}
    }
  };

  var nodeTestRunnerElmJsonPath = path.resolve(path.join(__dirname, "..", "elm.json"));
  var nodeTestRunnerElmJson = fs.readJsonSync(nodeTestRunnerElmJsonPath);
  // we want to use the version of elm-explorations/test that the user
  // specifies in their own test-dependencies. everything else needs to
  // be included for the test runner to compile.
  delete nodeTestRunnerElmJson.dependencies.direct['elm-explorations/test'];
  addDirectDependencies(nodeTestRunnerElmJson["dependencies"]["direct"], isPackageProject, testElmJson);
  addIndirectDependencies(nodeTestRunnerElmJson["dependencies"]["indirect"], testElmJson);

  if (isPackageProject) {
    addDirectDependencies(projectElmJson["dependencies"], isPackageProject, testElmJson);
    addDirectDependencies(projectElmJson["test-dependencies"], isPackageProject, testElmJson);
    // package projects don't explicitly list their transitive dependencies,
    // to we have to figure out what they are.  We write the elm.json that
    // we have so far, and run elm to see what it thinks is missing.
    fs.writeFileSync(
      path.join(generatedCodeDir, "elm.json"),
      JSON.stringify(testElmJson, null, 4)
    );
    var missingDeps = askElmForMissingTransitiveDependencies(pathToElmBinary, generatedCodeDir);
    addIndirectDependencies(missingDeps, testElmJson);
  } else {
    addDirectDependencies(projectElmJson["dependencies"]["direct"], isPackageProject, testElmJson);
    addIndirectDependencies(projectElmJson["dependencies"]["indirect"], testElmJson);
    addDirectDependencies(projectElmJson["test-dependencies"]["direct"], isPackageProject, testElmJson);
    addIndirectDependencies(projectElmJson["test-dependencies"]["indirect"], testElmJson);
  }

  // Make all the source-directories absolute, and introduce a new one.
  var projectSourceDirs;
  if (isPackageProject) {
    projectSourceDirs = [ "./src" ];
  } else {
    projectSourceDirs = projectElmJson["source-directories"];
  }
  var sourceDirs = projectSourceDirs.map(
    function(src) {
      return path.resolve(path.join(projectRootDir, src));
    }
  ).concat([testRootDir]);

  testElmJson["source-directories"] = [
    // Include elm-stuff/generated-sources - since we'll be generating sources in there.
    generatedSrc,

    // NOTE: we must include node-test-runner's Elm source as a source-directory
    // instead of adding it as a dependency so that it can include port modules
    path.resolve(path.join(__dirname, "..", "src"))
  ].concat(sourceDirs);

  // When running node-test-runner's own test suite, the node-test-runner/src folder
  // will get added twice: once because it's the source-directory of the packge being tested,
  // and once because elm-test will always add it.
  // To prevent elm from being confused, we need to remove the duplicate when this happens.
  testElmJson["source-directories"] =
    testElmJson["source-directories"].filter(function(value, index, self) {
      return self.indexOf(value) === index;
    });

  // Generate the new elm.json
  fs.writeFileSync(
    path.join(generatedCodeDir, "elm.json"),
    JSON.stringify(testElmJson, null, 4)
  );

  return [generatedCodeDir, generatedSrc, sourceDirs];
}

function addDirectDependencies(deps/*:Object*/, isPackageProject/*:boolean*/, testElmJson/*:Object*/) {
  Object.keys(deps).forEach(function(name) {
    var version = deps[name];
    if (isPackageProject) {
      // Use the lowest version in the range.
      // NOTE: technically this doesn't work if someone does something weird like:
      //
      // "2.0.0 < v < 3.0.0"
      //
      // ...but we're choosing not to support that right now.
      version = version.split(" ")[0];
    }
    if (testElmJson["dependencies"]["direct"].hasOwnProperty(name)) {
      var existingVersion = testElmJson["dependencies"]["direct"][name];

      // If we have a clash, choose the higher of the two versions.
      // This may not work! It's entirely possible that the result won't
      // compile. We're going to try it and see what happens.
      version = Version.getHigherVersion(version, existingVersion);
    }
    testElmJson["dependencies"]["direct"][name] = version;
  });
}

function addIndirectDependencies(deps, testElmJson/*:Object*/) {
  Object.keys(deps).forEach(function(name) {
    if (testElmJson["dependencies"]["direct"].hasOwnProperty(name)) {
      // already a normal dep
    } else {
      var version = deps[name];

      if (testElmJson["dependencies"]["indirect"].hasOwnProperty(name)) {
        var existingVersion = testElmJson["dependencies"]["indirect"][name];

        // If we have a clash, choose the higher of the two versions.
        // This may not work! It's entirely possible that the result won't
        // compile. We're going to try it and see what happens.
        version = Version.getHigherVersion(version, existingVersion);
      }

      testElmJson["dependencies"]["indirect"][name] = version;
    }
  });
}
function askElmForMissingTransitiveDependencies(pathToElmBinary, pathToElmProject) {
  var result = spawn.sync(pathToElmBinary, ["make", "--report=json"], {
    silent: true,
    env: process.env,
    cwd: pathToElmProject
  });

  if (result.stderr == null) {
    console.error("No output received from elm make when searching for indirect dependencies.");
    process.exit(1);
  }

  // TODO: hopefully the next Elm 0.19 beta will print the JSON to stdout instead
  var output = result.stderr.toString();

  // TODO: hopefully the next Elm 0.19 beta will not have this message (only occurs on linux) mixed in with the JSON output
  output = output.replace(/^elm:.*no version information available \(required by elm\)\n/, '');

  var report = JSON.parse(output);
  if (report.type === "error" && report.title === "NO INPUT") {
    // all transtive dependencies are listed already (elm is complaining that we didn't tell it which .elm file to build, which happens after the dependency validations)
    return {};
  } else if (report.type === "error" && report.title === "MISSING DEPENDENCIES") {
    var missingDeps = {};
    // parse the missing dependencies and versions from the error report
    report.message[1].string.replace(/"([^"]*)": "([^"]*)"/g, function(_, name, version) {
      missingDeps[name] = version;
    })
    return missingDeps;
  } else {
    console.error("elm-test internal error: got an unexpected result from 'elm make' when validating transitive dependencies.  Please report this at https://github.com/rtfeldman/node-test-runner/issues");
    process.exit(1);
    return {}; // This makes flow happy because it doesn't know process.exit will stop everything
  }
}

function generateMainModule(fuzz/*:number*/, seed/*:number*/, report/*:string*/, testFilePaths/*:Array<string>*/, tests/*:Array<Object>*/, generatedSrc/*:string*/, processes/*:number*/) {
  // Building things like:
  //
  // import MyTests
  //
  // MyTests.suite
  const imports = _.map(tests, function(test) {
    return "import " + test.name;
  });
  const testList = _.map(tests, function(mod) {
    return (
      '    Test.describe "' +
      mod.name +
      '" [' +
      _.map(mod.tests, function(test) {
        return mod.name + "." + test;
      }).join(",\n    ") +
      "]"
    );
  });

  if (testList.length === 0) {
    const errorMessage =
      testFilePaths.length > 0
        ? "I couldn't find any exposed values of type Test in files matching \"" +
          testFilePaths.toString() +
          '"\n\nMaybe try running elm-test with no arguments?'
        : "I couldn't find any exposed values of type Test in any *.elm files in the tests/ directory of your project's root directory.\n\nTo generate some initial tests to get things going, run elm-test init";

    console.error(errorMessage);
    process.exit(1);
  }

  function sanitizedToString(str) {
    return '"' + str.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"';
  }

  function getReportCode() {
    switch (report) {
      case "json":
        return "JsonReport";
      case "junit":
        return "JUnitReport";
      default:
        if (supportsColor) {
          return "(ConsoleReport UseColor)";
        } else {
          return "(ConsoleReport Monochrome)";
        }
    }
  }

  if (isNaN(seed)) {
    seed = Math.floor(Math.random() * (407199254740991)) + 1000;
  }

  var opts = {
    fuzz: isNaN(fuzz) ? "Nothing" : "Just " + fuzz,
    seed: seed,
    report: getReportCode(),
    paths: testFilePaths.map(sanitizedToString).join(",")
  };

  var optsCode =
    "{ runs = " +
    opts.fuzz +
    ", report = " +
    opts.report +
    ", seed = " +
    opts.seed +
    ", processes = " +
    processes +
    ", paths = [" +
    opts.paths +
    "]}";

  const testFileBody = [
    imports.join("\n"),
    "",
    "import Test.Reporter.Reporter exposing (Report(..))",
    "import Console.Text exposing (UseColor(..))",
    "import Test.Runner.Node",
    "import Test",
    "",
    "main : Test.Runner.Node.TestProgram",
    "main =",
    "    [ " + testList.join(", ") + " ]",
    "        |> Test.concat",
    "        |> Test.Runner.Node.run " + optsCode
  ].join("\n");

  // Generate a filename that incorporates the hash of file contents.
  // This way, if you run e.g. `elm-test Foo.elm` and then `elm-test Bar.elm`
  // and then re-run `elm-test Foo.elm` we still have a cached `Main` for
  // `Foo.elm` (assuming none of its necessary imports have changed - and
  // why would they?) so we don't have to recompile it.
  const salt = Murmur.murmur3(testFileBody);
  const moduleName = "Main" + salt;
  const mainPath = path.join(generatedSrc, "Test", "Generated");
  const mainFile = path.join(mainPath, moduleName + ".elm");
  // We'll be putting the generated Main in something like this:
  //
  // my-project-name/elm-stuff/generated-code/elm-community/elm-test/src/Test/Generated/Main123456.elm
  const testFileContents = [
    "module Test.Generated." + moduleName + " exposing (main)",
    testFileBody
  ].join("\n\n");

  // Make sure src/Test/Generated/ exists so we can write the file there.
  fs.mkdirpSync(mainPath);

  // Always write the file, in order to update its timestamp. This is important,
  // because if we run `elm-make Main123456.elm` and that file's timestamp did
  // not change, elm-make will short-circuit and not recompile *anything* - even
  // if some of Main's dependencies (such as an individual test file) changed.
  fs.writeFileSync(mainFile, testFileContents);

  return mainFile;
}

module.exports = {prepareCompiledJsFile, generateElmJson, generateMainModule};

<|endoftext|>


<commit_before>/* Import dependencies */
const async = require('async');
const readDataFile = require('../utils/readDataFile.js');
const lowerCaseFields = require('../utils/lowerCaseFields.js');
const titleCaseFields = require('../utils/titleCaseFields.js');
const dateFormatFields = require('../utils/dateFormatFields.js');
const Batch = require('./Batch.js');

/* Create importer class */
class Importer {
  constructor() {
    this.db = null;
  }

  setDatabase( db ) {
    this.db = db;
  }

  importFile( item, callback ) {
    /* Create the database connection */
    const collection = this.db.collection( item.collection );
    /* Delete any existing items */
    collection.deleteMany({}, ( err, response ) => {
      /* Get the array of files */
      const files = item.files ? item.files : [item.file];
      /* Fetch each file */
      async.each( files, ( file, callback ) => {
        /* Create some variables to store statistics */
        let count = 0;
        /* Create a new batch with batch size of 10,000 */
        const batch = new Batch( 10000 );
        /* Set the batch full handler */
        batch.setBatchFullHandler( batchItems => {
          /* Insert the records into the database */
          batchInsert( this.db, item.collection, batchItems );
          /* Print stats */
          console.log( `${count} ${item.collection} records imported` );
        });

        console.log( `Importing ${item.collection} from ${file}` );
        /* Read the data file */
        readDataFile(file, entry => {
          /* Increment the count */
          count++;
          /* Format the item so it's a bit nicer */
          let formattedEntry = formatEntry(item, entry);
          /* Add the entry to the batch */
          batch.addItem( formattedEntry );
        }, () => {
          /* Process the batch once more to process any remaining items */
          batch.process();
          console.log( `\nImported ${item.collection} from ${file}` );
          callback();
        });
      }, callback );
    });
  }
}

/* Export the Importer class */
module.exports = Importer;

/* This function standardises fields */
formatEntry = ( item, entry ) => {
  entry = lowerCaseFields(entry);

  if ( item.format != null && item.format === false ) {
    return entry;
  }

  entry = titleCaseFields({
    locality_name: true,
    name: true,
    description: true,
    state_name: true,
    building_name: true,
    street_name: true,
  }, entry);

  entry = dateFormatFields({
    date_created: true,
    date_retired: true,
    date_last_modified: true,
  }, entry);

  return entry;
}

/* This function provides a method to batch insert documents into a collection */
batchInsert = ( db, collectionName, docs ) => {
  const collection = db.collection( collectionName );
  collection.insert( docs, {
    ordered: false,
  });
}
<commit_msg>Improved importer<commit_after>/* Import dependencies */
const async = require('async');
const readDataFile = require('../utils/readDataFile.js');
const lowerCaseFields = require('../utils/lowerCaseFields.js');
const titleCaseFields = require('../utils/titleCaseFields.js');
const dateFormatFields = require('../utils/dateFormatFields.js');
const Batch = require('./Batch.js');

/* Create importer class */
class Importer {
  constructor() {
    this.db = null;
  }

  setDatabase( db ) {
    this.db = db;
  }

  importFile( item, callback ) {
    /* Create the database connection */
    const collection = this.db.collection( item.collection );

    /* Delete any existing items */
    collection.deleteMany({}, ( err, response ) => {
      /* Get the array of files */
      const files = item.files ? item.files : [item.file];

      /* Fetch each file */
      async.each( files, ( file, callback ) => {
        /* Create some variables to store statistics */
        let count = 0;

        /* Create a new batch with batch size of 10,000 */
        const batch = new Batch( 10000 );

        /* Set the batch full handler */
        batch.setBatchFullHandler( batchItems => {
          /* Insert the records into the database */
          batchInsert( this.db, item.collection, batchItems );

          /* Print stats */
          console.log( `${count} ${item.collection} records imported` );
        });

        console.log( `Importing ${item.collection} from ${file}` );

        /* Read the data file */
        readDataFile(file, entry => {
          /* Increment the count */
          count++;

          /* Format the item so it's a bit nicer */
          let formattedEntry = formatEntry(item, entry);

          /* Add the entry to the batch */
          batch.addItem( formattedEntry );
        }, () => {
          /* Process the batch once more to process any remaining items */
          batch.process();

          console.log( `\nImported ${item.collection} from ${file}` );
          callback();
        });
      }, callback );
    });
  }
}

/* Export the Importer class */
module.exports = Importer;

/* This function standardises fields */
formatEntry = ( item, entry ) => {
  entry = lowerCaseFields(entry);

  if ( item.format != null && item.format === false ) {
    return entry;
  }

  entry = titleCaseFields({
    locality_name: true,
    name: true,
    description: true,
    state_name: true,
    building_name: true,
    street_name: true,
  }, entry);

  entry = dateFormatFields({
    date_created: true,
    date_retired: true,
    date_last_modified: true,
  }, entry);

  return entry;
}

/* This function provides a method to batch insert documents into a collection */
batchInsert = ( db, collectionName, docs ) => {
  const collection = db.collection( collectionName );
  collection.insert( docs, {
    ordered: false,
  });
}
<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const process = require('process');

const escapeRegExp = require('lodash.escaperegexp');
const xRegExp = require('xregexp');

const ImportStatement = require('./ImportStatement');
const JsModule = require('./JsModule');

// @param pathToNormalize [String]
// @return [String]
function normalizePath(pathToNormalize) {
  if (!pathToNormalize) {
    return '';
  }
  return pathToNormalize.replace(/^\.\/?/, '');
}

// @param directory [String]
// @return [String, nil]
function findIndex(directory) {
  return ['index.js', 'index.jsx'].find(indexFile => (
    fs.existsSync(`${directory}/${indexFile}`)
  ));
}

// @param file_path [String]
// @param strip_file_extensions [Array]
// @return [String, String]
function resolveImportPathAndMain(filePath, stripFileExtensions) {
  if (filePath.endsWith('/package.json')) {
    if (!fs.existsSync(path)) {
      return [undefined, undefined];
    }

    const fileContents = File.read(filePath);
    if (!fileContents.trim().length) {
      return [null, null];
    }

    let mainFile = JSON.parse(fileContents).main;
    const match = xRegExp.exec(
      filePath, xRegExp('(?<package>.*)/package\.json'));

    if (!mainFile) {
      const indexFile = findIndex(match.package);
      if (!indexFile) {
        return [null, null];
      }
      mainFile = indexFile;
    }

    if (fs.lstatSync(`${match.package}/${mainFile}`).isDirectory()) {
      // The main in package.json refers to a directory, so we want to
      // resolve it to an index file.
      const indexFile = findIndex(`${match.package}/${mainFile}`);
      if (indexFile) {
        mainFile += `/${indexFile}`;
      }
    }

    return [match.package, mainFile];
  }

  const match = xRegExp.exec(filePath, xRegExp('(.*)/(index\.js[^/]*)$'));
  if (match) {
    return [match[1], match[2]];
  }

  const extensions = stripFileExtensions.map(ext => escapeRegExp(ext));
  const importPath = filePath.replace(RegExp(`(${extensions.join('|')})$`), '');
  return [importPath, null];
}

// Class that represents a js module found in the file system
class JSModule {
  // @param lookup_path [String] the lookup path in which this module was found
  // @param relative_file_path [String] a full path to the file, relative to
  //   the project root.
  // @param strip_file_extensions [Array] a list of file extensions to strip,
  //   e.g. ['.js', '.jsx']
  // @param make_relative_to [String|nil] a path to a different file which the
  //   resulting import path should be relative to.
  // @param strip_from_path [String]
  static construct({
    lookupPath,
    relativeFilePath,
    stripFileExtensions,
    makeRelativeTo,
    stripFromPath,
  }) {
    const jsModule = new JsModule();
    jsModule.lookupPath = normalizePath(lookupPath);
    jsModule.filePath = normalizePath(relativeFilePath);

    const importPathAndMainFile = resolveImportPathAndMain(
      jsModule.filePath, stripFileExtensions);
    let importPath = importPathAndMainFile[0];
    const mainFile = importPathAndMainFile[1];

    if (!importPath) {
      return null;
    }

    importPath = importPath.replace(
      RegExp(`^${escapeRegExp(jsModule.lookupPath)}`), '');

    jsModule.importPath = importPath;
    jsModule.mainFile = mainFile;
    if (makeRelativeTo) {
      jsModule.makeRelativeTo(makeRelativeTo);
    } else {
      jsModule.stripFromPath(stripFromPath);
    }
    return jsModule;
  }

  // @param import_path [String]
  constructor({ importPath }) {
    this.importPath = importPath;
  }

  // @param makeRelativeToPath [String]
  makeRelativeTo(makeRelativeToPath) {
    if (!this.lookupPath) {
      return;
    }

    // First, strip out any absolute path up until the current directory
    let makeRelativeTo = makeRelativeToPath.replace(`${process.cwd()}/`, '');

    // Ignore if the file to relate to is part of a different lookupPath
    if (!makeRelativeTo.startsWith(this.lookupPath)) {
      return;
    }

    // Strip out the lookupPath
    makeRelativeTo = makeRelativeTo.replace(
      RegExp(`^${escapeRegExp(this.lookupPath)}/`), '');

    let importPath = path.relative(this.importPath, makeRelativeTo);

    // `path.relative` will not add "./" automatically
    if (!importPath.startsWith('.')) {
      importPath = `./${importPath}`;
    }

    this.importPath = importPath;
  }

  // @param prefix [String]
  stripFromPath(prefix) {
    if (!prefix) {
      return;
    }
    this.importPath = this.importPath.replace(
      RegExp(`^${escapeRegExp(prefix)}`), '');
  }

  // @return [String] a readable description of the module
  displayName() {
    const parts = [this.importPath];
    if (this.mainFile) {
      parts.push(` (main: ${this.mainFile})`);
    }
    return parts.join('');
  }

  // @param path_to_current_file [String]
  // @return [String]
  openFilePath(pathToCurrentFile) {
    if (this.filePath) {
      // There is a filePath. This happens for JSModules that are not aliases.
      if (!this.filePath.startsWith('/package.json')) {
        return this.filePath;
      }

      // The filePath points to a package.json file, so we want to look in
      // that package.json file for a `main` configuration value and open that
      // file instead.
      return this.filePath.replace(/package\.json$/, this.mainFile);
    }

    // There is no file_path. This likely means that we are working with an
    // alias, so we want to expand it to a full path if we can.
    if (this.importPath.startsWith('.')) {
      // The import path in the alias starts with a ".", which means that it is
      // relative to the current file. In order to open this file, we need to
      // expand it to a full path.
      return path.resolve(path.dirname(pathToCurrentFile), this.importPath);
    }

    // This is likely an alias that points to a package, so let's try to find
    // its main file from its package.json file.
    const filePath = `node_modules/${this.importPath}/package.json`;
    const main = resolveImportPathAndMain(filePath, [])[1];
    if (main) {
      return `node_modules/${this.importPath}/${main}`;
    }

    return this.importPath;
  }

  // @param variable_name [String]
  // @param config [ImportJS::Configuration]
  // @return [ImportJS::ImportStatement]
  toImportStatement(variableName, config) {
    let namedImports;
    let defaultImport;
    if (this.hasNamedExports) {
      namedImports = [variableName];
    } else {
      defaultImport = variableName;
    }

    return new ImportStatement({
      declarationKeyword:
        config.get('declaration_keyword', { fromFile: this.filePath }),
      defaultImport,
      importFunction: config.get('import_function', { fromFile: this.filePath }),
      namedImports,
      path: this.importPath,
    });
  }
}

module.exports = JSModule;
<commit_msg>Fix JsModule for node<commit_after>'use strict';

const fs = require('fs');
const path = require('path');

const escapeRegExp = require('lodash.escaperegexp');
const xRegExp = require('xregexp');

const ImportStatement = require('./ImportStatement');
const JsModule = require('./JsModule');

// @param pathToNormalize [String]
// @return [String]
function normalizePath(pathToNormalize) {
  if (!pathToNormalize) {
    return '';
  }
  return pathToNormalize.replace(/^\.\/?/, '');
}

// @param directory [String]
// @return [String, nil]
function findIndex(directory) {
  return ['index.js', 'index.jsx'].find(indexFile => (
    fs.existsSync(`${directory}/${indexFile}`)
  ));
}

// @param file_path [String]
// @param strip_file_extensions [Array]
// @return [String, String]
function resolveImportPathAndMain(filePath, stripFileExtensions) {
  if (filePath.endsWith('/package.json')) {
    if (!fs.existsSync(path)) {
      return [undefined, undefined];
    }

    const fileContents = File.read(filePath);
    if (!fileContents.trim().length) {
      return [null, null];
    }

    let mainFile = JSON.parse(fileContents).main;
    const match = xRegExp.exec(
      filePath, xRegExp('(?<package>.*)/package\.json'));

    if (!mainFile) {
      const indexFile = findIndex(match.package);
      if (!indexFile) {
        return [null, null];
      }
      mainFile = indexFile;
    }

    if (fs.lstatSync(`${match.package}/${mainFile}`).isDirectory()) {
      // The main in package.json refers to a directory, so we want to
      // resolve it to an index file.
      const indexFile = findIndex(`${match.package}/${mainFile}`);
      if (indexFile) {
        mainFile += `/${indexFile}`;
      }
    }

    return [match.package, mainFile];
  }

  const match = xRegExp.exec(filePath, xRegExp('(.*)/(index\.js[^/]*)$'));
  if (match) {
    return [match[1], match[2]];
  }

  const extensions = stripFileExtensions.map(ext => escapeRegExp(ext));
  const importPath = filePath.replace(RegExp(`(${extensions.join('|')})$`), '');
  return [importPath, null];
}

// Class that represents a js module found in the file system
class JSModule {
  // @param lookup_path [String] the lookup path in which this module was found
  // @param relative_file_path [String] a full path to the file, relative to
  //   the project root.
  // @param strip_file_extensions [Array] a list of file extensions to strip,
  //   e.g. ['.js', '.jsx']
  // @param make_relative_to [String|nil] a path to a different file which the
  //   resulting import path should be relative to.
  // @param strip_from_path [String]
  static construct(opts) {
    const jsModule = new JsModule();
    jsModule.lookupPath = normalizePath(opts.lookupPath);
    jsModule.filePath = normalizePath(opts.relativeFilePath);

    const importPathAndMainFile = resolveImportPathAndMain(
      jsModule.filePath, opts.stripFileExtensions);
    let importPath = importPathAndMainFile[0];
    const mainFile = importPathAndMainFile[1];

    if (!importPath) {
      return null;
    }

    importPath = importPath.replace(
      RegExp(`^${escapeRegExp(jsModule.lookupPath)}`), '');

    jsModule.importPath = importPath;
    jsModule.mainFile = mainFile;
    if (opts.makeRelativeTo) {
      jsModule.makeRelativeTo(opts.makeRelativeTo);
    } else {
      jsModule.stripFromPath(opts.stripFromPath);
    }
    return jsModule;
  }

  // @param import_path [String]
  constructor(opts) {
    this.importPath = opts.importPath;
  }

  // @param makeRelativeToPath [String]
  makeRelativeTo(makeRelativeToPath) {
    if (!this.lookupPath) {
      return;
    }

    // First, strip out any absolute path up until the current directory
    let makeRelativeTo = makeRelativeToPath.replace(`${process.cwd()}/`, '');

    // Ignore if the file to relate to is part of a different lookupPath
    if (!makeRelativeTo.startsWith(this.lookupPath)) {
      return;
    }

    // Strip out the lookupPath
    makeRelativeTo = makeRelativeTo.replace(
      RegExp(`^${escapeRegExp(this.lookupPath)}/`), '');

    let importPath = path.relative(this.importPath, makeRelativeTo);

    // `path.relative` will not add "./" automatically
    if (!importPath.startsWith('.')) {
      importPath = `./${importPath}`;
    }

    this.importPath = importPath;
  }

  // @param prefix [String]
  stripFromPath(prefix) {
    if (!prefix) {
      return;
    }
    this.importPath = this.importPath.replace(
      RegExp(`^${escapeRegExp(prefix)}`), '');
  }

  // @return [String] a readable description of the module
  displayName() {
    const parts = [this.importPath];
    if (this.mainFile) {
      parts.push(` (main: ${this.mainFile})`);
    }
    return parts.join('');
  }

  // @param path_to_current_file [String]
  // @return [String]
  openFilePath(pathToCurrentFile) {
    if (this.filePath) {
      // There is a filePath. This happens for JSModules that are not aliases.
      if (!this.filePath.startsWith('/package.json')) {
        return this.filePath;
      }

      // The filePath points to a package.json file, so we want to look in
      // that package.json file for a `main` configuration value and open that
      // file instead.
      return this.filePath.replace(/package\.json$/, this.mainFile);
    }

    // There is no file_path. This likely means that we are working with an
    // alias, so we want to expand it to a full path if we can.
    if (this.importPath.startsWith('.')) {
      // The import path in the alias starts with a ".", which means that it is
      // relative to the current file. In order to open this file, we need to
      // expand it to a full path.
      return path.resolve(path.dirname(pathToCurrentFile), this.importPath);
    }

    // This is likely an alias that points to a package, so let's try to find
    // its main file from its package.json file.
    const filePath = `node_modules/${this.importPath}/package.json`;
    const main = resolveImportPathAndMain(filePath, [])[1];
    if (main) {
      return `node_modules/${this.importPath}/${main}`;
    }

    return this.importPath;
  }

  // @param variable_name [String]
  // @param config [ImportJS::Configuration]
  // @return [ImportJS::ImportStatement]
  toImportStatement(variableName, config) {
    let namedImports;
    let defaultImport;
    if (this.hasNamedExports) {
      namedImports = [variableName];
    } else {
      defaultImport = variableName;
    }

    return new ImportStatement({
      declarationKeyword:
        config.get('declaration_keyword', { fromFile: this.filePath }),
      defaultImport,
      importFunction: config.get('import_function', { fromFile: this.filePath }),
      namedImports,
      path: this.importPath,
    });
  }
}

module.exports = JSModule;
<|endoftext|>


<commit_before>$(document).ready(function() {
    function t(t) {
        return !isNaN(parseFloat(t)) && isFinite(t)
    }

    function a() {
        var a = 0,
            i = 0,
            e = 0;
        $("#gpa").find("tr").each(function() {
            var d = $(this).find("input.credit").val(),
                l = $(this).find("input.grade").val();
            ("O" == l || "o" == l || "10" == l) && (l = 10), ("a+" == l || "A+" == l || "9" == l) && (l = 9), ("A" == l || "a" == l || "8" == l) && (l = 8), ("b+" == l || "B+" == l || "7" == l) && (l = 7), ("c" == l || "C" == l || "6" == l) && (l = 6), ("d" == l || "D" == l || "5" == l) && (l = 5), ("p" == l || "P" == l || "4" == l) && (l = 4);
            var n = d * l;
            $(this).find("input.row-total").val(n ? n : ""), i += t(l) ? parseInt(l, 10) : 0, a += t(d) ? parseInt(d, 10) : 0, e += t(n) ? n : 0
        }), $("#credit-grand-total").html("Total Credits: " + a), $("#table-grand-total").html("GPA: " + (e / a).toFixed(3)), $("#grade-grand-total").html("Total Grades: " + e)
    }

    function i() {
        var t = $("
" + (d + 1) + "

<input type='text' id='" + (d + 1) + "Code' tabIndex='" + l++ + "'>Code

<input class='credit' type='text' tabIndex='" + l++ + "' id='" + (d + 1) + "Credits'>Credits

<input class='grade' maxlength='2' type='text' tabIndex='" + l++ + "' id='" + (d + 1) + "Grade'>Grade

<input class='row-total' type='text' readonly tabIndex='-1'>

");
        $("#gpatable").append(t), d++
    }

    function e() {
        d > 1 && ($("#gpatable").find("tr").last().remove(), d--, a())
    }
    $(".button-collapse").sideNav();
    var d = 5,
        l = 15;
    $(function() {
        $("#gpa").on("keyup", ".calculation", a), $("#gpa").on("keyup blur", ".form-control", a), $("#gpa").on("keyup", ".grade:last", function() {
            i()
        }), $("#add_row").on("click", function() {
            i()
        }), $("#delete_row").on("click", function() {
            e()
        })
    }), $("#gpatable").on("keyup", ".credit", function() {
        var t = $(this).val(),
            a = /[^0-9]/gi;
        a.test(t) && (t = t.replace(a, ""), $(this).val(t))
    }), $("#gpatable").on("keyup", ".grade", function() {
        var t = $(this).val(),
            a = /(\ba\+)|[oabcdp987654]|(10)/gi;
        a.test(t) && (t = t.replace(a, ""), $(this).val(t))
    })
});
<commit_msg>Fixed regex bug<commit_after>$(document).ready(function() {
    function t(t) {
        return !isNaN(parseFloat(t)) && isFinite(t)
    }

    function a() {
        var a = 0,
            i = 0,
            e = 0;
        $("#gpa").find("tr").each(function() {
            var d = $(this).find("input.credit").val(),
                l = $(this).find("input.grade").val();
            ("O" == l || "o" == l || "10" == l) && (l = 10), ("a+" == l || "A+" == l || "9" == l) && (l = 9), ("A" == l || "a" == l || "8" == l) && (l = 8), ("b+" == l || "B+" == l || "7" == l) && (l = 7), ("c" == l || "C" == l || "6" == l) && (l = 6), ("d" == l || "D" == l || "5" == l) && (l = 5), ("p" == l || "P" == l || "4" == l) && (l = 4);
            var n = d * l;
            $(this).find("input.row-total").val(n ? n : ""), i += t(l) ? parseInt(l, 10) : 0, a += t(d) ? parseInt(d, 10) : 0, e += t(n) ? n : 0
        }), $("#credit-grand-total").html("Total Credits: " + a), $("#table-grand-total").html("GPA: " + (e / a).toFixed(3)), $("#grade-grand-total").html("Total Grades: " + e)
    }

    function i() {
        var t = $("
" + (d + 1) + "

<input type='text' id='" + (d + 1) + "Code' tabIndex='" + l++ + "'>Code

<input class='credit' type='text' tabIndex='" + l++ + "' id='" + (d + 1) + "Credits'>Credits

<input class='grade' maxlength='2' type='text' tabIndex='" + l++ + "' id='" + (d + 1) + "Grade'>Grade

<input class='row-total' type='text' readonly tabIndex='-1'>

");
        $("#gpatable").append(t), d++
    }

    function e() {
        d > 1 && ($("#gpatable").find("tr").last().remove(), d--, a())
    }
    $(".button-collapse").sideNav();
    var d = 5,
        l = 15;
    $(function() {
        $("#gpa").on("keyup", ".calculation", a), $("#gpa").on("keyup blur", ".form-control", a), $("#gpa").on("keyup", ".grade:last", function() {
            i()
        }), $("#add_row").on("click", function() {
            i()
        }), $("#delete_row").on("click", function() {
            e()
        })
    }), $("#gpatable").on("keyup", ".credit", function() {
        var t = $(this).val(),
            a = /[^0-9]/gi;
        a.test(t) && (t = t.replace(a, ""), $(this).val(t))
    }), $("#gpatable").on("keyup", ".grade", function() {
        var t = $(this).val(),
            a = /[^oabcdp10987654+]/gi;		//TODO: Make this regex stronger
        a.test(t) && (t = t.replace(a, ""), $(this).val(t))
    })
});
<|endoftext|>


<commit_before>/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

/*!
 * Next JS
 * Copyright(c) 2006-2011 Xenophy.CO.,LTD All rights Reserved.
 * http://www.xenophy.com
 */

// {{{ requires

var path = require('path');

// }}}
// {{{ NX

/**
 * @class NX
 */
NX = {

    // {{{ versionDetail

    /**
     * @prop versionDetail
     */
    versionDetail: {major: 0, minor: 5, patch: 0, edition: ''},

    // }}}
    // {{{ emptyFn

    /**
     * @prop emptyFn
     */
    emptyFn : function() {},

    // }}}
    // {{{ apply

    /**
     * @method apply
     */
    apply: function(o, cfg, defaults) {

        if(defaults) {
            NX.apply(o, defaults);
        }

        if(o && cfg && typeof cfg === 'object') {
            for(var key in cfg) {
                o[key] = cfg[key];
            }
        }

        return o;
    },

    // }}}
    // {{{ applyIf

    /**
     * @method applyIf
     */
    applyIf : function(target, cfg) {

        if(NX.isObject(target)) {
            NX.iterate(cfg, function(prop, v) {
                if(target[prop] == undefined) {
                    target[prop] = v;
                }
            });
        }

        return target;
    },

    // }}}
    // {{{ arrayUnique

    /**
     * @method arrayUnique
     */
    arrayUnique : function(inputArr) {

        var key = '', tmp_arr2 = {}, val = '';
        var __array_search = function (needle, haystack) {
            var fkey = '';
            for (fkey in haystack) {
                if (haystack.hasOwnProperty(fkey)) {
                    if ((haystack[fkey] + '') === (needle + '')) {
                        return fkey;
                    }
                }
            }
            return false;
        };

        for (key in inputArr) {
            if (inputArr.hasOwnProperty(key)) {
                val = inputArr[key];
                if (false === __array_search(val, tmp_arr2)) {
                    tmp_arr2[key] = val;
                }
            }
        }

        return tmp_arr2;
    },

    // }}}
    // {{{ asort

    /**
     * @method asort
     */
    asort : function asort(arr, key) {
        arr.sort(function (b1, b2) {
            return b1[key] > b2[key] ? 1 : -1;
        });
    },

    // }}}
    // {{{ clone

    /**
     * @method clone
     */
    clone : function(obj) {

        function doClone(o) {

            if(!o || 'object' !== typeof o) {
                return o;
            }

            if('function' === typeof o.clone) {
                return o.clone();
            }

            if(o.hasOwnProperty('__clonedTo')) {
                return o.__clonedTo;
            }

            var c = '[object Array]' === Object.prototype.toString.call(o) ? [] : {};

            o.__clonedTo = c;

            var p, v;

            for(p in o) {

                if((p !== '__clonedTo') && o.hasOwnProperty(p)) {

                    v = o[p];

                    if(v && 'object' === typeof v) {
                        c[p] = doClone(v);
                    } else {
                        c[p] = v;
                    }

                }
            }

            return c;
        }

        function finalizeClone(o) {

            if(o.hasOwnProperty('__clonedTo')) {

                delete o.__clonedTo;
                var p, v;

                for(p in o) {
                    if(o.hasOwnProperty(p)) {
                        v = o[p];
                        if(v && 'object' === typeof v) {
                            finalizeClone(v);
                        }
                    }
                }
            }
        }

        var clone = doClone(obj);

        finalizeClone(obj);

        return clone;
    },

    // }}}
    // {{{ escapeRe

    /**
     * @method escapeRe
     */
    escapeRe : function(s) {
        return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
    },

    // }}}
    // {{{ each

    /**
     * @method each
     */
    each : function(arr, fn, scope) {

        if(NX.isEmpty(arr, true)){
            return;
        }

        if(!NX.isIterable(arr) || NX.isPrimitive(arr)){
            arr = [arr];
        }

        for(var i = 0, len = arr.length; i < len; i++){
            if(fn.call(scope || arr[i], arr[i], i, arr) === false){
                return i;
            };
        }
    },

    // }}}
    // {{{ extend

    /**
     * @method extend
     */
    extend : function() {

        var inlineOverrides = function(o) {
            for(var m in o) {
                this[m] = o[m];
            }
        };

        var objectConstructor = Object.prototype.constructor;

        return function(subclass, superclass, overrides) {

            if(NX.isObject(superclass)) {
                overrides = superclass;
                superclass = subclass;
                subclass = overrides.constructor != objectConstructor
                ? overrides.constructor
                : function(){ superclass.apply(this, arguments); };
            }

            if(!superclass) {
                throw "The specified superclass object is illegal.";
            }

            var F = function(){},
            subclassProto,
            superclassProto = superclass.prototype;

            F.prototype = superclassProto;
            subclassProto = subclass.prototype = new F();
            subclassProto.constructor = subclass;
            subclass.superclass = superclassProto;

            if(superclassProto.constructor == objectConstructor){
                superclassProto.constructor = superclass;
            }

            subclass.override = function(overrides){
                NX.override(subclass, overrides);
            };

            subclassProto.superclass = subclassProto.supr = (function(){
                return superclassProto;
            });

            subclassProto.override = inlineOverrides;
            subclassProto.proto = subclassProto;

            subclass.override(overrides);
            subclass.extend = function(o) {
                return NX.extend(subclass, o);
            };

            return subclass;
        };
    }(),

    // }}}
    // {{{ inArray

    /**
     * @method inArray
     */
    inArray : function(needle, haystack, argStrict) {

        var key = '', strict = !!argStrict;

        if(strict) {
            for(key in haystack) {
                if(haystack[key] === needle) {
                    return true;
                }
            }
        } else {
            for(key in haystack) {
                if(haystack[key] == needle) {
                    return true;
                }
            }
        }

        return false;
    },

    // }}}
    // {{{ isArray

    /**
     * @method isArray
     */
    isArray : function(v) {
        return toString.apply(v) === '[object Array]';
    },

    // }}}
    // {{{ isBoolean

    /**
     * @method isBoolean
     */
    isBoolean : function(v) {
        return typeof v === 'boolean';
    },

    // }}}
    // {{{ isDate

    /**
     * @method isDate
     */
    isDate : function(v) {
        return toString.apply(v) === '[object Date]';
    },

    // }}}
    // {{{ isNull

    /**
     * @method isNull
     */
    isNull : function(v) {
        return v === null;
    },

    // }}}
    // {{{ isDefined

    /**
     * @method isDefined
     */
    isDefined : function(v) {
        return typeof v !== 'undefined';
    },

    // }}}
    // {{{ isEmpty

    /**
     * @method isEmpty
     */
    isEmpty : function(v, allowBlank) {
        return v === null || v === undefined || ((NX.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
    },

    // }}}
    // {{{ isFunction

    /**
     * @method isFunction
     */
    isFunction : function(v) {
        return toString.apply(v) === '[object Function]';
    },

    // }}}
    // {{{ isIterable

    /**
     * @method isIterable
     */
    isIterable : function(v) {

        if(NX.isArray(v) || v.callee){
            return true;
        }

        return false;
    },

    // }}}
    // {{{ isNumber

    /**
     * @method isNumber
     */
    isNumber : function(v) {
        return typeof v === 'number' && isFinite(v);
    },

    // }}}
    // {{{ isObject

    /**
     * @method isObject
     */
    isObject : function(v) {
        return !!v && Object.prototype.toString.call(v) === '[object Object]';
    },

    // }}}
    // {{{ isPrimitive

    /**
     * @method isPrimitive
     */
    isPrimitive : function(v) {
        return NX.isString(v) || NX.isNumber(v) || NX.isBoolean(v);
    },

    // }}}
    // {{{ isString

    /**
     * @method isString
     */
    isString : function(v) {
        return typeof v === 'string';
    },

    // }}}
    // {{{ iterate

    /**
     * @method iterate
     */
    iterate : function(obj, fn, scope) {

        if(NX.isEmpty(obj)) {
            return;
        }

        if(NX.isIterable(obj)) {

            NX.each(obj, fn, scope);
            return;

        } else if(typeof obj == 'object' || typeof 'function') {

            for(var prop in obj){
                if(obj.hasOwnProperty(prop)){
                    if(fn.call(scope || obj, prop, obj[prop], obj) === false){
                        return;
                    };
                }
            }

        }

    },

    // }}}
    // {{{ namespace

    /**
     * @method namespace
     */
    namespace : function() {

        var o, p, g = global;

        NX.iterate(arguments, function(v) {

            p = v.split(".");
            o = g[p[0]] = Object(g[p[0]]);

            for(x = 1, xln = p.length; x < xln; x++) {
                o = o[p[x]] = Object(o[p[x]]);
            }

        });

        return o;
    },

    // }}}
    // {{{ override

    /**
     * @method override
     */
    override : function(orgcls, overrides) {
        NX.apply(orgcls.prototype, overrides);
    },

    // }}}
    // {{{ sleep

    /**
     * @method sleep
     */
    sleep : function(ms) {

        var start = new Date;

        while(1) {
            var cur = new Date;
            if(ms <= cur.getTime() - start.getTime()) {
                break;
            }
        }

    },

    // }}}
    // {{{ toArray

    /**
     * @method toArray
     */
    toArray : function(arr, start, end) {
        return Array.prototype.slice.call(arr, start || 0, end || arr.length);
    },

    // }}}
    // {{{ toBoolean

    /**
     * @method toBoolean
     */
    toBoolean : function(obj) {
        return typeof obj === 'string'
            ? (/^(y(es)?|true|1)$/).test(obj)
            : !! obj;
    },

    // }}}
    // {{{ moduleCacheClear

    /**
     * @method moduleCacheClear
     */
    moduleCacheClear : function(filepath) {

        if(require.cache[filepath]) {
            delete require.cache[filepath];
        }

    }

    // }}}

};

// }}}
// {{{ version

/**
 * @prop version
 */
NX.version  = [NX.versionDetail.major, NX.versionDetail.minor, NX.versionDetail.patch].join('.');
NX.version += NX.versionDetail.edition;

// }}}
// {{{ ns

/**
 * @method ns
 */
NX.ns = NX.namespace;

// }}}
// {{{ require subclasses

NX.each([
    'controller/AbstractController',
    'controller/WebController',
    'controller/WebSocketController',
    'controller/Action',
    'controller/DirectAction',
    'module/adapter/AbstractAdapter',
    'module/adapter/MySQL',
    'module/AbstractModule',
    'module/Connection',
    'module/Module',
    'server/AbstractDispatcher',
    'server/Dispatcher',
    'server/HttpServer',
    'util/JSON',
    'util/MarkDown',
    'util/String',
    'util/Template',
    'util/template/Foreach',
    'util/template/If',
    'util/template/Include',
    'util/template/TextNode',
    'view/AbstractView',
    'view/WebView'
], function(item) {
    require('./' + item + '.js');
});

// }}}
// {{{ createServer

/**
 * @method createServer
 */
NX.createServer = NX.server.HttpServer.createServer;

// }}}
// {{{ trim

/**
 * @method trim
 */
NX.trim = NX.util.String.trim;

// }}}
// {{{ stripTags

/**
 * @method stripTags
 */
NX.stripTags = NX.util.String.stripTags;

// }}}
// {{{ stripScripts

/**
 * @method stripScripts
 */
NX.stripScripts = NX.util.String.stripScripts;

// }}}
// {{{ capitalize

/**
 * @method capitalize
 */
NX.capitalize = NX.util.String.capitalize;

// }}}
// {{{ explode

/**
 * @method explode
 */
NX.explode = NX.util.String.explode;

// }}}
// {{{ implode

/**
 * @method implode
 */
NX.implode = NX.util.String.implode;

// }}}
// {{{ sprintf

/**
 * @method sprintf
 */
NX.sprintf = NX.util.String.sprintf;

// }}}
// {{{ NX.encode

/**
 * @method encode
 */
NX.encode = NX.util.JSON.encode;

// }}}
// {{{ NX.decode

/**
 * @method decode
 */
NX.decode = NX.util.JSON.decode;

// }}}

// {{{ Next JS Enviroment

process.NXEnv = {
    name: process.env.NODE_ENV || 'development',
    port: 3000,
    testport: 15000,
    host: null,
    dirname: path.dirname(module.parent.filename),
    basename: path.basename(module.parent.filename),
    libdir: __dirname
};

// }}}

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * c-hanging-comment-ender-p: nil
 * End:
 */
<commit_msg>バージョン番号変更<commit_after>/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

/*!
 * Next JS
 * Copyright(c) 2006-2011 Xenophy.CO.,LTD All rights Reserved.
 * http://www.xenophy.com
 */

// {{{ requires

var path = require('path');

// }}}
// {{{ NX

/**
 * @class NX
 */
NX = {

    // {{{ versionDetail

    /**
     * @prop versionDetail
     */
    versionDetail: {major: 0, minor: 5, patch: 1, edition: 'dev'},

    // }}}
    // {{{ emptyFn

    /**
     * @prop emptyFn
     */
    emptyFn : function() {},

    // }}}
    // {{{ apply

    /**
     * @method apply
     */
    apply: function(o, cfg, defaults) {

        if(defaults) {
            NX.apply(o, defaults);
        }

        if(o && cfg && typeof cfg === 'object') {
            for(var key in cfg) {
                o[key] = cfg[key];
            }
        }

        return o;
    },

    // }}}
    // {{{ applyIf

    /**
     * @method applyIf
     */
    applyIf : function(target, cfg) {

        if(NX.isObject(target)) {
            NX.iterate(cfg, function(prop, v) {
                if(target[prop] == undefined) {
                    target[prop] = v;
                }
            });
        }

        return target;
    },

    // }}}
    // {{{ arrayUnique

    /**
     * @method arrayUnique
     */
    arrayUnique : function(inputArr) {

        var key = '', tmp_arr2 = {}, val = '';
        var __array_search = function (needle, haystack) {
            var fkey = '';
            for (fkey in haystack) {
                if (haystack.hasOwnProperty(fkey)) {
                    if ((haystack[fkey] + '') === (needle + '')) {
                        return fkey;
                    }
                }
            }
            return false;
        };

        for (key in inputArr) {
            if (inputArr.hasOwnProperty(key)) {
                val = inputArr[key];
                if (false === __array_search(val, tmp_arr2)) {
                    tmp_arr2[key] = val;
                }
            }
        }

        return tmp_arr2;
    },

    // }}}
    // {{{ asort

    /**
     * @method asort
     */
    asort : function asort(arr, key) {
        arr.sort(function (b1, b2) {
            return b1[key] > b2[key] ? 1 : -1;
        });
    },

    // }}}
    // {{{ clone

    /**
     * @method clone
     */
    clone : function(obj) {

        function doClone(o) {

            if(!o || 'object' !== typeof o) {
                return o;
            }

            if('function' === typeof o.clone) {
                return o.clone();
            }

            if(o.hasOwnProperty('__clonedTo')) {
                return o.__clonedTo;
            }

            var c = '[object Array]' === Object.prototype.toString.call(o) ? [] : {};

            o.__clonedTo = c;

            var p, v;

            for(p in o) {

                if((p !== '__clonedTo') && o.hasOwnProperty(p)) {

                    v = o[p];

                    if(v && 'object' === typeof v) {
                        c[p] = doClone(v);
                    } else {
                        c[p] = v;
                    }

                }
            }

            return c;
        }

        function finalizeClone(o) {

            if(o.hasOwnProperty('__clonedTo')) {

                delete o.__clonedTo;
                var p, v;

                for(p in o) {
                    if(o.hasOwnProperty(p)) {
                        v = o[p];
                        if(v && 'object' === typeof v) {
                            finalizeClone(v);
                        }
                    }
                }
            }
        }

        var clone = doClone(obj);

        finalizeClone(obj);

        return clone;
    },

    // }}}
    // {{{ escapeRe

    /**
     * @method escapeRe
     */
    escapeRe : function(s) {
        return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
    },

    // }}}
    // {{{ each

    /**
     * @method each
     */
    each : function(arr, fn, scope) {

        if(NX.isEmpty(arr, true)){
            return;
        }

        if(!NX.isIterable(arr) || NX.isPrimitive(arr)){
            arr = [arr];
        }

        for(var i = 0, len = arr.length; i < len; i++){
            if(fn.call(scope || arr[i], arr[i], i, arr) === false){
                return i;
            };
        }
    },

    // }}}
    // {{{ extend

    /**
     * @method extend
     */
    extend : function() {

        var inlineOverrides = function(o) {
            for(var m in o) {
                this[m] = o[m];
            }
        };

        var objectConstructor = Object.prototype.constructor;

        return function(subclass, superclass, overrides) {

            if(NX.isObject(superclass)) {
                overrides = superclass;
                superclass = subclass;
                subclass = overrides.constructor != objectConstructor
                ? overrides.constructor
                : function(){ superclass.apply(this, arguments); };
            }

            if(!superclass) {
                throw "The specified superclass object is illegal.";
            }

            var F = function(){},
            subclassProto,
            superclassProto = superclass.prototype;

            F.prototype = superclassProto;
            subclassProto = subclass.prototype = new F();
            subclassProto.constructor = subclass;
            subclass.superclass = superclassProto;

            if(superclassProto.constructor == objectConstructor){
                superclassProto.constructor = superclass;
            }

            subclass.override = function(overrides){
                NX.override(subclass, overrides);
            };

            subclassProto.superclass = subclassProto.supr = (function(){
                return superclassProto;
            });

            subclassProto.override = inlineOverrides;
            subclassProto.proto = subclassProto;

            subclass.override(overrides);
            subclass.extend = function(o) {
                return NX.extend(subclass, o);
            };

            return subclass;
        };
    }(),

    // }}}
    // {{{ inArray

    /**
     * @method inArray
     */
    inArray : function(needle, haystack, argStrict) {

        var key = '', strict = !!argStrict;

        if(strict) {
            for(key in haystack) {
                if(haystack[key] === needle) {
                    return true;
                }
            }
        } else {
            for(key in haystack) {
                if(haystack[key] == needle) {
                    return true;
                }
            }
        }

        return false;
    },

    // }}}
    // {{{ isArray

    /**
     * @method isArray
     */
    isArray : function(v) {
        return toString.apply(v) === '[object Array]';
    },

    // }}}
    // {{{ isBoolean

    /**
     * @method isBoolean
     */
    isBoolean : function(v) {
        return typeof v === 'boolean';
    },

    // }}}
    // {{{ isDate

    /**
     * @method isDate
     */
    isDate : function(v) {
        return toString.apply(v) === '[object Date]';
    },

    // }}}
    // {{{ isNull

    /**
     * @method isNull
     */
    isNull : function(v) {
        return v === null;
    },

    // }}}
    // {{{ isDefined

    /**
     * @method isDefined
     */
    isDefined : function(v) {
        return typeof v !== 'undefined';
    },

    // }}}
    // {{{ isEmpty

    /**
     * @method isEmpty
     */
    isEmpty : function(v, allowBlank) {
        return v === null || v === undefined || ((NX.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
    },

    // }}}
    // {{{ isFunction

    /**
     * @method isFunction
     */
    isFunction : function(v) {
        return toString.apply(v) === '[object Function]';
    },

    // }}}
    // {{{ isIterable

    /**
     * @method isIterable
     */
    isIterable : function(v) {

        if(NX.isArray(v) || v.callee){
            return true;
        }

        return false;
    },

    // }}}
    // {{{ isNumber

    /**
     * @method isNumber
     */
    isNumber : function(v) {
        return typeof v === 'number' && isFinite(v);
    },

    // }}}
    // {{{ isObject

    /**
     * @method isObject
     */
    isObject : function(v) {
        return !!v && Object.prototype.toString.call(v) === '[object Object]';
    },

    // }}}
    // {{{ isPrimitive

    /**
     * @method isPrimitive
     */
    isPrimitive : function(v) {
        return NX.isString(v) || NX.isNumber(v) || NX.isBoolean(v);
    },

    // }}}
    // {{{ isString

    /**
     * @method isString
     */
    isString : function(v) {
        return typeof v === 'string';
    },

    // }}}
    // {{{ iterate

    /**
     * @method iterate
     */
    iterate : function(obj, fn, scope) {

        if(NX.isEmpty(obj)) {
            return;
        }

        if(NX.isIterable(obj)) {

            NX.each(obj, fn, scope);
            return;

        } else if(typeof obj == 'object' || typeof 'function') {

            for(var prop in obj){
                if(obj.hasOwnProperty(prop)){
                    if(fn.call(scope || obj, prop, obj[prop], obj) === false){
                        return;
                    };
                }
            }

        }

    },

    // }}}
    // {{{ namespace

    /**
     * @method namespace
     */
    namespace : function() {

        var o, p, g = global;

        NX.iterate(arguments, function(v) {

            p = v.split(".");
            o = g[p[0]] = Object(g[p[0]]);

            for(x = 1, xln = p.length; x < xln; x++) {
                o = o[p[x]] = Object(o[p[x]]);
            }

        });

        return o;
    },

    // }}}
    // {{{ override

    /**
     * @method override
     */
    override : function(orgcls, overrides) {
        NX.apply(orgcls.prototype, overrides);
    },

    // }}}
    // {{{ sleep

    /**
     * @method sleep
     */
    sleep : function(ms) {

        var start = new Date;

        while(1) {
            var cur = new Date;
            if(ms <= cur.getTime() - start.getTime()) {
                break;
            }
        }

    },

    // }}}
    // {{{ toArray

    /**
     * @method toArray
     */
    toArray : function(arr, start, end) {
        return Array.prototype.slice.call(arr, start || 0, end || arr.length);
    },

    // }}}
    // {{{ toBoolean

    /**
     * @method toBoolean
     */
    toBoolean : function(obj) {
        return typeof obj === 'string'
            ? (/^(y(es)?|true|1)$/).test(obj)
            : !! obj;
    },

    // }}}
    // {{{ moduleCacheClear

    /**
     * @method moduleCacheClear
     */
    moduleCacheClear : function(filepath) {

        if(require.cache[filepath]) {
            delete require.cache[filepath];
        }

    }

    // }}}

};

// }}}
// {{{ version

/**
 * @prop version
 */
NX.version  = [NX.versionDetail.major, NX.versionDetail.minor, NX.versionDetail.patch].join('.');
NX.version += NX.versionDetail.edition;

// }}}
// {{{ ns

/**
 * @method ns
 */
NX.ns = NX.namespace;

// }}}
// {{{ require subclasses

NX.each([
    'controller/AbstractController',
    'controller/WebController',
    'controller/WebSocketController',
    'controller/Action',
    'controller/DirectAction',
    'module/adapter/AbstractAdapter',
    'module/adapter/MySQL',
    'module/AbstractModule',
    'module/Connection',
    'module/Module',
    'server/AbstractDispatcher',
    'server/Dispatcher',
    'server/HttpServer',
    'util/JSON',
    'util/MarkDown',
    'util/String',
    'util/Template',
    'util/template/Foreach',
    'util/template/If',
    'util/template/Include',
    'util/template/TextNode',
    'view/AbstractView',
    'view/WebView'
], function(item) {
    require('./' + item + '.js');
});

// }}}
// {{{ createServer

/**
 * @method createServer
 */
NX.createServer = NX.server.HttpServer.createServer;

// }}}
// {{{ trim

/**
 * @method trim
 */
NX.trim = NX.util.String.trim;

// }}}
// {{{ stripTags

/**
 * @method stripTags
 */
NX.stripTags = NX.util.String.stripTags;

// }}}
// {{{ stripScripts

/**
 * @method stripScripts
 */
NX.stripScripts = NX.util.String.stripScripts;

// }}}
// {{{ capitalize

/**
 * @method capitalize
 */
NX.capitalize = NX.util.String.capitalize;

// }}}
// {{{ explode

/**
 * @method explode
 */
NX.explode = NX.util.String.explode;

// }}}
// {{{ implode

/**
 * @method implode
 */
NX.implode = NX.util.String.implode;

// }}}
// {{{ sprintf

/**
 * @method sprintf
 */
NX.sprintf = NX.util.String.sprintf;

// }}}
// {{{ NX.encode

/**
 * @method encode
 */
NX.encode = NX.util.JSON.encode;

// }}}
// {{{ NX.decode

/**
 * @method decode
 */
NX.decode = NX.util.JSON.decode;

// }}}

// {{{ Next JS Enviroment

process.NXEnv = {
    name: process.env.NODE_ENV || 'development',
    port: 3000,
    testport: 15000,
    host: null,
    dirname: path.dirname(module.parent.filename),
    basename: path.basename(module.parent.filename),
    libdir: __dirname
};

// }}}

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * c-hanging-comment-ender-p: nil
 * End:
 */
<|endoftext|>