<commit_before>/**
 * Copyright 2019 The AMP HTML Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const colors = require('ansi-colors');
const file = require('gulp-file');
const fs = require('fs-extra');
const gulp = require('gulp');
const log = require('fancy-log');
const {
  bootstrapThirdPartyFrames,
  compileAllJs,
  compileCoreRuntime,
  compileJs,
  endBuildStep,
  maybeToEsmName,
  mkdirSync,
  printConfigHelp,
  printNobuildHelp,
  toPromise,
} = require('./helpers');
const {
  createCtrlcHandler,
  exitCtrlcHandler,
} = require('../common/ctrlcHandler');
const {
  displayLifecycleDebugging,
} = require('../compile/debug-compilation-lifecycle');
const {buildExtensions, parseExtensionFlags} = require('./extension-helpers');
const {cleanupBuildDir} = require('../compile/compile');
const {compileCss, cssEntryPoints} = require('./css');
const {compileJison} = require('./compile-jison');
const {formatExtractedMessages} = require('../compile/log-messages');
const {maybeUpdatePackages} = require('./update-packages');
const {VERSION} = require('../compile/internal-version');

const {green, cyan} = colors;
const argv = require('minimist')(process.argv.slice(2));

/**
 * Files that must be built for amp-web-push
 */
const WEB_PUSH_PUBLISHER_FILES = [
  'amp-web-push-helper-frame',
  'amp-web-push-permission-dialog',
];

/**
 * Versions that must be built for amp-web-push
 */
const WEB_PUSH_PUBLISHER_VERSIONS = ['0.1'];

/**
 * Used while building the experiments page.
 */
const hostname = argv.hostname || 'cdn.ampproject.org';

/**
 * Prints a useful help message prior to the gulp dist task
 *
 * @param {!Object} options
 */
function printDistHelp(options) {
  if (argv.sanitize_vars_for_diff && !argv.pseudo_names) {
    throw new Error('--sanitize_vars_for_diff requires --pseudo_names');
  }

  let cmd = 'gulp dist';
  if (options.fortesting) {
    cmd = cmd + ' --fortesting';
  }
  printConfigHelp(cmd);
  parseExtensionFlags();
  if (argv.define_experiment_constant) {
    log(
      green('Enabling the'),
      cyan(argv.define_experiment_constant),
      green('experiment.')
    );
  }
}

/**
 * Perform the prerequisite steps before starting the minified build.
 * Used by `gulp` and `gulp dist`.
 *
 * @param {!Object} options
 */
async function runPreDistSteps(options) {
  cleanupBuildDir();
  await prebuild();
  await compileCss(options);
  await compileJison();
  await copyCss();
  await copyParsers();
  await bootstrapThirdPartyFrames(options);
  displayLifecycleDebugging();
}

/**
 * Minified build. Entry point for `gulp dist`.
 */
async function dist() {
  await doDist();
}

/**
 * Performs a minified build with the given extra args.
 *
 * @param {Object=} extraArgs
 */
async function doDist(extraArgs = {}) {
  maybeUpdatePackages();
  const handlerProcess = createCtrlcHandler('dist');
  process.env.NODE_ENV = 'production';
  const options = {
    fortesting: extraArgs.fortesting || argv.fortesting,
    minify: true,
    watch: argv.watch,
  };
  printNobuildHelp();
  printDistHelp(options);
  await runPreDistSteps(options);

  // Steps that use closure compiler. Small ones before large (parallel) ones.
  if (argv.core_runtime_only) {
    await compileCoreRuntime(options);
  } else {
    await buildExperiments();
    await buildLoginDone('0.1');
    await buildWebPushPublisherFiles();
    await compileAllJs(options);
    await buildExtensions(options);
  }

  if (!argv.core_runtime_only) {
    await formatExtractedMessages();
  }
  if (!argv.watch) {
    exitCtrlcHandler(handlerProcess);
  }
}

/**
 * Build AMP experiments.js.
 *
 * @return {!Promise}
 */
function buildExperiments() {
  return compileJs(
    './build/experiments/',
    'experiments.max.js',
    './dist.tools/experiments/',
    {
      watch: argv.watch,
      minify: true,
      includePolyfills: true,
      minifiedName: maybeToEsmName('experiments.js'),
      esmPassCompilation: argv.esm || false,
    }
  );
}

/**
 * Build amp-login-done-${version}.js file.
 *
 * @param {string} version
 * @return {!Promise}
 */
function buildLoginDone(version) {
  const buildDir = `build/all/amp-access-${version}/`;
  const builtName = `amp-login-done-${version}.max.js`;
  const minifiedName = `amp-login-done-${version}.js`;
  const latestName = 'amp-login-done-latest.js';
  return compileJs('./' + buildDir, builtName, './dist/v0/', {
    watch: argv.watch,
    includePolyfills: true,
    minify: true,
    minifiedName,
    latestName,
    esmPassCompilation: argv.esm || false,
    extraGlobs: [
      buildDir + 'amp-login-done-0.1.max.js',
      buildDir + 'amp-login-done-dialog.js',
    ],
  });
}

/**
 * Build amp-web-push publisher files HTML page.
 */
async function buildWebPushPublisherFiles() {
  const distDir = 'dist/v0';
  const promises = [];
  WEB_PUSH_PUBLISHER_VERSIONS.forEach((version) => {
    WEB_PUSH_PUBLISHER_FILES.forEach((fileName) => {
      const tempBuildDir = `build/all/amp-web-push-${version}/`;
      const builtName = fileName + '.js';
      const minifiedName = maybeToEsmName(fileName + '.js');
      const p = compileJs('./' + tempBuildDir, builtName, './' + distDir, {
        watch: argv.watch,
        includePolyfills: true,
        minify: true,
        esmPassCompilation: argv.esm || false,
        minifiedName,
        extraGlobs: [tempBuildDir + '*.js'],
      });
      promises.push(p);
    });
  });
  await Promise.all(promises);
  await postBuildWebPushPublisherFilesVersion();
}

async function prebuild() {
  await preBuildExperiments();
  await preBuildLoginDone();
  await preBuildWebPushPublisherFiles();
}

/**
 * Copies the css from the build folder to the dist folder
 * @return {!Promise}
 */
function copyCss() {
  const startTime = Date.now();

  cssEntryPoints.forEach(({outCss}) => {
    fs.copySync(`build/css/${outCss}`, `dist/${outCss}`);
  });

  return toPromise(
    gulp
      .src('build/css/amp-*.css', {base: 'build/css/'})
      .pipe(gulp.dest('dist/v0'))
  ).then(() => {
    endBuildStep('Copied', 'build/css/*.css to dist/v0/*.css', startTime);
  });
}

/**
 * Copies parsers from the build folder to the dist folder
 * @return {!Promise}
 */
function copyParsers() {
  const startTime = Date.now();
  return fs.copy('build/parsers', 'dist/v0').then(() => {
    endBuildStep('Copied', 'build/parsers/ to dist/v0', startTime);
  });
}

/**
 * Build amp-web-push publisher files HTML page.
 *
 * @return {!Promise<!Array>}
 */
async function preBuildWebPushPublisherFiles() {
  mkdirSync('dist');
  mkdirSync('dist/v0');
  const promises = [];

  WEB_PUSH_PUBLISHER_VERSIONS.forEach((version) => {
    WEB_PUSH_PUBLISHER_FILES.forEach((fileName) => {
      const basePath = `extensions/amp-web-push/${version}/`;
      const tempBuildDir = `build/all/amp-web-push-${version}/`;

      // Build Helper Frame JS
      const js = fs.readFileSync(basePath + fileName + '.js', 'utf8');
      const builtName = fileName + '.js';
      const promise = toPromise(
        gulp
          .src(basePath + '/*.js', {base: basePath})
          .pipe(file(builtName, js))
          .pipe(gulp.dest(tempBuildDir))
      );
      promises.push(promise);
    });
  });
  return Promise.all(promises);
}

/**
 * post Build amp-web-push publisher files HTML page.
 */
function postBuildWebPushPublisherFilesVersion() {
  const distDir = 'dist/v0';
  WEB_PUSH_PUBLISHER_VERSIONS.forEach((version) => {
    const basePath = `extensions/amp-web-push/${version}/`;
    WEB_PUSH_PUBLISHER_FILES.forEach((fileName) => {
      const minifiedName = maybeToEsmName(fileName + '.js');
      if (!fs.existsSync(distDir + '/' + minifiedName)) {
        throw new Error(`Cannot find ${distDir}/${minifiedName}`);
      }

      // Build Helper Frame HTML
      let fileContents = fs.readFileSync(basePath + fileName + '.html', 'utf8');
      fileContents = fileContents.replace(
        '<!-- [GULP-MAGIC-REPLACE ' + fileName + '.js] -->',
        '<script>' +
          fs.readFileSync(distDir + '/' + minifiedName, 'utf8') +
          '</script>'
      );

      fs.writeFileSync('dist/v0/' + fileName + '.html', fileContents);
    });
  });
}

/**
 * Precompilation steps required to build experiment js binaries.
 * @return {!Promise}
 */
async function preBuildExperiments() {
  const path = 'tools/experiments';
  const htmlPath = path + '/experiments.html';
  const jsPath = path + '/experiments.js';

  // Build HTML.
  const html = fs.readFileSync(htmlPath, 'utf8');
  const minHtml = html
    .replace(
      '/dist.tools/experiments/experiments.js',
      `https://${hostname}/v0/experiments.js`
    )
    .replace(/\$internalRuntimeVersion\$/g, VERSION);

  await toPromise(
    gulp
      .src(htmlPath)
      .pipe(file('experiments.cdn.html', minHtml))
      .pipe(gulp.dest('dist.tools/experiments/'))
  );

  // Build JS.
  const js = fs.readFileSync(jsPath, 'utf8');
  const builtName = 'experiments.max.js';
  return toPromise(
    gulp
      .src(path + '/*.js')
      .pipe(file(builtName, js))
      .pipe(gulp.dest('build/experiments/'))
  );
}

/**
 * Build "Login Done" page.
 * @return {!Promise}
 */
function preBuildLoginDone() {
  return preBuildLoginDoneVersion('0.1');
}

/**
 * Build "Login Done" page for the specified version.
 *
 * @param {string} version
 * @return {!Promise}
 */
