<commit_before>/**
 * Copyright 2015 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.
 */
'use strict';

var argv = require('minimist')(process.argv.slice(2));
var gulp = require('gulp-help')(require('gulp'));
var glob = require('glob');
var Karma = require('karma').Server;
var config = require('../config');
var read = require('file-reader');
var fs = require('fs');
var path = require('path');
var util = require('gulp-util');
var webserver = require('gulp-webserver');
var app = require('../test-server').app;
var karmaDefault = require('./karma.conf');

/**
 * Read in and process the configuration settings for karma
 * @return {!Object} Karma configuration
 */
function getConfig() {
  if (argv.safari) {
    return Object.assign({}, karmaDefault, {browsers: ['Safari']});
  }
  if (argv.firefox) {
    return Object.assign({}, karmaDefault, {browsers: ['Firefox']});
  }
  if (argv.edge) {
    return Object.assign({}, karmaDefault, {browsers: ['Edge']});
  }

  if (argv.saucelabs) {
    if (!process.env.SAUCE_USERNAME) {
      throw new Error('Missing SAUCE_USERNAME Env variable');
    }
    if (!process.env.SAUCE_ACCESS_KEY) {
      throw new Error('Missing SAUCE_ACCESS_KEY Env variable');
    }
    return Object.assign({}, karmaDefault, {
      reporters: ['dots', 'saucelabs'],
      browsers: argv.oldchrome
          ? ['SL_Chrome_45']
          : [
            'SL_Chrome_android',
            'SL_Chrome_latest',
            'SL_Chrome_45',
            'SL_Firefox_latest',
            //'SL_Safari_8' // Disabled due to flakiness and low market share
            'SL_Safari_9',
            'SL_Edge_latest',
            //'SL_iOS_8_4', // Disabled due to flakiness and low market share
            'SL_iOS_9_1',
            'SL_iOS_10_0',
            //'SL_IE_11',
          ],
    });
  }
  return karmaDefault;
}

function getAdTypes() {
  const namingExceptions = {
    // We recommend 3P ad networks use the same string for filename and type.
    // Write exceptions here in alphabetic order.
    // filename: [type1, type2, ... ]
    adblade: ['adblade', 'industrybrains'],
    mantis: ['mantis-display', 'mantis-recommend'],
    weborama: ['weborama-display'],
  };

  // Start with Google ad types
  const adTypes = ['adsense', 'doubleclick'];

  // Add all other ad types
  const files = fs.readdirSync('./ads/');
  for (var i = 0; i < files.length; i++) {
    if (path.extname(files[i]) == '.js'
        && files[i][0] != '_' && files[i] != 'ads.extern.js') {
      const adType = path.basename(files[i], '.js');
      const expanded = namingExceptions[adType];
      if (expanded) {
        for (var j = 0; j < expanded.length; j++) {
          adTypes.push(expanded[j]);
        }
      } else {
        adTypes.push(adType);
      }
    }
  }
  return adTypes;
}

/**
 * Run tests.
 */
gulp.task('test', 'Runs tests', argv.nobuild ? [] : ['build'], function(done) {
  if (!argv.integration && process.env.AMPSAUCE_REPO) {
    console./*OK*/info('Deactivated for ampsauce repo')
  }

  var c = getConfig();

  if (argv.watch || argv.w) {
    c.singleRun = false;
  }

  if (argv.verbose || argv.v) {
    c.client.captureConsole = true;
  }

  if (argv.files) {
    c.files = [].concat(config.commonTestPaths, argv.files);
  } else if (argv.integration) {
    c.files = config.integrationTestPaths;
  } else if (argv.randomize || argv.glob) {
    /** Randomize the order of the test running */
    var testPaths = [
      'test/**/*.js',
      'ads/**/test/test-*.js',
      'extensions/**/test/**/*.js',
    ];

    var testFiles = [];

    for (var index in testPaths) {
      testFiles = testFiles.concat(glob.sync(testPaths[index]));
    }

    if (argv.randomize) {
      testFiles = shuffleArray(testFiles);
    }
    // we need to replace the test init with something that won't match
    // any file. _init_tests gets added twice due to the regex matching.
    testFiles[testFiles.indexOf('test/_init_tests.js')] = '_WONTMATCH.qqq';
    c.files = config.commonTestPaths.concat(testFiles);

    util.log(util.colors.blue(JSON.stringify(c.files)));
    util.log(util.colors.yellow("Save the above files in a .json file to reuse"));

  } else if (argv.testlist) {
    var file = read.file(argv.testlist);
    util.log(file);
    c.files = file;

  } else {
    c.files = config.testPaths;
  }

  // c.client is available in test browser via window.parent.karma.config
  c.client.amp = {
    useCompiledJs: !!argv.compiled,
    saucelabs: !!argv.saucelabs,
    adTypes: getAdTypes(),
  };

  if (argv.compiled) {
    process.env.SERVE_MODE = 'compiled';
  } else {
    process.env.SERVE_MODE = 'default';
  }

  if (argv.grep) {
    c.client.mocha = {
      'grep': argv.grep,
    };
  }

  // Run fake-server to test XHR responses.
  var server = gulp.src(process.cwd())
      .pipe(webserver({
        port: 31862,
        host: 'localhost',
        directoryListing: true,
        middleware: [app],
      }));
  util.log(util.colors.yellow(
      'Started test responses server on localhost:31862'));

  new Karma(c, function(exitCode) {
    util.log(util.colors.yellow(
        'Shutting down test responses server on localhost:31862'));
    server.emit('kill');
    if (exitCode) {
      var error = new Error(
          util.colors.red('Karma test failed (error code: ' + exitCode + ')'));
      done(error);
    } else {
      done();
    }
  }).start();
}, {
  options: {
    'verbose': '  With logging enabled',
    'watch': '  Watches for changes in files, runs corresponding test(s)',
    'saucelabs': '  Runs test on saucelabs (requires setup)',
    'safari': '  Runs tests in Safari',
    'firefox': '  Runs tests in Firefox',
    'edge': '  Runs tests in Edge',
    'integration': 'Run only integration tests.',
    'compiled': 'Changes integration tests to use production JS ' +
        'binaries for execution',
    'oldchrome': 'Runs test with an old chrome. Saucelabs only.',
    'grep': 'Runs tests that match the pattern',
    'files': 'Runs tests for specific files',
    'randomize': 'Runs entire test suite in random order',
    'testlist': 'Runs tests specified in JSON by supplied file',
    'glob': 'Explicitly expands test paths using glob before passing ' +
        'to Karma',
  }
});

