<commit_before>
/**
 * main.js
 * 애플리케이션 메인
 */
define( [ 'backbone', 'multipage-router', 'template!msg', 'bootstrap', 'style!main' ], function( Backbone, MultipageRouter, msgTemplate ) {
	return {
		launch: function() {

			// 추첨 대상
			var phones = [
				"01042540552",
				"01029338375",
				"01072987300",
				"01042540552"
			];

			// 중복을 제거한다.
			phones = _.uniq( phones );

			// 응모자, 당첨자 수
			var entryCount = phones.length, winCount = 0;

			// 응모자 수를 업데이트하는 함수를 리턴한다.
			function updateCount( el, count ) {
				return function() {
					$( el ).text( count );
				};
			}

			// HOME 화면
			$( '#section-home' ).on( 'active', function( event ) {

				$( '#p-msg' ).html( msgTemplate( { entryCount: entryCount, winCount: winCount, targetCount: phones.length } ) );

				for ( var i = 0; i < 10; i++ )
					setTimeout( updateCount( '#entry-count', Math.floor( entryCount * i / 9 ) ), i * 100 );

				for ( var i = 0; i < 10; i++ )
					setTimeout( updateCount( '#win-count', Math.floor( winCount * i / 9 ) ), i * 100 );

			} ).on( 'inactive', function() {
				updateCount( '#entry-count', 0 )();
				updateCount( '#win-count', 0 )();
			} );

			// 추첨 화면
			$( '#section-pick' ).on( 'active', function( event ) {
			} ).on( 'inactive', function() {
				$( '#modal-done' ).modal( 'hide' );
			} );

			// 슬롯머신 레버
			$( '#arm' ).click( function( event ) {
				var arm = $( this ).addClass( 'clicked' );

				setTimeout( function() { arm.removeClass( 'clicked' ); }, 500 );

				event.preventDefault();

				// 슬롯머신을 돌리고 일정 시간 후에 멈춘다.
				var equation = $( '#equation' ).removeClass( 'done' ).addClass( 'three' );
				setTimeout( function() { equation.addClass( 'done' ); }, 3000 );

				setTimeout( function() {

					// 당첨자를 선정한다.
					var index = Math.floor( Math.random() * phones.length );
					$( '#btn-call' ).attr( 'href', 'tel:' + phones[ index ] );
					winCount++;

					// 당첨자는 추첨 목록에서 제외한다.
					phones = _.without( phones, phones[ index ] );

					$( '#modal-done' ).modal( 'show' );
				}, 5000 );
			} );

			// Router
			new ( MultipageRouter.extend( { useDataAttributes: true } ) );
			Backbone.history.start();
		}
	};
} );
<commit_msg>경품 추첨: 모듈 정의 부분 수정<commit_after>
/**
 * main.js
 * 애플리케이션 메인
 */
define( [ 'jquery', 'underscore', 'backbone', 'multipage-router', 'template!msg', 'bootstrap', 'style!main' ], function( $, _, Backbone, MultipageRouter, msgTemplate ) {
	return {
		launch: function() {

			// 추첨 대상
			var phones = [
				"01042540552",
				"01029338375",
				"01072987300",
				"01042540552"
			];

			// 중복을 제거한다.
			phones = _.uniq( phones );

			// 응모자, 당첨자 수
			var entryCount = phones.length, winCount = 0;

			// 응모자 수를 업데이트하는 함수를 리턴한다.
			function updateCount( el, count ) {
				return function() {
					$( el ).text( count );
				};
			}

			// HOME 화면
			$( '#section-home' ).on( 'active', function( event ) {

				$( '#p-msg' ).html( msgTemplate( { entryCount: entryCount, winCount: winCount, targetCount: phones.length } ) );

				for ( var i = 0; i < 10; i++ )
					setTimeout( updateCount( '#entry-count', Math.floor( entryCount * i / 9 ) ), i * 100 );

				for ( var i = 0; i < 10; i++ )
					setTimeout( updateCount( '#win-count', Math.floor( winCount * i / 9 ) ), i * 100 );

			} ).on( 'inactive', function() {
				updateCount( '#entry-count', 0 )();
				updateCount( '#win-count', 0 )();
			} );

			// 추첨 화면
			$( '#section-pick' ).on( 'active', function( event ) {
			} ).on( 'inactive', function() {
				$( '#modal-done' ).modal( 'hide' );
			} );

			// 슬롯머신 레버
			$( '#arm' ).click( function( event ) {
				var arm = $( this ).addClass( 'clicked' );

				setTimeout( function() { arm.removeClass( 'clicked' ); }, 500 );

				event.preventDefault();

				// 슬롯머신을 돌리고 일정 시간 후에 멈춘다.
				var equation = $( '#equation' ).removeClass( 'done' ).addClass( 'three' );
				setTimeout( function() { equation.addClass( 'done' ); }, 3000 );

				setTimeout( function() {

					// 당첨자를 선정한다.
					var index = Math.floor( Math.random() * phones.length );
					$( '#btn-call' ).attr( 'href', 'tel:' + phones[ index ] );
					winCount++;

					// 당첨자는 추첨 목록에서 제외한다.
					phones = _.without( phones, phones[ index ] );

					$( '#modal-done' ).modal( 'show' );
				}, 5000 );
			} );

			// Router
			new ( MultipageRouter.extend( { useDataAttributes: true } ) );
			Backbone.history.start();
		}
	};
} );
<|endoftext|>


<commit_before>/**
 * appBeforeBuild2MakePRD.js
 * @author LuoWen
 * @date 20160505
 */
module.exports = function(context) {
    var path = context.requireCordovaModule('path'),
        fs = context.requireCordovaModule('fs'),
        shell = context.requireCordovaModule('shelljs'),
        projectRoot = context.opts.projectRoot;

    //--------------------Android-------------------
    if (context.opts.cordova.platforms.indexOf("android") !== -1) {
        var targetDir = path.join(projectRoot, "platforms", "android", "src", "org", "apache", "cordova", "filetransfer");
        var targetFiles = ["FileTransfer.java"];
        var tmpls = [{
            source: "outputStream = resourceApi.openOutputStream(targetUri);",
            target: "outputStream = resourceApi.openOutputStream(targetUri, true /*Commented for PRD by LuoWen*/);"
        }, {
            source: "file.delete();",
            target: "//file.delete(/*Commented for PRD by LuoWen*/);"
        }, {
            source: "file.delete();",
            target: "//file.delete(/*Commented for PRD by LuoWen*/);"
        }];

        replaceTmpls(fs, path, targetDir, targetFiles, tmpls);

        //--------------------iOS-------------------
    } else if (context.opts.cordova.platforms.indexOf("ios") !== -1) {
        var targetDir = path.join(projectRoot, "platforms", "ios", "小爱学习圈", "plugins", "cordova-plugin-file-transfer");
        var targetFiles = ["CDVFileTransfer.m"];
        var tmpls = [{
            source: "// create target file",
            target: "if ([[NSFileManager defaultManager] fileExistsAtPath:filePath] == NO) { \r\n // /*Commented for PRD by LuoWen*/create target file"
        }, {
            source: "// open target file for writing",
            target: "} \r\n // /*Commented for PRD by LuoWen*/open target file for writing"
        }, {
            source: 'DLog(@"Streaming to file %@", filePath);',
            target: '[self.targetFileHandle seekToEndOfFile]; \r\n DLog(@"Streaming to file %@", filePath/*Commented for PRD by LuoWen*/);'
        }];

        replaceTmpls(fs, path, targetDir, targetFiles, tmpls);

        //--------------------Others-------------------
    } else {
        console.log('Unknown Platform', context.opts.cordova.platforms);
    }
};

function replaceTmpls(fs, path, targetDir, targetFiles, tmpls) {
    targetFiles.forEach(function(file) {
        var targetFile = path.join(targetDir, file);
        fs.readFile(targetFile, {
            encoding: 'utf-8'
        }, function(err, data) {
            if (err) {
                throw err;
            }
            var originData = data;

            tmpls.forEach(function(tmpl) {
                data = data.replace(tmpl.source, tmpl.target);
            });

            if (data.split(/Commented/mg).length === tmpls.length + 1) {
                if (originData === data) {
                    console.log("\r\nPRD running, no need to replace.\r\n");
                } else {
                    console.log('\r\nPRD replace success.\r\n');
                }
            } else {
                console.error("\r\nPRD replace Failed !!!\r\n");
            }

            fs.writeFileSync(targetFile, data);
        });
    });
}
<commit_msg>fixed PRD for iOS; iOS断点续下载修复正常<commit_after>/**
 * appBeforeBuild2MakePRD.js
 * @author LuoWen
 * @date 20160505
 */
module.exports = function(context) {
    var path = context.requireCordovaModule('path'),
        fs = context.requireCordovaModule('fs'),
        shell = context.requireCordovaModule('shelljs'),
        projectRoot = context.opts.projectRoot,
        plugins     = context.opts.plugins || [];

    // The plugins array will be empty during platform add
    if (plugins.length > 0 && plugins.indexOf('cordova-plugin-pause-resume-download') === -1) {
        return ;
    }

    var ConfigParser = null;
    try {
        ConfigParser = context.requireCordovaModule('cordova-common').ConfigParser;
    } catch(e) {
        // fallback
        ConfigParser = context.requireCordovaModule('cordova-lib/src/configparser/ConfigParser');
    }

    var config      = new ConfigParser(path.join(context.opts.projectRoot, "config.xml")),
        packageName = config.android_packageName() || config.packageName();

    // replace dash (-) with underscore (_)
    packageName = packageName.replace(/-/g , "_");

    console.info("Running android-install.Hook: " + context.hook + ", Package: " + packageName + ", Path: " + projectRoot + ".");

    if (!packageName) {
        console.error("Package name could not be found!");
        return ;
    }

    var projectName = config.name();

    //--------------------Android-------------------
    if (context.opts.cordova.platforms.indexOf("android") !== -1) {
        var targetDir = path.join(projectRoot, "platforms", "android", "src", "org", "apache", "cordova", "filetransfer");
        var targetFiles = ["FileTransfer.java"];
        var tmpls = [{
            source: "outputStream = resourceApi.openOutputStream(targetUri);",
            target: "outputStream = resourceApi.openOutputStream(targetUri, true /*Commented for PRD by LuoWen*/);"
        }, {
            source: "file.delete();",
            target: "//file.delete(/*Commented for PRD by LuoWen*/);"
        }, {
            source: "file.delete();",
            target: "//file.delete(/*Commented for PRD by LuoWen*/);"
        }];

        replaceTmpls(fs, path, targetDir, targetFiles, tmpls);

        //--------------------iOS-------------------
    } else if (context.opts.cordova.platforms.indexOf("ios") !== -1) {
        var targetDir = path.join(projectRoot, "platforms", "ios", projectName, "plugins", "cordova-plugin-file-transfer");
        console.log('ios targetDir', targetDir)
        var targetFiles = ["CDVFileTransfer.m"];
        var tmpls = [{
            source: "// create target file",
            target: "if ([[NSFileManager defaultManager] fileExistsAtPath:filePath] == NO) { \r\n\t\t// /*Commented for PRD by LuoWen*/ // create target file"
        }, {
            source: "// open target file for writing",
            target: "} \r\n\t\t// /*Commented for PRD by LuoWen*/ // open target file for writing"
        }, {
            source: 'DLog(@"Streaming to file %@", filePath);',
            target: '[self.targetFileHandle seekToEndOfFile]; \r\n\t\tDLog(@"Streaming append to file %@", filePath/*Commented for PRD by LuoWen*/);'
        }, {
            source: '[self removeTargetFile];',
            target: '// [self removeTargetFile]; /*Commented for PRD by LuoWen*/'
        }];

        replaceTmpls(fs, path, targetDir, targetFiles, tmpls);

        //--------------------Others-------------------
    } else {
        console.log('Unknown Platform', context.opts.cordova.platforms);
    }
};