function preBuildLoginDoneVersion(version) {
  const path = `extensions/amp-access/${version}/`;
  const buildDir = `build/all/amp-access-${version}/`;
  const htmlPath = path + 'amp-login-done.html';
  const jsPath = path + 'amp-login-done.js';

  // Build HTML.
  const html = fs.readFileSync(htmlPath, 'utf8');
  const minJs = `https://${hostname}/v0/amp-login-done-${version}.js`;
  const minHtml = html
    .replace(`../../../dist/v0/amp-login-done-${version}.max.js`, minJs)
    .replace(`../../../dist/v0/amp-login-done-${version}.js`, minJs);
  if (minHtml.indexOf(minJs) == -1) {
    throw new Error('Failed to correctly set JS in login-done.html');
  }

  mkdirSync('dist');
  mkdirSync('dist/v0');

  fs.writeFileSync('dist/v0/amp-login-done-' + version + '.html', minHtml);

  // Build JS.
  const js = fs.readFileSync(jsPath, 'utf8');
  const builtName = 'amp-login-done-' + version + '.max.js';
  return toPromise(
    gulp
      .src(path + '/*.js', {base: path})
      .pipe(file(builtName, js))
      .pipe(gulp.dest(buildDir))
  );
}

module.exports = {
  dist,
  doDist,
  runPreDistSteps,
};

/* eslint "google-camelcase/google-camelcase": 0 */

dist.description =
  'Compiles AMP production binaries and applies AMP_CONFIG to runtime files';