function shuffleArray(array) {
    for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
}
<commit_msg>Support running randomized test runs for just a4a tests (#10096)<commit_after>/**
 * Copyright 2015 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.
 */
'use strict';

var argv = require('minimist')(process.argv.slice(2));
var gulp = require('gulp-help')(require('gulp'));
var glob = require('glob');
var Karma = require('karma').Server;
var config = require('../config');
var read = require('file-reader');
var fs = require('fs');
var path = require('path');
var util = require('gulp-util');
var webserver = require('gulp-webserver');
var app = require('../test-server').app;
var karmaDefault = require('./karma.conf');

/**
 * Read in and process the configuration settings for karma
 * @return {!Object} Karma configuration
 */
function getConfig() {
  if (argv.safari) {
    return Object.assign({}, karmaDefault, {browsers: ['Safari']});
  }
  if (argv.firefox) {
    return Object.assign({}, karmaDefault, {browsers: ['Firefox']});
  }
  if (argv.edge) {
    return Object.assign({}, karmaDefault, {browsers: ['Edge']});
  }

  if (argv.saucelabs) {
    if (!process.env.SAUCE_USERNAME) {
      throw new Error('Missing SAUCE_USERNAME Env variable');
    }
    if (!process.env.SAUCE_ACCESS_KEY) {
      throw new Error('Missing SAUCE_ACCESS_KEY Env variable');
    }
    return Object.assign({}, karmaDefault, {
      reporters: ['dots', 'saucelabs'],
      browsers: argv.oldchrome
          ? ['SL_Chrome_45']
          : [
            'SL_Chrome_android',
            'SL_Chrome_latest',
            'SL_Chrome_45',
            'SL_Firefox_latest',
            //'SL_Safari_8' // Disabled due to flakiness and low market share
            'SL_Safari_9',
            'SL_Edge_latest',
            //'SL_iOS_8_4', // Disabled due to flakiness and low market share
            'SL_iOS_9_1',
            'SL_iOS_10_0',
            //'SL_IE_11',
          ],
    });
  }
  return karmaDefault;
}

function getAdTypes() {
  const namingExceptions = {
    // We recommend 3P ad networks use the same string for filename and type.
    // Write exceptions here in alphabetic order.
    // filename: [type1, type2, ... ]
    adblade: ['adblade', 'industrybrains'],
    mantis: ['mantis-display', 'mantis-recommend'],
    weborama: ['weborama-display'],
  };

  // Start with Google ad types
  const adTypes = ['adsense', 'doubleclick'];

  // Add all other ad types
  const files = fs.readdirSync('./ads/');
  for (var i = 0; i < files.length; i++) {
    if (path.extname(files[i]) == '.js'
        && files[i][0] != '_' && files[i] != 'ads.extern.js') {
      const adType = path.basename(files[i], '.js');
      const expanded = namingExceptions[adType];
      if (expanded) {
        for (var j = 0; j < expanded.length; j++) {
          adTypes.push(expanded[j]);
        }
      } else {
        adTypes.push(adType);
      }
    }
  }
  return adTypes;
}

/**
 * Run tests.
 */
gulp.task('test', 'Runs tests', argv.nobuild ? [] : ['build'], function(done) {
  if (!argv.integration && process.env.AMPSAUCE_REPO) {
    console./*OK*/info('Deactivated for ampsauce repo')
  }

  var c = getConfig();

  if (argv.watch || argv.w) {
    c.singleRun = false;
  }

  if (argv.verbose || argv.v) {
    c.client.captureConsole = true;
  }

  if (argv.files) {
    c.files = [].concat(config.commonTestPaths, argv.files);
  } else if (argv.integration) {
    c.files = config.integrationTestPaths;
  } else if (argv.randomize || argv.glob || argv.a4a) {
    /** Randomize the order of the test running */
    var testPaths;
    if (argv.a4a) {
      testPaths = [
        'extensions/amp-a4a/**/test/**/*.js',
        'extensions/amp-ad-network-*/**/test/**/*.js',
        'ads/google/a4a/test/*.js'
      ];
    } else {
      testPaths = [
        'test/**/*.js',
        'ads/**/test/test-*.js',
        'extensions/**/test/**/*.js',
      ];
    }

    var testFiles = [];

    for (var index in testPaths) {
      testFiles = testFiles.concat(glob.sync(testPaths[index]));
    }

    if (argv.randomize) {
      testFiles = shuffleArray(testFiles);
    }
    // we need to replace the test init with something that won't match
    // any file. _init_tests gets added twice due to the regex matching.
    testFiles[testFiles.indexOf('test/_init_tests.js')] = '_WONTMATCH.qqq';
    c.files = config.commonTestPaths.concat(testFiles);

    util.log(util.colors.blue(JSON.stringify(c.files)));
    util.log(util.colors.yellow("Save the above files in a .json file to reuse"));

  } else if (argv.testlist) {
    var file = read.file(argv.testlist);
    util.log(file);
    c.files = file;

  } else {
    c.files = config.testPaths;
  }

  // c.client is available in test browser via window.parent.karma.config
  c.client.amp = {
    useCompiledJs: !!argv.compiled,
    saucelabs: !!argv.saucelabs,
    adTypes: getAdTypes(),
  };

  if (argv.compiled) {
    process.env.SERVE_MODE = 'compiled';
  } else {
    process.env.SERVE_MODE = 'default';
  }

  if (argv.grep) {
    c.client.mocha = {
      'grep': argv.grep,
    };
  }

  // Run fake-server to test XHR responses.
  var server = gulp.src(process.cwd())
      .pipe(webserver({
        port: 31862,
        host: 'localhost',
        directoryListing: true,
        middleware: [app],
      }));
  util.log(util.colors.yellow(
      'Started test responses server on localhost:31862'));

  new Karma(c, function(exitCode) {
    util.log(util.colors.yellow(
        'Shutting down test responses server on localhost:31862'));
    server.emit('kill');
    if (exitCode) {
      var error = new Error(
          util.colors.red('Karma test failed (error code: ' + exitCode + ')'));
      done(error);
    } else {
      done();
    }
  }).start();
}, {
  options: {
    'verbose': '  With logging enabled',
    'watch': '  Watches for changes in files, runs corresponding test(s)',
    'saucelabs': '  Runs test on saucelabs (requires setup)',
    'safari': '  Runs tests in Safari',
    'firefox': '  Runs tests in Firefox',
    'edge': '  Runs tests in Edge',
    'integration': 'Run only integration tests.',
    'compiled': 'Changes integration tests to use production JS ' +
        'binaries for execution',
    'oldchrome': 'Runs test with an old chrome. Saucelabs only.',
    'grep': 'Runs tests that match the pattern',
    'files': 'Runs tests for specific files',
    'randomize': 'Runs entire test suite in random order',
    'testlist': 'Runs tests specified in JSON by supplied file',
    'glob': 'Explicitly expands test paths using glob before passing ' +
        'to Karma',
  }
});

function shuffleArray(array) {
    for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
}
<|endoftext|>


<commit_before>module.exports = function(grunt, config, parameters, done) {

	function endForError(e) {
		process.stderr.write(e.message || e);
		done(false);
	}

	try {
		var rimraf = require('rimraf'),
			fs = require('fs'),
			download = require('download'),
			path = "./release";

		rimraf.sync(path);
		fs.mkdir(path);

		// Download archive from git
		process.stdout.write("Downloading Archive...\n");
		var stream = download('https://github.com/concrete5/concrete5/archive/master.zip', path, {
			extract: true
		});
		stream.on('close', function() {
			done();
		});

	}
	catch(e) {
		endForError(e);
		return;
	}
};<commit_msg>Use shelljs instead of rimraf<commit_after>module.exports = function(grunt, config, parameters, done) {

	function endForError(e) {
		process.stderr.write(e.message || e);
		done(false);
	}

	try {
		var shell = require('shelljs'),
			fs = require('fs'),
			download = require('download'),
			path = "./release";

		shell.rm('-rf', path);
		fs.mkdir(path);

		// Download archive from git
		process.stdout.write("Downloading Archive...\n");
		var stream = download('https://github.com/concrete5/concrete5/archive/master.zip', path, {
			extract: true
		});
		stream.on('close', function() {
			done();
		});

	}
	catch(e) {
		endForError(e);
		return;
	}
};<|endoftext|>


<commit_before>var isEqual = require('lodash.isequal');
var normalize = require('geojson-normalize');
var hat = require('hat');
var featuresAt = require('./lib/features_at');
var stringSetsAreEqual = require('./lib/string_sets_are_equal');
var geojsonhint = require('geojsonhint');
var Constants = require('./constants');

var featureTypes = {
  'Polygon': require('./feature_types/polygon'),
  'LineString': require('./feature_types/line_string'),
  'Point': require('./feature_types/point'),
  'MultiPolygon': require('./feature_types/multi_feature'),
  'MultiLineString': require('./feature_types/multi_feature'),
  'MultiPoint': require('./feature_types/multi_feature')
};

module.exports = function(ctx) {

  return {
    getFeatureIdsAt: function(point) {
      var features = featuresAt({point}, null, ctx);
      return features.map(feature => feature.properties.id);
    },
    getSelectedIds: function () {
      return ctx.store.getSelectedIds();
    },
    setSelected: function(idsToSelect) {
      if (stringSetsAreEqual(idsToSelect, ctx.store.getSelectedIds())) return;
      if (this.getMode() !== Constants.modes.SIMPLE_SELECT) {
        ctx.events.changeMode(Constants.modes.SIMPLE_SELECT, { featureIds: idsToSelect }, { silent: true });
      } else {
        ctx.store.setSelected(idsToSelect, { silent: true });
        ctx.store.render();
      }
    },
    set: function(featureCollection) {
      if (featureCollection.type === undefined || featureCollection.type !== 'FeatureCollection' || !Array.isArray(featureCollection.features)) {
        throw new Error('Invalid FeatureCollection');
      }
      var toDelete = ctx.store.getAllIds().slice(0);
      var newIds = this.add(featureCollection);

      var newIdsForFasterLookUp = {};
      for (var i = 0; i < newIds.length; i++) {
        newIdsForFasterLookUp[newIds[i]] = 0;
      }

      toDelete = toDelete.filter(id => {
        return newIdsForFasterLookUp[id] === undefined;
      });
      this.delete(toDelete);

      return newIds;
    },
    add: function (geojson) {
      var featureCollection = normalize(geojson);
      var errors = geojsonhint.hint(featureCollection);
      if (errors.length) {
        throw new Error(errors[0].message);
      }
      featureCollection = JSON.parse(JSON.stringify(featureCollection));

      var ids = featureCollection.features.map(feature => {
        feature.id = feature.id || hat();

        if (ctx.store.get(feature.id) === undefined) {
          var model = featureTypes[feature.geometry.type];
          let internalFeature = new model(ctx, feature);
          ctx.store.add(internalFeature);
        }
        else {
          let internalFeature = ctx.store.get(feature.id);
          internalFeature.properties = feature.properties;
          if (!isEqual(internalFeature.getCoordinates(), feature.geometry.coordinates)) {
            internalFeature.incomingCoords(feature.geometry.coordinates);
          }
        }
        return feature.id;
      });

      ctx.store.render();
      return ids;
    },
    get: function (id) {
      var feature = ctx.store.get(id);
      if (feature) {
        return feature.toGeoJSON();
      }
    },
    getAll: function() {
      return {
        type: 'FeatureCollection',
        features: ctx.store.getAll().map(feature => feature.toGeoJSON())
      };
    },
    delete: function(id) {
      ctx.store.delete([id], { silent: true });
      ctx.store.render();
    },
    deleteAll: function() {
      ctx.store.delete(ctx.store.getAllIds(), { silent: true });
      ctx.store.render();
    },
    changeMode: function(mode, modeOptions) {
      ctx.events.changeMode(mode, modeOptions, { silent: true });
    },
    getMode: function() {
      return ctx.events.getMode();
    },
    trash: function() {
      ctx.events.trash({ silent: true });
    }
  };
};
<commit_msg>Update Draw.delete so it handles single ids or an array<commit_after>var isEqual = require('lodash.isequal');
var normalize = require('geojson-normalize');
var hat = require('hat');
var featuresAt = require('./lib/features_at');
var stringSetsAreEqual = require('./lib/string_sets_are_equal');
var geojsonhint = require('geojsonhint');
var Constants = require('./constants');

var featureTypes = {
  'Polygon': require('./feature_types/polygon'),
  'LineString': require('./feature_types/line_string'),
  'Point': require('./feature_types/point'),
  'MultiPolygon': require('./feature_types/multi_feature'),
  'MultiLineString': require('./feature_types/multi_feature'),
  'MultiPoint': require('./feature_types/multi_feature')
};

module.exports = function(ctx) {

  return {
    getFeatureIdsAt: function(point) {
      var features = featuresAt({point}, null, ctx);
      return features.map(feature => feature.properties.id);
    },
    getSelectedIds: function () {
      return ctx.store.getSelectedIds();
    },
    setSelected: function(idsToSelect) {
      if (stringSetsAreEqual(idsToSelect, ctx.store.getSelectedIds())) return;
      if (this.getMode() !== Constants.modes.SIMPLE_SELECT) {
        ctx.events.changeMode(Constants.modes.SIMPLE_SELECT, { featureIds: idsToSelect }, { silent: true });
      } else {
        ctx.store.setSelected(idsToSelect, { silent: true });
        ctx.store.render();
      }
    },
    set: function(featureCollection) {
      if (featureCollection.type === undefined || featureCollection.type !== 'FeatureCollection' || !Array.isArray(featureCollection.features)) {
        throw new Error('Invalid FeatureCollection');
      }
      var toDelete = ctx.store.getAllIds().slice(0);
      var newIds = this.add(featureCollection);

      var newIdsForFasterLookUp = {};
      for (var i = 0; i < newIds.length; i++) {
        newIdsForFasterLookUp[newIds[i]] = 0;
      }

      toDelete = toDelete.filter(id => {
        return newIdsForFasterLookUp[id] === undefined;
      });
      this.delete(toDelete);

      return newIds;
    },
    add: function (geojson) {
      var featureCollection = normalize(geojson);
      var errors = geojsonhint.hint(featureCollection);
      if (errors.length) {
        throw new Error(errors[0].message);
      }
      featureCollection = JSON.parse(JSON.stringify(featureCollection));

      var ids = featureCollection.features.map(feature => {
        feature.id = feature.id || hat();

        if (ctx.store.get(feature.id) === undefined) {
          var model = featureTypes[feature.geometry.type];
          let internalFeature = new model(ctx, feature);
          ctx.store.add(internalFeature);
        }
        else {
          let internalFeature = ctx.store.get(feature.id);
          internalFeature.properties = feature.properties;
          if (!isEqual(internalFeature.getCoordinates(), feature.geometry.coordinates)) {
            internalFeature.incomingCoords(feature.geometry.coordinates);
          }
        }
        return feature.id;
      });

      ctx.store.render();
      return ids;
    },
    get: function (id) {
      var feature = ctx.store.get(id);
      if (feature) {
        return feature.toGeoJSON();
      }
    },
    getAll: function() {
      return {
        type: 'FeatureCollection',
        features: ctx.store.getAll().map(feature => feature.toGeoJSON())
      };
    },
    delete: function(featureIds) {
      ctx.store.delete(featureIds, { silent: true });
      ctx.store.render();
    },
    deleteAll: function() {
      ctx.store.delete(ctx.store.getAllIds(), { silent: true });
      ctx.store.render();
    },
    changeMode: function(mode, modeOptions) {
      ctx.events.changeMode(mode, modeOptions, { silent: true });
    },
    getMode: function() {
      return ctx.events.getMode();
    },
    trash: function() {
      ctx.events.trash({ silent: true });
    }
  };
};
<|endoftext|>


<commit_before>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

(function pdfApiWrapper() {
  function PdfPageWrapper(page) {
    this.page = page;
  }
  PdfPageWrapper.prototype = {
    get width() {
      return this.page.width;
    },
    get height() {
      return this.page.height;
    },
    get stats() {
      return this.page.stats;
    },
    get ref() {
      return this.page.ref;
    },
    get view() {
      return this.page.view;
    },
    rotatePoint: function(x, y) {
      return this.page.rotatePoint(x, y);
    },
    getAnnotations: function() {
      var promise = new PDFJS.Promise();
      var annotations = this.page.getAnnotations();
      promise.resolve(annotations);
      return promise;
    },
    render: function(renderContext) {
      var promise = new PDFJS.Promise();
      this.page.startRendering(renderContext.canvasContext,
        function complete(error) {
          if (error)
            promise.reject(error);
          else
            promise.resolve();
        },
        renderContext.textLayer);
      return promise;
    },
    getTextContent: function() {
      var promise = new PDFJS.Promise();
      var textContent = 'page text'; // not implemented
      promise.resolve(textContent);
      return promise;
    },
    getOperationList: function() {
      var promise = new PDFJS.Promise();
      var operationList = { // not implemented
        dependencyFontsID: null,
        operatorList: null
      };
      promise.resolve(operationList);
      return promise;
    }
  };

  function PdfDocumentWrapper(pdf) {
    this.pdf = pdf;
  }
  PdfDocumentWrapper.prototype = {
    get numPages() {
      return this.pdf.numPages;
    },
    get fingerprint() {
      return this.pdf.fingerPrint;
    },
    getPage: function(number) {
      var promise = new PDFJS.Promise();
      var page = this.pdf.getPage(number);
      promise.resolve(new PdfPageWrapper(page));
      return promise;
    },
    getDestinations: function() {
      var promise = new PDFJS.Promise();
      var destinations = this.pdf.catalog.destinations;
      promise.resolve(destinations);
      return promise;
    },
    getOutline: function() {
      var promise = new PDFJS.Promise();
      var outline = this.pdf.catalog.documentOutline;
      promise.resolve(outline);
      return promise;
    },
    getMetadata: function() {
      var promise = new PDFJS.Promise();
      var info = this.pdf.info;
      var metadata = this.pdf.catalog.metadata;
      promise.resolve(info, metadata ? new PDFJS.Metadata(metadata) : null);
      return promise;
    }
  };

  PDFJS.getDocument = function getDocument(source) {
    var promise = new PDFJS.Promise();
    if (typeof source === 'string') {
      // fetch url
      PDFJS.getPdf(
        {
          url: source,
          progress: function getPdfProgress(evt) {
            if (evt.lengthComputable)
              promise.progress({
                loaded: evt.loaded,
                total: evt.total
              });
          },
          error: function getPdfError(e) {
            promise.reject('Unexpected server response of ' +
              e.target.status + '.');
          }
        },
        function getPdfLoad(data) {
          var pdf = null;
          try {
            pdf = new PDFJS.PDFDoc(data);
          } catch (e) {
            promise.reject('An error occurred while reading the PDF.', e);
          }
          if (pdf)
            promise.resolve(new PdfDocumentWrapper(pdf));
        });
    } else {
      // assuming the source is array, instantiating directly from it
      var pdf = null;
      try {
        pdf = new PDFJS.PDFDoc(source);
      } catch (e) {
        promise.reject('An error occurred while reading the PDF.', e);
      }
      if (pdf)
        promise.resolve(new PdfDocumentWrapper(pdf));
    }
    return promise;
  };
})();
<commit_msg>Fix fingerprint name.<commit_after>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

(function pdfApiWrapper() {
  function PdfPageWrapper(page) {
    this.page = page;
  }
  PdfPageWrapper.prototype = {
    get width() {
      return this.page.width;
    },
    get height() {
      return this.page.height;
    },
    get stats() {
      return this.page.stats;
    },
    get ref() {
      return this.page.ref;
    },
    get view() {
      return this.page.view;
    },
    rotatePoint: function(x, y) {
      return this.page.rotatePoint(x, y);
    },
    getAnnotations: function() {
      var promise = new PDFJS.Promise();
      var annotations = this.page.getAnnotations();
      promise.resolve(annotations);
      return promise;
    },
    render: function(renderContext) {
      var promise = new PDFJS.Promise();
      this.page.startRendering(renderContext.canvasContext,
        function complete(error) {
          if (error)
            promise.reject(error);
          else
            promise.resolve();
        },
        renderContext.textLayer);
      return promise;
    },
    getTextContent: function() {
      var promise = new PDFJS.Promise();
      var textContent = 'page text'; // not implemented
      promise.resolve(textContent);
      return promise;
    },
    getOperationList: function() {
      var promise = new PDFJS.Promise();
      var operationList = { // not implemented
        dependencyFontsID: null,
        operatorList: null
      };
      promise.resolve(operationList);
      return promise;
    }
  };

  function PdfDocumentWrapper(pdf) {
    this.pdf = pdf;
  }
  PdfDocumentWrapper.prototype = {
    get numPages() {
      return this.pdf.numPages;
    },
    get fingerprint() {
      return this.pdf.fingerprint;
    },
    getPage: function(number) {
      var promise = new PDFJS.Promise();
      var page = this.pdf.getPage(number);
      promise.resolve(new PdfPageWrapper(page));
      return promise;
    },
    getDestinations: function() {
      var promise = new PDFJS.Promise();
      var destinations = this.pdf.catalog.destinations;
      promise.resolve(destinations);
      return promise;
    },
    getOutline: function() {
      var promise = new PDFJS.Promise();
      var outline = this.pdf.catalog.documentOutline;
      promise.resolve(outline);
      return promise;
    },
    getMetadata: function() {
      var promise = new PDFJS.Promise();
      var info = this.pdf.info;
      var metadata = this.pdf.catalog.metadata;
      promise.resolve(info, metadata ? new PDFJS.Metadata(metadata) : null);
      return promise;
    }
  };

  PDFJS.getDocument = function getDocument(source) {
    var promise = new PDFJS.Promise();
    if (typeof source === 'string') {
      // fetch url
      PDFJS.getPdf(
        {
          url: source,
          progress: function getPdfProgress(evt) {
            if (evt.lengthComputable)
              promise.progress({
                loaded: evt.loaded,
                total: evt.total
              });
          },
          error: function getPdfError(e) {
            promise.reject('Unexpected server response of ' +
              e.target.status + '.');
          }
        },
        function getPdfLoad(data) {
          var pdf = null;
          try {
            pdf = new PDFJS.PDFDoc(data);
          } catch (e) {
            promise.reject('An error occurred while reading the PDF.', e);
          }
          if (pdf)
            promise.resolve(new PdfDocumentWrapper(pdf));
        });
    } else {
      // assuming the source is array, instantiating directly from it
      var pdf = null;
      try {
        pdf = new PDFJS.PDFDoc(source);
      } catch (e) {
        promise.reject('An error occurred while reading the PDF.', e);
      }
      if (pdf)
        promise.resolve(new PdfDocumentWrapper(pdf));
    }
    return promise;
  };
})();
<|endoftext|>


<commit_before>'use strict';

const tape = require('tape');
const run = require('./run.util.js');
const existsSync = require('fs').existsSync || require('path').existsSync;
const fs = require('fs');
const rm = require('rimraf');
const path = require('path');
const napi = require('../lib/util/napi.js');
const versioning = require('../lib/util/versioning.js');
const tar = require('tar');

// this is a derived from build.test.js and should be kept in sync with it
// as much as possible.
const { mockS3Http } = require('../lib/node-pre-gyp.js');
const proxy = require('./proxy.util');

const proxyPort = 8124;
const proxyServer = `http://localhost:${proxyPort}`;

let initial_s3_host;
let initial_mock_s3;

// https://stackoverflow.com/questions/38599457/how-to-write-a-custom-assertion-for-testing-node-or-javascript-with-tape-or-che
tape.Test.prototype.stringContains = function(actual, contents, message) {
  this._assert(actual.indexOf(contents) > -1, {
    message: message || 'should contain ' + contents,
    operator: 'stringContains',
    actual: actual,
    expected: contents
  });
};

//
// skip tests that require a real S3 bucket when in a CI environment
// and the AWS access key is not available.
//
const isCI = process.env.CI && process.env.CI.toLowerCase() === 'true'
  && !process.env.AWS_ACCESS_KEY_ID;

function ciSkip(...args) {
  if (isCI) {
    tape.skip(...args);
  } else {
    tape(...args);
  }
}
ciSkip.skip = function(...args) {
  tape.skip(...args);
};

const test = tape;

test('setup proxy server', (t) => {
  delete process.env.http_proxy;
  delete process.env.https_proxy;
  delete process.env.HTTPS_PROXY;
  delete process.env.all_proxy;
  delete process.env.ALL_PROXY;
  delete process.env.no_proxy;
  delete process.env.NO_PROXY;
  process.env.NOCK_OFF = true;

  initial_mock_s3 = process.env.node_pre_gyp_mock_s3;
  delete process.env.node_pre_gyp_mock_s3;
  mockS3Http('off');

  proxy.startServer({ port: proxyPort });
  process.env.https_proxy = process.env.http_proxy = proxyServer;
  initial_s3_host = process.env.node_pre_gyp_s3_host;
  console.log('proxy.test.js => s3_host:', initial_s3_host);
  process.env.node_pre_gyp_s3_host = 'staging';

  process.env.NOCK_OFF = true;
  t.end();
});

// The list of different sample apps that we use to test. It's only one app for now but if other
// tests are needed they can be added easily.
const apps = [
  {
    'name': 'app1',
    'args': '',
    'files': {
      'base': ['binding/app1.node']
    }
  }
];

// Because the below tests only ensure that flags can be correctly passed to node-gyp is it not
// likely they will behave differently for different apps. So we save time by avoiding running these for each app.
const appOne = apps[0];

// make sure node-gyp options are passed by passing invalid values
// and ensuring the expected errors are returned from node-gyp
test(appOne.name + ' passes --nodedir down to node-gyp via node-pre-gyp ' + appOne.args, (t) => {
  run('node-pre-gyp', 'configure', '--nodedir=invalid-value', appOne, {}, (err, stdout, stderr) => {
    t.ok(err, 'Expected command to fail');
    t.stringContains(stderr, 'common.gypi not found');
    t.end();
  });
});

// NOTE: currently fails with npm v3.x on windows (hence downgrade in appveyor.yml)
test(appOne.name + ' passes --nodedir down to node-gyp via npm' + appOne.args, (t) => {
  run('npm', 'install', '--build-from-source --nodedir=invalid-value', appOne, {}, (err, stdout, stderr) => {
    t.ok(err, 'Expected command to fail');
    t.stringContains(stderr, 'common.gypi not found');
    t.end();
  });
});

// note: --ensure=false tells node-gyp to attempt to re-download the node headers
// even if they already exist on disk at ~/.node-gyp/{version}
test(appOne.name + ' passes --dist-url down to node-gyp via node-pre-gyp ' + appOne.args, (t) => {
  run('node-pre-gyp', 'configure', '--ensure=false --dist-url=invalid-value', appOne, {}, (err) => {
    t.ok(err, 'Expected command to fail');
    t.end();
  });
});

test(appOne.name + ' passes --dist-url down to node-gyp via npm ' + appOne.args, (t) => {
  run('npm', 'install', '--build-from-source --ensure=false --dist-url=invalid-value', appOne, {}, (err) => {
    t.ok(err, 'Expected command to fail');
    t.end();
  });
});

// Tests run for all apps

apps.forEach((app) => {

  if (app.name === 'app7' && !napi.get_napi_version()) return;

  // clear out entire binding directory
  // to ensure no stale builds. This is needed
  // because "node-pre-gyp clean" only removes
  // the current target and not alternative builds
  test('cleanup of app', (t) => {
    const binding_directory = path.join(__dirname, app.name, 'lib/binding');
    if (fs.existsSync(binding_directory)) {
      rm.sync(binding_directory);
    }
    t.end();
  });

  test(app.name + ' configures ' + app.args, (t) => {
    run('node-pre-gyp', 'configure', '--loglevel=error', app, {}, (err) => {
      t.ifError(err);
      t.end();
    });
  });

  test(app.name + ' configures with unparsed options ' + app.args, (t) => {
    run('node-pre-gyp', 'configure', '--loglevel=info -- -Dfoo=bar', app, {}, (err, stdout, stderr) => {
      t.ifError(err);
      t.equal(stdout, '');
      t.ok(stderr.search(/(gyp info spawn args).*(-Dfoo=bar)/) > -1);
      t.end();
    });
  });

  if (process.platform !== 'win32') {
    test(app.name + ' builds with unparsed options ' + app.args, (t) => {
      // clean and build as separate steps here because configure only works with -Dfoo=bar
      // and build only works with FOO=bar
      run('node-pre-gyp', 'clean', '', app, {}, (err) => {
        t.ifError(err);
        const propertyPrefix = (process.platform === 'win32') ? '/p:' : '';
        run('node-pre-gyp', 'build', '--loglevel=info -- ' + propertyPrefix + 'FOO=bar', app, {}, (err2, stdout, stderr) => {
          t.ifError(err2);
          t.ok(stderr.search(/(gyp info spawn args).*(FOO=bar)/) > -1);
          if (process.platform !== 'win32') {
            if (app.args.indexOf('--debug') > -1) {
              t.stringContains(stdout, 'Debug/' + app.name + '.node');
            } else {
              t.stringContains(stdout, 'Release/' + app.name + '.node');
            }
          }
          t.end();
        });
      });
    });
  } else {
    // Skipping since this support broke upstream in node-gyp: https://github.com/nodejs/node-gyp/pull/1616
    test.skip(app.name + ' builds with unparsed options ' + app.args, () => {});
  }

  test(app.name + ' builds ' + app.args, (t) => {
    run('node-pre-gyp', 'rebuild', '--fallback-to-build', app, {}, (err, stdout, stderr) => {
      t.ifError(err);
      if (err) {
        console.log(stdout);
        console.log(stderr);
      }
      if (process.platform !== 'win32') {
        if (app.args.indexOf('--debug') > -1) {
          t.stringContains(stdout, 'Debug/' + app.name + '.node');
        } else {
          t.stringContains(stdout, 'Release/' + app.name + '.node');
        }
      }
      t.end();
    });
  });

  test(app.name + ' is found ' + app.args, (t) => {
    run('node-pre-gyp', 'reveal', 'module_path --silent', app, {}, (err, stdout) => {
      t.ifError(err);
      let module_path = stdout.trim();
      if (module_path.indexOf('\n') !== -1) { // take just the first line
        module_path = module_path.substr(0, module_path.indexOf('\n'));
      }
      t.stringContains(module_path, app.name);
      t.ok(existsSync(module_path), 'is valid path to existing binary: ' + module_path);
      const module_binary = path.join(module_path, app.name + '.node');
      t.ok(existsSync(module_binary));
      t.end();
    });
  });

  test(app.name + ' passes tests ' + app.args, (t) => {
    run('npm', 'test', '', app, { cwd: path.join(__dirname, app.name) }, (err, stdout) => {
      t.ifError(err);
      // we expect app2 to console.log on success
      if (app.name === 'app2') {
        if (app.args.indexOf('--debug') > -1) {
          t.stringContains(stdout, 'Loaded Debug build');
        } else {
          t.stringContains(stdout, 'Loaded Release build');
        }
      } else {
        // we expect some npm output
        t.notEqual(stdout, '');
      }
      t.end();
    });
  });

  test(app.name + ' packages ' + app.args, (t) => {
    run('node-pre-gyp', 'package', '', app, {}, (err) => {
      t.ifError(err);
      // Make sure a tarball was created
      run('node-pre-gyp', 'reveal', 'staged_tarball --silent', app, {}, (err2, stdout) => {
        t.ifError(err2);
        let staged_tarball = stdout.trim();
        if (staged_tarball.indexOf('\n') !== -1) { // take just the first line
          staged_tarball = staged_tarball.substr(0, staged_tarball.indexOf('\n'));
        }
        const tarball_path = path.join(__dirname, app.name, staged_tarball);
        t.ok(existsSync(tarball_path), 'staged tarball is a valid file');
        if (!app.files) {
          return t.end();
        }
        // Make sure the package contains what we expect
        const entries = [];
        tar.t({
          file: tarball_path,
          sync: true,
          onentry: function(entry) {
            entries.push(entry.path);
          }
        });
        let files = app.files.base;
        const nodever = versioning.get_runtime_abi('node');
        // Look for a more specific choice
        if (Object.hasOwnProperty.call(app.files, process.platform)) {
          const appPlatList = app.files[process.platform];
          if (Object.hasOwnProperty.call(appPlatList, nodever)) {
            files = appPlatList[nodever];
          } else if (Object.hasOwnProperty.call(appPlatList, 'base')) {
            files = appPlatList.base;
          } else {
            files = appPlatList;
          }
        }
        // windows is too variable to keep this test up to date across node versions
        if (process.platform !== 'win32') {
          t.same(entries.sort(), files.sort(), 'staged tarball contains the right files');
        }
        t.end();
      });
    });
  });

  test(app.name + ' package is valid ' + app.args, (t) => {
    run('node-pre-gyp', 'testpackage', '', app, {}, (err) => {
      t.ifError(err);
      t.end();
    });
  });

  ciSkip(app.name + ' publishes ' + app.args, (t) => {
    run('node-pre-gyp', 'unpublish publish', '', app, {}, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  ciSkip(app.name + ' info shows it ' + app.args, (t) => {
    run('node-pre-gyp', 'reveal', 'package_name', app, {}, (err, stdout) => {
      t.ifError(err);
      let package_name = stdout.trim();
      if (package_name.indexOf('\n') !== -1) { // take just the first line
        package_name = package_name.substr(0, package_name.indexOf('\n'));
      }
      run('node-pre-gyp', 'info', '', app, {}, (err2, stdout2) => {
        t.ifError(err2);
        t.stringContains(stdout2, package_name);
        t.end();
      });
    });
  });

  ciSkip(app.name + ' can be uninstalled ' + app.args, (t) => {
    run('node-pre-gyp', 'clean', '', app, {}, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  ciSkip(app.name + ' can be installed via remote ' + app.args, (t) => {
    const opts = {
      cwd: path.join(__dirname, app.name),
      npg_debug: false
    };
    run('npm', 'install', '--fallback-to-build=false', app, opts, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  ciSkip(app.name + ' can be reinstalled via remote ' + app.args, (t) => {
    const opts = {
      cwd: path.join(__dirname, app.name),
      npg_debug: false
    };
    run('npm', 'install', '--update-binary --fallback-to-build=false', app, opts, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  ciSkip(app.name + ' via remote passes tests ' + app.args, (t) => {
    const opts = {
      cwd: path.join(__dirname, app.name),
      npg_debug: false
    };
    run('npm', 'install', '', app, opts, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  ciSkip(app.name + ' unpublishes ' + app.args, (t) => {
    run('node-pre-gyp', 'unpublish', '', app, {}, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  // note: the above test will result in a non-runnable binary, so the below test must succeed otherwise all following tests will fail

  test(app.name + ' builds with custom --target ' + app.args, (t) => {
    run('node-pre-gyp', 'rebuild', '--loglevel=error --fallback-to-build --target=' + process.versions.node, app, {}, (err) => {
      t.ifError(err);
      t.end();
    });
  });
});

// this is really just onFinish() but local to the tests in this file
test(`cleanup after ${__filename}`, (t) => {
  mockS3Http('on');
  proxy.stopServer();
  delete process.env.NOCK_OFF;
  delete process.env.http_proxy;
  delete process.env.https_proxy;
  process.env.node_pre_gyp_s3_host = initial_s3_host;
  process.env.node_pre_gyp_mock_s3 = initial_mock_s3;
  t.end();
});
<commit_msg>get rid of extra var<commit_after>'use strict';

const test = require('tape');
const run = require('./run.util.js');
const existsSync = require('fs').existsSync || require('path').existsSync;
const fs = require('fs');
const rm = require('rimraf');
const path = require('path');
const napi = require('../lib/util/napi.js');
const versioning = require('../lib/util/versioning.js');
const tar = require('tar');

// this is a derived from build.test.js and should be kept in sync with it
// as much as possible.
const { mockS3Http } = require('../lib/node-pre-gyp.js');
const proxy = require('./proxy.util');

const proxyPort = 8124;
const proxyServer = `http://localhost:${proxyPort}`;

let initial_s3_host;
let initial_mock_s3;

// https://stackoverflow.com/questions/38599457/how-to-write-a-custom-assertion-for-testing-node-or-javascript-with-tape-or-che
test.Test.prototype.stringContains = function(actual, contents, message) {
  this._assert(actual.indexOf(contents) > -1, {
    message: message || 'should contain ' + contents,
    operator: 'stringContains',
    actual: actual,
    expected: contents
  });
};

//
// skip tests that require a real S3 bucket when in a CI environment
// and the AWS access key is not available.
//
const isCI = process.env.CI && process.env.CI.toLowerCase() === 'true'
  && !process.env.AWS_ACCESS_KEY_ID;

function ciSkip(...args) {
  if (isCI) {
    test.skip(...args);
  } else {
    test(...args);
  }
}
ciSkip.skip = function(...args) {
  test.skip(...args);
};

test('setup proxy server', (t) => {
  delete process.env.http_proxy;
  delete process.env.https_proxy;
  delete process.env.HTTPS_PROXY;
  delete process.env.all_proxy;
  delete process.env.ALL_PROXY;
  delete process.env.no_proxy;
  delete process.env.NO_PROXY;
  process.env.NOCK_OFF = true;

  initial_mock_s3 = process.env.node_pre_gyp_mock_s3;
  delete process.env.node_pre_gyp_mock_s3;
  mockS3Http('off');

  proxy.startServer({ port: proxyPort });
  process.env.https_proxy = process.env.http_proxy = proxyServer;
  initial_s3_host = process.env.node_pre_gyp_s3_host;
  console.log('proxy.test.js => s3_host:', initial_s3_host);
  process.env.node_pre_gyp_s3_host = 'staging';

  process.env.NOCK_OFF = true;
  t.end();
});

// The list of different sample apps that we use to test. It's only one app for now but if other
// tests are needed they can be added easily.
const apps = [
  {
    'name': 'app1',
    'args': '',
    'files': {
      'base': ['binding/app1.node']
    }
  }
];

// Because the below tests only ensure that flags can be correctly passed to node-gyp is it not
// likely they will behave differently for different apps. So we save time by avoiding running these for each app.
const appOne = apps[0];

// make sure node-gyp options are passed by passing invalid values
// and ensuring the expected errors are returned from node-gyp
test(appOne.name + ' passes --nodedir down to node-gyp via node-pre-gyp ' + appOne.args, (t) => {
  run('node-pre-gyp', 'configure', '--nodedir=invalid-value', appOne, {}, (err, stdout, stderr) => {
    t.ok(err, 'Expected command to fail');
    t.stringContains(stderr, 'common.gypi not found');
    t.end();
  });
});

// NOTE: currently fails with npm v3.x on windows (hence downgrade in appveyor.yml)
test(appOne.name + ' passes --nodedir down to node-gyp via npm' + appOne.args, (t) => {
  run('npm', 'install', '--build-from-source --nodedir=invalid-value', appOne, {}, (err, stdout, stderr) => {
    t.ok(err, 'Expected command to fail');
    t.stringContains(stderr, 'common.gypi not found');
    t.end();
  });
});

// note: --ensure=false tells node-gyp to attempt to re-download the node headers
// even if they already exist on disk at ~/.node-gyp/{version}
test(appOne.name + ' passes --dist-url down to node-gyp via node-pre-gyp ' + appOne.args, (t) => {
  run('node-pre-gyp', 'configure', '--ensure=false --dist-url=invalid-value', appOne, {}, (err) => {
    t.ok(err, 'Expected command to fail');
    t.end();
  });
});

test(appOne.name + ' passes --dist-url down to node-gyp via npm ' + appOne.args, (t) => {
  run('npm', 'install', '--build-from-source --ensure=false --dist-url=invalid-value', appOne, {}, (err) => {
    t.ok(err, 'Expected command to fail');
    t.end();
  });
});

// Tests run for all apps

apps.forEach((app) => {

  if (app.name === 'app7' && !napi.get_napi_version()) return;

  // clear out entire binding directory
  // to ensure no stale builds. This is needed
  // because "node-pre-gyp clean" only removes
  // the current target and not alternative builds
  test('cleanup of app', (t) => {
    const binding_directory = path.join(__dirname, app.name, 'lib/binding');
    if (fs.existsSync(binding_directory)) {
      rm.sync(binding_directory);
    }
    t.end();
  });

  test(app.name + ' configures ' + app.args, (t) => {
    run('node-pre-gyp', 'configure', '--loglevel=error', app, {}, (err) => {
      t.ifError(err);
      t.end();
    });
  });

  test(app.name + ' configures with unparsed options ' + app.args, (t) => {
    run('node-pre-gyp', 'configure', '--loglevel=info -- -Dfoo=bar', app, {}, (err, stdout, stderr) => {
      t.ifError(err);
      t.equal(stdout, '');
      t.ok(stderr.search(/(gyp info spawn args).*(-Dfoo=bar)/) > -1);
      t.end();
    });
  });

  if (process.platform !== 'win32') {
    test(app.name + ' builds with unparsed options ' + app.args, (t) => {
      // clean and build as separate steps here because configure only works with -Dfoo=bar
      // and build only works with FOO=bar
      run('node-pre-gyp', 'clean', '', app, {}, (err) => {
        t.ifError(err);
        const propertyPrefix = (process.platform === 'win32') ? '/p:' : '';
        run('node-pre-gyp', 'build', '--loglevel=info -- ' + propertyPrefix + 'FOO=bar', app, {}, (err2, stdout, stderr) => {
          t.ifError(err2);
          t.ok(stderr.search(/(gyp info spawn args).*(FOO=bar)/) > -1);
          if (process.platform !== 'win32') {
            if (app.args.indexOf('--debug') > -1) {
              t.stringContains(stdout, 'Debug/' + app.name + '.node');
            } else {
              t.stringContains(stdout, 'Release/' + app.name + '.node');
            }
          }
          t.end();
        });
      });
    });
  } else {
    // Skipping since this support broke upstream in node-gyp: https://github.com/nodejs/node-gyp/pull/1616
    test.skip(app.name + ' builds with unparsed options ' + app.args, () => {});
  }

  test(app.name + ' builds ' + app.args, (t) => {
    run('node-pre-gyp', 'rebuild', '--fallback-to-build', app, {}, (err, stdout, stderr) => {
      t.ifError(err);
      if (err) {
        console.log(stdout);
        console.log(stderr);
      }
      if (process.platform !== 'win32') {
        if (app.args.indexOf('--debug') > -1) {
          t.stringContains(stdout, 'Debug/' + app.name + '.node');
        } else {
          t.stringContains(stdout, 'Release/' + app.name + '.node');
        }
      }
      t.end();
    });
  });

  test(app.name + ' is found ' + app.args, (t) => {
    run('node-pre-gyp', 'reveal', 'module_path --silent', app, {}, (err, stdout) => {
      t.ifError(err);
      let module_path = stdout.trim();
      if (module_path.indexOf('\n') !== -1) { // take just the first line
        module_path = module_path.substr(0, module_path.indexOf('\n'));
      }
      t.stringContains(module_path, app.name);
      t.ok(existsSync(module_path), 'is valid path to existing binary: ' + module_path);
      const module_binary = path.join(module_path, app.name + '.node');
      t.ok(existsSync(module_binary));
      t.end();
    });
  });

  test(app.name + ' passes tests ' + app.args, (t) => {
    run('npm', 'test', '', app, { cwd: path.join(__dirname, app.name) }, (err, stdout) => {
      t.ifError(err);
      // we expect app2 to console.log on success
      if (app.name === 'app2') {
        if (app.args.indexOf('--debug') > -1) {
          t.stringContains(stdout, 'Loaded Debug build');
        } else {
          t.stringContains(stdout, 'Loaded Release build');
        }
      } else {
        // we expect some npm output
        t.notEqual(stdout, '');
      }
      t.end();
    });
  });

  test(app.name + ' packages ' + app.args, (t) => {
    run('node-pre-gyp', 'package', '', app, {}, (err) => {
      t.ifError(err);
      // Make sure a tarball was created
      run('node-pre-gyp', 'reveal', 'staged_tarball --silent', app, {}, (err2, stdout) => {
        t.ifError(err2);
        let staged_tarball = stdout.trim();
        if (staged_tarball.indexOf('\n') !== -1) { // take just the first line
          staged_tarball = staged_tarball.substr(0, staged_tarball.indexOf('\n'));
        }
        const tarball_path = path.join(__dirname, app.name, staged_tarball);
        t.ok(existsSync(tarball_path), 'staged tarball is a valid file');
        if (!app.files) {
          return t.end();
        }
        // Make sure the package contains what we expect
        const entries = [];
        tar.t({
          file: tarball_path,
          sync: true,
          onentry: function(entry) {
            entries.push(entry.path);
          }
        });
        let files = app.files.base;
        const nodever = versioning.get_runtime_abi('node');
        // Look for a more specific choice
        if (Object.hasOwnProperty.call(app.files, process.platform)) {
          const appPlatList = app.files[process.platform];
          if (Object.hasOwnProperty.call(appPlatList, nodever)) {
            files = appPlatList[nodever];
          } else if (Object.hasOwnProperty.call(appPlatList, 'base')) {
            files = appPlatList.base;
          } else {
            files = appPlatList;
          }
        }
        // windows is too variable to keep this test up to date across node versions
        if (process.platform !== 'win32') {
          t.same(entries.sort(), files.sort(), 'staged tarball contains the right files');
        }
        t.end();
      });
    });
  });

  test(app.name + ' package is valid ' + app.args, (t) => {
    run('node-pre-gyp', 'testpackage', '', app, {}, (err) => {
      t.ifError(err);
      t.end();
    });
  });

  ciSkip(app.name + ' publishes ' + app.args, (t) => {
    run('node-pre-gyp', 'unpublish publish', '', app, {}, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  ciSkip(app.name + ' info shows it ' + app.args, (t) => {
    run('node-pre-gyp', 'reveal', 'package_name', app, {}, (err, stdout) => {
      t.ifError(err);
      let package_name = stdout.trim();
      if (package_name.indexOf('\n') !== -1) { // take just the first line
        package_name = package_name.substr(0, package_name.indexOf('\n'));
      }
      run('node-pre-gyp', 'info', '', app, {}, (err2, stdout2) => {
        t.ifError(err2);
        t.stringContains(stdout2, package_name);
        t.end();
      });
    });
  });

  ciSkip(app.name + ' can be uninstalled ' + app.args, (t) => {
    run('node-pre-gyp', 'clean', '', app, {}, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  ciSkip(app.name + ' can be installed via remote ' + app.args, (t) => {
    const opts = {
      cwd: path.join(__dirname, app.name),
      npg_debug: false
    };
    run('npm', 'install', '--fallback-to-build=false', app, opts, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  ciSkip(app.name + ' can be reinstalled via remote ' + app.args, (t) => {
    const opts = {
      cwd: path.join(__dirname, app.name),
      npg_debug: false
    };
    run('npm', 'install', '--update-binary --fallback-to-build=false', app, opts, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  ciSkip(app.name + ' via remote passes tests ' + app.args, (t) => {
    const opts = {
      cwd: path.join(__dirname, app.name),
      npg_debug: false
    };
    run('npm', 'install', '', app, opts, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  ciSkip(app.name + ' unpublishes ' + app.args, (t) => {
    run('node-pre-gyp', 'unpublish', '', app, {}, (err, stdout) => {
      t.ifError(err);
      t.notEqual(stdout, '');
      t.end();
    });
  });

  // note: the above test will result in a non-runnable binary, so the below test must succeed otherwise all following tests will fail

  test(app.name + ' builds with custom --target ' + app.args, (t) => {
    run('node-pre-gyp', 'rebuild', '--loglevel=error --fallback-to-build --target=' + process.versions.node, app, {}, (err) => {
      t.ifError(err);
      t.end();
    });
  });
});

// this is really just onFinish() but local to the tests in this file
test(`cleanup after ${__filename}`, (t) => {
  mockS3Http('on');
  proxy.stopServer();
  delete process.env.NOCK_OFF;
  delete process.env.http_proxy;
  delete process.env.https_proxy;
  process.env.node_pre_gyp_s3_host = initial_s3_host;
  process.env.node_pre_gyp_mock_s3 = initial_mock_s3;
  t.end();
});
<|endoftext|>


<commit_before>/**
 *
 * @author petr.sloup@klokantech.com (Petr Sloup)
 *
 * Copyright 2013 Klokan Technologies Gmbh (www.klokantech.com)
 */

goog.provide('weapi');
goog.provide('weapi.exports.Polygon');

goog.require('goog.math');

goog.require('we.canvas2image');
goog.require('weapi.App');
goog.require('weapi.EditablePolygon');
goog.require('weapi.Map');
goog.require('weapi.MiniGlobe');

//TODO: reversed tilting, polygons -- new polyicons, pixelcolor, WMS

//Constructor
goog.exportSymbol('WebGLEarth', weapi.App);

////////////////////////////////////////////////////////////////////////////////
/* Camera manipulation */

goog.exportSymbol('WebGLEarth.prototype.setAltitude', function(alt) {
  var cam = this.camera;
  cam.animator.cancel();

  var heading = cam.getHeading();
  var tilt = cam.getTilt();

  cam.setPos(undefined, undefined, alt);
  cam.setHeadingAndTilt(heading, tilt);
});

goog.exportSymbol('WebGLEarth.prototype.getAltitude', function() {
  return this.camera.getPos()[2];
});

goog.exportSymbol('WebGLEarth.prototype.setZoom', function(zoom) {
  var alt = weapi.Camera.calcAltitudeForZoom(this.canvas,
                                             this.camera.camera.frustum.fovy,
                                             zoom, this.camera.getPos()[0]);
  this['setAltitude'](alt);
});

goog.exportSymbol('WebGLEarth.prototype.getZoom', function() {
  var pos = this.camera.getPos();
  var zoom = weapi.Camera.calcZoomForAltitude(this.canvas,
                                              this.camera.camera.frustum.fovy,
                                              pos[2], pos[0]);
  return zoom;
});

goog.exportSymbol('WebGLEarth.prototype.setPosition', function(lat, lon,
    opt_zoom, opt_altitude, opt_heading, opt_tilt, opt_targetPosition) {
      var cam = this.camera;
      cam.animator.cancel();

      lat = goog.math.toRadians(lat);
      lon = goog.math.toRadians(lon);

      if (goog.isDefAndNotNull(opt_zoom)) {
        //window['console']['log']('Zoom is no longer supported.');
        opt_altitude = weapi.Camera.calcAltitudeForZoom(this.canvas,
                                                        cam.camera.frustum.fovy,
                                                        opt_zoom, lat);
      }

      var alt = opt_altitude || cam.getPos()[2];
      var heading = goog.math.toRadians(opt_heading) || cam.getHeading();
      var tilt = goog.math.toRadians(opt_tilt) || cam.getTilt();

      if (opt_targetPosition) {
        var newPos = weapi.Camera.calculatePositionForGivenTarget(
            lat, lon, alt,
            heading, tilt);

        lat = newPos[0];
        lon = newPos[1];
        if (goog.isDefAndNotNull(opt_zoom)) {
          // recalc altitude to better fit modified latitude
          //window['console']['log']('Zoom is no longer supported.');
          alt = weapi.Camera.calcAltitudeForZoom(this.canvas,
                                                 cam.camera.frustum.fovy,
                                                 opt_zoom, lat);
        }
      }

      cam.setPosHeadingAndTilt(lat, lon, alt, heading, tilt);
    });

goog.exportSymbol('WebGLEarth.prototype.getPosition', function() {
  var pos = this.camera.getPos();
  return [goog.math.toDegrees(pos[0]), goog.math.toDegrees(pos[1])];
});

goog.exportSymbol('WebGLEarth.prototype.getHeading', function() {
  return goog.math.toDegrees(this.camera.getHeading());
});

goog.exportSymbol('WebGLEarth.prototype.getTilt', function() {
  return goog.math.toDegrees(this.camera.getTilt());
});

goog.exportSymbol('WebGLEarth.prototype.setHeading', function(heading) {
  this.camera.animator.cancel();
  this.camera.setHeading(goog.math.toRadians(heading));
});

goog.exportSymbol('WebGLEarth.prototype.setTilt', function(tilt) {
  this.camera.animator.cancel();
  this.camera.setTilt(goog.math.toRadians(tilt));
});

goog.exportSymbol('WebGLEarth.prototype.flyTo', function(latitude, longitude,
                                                         opt_altitude,
                                                         opt_heading,
                                                         opt_tilt,
                                                         opt_targetPosition) {
      this.camera.animator.flyTo(goog.math.toRadians(latitude),
          goog.math.toRadians(longitude),
          opt_altitude,
          goog.math.toRadians(opt_heading),
          goog.math.toRadians(opt_tilt),
          opt_targetPosition);
    });

goog.exportSymbol('WebGLEarth.prototype.flyToFitBounds', function(minlat,
                                                                  maxlat,
                                                                  minlon,
                                                                  maxlon) {
      minlat = goog.math.toRadians(minlat);
      maxlat = goog.math.toRadians(maxlat);
      minlon = goog.math.toRadians(minlon);
      maxlon = goog.math.toRadians(maxlon);

      var altitude = this.camera.calcDistanceToViewBounds(minlat, maxlat,
                                                          minlon, maxlon);

      minlon = goog.math.modulo(minlon, 2 * Math.PI);
      maxlon = goog.math.modulo(maxlon, 2 * Math.PI);

      var lonDiff = minlon - maxlon;
      if (lonDiff < -Math.PI) {
        minlon += 2 * Math.PI;
      } else if (lonDiff > Math.PI) {
        maxlon += 2 * Math.PI;
      }

      var center = [(minlat + maxlat) / 2, (minlon + maxlon) / 2];

      this.camera.animator.flyTo(center[0], center[1], altitude);
    });

goog.exportSymbol('WebGLEarth.prototype.getTarget', function() {
  var center = new Cesium.Cartesian2(this.canvas.width / 2,
                                     this.canvas.height / 2);
  var position = this.camera.camera.controller.pickEllipsoid(center);

  if (goog.isDefAndNotNull(position)) {
    var carto = this.camera.ellipsoid.cartesianToCartographic(position);
    return [goog.math.toDegrees(carto.latitude),
            goog.math.toDegrees(carto.longitude)];
  } else {
    return undefined;
  }
});

////////////////////////////////////////////////////////////////////////////////
/* Various */

goog.exportSymbol('WebGLEarth.prototype.handleResize',
                  weapi.App.prototype.handleResize);

goog.exportSymbol('WebGLEarth.prototype.saveScreenshot', function(name) {
  this.afterFrameOnce = goog.bind(function() {
    var canvas_ = we.canvas2image.prepareCanvas(this.scene.getCanvas(),
                                                this.markerManager,
                                                this.miniglobe);
    we.canvas2image.saveCanvasAsPNG(canvas_, name);
  }, this);
});

goog.exportSymbol('WebGLEarth.prototype.getScreenshot', function(callback) {
  this.afterFrameOnce = goog.bind(function() {
    var canvas_ = we.canvas2image.prepareCanvas(this.scene.getCanvas(),
                                                this.markerManager,
                                                this.miniglobe);
    callback(we.canvas2image.getCanvasAsDataURL(canvas_));
  }, this);
});

goog.exportSymbol('WebGLEarth.prototype.showMiniGlobe', function(src, size) {
  if (goog.isDefAndNotNull(src)) {
    this.miniglobe = new weapi.MiniGlobe(this, 32, 32, src);
    this.miniglobe.setSize(size);
  } else {
    this.miniglobe = null;
  }
});

goog.exportSymbol('WebGLEarth.prototype.pauseRendering', function() {
  this.forcedPause = true;
});

goog.exportSymbol('WebGLEarth.prototype.resumeRendering', function() {
  this.forcedPause = false;
});

////////////////////////////////////////////////////////////////////////////////
/* Maps */

goog.exportSymbol('WebGLEarth.Maps', weapi.maps.MapType);
goog.exportSymbol('WebGLEarth.prototype.initMap', function(type, opts) {
  return weapi.maps.initMap(this, type, opts);
});
goog.exportSymbol('WebGLEarth.prototype.setBaseMap',
                  weapi.App.prototype.setBaseMap);
goog.exportSymbol('WebGLEarth.prototype.setOverlayMap',
                  weapi.App.prototype.setOverlayMap);

goog.exportSymbol('WebGLEarth.Map', weapi.Map);
goog.exportSymbol('WebGLEarth.Map.prototype.setBoundingBox',
                  weapi.Map.prototype.setBoundingBox);
goog.exportSymbol('WebGLEarth.Map.prototype.setOpacity',
                  weapi.Map.prototype.setOpacity);
goog.exportSymbol('WebGLEarth.Map.prototype.getOpacity',
                  weapi.Map.prototype.getOpacity);

////////////////////////////////////////////////////////////////////////////////
/* Markers */

goog.exportSymbol('WebGLEarth.Marker', weapi.markers.PrettyMarker);
goog.exportSymbol('WebGLEarth.Marker.prototype.setPosition', function(lat,
                                                                      lon) {
      this.lat = goog.math.toRadians(lat);
      this.lon = goog.math.toRadians(lon);
    });

goog.exportSymbol('WebGLEarth.Marker.prototype.bindPopup', function(content,
                                                                    maxWidth,
                                                                    closeBtn) {
      this.attachPopup(new weapi.markers.Popup(content, maxWidth, closeBtn));
      return this;
    });

goog.exportSymbol('WebGLEarth.Marker.prototype.openPopup', function() {
  this.showPopup(true);
});

goog.exportSymbol('WebGLEarth.Marker.prototype.closePopup', function() {
  this.showPopup(false);
});

goog.exportSymbol('WebGLEarth.prototype.initMarker',
                  weapi.App.prototype.initMarker);
goog.exportSymbol('WebGLEarth.prototype.removeMarker',
                  weapi.App.prototype.removeMarker);

goog.exportSymbol('WebGLEarth.Marker.prototype.on', function(type, listener) {
  /**
   * Wraps the listener function with a wrapper function
   * that adds some extended event info.
   * @param {!weapi.markers.AbstractMarker} marker .
   * @param {function(Event)} listener Original listener function.
   * @return {function(Event)} Wrapper listener.
   */
  var wrap = function(marker, listener) {
    return function(e) {
      e.target = marker;
      e['latitude'] = goog.math.toDegrees(marker.lat);
      e['longitude'] = goog.math.toDegrees(marker.lon);

      listener(e);
    };
  };
  var key = goog.events.listen(this.element, type, wrap(this, listener));
  listener[goog.getUid(this) + '___eventKey_' + type] = key;

  return key;
});
goog.exportSymbol('WebGLEarth.Marker.prototype.off', weapi.App.prototype.off);
goog.exportSymbol('WebGLEarth.Marker.prototype.offAll', function(type) {
  goog.events.removeAll(this.element, type);
});

////////////////////////////////////////////////////////////////////////////////
/* Polygons */

/**
 * @param {!weapi.App} app .
 * @constructor
 * @extends {weapi.EditablePolygon}
 */
weapi.exports.Polygon = function(app) {
  goog.base(this, app, app.markerManager);
};
goog.inherits(weapi.exports.Polygon, weapi.EditablePolygon);

goog.exportSymbol('WebGLEarth.Polygon', weapi.exports.Polygon);

goog.exportSymbol('WebGLEarth.Polygon.prototype.destroy',
                  weapi.exports.Polygon.prototype.destroy);

goog.exportSymbol('WebGLEarth.Polygon.prototype.enableClickToAdd',
                  weapi.exports.Polygon.prototype.enableClickToAdd);
goog.exportSymbol('WebGLEarth.Polygon.prototype.disableClickToAdd',
                  weapi.exports.Polygon.prototype.disableClickToAdd);

goog.exportSymbol('WebGLEarth.Polygon.prototype.setFillColor',
                  weapi.exports.Polygon.prototype.setFillColor);
goog.exportSymbol('WebGLEarth.Polygon.prototype.setStrokeColor',
                  weapi.exports.Polygon.prototype.setStrokeColor);

goog.exportSymbol('WebGLEarth.Polygon.prototype.setOnChange',
                  weapi.exports.Polygon.prototype.setOnChange);
goog.exportSymbol('WebGLEarth.Polygon.prototype.isValid',
                  weapi.exports.Polygon.prototype.isValid);
goog.exportSymbol('WebGLEarth.Polygon.prototype.getRoughArea',
                  weapi.exports.Polygon.prototype.getRoughArea);
goog.exportSymbol('WebGLEarth.Polygon.prototype.intersects',
                  weapi.exports.Polygon.prototype.intersects);

goog.exportSymbol('WebGLEarth.Polygon.prototype.setIcon',
                  weapi.exports.Polygon.prototype.setIcon);
goog.exportSymbol('WebGLEarth.Polygon.prototype.showDraggers',
                  weapi.exports.Polygon.prototype.showDraggers);

goog.exportSymbol('WebGLEarth.Polygon.prototype.addPoint',
                  weapi.exports.Polygon.prototype.addPoint);
goog.exportSymbol('WebGLEarth.Polygon.prototype.movePoint',
                  weapi.exports.Polygon.prototype.movePoint);
goog.exportSymbol('WebGLEarth.Polygon.prototype.removePoint',
                  weapi.exports.Polygon.prototype.removePoint);

goog.exportSymbol('WebGLEarth.Polygon.prototype.getPoints',
                  weapi.exports.Polygon.prototype.getPoints);
goog.exportSymbol('WebGLEarth.Polygon.prototype.getCentroid',
                  weapi.exports.Polygon.prototype.getCentroid);

goog.exportSymbol('WebGLEarth.Polygon.prototype.onClick',
                  function(callback) {
                    goog.events.listen(this.app.canvas,
                        goog.events.EventType.CLICK, function(e) {
                      var cartesian = this.app.camera.camera.controller.
                          pickEllipsoid(
                          new Cesium.Cartesian2(e.offsetX, e.offsetY));
                      if (goog.isDefAndNotNull(cartesian)) {
                        var carto = Cesium.Ellipsoid.WGS84.
                            cartesianToCartographic(cartesian);
                        if (this.isPointIn(
                            goog.math.toDegrees(carto.latitude),
                            goog.math.toDegrees(carto.longitude)) ||
                                this.icon_.isPointIn(e.offsetX, e.offsetY)) {
                          callback(this);
                        }
                      }
                    }, false, this);
                  });

////////////////////////////////////////////////////////////////////////////////
/* DEPRECATED */
goog.exportSymbol('WebGLEarth.prototype.setCenter', function(coords) {
  var cam = this.camera;
  cam.animator.cancel();

  cam.setPosHeadingAndTilt(goog.math.toRadians(coords[0]),
                           goog.math.toRadians(coords[1]),
                           cam.getPos()[2], cam.getHeading(), 0);
});

goog.exportSymbol('WebGLEarth.prototype.getCenter', function() {
  var pos = this.camera.getPos();
  return [goog.math.toDegrees(pos[0]), goog.math.toDegrees(pos[1])];
});
<commit_msg>Forgotten events exports<commit_after>/**
 *
 * @author petr.sloup@klokantech.com (Petr Sloup)
 *
 * Copyright 2013 Klokan Technologies Gmbh (www.klokantech.com)
 */

goog.provide('weapi');
goog.provide('weapi.exports.Polygon');

goog.require('goog.math');

goog.require('we.canvas2image');
goog.require('weapi.App');
goog.require('weapi.EditablePolygon');
goog.require('weapi.Map');
goog.require('weapi.MiniGlobe');

//TODO: reversed tilting, polygons -- new polyicons, pixelcolor, WMS

//Constructor
goog.exportSymbol('WebGLEarth', weapi.App);

////////////////////////////////////////////////////////////////////////////////
/* Camera manipulation */

goog.exportSymbol('WebGLEarth.prototype.setAltitude', function(alt) {
  var cam = this.camera;
  cam.animator.cancel();

  var heading = cam.getHeading();
  var tilt = cam.getTilt();

  cam.setPos(undefined, undefined, alt);
  cam.setHeadingAndTilt(heading, tilt);
});

goog.exportSymbol('WebGLEarth.prototype.getAltitude', function() {
  return this.camera.getPos()[2];
});

goog.exportSymbol('WebGLEarth.prototype.setZoom', function(zoom) {
  var alt = weapi.Camera.calcAltitudeForZoom(this.canvas,
                                             this.camera.camera.frustum.fovy,
                                             zoom, this.camera.getPos()[0]);
  this['setAltitude'](alt);
});

goog.exportSymbol('WebGLEarth.prototype.getZoom', function() {
  var pos = this.camera.getPos();
  var zoom = weapi.Camera.calcZoomForAltitude(this.canvas,
                                              this.camera.camera.frustum.fovy,
                                              pos[2], pos[0]);
  return zoom;
});

goog.exportSymbol('WebGLEarth.prototype.setPosition', function(lat, lon,
    opt_zoom, opt_altitude, opt_heading, opt_tilt, opt_targetPosition) {
      var cam = this.camera;
      cam.animator.cancel();

      lat = goog.math.toRadians(lat);
      lon = goog.math.toRadians(lon);

      if (goog.isDefAndNotNull(opt_zoom)) {
        //window['console']['log']('Zoom is no longer supported.');
        opt_altitude = weapi.Camera.calcAltitudeForZoom(this.canvas,
                                                        cam.camera.frustum.fovy,
                                                        opt_zoom, lat);
      }

      var alt = opt_altitude || cam.getPos()[2];
      var heading = goog.math.toRadians(opt_heading) || cam.getHeading();
      var tilt = goog.math.toRadians(opt_tilt) || cam.getTilt();

      if (opt_targetPosition) {
        var newPos = weapi.Camera.calculatePositionForGivenTarget(
            lat, lon, alt,
            heading, tilt);

        lat = newPos[0];
        lon = newPos[1];
        if (goog.isDefAndNotNull(opt_zoom)) {
          // recalc altitude to better fit modified latitude
          //window['console']['log']('Zoom is no longer supported.');
          alt = weapi.Camera.calcAltitudeForZoom(this.canvas,
                                                 cam.camera.frustum.fovy,
                                                 opt_zoom, lat);
        }
      }

      cam.setPosHeadingAndTilt(lat, lon, alt, heading, tilt);
    });

goog.exportSymbol('WebGLEarth.prototype.getPosition', function() {
  var pos = this.camera.getPos();
  return [goog.math.toDegrees(pos[0]), goog.math.toDegrees(pos[1])];
});

goog.exportSymbol('WebGLEarth.prototype.getHeading', function() {
  return goog.math.toDegrees(this.camera.getHeading());
});

goog.exportSymbol('WebGLEarth.prototype.getTilt', function() {
  return goog.math.toDegrees(this.camera.getTilt());
});

goog.exportSymbol('WebGLEarth.prototype.setHeading', function(heading) {
  this.camera.animator.cancel();
  this.camera.setHeading(goog.math.toRadians(heading));
});

goog.exportSymbol('WebGLEarth.prototype.setTilt', function(tilt) {
  this.camera.animator.cancel();
  this.camera.setTilt(goog.math.toRadians(tilt));
});

goog.exportSymbol('WebGLEarth.prototype.flyTo', function(latitude, longitude,
                                                         opt_altitude,
                                                         opt_heading,
                                                         opt_tilt,
                                                         opt_targetPosition) {
      this.camera.animator.flyTo(goog.math.toRadians(latitude),
          goog.math.toRadians(longitude),
          opt_altitude,
          goog.math.toRadians(opt_heading),
          goog.math.toRadians(opt_tilt),
          opt_targetPosition);
    });

goog.exportSymbol('WebGLEarth.prototype.flyToFitBounds', function(minlat,
                                                                  maxlat,
                                                                  minlon,
                                                                  maxlon) {
      minlat = goog.math.toRadians(minlat);
      maxlat = goog.math.toRadians(maxlat);
      minlon = goog.math.toRadians(minlon);
      maxlon = goog.math.toRadians(maxlon);

      var altitude = this.camera.calcDistanceToViewBounds(minlat, maxlat,
                                                          minlon, maxlon);

      minlon = goog.math.modulo(minlon, 2 * Math.PI);
      maxlon = goog.math.modulo(maxlon, 2 * Math.PI);

      var lonDiff = minlon - maxlon;
      if (lonDiff < -Math.PI) {
        minlon += 2 * Math.PI;
      } else if (lonDiff > Math.PI) {
        maxlon += 2 * Math.PI;
      }

      var center = [(minlat + maxlat) / 2, (minlon + maxlon) / 2];

      this.camera.animator.flyTo(center[0], center[1], altitude);
    });

goog.exportSymbol('WebGLEarth.prototype.getTarget', function() {
  var center = new Cesium.Cartesian2(this.canvas.width / 2,
                                     this.canvas.height / 2);
  var position = this.camera.camera.controller.pickEllipsoid(center);

  if (goog.isDefAndNotNull(position)) {
    var carto = this.camera.ellipsoid.cartesianToCartographic(position);
    return [goog.math.toDegrees(carto.latitude),
            goog.math.toDegrees(carto.longitude)];
  } else {
    return undefined;
  }
});

////////////////////////////////////////////////////////////////////////////////
/* Various */

goog.exportSymbol('WebGLEarth.prototype.handleResize',
                  weapi.App.prototype.handleResize);

goog.exportSymbol('WebGLEarth.prototype.saveScreenshot', function(name) {
  this.afterFrameOnce = goog.bind(function() {
    var canvas_ = we.canvas2image.prepareCanvas(this.scene.getCanvas(),
                                                this.markerManager,
                                                this.miniglobe);
    we.canvas2image.saveCanvasAsPNG(canvas_, name);
  }, this);
});

goog.exportSymbol('WebGLEarth.prototype.getScreenshot', function(callback) {
  this.afterFrameOnce = goog.bind(function() {
    var canvas_ = we.canvas2image.prepareCanvas(this.scene.getCanvas(),
                                                this.markerManager,
                                                this.miniglobe);
    callback(we.canvas2image.getCanvasAsDataURL(canvas_));
  }, this);
});

goog.exportSymbol('WebGLEarth.prototype.showMiniGlobe', function(src, size) {
  if (goog.isDefAndNotNull(src)) {
    this.miniglobe = new weapi.MiniGlobe(this, 32, 32, src);
    this.miniglobe.setSize(size);
  } else {
    this.miniglobe = null;
  }
});

goog.exportSymbol('WebGLEarth.prototype.pauseRendering', function() {
  this.forcedPause = true;
});

goog.exportSymbol('WebGLEarth.prototype.resumeRendering', function() {
  this.forcedPause = false;
});

////////////////////////////////////////////////////////////////////////////////
/* Maps */

goog.exportSymbol('WebGLEarth.Maps', weapi.maps.MapType);
goog.exportSymbol('WebGLEarth.prototype.initMap', function(type, opts) {
  return weapi.maps.initMap(this, type, opts);
});
goog.exportSymbol('WebGLEarth.prototype.setBaseMap',
                  weapi.App.prototype.setBaseMap);
goog.exportSymbol('WebGLEarth.prototype.setOverlayMap',
                  weapi.App.prototype.setOverlayMap);

goog.exportSymbol('WebGLEarth.Map', weapi.Map);
goog.exportSymbol('WebGLEarth.Map.prototype.setBoundingBox',
                  weapi.Map.prototype.setBoundingBox);
goog.exportSymbol('WebGLEarth.Map.prototype.setOpacity',
                  weapi.Map.prototype.setOpacity);
goog.exportSymbol('WebGLEarth.Map.prototype.getOpacity',
                  weapi.Map.prototype.getOpacity);

////////////////////////////////////////////////////////////////////////////////
/* Markers */

goog.exportSymbol('WebGLEarth.Marker', weapi.markers.PrettyMarker);
goog.exportSymbol('WebGLEarth.Marker.prototype.setPosition', function(lat,
                                                                      lon) {
      this.lat = goog.math.toRadians(lat);
      this.lon = goog.math.toRadians(lon);
    });

goog.exportSymbol('WebGLEarth.Marker.prototype.bindPopup', function(content,
                                                                    maxWidth,
                                                                    closeBtn) {
      this.attachPopup(new weapi.markers.Popup(content, maxWidth, closeBtn));
      return this;
    });

goog.exportSymbol('WebGLEarth.Marker.prototype.openPopup', function() {
  this.showPopup(true);
});

goog.exportSymbol('WebGLEarth.Marker.prototype.closePopup', function() {
  this.showPopup(false);
});

goog.exportSymbol('WebGLEarth.prototype.initMarker',
                  weapi.App.prototype.initMarker);
goog.exportSymbol('WebGLEarth.prototype.removeMarker',
                  weapi.App.prototype.removeMarker);

goog.exportSymbol('WebGLEarth.Marker.prototype.on', function(type, listener) {
  /**
   * Wraps the listener function with a wrapper function
   * that adds some extended event info.
   * @param {!weapi.markers.AbstractMarker} marker .
   * @param {function(Event)} listener Original listener function.
   * @return {function(Event)} Wrapper listener.
   */
  var wrap = function(marker, listener) {
    return function(e) {
      e.target = marker;
      e['latitude'] = goog.math.toDegrees(marker.lat);
      e['longitude'] = goog.math.toDegrees(marker.lon);

      listener(e);
    };
  };
  var key = goog.events.listen(this.element, type, wrap(this, listener));
  listener[goog.getUid(this) + '___eventKey_' + type] = key;

  return key;
});
goog.exportSymbol('WebGLEarth.Marker.prototype.off', weapi.App.prototype.off);
goog.exportSymbol('WebGLEarth.Marker.prototype.offAll', function(type) {
  goog.events.removeAll(this.element, type);
});

////////////////////////////////////////////////////////////////////////////////
/* Events */

goog.exportSymbol('WebGLEarth.prototype.on', weapi.App.prototype.on);
goog.exportSymbol('WebGLEarth.prototype.off', weapi.App.prototype.off);
goog.exportSymbol('WebGLEarth.prototype.offAll', weapi.App.prototype.offAll);

////////////////////////////////////////////////////////////////////////////////
/* Polygons */

/**
 * @param {!weapi.App} app .
 * @constructor
 * @extends {weapi.EditablePolygon}
 */
weapi.exports.Polygon = function(app) {
  goog.base(this, app, app.markerManager);
};
goog.inherits(weapi.exports.Polygon, weapi.EditablePolygon);

goog.exportSymbol('WebGLEarth.Polygon', weapi.exports.Polygon);

goog.exportSymbol('WebGLEarth.Polygon.prototype.destroy',
                  weapi.exports.Polygon.prototype.destroy);

goog.exportSymbol('WebGLEarth.Polygon.prototype.enableClickToAdd',
                  weapi.exports.Polygon.prototype.enableClickToAdd);
goog.exportSymbol('WebGLEarth.Polygon.prototype.disableClickToAdd',
                  weapi.exports.Polygon.prototype.disableClickToAdd);

goog.exportSymbol('WebGLEarth.Polygon.prototype.setFillColor',
                  weapi.exports.Polygon.prototype.setFillColor);
goog.exportSymbol('WebGLEarth.Polygon.prototype.setStrokeColor',
                  weapi.exports.Polygon.prototype.setStrokeColor);

goog.exportSymbol('WebGLEarth.Polygon.prototype.setOnChange',
                  weapi.exports.Polygon.prototype.setOnChange);
goog.exportSymbol('WebGLEarth.Polygon.prototype.isValid',
                  weapi.exports.Polygon.prototype.isValid);
goog.exportSymbol('WebGLEarth.Polygon.prototype.getRoughArea',
                  weapi.exports.Polygon.prototype.getRoughArea);
goog.exportSymbol('WebGLEarth.Polygon.prototype.intersects',
                  weapi.exports.Polygon.prototype.intersects);

goog.exportSymbol('WebGLEarth.Polygon.prototype.setIcon',
                  weapi.exports.Polygon.prototype.setIcon);
goog.exportSymbol('WebGLEarth.Polygon.prototype.showDraggers',
                  weapi.exports.Polygon.prototype.showDraggers);

goog.exportSymbol('WebGLEarth.Polygon.prototype.addPoint',
                  weapi.exports.Polygon.prototype.addPoint);
goog.exportSymbol('WebGLEarth.Polygon.prototype.movePoint',
                  weapi.exports.Polygon.prototype.movePoint);
goog.exportSymbol('WebGLEarth.Polygon.prototype.removePoint',
                  weapi.exports.Polygon.prototype.removePoint);

goog.exportSymbol('WebGLEarth.Polygon.prototype.getPoints',
                  weapi.exports.Polygon.prototype.getPoints);
goog.exportSymbol('WebGLEarth.Polygon.prototype.getCentroid',
                  weapi.exports.Polygon.prototype.getCentroid);

goog.exportSymbol('WebGLEarth.Polygon.prototype.onClick',
                  function(callback) {
                    goog.events.listen(this.app.canvas,
                        goog.events.EventType.CLICK, function(e) {
                      var cartesian = this.app.camera.camera.controller.
                          pickEllipsoid(
                          new Cesium.Cartesian2(e.offsetX, e.offsetY));
                      if (goog.isDefAndNotNull(cartesian)) {
                        var carto = Cesium.Ellipsoid.WGS84.
                            cartesianToCartographic(cartesian);
                        if (this.isPointIn(
                            goog.math.toDegrees(carto.latitude),
                            goog.math.toDegrees(carto.longitude)) ||
                                this.icon_.isPointIn(e.offsetX, e.offsetY)) {
                          callback(this);
                        }
                      }
                    }, false, this);
                  });

////////////////////////////////////////////////////////////////////////////////
/* DEPRECATED */
goog.exportSymbol('WebGLEarth.prototype.setCenter', function(coords) {
  var cam = this.camera;
  cam.animator.cancel();

  cam.setPosHeadingAndTilt(goog.math.toRadians(coords[0]),
                           goog.math.toRadians(coords[1]),
                           cam.getPos()[2], cam.getHeading(), 0);
});

goog.exportSymbol('WebGLEarth.prototype.getCenter', function() {
  var pos = this.camera.getPos();
  return [goog.math.toDegrees(pos[0]), goog.math.toDegrees(pos[1])];
});
<|endoftext|>


<commit_before>'use strict';
import React from 'react';
import Shortid from 'shortid';
import { Router, Route, Link } from 'react-router';

export default class Home extends React.Component {
	render(){
		let id = this.props.urlid || Shortid.generate();

		return (

Usage

							Notica is a Bash function / alias that sends a notification to a tab in your browser when it's ran:

$ long-running-command; notica Finished!

							This will wait until the first command completes before running Notica. That way you can go do other things while your long task runs. Then you will recieve a notification on any devices that have the Notica website open.

Quick Setup

							Run this command:

								$ echo 'notica() { curl --data "d:$*" https://notica.us/{id}; }' >> ~/.bashrc && source ~/.bashrc

Go to this link to receive your notifications (bookmark it since it's yours): <Link to={'/' + id}>https://notica.us/{id}</Link>

Setup

Curl is required to use Notica.

							Add this line to your .bashrc file:

								notica() { curl --data "d:$*" https://notica.us/{id}; }

							Source your .bashrc file to apply the changes:

							$ source .bashrc

							All done! Now go to this link (bookmark it since it's yours):

							<Link to={'/' + id}>https://notica.us/{id}</Link>

About

							Notica was written by Tanner Collin after he got tired of checking if his commands were done running.

							Notica is free and open-source software: https://github.com/tannercollin/Notica

							Thanks to exdevlin for thinking of the name. Thanks to all the devs behind Node.js, React, webpack, and socket.io.

		);
	}
}
<commit_msg>Add a space in the curl commands so it works with other shells<commit_after>'use strict';
import React from 'react';
import Shortid from 'shortid';
import { Router, Route, Link } from 'react-router';

export default class Home extends React.Component {
	render(){
		let id = this.props.urlid || Shortid.generate();

		return (

Usage

							Notica is a Bash function / alias that sends a notification to a tab in your browser when it's ran:

$ long-running-command; notica Finished!

							This will wait until the first command completes before running Notica. That way you can go do other things while your long task runs. Then you will recieve a notification on any devices that have the Notica website open.

Quick Setup

							Run this command:

								$ echo 'notica() { curl --data "d:$*" https://notica.us/{id} ; }' >> ~/.bashrc && source ~/.bashrc

Go to this link to receive your notifications (bookmark it since it's yours): <Link to={'/' + id}>https://notica.us/{id}</Link>

Setup

Curl is required to use Notica.

							Add this line to your .bashrc file:

								notica() { curl --data "d:$*" https://notica.us/{id} ; }

							Source your .bashrc file to apply the changes:

							$ source .bashrc

							All done! Now go to this link (bookmark it since it's yours):

							<Link to={'/' + id}>https://notica.us/{id}</Link>

About

							Notica was written by Tanner Collin after he got tired of checking if his commands were done running.

							Notica is free and open-source software: https://github.com/tannercollin/Notica

							Thanks to exdevlin for thinking of the name. Thanks to all the devs behind Node.js, React, webpack, and socket.io.

		);
	}
}
<|endoftext|>