function replaceTmpls(fs, path, targetDir, targetFiles, tmpls) {
    targetFiles.forEach(function(file) {
        var targetFile = path.join(targetDir, file);
        fs.readFile(targetFile, {
            encoding: 'utf-8'
        }, function(err, data) {
            if (err) {
                throw err;
            }
            var originData = data;

            tmpls.forEach(function(tmpl) {
                data = data.replace(tmpl.source, tmpl.target);
            });

            if (data.split(/Commented/mg).length === tmpls.length + 1) {
                if (originData === data) {
                    console.log("\r\nPRD running, no need to replace.\r\n");
                } else {
                    console.log('\r\nPRD replace success.\r\n');
                }
            } else {
                console.error("\r\nPRD replace Failed !!!\r\n");
            }

            fs.writeFileSync(targetFile, data);
        });
    });
}
<|endoftext|>


<commit_before>/*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */

import { join } from 'path';
import { Router } from 'express';
import jade from 'jade';
import fm from 'front-matter';
import fs from '../utils/fs';
import request from 'superagent';

// A folder with Jade/Markdown/HTML content pages
const CONTENT_DIR = join(__dirname, './content');

// Extract 'front matter' metadata and generate HTML
const parseJade = (path, jadeContent) => {
  const fmContent = fm(jadeContent);
  const htmlContent = jade.render(fmContent.body);
  return Object.assign({ path, content: htmlContent }, fmContent.attributes);
};

const router = new Router();

router.get('/', async (req, res, next) => {
  try {
    const path = req.query.path;

    if (!path || path === 'undefined') {
      res.status(400).send({error: `The 'path' query parameter cannot be empty.`});
      return;
    }

    let fileName = join(CONTENT_DIR, (path === '/' ? '/index' : path) + '.jade');
    if (!await fs.exists(fileName)) {
      fileName = join(CONTENT_DIR, path + '/index.jade');
    }

    if (!await fs.exists(fileName)) {
      res.status(404).send({error: `The page '${path}' is not found.`});
    } else {
      const source = await fs.readFile(fileName, { encoding: 'utf8' });
      const content = parseJade(path, source);
      res.status(200).send(content);
    }
  } catch (err) {
    next(err);
  }
});

router.post('/', function(req,res){
    request
     .post('something')
     .send(req.body)
     .end(function(err, backendResponse){
       res.status(backendResponse.status).send(backendResponse.text)
    })
   }
  );

export default router;

<commit_msg>inject backend url on boot<commit_after>/*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */

import { join } from 'path';
import { Router } from 'express';
import jade from 'jade';
import fm from 'front-matter';
import fs from '../utils/fs';
import request from 'superagent';

// A folder with Jade/Markdown/HTML content pages
const CONTENT_DIR = join(__dirname, './content');

// Extract 'front matter' metadata and generate HTML
const parseJade = (path, jadeContent) => {
  const fmContent = fm(jadeContent);
  const htmlContent = jade.render(fmContent.body);
  return Object.assign({ path, content: htmlContent }, fmContent.attributes);
};

const router = new Router();

router.get('/', async (req, res, next) => {
  try {
    const path = req.query.path;

    if (!path || path === 'undefined') {
      res.status(400).send({error: `The 'path' query parameter cannot be empty.`});
      return;
    }

    let fileName = join(CONTENT_DIR, (path === '/' ? '/index' : path) + '.jade');
    if (!await fs.exists(fileName)) {
      fileName = join(CONTENT_DIR, path + '/index.jade');
    }

    if (!await fs.exists(fileName)) {
      res.status(404).send({error: `The page '${path}' is not found.`});
    } else {
      const source = await fs.readFile(fileName, { encoding: 'utf8' });
      const content = parseJade(path, source);
      res.status(200).send(content);
    }
  } catch (err) {
    next(err);
  }
});

router.post('/', function(req,res){
    request
     .post(process.env.BACKEND_URL)
     .send(req.body)
     .end(function(err, backendResponse){
       res.status(backendResponse.status).send(backendResponse.text)
    })
   }
  );

export default router;

<|endoftext|>