dist.flags = {
  pseudo_names:
    '  Compiles with readable names. ' +
    'Great for profiling and debugging production code.',
  pretty_print:
    '  Outputs compiled code with whitespace. ' +
    'Great for debugging production code.',
  fortesting: '  Compiles production binaries for local testing',
  noconfig: '  Compiles production binaries without applying AMP_CONFIG',
  config: '  Sets the runtime\'s AMP_CONFIG to one of "prod" or "canary"',
  extensions: '  Builds only the listed extensions.',
  extensions_from: '  Builds only the extensions from the listed AMP(s).',
  noextensions: '  Builds with no extensions.',
  core_runtime_only: '  Builds only the core runtime.',
  full_sourcemaps: '  Includes source code content in sourcemaps',
  sourcemap_url: '  Sets a custom sourcemap URL with placeholder {version}',
  type: '  Points sourcemap to fetch files from the correct GitHub tag',
  esm: '  Does not transpile down to ES5',
  version_override: '  Override the version written to AMP_CONFIG',
  watch: '  Watches for changes in files, re-compiles when detected',
  closure_concurrency: '  Sets the number of concurrent invocations of closure',
  debug: '  Outputs the file contents during compilation lifecycles',
  define_experiment_constant:
    '  Builds runtime with the EXPERIMENT constant set to true',
  sanitize_vars_for_diff:
    '  Sanitize the output to diff build results. Requires --pseudo_names',
};
<commit_msg>added flag (#29331)<commit_after>/**
 * Copyright 2019 The AMP HTML Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const colors = require('ansi-colors');
const file = require('gulp-file');
const fs = require('fs-extra');
const gulp = require('gulp');
const log = require('fancy-log');
const {
  bootstrapThirdPartyFrames,
  compileAllJs,
  compileCoreRuntime,
  compileJs,
  endBuildStep,
  maybeToEsmName,
  mkdirSync,
  printConfigHelp,
  printNobuildHelp,
  toPromise,
} = require('./helpers');
const {
  createCtrlcHandler,
  exitCtrlcHandler,
} = require('../common/ctrlcHandler');
const {
  displayLifecycleDebugging,
} = require('../compile/debug-compilation-lifecycle');
const {buildExtensions, parseExtensionFlags} = require('./extension-helpers');
const {cleanupBuildDir} = require('../compile/compile');
const {compileCss, cssEntryPoints} = require('./css');
const {compileJison} = require('./compile-jison');
const {formatExtractedMessages} = require('../compile/log-messages');
const {maybeUpdatePackages} = require('./update-packages');
const {VERSION} = require('../compile/internal-version');

const {green, cyan} = colors;
const argv = require('minimist')(process.argv.slice(2));

/**
 * Files that must be built for amp-web-push
 */
const WEB_PUSH_PUBLISHER_FILES = [
  'amp-web-push-helper-frame',
  'amp-web-push-permission-dialog',
];

/**
 * Versions that must be built for amp-web-push
 */
const WEB_PUSH_PUBLISHER_VERSIONS = ['0.1'];

/**
 * Used while building the experiments page.
 */
const hostname = argv.hostname || 'cdn.ampproject.org';

/**
 * Prints a useful help message prior to the gulp dist task
 *
 * @param {!Object} options
 */
function printDistHelp(options) {
  if (argv.sanitize_vars_for_diff && !argv.pseudo_names) {
    throw new Error('--sanitize_vars_for_diff requires --pseudo_names');
  }

  let cmd = 'gulp dist';
  if (options.fortesting) {
    cmd = cmd + ' --fortesting';
  }
  printConfigHelp(cmd);
  parseExtensionFlags();
  if (argv.define_experiment_constant) {
    log(
      green('Enabling the'),
      cyan(argv.define_experiment_constant),
      green('experiment.')
    );
  }
}

/**
 * Perform the prerequisite steps before starting the minified build.
 * Used by `gulp` and `gulp dist`.
 *
 * @param {!Object} options
 */
async function runPreDistSteps(options) {
  cleanupBuildDir();
  await prebuild();
  await compileCss(options);
  await compileJison();
  await copyCss();
  await copyParsers();
  await bootstrapThirdPartyFrames(options);
  displayLifecycleDebugging();
}

/**
 * Minified build. Entry point for `gulp dist`.
 */
async function dist() {
  await doDist();
}

/**
 * Performs a minified build with the given extra args.
 *
 * @param {Object=} extraArgs
 */
async function doDist(extraArgs = {}) {
  maybeUpdatePackages();
  const handlerProcess = createCtrlcHandler('dist');
  process.env.NODE_ENV = 'production';
  const options = {
    fortesting: extraArgs.fortesting || argv.fortesting,
    minify: true,
    watch: argv.watch,
  };
  printNobuildHelp();
  printDistHelp(options);
  await runPreDistSteps(options);

  // Steps that use closure compiler. Small ones before large (parallel) ones.
  if (argv.core_runtime_only) {
    await compileCoreRuntime(options);
  } else {
    await buildExperiments();
    await buildLoginDone('0.1');
    await buildWebPushPublisherFiles();
    await compileAllJs(options);
    await buildExtensions(options);
  }

  if (!argv.core_runtime_only) {
    await formatExtractedMessages();
  }
  if (!argv.watch) {
    exitCtrlcHandler(handlerProcess);
  }
}

/**
 * Build AMP experiments.js.
 *
 * @return {!Promise}
 */
function buildExperiments() {
  return compileJs(
    './build/experiments/',
    'experiments.max.js',
    './dist.tools/experiments/',
    {
      watch: argv.watch,
      minify: true,
      includePolyfills: true,
      minifiedName: maybeToEsmName('experiments.js'),
      esmPassCompilation: argv.esm || false,
    }
  );
}

/**
 * Build amp-login-done-${version}.js file.
 *
 * @param {string} version
 * @return {!Promise}
 */
function buildLoginDone(version) {
  const buildDir = `build/all/amp-access-${version}/`;
  const builtName = `amp-login-done-${version}.max.js`;
  const minifiedName = `amp-login-done-${version}.js`;
  const latestName = 'amp-login-done-latest.js';
  return compileJs('./' + buildDir, builtName, './dist/v0/', {
    watch: argv.watch,
    includePolyfills: true,
    minify: true,
    minifiedName,
    latestName,
    esmPassCompilation: argv.esm || false,
    extraGlobs: [
      buildDir + 'amp-login-done-0.1.max.js',
      buildDir + 'amp-login-done-dialog.js',
    ],
  });
}

/**
 * Build amp-web-push publisher files HTML page.
 */
async function buildWebPushPublisherFiles() {
  const distDir = 'dist/v0';
  const promises = [];
  WEB_PUSH_PUBLISHER_VERSIONS.forEach((version) => {
    WEB_PUSH_PUBLISHER_FILES.forEach((fileName) => {
      const tempBuildDir = `build/all/amp-web-push-${version}/`;
      const builtName = fileName + '.js';
      const minifiedName = maybeToEsmName(fileName + '.js');
      const p = compileJs('./' + tempBuildDir, builtName, './' + distDir, {
        watch: argv.watch,
        includePolyfills: true,
        minify: true,
        esmPassCompilation: argv.esm || false,
        minifiedName,
        extraGlobs: [tempBuildDir + '*.js'],
      });
      promises.push(p);
    });
  });
  await Promise.all(promises);
  await postBuildWebPushPublisherFilesVersion();
}

async function prebuild() {
  await preBuildExperiments();
  await preBuildLoginDone();
  await preBuildWebPushPublisherFiles();
}

/**
 * Copies the css from the build folder to the dist folder
 * @return {!Promise}
 */
function copyCss() {
  const startTime = Date.now();

  cssEntryPoints.forEach(({outCss}) => {
    fs.copySync(`build/css/${outCss}`, `dist/${outCss}`);
  });

  return toPromise(
    gulp
      .src('build/css/amp-*.css', {base: 'build/css/'})
      .pipe(gulp.dest('dist/v0'))
  ).then(() => {
    endBuildStep('Copied', 'build/css/*.css to dist/v0/*.css', startTime);
  });
}

/**
 * Copies parsers from the build folder to the dist folder
 * @return {!Promise}
 */
function copyParsers() {
  const startTime = Date.now();
  return fs.copy('build/parsers', 'dist/v0').then(() => {
    endBuildStep('Copied', 'build/parsers/ to dist/v0', startTime);
  });
}

/**
 * Build amp-web-push publisher files HTML page.
 *
 * @return {!Promise<!Array>}
 */
async function preBuildWebPushPublisherFiles() {
  mkdirSync('dist');
  mkdirSync('dist/v0');
  const promises = [];

  WEB_PUSH_PUBLISHER_VERSIONS.forEach((version) => {
    WEB_PUSH_PUBLISHER_FILES.forEach((fileName) => {
      const basePath = `extensions/amp-web-push/${version}/`;
      const tempBuildDir = `build/all/amp-web-push-${version}/`;

      // Build Helper Frame JS
      const js = fs.readFileSync(basePath + fileName + '.js', 'utf8');
      const builtName = fileName + '.js';
      const promise = toPromise(
        gulp
          .src(basePath + '/*.js', {base: basePath})
          .pipe(file(builtName, js))
          .pipe(gulp.dest(tempBuildDir))
      );
      promises.push(promise);
    });
  });
  return Promise.all(promises);
}

/**
 * post Build amp-web-push publisher files HTML page.
 */
function postBuildWebPushPublisherFilesVersion() {
  const distDir = 'dist/v0';
  WEB_PUSH_PUBLISHER_VERSIONS.forEach((version) => {
    const basePath = `extensions/amp-web-push/${version}/`;
    WEB_PUSH_PUBLISHER_FILES.forEach((fileName) => {
      const minifiedName = maybeToEsmName(fileName + '.js');
      if (!fs.existsSync(distDir + '/' + minifiedName)) {
        throw new Error(`Cannot find ${distDir}/${minifiedName}`);
      }

      // Build Helper Frame HTML
      let fileContents = fs.readFileSync(basePath + fileName + '.html', 'utf8');
      fileContents = fileContents.replace(
        '<!-- [GULP-MAGIC-REPLACE ' + fileName + '.js] -->',
        '<script>' +
          fs.readFileSync(distDir + '/' + minifiedName, 'utf8') +
          '</script>'
      );

      fs.writeFileSync('dist/v0/' + fileName + '.html', fileContents);
    });
  });
}

/**
 * Precompilation steps required to build experiment js binaries.
 * @return {!Promise}
 */
async function preBuildExperiments() {
  const path = 'tools/experiments';
  const htmlPath = path + '/experiments.html';
  const jsPath = path + '/experiments.js';

  // Build HTML.
  const html = fs.readFileSync(htmlPath, 'utf8');
  const minHtml = html
    .replace(
      '/dist.tools/experiments/experiments.js',
      `https://${hostname}/v0/experiments.js`
    )
    .replace(/\$internalRuntimeVersion\$/g, VERSION);

  await toPromise(
    gulp
      .src(htmlPath)
      .pipe(file('experiments.cdn.html', minHtml))
      .pipe(gulp.dest('dist.tools/experiments/'))
  );

  // Build JS.
  const js = fs.readFileSync(jsPath, 'utf8');
  const builtName = 'experiments.max.js';
  return toPromise(
    gulp
      .src(path + '/*.js')
      .pipe(file(builtName, js))
      .pipe(gulp.dest('build/experiments/'))
  );
}

/**
 * Build "Login Done" page.
 * @return {!Promise}
 */
function preBuildLoginDone() {
  return preBuildLoginDoneVersion('0.1');
}

/**
 * Build "Login Done" page for the specified version.
 *
 * @param {string} version
 * @return {!Promise}
 */
function preBuildLoginDoneVersion(version) {
  const path = `extensions/amp-access/${version}/`;
  const buildDir = `build/all/amp-access-${version}/`;
  const htmlPath = path + 'amp-login-done.html';
  const jsPath = path + 'amp-login-done.js';

  // Build HTML.
  const html = fs.readFileSync(htmlPath, 'utf8');
  const minJs = `https://${hostname}/v0/amp-login-done-${version}.js`;
  const minHtml = html
    .replace(`../../../dist/v0/amp-login-done-${version}.max.js`, minJs)
    .replace(`../../../dist/v0/amp-login-done-${version}.js`, minJs);
  if (minHtml.indexOf(minJs) == -1) {
    throw new Error('Failed to correctly set JS in login-done.html');
  }

  mkdirSync('dist');
  mkdirSync('dist/v0');

  fs.writeFileSync('dist/v0/amp-login-done-' + version + '.html', minHtml);

  // Build JS.
  const js = fs.readFileSync(jsPath, 'utf8');
  const builtName = 'amp-login-done-' + version + '.max.js';
  return toPromise(
    gulp
      .src(path + '/*.js', {base: path})
      .pipe(file(builtName, js))
      .pipe(gulp.dest(buildDir))
  );
}

module.exports = {
  dist,
  doDist,
  runPreDistSteps,
};

/* eslint "google-camelcase/google-camelcase": 0 */

dist.description =
  'Compiles AMP production binaries and applies AMP_CONFIG to runtime files';
dist.flags = {
  pseudo_names:
    '  Compiles with readable names. ' +
    'Great for profiling and debugging production code.',
  pretty_print:
    '  Outputs compiled code with whitespace. ' +
    'Great for debugging production code.',
  fortesting: '  Compiles production binaries for local testing',
  noconfig: '  Compiles production binaries without applying AMP_CONFIG',
  config: '  Sets the runtime\'s AMP_CONFIG to one of "prod" or "canary"',
  extensions: '  Builds only the listed extensions.',
  extensions_from: '  Builds only the extensions from the listed AMP(s).',
  noextensions: '  Builds with no extensions.',
  core_runtime_only: '  Builds only the core runtime.',
  full_sourcemaps: '  Includes source code content in sourcemaps',
  sourcemap_url: '  Sets a custom sourcemap URL with placeholder {version}',
  type: '  Points sourcemap to fetch files from the correct GitHub tag',
  esm: '  Does not transpile down to ES5',
  version_override: '  Override the version written to AMP_CONFIG',
  watch: '  Watches for changes in files, re-compiles when detected',
  closure_concurrency: '  Sets the number of concurrent invocations of closure',
  debug: '  Outputs the file contents during compilation lifecycles',
  define_experiment_constant:
    '  Builds runtime with the EXPERIMENT constant set to true',
  sanitize_vars_for_diff:
    '  Sanitize the output to diff build results. Requires --pseudo_names',
  sxg: '  Outputs the compiled code for the SxG build',
};
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc function
 * @name ausEnvApp.controller:MainCtrl
 * @description
 * # MainCtrl
 * Controller of the ausEnvApp
 */
angular.module('ausEnvApp')
  .controller('MainCtrl', function ($scope,$uibModal,selection) {
    $scope.selection = selection;
    $scope.options = {
      doNotShow:false
    };

    $scope.moveYear = function(dir){
      $scope.selection.moveYear(dir);
    };

    $scope.runningLocally = (window.location.hostname==='localhost');

    var options = {
      animation:true,
      templateUrl: 'views/about.html',
      scope: $scope
    };

    if(!localStorage.preventAbout){
      $uibModal.open(options);
    }

    $scope.doNotShowClicked = function(){
      console.log($scope.options);
      if($scope.options.doNotShow){
        localStorage.setItem('preventAbout',true);
      } else {
        localStorage.removeItem('preventAbout');
      }
    };
  });
<commit_msg>Placeholder splash screen<commit_after>'use strict';

/**
 * @ngdoc function
 * @name ausEnvApp.controller:MainCtrl
 * @description
 * # MainCtrl
 * Controller of the ausEnvApp
 */
angular.module('ausEnvApp')
  .controller('MainCtrl', function ($scope,$uibModal,selection) {
    $scope.selection = selection;
    $scope.options = {
      doNotShow:false
    };

    $scope.moveYear = function(dir){
      $scope.selection.moveYear(dir);
    };

    $scope.runningLocally = (window.location.hostname==='localhost');

    var options = {
      animation:true,
      templateUrl: 'views/about.html',
      scope: $scope
    };

    if(!localStorage.preventAbout){
      $scope.modalInstance = $uibModal.open(options);
    }

    $scope.closeModal = function(){
      $scope.modalInstance.dismiss();
    };

    $scope.doNotShowClicked = function(){
      console.log($scope.options);
      if($scope.options.doNotShow){
        localStorage.setItem('preventAbout',true);
      } else {
        localStorage.removeItem('preventAbout');
      }
    };
  });
<|endoftext|>


<commit_before>var tokTypes = require("babel").acorn.tokTypes;
var traverse = require("babel").traverse;
var t        = require("babel").types;

exports.toToken = function (token) {
  var type = token.type;

  if (type === tokTypes.name) {
    token.type = "Identifier";
  } else if (type === tokTypes.semi || type === tokTypes.comma || type === tokTypes.parenL || type === tokTypes.parenR || type === tokTypes.braceL || type === tokTypes.braceR) {
    token.type = "Punctuator";
    token.value = type.type;
  }

  return token;
};

exports.toAST = function (ast) {
  traverse(ast, astTransformVisitor);
};

function isCompatTag(tagName) {
  return tagName && /^[a-z]|\-/.test(tagName);
}

var astTransformVisitor = {
  noScope: true,
  enter: function (node, parent) {
    if (t.isSpreadProperty(node)) {
      node.type = "Property";
      node.kind = "init";
      node.computed = false;
      node.key = node.value = node.argument;
      delete node.argument;
    }

    if (t.isRestElement(node)) {
      return node.argument;
    }

    if (t.isImportBatchSpecifier(node)) {
      // ImportBatchSpecifier<name> => ImportNamespaceSpecifier<id>
      node.type = "ImportNamespaceSpecifier";
      node.id = node.name;
      delete node.name;
    }

    if (t.isAwaitExpression(node)) {
      node.type = "YieldExpression";
    }

    // classes

    if (t.isReferencedIdentifier(node, parent, { name: "super" })) {
      return t.inherits(t.thisExpression(), node);
    }

    if (t.isClassProperty(node)) {
      // eslint doesn't like these
      this.remove();
    }

    // JSX

    if (t.isJSXIdentifier(node)) {
      if (node.name === "this" && t.isReferenced(node, parent)) {
        return t.inherits(t.thisExpression(), node);
      } else if (!t.isJSXAttribute(parent) && !isCompatTag(node.name)) {
        node.type = "Identifier";
      } else {
        // just ignore this node as it'd be something like <div> or an attribute name
      }
    }

    if (t.isJSXMemberExpression(node)) {
      node.type = "MemberExpression";
    }

    // functions

    if (t.isFunction(node)) {
      node.defaults = [];
      node.params = node.params.map(function (param) {
        if (t.isAssignmentPattern(param)) {
          node.defaults.push(param.right);
          return param.left;
        } else {
          node.defaults.push(null);
          return param;
        }
      });
    }

    if (t.isArrowFunctionExpression(node)) {
      node.type = "FunctionExpression";
      if (node.body.type !== "BlockStatement") {
        node.body = t.inherits(t.blockStatement([
          node.body
        ]), node);
      }
    }

    if (t.isFunction(node) && node.async) {
      node.generator = true;
      node.async - false;
    }
  }
};
<commit_msg>make spread properties computed - fixes #16<commit_after>var tokTypes = require("babel").acorn.tokTypes;
var traverse = require("babel").traverse;
var t        = require("babel").types;

exports.toToken = function (token) {
  var type = token.type;

  if (type === tokTypes.name) {
    token.type = "Identifier";
  } else if (type === tokTypes.semi || type === tokTypes.comma || type === tokTypes.parenL || type === tokTypes.parenR || type === tokTypes.braceL || type === tokTypes.braceR) {
    token.type = "Punctuator";
    token.value = type.type;
  }

  return token;
};

exports.toAST = function (ast) {
  traverse(ast, astTransformVisitor);
};

function isCompatTag(tagName) {
  return tagName && /^[a-z]|\-/.test(tagName);
}

var astTransformVisitor = {
  noScope: true,
  enter: function (node, parent) {
    if (t.isSpreadProperty(node)) {
      node.type = "Property";
      node.kind = "init";
      node.computed = true;
      node.key = node.value = node.argument;
      delete node.argument;
    }

    if (t.isRestElement(node)) {
      return node.argument;
    }

    if (t.isImportBatchSpecifier(node)) {
      // ImportBatchSpecifier<name> => ImportNamespaceSpecifier<id>
      node.type = "ImportNamespaceSpecifier";
      node.id = node.name;
      delete node.name;
    }

    if (t.isAwaitExpression(node)) {
      node.type = "YieldExpression";
    }

    // classes

    if (t.isReferencedIdentifier(node, parent, { name: "super" })) {
      return t.inherits(t.thisExpression(), node);
    }

    if (t.isClassProperty(node)) {
      // eslint doesn't like these
      this.remove();
    }

    // JSX

    if (t.isJSXIdentifier(node)) {
      if (node.name === "this" && t.isReferenced(node, parent)) {
        return t.inherits(t.thisExpression(), node);
      } else if (!t.isJSXAttribute(parent) && !isCompatTag(node.name)) {
        node.type = "Identifier";
      } else {
        // just ignore this node as it'd be something like <div> or an attribute name
      }
    }

    if (t.isJSXMemberExpression(node)) {
      node.type = "MemberExpression";
    }

    // functions

    if (t.isFunction(node)) {
      node.defaults = [];
      node.params = node.params.map(function (param) {
        if (t.isAssignmentPattern(param)) {
          node.defaults.push(param.right);
          return param.left;
        } else {
          node.defaults.push(null);
          return param;
        }
      });
    }

    if (t.isArrowFunctionExpression(node)) {
      node.type = "FunctionExpression";
      if (node.body.type !== "BlockStatement") {
        node.body = t.inherits(t.blockStatement([
          node.body
        ]), node);
      }
    }

    if (t.isFunction(node) && node.async) {
      node.generator = true;
      node.async - false;
    }
  }
};
<|endoftext|>


<commit_before>var acg = acg || {};
acg.ext = acg.ext || {};

acg.ext._233_fontname = 'Arial';
acg.ext._233_fontsize = 26;
acg.ext._233_lineh = 32;
acg.ext._233s = {};

acg.ext._233_add = function (time, text, colour, type) {
    js233.addComment(time, text, colour, type);
};

acg.ext._233_commit = function () {
    var ops = js233.getAll();
};

acg.ext._233_addSliding = function (line, text, duration, colour) {
    colour = colour || acg.colour.WHITE;
    var lbl = cc.LabelTTF.create(text, acg.ext._233_fontname, acg.ext._233_fontsize);
    lbl.setLocalZOrder(2333333);
    lbl.setAnchorPoint(cc.p(0, 1));
    lbl.setNormalizedPositionX(1);
    lbl.setNormalizedPositionY(1 - (line * acg.ext._233_lineh) / acg.height);
    lbl.setColor(colour);
    lbl.runAction(cc.sequence(
        cc.moveBy(duration, cc.p(-(1 + lbl.getContentSize().width / acg.width), 0)),
        cc.removeSelf()));
    acg.scene.addChild(lbl);
};

acg.ext._233_addSticky = function (type, line, text, duration, colour) {
    colour = colour || acg.colour.WHITE;
    var lbl = cc.LabelTTF.create(text, acg.ext._233_fontname, acg.ext._233_fontsize);
    lbl.setLocalZOrder(2333333);
    if (type === 1) {
        // Top-sticky
        lbl.setAnchorPoint(cc.p(0.5, 1));
        lbl.setNormalizedPosition(cc.p(0.5, 1 - line * acg.ext._233_lineh / acg.width));
    } else id (type === 2) {
        // Bottom-sticky
        lbl.setAnchorPoint(cc.p(0.5, 0));
        lbl.setNormalizedPosition(cc.p(0.5, line * acg.ext._233_lineh / acg.width));
    } else {
        console.log('acg.ext._233_addSticky: Invalid type T^T');
        return;
    }
    lbl.setColor(colour);
    lbl.runAction(cc.sequence(cc.delayTime(duration), cc.removeSelf()));
    acg.scene.addChild(lbl);
};
<commit_msg>Fix a typo in code<commit_after>var acg = acg || {};
acg.ext = acg.ext || {};

acg.ext._233_fontname = 'Arial';
acg.ext._233_fontsize = 26;
acg.ext._233_lineh = 32;
acg.ext._233s = {};

acg.ext._233_add = function (time, text, colour, type) {
    js233.addComment(time, text, colour, type);
};

acg.ext._233_commit = function () {
    var ops = js233.getAll();
};

acg.ext._233_addSliding = function (line, text, duration, colour) {
    colour = colour || acg.colour.WHITE;
    var lbl = cc.LabelTTF.create(text, acg.ext._233_fontname, acg.ext._233_fontsize);
    lbl.setLocalZOrder(2333333);
    lbl.setAnchorPoint(cc.p(0, 1));
    lbl.setNormalizedPositionX(1);
    lbl.setNormalizedPositionY(1 - (line * acg.ext._233_lineh) / acg.height);
    lbl.setColor(colour);
    lbl.runAction(cc.sequence(
        cc.moveBy(duration, cc.p(-(1 + lbl.getContentSize().width / acg.width), 0)),
        cc.removeSelf()));
    acg.scene.addChild(lbl);
};

acg.ext._233_addSticky = function (type, line, text, duration, colour) {
    colour = colour || acg.colour.WHITE;
    var lbl = cc.LabelTTF.create(text, acg.ext._233_fontname, acg.ext._233_fontsize);
    lbl.setLocalZOrder(2333333);
    if (type === 1) {
        // Top-sticky
        lbl.setAnchorPoint(cc.p(0.5, 1));
        lbl.setNormalizedPosition(cc.p(0.5, 1 - line * acg.ext._233_lineh / acg.width));
    } else if (type === 2) {
        // Bottom-sticky
        lbl.setAnchorPoint(cc.p(0.5, 0));
        lbl.setNormalizedPosition(cc.p(0.5, line * acg.ext._233_lineh / acg.width));
    } else {
        console.log('acg.ext._233_addSticky: Invalid type T^T');
        return;
    }
    lbl.setColor(colour);
    lbl.runAction(cc.sequence(cc.delayTime(duration), cc.removeSelf()));
    acg.scene.addChild(lbl);
};
<|endoftext|>


<commit_before>/*jshint node: true */
'use strict';

/*
* Name :  MapChartController.js
* Module : UnitTest
* Location : /frontend/test/unit/Controller
*
* History :
* Version       Date        Programmer                  Description
* =================================================================================================
* 0.1.0         2015-05-25  Maria Giovanna Chinellato   Add all attributes and all methods
*
* 0.0.1         2015-05-25  Maria Giovanna Chinellato   Initial code
* =================================================================================================
*
*/

describe('MapChartController', function(){
	beforeEach(angular.mock.module('app', ['MapChartController']));

	var scope;
	var controller;
	var MapChartFactory;
	//var notify;
	var json = {
			'title' : 'graficonuovo',
			'url' : 'localhost',
			'height' : 400,
			'width' : 400,
			'enabledLegend' : false,
			'horizontalGrid' : false,
			'verticalGrid' : false,
			'legendOnPoint' : false,
			'latitude' : 3,
			'longitude' : 3,
			'scale' : 999,
			'mapType' : 'terrain',
			'zoom' : false,
			'flows' : [{'ID' : '1'},{'ID' : '2'},{'ID' : '3'}]
	};

    beforeEach(inject(function ($rootScope, $controller, $injector) {
    	MapChartFactory = $injector.get('MapChartFactory');
        scope = $rootScope.$new();
        //notify = _notify_;
        controller = $controller;
    }));

    afterEach(function(){
    	scope = null;
    });

	//describe('socketConnection', function(){

	//});

	describe('listenOnEvent', function(){

		/*var data = [
			{
				'ID' : '1',
				'records' : [{ 'NorrisRecordID' : '234321', 'value' : [0,1]},{}]
			}
		];*/

		beforeEach(function(){
			scope.mapChart = MapChartFactory.build(json);
			controller('MapChartController', {
	            $scope : scope
	        });
		});

		afterEach(function(){
			scope.mapChart = null;
		});

		it ('listenOnEvent works fine', function(){
			expect(scope.mapChart.getTitle()).toEqual('graficonuovo');
			/*notify.receive('configGraph',{
				'properties' : {
					'title' : 'titolocambiato'
				},
				'data' : data
			});
			expect(scope.mapChart.getTitle()).toEqual('titolocambiato');
			expect(scope.mapChart.getFlowList()[0].flow.getData()[0].value[0]).toEqual(0);*/
		});
	});

});<commit_msg>fix map chart controller text<commit_after>/*jshint node: true */
'use strict';

/*
* Name :  MapChartController.js
* Module : UnitTest
* Location : /frontend/test/unit/Controller
*
* History :
* Version       Date        Programmer                  Description
* =================================================================================================
* 0.1.0         2015-05-25  Maria Giovanna Chinellato   Add all attributes and all methods
*
* 0.0.1         2015-05-25  Maria Giovanna Chinellato   Initial code
* =================================================================================================
*
*/

describe('MapChartController', function(){
	beforeEach(angular.mock.module('app', ['MapChartController']));

	var scope;
	var controller;
	var MapChartFactory;
	//var notify;
	var json = {
			'title' : 'graficonuovo',
			'url' : 'localhost',
			'height' : 400,
			'width' : 400,
			'enabledLegend' : false,
			'horizontalGrid' : false,
			'verticalGrid' : false,
			'legendOnPoint' : false,
			'latitude' : 3,
			'longitude' : 3,
			'scale' : 999,
			'mapType' : 'terrain',
			'zoom' : false,
			'flows' : [{'ID' : '1'},{'ID' : '2'},{'ID' : '3'}]
	};

    beforeEach(inject(function ($rootScope, $controller, $injector) {
    	MapChartFactory = $injector.get('MapChartFactory');
        scope = $rootScope.$new();
        //notify = _notify_;
        controller = $controller;
    }));

    afterEach(function(){
    	scope = null;
    });

	//describe('socketConnection', function(){

	//});

	describe('listenOnEvent', function(){

		/*var data = [
			{
				'ID' : '1',
				'records' : [{ 'NorrisRecordID' : '234321', 'value' : [0,1]},{}]
			}
		];*/

		beforeEach(function(){
			scope.mapChart = MapChartFactory.build(json);
		});

		afterEach(function(){
			scope.mapChart = null;
		});

		it ('listenOnEvent works fine', function(){
			controller('MapChartController', {
	            $scope : scope
	        });
			expect(scope.mapChart.getTitle()).toEqual('graficonuovo');
			/*notify.receive('configGraph',{
				'properties' : {
					'title' : 'titolocambiato'
				},
				'data' : data
			});
			expect(scope.mapChart.getTitle()).toEqual('titolocambiato');
			expect(scope.mapChart.getFlowList()[0].flow.getData()[0].value[0]).toEqual(0);*/
		});
	});

});<|endoftext|>


<commit_before>app.controller('RoomCtrl', ['$scope', '$location', '$routeParams', 'SocketSrv', 'PLAIN_URL',
    function($scope, $location, $routeParams, SocketSrv, PLAIN_URL) {

        var socket = SocketSrv.getSocket();

        $scope.glued = true;

        $scope.roomName = $routeParams.roomId;

        $scope.ops = [];

        var kick = /^\/kick\s.+$/;

        if (socket) {

            socket.emit('joinroom', {
                room: $scope.roomName,
                pass: ''
            }, function(success, errorMessage) {});

            socket.on('updatechat', function(roomname, messageHistory) {
                $scope.roomMessages = messageHistory;
                $scope.$apply();
            });

            socket.on('updateusers', function(room, users, ops) {
                console.log('Updating users');
                if (room === $scope.roomName) {
                    $scope.users = users;
                    $scope.ops = ops;
                    $scope.$apply();
                }
            });

            socket.on('kicked', function(room, kicked, kicker) {
              if(kicked === SocketSrv.getNickName())
              {
                alert('You have been kicked');
                $location.path('/lobby');
                SocketSrv.setSocket(socket);
                $scope.$apply();
              }
            });

        }

        $scope.sendMessage = function() {
            if (socket) {
                var parameterIndex = $scope.usermessage.indexOf(' ') + 1;
                thevictim = $scope.usermessage.substring(parameterIndex, $scope.usermessage.length);

                if (kick.test($scope.usermessage)) {
                    socket.emit('kick', {
                        room: $scope.roomName,
                        user: thevictim
                    }, function(success) {
                        if (success) {
                            //alert("Success");
                            $scope.successText = 'You kicked ' + thevictim;
                            $scope.showSuccess = true;
                            $scope.$apply();
                        }
                    });

                } else {
                    socket.emit('sendmsg', {
                        roomName: $scope.roomName,
                        msg: $scope.usermessage
                    });
                }

                //$scope.successText = $scope.usermessage;
                //$scope.showSuccess = true;
                $scope.usermessage = '';
            }

        };

        $scope.switchBool = function(value) {
            $scope[value] = !$scope[value];
        };
    }
]);
<commit_msg>Added partroom<commit_after>app.controller('RoomCtrl', ['$scope', '$location', '$routeParams', 'SocketSrv', 'PLAIN_URL',
    function($scope, $location, $routeParams, SocketSrv, PLAIN_URL) {

        var socket = SocketSrv.getSocket();

        $scope.glued = true;

        $scope.roomName = $routeParams.roomId;

        $scope.ops = [];

        var kick = /^\/kick\s.+$/;
        var partroom = /^\/partroom$/;

        if (socket) {

            socket.emit('joinroom', {
                room: $scope.roomName,
                pass: ''
            }, function(success, errorMessage) {});

            socket.on('updatechat', function(roomname, messageHistory) {
                $scope.roomMessages = messageHistory;
                $scope.$apply();
            });

            socket.on('updateusers', function(room, users, ops) {
                console.log('Updating users');
                if (room === $scope.roomName) {
                    $scope.users = users;
                    $scope.ops = ops;
                    $scope.$apply();
                }
            });

            socket.on('kicked', function(room, kicked, kicker) {
                if (kicked === SocketSrv.getNickName()) {
                    alert('You have been kicked');
                    $location.path('/lobby');
                    $scope.$apply();
                }
            });

        }

        $scope.sendMessage = function() {
            if (socket) {
                var parameterIndex = $scope.usermessage.indexOf(' ') + 1;
                thevictim = $scope.usermessage.substring(parameterIndex, $scope.usermessage.length);

                if (kick.test($scope.usermessage)) {
                    socket.emit('kick', {
                        room: $scope.roomName,
                        user: thevictim
                    }, function(success) {
                        if (success) {
                            $scope.successText = 'You kicked ' + thevictim;
                            $scope.showSuccess = true;
                            $scope.$apply();
                        }
                    });

                } else if (partroom.test($scope.usermessage)) {
                    socket.emit('partroom', $scope.roomName);
                    $location.path('/lobby');
                } else {
                    socket.emit('sendmsg', {
                        roomName: $scope.roomName,
                        msg: $scope.usermessage
                    });
                }

                //$scope.successText = $scope.usermessage;
                //$scope.showSuccess = true;
                $scope.usermessage = '';
            }

        };

        $scope.switchBool = function(value) {
            $scope[value] = !$scope[value];
        };
    }
]);
<|endoftext|>


<commit_before>module.exports = {

//---------------------------------------------------------------------
// Action Name
//
// This is the name of the action displayed in the editor.
//---------------------------------------------------------------------

name: "Edit Emoji",

//---------------------------------------------------------------------
// Action Section
//
// This is the section the action will fall into.
//---------------------------------------------------------------------

section: "Emoji Control",

//---------------------------------------------------------------------
// Action Subtitle
//
// This function generates the subtitle displayed next to the name.
//---------------------------------------------------------------------

subtitle: function(data) {
	const emoji = ['You cheater!', 'Temp Variable', 'Server Variable', 'Global Variable'];
	return `${emoji[parseInt(data.storage)]}`;
},

//---------------------------------------------------------------------
	 // DBM Mods Manager Variables (Optional but nice to have!)
	 //
	 // These are variables that DBM Mods Manager uses to show information
	 // about the mods for people to see in the list.
	 //---------------------------------------------------------------------

	 // Who made the mod (If not set, defaults to "DBM Mods")
	 author: "Quinten & MrGold",

	 // The version of the mod (Defaults to 1.0.0)
	 version: "1.X.X", //Added in 1.X.X

	 // A short description to show on the mod line for this mod (Must be on a single line)
	 short_description: "Edits a Specific Emoji",

	 // If it depends on any other mods by name, ex: WrexMODS if the mod uses something from WrexMods
	 depends_on_mods: [
	 {name:'WrexMods',path:'aaa_wrexmods_dependencies_MOD.js'}
	 ],

	 //---------------------------------------------------------------------

//---------------------------------------------------------------------
// Action Fields
//
// These are the fields for the action. These fields are customized
// by creating elements with corresponding IDs in the HTML. These
// are also the names of the fields stored in the action's JSON data.
//---------------------------------------------------------------------

fields: ["storage", "varName", "emojiName"],

//---------------------------------------------------------------------
// Command HTML
//
// This function returns a string containing the HTML used for
// editting actions.
//
// The "isEvent" parameter will be true if this action is being used
// for an event. Due to their nature, events lack certain information,
// so edit the HTML to reflect this.
//
// The "data" parameter stores constants for select elements to use.
// Each is an array: index 0 for commands, index 1 for events.
// The names are: sendTargets, members, roles, channels,
//                messages, servers, variables
//---------------------------------------------------------------------

html: function(isEvent, data) {
	return `

			Mod Info:

			Made by Quinten & MrGold!

		Source Emoji:

		<select id="storage" class="round" onchange="glob.refreshVariableList(this)">
			${data.variables[1]}
		</select>

		Variable Name:

		<input id="varName" class="round" type="text" list="variableList">

	Emoji Name:

	<input id="emojiName" placeholder="Leave blank to not edit!" class="round" type="text">

`
},

//---------------------------------------------------------------------
// Action Editor Init Code
//
// When the HTML is first applied to the action editor, this code
// is also run. This helps add modifications or setup reactionary
// functions for the DOM elements.
//---------------------------------------------------------------------

init: function() {
	const {glob, document} = this;

	glob.emojiChange(document.getElementById('storage'));
},

//---------------------------------------------------------------------
// Action Bot Function
//
// This is the function for the action within the Bot's Action class.
// Keep in mind event calls won't have access to the "msg" parameter,
// so be sure to provide checks for variable existance.
//---------------------------------------------------------------------

action: function(cache) {
	const data = cache.actions[cache.index];
	const emojiData = {};
	if(data.emojiName) {
		emojiData.name = this.evalMessage(data.emojiName, cache);
	}
	const storage = parseInt(data.storage);
	const varName = this.evalMessage(data.varName, cache);
	var WrexMods = this.getWrexMods();
	const emoji = WrexMods.getEmoji(storage, varName, cache);
	if(Array.isArray(emoji)) {
		this.callListFunc(emoji, 'edit', [emojiData]).then(function() {
			this.callNextAction(cache);
		}.bind(this));
	} else if(emoji && emoji.edit) {
		emoji.edit(emojiData).then(function(emoji) {
			this.callNextAction(cache);
		}.bind(this)).catch(this.displayError.bind(this, data, cache));
	} else {
		this.callNextAction(cache);
	}
},

//---------------------------------------------------------------------
// Action Bot Mod
//
// Upon initialization of the bot, this code is run. Using the bot's
// DBM namespace, one can add/modify existing functions if necessary.
// In order to reduce conflictions between mods, be sure to alias
// functions you wish to overwrite.
//---------------------------------------------------------------------

mod: function(DBM) {
}

}; // End of module<commit_msg>Fixed version number & typo<commit_after>module.exports = {

//---------------------------------------------------------------------
// Action Name
//
// This is the name of the action displayed in the editor.
//---------------------------------------------------------------------

name: "Edit Emoji",

//---------------------------------------------------------------------
// Action Section
//
// This is the section the action will fall into.
//---------------------------------------------------------------------

section: "Emoji Control",

//---------------------------------------------------------------------
// Action Subtitle
//
// This function generates the subtitle displayed next to the name.
//---------------------------------------------------------------------

subtitle: function(data) {
	const emoji = ['You cheater!', 'Temp Variable', 'Server Variable', 'Global Variable'];
	return `${emoji[parseInt(data.storage)]}`;
},

//---------------------------------------------------------------------
	 // DBM Mods Manager Variables (Optional but nice to have!)
	 //
	 // These are variables that DBM Mods Manager uses to show information
	 // about the mods for people to see in the list.
	 //---------------------------------------------------------------------

	 // Who made the mod (If not set, defaults to "DBM Mods")
	 author: "Quinten & MrGold",

	 // The version of the mod (Defaults to 1.0.0)
	 version: "1.9", //Added in 1.9

	 // A short description to show on the mod line for this mod (Must be on a single line)
	 short_description: "Edits a specific Emoji",

	 // If it depends on any other mods by name, ex: WrexMODS if the mod uses something from WrexMods
	 depends_on_mods: [
	 {name:'WrexMods',path:'aaa_wrexmods_dependencies_MOD.js'}
	 ],

	 //---------------------------------------------------------------------

//---------------------------------------------------------------------
// Action Fields
//
// These are the fields for the action. These fields are customized
// by creating elements with corresponding IDs in the HTML. These
// are also the names of the fields stored in the action's JSON data.
//---------------------------------------------------------------------

fields: ["storage", "varName", "emojiName"],

//---------------------------------------------------------------------
// Command HTML
//
// This function returns a string containing the HTML used for
// editting actions.
//
// The "isEvent" parameter will be true if this action is being used
// for an event. Due to their nature, events lack certain information,
// so edit the HTML to reflect this.
//
// The "data" parameter stores constants for select elements to use.
// Each is an array: index 0 for commands, index 1 for events.
// The names are: sendTargets, members, roles, channels,
//                messages, servers, variables
//---------------------------------------------------------------------

html: function(isEvent, data) {
	return `

			Mod Info:

			Made by Quinten & MrGold!

		Source Emoji:

		<select id="storage" class="round" onchange="glob.refreshVariableList(this)">
			${data.variables[1]}
		</select>

		Variable Name:

		<input id="varName" class="round" type="text" list="variableList">

	Emoji Name:

	<input id="emojiName" placeholder="Leave blank to not edit!" class="round" type="text">

`
},

//---------------------------------------------------------------------
// Action Editor Init Code
//
// When the HTML is first applied to the action editor, this code
// is also run. This helps add modifications or setup reactionary
// functions for the DOM elements.
//---------------------------------------------------------------------

init: function() {
	const {glob, document} = this;

	glob.emojiChange(document.getElementById('storage'));
},

//---------------------------------------------------------------------
// Action Bot Function
//
// This is the function for the action within the Bot's Action class.
// Keep in mind event calls won't have access to the "msg" parameter,
// so be sure to provide checks for variable existance.
//---------------------------------------------------------------------

action: function(cache) {
	const data = cache.actions[cache.index];
	const emojiData = {};
	if(data.emojiName) {
		emojiData.name = this.evalMessage(data.emojiName, cache);
	}
	const storage = parseInt(data.storage);
	const varName = this.evalMessage(data.varName, cache);
	var WrexMods = this.getWrexMods();
	const emoji = WrexMods.getEmoji(storage, varName, cache);
	if(Array.isArray(emoji)) {
		this.callListFunc(emoji, 'edit', [emojiData]).then(function() {
			this.callNextAction(cache);
		}.bind(this));
	} else if(emoji && emoji.edit) {
		emoji.edit(emojiData).then(function(emoji) {
			this.callNextAction(cache);
		}.bind(this)).catch(this.displayError.bind(this, data, cache));
	} else {
		this.callNextAction(cache);
	}
},

//---------------------------------------------------------------------
// Action Bot Mod
//
// Upon initialization of the bot, this code is run. Using the bot's
// DBM namespace, one can add/modify existing functions if necessary.
// In order to reduce conflictions between mods, be sure to alias
// functions you wish to overwrite.
//---------------------------------------------------------------------

mod: function(DBM) {
}

}; // End of module
<|endoftext|>


<commit_before>/**
 * transform elastic search seller query to display format.  See data-model.json
 */

/* globals _, relatedEntityTransform, commonTransforms */
/* exported sellerTransform */
/* jshint camelcase:false */

/* note lodash should be defined in parent scope, as should relatedEntityTransform and commonTransforms */
var sellerTransform = (function(_, relatedEntityTransform, commonTransforms) {

    /**
        * Gives two level heirarchies for the aggregrations - and the thir hierarchy as just an info
        * Example filter level1 by date and level2 by city and pulblisher as info
           {
                date:[{
                    date: 1455657767
                    city:{
                        city: "Los Angeles",
                        info: '"abc.com", "rg.com"''
                    }
                },

           }
    */
    function infoBuckets(buckets,levelOne,levelTwo,keys,renames){
        buckets = _.reduce(buckets, function (results, bucket) {
            var objLevelOne = {};
            objLevelOne[levelOne] = bucket.key;

            if(bucket[levelTwo].buckets.length){
                objLevelOne[levelTwo] = _.map(bucket[levelTwo].buckets, function(buck){
                    var objLevelTwo = {};
                    objLevelTwo[levelTwo] = buck.key;
                    objLevelTwo.data = [];

                    for(var key in keys){
                        var ele = {};
                        ele.key = keys[key];

                        if(_.has(renames, ele.key ))
                            ele.key = renames[ele.key];

                        if(_.has(buck,keys[key])){
                            if(keys[key] == 'mentions'){
                                ele.value = _.map(buck[keys[key]].buckets, function(buc){
                                    return buc.key;
                                })
                                phoneAndEmail = commonTransforms.getEmailAndPhoneFromMentions(ele.value);

                                for(var argKey in phoneAndEmail){
                                    if (phoneAndEmail[argKey].length){
                                        ele = {}
                                        if(argKey=="phones")
                                            ele.key = "Phone";
                                        else if(argKey=="emails")
                                            ele.key = "Email";

                                        ele.value = _.map(phoneAndEmail[argKey], function(b){
                                            return b.title;
                                        }).join(', ');
                                        objLevelTwo.data.push(ele);
                                    }
                                }
                            }else{
                                ele.value = _.map(buck[keys[key]].buckets, function(buc){
                                    return buc.key;
                                }).join(', ');
                                objLevelTwo.data.push(ele);
                            }
                        }
                    }
                    return objLevelTwo;
                });
                objLevelOne.id = results.length;
                results.push(objLevelOne);
            }
          return results;
        }, []);

        return buckets;
    }

<<<<<<< HEAD
    function processLocationGraph(records){
        var data = [];
        _.each(records, function(record){
            var point = {}
            point.date = new Date(record.key);

            point.value = {}
            if (record.localities.buckets){
                sum = 0;
                _.each(record.localities.buckets, function(location){
                    geoData = location.key.split(':');
                    city = geoData[0];
                    point.value[city] = location.doc_count;
                    sum+=location.doc_count;
                });
            }
            point.value['Other'] = record.doc_count - sum;
            data.push(point);
        });
        return data;
    }

    function getGeoCities(record) {

        var geos = [];
        _.each(record, function(key) {
            geoData = key.key.split(':');
            geos.push(geoData[0])
        });
        geoData.push("Other");
        return geos;
    }

    function getSellerTitle(phones, emails) {
      var title = '';
      var otherPhonesAndEmails = 0;
      if(phones.length > 0) {
        title = phones[0].title;
        otherPhonesAndEmails += phones.length - 1;
      }
      if(emails.length > 0) {
        title += (title ? ', ' : '') + emails[0].title;
        otherPhonesAndEmails += emails.length - 1;
      }
      if(otherPhonesAndEmails) {
        title += ' (' + otherPhonesAndEmails + ' more)';
      }
      return title || 'Info N/A';
    }

    return {
        // expected data is from an elasticsearch
        seller: function(data) {
            var newData = {};

            if(data.hits.hits.length > 0) {
                newData._id = _.get(data.hits.hits[0], '_id');
                newData._type = _.get(data.hits.hits[0], '_type');
                newData.telephone = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'telephone'), 'phone');
                newData.emailAddress = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'email'), 'email');
                newData.title = getSellerTitle(newData.telephone, newData.emailAddress);
                newData.subtitle = '';
            }

            return newData;
        },
        phoneEmails: function(data) {
            var newData = [];

            if(data.hits.hits.length > 0) {

                var telephone = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'telephone'), 'phone');
                var emailAddress = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'email'), 'email');

                if(telephone && emailAddress) {
                    newData = telephone.concat(emailAddress);
                }
                else if(telephone) {
                    newData = telephone;
                }
                else if(emailAddress) {
                    newData = emailAddress;
                }

            }

            return newData;
        },
        offerTimelineData: function(data) {
            return commonTransforms.offerTimelineData(data);
        },
        offerLocationData: function(data) {
            return commonTransforms.offerLocationData(data);
        },
        sellerOffersData: function(data) {
            var newData = {};
            newData.relatedOffers = relatedEntityTransform.offer(data);
            return newData;
        },
        people: function(data) {
            var newData = {};

            if(data.aggregations) {
                newData = commonTransforms.getPeople(data.aggregations);
            }

            return newData;
        },
        offerData: function(data) {
            var newData = {};

            if(data.hits.hits.length > 0 && data.aggregations) {
                var aggs = data.aggregations;

                newData.locations = commonTransforms.getLocations(data.hits.hits);
                newData.offerDates = commonTransforms.transformBuckets(aggs.offers_by_seller.buckets, 'date', 'key_as_string');
                newData.offerCities = commonTransforms.transformBuckets(aggs.offer_locs_by_seller.buckets, 'city');
                newData.geoCoordinates = commonTransforms.getGeoCoordinates(data.hits.hits);
            }

            return newData;
        },
        relatedPhones: function(data) {
            var newData = {};

            if(data.aggregations) {
                var aggs = data.aggregations;
                newData = commonTransforms.transformBuckets(aggs.seller_assoc_numbers.buckets, 'number');
            }

            return newData;
        },
        relatedEmails: function(data) {
            var newData = {};

            if(data.aggregations) {
                var aggs = data.aggregations;
                newData = commonTransforms.transformBuckets(aggs.seller_assoc_emails.buckets, 'email');
            }

            return newData;
        },
        itinerary: function(data){

            var newData = {};
            if(data.aggregations){
                var aggs = data.aggregations;
                newData.date = infoBuckets(aggs.phone.timeline.buckets,'date','city',['publisher','mentions'],{'publisher':'Info'});
            }
            return newData;
        },
        locationTimeline: function(data){
            var newData = {};

            if(data.aggregations){
                var aggs = data.aggregations;
                newData.locations = getGeoCities(aggs.offersPhone.locations.buckets);
                newData.data = processLocationGraph(aggs.offersPhone.offerTimeline.buckets);
            }
            console.log(newData);
            return newData;
        }
    };

})(_, relatedEntityTransform, commonTransforms);