<commit_before><<<<<<< 91431201771f54434ebda173c26bda1c3df405d4
export async function create ({ pool, name, description, pif, mtu = 1500, vlan = 0 }) {
  return this.getXapi(pool).createNetwork({
    name,
    description,
    pifId: pif && this.getObject(pif, 'PIF')._xapiId,
    mtu: +mtu,
    vlan: +vlan
  })
=======
export async function create ({ pool, name, description, pif, mtu, vlan }) {
  if (pif) {
    pif = this.getObject(pif, 'PIF')
  }
  const params = {
    name,
    description,
    pif: pif && pif._xapiRef,
    mtu: mtu || '1500',
    vlan: vlan || '0'
  }
  return this.getXapi(pool).createNetwork(params)
>>>>>>> `network.create` instead of `createNetwork` for host and pool
}

create.params = {
  pool: { type: 'string' },
  name: { type: 'string' },
  description: { type: 'string', optional: true },
  pif: { type: 'string', optional: true },
<<<<<<< 91431201771f54434ebda173c26bda1c3df405d4
  mtu: { type: ['integer', 'string'], optional: true },
  vlan: { type: ['integer', 'string'], optional: true }
=======
  mtu: { type: 'string', optional: true },
  vlan: { type: 'string', optional: true }
>>>>>>> `network.create` instead of `createNetwork` for host and pool
}

create.resolve = {
  pool: ['pool', 'pool', 'administrate']
}
create.permission = 'admin'
<<<<<<< 91431201771f54434ebda173c26bda1c3df405d4
=======
exports.create = create
>>>>>>> `network.create` instead of `createNetwork` for host and pool
<commit_msg>Fixes.<commit_after>export async function create ({ pool, name, description, pif, mtu = 1500, vlan = 0 }) {
  return this.getXapi(pool).createNetwork({
    name,
    description,
    pifId: pif && this.getObject(pif, 'PIF')._xapiId,
    mtu: +mtu,
    vlan: +vlan
  })
}

create.params = {
  pool: { type: 'string' },
  name: { type: 'string' },
  description: { type: 'string', optional: true },
  pif: { type: 'string', optional: true },
  mtu: { type: ['integer', 'string'], optional: true },
  vlan: { type: ['integer', 'string'], optional: true }
}

create.resolve = {
  pool: ['pool', 'pool', 'administrate']
}
create.permission = 'admin'
<|endoftext|>


<commit_before>import 'colors';
import debug from 'debug';
import fs from 'fs-extra';
import glob from 'glob';
import path from 'path';
import pify from 'pify';
import packager from 'electron-packager';
import { hostArch } from 'electron-packager/targets';

import getForgeConfig from '../util/forge-config';
import runHook from '../util/hook';
import { warn } from '../util/messages';
import realOra, { fakeOra } from '../util/ora';
import packagerCompileHook from '../util/compile-hook';
import readPackageJSON from '../util/read-package-json';
import rebuildHook from '../util/rebuild';
import requireSearch from '../util/require-search';
import resolveDir from '../util/resolve-dir';

const d = debug('electron-forge:packager');

/**
 * @typedef {Object} PackageOptions
 * @property {string} [dir=process.cwd()] The path to the app to package
 * @property {boolean} [interactive=false] Whether to use sensible defaults or prompt the user visually
 * @property {string} [arch=process.arch] The target arch
 * @property {string} [platform=process.platform] The target platform.
 * @property {string} [outDir=`${dir}/out`] The path to the output directory for packaged apps
 */

/**
 * Resolves hooks if they are a path to a file (instead of a `Function`).
 */
function resolveHooks(hooks, dir) {
  if (hooks) {
    return hooks.map(hook => (typeof hook === 'string' ? requireSearch(dir, [hook]) : hook));
  }

  return [];
}

/**
 * Package an Electron application into an platform dependent format.
 *
 * @param {PackageOptions} providedOptions - Options for the Package method
 * @return {Promise} Will resolve when the package process is complete
 */
export default async (providedOptions = {}) => {
  // eslint-disable-next-line prefer-const, no-unused-vars
  let { dir, interactive, arch, platform } = Object.assign({
    dir: process.cwd(),
    interactive: false,
    arch: hostArch(),
    platform: process.platform,
  }, providedOptions);

  const ora = interactive ? realOra : fakeOra;

  const outDir = providedOptions.outDir || path.resolve(dir, 'out');
  let prepareSpinner = ora(`Preparing to Package Application for arch: ${(arch === 'all' ? 'ia32' : arch).cyan}`).start();
  let prepareCounter = 0;

  dir = await resolveDir(dir);
  if (!dir) {
    throw 'Failed to locate compilable Electron application';
  }

  const packageJSON = await readPackageJSON(dir);

  if (path.dirname(require.resolve(path.resolve(dir, packageJSON.main))) === dir) {
    console.error(`Entry point: ${packageJSON.main}`.red);
    throw 'The entry point to your application ("packageJSON.main") must be in a subfolder not in the top level directory';
  }

  const forgeConfig = await getForgeConfig(dir);
  let packagerSpinner;

  const packageOpts = Object.assign({
    asar: false,
    overwrite: true,
  }, forgeConfig.electronPackagerConfig, {
    afterCopy: [async (buildPath, electronVersion, pPlatform, pArch, done) => {
      if (packagerSpinner) {
        packagerSpinner.succeed();
        prepareCounter += 1;
        prepareSpinner = ora(`Preparing to Package Application for arch: ${(prepareCounter === 2 ? 'armv7l' : 'x64').cyan}`).start();
      }
      await fs.remove(path.resolve(buildPath, 'node_modules/electron-compile/test'));
      const bins = await pify(glob)(path.join(buildPath, '**/.bin/**/*'));
      for (const bin of bins) {
        await fs.remove(bin);
      }
      done();
    }, async (...args) => {
      prepareSpinner.succeed();
      await packagerCompileHook(dir, ...args);
    }, async (buildPath, electronVersion, pPlatform, pArch, done) => {
      const copiedPackageJSON = await readPackageJSON(buildPath);
      if (copiedPackageJSON.config && copiedPackageJSON.config.forge) {
        delete copiedPackageJSON.config.forge;
      }
      await fs.writeFile(path.resolve(buildPath, 'package.json'), JSON.stringify(copiedPackageJSON, null, 2));
      done();
    }].concat(resolveHooks(forgeConfig.electronPackagerConfig.afterCopy, dir)),
    afterExtract: resolveHooks(forgeConfig.electronPackagerConfig.afterExtract, dir),
    afterPrune: [async (buildPath, electronVersion, pPlatform, pArch, done) => {
      await rebuildHook(buildPath, electronVersion, pPlatform, pArch);
      packagerSpinner = ora('Packaging Application').start();
      done();
    }].concat(resolveHooks(forgeConfig.electronPackagerConfig.afterPrune, dir)),
    dir,
    arch,
    platform,
    out: outDir,
    electronVersion: packageJSON.devDependencies['electron-prebuilt-compile'],
  });
  packageOpts.quiet = true;
  if (typeof packageOpts.asar === 'object' && packageOpts.asar.unpack) {
    packagerSpinner.fail();
    throw new Error('electron-compile does not support asar.unpack yet.  Please use asar.unpackDir');
  }

  if (!packageJSON.version && !packageOpts.appVersion) {
    // eslint-disable-next-line max-len
    warn(interactive, "Please set 'version' or 'config.forge.electronPackagerConfig.appVersion' in your application's package.json so auto-updates work properly".yellow);
  }

  await runHook(forgeConfig, 'generateAssets');
  await runHook(forgeConfig, 'prePackage');

  d('packaging with options', packageOpts);

  await packager(packageOpts);

  await runHook(forgeConfig, 'postPackage');

  packagerSpinner.succeed();
};
<commit_msg>Rebuild modules regardless of whether prune is enabled<commit_after>import 'colors';
import debug from 'debug';
import fs from 'fs-extra';
import glob from 'glob';
import path from 'path';
import pify from 'pify';
import packager from 'electron-packager';
import { hostArch } from 'electron-packager/targets';

import getForgeConfig from '../util/forge-config';
import runHook from '../util/hook';
import { warn } from '../util/messages';
import realOra, { fakeOra } from '../util/ora';
import packagerCompileHook from '../util/compile-hook';
import readPackageJSON from '../util/read-package-json';
import rebuildHook from '../util/rebuild';
import requireSearch from '../util/require-search';
import resolveDir from '../util/resolve-dir';

const d = debug('electron-forge:packager');

/**
 * @typedef {Object} PackageOptions
 * @property {string} [dir=process.cwd()] The path to the app to package
 * @property {boolean} [interactive=false] Whether to use sensible defaults or prompt the user visually
 * @property {string} [arch=process.arch] The target arch
 * @property {string} [platform=process.platform] The target platform.
 * @property {string} [outDir=`${dir}/out`] The path to the output directory for packaged apps
 */

/**
 * Resolves hooks if they are a path to a file (instead of a `Function`).
 */
function resolveHooks(hooks, dir) {
  if (hooks) {
    return hooks.map(hook => (typeof hook === 'string' ? requireSearch(dir, [hook]) : hook));
  }

  return [];
}

/**
 * Package an Electron application into an platform dependent format.
 *
 * @param {PackageOptions} providedOptions - Options for the Package method
 * @return {Promise} Will resolve when the package process is complete
 */
export default async (providedOptions = {}) => {
  // eslint-disable-next-line prefer-const, no-unused-vars
  let { dir, interactive, arch, platform } = Object.assign({
    dir: process.cwd(),
    interactive: false,
    arch: hostArch(),
    platform: process.platform,
  }, providedOptions);

  const ora = interactive ? realOra : fakeOra;

  const outDir = providedOptions.outDir || path.resolve(dir, 'out');
  let prepareSpinner = ora(`Preparing to Package Application for arch: ${(arch === 'all' ? 'ia32' : arch).cyan}`).start();
  let prepareCounter = 0;

  dir = await resolveDir(dir);
  if (!dir) {
    throw 'Failed to locate compilable Electron application';
  }

  const packageJSON = await readPackageJSON(dir);

  if (path.dirname(require.resolve(path.resolve(dir, packageJSON.main))) === dir) {
    console.error(`Entry point: ${packageJSON.main}`.red);
    throw 'The entry point to your application ("packageJSON.main") must be in a subfolder not in the top level directory';
  }

  const forgeConfig = await getForgeConfig(dir);
  let packagerSpinner;

  const pruneEnabled = !('prune' in forgeConfig.electronPackagerConfig) || forgeConfig.electronPackagerConfig.prune;

  const rebuildHookFn = async (buildPath, electronVersion, pPlatform, pArch, done) => {
    await rebuildHook(buildPath, electronVersion, pPlatform, pArch);
    packagerSpinner = ora('Packaging Application').start();
    done();
  };

  const afterCopyHooks = [
    async (buildPath, electronVersion, pPlatform, pArch, done) => {
      if (packagerSpinner) {
        packagerSpinner.succeed();
        prepareCounter += 1;
        prepareSpinner = ora(`Preparing to Package Application for arch: ${(prepareCounter === 2 ? 'armv7l' : 'x64').cyan}`).start();
      }
      await fs.remove(path.resolve(buildPath, 'node_modules/electron-compile/test'));
      const bins = await pify(glob)(path.join(buildPath, '**/.bin/**/*'));
      for (const bin of bins) {
        await fs.remove(bin);
      }
      done();
    }, async (...args) => {
      prepareSpinner.succeed();
      await packagerCompileHook(dir, ...args);
    },
  ];

  if (!pruneEnabled) {
    afterCopyHooks.push(rebuildHookFn);
  }

  afterCopyHooks.push(async (buildPath, electronVersion, pPlatform, pArch, done) => {
    const copiedPackageJSON = await readPackageJSON(buildPath);
    if (copiedPackageJSON.config && copiedPackageJSON.config.forge) {
      delete copiedPackageJSON.config.forge;
    }
    await fs.writeFile(path.resolve(buildPath, 'package.json'), JSON.stringify(copiedPackageJSON, null, 2));
    done();
  });

  afterCopyHooks.concat(resolveHooks(forgeConfig.electronPackagerConfig.afterCopy, dir));

  const afterPruneHooks = [];

  if (pruneEnabled) {
    afterPruneHooks.push(rebuildHookFn);
    afterPruneHooks.concat(resolveHooks(forgeConfig.electronPackagerConfig.afterPrune, dir));
  }

  const packageOpts = Object.assign({
    asar: false,
    overwrite: true,
  }, forgeConfig.electronPackagerConfig, {
    afterCopy: afterCopyHooks,
    afterExtract: resolveHooks(forgeConfig.electronPackagerConfig.afterExtract, dir),
    afterPrune: afterPruneHooks,
    dir,
    arch,
    platform,
    out: outDir,
    electronVersion: packageJSON.devDependencies['electron-prebuilt-compile'],
  });
  packageOpts.quiet = true;
  if (typeof packageOpts.asar === 'object' && packageOpts.asar.unpack) {
    packagerSpinner.fail();
    throw new Error('electron-compile does not support asar.unpack yet.  Please use asar.unpackDir');
  }

  if (!packageJSON.version && !packageOpts.appVersion) {
    // eslint-disable-next-line max-len
    warn(interactive, "Please set 'version' or 'config.forge.electronPackagerConfig.appVersion' in your application's package.json so auto-updates work properly".yellow);
  }

  await runHook(forgeConfig, 'generateAssets');
  await runHook(forgeConfig, 'prePackage');

  d('packaging with options', packageOpts);

  await packager(packageOpts);

  await runHook(forgeConfig, 'postPackage');

  packagerSpinner.succeed();
};
<|endoftext|>


<commit_before>// $Revision$

var Ensembl = new Base();

Ensembl.extend({
  constructor: null,

  initialize: function () {
    var hints       = this.cookie.get('ENSEMBL_HINTS');
    var imagePanels = $('.image_panel');

    if (!window.name) {
      window.name = 'ensembl_' + new Date().getTime() + '_' + Math.floor(Math.random() * 10000);
    }

    this.locationURL     = typeof window.history.pushState === 'function' ? 'search' : 'hash';
    this.hashParamRegex  = '([#?;&]__PARAM__=)[^;&]+((;&)?)';
    this.locationMatch   = new RegExp(/[#?;&]r=([^;&]+)/);
    this.locationReplace = new RegExp(this.hashParamRegex.replace('__PARAM__', 'r'));
    this.width           = parseInt(this.cookie.get('ENSEMBL_WIDTH'), 10) || this.setWidth(undefined, 1);
    this.dynamicWidth    = !!this.cookie.get('DYNAMIC_WIDTH');
    this.hideHints       = {};
    this.initialPanels   = $('.initial_panel');
    this.minWidthEl      = $('#min_width_container');
    this.images          = { total: imagePanels.length, last: imagePanels.last()[0] }; // Store image panel details for highlighting

    if (this.dynamicWidth && !window.name.match(/^popup_/)) {
      var width = this.imageWidth();

      if (this.width !== width) {
        this.width = width;
        this.cookie.set('ENSEMBL_WIDTH', width);
      }
    }

    if (hints) {
      $.each(hints.split(/:/), function () {
        Ensembl.hideHints[this] = 1;
      });
    }

    imagePanels = null;

    this.setCoreParams();

    this.LayoutManager.initialize();

    // If there's a hash in the URL with a new location in it, and the browser supports history API,
    // update window.location.search to contain the new location.
    // Also change all ajax_load values, so panels are loaded matching the new location.
    var removeHash = this.locationURL === 'hash' ? '' : window.location.hash.match('=');
    var hashChange = removeHash ? window.location.hash.match(this.locationMatch) : false;

    $('input.ajax_load').val(function (i, val) { return Ensembl.urlFromHash(val); });

    if (removeHash) {
      window.history.replaceState({}, '', Ensembl.urlFromHash(window.location.search));
    }

    this.PanelManager.initialize();

    if (hashChange) {
      this.EventManager.trigger('hashChange', hashChange[1]); // update links and HTML for the new location
    }
  },

  cookie: {
    set: function (name, value, expiry, unescaped) {
      var cookie = [
        unescaped === true ? (name + '=' + (value || '')) : (escape(name) + '=' + escape(value || '')),
        '; expires=',
        ((expiry === -1 || value === '') ? 'Thu, 01 Jan 1970' : 'Tue, 19 Jan 2038'),
        ' 00:00:00 GMT; path=/'
      ].join('');

      document.cookie = cookie;

      return value;
    },

    get: function (name, unescaped) {
      var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + (unescaped === true ? name : escape(name)) + '=([^;\\s]*)'));
      return cookie ? unescape(cookie[2]) : '';
    }
  },

  imageWidth: function () {
    return Math.floor(($(window).width() - 240) / 100) * 100;
  },

  setWidth: function (w, changed) {
    var numeric = !isNaN(w);

    w = numeric ? w : this.imageWidth();

    this.width = w < 500 ? 500 : w;

    if (changed) {
      this.cookie.set('ENSEMBL_WIDTH', this.width);
      this.cookie.set('DYNAMIC_WIDTH', numeric ? '' : 1);
      this.dynamicWidth = !numeric;
    }

    return this.width;
  },

  setCoreParams: function () {
    var regex       = '[#?;&]%s=([^;&]+)';
    var url         = window.location.search;
    var hash        = window.location.hash;
    var locationURL = this.locationURL === 'hash' ? hash : url;
    var lastR       = this.coreParams ? this.coreParams.r : '';
    var match, m, i, r;

    this.hash          = hash;
    this.coreParams    = {};
    this.initialR      = $('input[name=r]', '#core_params').val();
    this.location      = { length: 100000 };
    this.speciesPath   = $('#species_path').val() || '';
    this.speciesCommon = $('#species_common_name').val() || '';
    this.species       = this.speciesPath.split('/').pop();
    this.multiSpecies  = {};

    $('input', '#core_params').each(function () {
      var hashMatch = locationURL.match(regex.replace('%s', this.name));
      Ensembl.coreParams[this.name] = hashMatch ? unescape(hashMatch[1]) : this.value;
    });

    this.lastR = lastR || (hash ? this.coreParams.r : this.initialR);

    match = this.coreParams.r ? this.coreParams.r.match(/(.+):(\d+)-(\d+)/) : false;

    if (match) {
      this.location = { name: match[1], start: parseInt(match[2], 10), end: parseInt(match[3], 10) };
      this.location.length = this.location.end - this.location.start + 1;

      if (this.location.length > 1000000) {
        this.location.length = 1000000;
      }
    }

    match = url.match(/s\d+=([^;&]+)/g);

    if (match) {
      $.each(match, function () {
        m = this.split('=');
        i = m[0].substr(1);

        Ensembl.multiSpecies[i] = {};

        $.each(['r', 'g', 's'], function (j, param) {
          Ensembl.multiSpecies[i][param] = url.match(regex.replace('%s', param + i));

          if (Ensembl.multiSpecies[i][param]) {
            Ensembl.multiSpecies[i][param] = unescape(Ensembl.multiSpecies[i][param][1]);
          }

          if (param === 'r' && Ensembl.multiSpecies[i].r) {
            r = Ensembl.multiSpecies[i].r.match(/(.+):(\d+)-(\d+)/);

            Ensembl.multiSpecies[i].location = { name: r[1], start: parseInt(r[2], 10), end: parseInt(r[3], 10) };
          }
        });
      });
    }
  },

  cleanURL: function (url) {
    return unescape(url.replace(/&/g, ';').replace(/#.*$/g, '').replace(/([?;])time=[^;]+;?/g, '$1').replace(/[?;]$/g, ''));
  },

  // Remove the old time stamp from a URL and replace with a new one
  replaceTimestamp: function (url) {
    var d    = new Date();
    var time = d.getTime() + d.getMilliseconds() / 1000;

    url  = this.cleanURL(url);
    url += (url.match(/\?/) ? ';' : '?') + 'time=' + time;

    return url;
  },

  redirect: function (url) {
    for (var p in this.PanelManager.panels) {
      this.PanelManager.panels[p].destructor('cleanup');
    }

    url = url || this.replaceTimestamp(window.location.href);

    if (window.location.hash) {
      url = this.urlFromHash(url);
    }

    window.location = url;
  },

  updateLocation: function (r) {
    this.historyReady = true;

    this.updateURL({ r: r });

    if (this.locationURL === 'search') {
      this.setCoreParams();
      this.EventManager.trigger('hashChange', r);
    }
  },

  updateURL: function (params, inputURL) {
    var url = inputURL ? (inputURL + (inputURL.match(/\?/) ? '' : '?')) : window.location[this.locationURL];

    for (var i in params) {
      if (url.match(i + '=')) {
        url = url.replace(new RegExp(this.hashParamRegex.replace('__PARAM__', i)), '$1' + params[i] + '$2');
      } else {
        url += (url ? ';' : '') + i + '=' + params[i];
      }
    }

    if (inputURL) {
      return url;
    }

    if (this.locationURL === 'hash') {
      window.location.hash = url;
    } else {
      window.history.pushState({}, '', url);
    }
  },

  urlFromHash: function (url, paramOnly) {
    var location = window.location[this.locationURL].replace(/^#/, '?') + ';';
    var match    = location.match(this.locationMatch);
    var r        = match ? match[1] : this.initialR || '';

    if (paramOnly) {
      return r;
    }

    var hash = r && this.locationURL === 'search' ? { r: r } : {};

    $.each(window.location.hash.replace('#', '').split(/[;&]/), function () {
      var param = this.split('=');

      if (param.length === 2) {
        hash[param[0]] = param[1];
      }
    });

    return this.updateURL(hash, url);
  },

  thousandify: function (str) {
    str += '';

    var rgx = /(\d+)(\d{3})/;
    var x   = str.split('.');
    var x1  = x[0];
    var x2  = x.length > 1 ? '.' + x[1] : '';

    while (rgx.test(x1)) {
      x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }

    return x1 + x2;
  }
});

window.Ensembl = Ensembl; // Make Ensembl namespace available on window - needed for upload iframes because the minifier will compress the variable name Ensembl
<commit_msg>parse body class add make Ensembl.browser from it<commit_after>// $Revision$

var Ensembl = new Base();

Ensembl.extend({
  constructor: null,

  initialize: function () {
    var hints       = this.cookie.get('ENSEMBL_HINTS');
    var imagePanels = $('.image_panel');
    var bodyClass   = $('body')[0].className.split(' ');

    if (!window.name) {
      window.name = 'ensembl_' + new Date().getTime() + '_' + Math.floor(Math.random() * 10000);
    }

    this.browser         = {};
    this.locationURL     = typeof window.history.pushState === 'function' ? 'search' : 'hash';
    this.hashParamRegex  = '([#?;&]__PARAM__=)[^;&]+((;&)?)';
    this.locationMatch   = new RegExp(/[#?;&]r=([^;&]+)/);
    this.locationReplace = new RegExp(this.hashParamRegex.replace('__PARAM__', 'r'));
    this.width           = parseInt(this.cookie.get('ENSEMBL_WIDTH'), 10) || this.setWidth(undefined, 1);
    this.dynamicWidth    = !!this.cookie.get('DYNAMIC_WIDTH');
    this.hideHints       = {};
    this.initialPanels   = $('.initial_panel');
    this.minWidthEl      = $('#min_width_container');
    this.images          = { total: imagePanels.length, last: imagePanels.last()[0] }; // Store image panel details for highlighting

    for (var i in bodyClass) {
      if (bodyClass[i]) {
        this.browser[bodyClass[i]] = true;
      }
    }

    if (this.dynamicWidth && !window.name.match(/^popup_/)) {
      var width = this.imageWidth();

      if (this.width !== width) {
        this.width = width;
        this.cookie.set('ENSEMBL_WIDTH', width);
      }
    }

    if (hints) {
      $.each(hints.split(/:/), function () {
        Ensembl.hideHints[this] = 1;
      });
    }

    imagePanels = null;

    this.setCoreParams();

    this.LayoutManager.initialize();

    // If there's a hash in the URL with a new location in it, and the browser supports history API,
    // update window.location.search to contain the new location.
    // Also change all ajax_load values, so panels are loaded matching the new location.
    var removeHash = this.locationURL === 'hash' ? '' : window.location.hash.match('=');
    var hashChange = removeHash ? window.location.hash.match(this.locationMatch) : false;

    $('input.ajax_load').val(function (i, val) { return Ensembl.urlFromHash(val); });

    if (removeHash) {
      window.history.replaceState({}, '', Ensembl.urlFromHash(window.location.search));
    }

    this.PanelManager.initialize();

    if (hashChange) {
      this.EventManager.trigger('hashChange', hashChange[1]); // update links and HTML for the new location
    }
  },

  cookie: {
    set: function (name, value, expiry, unescaped) {
      var cookie = [
        unescaped === true ? (name + '=' + (value || '')) : (escape(name) + '=' + escape(value || '')),
        '; expires=',
        ((expiry === -1 || value === '') ? 'Thu, 01 Jan 1970' : 'Tue, 19 Jan 2038'),
        ' 00:00:00 GMT; path=/'
      ].join('');

      document.cookie = cookie;

      return value;
    },

    get: function (name, unescaped) {
      var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + (unescaped === true ? name : escape(name)) + '=([^;\\s]*)'));
      return cookie ? unescape(cookie[2]) : '';
    }
  },

  imageWidth: function () {
    return Math.floor(($(window).width() - 240) / 100) * 100;
  },

  setWidth: function (w, changed) {
    var numeric = !isNaN(w);

    w = numeric ? w : this.imageWidth();

    this.width = w < 500 ? 500 : w;

    if (changed) {
      this.cookie.set('ENSEMBL_WIDTH', this.width);
      this.cookie.set('DYNAMIC_WIDTH', numeric ? '' : 1);
      this.dynamicWidth = !numeric;
    }

    return this.width;
  },

  setCoreParams: function () {
    var regex       = '[#?;&]%s=([^;&]+)';
    var url         = window.location.search;
    var hash        = window.location.hash;
    var locationURL = this.locationURL === 'hash' ? hash : url;
    var lastR       = this.coreParams ? this.coreParams.r : '';
    var match, m, i, r;

    this.hash          = hash;
    this.coreParams    = {};
    this.initialR      = $('input[name=r]', '#core_params').val();
    this.location      = { length: 100000 };
    this.speciesPath   = $('#species_path').val() || '';
    this.speciesCommon = $('#species_common_name').val() || '';
    this.species       = this.speciesPath.split('/').pop();
    this.multiSpecies  = {};

    $('input', '#core_params').each(function () {
      var hashMatch = locationURL.match(regex.replace('%s', this.name));
      Ensembl.coreParams[this.name] = hashMatch ? unescape(hashMatch[1]) : this.value;
    });

    this.lastR = lastR || (hash ? this.coreParams.r : this.initialR);

    match = this.coreParams.r ? this.coreParams.r.match(/(.+):(\d+)-(\d+)/) : false;

    if (match) {
      this.location = { name: match[1], start: parseInt(match[2], 10), end: parseInt(match[3], 10) };
      this.location.length = this.location.end - this.location.start + 1;

      if (this.location.length > 1000000) {
        this.location.length = 1000000;
      }
    }

    match = url.match(/s\d+=([^;&]+)/g);

    if (match) {
      $.each(match, function () {
        m = this.split('=');
        i = m[0].substr(1);

        Ensembl.multiSpecies[i] = {};

        $.each(['r', 'g', 's'], function (j, param) {
          Ensembl.multiSpecies[i][param] = url.match(regex.replace('%s', param + i));

          if (Ensembl.multiSpecies[i][param]) {
            Ensembl.multiSpecies[i][param] = unescape(Ensembl.multiSpecies[i][param][1]);
          }

          if (param === 'r' && Ensembl.multiSpecies[i].r) {
            r = Ensembl.multiSpecies[i].r.match(/(.+):(\d+)-(\d+)/);

            Ensembl.multiSpecies[i].location = { name: r[1], start: parseInt(r[2], 10), end: parseInt(r[3], 10) };
          }
        });
      });
    }
  },

  cleanURL: function (url) {
    return unescape(url.replace(/&/g, ';').replace(/#.*$/g, '').replace(/([?;])time=[^;]+;?/g, '$1').replace(/[?;]$/g, ''));
  },

  // Remove the old time stamp from a URL and replace with a new one
  replaceTimestamp: function (url) {
    var d    = new Date();
    var time = d.getTime() + d.getMilliseconds() / 1000;

    url  = this.cleanURL(url);
    url += (url.match(/\?/) ? ';' : '?') + 'time=' + time;

    return url;
  },

  redirect: function (url) {
    for (var p in this.PanelManager.panels) {
      this.PanelManager.panels[p].destructor('cleanup');
    }

    url = url || this.replaceTimestamp(window.location.href);

    if (window.location.hash) {
      url = this.urlFromHash(url);
    }

    window.location = url;
  },

  updateLocation: function (r) {
    this.historyReady = true;

    this.updateURL({ r: r });

    if (this.locationURL === 'search') {
      this.setCoreParams();
      this.EventManager.trigger('hashChange', r);
    }
  },

  updateURL: function (params, inputURL) {
    var url = inputURL ? (inputURL + (inputURL.match(/\?/) ? '' : '?')) : window.location[this.locationURL];

    for (var i in params) {
      if (url.match(i + '=')) {
        url = url.replace(new RegExp(this.hashParamRegex.replace('__PARAM__', i)), '$1' + params[i] + '$2');
      } else {
        url += (url ? ';' : '') + i + '=' + params[i];
      }
    }

    if (inputURL) {
      return url;
    }

    if (this.locationURL === 'hash') {
      window.location.hash = url;
    } else {
      window.history.pushState({}, '', url);
    }
  },

  urlFromHash: function (url, paramOnly) {
    var location = window.location[this.locationURL].replace(/^#/, '?') + ';';
    var match    = location.match(this.locationMatch);
    var r        = match ? match[1] : this.initialR || '';

    if (paramOnly) {
      return r;
    }

    var hash = r && this.locationURL === 'search' ? { r: r } : {};

    $.each(window.location.hash.replace('#', '').split(/[;&]/), function () {
      var param = this.split('=');

      if (param.length === 2) {
        hash[param[0]] = param[1];
      }
    });

    return this.updateURL(hash, url);
  },

  thousandify: function (str) {
    str += '';

    var rgx = /(\d+)(\d{3})/;
    var x   = str.split('.');
    var x1  = x[0];
    var x2  = x.length > 1 ? '.' + x[1] : '';

    while (rgx.test(x1)) {
      x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }

    return x1 + x2;
  }
});

window.Ensembl = Ensembl; // Make Ensembl namespace available on window - needed for upload iframes because the minifier will compress the variable name Ensembl
<|endoftext|>


<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

/**
 * @name ToolEvent
 *
 * @class ToolEvent The ToolEvent object is received by the {@link Tool}'s mouse
 * event handlers {@link Tool#onMouseDown}, {@link Tool#onMouseDrag},
 * {@link Tool#onMouseMove} and {@link Tool#onMouseUp}. The ToolEvent
 * object is the only parameter passed to these functions and contains
 * information about the mouse event.
 *
 * @extends Event
 */
var ToolEvent = this.ToolEvent = Event.extend(/** @lends ToolEvent# */{
	initialize: function(tool, type, event) {
		this.tool = tool;
		this.type = type;
		this.event = event;
	},

	/**
	 * Convenience method to allow local overrides of point values.
	 * See application below.
	 */
	_choosePoint: function(point, toolPoint) {
		return point ? point : toolPoint ? toolPoint.clone() : null;
	},

	/**
	 * The type of tool event.
	 *
	 * @name ToolEvent#type
	 * @type String('mousedown', 'mouseup', 'mousemove', 'mousedrag')
	 */

	/**
	 * The position of the mouse in project coordinates when the event was
	 * fired.
	 *
	 * @example
	 * function onMouseDrag(event) {
	 * 	// the position of the mouse when it is dragged
	 * 	console.log(event.point);
	 * }
	 *
	 * function onMouseUp(event) {
	 * 	// the position of the mouse when it is released
	 * 	console.log(event.point);
	 * }
	 *
	 * @type Point
	 * @bean
	 */
	getPoint: function() {
		return this._choosePoint(this._point, this.tool._point);
	},

	setPoint: function(point) {
		this._point = point;
	},

	/**
	 * The position of the mouse in project coordinates when the previous
	 * event was fired.
	 *
	 * @type Point
	 * @bean
	 */
	getLastPoint: function() {
		return this._choosePoint(this._lastPoint, this.tool._lastPoint);
	},

	setLastPoint: function(lastPoint) {
		this._lastPoint = lastPoint;
	},

	/**
	 * The position of the mouse in project coordinates when the mouse button
	 * was last clicked.
	 *
	 * @type Point
	 * @bean
	 */
	getDownPoint: function() {
		return this._choosePoint(this._downPoint, this.tool._downPoint);
	},

	setDownPoint: function(downPoint) {
		this._downPoint = downPoint;
	},

	/**
	 * The point in the middle between {@link #lastPoint} and
	 * {@link #point}. This is a useful position to use when creating
	 * artwork based on the moving direction of the mouse, as returned by
	 * {@link #delta}.
	 *
	 * @type Point
	 * @bean
	 */
	getMiddlePoint: function() {
		// For explanations, see getDelta()
		if (!this._middlePoint && this.tool._lastPoint) {
			// (point + lastPoint) / 2
			return this.tool._point.add(this.tool._lastPoint).divide(2);
		}
		return this.middlePoint;
	},

	setMiddlePoint: function(middlePoint) {
		this._middlePoint = middlePoint;
	},

	/**
	 * The difference between the current position and the last position of the
	 * mouse when the event was fired. In case of the mouseup event, the
	 * difference to the mousedown position is returned.
	 *
	 * @type Point
	 * @bean
	 */
	getDelta: function() {
		// Do not put the calculated delta into delta, since this only reserved
		// for overriding event.delta.
		// Instead, keep calculating the delta each time, so the result can be
		// directly modified by the script without changing the internal values.
		// We could cache this and use clone, but this is almost as fast...
		return !this._delta && this.tool._lastPoint
		 		? this.tool._point.subtract(this.tool._lastPoint)
				: this._delta;
	},

	setDelta: function(delta) {
		this._delta = delta;
	},

	/**
	 * The number of times the mouse event was fired.
	 *
	 * @type Number
	 * @bean
	 */
	getCount: function() {
		// Return downCount for both mouse down and up, since
		// the count is the same.
		return /^mouse(down|up)$/.test(this.type)
				? this.tool._downCount
				: this.tool._count;
	},

	setCount: function(count) {
		this.tool[/^mouse(down|up)$/.test(this.type) ? 'downCount' : 'count']
			= count;
	},

	/**
	 * The item at the position of the mouse (if any).
	 *
	 * If the item is contained within one or more {@link Group} or
	 * {@link CompoundPath} items, the most top level group or compound path
	 * that it is contained within is returned.
	 *
	 * @type Item
	 * @bean
	 */
	getItem: function() {
		if (!this._item) {
			var result = this.tool._scope.project.hitTest(this.getPoint());
			if (result) {
				var item = result.item,
					// Find group parent
					parent = item.getParent();
				while ((parent instanceof Group && !(parent instanceof Layer))
						|| parent instanceof CompoundPath) {
					item = parent;
					parent = parent.getParent();
				}
				this._item = item;
			}
		}
		return this._item;
	},

	setItem: function(item) {
		this._item = item;
	},

	/**
	 * @return {String} A string representation of the tool event.
	 */
	toString: function() {
		return '{ type: ' + this.type
				+ ', point: ' + this.getPoint()
				+ ', count: ' + this.getCount()
				+ ', modifiers: ' + this.getModifiers()
				+ ' }';
	}
});
<commit_msg>ToolEvent#getItem: replace getter with direct access to internal variable.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

/**
 * @name ToolEvent
 *
 * @class ToolEvent The ToolEvent object is received by the {@link Tool}'s mouse
 * event handlers {@link Tool#onMouseDown}, {@link Tool#onMouseDrag},
 * {@link Tool#onMouseMove} and {@link Tool#onMouseUp}. The ToolEvent
 * object is the only parameter passed to these functions and contains
 * information about the mouse event.
 *
 * @extends Event
 */
var ToolEvent = this.ToolEvent = Event.extend(/** @lends ToolEvent# */{
	initialize: function(tool, type, event) {
		this.tool = tool;
		this.type = type;
		this.event = event;
	},

	/**
	 * Convenience method to allow local overrides of point values.
	 * See application below.
	 */
	_choosePoint: function(point, toolPoint) {
		return point ? point : toolPoint ? toolPoint.clone() : null;
	},

	/**
	 * The type of tool event.
	 *
	 * @name ToolEvent#type
	 * @type String('mousedown', 'mouseup', 'mousemove', 'mousedrag')
	 */

	/**
	 * The position of the mouse in project coordinates when the event was
	 * fired.
	 *
	 * @example
	 * function onMouseDrag(event) {
	 * 	// the position of the mouse when it is dragged
	 * 	console.log(event.point);
	 * }
	 *
	 * function onMouseUp(event) {
	 * 	// the position of the mouse when it is released
	 * 	console.log(event.point);
	 * }
	 *
	 * @type Point
	 * @bean
	 */
	getPoint: function() {
		return this._choosePoint(this._point, this.tool._point);
	},

	setPoint: function(point) {
		this._point = point;
	},

	/**
	 * The position of the mouse in project coordinates when the previous
	 * event was fired.
	 *
	 * @type Point
	 * @bean
	 */
	getLastPoint: function() {
		return this._choosePoint(this._lastPoint, this.tool._lastPoint);
	},

	setLastPoint: function(lastPoint) {
		this._lastPoint = lastPoint;
	},

	/**
	 * The position of the mouse in project coordinates when the mouse button
	 * was last clicked.
	 *
	 * @type Point
	 * @bean
	 */
	getDownPoint: function() {
		return this._choosePoint(this._downPoint, this.tool._downPoint);
	},

	setDownPoint: function(downPoint) {
		this._downPoint = downPoint;
	},

	/**
	 * The point in the middle between {@link #lastPoint} and
	 * {@link #point}. This is a useful position to use when creating
	 * artwork based on the moving direction of the mouse, as returned by
	 * {@link #delta}.
	 *
	 * @type Point
	 * @bean
	 */
	getMiddlePoint: function() {
		// For explanations, see getDelta()
		if (!this._middlePoint && this.tool._lastPoint) {
			// (point + lastPoint) / 2
			return this.tool._point.add(this.tool._lastPoint).divide(2);
		}
		return this.middlePoint;
	},

	setMiddlePoint: function(middlePoint) {
		this._middlePoint = middlePoint;
	},

	/**
	 * The difference between the current position and the last position of the
	 * mouse when the event was fired. In case of the mouseup event, the
	 * difference to the mousedown position is returned.
	 *
	 * @type Point
	 * @bean
	 */
	getDelta: function() {
		// Do not put the calculated delta into delta, since this only reserved
		// for overriding event.delta.
		// Instead, keep calculating the delta each time, so the result can be
		// directly modified by the script without changing the internal values.
		// We could cache this and use clone, but this is almost as fast...
		return !this._delta && this.tool._lastPoint
		 		? this.tool._point.subtract(this.tool._lastPoint)
				: this._delta;
	},

	setDelta: function(delta) {
		this._delta = delta;
	},

	/**
	 * The number of times the mouse event was fired.
	 *
	 * @type Number
	 * @bean
	 */
	getCount: function() {
		// Return downCount for both mouse down and up, since
		// the count is the same.
		return /^mouse(down|up)$/.test(this.type)
				? this.tool._downCount
				: this.tool._count;
	},

	setCount: function(count) {
		this.tool[/^mouse(down|up)$/.test(this.type) ? 'downCount' : 'count']
			= count;
	},

	/**
	 * The item at the position of the mouse (if any).
	 *
	 * If the item is contained within one or more {@link Group} or
	 * {@link CompoundPath} items, the most top level group or compound path
	 * that it is contained within is returned.
	 *
	 * @type Item
	 * @bean
	 */
	getItem: function() {
		if (!this._item) {
			var result = this.tool._scope.project.hitTest(this.getPoint());
			if (result) {
				var item = result.item,
					// Find group parent
					parent = item.getParent();
				while ((parent instanceof Group && !(parent instanceof Layer))
						|| parent instanceof CompoundPath) {
					item = parent;
					parent = parent._parent;
				}
				this._item = item;
			}
		}
		return this._item;
	},

	setItem: function(item) {
		this._item = item;
	},

	/**
	 * @return {String} A string representation of the tool event.
	 */
	toString: function() {
		return '{ type: ' + this.type
				+ ', point: ' + this.getPoint()
				+ ', count: ' + this.getCount()
				+ ', modifiers: ' + this.getModifiers()
				+ ' }';
	}
});
<|endoftext|>


<commit_before>import applicationConfig from './applicationConfig';

class Server {
    constructor() {
        let config = applicationConfig;
        this.facebookServer = config.getFacebookResource();
        this.propertiesService = config.getPropertiesService();
    }

    startServer() {
        let facebookAccessToken = this.propertiesService.get('facebook.access.token');
        let facebookVerifyToken = this.propertiesService.get('facebook.verify.token');
        this.facebookServer.startResource(facebookAccessToken, facebookVerifyToken);
        console.log('Application started!');
    }
}

const server = new Server();
server.startServer();<commit_msg>[Tim] - test deployement<commit_after>import applicationConfig from './applicationConfig';

class Server {
    constructor() {
        let config = applicationConfig;
        this.facebookServer = config.getFacebookResource();
        this.propertiesService = config.getPropertiesService();
    }

    startServer() {
        let facebookAccessToken = this.propertiesService.get('facebook.access.token');
        let facebookVerifyToken = this.propertiesService.get('facebook.verify.token');
        this.facebookServer.startResource(facebookAccessToken, facebookVerifyToken);
        console.log('Application started!!');
    }
}

const server = new Server();
server.startServer();<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 * Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
 */

'use strict';

const NodePath = require('./node-path');

/**
 * Does an actual AST traversal, using visitor pattern,
 * and calling set of callbacks.
 *
 * Based on https://github.com/olov/ast-traverse
 *
 * Expects AST in Mozilla Parser API: nodes which are supposed to be
 * handled should have `type` property.
 *
 * @param Object root - a root node to start traversal from.
 *
 * @param Object options - an object with set of callbacks:
 *
 *   - `pre(node, parent, prop, index)` - a hook called on node enter
 *   - `post`(node, parent, prop, index) - a hook called on node exit
 *   - `skipProperty(prop)` - a predicated whether a property should be skipped
 */
function astTraverse(root, options = {}) {
  const pre = options.pre;
  const post = options.post;
  const skipProperty = options.skipProperty;

  function visit(node, parent, prop, idx) {
    if (!node || typeof node.type !== 'string') {
      return;
    }

    let res = undefined;
    if (pre) {
      res = pre(node, parent, prop, idx);
    }

    if (res !== false) {
      for (let prop in node) if (node.hasOwnProperty(prop)) {
        if (skipProperty ? skipProperty(prop, node) : prop[0] === '$') {
          continue;
        }

        const child = node[prop];

        // Collection node.
        //
        // NOTE: a node (or several nodes) can be removed or inserted
        // during traversal.
        //
        // Current traversing index is stored on top of the
        // `NodePath.traversingIndexStack`. The stack is used to support
        // recursive nature of the traversal.
        //
        // In this case `NodePath.traversingIndex` (which we use here) is
        // updated in the NodePath remove/insert methods.
        //
        if (Array.isArray(child)) {
          let index = 0;
          NodePath.traversingIndexStack.push(index);
          while (index < child.length) {
            visit(
              child[index],
              node,
              prop,
              index
            );
            index = NodePath.updateTraversingIndex(+1);
          }
          NodePath.traversingIndexStack.pop();
        }

        // Simple node.
        else {
          visit(child, node, prop);
        }
      }
    }

    if (post) {
      post(node, parent, prop, idx);
    }
  }

  visit(root, null);
}

module.exports = {
  /**
   * Traverses an AST.
   *
   * @param Object ast - an AST node
   *
   * @param Array<Object>|Object handlers:
   *
   *   an object (or an array of objects)
   *   containing handler function per node. In case of an array of
   *   handlers, they are applied in order. A handler may return a
   *   transformed node (or a different type).
   *
   * @param Object options:
   *
   *   a config object, specifying traversal options:
   *
   *   `asNodes`: boolean - whether handlers should receives raw AST nodes
   *   (false by default), instead of a `NodePath` wrapper. Note, by default
   *   `NodePath` wrapper provides a set of convenient method to manipulate
   *   a traversing AST, and also has access to all parents list. A raw
   *   nodes traversal should be used in rare cases, when no `NodePath`
   *   features are needed.
   *
   * Special hooks:
   *
   *   - `shouldRun(ast)` - a predicate determining whether the handler
   *                        should be applied.
   *
   * NOTE: Multiple handlers are used as an optimization of applying all of
   * them in one AST traversal pass.
   */
  traverse(ast, handlers, options = {asNodes: false}) {
    if (!Array.isArray(handlers)) {
      handlers = [handlers];
    }

    // Filter out handlers by result of `shouldRun`, if the method presents.
    handlers = handlers.filter(handler => {
      if (typeof handler.shouldRun !== 'function') {
        return true;
      }
      return handler.shouldRun(ast);
    });

    NodePath.initRegistry();

    // Allow handlers to initializer themselves.
    handlers.forEach(handler => {
      if (typeof handler.init === 'function') {
        handler.init();
      }
    });

    // Handle actual nodes.
    astTraverse(ast, {

      /**
       * Handler on node enter.
       */
      pre(node, parent, prop, index) {
        let parentPath;
        let nodePath;

        if (!options.asNodes) {
          parentPath = NodePath.getForNode(parent);

          nodePath = NodePath.getForNode(
            node,
            parentPath,
            prop,
            index
          );
        }

        for (const handler of handlers) {
          // "Catch-all" `*` handler.
          if (typeof handler['*'] === 'function') {
            if (options.asNodes) {
              handler['*'](node, parent, prop, index);
            } else {
              // A path/node can be removed by some previous handler.
              if (!nodePath.isRemoved()) {
                handler['*'](nodePath);
              }
            }
          }

          // Per-node handler.
          if (typeof handler[node.type] === 'function') {
            if (options.asNodes) {
              handler[node.type](node, parent, prop, index);
            } else {
              // A path/node can be removed by some previous handler.
              if (!nodePath.isRemoved()) {
                const handlerResult = handler[node.type](nodePath);
                // Explicitly stop traversal.
                if (handlerResult === false) {
                  return false;
                }
              }
            }
          }
        }
      },

      /**
       * Skip locations by default.
       */
      skipProperty(prop) {
        return prop === 'loc';
      },
    });
  },
};<commit_msg>Traverse: recalculate from parent after handling<commit_after>/**
 * The MIT License (MIT)
 * Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
 */

'use strict';

const NodePath = require('./node-path');

/**
 * Does an actual AST traversal, using visitor pattern,
 * and calling set of callbacks.
 *
 * Based on https://github.com/olov/ast-traverse
 *
 * Expects AST in Mozilla Parser API: nodes which are supposed to be
 * handled should have `type` property.
 *
 * @param Object root - a root node to start traversal from.
 *
 * @param Object options - an object with set of callbacks:
 *
 *   - `pre(node, parent, prop, index)` - a hook called on node enter
 *   - `post`(node, parent, prop, index) - a hook called on node exit
 *   - `skipProperty(prop)` - a predicated whether a property should be skipped
 */
function astTraverse(root, options = {}) {
  const pre = options.pre;
  const post = options.post;
  const skipProperty = options.skipProperty;

  function visit(node, parent, prop, idx) {
    if (!node || typeof node.type !== 'string') {
      return;
    }

    let res = undefined;
    if (pre) {
      res = pre(node, parent, prop, idx);
    }

    if (res !== false) {

      // A node can be replaced during traversal, so we have to
      // recalculate it from the parent, to avoid traversing "dead" nodes.
      if (parent) {
        if (idx) {
          node = parent[prop][idx];
        } else {
          node = parent[prop];
        }
      }

      for (let prop in node) if (node.hasOwnProperty(prop)) {
        if (skipProperty ? skipProperty(prop, node) : prop[0] === '$') {
          continue;
        }

        const child = node[prop];

        // Collection node.
        //
        // NOTE: a node (or several nodes) can be removed or inserted
        // during traversal.
        //
        // Current traversing index is stored on top of the
        // `NodePath.traversingIndexStack`. The stack is used to support
        // recursive nature of the traversal.
        //
        // In this case `NodePath.traversingIndex` (which we use here) is
        // updated in the NodePath remove/insert methods.
        //
        if (Array.isArray(child)) {
          let index = 0;
          NodePath.traversingIndexStack.push(index);
          while (index < child.length) {
            visit(
              child[index],
              node,
              prop,
              index
            );
            index = NodePath.updateTraversingIndex(+1);
          }
          NodePath.traversingIndexStack.pop();
        }

        // Simple node.
        else {
          visit(child, node, prop);
        }
      }
    }

    if (post) {
      post(node, parent, prop, idx);
    }
  }

  visit(root, null);
}

module.exports = {
  /**
   * Traverses an AST.
   *
   * @param Object ast - an AST node
   *
   * @param Array<Object>|Object handlers:
   *
   *   an object (or an array of objects)
   *   containing handler function per node. In case of an array of
   *   handlers, they are applied in order. A handler may return a
   *   transformed node (or a different type).
   *
   * @param Object options:
   *
   *   a config object, specifying traversal options:
   *
   *   `asNodes`: boolean - whether handlers should receives raw AST nodes
   *   (false by default), instead of a `NodePath` wrapper. Note, by default
   *   `NodePath` wrapper provides a set of convenient method to manipulate
   *   a traversing AST, and also has access to all parents list. A raw
   *   nodes traversal should be used in rare cases, when no `NodePath`
   *   features are needed.
   *
   * Special hooks:
   *
   *   - `shouldRun(ast)` - a predicate determining whether the handler
   *                        should be applied.
   *
   * NOTE: Multiple handlers are used as an optimization of applying all of
   * them in one AST traversal pass.
   */
  traverse(ast, handlers, options = {asNodes: false}) {
    if (!Array.isArray(handlers)) {
      handlers = [handlers];
    }

    // Filter out handlers by result of `shouldRun`, if the method presents.
    handlers = handlers.filter(handler => {
      if (typeof handler.shouldRun !== 'function') {
        return true;
      }
      return handler.shouldRun(ast);
    });

    NodePath.initRegistry();

    // Allow handlers to initializer themselves.
    handlers.forEach(handler => {
      if (typeof handler.init === 'function') {
        handler.init();
      }
    });

    // Handle actual nodes.
    astTraverse(ast, {

      /**
       * Handler on node enter.
       */
      pre(node, parent, prop, index) {
        let parentPath;
        let nodePath;

        if (!options.asNodes) {
          parentPath = NodePath.getForNode(parent);

          nodePath = NodePath.getForNode(
            node,
            parentPath,
            prop,
            index
          );
        }

        for (const handler of handlers) {
          // "Catch-all" `*` handler.
          if (typeof handler['*'] === 'function') {
            if (options.asNodes) {
              handler['*'](node, parent, prop, index);
            } else {
              // A path/node can be removed by some previous handler.
              if (!nodePath.isRemoved()) {
                handler['*'](nodePath);
              }
            }
          }

          // Per-node handler.
          if (typeof handler[node.type] === 'function') {
            if (options.asNodes) {
              handler[node.type](node, parent, prop, index);
            } else {
              // A path/node can be removed by some previous handler.
              if (!nodePath.isRemoved()) {
                const handlerResult = handler[node.type](nodePath);
                // Explicitly stop traversal.
                if (handlerResult === false) {
                  return false;
                }
              }
            }
          }
        }
      },

      /**
       * Skip locations by default.
       */
      skipProperty(prop) {
        return prop === 'loc';
      },
    });
  },
};<|endoftext|>


<commit_before>// Your code here.

/**
 * Log the first five elements of a sequence.
 * @param {object} sequence
 */
function logFive(sequence) {
	for (let i = 0; i < 5; i++) {
		if (!sequence.next()) {
			break;
		}
		console.log(sequence.current());
	}
}

/**
 * Sequentialize the array
 * @param {array} array
 */
function ArraySeq(array) {
  this.array = array;
  this.i = -1;
}
ArraySeq.prototype.current = function() {
  this.i++;
  return this.array[this.i];
};
ArraySeq.prototype.next = function() {
  return this.array[this.i + 1];
};

logFive(new ArraySeq([1, 2]));
// → 1
// → 2
// logFive(new RangeSeq(100, 1000));
// → 100
// → 101
// → 102
// → 103
// → 104
<commit_msg>6: Sequence interface: RangeSeq()<commit_after>// Your code here.

/**
 * Log the first five elements of a sequence.
 * @param {object} sequence
 */
function logFive(sequence) {
	for (let i = 0; i < 5; i++) {
		if (!sequence.next()) {
			break;
		}
		console.log(sequence.current());
	}
}

/**
 * Sequentialize an array
 * @param {array} array
 */
function ArraySeq(array) {
  this.array = array;
  this.i = -1;
}
ArraySeq.prototype.current = function() {
  this.i++;
  return this.array[this.i];
};
ArraySeq.prototype.next = function() {
  return this.array[this.i + 1];
};

logFive(new ArraySeq([1, 2]));
// → 1
// → 2

/**
 * Sequentialize a range
 * @param {number} start
 * @param {number} end
 */
function RangeSeq(start, end) {
	this.start = start;
	this.end = end;
	this.i = start;
}
RangeSeq.prototype.current = function() {
	this.i++;
	return this.i - 1;
};
RangeSeq.prototype.next = function() {
	if (this.i < this.end) {
		return true;
	} else {
		return false;
	}
};

logFive(new RangeSeq(100, 1000));
// → 100
// → 101
// → 102
// → 103
// → 104
<|endoftext|>


<commit_before>var couchWrapper = require('./couch-wrapper')

var http = require('http');
var crypto = require('crypto');
var Cookies = require('cookies');

var users = [];
users["token"] = "kikoo";
var server = http.createServer().listen(8080, '127.0.0.1');

server.on('request', function(request, response) {
	var body = "";
	var cookieJar = new Cookies(request, response);

	request.on('data', function(chunk) {
		body += chunk;
	});

	request.on('end', function() {

		/* response handling */
		function badRequest(body) {
			response.writeHead(400, "Bad Request");
			if (body)
				response.write(body);
			response.end();
		}
		 // we provide a public API
		response.setHeader("Access-Control-Allow-Origin", "*");

		/* request handling */
		// parse request
		parsedUrl = require('url').parse(request.url, true);

		// parse request's parameters
		var params;
		try {
			if ((request.method == "POST" || request.method == "PUT" || request.method == "DELETE")) {
				if (body)
					params = JSON.parse(body);
				else
					params = {};
			}
			else if (request.method == "GET")
				params = parsedUrl.query;
			else
				params = {};
		}
		catch (error) {
			badRequest("Unable to parse parameters.");
		}
		var token = "";
		if (params.token) {
			token = params.token;
			delete params.token;
		}
		if (parsedUrl.query.token) {
			token = parsedUrl.query.token;
		}
		var isAuthenticatedUser = token && users[token] ? true : false;

		/* CORS handling
		 * Thanks to nilcolor.
		 * https://gist.github.com/nilcolor/816580
		 */

		if (request.method === 'OPTIONS') {
			var headers = {};
			// IE8 does not allow domains to be specified, just the *
			// headers["Access-Control-Allow-Origin"] = req.headers.origin;
			// Already done
			// headers["Access-Control-Allow-Origin"] = "*";
			headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
			headers["Access-Control-Allow-Credentials"] = false;
			headers["Access-Control-Max-Age"] = '86400'; // 24 hours
			headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
			response.writeHead(200, headers);
			response.end();
		}

		/* USER */

		// Sign in
		else if (parsedUrl.pathname == "/users/signin" && request.method == "POST") {
			if (!params.login || !params.passwd) {
				badRequest("Login or password is missing.");
			}

			else {
				var shasum = crypto.createHash('sha512').update(params.passwd, 'utf8').digest('hex');
				couchWrapper.userLogin(params.login, function(user_data) {
					if (user_data && user_data.shasum && shasum == user_data.shasum) {
						users[user_data.uuid] = params.login;
						cookieJar.set("token", user_data.uuid, {httpOnly: false});
						response.writeHead(204, "No Content");
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
		}

		// Sign out
		else if (parsedUrl.pathname == "/user/signout" && request.method == "POST") {
			if (isAuthenticatedUser) {
				delete users[token];
				cookieJar.set("token", "deleted", {httpOnly: false, expires: new Date(0)});
				response.writeHead(204, "No Content");
			}
			else {
				response.writeHead(401, "Unauthorized");
			}
			response.end();
		}

		// Sign up
		else if (parsedUrl.pathname == "/users/signup" && request.method == "POST") {
			if (!params.login || !params.passwd || !params.email || !params.imgUrl) {
				badRequest("Parameters are missing.");
			}
			else {
				// generate shasum...
				var shasum = crypto.createHash('sha512').update(params.passwd, 'utf8').digest('hex');
				params.shasum = shasum;
				// ... then delete the password
				delete params.passwd;
				couchWrapper.userCreate(params, function(uuid) {
					if (uuid) {
						users[uuid] = params.login
						response.writeHead(201, "Created");
						response.write(JSON.stringify(uuid));
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
		}

		// Get a single user or get the authenticated user
		else if (((parsedUrl.pathname.indexOf('/users/') == 0 && parsedUrl.pathname.split('/').length == 3) || parsedUrl.pathname == '/user') && request.method == 'GET') {
			// determine the user
			var login = request.url.indexOf('/users/') == 0 ? request.url.substr('/users/'.length) : users[token];
			if (isAuthenticatedUser) {
				couchWrapper.userGet(login, function(user_object) {
					if (user_object) {
						couchWrapper.docByUser(login, function(docs_list) {
							if (docs_list !== null) {
								user_object.documents = docs_list;
								response.writeHead(200, "OK");
								response.write(JSON.stringify(user_object));
							}
							else {
								response.writeHead(403, "Forbidden");
							}
							response.end();
						});
					}
					else {
						response.writeHead(403, "Forbidden");
						response.end();
					}
				});
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// Delete the authenticated user
		else if (parsedUrl.pathname == "/user" && request.method == "DELETE") {
			if (isAuthenticatedUser) {
				couchWrapper.userDelete(users[token], function(success) {
					if (success) {
						response.writeHead(204, "No Content");
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
				delete users[token];
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// Get the login associated to a token
		else if (parsedUrl.pathname.indexOf("/tokens/") == 0 && request.method == "GET") {
			if (parsedUrl.pathname == "/tokens/") {
				badRequest("Parameters are missing.");
			}
			else {
				if (users[parsedUrl.pathname.substr("/tokens/".length)]) {
					response.writeHead(200, "OK");
					response.write(JSON.stringify(users[parsedUrl.pathname.substr("/tokens/".length)]));
				}
				else {
					response.writeHead(404, "Not Found");
				}
				response.end();
			}
		}

		/* Document */

		// Create a single document
		else if (parsedUrl.pathname == "/documents" && request.method == "POST") {
			if (isAuthenticatedUser) {
				couchWrapper.docAdd(params, function(id) {
					if (id) {
						response.writeHead(201, "Created");
						response.write(JSON.stringify(id));
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// Update a document
		else if (parsedUrl.pathname.indexOf("/documents/") == 0 && request.method == "PUT") {
			if (isAuthenticatedUser) {
				couchWrapper.docUpdate(params, function(success) {
					if (success) {
						response.writeHead(204, "No Content");
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}

		}

		// Delete a document
		else if (parsedUrl.pathname.indexOf("/documents/") == 0 && request.method == "DELETE") {
			if (isAuthenticatedUser) {
				couchWrapper.docDelete(parsedUrl.pathname.substr('/documents/'.length), function(success) {
					if (success) {
						response.writeHead(204, "No Content");
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// List your documents or user documents
		else if ((parsedUrl.pathname == "/documents" || (parsedUrl.pathname.indexOf("/users/") == 0 && parsedUrl.pathname.indexOf("/documents") == parsedUrl.pathname.length - "/documents".length) && parsedUrl.pathname.split('/').length == 4) && request.method == "GET") {
			if (isAuthenticatedUser) {
				var login = parsedUrl.pathname == "/documents" ? users[token] : parsedUrl.pathname.substring('/users/'.length, parsedUrl.pathname.indexOf('/documents'));
				if (login) {
					couchWrapper.docByUser(login, function(docs_list) {
						if (docs_list !== null) {
							response.writeHead(200, "OK");
							response.write(JSON.stringify(docs_list));
						}
						else {
							response.writeHead(403, "Forbidden");
						}
						response.end();
					});
				}
				else {
					badRequest("Parameters are missing.");
				}
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// Get a single document
		else if (parsedUrl.pathname.indexOf("/documents/") == 0 && request.method == "GET") {
			if (isAuthenticatedUser) {
				couchWrapper.docGet(parsedUrl.pathname.substr('/documents/'.length), function(doc) {
					if (doc) {
						response.writeHead(200, "OK");
						response.write(JSON.stringify(doc));
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// Default
		else {
			badRequest("The request does not match with an API function.");
		}
	});
});
<commit_msg>server.js now acceptions requests from all hosts<commit_after>var couchWrapper = require('./couch-wrapper')

var http = require('http');
var crypto = require('crypto');
var Cookies = require('cookies');

var users = [];
users["token"] = "kikoo";
var server = http.createServer().listen(8080);

server.on('request', function(request, response) {
	var body = "";
	var cookieJar = new Cookies(request, response);

	request.on('data', function(chunk) {
		body += chunk;
	});

	request.on('end', function() {

		/* response handling */
		function badRequest(body) {
			response.writeHead(400, "Bad Request");
			if (body)
				response.write(body);
			response.end();
		}
		 // we provide a public API
		response.setHeader("Access-Control-Allow-Origin", "*");

		/* request handling */
		// parse request
		parsedUrl = require('url').parse(request.url, true);

		// parse request's parameters
		var params;
		try {
			if ((request.method == "POST" || request.method == "PUT" || request.method == "DELETE")) {
				if (body)
					params = JSON.parse(body);
				else
					params = {};
			}
			else if (request.method == "GET")
				params = parsedUrl.query;
			else
				params = {};
		}
		catch (error) {
			badRequest("Unable to parse parameters.");
		}
		var token = "";
		if (params.token) {
			token = params.token;
			delete params.token;
		}
		if (parsedUrl.query.token) {
			token = parsedUrl.query.token;
		}
		var isAuthenticatedUser = token && users[token] ? true : false;

		/* CORS handling
		 * Thanks to nilcolor.
		 * https://gist.github.com/nilcolor/816580
		 */

		if (request.method === 'OPTIONS') {
			var headers = {};
			// IE8 does not allow domains to be specified, just the *
			// headers["Access-Control-Allow-Origin"] = req.headers.origin;
			// Already done
			// headers["Access-Control-Allow-Origin"] = "*";
			headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
			headers["Access-Control-Allow-Credentials"] = false;
			headers["Access-Control-Max-Age"] = '86400'; // 24 hours
			headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
			response.writeHead(200, headers);
			response.end();
		}

		/* USER */

		// Sign in
		else if (parsedUrl.pathname == "/users/signin" && request.method == "POST") {
			if (!params.login || !params.passwd) {
				badRequest("Login or password is missing.");
			}

			else {
				var shasum = crypto.createHash('sha512').update(params.passwd, 'utf8').digest('hex');
				couchWrapper.userLogin(params.login, function(user_data) {
					if (user_data && user_data.shasum && shasum == user_data.shasum) {
						users[user_data.uuid] = params.login;
						cookieJar.set("token", user_data.uuid, {httpOnly: false});
						response.writeHead(204, "No Content");
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
		}

		// Sign out
		else if (parsedUrl.pathname == "/user/signout" && request.method == "POST") {
			if (isAuthenticatedUser) {
				delete users[token];
				cookieJar.set("token", "deleted", {httpOnly: false, expires: new Date(0)});
				response.writeHead(204, "No Content");
			}
			else {
				response.writeHead(401, "Unauthorized");
			}
			response.end();
		}

		// Sign up
		else if (parsedUrl.pathname == "/users/signup" && request.method == "POST") {
			if (!params.login || !params.passwd || !params.email || !params.imgUrl) {
				badRequest("Parameters are missing.");
			}
			else {
				// generate shasum...
				var shasum = crypto.createHash('sha512').update(params.passwd, 'utf8').digest('hex');
				params.shasum = shasum;
				// ... then delete the password
				delete params.passwd;
				couchWrapper.userCreate(params, function(uuid) {
					if (uuid) {
						users[uuid] = params.login
						response.writeHead(201, "Created");
						response.write(JSON.stringify(uuid));
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
		}

		// Get a single user or get the authenticated user
		else if (((parsedUrl.pathname.indexOf('/users/') == 0 && parsedUrl.pathname.split('/').length == 3) || parsedUrl.pathname == '/user') && request.method == 'GET') {
			// determine the user
			var login = request.url.indexOf('/users/') == 0 ? request.url.substr('/users/'.length) : users[token];
			if (isAuthenticatedUser) {
				couchWrapper.userGet(login, function(user_object) {
					if (user_object) {
						couchWrapper.docByUser(login, function(docs_list) {
							if (docs_list !== null) {
								user_object.documents = docs_list;
								response.writeHead(200, "OK");
								response.write(JSON.stringify(user_object));
							}
							else {
								response.writeHead(403, "Forbidden");
							}
							response.end();
						});
					}
					else {
						response.writeHead(403, "Forbidden");
						response.end();
					}
				});
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// Delete the authenticated user
		else if (parsedUrl.pathname == "/user" && request.method == "DELETE") {
			if (isAuthenticatedUser) {
				couchWrapper.userDelete(users[token], function(success) {
					if (success) {
						response.writeHead(204, "No Content");
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
				delete users[token];
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// Get the login associated to a token
		else if (parsedUrl.pathname.indexOf("/tokens/") == 0 && request.method == "GET") {
			if (parsedUrl.pathname == "/tokens/") {
				badRequest("Parameters are missing.");
			}
			else {
				if (users[parsedUrl.pathname.substr("/tokens/".length)]) {
					response.writeHead(200, "OK");
					response.write(JSON.stringify(users[parsedUrl.pathname.substr("/tokens/".length)]));
				}
				else {
					response.writeHead(404, "Not Found");
				}
				response.end();
			}
		}

		/* Document */

		// Create a single document
		else if (parsedUrl.pathname == "/documents" && request.method == "POST") {
			if (isAuthenticatedUser) {
				couchWrapper.docAdd(params, function(id) {
					if (id) {
						response.writeHead(201, "Created");
						response.write(JSON.stringify(id));
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// Update a document
		else if (parsedUrl.pathname.indexOf("/documents/") == 0 && request.method == "PUT") {
			if (isAuthenticatedUser) {
				couchWrapper.docUpdate(params, function(success) {
					if (success) {
						response.writeHead(204, "No Content");
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}

		}

		// Delete a document
		else if (parsedUrl.pathname.indexOf("/documents/") == 0 && request.method == "DELETE") {
			if (isAuthenticatedUser) {
				couchWrapper.docDelete(parsedUrl.pathname.substr('/documents/'.length), function(success) {
					if (success) {
						response.writeHead(204, "No Content");
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// List your documents or user documents
		else if ((parsedUrl.pathname == "/documents" || (parsedUrl.pathname.indexOf("/users/") == 0 && parsedUrl.pathname.indexOf("/documents") == parsedUrl.pathname.length - "/documents".length) && parsedUrl.pathname.split('/').length == 4) && request.method == "GET") {
			if (isAuthenticatedUser) {
				var login = parsedUrl.pathname == "/documents" ? users[token] : parsedUrl.pathname.substring('/users/'.length, parsedUrl.pathname.indexOf('/documents'));
				if (login) {
					couchWrapper.docByUser(login, function(docs_list) {
						if (docs_list !== null) {
							response.writeHead(200, "OK");
							response.write(JSON.stringify(docs_list));
						}
						else {
							response.writeHead(403, "Forbidden");
						}
						response.end();
					});
				}
				else {
					badRequest("Parameters are missing.");
				}
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// Get a single document
		else if (parsedUrl.pathname.indexOf("/documents/") == 0 && request.method == "GET") {
			if (isAuthenticatedUser) {
				couchWrapper.docGet(parsedUrl.pathname.substr('/documents/'.length), function(doc) {
					if (doc) {
						response.writeHead(200, "OK");
						response.write(JSON.stringify(doc));
					}
					else {
						response.writeHead(403, "Forbidden");
					}
					response.end();
				});
			}
			else {
				response.writeHead(401, "Unauthorized");
				response.end();
			}
		}

		// Default
		else {
			badRequest("The request does not match with an API function.");
		}
	});
});
<|endoftext|>