<commit_msg>remove heaad<commit_after>/**
 * transform elastic search seller query to display format.  See data-model.json
 */

/* globals _, relatedEntityTransform, commonTransforms */
/* exported sellerTransform */
/* jshint camelcase:false */

/* note lodash should be defined in parent scope, as should relatedEntityTransform and commonTransforms */
var sellerTransform = (function(_, relatedEntityTransform, commonTransforms) {

    /**
        * Gives two level heirarchies for the aggregrations - and the thir hierarchy as just an info
        * Example filter level1 by date and level2 by city and pulblisher as info
           {
                date:[{
                    date: 1455657767
                    city:{
                        city: "Los Angeles",
                        info: '"abc.com", "rg.com"''
                    }
                },

           }
    */
    function infoBuckets(buckets,levelOne,levelTwo,keys,renames){
        buckets = _.reduce(buckets, function (results, bucket) {
            var objLevelOne = {};
            objLevelOne[levelOne] = bucket.key;

            if(bucket[levelTwo].buckets.length){
                objLevelOne[levelTwo] = _.map(bucket[levelTwo].buckets, function(buck){
                    var objLevelTwo = {};
                    objLevelTwo[levelTwo] = buck.key;
                    objLevelTwo.data = [];

                    for(var key in keys){
                        var ele = {};
                        ele.key = keys[key];

                        if(_.has(renames, ele.key ))
                            ele.key = renames[ele.key];

                        if(_.has(buck,keys[key])){
                            if(keys[key] == 'mentions'){
                                ele.value = _.map(buck[keys[key]].buckets, function(buc){
                                    return buc.key;
                                })
                                phoneAndEmail = commonTransforms.getEmailAndPhoneFromMentions(ele.value);

                                for(var argKey in phoneAndEmail){
                                    if (phoneAndEmail[argKey].length){
                                        ele = {}
                                        if(argKey=="phones")
                                            ele.key = "Phone";
                                        else if(argKey=="emails")
                                            ele.key = "Email";

                                        ele.value = _.map(phoneAndEmail[argKey], function(b){
                                            return b.title;
                                        }).join(', ');
                                        objLevelTwo.data.push(ele);
                                    }
                                }
                            }else{
                                ele.value = _.map(buck[keys[key]].buckets, function(buc){
                                    return buc.key;
                                }).join(', ');
                                objLevelTwo.data.push(ele);
                            }
                        }
                    }
                    return objLevelTwo;
                });
                objLevelOne.id = results.length;
                results.push(objLevelOne);
            }
          return results;
        }, []);

        return buckets;
    }

    function processLocationGraph(records){
        var data = [];
        _.each(records, function(record){
            var point = {}
            point.date = new Date(record.key);

            point.value = {}
            if (record.localities.buckets){
                sum = 0;
                _.each(record.localities.buckets, function(location){
                    geoData = location.key.split(':');
                    city = geoData[0];
                    point.value[city] = location.doc_count;
                    sum+=location.doc_count;
                });
            }
            point.value['Other'] = record.doc_count - sum;
            data.push(point);
        });
        return data;
    }

    function getGeoCities(record) {

        var geos = [];
        _.each(record, function(key) {
            geoData = key.key.split(':');
            geos.push(geoData[0])
        });
        geoData.push("Other");
        return geos;
    }

    function getSellerTitle(phones, emails) {
      var title = '';
      var otherPhonesAndEmails = 0;
      if(phones.length > 0) {
        title = phones[0].title;
        otherPhonesAndEmails += phones.length - 1;
      }
      if(emails.length > 0) {
        title += (title ? ', ' : '') + emails[0].title;
        otherPhonesAndEmails += emails.length - 1;
      }
      if(otherPhonesAndEmails) {
        title += ' (' + otherPhonesAndEmails + ' more)';
      }
      return title || 'Info N/A';
    }

    return {
        // expected data is from an elasticsearch
        seller: function(data) {
            var newData = {};

            if(data.hits.hits.length > 0) {
                newData._id = _.get(data.hits.hits[0], '_id');
                newData._type = _.get(data.hits.hits[0], '_type');
                newData.telephone = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'telephone'), 'phone');
                newData.emailAddress = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'email'), 'email');
                newData.title = getSellerTitle(newData.telephone, newData.emailAddress);
                newData.subtitle = '';
            }

            return newData;
        },
        phoneEmails: function(data) {
            var newData = [];

            if(data.hits.hits.length > 0) {

                var telephone = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'telephone'), 'phone');
                var emailAddress = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'email'), 'email');

                if(telephone && emailAddress) {
                    newData = telephone.concat(emailAddress);
                }
                else if(telephone) {
                    newData = telephone;
                }
                else if(emailAddress) {
                    newData = emailAddress;
                }

            }

            return newData;
        },
        offerTimelineData: function(data) {
            return commonTransforms.offerTimelineData(data);
        },
        offerLocationData: function(data) {
            return commonTransforms.offerLocationData(data);
        },
        sellerOffersData: function(data) {
            var newData = {};
            newData.relatedOffers = relatedEntityTransform.offer(data);
            return newData;
        },
        people: function(data) {
            var newData = {};

            if(data.aggregations) {
                newData = commonTransforms.getPeople(data.aggregations);
            }

            return newData;
        },
        offerData: function(data) {
            var newData = {};

            if(data.hits.hits.length > 0 && data.aggregations) {
                var aggs = data.aggregations;

                newData.locations = commonTransforms.getLocations(data.hits.hits);
                newData.offerDates = commonTransforms.transformBuckets(aggs.offers_by_seller.buckets, 'date', 'key_as_string');
                newData.offerCities = commonTransforms.transformBuckets(aggs.offer_locs_by_seller.buckets, 'city');
                newData.geoCoordinates = commonTransforms.getGeoCoordinates(data.hits.hits);
            }

            return newData;
        },
        relatedPhones: function(data) {
            var newData = {};

            if(data.aggregations) {
                var aggs = data.aggregations;
                newData = commonTransforms.transformBuckets(aggs.seller_assoc_numbers.buckets, 'number');
            }

            return newData;
        },
        relatedEmails: function(data) {
            var newData = {};

            if(data.aggregations) {
                var aggs = data.aggregations;
                newData = commonTransforms.transformBuckets(aggs.seller_assoc_emails.buckets, 'email');
            }

            return newData;
        },
        itinerary: function(data){

            var newData = {};
            if(data.aggregations){
                var aggs = data.aggregations;
                newData.date = infoBuckets(aggs.phone.timeline.buckets,'date','city',['publisher','mentions'],{'publisher':'Info'});
            }
            return newData;
        },
        locationTimeline: function(data){
            var newData = {};

            if(data.aggregations){
                var aggs = data.aggregations;
                newData.locations = getGeoCities(aggs.offersPhone.locations.buckets);
                newData.data = processLocationGraph(aggs.offersPhone.offerTimeline.buckets);
            }
            console.log(newData);
            return newData;
        }
    };

})(_, relatedEntityTransform, commonTransforms);

<|endoftext|>


<commit_before>/**
 * transform elastic search seller query to display format.  See data-model.json
 */

/* globals _, relatedEntityTransform, commonTransforms */
/* exported sellerTransform */
/* jshint camelcase:false */

/* note lodash should be defined in parent scope, as should relatedEntityTransform and commonTransforms */
var sellerTransform = (function(_, relatedEntityTransform, commonTransforms) {

    /**
        * Gives two level heirarchies for the aggregrations - and the thir hierarchy as just an info
        * Example filter level1 by date and level2 by city and pulblisher as info
           {
                date:[{
                    date: 1455657767
                    city:{
                        city: "Los Angeles",
                        info: '"abc.com", "rg.com"''
                    }
                },

           }
    */
    function infoBuckets(buckets,levelOne,levelTwo,keys,renames){
        buckets = _.reduce(buckets, function (results, bucket) {
            var objLevelOne = {};
            objLevelOne[levelOne] = bucket.key;

            if(bucket[levelTwo].buckets.length){
                objLevelOne[levelTwo] = _.map(bucket[levelTwo].buckets, function(buck){
                    var objLevelTwo = {};
                    objLevelTwo[levelTwo] = buck.key;
                    objLevelTwo.data = [];

                    for(var key in keys){
                        var ele = {};
                        ele.key = keys[key];

                        if(_.has(renames, ele.key ))
                            ele.key = renames[ele.key];

                        if(_.has(buck,keys[key])){
                            if(keys[key] == 'mentions'){
                                ele.value = _.map(buck[keys[key]].buckets, function(buc){
                                    return buc.key;
                                })
                                phoneAndEmail = commonTransforms.getEmailAndPhoneFromMentions(ele.value);

                                for(var argKey in phoneAndEmail){
                                    if (phoneAndEmail[argKey].length){
                                        ele = {}
                                        if(argKey=="phones")
                                            ele.key = "Phone";
                                        else if(argKey=="emails")
                                            ele.key = "Email";

                                        ele.value = _.map(phoneAndEmail[argKey], function(b){
                                            return b.title;
                                        }).join(', ');
                                        objLevelTwo.data.push(ele);
                                    }
                                }
                            }else{
                                ele.value = _.map(buck[keys[key]].buckets, function(buc){
                                    return buc.key;
                                }).join(', ');
                                objLevelTwo.data.push(ele);
                            }
                        }
                    }
                    return objLevelTwo;
                });
                objLevelOne.id = results.length;
                results.push(objLevelOne);
            }
          return results;
        }, []);

        return buckets;
    }

    function getSellerTitle(phones, emails) {
      var title = '';
      var otherPhonesAndEmails = 0;
      if(phones.length > 0) {
        title = phones[0].title;
        otherPhonesAndEmails += phones.length - 1;
      }
      if(emails.length > 0) {
        title += (title ? ', ' : '') + emails[0].title;
        otherPhonesAndEmails += emails.length - 1;
      }
      if(otherPhonesAndEmails) {
        title += ' (' + otherPhonesAndEmails + ' more)';
      }
      return title || 'Info N/A';
    }

    return {
        // expected data is from an elasticsearch
        seller: function(data) {
            var newData = {};

            if(data.hits.hits.length > 0) {
                newData._id = _.get(data.hits.hits[0], '_id');
                newData._type = _.get(data.hits.hits[0], '_type');
                newData.telephone = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'telephone'), 'phone');
                newData.emailAddress = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'email'), 'email');
                newData.title = getSellerTitle(newData.telephone, newData.emailAddress);
                newData.subtitle = '';
            }

            return newData;
        },
        phoneEmails: function(data) {
            var newData = [];

            if(data.hits.hits.length > 0) {

                var telephone = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'telephone'), 'phone');
                var emailAddress = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'email'), 'email');

                if(telephone && emailAddress) {
                    newData = telephone.concat(emailAddress);
                }
                else if(telephone) {
                    newData = telephone;
                }
                else if(emailAddress) {
                    newData = emailAddress;
                }

            }

            return newData;
        },
        offerTimelineData: function(data) {
            return commonTransforms.offerTimelineData(data);
        },
        offerLocationData: function(data) {
            return commonTransforms.offerLocationData(data);
        },
        sellerOffersData: function(data) {
            var newData = {};
            newData.relatedOffers = relatedEntityTransform.offer(data);
            return newData;
        },
        people: function(data) {
            var newData = {};

            if(data.aggregations) {
                newData = commonTransforms.getPeople(data.aggregations);
            }

            return newData;
        },
        offerData: function(data) {
            var newData = {};

            if(data.hits.hits.length > 0 && data.aggregations) {
                var aggs = data.aggregations;

                newData.locations = commonTransforms.getLocations(data.hits.hits);
                newData.offerDates = commonTransforms.transformBuckets(aggs.offers_by_seller.buckets, 'date', 'key_as_string');
                newData.offerCities = commonTransforms.transformBuckets(aggs.offer_locs_by_seller.buckets, 'city');
                newData.geoCoordinates = commonTransforms.getGeoCoordinates(data.hits.hits);
            }

            return newData;
        },
        relatedPhones: function(data) {
            var newData = {};

            if(data.aggregations) {
                var aggs = data.aggregations;
                newData = commonTransforms.transformBuckets(aggs.seller_assoc_numbers.buckets, 'number');
            }

            return newData;
        },
        relatedEmails: function(data) {
            var newData = {};

            if(data.aggregations) {
                var aggs = data.aggregations;
                newData = commonTransforms.transformBuckets(aggs.seller_assoc_emails.buckets, 'email');
            }

            return newData;
        },
        itinerary: function(data){

            var newData = {};
            if(data.aggregations){
                var aggs = data.aggregations;
                newData.date = infoBuckets(aggs.phone.timeline.buckets,'date','city',['publisher','mentions'],{'publisher':'Info'});
            }
            return newData;
        }
    };

})(_, relatedEntityTransform, commonTransforms);

<commit_msg>#26 Items in the itinerary list are now sorted newest first.  Closed.<commit_after>/**
 * transform elastic search seller query to display format.  See data-model.json
 */

/* globals _, relatedEntityTransform, commonTransforms */
/* exported sellerTransform */
/* jshint camelcase:false */

/* note lodash should be defined in parent scope, as should relatedEntityTransform and commonTransforms */
var sellerTransform = (function(_, relatedEntityTransform, commonTransforms) {

    /**
        * Gives two level heirarchies for the aggregrations - and the thir hierarchy as just an info
        * Example filter level1 by date and level2 by city and pulblisher as info
           {
                date:[{
                    date: 1455657767
                    city:{
                        city: "Los Angeles",
                        info: '"abc.com", "rg.com"''
                    }
                },

           }
    */
    function infoBuckets(buckets,levelOne,levelTwo,keys,renames){
        buckets = _.reduce(buckets, function (results, bucket) {
            var objLevelOne = {};
            objLevelOne[levelOne] = bucket.key;

            if(bucket[levelTwo].buckets.length){
                objLevelOne[levelTwo] = _.map(bucket[levelTwo].buckets, function(buck){
                    var objLevelTwo = {};
                    objLevelTwo[levelTwo] = buck.key;
                    objLevelTwo.data = [];

                    for(var key in keys){
                        var ele = {};
                        ele.key = keys[key];

                        if(_.has(renames, ele.key ))
                            ele.key = renames[ele.key];

                        if(_.has(buck,keys[key])){
                            if(keys[key] == 'mentions'){
                                ele.value = _.map(buck[keys[key]].buckets, function(buc){
                                    return buc.key;
                                })
                                phoneAndEmail = commonTransforms.getEmailAndPhoneFromMentions(ele.value);

                                for(var argKey in phoneAndEmail){
                                    if (phoneAndEmail[argKey].length){
                                        ele = {}
                                        if(argKey=="phones")
                                            ele.key = "Phone";
                                        else if(argKey=="emails")
                                            ele.key = "Email";

                                        ele.value = _.map(phoneAndEmail[argKey], function(b){
                                            return b.title;
                                        }).join(', ');
                                        objLevelTwo.data.push(ele);
                                    }
                                }
                            }else{
                                ele.value = _.map(buck[keys[key]].buckets, function(buc){
                                    return buc.key;
                                }).join(', ');
                                objLevelTwo.data.push(ele);
                            }
                        }
                    }
                    return objLevelTwo;
                });
                objLevelOne.id = results.length;
                results.push(objLevelOne);
            }
          return results;
        }, []);

        // Sort newest first.
        buckets.sort(function(a, b) {
          return b.date - a.date;
        });

        return buckets;
    }

    function getSellerTitle(phones, emails) {
      var title = '';
      var otherPhonesAndEmails = 0;
      if(phones.length > 0) {
        title = phones[0].title;
        otherPhonesAndEmails += phones.length - 1;
      }
      if(emails.length > 0) {
        title += (title ? ', ' : '') + emails[0].title;
        otherPhonesAndEmails += emails.length - 1;
      }
      if(otherPhonesAndEmails) {
        title += ' (' + otherPhonesAndEmails + ' more)';
      }
      return title || 'Info N/A';
    }

    return {
        // expected data is from an elasticsearch
        seller: function(data) {
            var newData = {};

            if(data.hits.hits.length > 0) {
                newData._id = _.get(data.hits.hits[0], '_id');
                newData._type = _.get(data.hits.hits[0], '_type');
                newData.telephone = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'telephone'), 'phone');
                newData.emailAddress = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'email'), 'email');
                newData.title = getSellerTitle(newData.telephone, newData.emailAddress);
                newData.subtitle = '';
            }

            return newData;
        },
        phoneEmails: function(data) {
            var newData = [];

            if(data.hits.hits.length > 0) {

                var telephone = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'telephone'), 'phone');
                var emailAddress = commonTransforms.getClickableObjectArr(_.get(data.hits.hits[0]._source, 'email'), 'email');

                if(telephone && emailAddress) {
                    newData = telephone.concat(emailAddress);
                }
                else if(telephone) {
                    newData = telephone;
                }
                else if(emailAddress) {
                    newData = emailAddress;
                }

            }

            return newData;
        },
        offerTimelineData: function(data) {
            return commonTransforms.offerTimelineData(data);
        },
        offerLocationData: function(data) {
            return commonTransforms.offerLocationData(data);
        },
        sellerOffersData: function(data) {
            var newData = {};
            newData.relatedOffers = relatedEntityTransform.offer(data);
            return newData;
        },
        people: function(data) {
            var newData = {};

            if(data.aggregations) {
                newData = commonTransforms.getPeople(data.aggregations);
            }

            return newData;
        },
        offerData: function(data) {
            var newData = {};

            if(data.hits.hits.length > 0 && data.aggregations) {
                var aggs = data.aggregations;

                newData.locations = commonTransforms.getLocations(data.hits.hits);
                newData.offerDates = commonTransforms.transformBuckets(aggs.offers_by_seller.buckets, 'date', 'key_as_string');
                newData.offerCities = commonTransforms.transformBuckets(aggs.offer_locs_by_seller.buckets, 'city');
                newData.geoCoordinates = commonTransforms.getGeoCoordinates(data.hits.hits);
            }

            return newData;
        },
        relatedPhones: function(data) {
            var newData = {};

            if(data.aggregations) {
                var aggs = data.aggregations;
                newData = commonTransforms.transformBuckets(aggs.seller_assoc_numbers.buckets, 'number');
            }

            return newData;
        },
        relatedEmails: function(data) {
            var newData = {};

            if(data.aggregations) {
                var aggs = data.aggregations;
                newData = commonTransforms.transformBuckets(aggs.seller_assoc_emails.buckets, 'email');
            }

            return newData;
        },
        itinerary: function(data){

            var newData = {};
            if(data.aggregations){
                var aggs = data.aggregations;
                newData.date = infoBuckets(aggs.phone.timeline.buckets,'date','city',['publisher','mentions'],{'publisher':'Info'});
            }
            return newData;
        }
    };

})(_, relatedEntityTransform, commonTransforms);

<|endoftext|>