<commit_before>/*
 * gult-stubby
 * https://github.com/felixzapata/gulp-pug-i18n
 *
 * Copyright (c) 2016 Félix Zapata
 * Licensed under the MIT license.
 */

'use strict';

var R = require('ramda');
var pug = require('pug');
var glob = require('glob');
var fs = require('fs');
var gutil = require('gulp-util');
var ext = require('gulp-util').replaceExtension;
var PluginError = require('gulp-util').PluginError;
var path = require('path');
var YAML = require('js-yaml');
var through = require('through2');
var PLUGIN_NAME = 'gulp-pug-i18n';

function getExtension(filepath) {
    return path.extname(filepath);
}

function setExtension(ext) {
    if (ext.charAt(0) !== '.') {
        ext = '.' + ext;
    }
    return ext;
}

function readYAML(filepath, options) {
    var src = fs.readFileSync(filepath, options);
    var result;
    try {
        result = YAML.load(src);
        return result;
    } catch (e) {
        throw new gutil.PluginError(PLUGIN_NAME, 'Unable to parse "' + filepath + '" file (' + e.problem + ').', e);
    }
}

function readJSON(filepath, options) {
    var src = fs.readFileSync(filepath, options);
    var result;
    try {
        result = JSON.parse(src);
        return result;
    } catch (e) {
        throw new gutil.PluginError(PLUGIN_NAME, 'Unable to parse "' + filepath + '" file (' + e.message + ').', e);
    }
}

function addLocaleExtensionDest(obj, locale, outputExt) {

    var files = glob.sync(path.join(obj.cwd, obj.src));
    return _.map(files, function (file) {

        var dest, ext;

        locale = locale.toLowerCase();
        ext = getExtension(file);

        function getBaseName() {
            return path.basename(file).split('.')[0];
        }

        if (ext) {
            dest = path.join(obj.dest, path.basename(file, ext) + '.' + locale);
        } else {
            dest = path.join(obj.dest, getBaseName() + '.' + locale);
        }

        if (obj.ext) {
            dest += setExtension(obj.ext);
        } else {
            dest += setExtension(outputExt);
        }

        return dest;
    });
}

function addLocaleDirnameDest(file, locale, outputExt) {
    var base, dest, ext = getExtension(file);
    if (ext) {
        dest = path.join(path.dirname(file), locale, path.basename(file, ext) + setExtension(ext));
    } else {
        if (/(\/|\*+)$/i.test(file)) {
            base = file.split('/');
            dest = path.join(path.join.apply(null, base.slice(0, -1)), locale, base.slice(-1)[0]);
        } else {
            dest = path.join(file, locale);
        }
    }
    dest = dest.replace(/\.pug$/i, setExtension(outputExt));
    return dest;
}

function readFile(filepath) {
    var data;
    try {
        if (/(\.yaml|\.yml)$/i.test(filepath)) {
            data = readYAML(filepath);
        } else if (/\.js$/i.test(filepath)) {
            data = require(path.resolve(filepath));
        } else {
            data = readJSON(filepath);
        }
    } catch (_error) {
        throw new gutil.PluginError("Cannot parse file '" + filepath + "': " + _error.message, _error);
    }
    return data;
}

function plugI18nPlugin(options) {

    var baseName;
    var compiledFiles = [];
    var defaultExt;
    var dest;
    var localeExtension;
    var localePath;
    var namespace;
    var fileExt;
    var locale;

    if (!options.i18n) {
        options.i18n = {};
    } else {
        locales = options.i18n.locales;
        namespace = options.i18n.namespace;
        localeExtension = options.i18n.localeExtension;
        defaultExt = options.i18n.defaultExt;
    }

    if (!namespace) {
        namespace = '$i18n';
    }

    if (!localeExtension) {
        localeExtension = false;
    }

    if (!defaultExt) {
        defaultExt = '.html';
    }

    var locales = glob.sync(options.i18n.locales);

    var bufferContents = function (file, enc, cb) {

        if (file.isNull()) {
            cb(null, file);
            return;
        }

        if (file.isStream()) {
            driver.quit();
            cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
            return;
        }

        if (locales && locales.length) {

            for (var i = 0, len = locales.length; i < len; i++) {
                localePath = locales[i];
                fileExt = localePath.split('.').slice(-1)[0];
                locale = path.basename(localePath, '.' + fileExt);
                baseName = path.basename(file.path);
                gutil.log('Loading locale ' + locale);
                gutil.log('Reading translation data: ' + localePath);
                if (!options.data) {
                    options.data = {};
                }
                options.data[namespace] = readFile(localePath);

                if (localeExtension) {
                    dest = addLocaleExtensionDest(baseName, locale, defaultExt);
                } else {
                    dest = addLocaleDirnameDest(baseName, locale, defaultExt);
                }

                compiledFiles.push(new gutil.File({
                    base: path.join(__dirname, locale),
                    cwd: __dirname,
                    contents: new Buffer(pug.compileFile(file.path, options)(options.data)),
                    path: path.join(options.i18n.dest, dest)
                }));

            }

        } else {
            gutil.log('Locales files not found. Nothing to translate');
        }
        cb();
    }

    var endStream = function (cb) {
        if (!compiledFiles || compiledFiles.length === 0) {
            cb();
            return;
        }
        for (var i = 0, len = compiledFiles.length; i < len; i++) {
            this.push(compiledFiles[i]);
        }
        cb();
    }

    return through.obj(bufferContents, endStream);
}

module.exports = plugI18nPlugin;
<commit_msg>style(index.js): change due to lint errors<commit_after>/*
 * gult-stubby
 * https://github.com/felixzapata/gulp-pug-i18n
 *
 * Copyright (c) 2016 Félix Zapata
 * Licensed under the MIT license.
 */

'use strict';

var pug = require('pug');
var glob = require('glob');
var fs = require('fs');
var gutil = require('gulp-util');
var path = require('path');
var YAML = require('js-yaml');
var through = require('through2');
var PLUGIN_NAME = 'gulp-pug-i18n';

function getExtension(filepath) {
    return path.extname(filepath);
}

function setExtension(ext) {
    if (ext.charAt(0) !== '.') {
        ext = '.' + ext;
    }
    return ext;
}

function readYAML(filepath, options) {
    var src = fs.readFileSync(filepath, options);
    var result;
    try {
        result = YAML.load(src);
        return result;
    } catch (e) {
        throw new gutil.PluginError(PLUGIN_NAME, 'Unable to parse "' + filepath + '" file (' + e.problem + ').', e);
    }
}

function readJSON(filepath, options) {
    var src = fs.readFileSync(filepath, options);
    var result;
    try {
        result = JSON.parse(src);
        return result;
    } catch (e) {
        throw new gutil.PluginError(PLUGIN_NAME, 'Unable to parse "' + filepath + '" file (' + e.message + ').', e);
    }
}

function addLocaleExtensionDest(obj, locale, outputExt) {

    var files = glob.sync(path.join(obj.cwd, obj.src));
    return files.map(function (file) {

        var dest, ext;

        locale = locale.toLowerCase();
        ext = getExtension(file);

        function getBaseName() {
            return path.basename(file).split('.')[0];
        }

        if (ext) {
            dest = path.join(obj.dest, path.basename(file, ext) + '.' + locale);
        } else {
            dest = path.join(obj.dest, getBaseName() + '.' + locale);
        }

        if (obj.ext) {
            dest += setExtension(obj.ext);
        } else {
            dest += setExtension(outputExt);
        }

        return dest;
    });
}

function addLocaleDirnameDest(file, locale, outputExt) {
    var base, dest, ext = getExtension(file);
    if (ext) {
        dest = path.join(path.dirname(file), locale, path.basename(file, ext) + setExtension(ext));
    } else {
        if (/(\/|\*+)$/i.test(file)) {
            base = file.split('/');
            dest = path.join(path.join.apply(null, base.slice(0, -1)), locale, base.slice(-1)[0]);
        } else {
            dest = path.join(file, locale);
        }
    }
    dest = dest.replace(/\.pug$/i, setExtension(outputExt));
    return dest;
}

function readFile(filepath) {
    var data;
    try {
        if (/(\.yaml|\.yml)$/i.test(filepath)) {
            data = readYAML(filepath);
        } else if (/\.js$/i.test(filepath)) {
            data = require(path.resolve(filepath));
        } else {
            data = readJSON(filepath);
        }
    } catch (_error) {
        throw new gutil.PluginError("Cannot parse file '" + filepath + "': " + _error.message, _error);
    }
    return data;
}

function plugI18nPlugin(options) {

    var baseName;
    var compiledFiles = [];
    var defaultExt;
    var dest;
    var localeExtension;
    var localePath;
    var namespace;
    var fileExt;
    var locale;

    if (!options.i18n) {
        options.i18n = {};
    } else {
        locales = options.i18n.locales;
        namespace = options.i18n.namespace;
        localeExtension = options.i18n.localeExtension;
        defaultExt = options.i18n.defaultExt;
    }

    if (!namespace) {
        namespace = '$i18n';
    }

    if (!localeExtension) {
        localeExtension = false;
    }

    if (!defaultExt) {
        defaultExt = '.html';
    }

    var locales = glob.sync(options.i18n.locales);

    var bufferContents = function (file, enc, cb) {

        if (file.isNull()) {
            cb(null, file);
            return;
        }

        if (file.isStream()) {
            cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
            return;
        }

        if (locales && locales.length) {

            for (var i = 0, len = locales.length; i < len; i++) {
                localePath = locales[i];
                fileExt = localePath.split('.').slice(-1)[0];
                locale = path.basename(localePath, '.' + fileExt);
                baseName = path.basename(file.path);
                gutil.log('Loading locale ' + locale);
                gutil.log('Reading translation data: ' + localePath);
                if (!options.data) {
                    options.data = {};
                }
                options.data[namespace] = readFile(localePath);

                if (localeExtension) {
                    dest = addLocaleExtensionDest(baseName, locale, defaultExt);
                } else {
                    dest = addLocaleDirnameDest(baseName, locale, defaultExt);
                }

                compiledFiles.push(new gutil.File({
                    base: path.join(__dirname, locale),
                    cwd: __dirname,
                    contents: new Buffer(pug.compileFile(file.path, options)(options.data)),
                    path: path.join(options.i18n.dest, dest)
                }));

            }

        } else {
            gutil.log('Locales files not found. Nothing to translate');
        }
        cb();
    }

    var endStream = function (cb) {
        if (!compiledFiles || compiledFiles.length === 0) {
            cb();
            return;
        }
        for (var i = 0, len = compiledFiles.length; i < len; i++) {
            this.push(compiledFiles[i]);
        }
        cb();
    }

    return through.obj(bufferContents, endStream);
}

module.exports = plugI18nPlugin;
<|endoftext|>


<commit_before>'use strict'

const {log, BaseKonnector, saveBills, request} = require('cozy-konnector-libs')
const moment = require('moment')
const bluebird = require('bluebird')

let rq = request({
  // debug: true,
  cheerio: true,
  json: false,
  jar: true
})

module.exports = new BaseKonnector(function fetch (fields) {
  return checkLogin(fields)
  .then(() => logIn(fields))
  .then($ => parsePage($))
  .then(entries => {
    // get custom bank identifier if any
    let identifiers = 'C.P.A.M.'
    if (fields.bank_identifier && fields.bank_identifier.length) {
      identifiers = fields.bank_identifier
    }

    return saveBills(entries, fields.folderPath, {
      timeout: Date.now() + 60 * 1000,
      identifiers,
      dateDelta: 10,
      amountDelta: 0.1
    })
  })
})

const checkLogin = function (fields) {
  log('info', 'Checking the length of the login')
  if (fields.login.length > 13) return Promise.reject(new Error('LOGIN_FAILED'))

  return Promise.resolve()
}

// Procedure to login to Ameli website.
const logIn = function (fields) {
  log('info', 'Now logging in')
  const loginUrl = 'https://assure.ameli.fr/PortailAS/appmanager/PortailAS/assure?_somtc=true'

  const submitUrl = 'https://assure.ameli.fr/PortailAS/appmanager/PortailAS/' +
    'assure?_nfpb=true&_windowLabel=connexioncompte_2&connexioncompte_2_' +
    'actionOverride=/portlets/connexioncompte/validationconnexioncompte&_pageLabel=as_login_page'

  const reimbursementUrl = 'https://assure.ameli.fr/PortailAS/appmanager/PortailAS/assure?_nfpb=true&_pageLabel=as_paiements_page'

  const form = {
    'connexioncompte_2numSecuriteSociale': fields.login,
    'connexioncompte_2codeConfidentiel': fields.password,
    'connexioncompte_2actionEvt': 'connecter',
    'submit': 'Valider'
  }

  return rq({
    url: loginUrl,
    resolveWithFullResponse: true
  })
  // First request to get the cookie
  .then(res => rq({
    method: 'POST',
    form,
    url: submitUrl
  }))
  // Second request to authenticate
  .then($ => {
    if ($('[title="Déconnexion du compte ameli"]').length !== 1) {
      throw new Error('LOGIN_FAILED')
    }

    log('info', 'Correctly logged in')
    return rq(reimbursementUrl)
  })
}

// Parse the fetched page to extract bill data.
const parsePage = function ($) {
  log('info', 'Fetching the list of bills')
  const entries = []

  // Get the start and end date to generate the bill's url
  const endDate = $('#paiements_1dateFin').attr('value')

  const baseUrl = 'https://assure.ameli.fr/PortailAS/paiements.do?actionEvt='

  // We can get the history only 6 months back
  const startDate = moment(endDate, 'DD/MM/YYYY').subtract(6, 'months').format('DD/MM/YYYY')

  const billUrl = `${baseUrl}afficherPaiementsComplementaires&DateDebut=${startDate}&DateFin=${endDate}\
&Beneficiaire=tout_selectionner&afficherReleves=false&afficherIJ=false&afficherInva=false&afficherRentes=false\
&afficherRS=false&indexPaiement=&idNotif=`

  return rq(billUrl)
  .then($ => {
    let i = 0

    // Each bloc represents a month that includes 0 to n reimbursement
    $('.blocParMois').each(function () {
      // It would be too easy to get the full date at the same place
      let year = $($(this).find('.rowdate .mois').get(0)).text()
      year = year.split(' ')[1]

      return $(`[id^=lignePaiement${i++}]`).each(function () {
        let amount = $($(this).find('.col-montant').get(0)).text()
        amount = amount.replace(' €', '').replace(',', '.')
        amount = parseFloat(amount)

        const month = $($(this).find('.col-date .mois').get(0)).text()
        const day = $($(this).find('.col-date .jour').get(0)).text()
        let date = `${day} ${month} ${year}`
        moment.locale('fr')
        date = moment(date, 'Do MMMM YYYY')

        const label = $($(this).find('.col-label').get(0)).text()

        // Retrieve and extract the infos needed to generate the pdf
        const attrInfos = $(this).attr('onclick')
        const tokens = attrInfos.split("'")

        const idPaiement = tokens[1]
        const naturePaiement = tokens[3]
        const indexGroupe = tokens[5]
        const indexPaiement = tokens[7]

        const detailsUrl = `${baseUrl}chargerDetailPaiements\
&idPaiement=${idPaiement}\
&naturePaiement=${naturePaiement}\
&indexGroupe=${indexGroupe}\
&indexPaiement=${indexPaiement}`

        let lineId = indexGroupe + indexPaiement

        let bill = {
          amount,
          type: 'health',
          subtype: label,
          date: date.toDate(),
          vendor: 'Ameli',
          lineId,
          detailsUrl
        }

        if (bill.amount != null && naturePaiement === 'REMBOURSEMENT_SOINS') { return entries.push(bill) }
      })
    })
    return bluebird.each(entries, getPdf)
  })
}

const getPdf = function (bill) {
  // Request the generated url to get the detailed pdf
  return rq(bill.detailsUrl)
  .then($ => {
    let pdfUrl = $(`[id=liendowndecompte${bill.lineId}]`).attr('href')
    if (pdfUrl) {
      bill.fileurl = `https://assure.ameli.fr${pdfUrl}`
      bill.filename = getFileName(bill.date)
    }
    return bill
  })
}

function getFileName (date) {
  return `${moment(date).format('YYYYMMDD')}_ameli.pdf`
}
<commit_msg>feat: now get the details of healt cares<commit_after>'use strict'

const {log, BaseKonnector, saveBills, request} = require('cozy-konnector-libs')
const moment = require('moment')
const bluebird = require('bluebird')

let rq = request({
  // debug: true,
  cheerio: true,
  json: false,
  jar: true
})

module.exports = new BaseKonnector(function fetch (fields) {
  return checkLogin(fields)
  .then(() => logIn(fields))
  .then($ => parsePage($))
  .then(entries => {
    // get custom bank identifier if any
    let identifiers = 'C.P.A.M.'
    if (fields.bank_identifier && fields.bank_identifier.length) {
      identifiers = fields.bank_identifier
    }

    return saveBills(entries, fields.folderPath, {
      timeout: Date.now() + 60 * 1000,
      identifiers,
      dateDelta: 10,
      amountDelta: 0.1
    })
  })
})

const checkLogin = function (fields) {
  log('info', 'Checking the length of the login')
  if (fields.login.length > 13) return Promise.reject(new Error('LOGIN_FAILED'))

  return Promise.resolve()
}

// Procedure to login to Ameli website.
const logIn = function (fields) {
  log('info', 'Now logging in')
  const loginUrl = 'https://assure.ameli.fr/PortailAS/appmanager/PortailAS/assure?_somtc=true'

  const submitUrl = 'https://assure.ameli.fr/PortailAS/appmanager/PortailAS/' +
    'assure?_nfpb=true&_windowLabel=connexioncompte_2&connexioncompte_2_' +
    'actionOverride=/portlets/connexioncompte/validationconnexioncompte&_pageLabel=as_login_page'

  const reimbursementUrl = 'https://assure.ameli.fr/PortailAS/appmanager/PortailAS/assure?_nfpb=true&_pageLabel=as_paiements_page'

  const form = {
    'connexioncompte_2numSecuriteSociale': fields.login,
    'connexioncompte_2codeConfidentiel': fields.password,
    'connexioncompte_2actionEvt': 'connecter',
    'submit': 'Valider'
  }

  return rq({
    url: loginUrl,
    resolveWithFullResponse: true
  })
  // First request to get the cookie
  .then(res => rq({
    method: 'POST',
    form,
    url: submitUrl
  }))
  // Second request to authenticate
  .then($ => {
    if ($('[title="Déconnexion du compte ameli"]').length !== 1) {
      throw new Error('LOGIN_FAILED')
    }

    log('info', 'Correctly logged in')
    return rq(reimbursementUrl)
  })
}

// Parse the fetched page to extract bill data.
const parsePage = function ($) {
  log('info', 'Fetching the list of bills')

  // Get the start and end date to generate the bill's url
  const endDate = $('#paiements_1dateFin').attr('value')

  const baseUrl = 'https://assure.ameli.fr/PortailAS/paiements.do?actionEvt='

  // We can get the history only 6 months back
  const startDate = moment(endDate, 'DD/MM/YYYY').subtract(6, 'months').format('DD/MM/YYYY')

  const billUrl = `${baseUrl}afficherPaiementsComplementaires&DateDebut=${startDate}&DateFin=${endDate}\
&Beneficiaire=tout_selectionner&afficherReleves=false&afficherIJ=false&afficherInva=false&afficherRentes=false\
&afficherRS=false&indexPaiement=&idNotif=`

  const bills = []
  return rq(billUrl)
  .then($ => {
    const reimbursements = []
    let i = 0

    // Each bloc represents a month that includes 0 to n reimbursement
    $('.blocParMois').each(function () {
      // It would be too easy to get the full date at the same place
      let year = $($(this).find('.rowdate .mois').get(0)).text()
      year = year.split(' ')[1]

      return $(`[id^=lignePaiement${i++}]`).each(function () {
        const month = $($(this).find('.col-date .mois').get(0)).text()
        const day = $($(this).find('.col-date .jour').get(0)).text()
        let date = `${day} ${month} ${year}`
        moment.locale('fr')
        date = moment(date, 'Do MMMM YYYY')

        // Retrieve and extract the infos needed to generate the pdf
        const attrInfos = $(this).attr('onclick')
        const tokens = attrInfos.split("'")

        const idPaiement = tokens[1]
        const naturePaiement = tokens[3]
        const indexGroupe = tokens[5]
        const indexPaiement = tokens[7]

        const detailsUrl = `${baseUrl}chargerDetailPaiements\
&idPaiement=${idPaiement}\
&naturePaiement=${naturePaiement}\
&indexGroupe=${indexGroupe}\
&indexPaiement=${indexPaiement}`

        let lineId = indexGroupe + indexPaiement

        let reimbursement = {
          date,
          lineId,
          detailsUrl
        }

        if (naturePaiement === 'REMBOURSEMENT_SOINS') {
          reimbursements.push(reimbursement)
        }
      })
    })
    return bluebird.each(reimbursements, reimbursement => {
      return rq(reimbursement.detailsUrl)
      .then($ => {
        // get the health cares related to the given reimbursement
        const data = []
        $('#tableauPrestation tbody tr').each(function () {
          const cells = $(this).find('td').map(function (index) {
            if (index === 0) return [$(this).find('.naturePrestation').text().trim(), $(this).html().split('<br>').pop().trim()]
            return $(this).text().trim()
          }).get()
          if (cells.length === 6 && cells[0].trim() !== 'participation forfaitaire') {
            // also get what is need for the pdf url
            cells.push($(`[id=liendowndecompte${reimbursement.lineId}]`).attr('href'))
            data.push(cells)
          }
        })
        return data
      })
      .then(rows => {
        // convert this data into bills
        rows.forEach(row => {
          bills.push({
            type: 'health',
            subtype: row[0],
            date: reimbursement.date.toDate(),
            originalDate: moment(row[1], 'DD/MM/YYYY').toDate(),
            vendor: 'Ameli',
            amount: parseFloat(row[5].replace(' €', '').replace(',', '.')),
            originalAmount: parseFloat(row[2].replace(' €', '').replace(',', '.')),
            fileurl: 'https://assure.ameli.fr' + row[6],
            filename: getFileName(reimbursement.date)
          })
        })
      })
    })
  })
  .then(() => bills)
}

function getFileName (date) {
  return `${moment(date).format('YYYYMMDD')}_ameli.pdf`
}
<|endoftext|>


<commit_before>(function () {
  'use strict';

  var _ = require('underscore'),
    fs = require('fs'),
    join = require('path').join,
    resolve = require('path').resolve,
    dirname = require('path').dirname,
    defaultOptions = {
      extensions: ['js', 'json', 'coffee'],
      recurse: true,
      rename: function (name) {
        return name;
      }
    };

  function requireDirectory(m, path, options) {
    var retval = {},
      includeFile = null;

    // path is optional
    if (path && !options && !_.isString(path)) {
      options = path;
      path = null;
    }

    // default options
    options = _.defaults(options || {}, defaultOptions);

    // if no path was passed in, assume the equivelant of __dirname from caller
    // otherwise, resolve path relative to the equivalent of __dirname
    if (!path) {
      path = dirname(m.filename);
    } else {
      path = resolve(dirname(m.filename), path);
    }

    includeFile = function (path, filename) {
      // verify file has valid extension
      if (!new RegExp('\\.(' + options.extensions.join('|') + ')$', 'i').test(filename)) {
        return false;
      }

      // if options.include is a RegExp, evaluate it and make sure the path passes
      if (options.include && options.include instanceof RegExp && !options.include.test(path)) {
        return false;
      }

      // if options.include is a function, evaluate it and make sure the path passes
      if (options.include && _.isFunction(options.include) && !options.include(path, filename)) {
        return false;
      }

      // if options.exclude is a RegExp, evaluate it and make sure the path doesn't pass
      if (options.exclude && options.exclude instanceof RegExp && options.exclude.test(path)) {
        return false;
      }

      // if options.exclude is a function, evaluate it and make sure the path doesn't pass
      if (options.exclude && _.isFunction(options.exclude) && options.exclude(path, filename)) {
        return false;
      }

      return true;
    };

    // get the path of each file in specified directory, append to current tree node, recurse
    path = resolve(path);
    fs.readdirSync(path).forEach(function (filename) {
      var joined = join(path, filename),
        files,
        name,
        obj;
      if (fs.statSync(joined).isDirectory() && options.recurse) {
        files = requireDirectory(m, joined, options); // this node is a directory; recurse
        if (Object.keys(files).length) { // include JSON files
          retval[options.rename(filename)] = files;
        }
      } else {
        if (joined !== m.filename && includeFile(joined, filename)) {
          name = filename.substring(0, filename.lastIndexOf('.')); // hash node shouldn't include file extension
          obj = m.require(joined);
          if (options.visit && typeof(options.visit) === 'function') {
            retval[options.rename(name)] = options.visit(obj) || obj;
          } else {
            retval[options.rename(name)] = obj;
          }
        }
      }
    });
    return retval;
  }

  module.exports = requireDirectory;
  module.exports.defaults = defaultOptions;

}());

<commit_msg>cleaned code up a bit. releasing as v2 to npm<commit_after>(function () {
  'use strict';

  var _ = require('underscore'),
    fs = require('fs'),
    join = require('path').join,
    resolve = require('path').resolve,
    dirname = require('path').dirname,
    defaultOptions = {
      extensions: ['js', 'json', 'coffee'],
      recurse: true,
      rename: function (name) {
        return name;
      },
      visit: function (obj) {
        return obj;
      }
    };

  function requireDirectory(m, path, options) {
    var retval = {},
      includeFile = null;

    // path is optional
    if (path && !options && !_.isString(path)) {
      options = path;
      path = null;
    }

    // default options
    options = _.defaults(options || {}, defaultOptions);

    // if no path was passed in, assume the equivelant of __dirname from caller
    // otherwise, resolve path relative to the equivalent of __dirname
    if (!path) {
      path = dirname(m.filename);
    } else {
      path = resolve(dirname(m.filename), path);
    }

    includeFile = function (path, filename) {
      // verify file has valid extension
      if (!new RegExp('\\.(' + options.extensions.join('|') + ')$', 'i').test(filename)) {
        return false;
      }

      // if options.include is a RegExp, evaluate it and make sure the path passes
      if (options.include && options.include instanceof RegExp && !options.include.test(path)) {
        return false;
      }

      // if options.include is a function, evaluate it and make sure the path passes
      if (options.include && _.isFunction(options.include) && !options.include(path, filename)) {
        return false;
      }

      // if options.exclude is a RegExp, evaluate it and make sure the path doesn't pass
      if (options.exclude && options.exclude instanceof RegExp && options.exclude.test(path)) {
        return false;
      }

      // if options.exclude is a function, evaluate it and make sure the path doesn't pass
      if (options.exclude && _.isFunction(options.exclude) && options.exclude(path, filename)) {
        return false;
      }

      return true;
    };

    // get the path of each file in specified directory, append to current tree node, recurse
    path = resolve(path);
    fs.readdirSync(path).forEach(function (filename) {
      var joined = join(path, filename),
        files,
        key,
        obj;
      if (fs.statSync(joined).isDirectory() && options.recurse) {
        files = requireDirectory(m, joined, options); // this node is a directory; recurse
        if (Object.keys(files).length) { // exclude empty directories
          retval[options.rename(filename, joined, filename)] = files;
        }
      } else {
        if (joined !== m.filename && includeFile(joined, filename)) {
          key = filename.substring(0, filename.lastIndexOf('.')); // hash node key shouldn't include file extension
          obj = m.require(joined);
          retval[options.rename(key, joined, filename)] = options.visit(obj, joined, filename) || obj;
        }
      }
    });
    return retval;
  }

  module.exports = requireDirectory;
  module.exports.defaults = defaultOptions;

}());

<|endoftext|>


<commit_before>console.time('init')

var AWS = require('aws-sdk')
var Promise = require('bluebird')
var exec = require('./lib/exec')
var fs = Promise.promisifyAll(require('fs'))
var s3 = Promise.promisifyAll(new AWS.S3())
const BUCKET = 'lilybin-scores'
const LY_DIR = '/tmp/ly'

process.chdir('/tmp')
process.env['PATH'] += ':' + LY_DIR + '/usr/bin'
process.env['LD_LIBRARY_PATH'] = LY_DIR + '/usr/lib'

var mime = {
  'pdf' : 'application/octet-stream'
, 'midi': 'application/octet-stream'
, 'png' : 'image/png'
}

exports.handler = function(event, context) {
  console.log('Received event:', JSON.stringify(event, null, 2))
  makeTime('init', 'installation')

  return Promise.join(
    exec('sh ' + __dirname + '/install-lilypond.sh')
  , fs.writeFileAsync('input.ly', event.body)
  ).bind({
    key : event.key
  }).then(makeTime.bind(null, 'installation', 'lilypond'))
  .then(exec.bind(
    null,
    'lilypond -dsafe --formats=pdf,png -o rendered input.ly'
  ))
  .then(function (res) {
    this.result = res
  }).then(makeTime.bind(null, 'lilypond', 'upload'))
  .then(function () {
    return uploadFiles(this.key, this.result)
  }).then(console.timeEnd.bind(console, 'upload'))
  .then(function () {
    context.succeed(this.result)
  }).catch(context.fail.bind(context))
}

function makeTime (end, begin) {
  console.timeEnd(end)
  console.time(begin)
}

function uploadFile (key, file, mode) {
  return fs.readFileAsync(file)
  .then(function (data) {
    return s3.putObjectAsync({
      Bucket      : BUCKET
    , Key         : key
    , Body        : data
    , ContentType : mime[mode]
    , StorageClass: 'REDUCED_REDUNDANCY'
    })
  }, noop)                              // ignore error
}

function uploadFiles (key, res) {
  var pdfPromise = uploadFile(key + '.pdf', 'rendered.pdf', 'pdf')
  var midiPromise = uploadFile(key + '.midi', 'rendered.midi', 'midi')
  var pngPromise = (fs.accessAsync || fs.statAsync)('rendered.png')
    .then(function () {
      res.pages = 1
      return uploadFile(key + '-page1.png', 'rendered.png', 'png')
    }, function () {
      return countPages().then(function (pages) {
        res.pages = pages
        var promises = [];

        for (var i = 1; i <= pages; i ++) {
          promises.push(uploadFile(
            key + '-page' + i + '.png', 'rendered-page' + i + '.png', 'png'
          ))
        }
        return Promise.all(promises)
      })
    })

  return Promise.join(pdfPromise, midiPromise, pngPromise)
}

function countPages () {
  var re = new RegExp('rendered-page.*\.png')
  return fs.readdirAsync('.').then(function (files) {
    return files.filter(re.test.bind(re)).length
  })
}

function noop () {}
<commit_msg>Revert "Use safe mode"<commit_after>console.time('init')

var AWS = require('aws-sdk')
var Promise = require('bluebird')
var exec = require('./lib/exec')
var fs = Promise.promisifyAll(require('fs'))
var s3 = Promise.promisifyAll(new AWS.S3())
const BUCKET = 'lilybin-scores'
const LY_DIR = '/tmp/ly'

process.chdir('/tmp')
process.env['PATH'] += ':' + LY_DIR + '/usr/bin'
process.env['LD_LIBRARY_PATH'] = LY_DIR + '/usr/lib'

var mime = {
  'pdf' : 'application/octet-stream'
, 'midi': 'application/octet-stream'
, 'png' : 'image/png'
}

exports.handler = function(event, context) {
  console.log('Received event:', JSON.stringify(event, null, 2))
  makeTime('init', 'installation')

  return Promise.join(
    exec('sh ' + __dirname + '/install-lilypond.sh')
  , fs.writeFileAsync('input.ly', event.body)
  ).bind({
    key : event.key
  }).then(makeTime.bind(null, 'installation', 'lilypond'))
  .then(exec.bind(
    null,
    'lilypond --formats=pdf,png -o rendered input.ly'
  ))
  .then(function (res) {
    this.result = res
  }).then(makeTime.bind(null, 'lilypond', 'upload'))
  .then(function () {
    return uploadFiles(this.key, this.result)
  }).then(console.timeEnd.bind(console, 'upload'))
  .then(function () {
    context.succeed(this.result)
  }).catch(context.fail.bind(context))
}

function makeTime (end, begin) {
  console.timeEnd(end)
  console.time(begin)
}

function uploadFile (key, file, mode) {
  return fs.readFileAsync(file)
  .then(function (data) {
    return s3.putObjectAsync({
      Bucket      : BUCKET
    , Key         : key
    , Body        : data
    , ContentType : mime[mode]
    , StorageClass: 'REDUCED_REDUNDANCY'
    })
  }, noop)                              // ignore error
}

function uploadFiles (key, res) {
  var pdfPromise = uploadFile(key + '.pdf', 'rendered.pdf', 'pdf')
  var midiPromise = uploadFile(key + '.midi', 'rendered.midi', 'midi')
  var pngPromise = (fs.accessAsync || fs.statAsync)('rendered.png')
    .then(function () {
      res.pages = 1
      return uploadFile(key + '-page1.png', 'rendered.png', 'png')
    }, function () {
      return countPages().then(function (pages) {
        res.pages = pages
        var promises = [];

        for (var i = 1; i <= pages; i ++) {
          promises.push(uploadFile(
            key + '-page' + i + '.png', 'rendered-page' + i + '.png', 'png'
          ))
        }
        return Promise.all(promises)
      })
    })

  return Promise.join(pdfPromise, midiPromise, pngPromise)
}

function countPages () {
  var re = new RegExp('rendered-page.*\.png')
  return fs.readdirAsync('.').then(function (files) {
    return files.filter(re.test.bind(re)).length
  })
}

function noop () {}
<|endoftext|>


<commit_before>'use strict';

var redis = require('redis'),
    coRedis = require('co-redis'),
    koa = require('koa');

var app = koa(),
    client  = redis.createClient(
      process.env.REDIS_PORT,
      process.env.REDIS_HOST
    ),
    dbCo = coRedis(client);

if (process.env.REDIS_SECRET) {
  client.auth(process.env.REDIS_SECRET);
}

client.on('error', function (err) {
  console.log('Redis client error: ' + err);
});

app.use(function* () {

  var indexkey;

  if (this.request.query.index_key) {
    indexkey = process.env.APP_NAME +':'+ this.request.query.index_key;
  } else {
    indexkey = yield dbCo.get(process.env.APP_NAME +':current');
  }
  var index = yield dbCo.get(indexkey);

  this.body = index || '';
});

app.listen(process.env.PORT || 3000);
<commit_msg>Return a 404 in case of empty index<commit_after>'use strict';

var redis = require('redis'),
    coRedis = require('co-redis'),
    koa = require('koa');

var app = koa(),
    client  = redis.createClient(
      process.env.REDIS_PORT,
      process.env.REDIS_HOST
    ),
    dbCo = coRedis(client);

if (process.env.REDIS_SECRET) {
  client.auth(process.env.REDIS_SECRET);
}

client.on('error', function (err) {
  console.log('Redis client error: ' + err);
});

app.use(function* () {

  var indexkey;

  if (this.request.query.index_key) {
    indexkey = process.env.APP_NAME +':'+ this.request.query.index_key;
  } else {
    indexkey = yield dbCo.get(process.env.APP_NAME +':current');
  }
  var index = yield dbCo.get(indexkey);

  if (index) {
    this.body = index;
  } else {
    this.status = 404;
  }
});

app.listen(process.env.PORT || 3000);
<|endoftext|>


<commit_before>// $Id$
(function ($) {

/**
 * Implementation of Drupal.behaviors for admin.
 */
Drupal.behaviors.admin = {
  attach: function() {

    // Set the intial state of the toolbar.
    $('#toolbar', context).once('toolbar', Drupal.admin.toolbar.init);

    // Toggling of admin shortcuts visibility.
    $('#toolbar span.toggle', context).once('toolbar-toggle').click(function() {
      Drupal.admin.toolbar.toggle();
      return false;
    });
  }
};

/**
 * Initialize cautiously to avoid collisions with other modules.
 */
Drupal.admin = Drupal.admin || {};
Drupal.admin.toolbar = Drupal.admin.toolbar || {};

/**
 * Retrieve last saved cookie settings and set up the initial toolbar state.
 */
Drupal.admin.toolbar.init = function() {
  // Retrieve the collapsed status from a stored cookie.
  var collapsed = $.cookie('Drupal.admin.toolbar.collapsed');

  // Expand or collapse the toolbar based on the cookie value.
  if (collapsed == 1) {
    Drupal.admin.toolbar.collapse();
  }
  else {
    Drupal.admin.toolbar.expand();
  }
}

/**
 * Collapse the admin toolbar.
 */
Drupal.admin.toolbar.collapse = function() {
  $('#toolbar div.toolbar-shortcuts').addClass('collapsed');
  $('#toolbar span.toggle').removeClass('toggle-active');
  $('body').removeClass('toolbar-shortcuts');
  $.cookie(
    'Drupal.admin.toolbar.collapsed',
    1,
    {path: Drupal.settings.basePath}
  );
}

/**
 * Expand the admin toolbar.
 */
Drupal.admin.toolbar.expand = function() {
  $('#toolbar div.toolbar-shortcuts').removeClass('collapsed');
  $('#toolbar span.toggle').addClass('toggle-active');
  $('body').addClass('toolbar-shortcuts');
  $.cookie(
    'Drupal.admin.toolbar.collapsed',
    0,
    {path: Drupal.settings.basePath}
  );
}

/**
 * Toggle the admin toolbar.
 */
Drupal.admin.toolbar.toggle = function() {
  if ($('#toolbar div.toolbar-shortcuts').is('.collapsed')) {
    Drupal.admin.toolbar.expand();
  }
  else {
    Drupal.admin.toolbar.collapse();
  }
}

})(jQuery);
<commit_msg>#564528 by roychri: Fixed Error: 'context is not defined' in modules/toolbar/toolbar.js.<commit_after>// $Id$
(function ($) {

/**
 * Implementation of Drupal.behaviors for admin.
 */
Drupal.behaviors.admin = {
  attach: function(context) {

    // Set the intial state of the toolbar.
    $('#toolbar', context).once('toolbar', Drupal.admin.toolbar.init);

    // Toggling of admin shortcuts visibility.
    $('#toolbar span.toggle', context).once('toolbar-toggle').click(function() {
      Drupal.admin.toolbar.toggle();
      return false;
    });
  }
};

/**
 * Initialize cautiously to avoid collisions with other modules.
 */
Drupal.admin = Drupal.admin || {};
Drupal.admin.toolbar = Drupal.admin.toolbar || {};

/**
 * Retrieve last saved cookie settings and set up the initial toolbar state.
 */
Drupal.admin.toolbar.init = function() {
  // Retrieve the collapsed status from a stored cookie.
  var collapsed = $.cookie('Drupal.admin.toolbar.collapsed');

  // Expand or collapse the toolbar based on the cookie value.
  if (collapsed == 1) {
    Drupal.admin.toolbar.collapse();
  }
  else {
    Drupal.admin.toolbar.expand();
  }
}

/**
 * Collapse the admin toolbar.
 */
Drupal.admin.toolbar.collapse = function() {
  $('#toolbar div.toolbar-shortcuts').addClass('collapsed');
  $('#toolbar span.toggle').removeClass('toggle-active');
  $('body').removeClass('toolbar-shortcuts');
  $.cookie(
    'Drupal.admin.toolbar.collapsed',
    1,
    {path: Drupal.settings.basePath}
  );
}

/**
 * Expand the admin toolbar.
 */
Drupal.admin.toolbar.expand = function() {
  $('#toolbar div.toolbar-shortcuts').removeClass('collapsed');
  $('#toolbar span.toggle').addClass('toggle-active');
  $('body').addClass('toolbar-shortcuts');
  $.cookie(
    'Drupal.admin.toolbar.collapsed',
    0,
    {path: Drupal.settings.basePath}
  );
}

/**
 * Toggle the admin toolbar.
 */
Drupal.admin.toolbar.toggle = function() {
  if ($('#toolbar div.toolbar-shortcuts').is('.collapsed')) {
    Drupal.admin.toolbar.expand();
  }
  else {
    Drupal.admin.toolbar.collapse();
  }
}

})(jQuery);
<|endoftext|>


<commit_before>// ControllerRouter class

'use strict';

var includes             = require('es5-ext/array/#/contains')
  , customError          = require('es5-ext/error/custom')
  , identity             = require('es5-ext/function/identity')
  , assign               = require('es5-ext/object/assign')
  , isPromise            = require('es5-ext/object/is-promise')
  , ensureCallable       = require('es5-ext/object/valid-callable')
  , ensureObject         = require('es5-ext/object/valid-object')
  , ensureStringifiable  = require('es5-ext/object/validate-stringifiable-value')
  , forEach              = require('es5-ext/object/for-each')
  , endsWith             = require('es5-ext/string/#/ends-with')
  , ee                   = require('event-emitter')
  , d                    = require('d')
  , autoBind             = require('d/auto-bind')
  , lazy                 = require('d/lazy')
  , compareDynamicRoutes = require('./lib/compare-dynamic-routes')
  , isStatic             = require('./lib/is-token-static')
  , resolvePathMeta      = require('./lib/resolve-path-meta')
  , ensurePath           = require('./lib/ensure-path')

  , push = Array.prototype.push, slice = Array.prototype.slice, apply = Function.prototype.apply
  , create = Object.create, defineProperty = Object.defineProperty, stringify = JSON.stringify
  , routeCallIdIndex = 0;

var ControllerRouter = module.exports = Object.defineProperties(function (routes/*, options*/) {
	var options;
	// Validate initialization
	if (!(this instanceof ControllerRouter)) return new ControllerRouter(routes, arguments[1]);
	options = Object(arguments[1]);
	this.constructor.ensureRoutes(routes, options);

	if (options.eventProto != null) {
		// Override default event prototype
		defineProperty(this, '_eventProto', d(ensureObject(options.eventProto)));
	}

	defineProperty(this, 'routes', d(routes));

	// Configure internal routes map
	forEach(this.constructor.normalizeRoutes(routes, options), function (conf, path) {
		var pathData = resolvePathMeta(path);
		if (pathData.static) {
			this._staticRoutes[path] = conf;
			return;
		}
		if (!this._dynamicRoutes[pathData.tokens.length]) {
			this._dynamicRoutes[pathData.tokens.length] = [];
		}
		pathData.conf = conf;
		pathData.matchPositionsLength = pathData.matchPositions.length;
		this._dynamicRoutes[pathData.tokens.length].push(pathData);
	}, this);
	forEach(this._dynamicRoutes, function (data) { data.sort(compareDynamicRoutes); });

	// Whether route should resolve with promise or not
	if (options.promiseResultImplementation) {
		defineProperty(this, 'Promise', d(ensureCallable(options.promiseResultImplementation)));
	}
}, {
	// Validates provided routes map
	ensureRoutes: d(function (routes) {
		forEach(ensureObject(routes), function (conf, path) {
			var isDynamic;
			ensureObject(conf);
			ensurePath(path);
			if (path !== '/') isDynamic = !path.split('/').every(isStatic);
			if (typeof conf === 'function') {
				if (isDynamic) {
					throw customError("Missing match function for " + stringify(path), 'MISSING_MATCH');
				}
				return;
			}
			if (typeof conf.controller !== 'function') {
				throw customError("Invalid controller for " + stringify(path), 'INVALID_CONTROLLER');
			}
			if (typeof conf.match !== 'function') {
				if (isDynamic) {
					throw customError("Invalid match function for " + stringify(path), 'INVALID_MATCH');
				}
				return;
			}
			if (!isDynamic) {
				throw customError("Missing regular expression in path " + stringify(path),
					'MISSING_PATH_REGEX');
			}
		});
		return routes;
	}),
	// Normalizes routes to bare ControllerRouter format. If ControllerRouter extension
	// provides more sophisticated routes format, this should be a function which transforms it
	// directly to map as understood by ControllerRouter
	normalizeRoutes: d(identity)
});

ee(Object.defineProperties(ControllerRouter.prototype, assign({
	_resolveResult: d(function (result) {
		var routeResult = result;
		if (result && isPromise(result.result)) {
			routeResult = result.result.then(function (resolvedResult) {
				result.result = resolvedResult;
				return result;
			});
		}
		return this.Promise ? this.Promise.resolve(routeResult) : routeResult;
	}),
	_resolveController: d(function (fn) {
		if (!this.Promise) {
			this.lastRouteData.result = fn();
		} else {
			try {
				this.lastRouteData.result = fn();
			} catch (e) {
				return this.Promise.reject(e);
			}
		}
		return this._resolveResult(this.lastRouteData);
	}),

	// Default prototype for an route event
	_eventProto: d(Object.prototype)
}, lazy({
	// Internal map of dynamic routes (those that contain regexp tokens)
	_dynamicRoutes: d(function () { return create(null); }),
	// Internal map of static routes (no regexp tokens)
	_staticRoutes: d(function () { return create(null); })
}), autoBind({
	// Routes path to controller and provides an event to be used for controller invocation
	routeEvent: d(function (event, path/*, …controllerArgs*/) {
		var pathTokens, controllerArgs = slice.call(arguments, 2), conf, initConf, controller
		  , asyncResult, callId = ++routeCallIdIndex;

		ensureObject(event);
		path = ensureStringifiable(path);

		this.emit("route:before", { event: event, path: path, args: controllerArgs });

		// Preprepare route data
		this.lastRouteData = { event: event };

		// Do not proceed for no path
		if (!path) return this._resolveResult(false);

		// Resolve path for route resolution
		if (path[0] === '/') path = path.slice(1);
		if (endsWith.call(path, '/')) path = path.slice(0, -1);
		event.path = path || '/';

		// Handle eventual static path
		conf = this._staticRoutes[path || '/'];
		if (conf) {
			initConf = this.routes[path || '/'];
			controller = conf.controller || conf;
			this.lastRouteData.conf =  initConf;
			return this._resolveController(apply.bind(controller, event, controllerArgs));
		}

		// Handle eventual dynamic paths
		pathTokens = path.split('/');
		if (!this._dynamicRoutes[pathTokens.length]) return this._resolveResult(false);
		this._dynamicRoutes[pathTokens.length].some(function (data) {
			var args = [], matchResult;

			// Check whether path matches
			if (!data.tokens.every(function (token, index) {
					var pathToken = pathTokens[index];
					if (includes.call(data.matchPositions, index)) {
						if (!token.test(pathToken)) return false;
						args.push(pathToken);
						return true;
					}
					return (token === pathToken);
				})) {
				return false;
			}

			// Path matches, now resolve with `match` function
			matchResult = data.conf.match.apply(event, args);
			if (isPromise(matchResult)) {
				asyncResult = matchResult.then(function (isMatch) {
					if (!isMatch) return false;
					this.lastRouteData = {
						event: event,
						conf: this.routes[data.path]
					};
					if (callId !== routeCallIdIndex) {
						// Cancel route (as promises are concerned we need to reject)
						throw customError("Route cancelled, as next one took action", 'OUTDATED_ROUTE_CALL');
					}
					this.lastRouteData.result = apply.call(data.conf.controller, event, controllerArgs);
					return this._resolveResult(this.lastRouteData);
				}.bind(this));
			} else if (matchResult) {
				conf = data.conf;
				initConf = this.routes[data.path];
			}
			return true;
		}, this);

		// If `match` is asynchronous return promise
		if (asyncResult) return this.Promise ? this.Promise.resolve(asyncResult) : asyncResult;
		if (!conf) return this._resolveResult(false);
		this.lastRouteData.conf = initConf;
		return this._resolveController(apply.bind(conf.controller, event, controllerArgs));
	}),

	// Routes path to controller
	route: d(function (path/*, …controllerArgs*/) {
		var args = [create(this._eventProto)];
		push.apply(args, arguments);
		return this.routeEvent.apply(this, args);
	})
}))));
<commit_msg>refactor: do not expose Object.prototype as eventProto<commit_after>// ControllerRouter class

'use strict';

var includes             = require('es5-ext/array/#/contains')
  , customError          = require('es5-ext/error/custom')
  , identity             = require('es5-ext/function/identity')
  , assign               = require('es5-ext/object/assign')
  , isPromise            = require('es5-ext/object/is-promise')
  , ensureCallable       = require('es5-ext/object/valid-callable')
  , ensureObject         = require('es5-ext/object/valid-object')
  , ensureStringifiable  = require('es5-ext/object/validate-stringifiable-value')
  , forEach              = require('es5-ext/object/for-each')
  , endsWith             = require('es5-ext/string/#/ends-with')
  , ee                   = require('event-emitter')
  , d                    = require('d')
  , autoBind             = require('d/auto-bind')
  , lazy                 = require('d/lazy')
  , compareDynamicRoutes = require('./lib/compare-dynamic-routes')
  , isStatic             = require('./lib/is-token-static')
  , resolvePathMeta      = require('./lib/resolve-path-meta')
  , ensurePath           = require('./lib/ensure-path')

  , push = Array.prototype.push, slice = Array.prototype.slice, apply = Function.prototype.apply
  , create = Object.create, defineProperty = Object.defineProperty, stringify = JSON.stringify
  , routeCallIdIndex = 0;

var ControllerRouter = module.exports = Object.defineProperties(function (routes/*, options*/) {
	var options;
	// Validate initialization
	if (!(this instanceof ControllerRouter)) return new ControllerRouter(routes, arguments[1]);
	options = Object(arguments[1]);
	this.constructor.ensureRoutes(routes, options);

	defineProperty(this, '_eventProto', d((options.eventProto != null) ? ensureObject(options.eventProto) : {}));

	defineProperty(this, 'routes', d(routes));

	// Configure internal routes map
	forEach(this.constructor.normalizeRoutes(routes, options), function (conf, path) {
		var pathData = resolvePathMeta(path);
		if (pathData.static) {
			this._staticRoutes[path] = conf;
			return;
		}
		if (!this._dynamicRoutes[pathData.tokens.length]) {
			this._dynamicRoutes[pathData.tokens.length] = [];
		}
		pathData.conf = conf;
		pathData.matchPositionsLength = pathData.matchPositions.length;
		this._dynamicRoutes[pathData.tokens.length].push(pathData);
	}, this);
	forEach(this._dynamicRoutes, function (data) { data.sort(compareDynamicRoutes); });

	// Whether route should resolve with promise or not
	if (options.promiseResultImplementation) {
		defineProperty(this, 'Promise', d(ensureCallable(options.promiseResultImplementation)));
	}
}, {
	// Validates provided routes map
	ensureRoutes: d(function (routes) {
		forEach(ensureObject(routes), function (conf, path) {
			var isDynamic;
			ensureObject(conf);
			ensurePath(path);
			if (path !== '/') isDynamic = !path.split('/').every(isStatic);
			if (typeof conf === 'function') {
				if (isDynamic) {
					throw customError("Missing match function for " + stringify(path), 'MISSING_MATCH');
				}
				return;
			}
			if (typeof conf.controller !== 'function') {
				throw customError("Invalid controller for " + stringify(path), 'INVALID_CONTROLLER');
			}
			if (typeof conf.match !== 'function') {
				if (isDynamic) {
					throw customError("Invalid match function for " + stringify(path), 'INVALID_MATCH');
				}
				return;
			}
			if (!isDynamic) {
				throw customError("Missing regular expression in path " + stringify(path),
					'MISSING_PATH_REGEX');
			}
		});
		return routes;
	}),
	// Normalizes routes to bare ControllerRouter format. If ControllerRouter extension
	// provides more sophisticated routes format, this should be a function which transforms it
	// directly to map as understood by ControllerRouter
	normalizeRoutes: d(identity)
});

ee(Object.defineProperties(ControllerRouter.prototype, assign({
	_resolveResult: d(function (result) {
		var routeResult = result;
		if (result && isPromise(result.result)) {
			routeResult = result.result.then(function (resolvedResult) {
				result.result = resolvedResult;
				return result;
			});
		}
		return this.Promise ? this.Promise.resolve(routeResult) : routeResult;
	}),
	_resolveController: d(function (fn) {
		if (!this.Promise) {
			this.lastRouteData.result = fn();
		} else {
			try {
				this.lastRouteData.result = fn();
			} catch (e) {
				return this.Promise.reject(e);
			}
		}
		return this._resolveResult(this.lastRouteData);
	})

}, lazy({
	// Internal map of dynamic routes (those that contain regexp tokens)
	_dynamicRoutes: d(function () { return create(null); }),
	// Internal map of static routes (no regexp tokens)
	_staticRoutes: d(function () { return create(null); })
}), autoBind({
	// Routes path to controller and provides an event to be used for controller invocation
	routeEvent: d(function (event, path/*, …controllerArgs*/) {
		var pathTokens, controllerArgs = slice.call(arguments, 2), conf, initConf, controller
		  , asyncResult, callId = ++routeCallIdIndex;

		ensureObject(event);
		path = ensureStringifiable(path);

		this.emit("route:before", { event: event, path: path, args: controllerArgs });

		// Preprepare route data
		this.lastRouteData = { event: event };

		// Do not proceed for no path
		if (!path) return this._resolveResult(false);

		// Resolve path for route resolution
		if (path[0] === '/') path = path.slice(1);
		if (endsWith.call(path, '/')) path = path.slice(0, -1);
		event.path = path || '/';

		// Handle eventual static path
		conf = this._staticRoutes[path || '/'];
		if (conf) {
			initConf = this.routes[path || '/'];
			controller = conf.controller || conf;
			this.lastRouteData.conf =  initConf;
			return this._resolveController(apply.bind(controller, event, controllerArgs));
		}

		// Handle eventual dynamic paths
		pathTokens = path.split('/');
		if (!this._dynamicRoutes[pathTokens.length]) return this._resolveResult(false);
		this._dynamicRoutes[pathTokens.length].some(function (data) {
			var args = [], matchResult;

			// Check whether path matches
			if (!data.tokens.every(function (token, index) {
					var pathToken = pathTokens[index];
					if (includes.call(data.matchPositions, index)) {
						if (!token.test(pathToken)) return false;
						args.push(pathToken);
						return true;
					}
					return (token === pathToken);
				})) {
				return false;
			}

			// Path matches, now resolve with `match` function
			matchResult = data.conf.match.apply(event, args);
			if (isPromise(matchResult)) {
				asyncResult = matchResult.then(function (isMatch) {
					if (!isMatch) return false;
					this.lastRouteData = {
						event: event,
						conf: this.routes[data.path]
					};
					if (callId !== routeCallIdIndex) {
						// Cancel route (as promises are concerned we need to reject)
						throw customError("Route cancelled, as next one took action", 'OUTDATED_ROUTE_CALL');
					}
					this.lastRouteData.result = apply.call(data.conf.controller, event, controllerArgs);
					return this._resolveResult(this.lastRouteData);
				}.bind(this));
			} else if (matchResult) {
				conf = data.conf;
				initConf = this.routes[data.path];
			}
			return true;
		}, this);

		// If `match` is asynchronous return promise
		if (asyncResult) return this.Promise ? this.Promise.resolve(asyncResult) : asyncResult;
		if (!conf) return this._resolveResult(false);
		this.lastRouteData.conf = initConf;
		return this._resolveController(apply.bind(conf.controller, event, controllerArgs));
	}),

	// Routes path to controller
	route: d(function (path/*, …controllerArgs*/) {
		var args = [create(this._eventProto)];
		push.apply(args, arguments);
		return this.routeEvent.apply(this, args);
	})
}))));
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as formatActions from '../../actions/formatActions';
import FormatForm from './FormatForm';

class ManageFormatPage extends React.Component {
    constructor(props, context) {
        super(props, context);

        this.state = {
            format: Object.assign({}, props.format),
            errors: {}
        };

        this.updateFormatState = this.updateFormatState.bind(this);
        this.save = this.save.bind(this);
    }

    updateFormatState(event) {
        let field = event.target.name;
        let format = Object.assign({}, this.state.format);
        format[field] = event.target.value;
        return this.setState({format: format});
    }

    save(event) {
        event.preventDefault();
        this.props.actions
            .saveFormat(this.state.format)
            .then(() => this.redirectToFormatsPage());
    }

    redirectToFormatsPage() {
        this.context.router.history.push("/formats");
    }

    render() {
        return (
            <FormatForm
                format={this.state.format}
                errors={this.state.errors}
                onChange={this.updateFormatState}
                onSave={this.save} />
        );
    }
}

ManageFormatPage.propTypes = {
    format: PropTypes.object.isRequired,
    actions: PropTypes.object.isRequired
};

ManageFormatPage.contextTypes = {
    router: PropTypes.object
};

function mapStateToProps(state, ownProps) {
    let id = ownProps.match.params.id;
    let format;
    if (id) {
        format = state.formats.find(it => it.id == id);
    } else {
        format = { name: '', id: '' };
    }
    return {
        format: format
    };
}

function mapDispatchToProps(dispatch) {
    return {
        actions: bindActionCreators(formatActions, dispatch)
    };
}

export default connect(mapStateToProps, mapDispatchToProps)(ManageFormatPage);
<commit_msg>Format Page Show button 'save' disabled when saving in progress and indicate saving progress Close #3<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as formatActions from '../../actions/formatActions';
import FormatForm from './FormatForm';

class ManageFormatPage extends React.Component {
    constructor(props, context) {
        super(props, context);

        this.state = {
            format: Object.assign({}, props.format),
            saving: false,
            errors: {}
        };

        this.updateFormatState = this.updateFormatState.bind(this);
        this.save = this.save.bind(this);
    }

    updateFormatState(event) {
        let field = event.target.name;
        let format = Object.assign({}, this.state.format);
        format[field] = event.target.value;
        return this.setState({format: format});
    }

    save(event) {
        event.preventDefault();
        this.setState({ saving: true })
        this.props.actions
            .saveFormat(this.state.format)
            .then(() => {
                this.setState({ saving: false });
                this.redirectToFormatsPage();
            });
    }

    redirectToFormatsPage() {
        this.context.router.history.push("/formats");
    }

    render() {
        return (
            <FormatForm
                format={this.state.format}
                errors={this.state.errors}
                onChange={this.updateFormatState}
                onSave={this.save}
                saving={this.state.saving} />
        );
    }
}

ManageFormatPage.propTypes = {
    format: PropTypes.object.isRequired,
    actions: PropTypes.object.isRequired
};

ManageFormatPage.contextTypes = {
    router: PropTypes.object
};

function mapStateToProps(state, ownProps) {
    let id = ownProps.match.params.id;
    let format;
    if (id) {
        format = state.formats.find(it => it.id == id);
    } else {
        format = { name: '', id: '' };
    }
    return {
        format: format
    };
}

function mapDispatchToProps(dispatch) {
    return {
        actions: bindActionCreators(formatActions, dispatch)
    };
}

export default connect(mapStateToProps, mapDispatchToProps)(ManageFormatPage);
<|endoftext|>


<commit_before>"use strict";
$(function(){

	var touchStartX = 0;
	var touchStartY = 0;

	var animationEndVendors = "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend";
	var viewport = getViewport();

	$(window).on("resize", function(e){
		resizePages();
	});

	resizePages();

	$(".hollow.secondary").on("click", function(e){

		e.preventDefault();

		$("#testInput").css("-webkit-animation-duration", "0.5s");
		$("#testInput").css("-webkit-animation-delay", "0s");
		$("#testInput").addClass("animated fadeInUp").one(animationEndVendors, function() {
			$(this).removeClass("animated fadeInUp");
		});

	});

	$("body").on("touchstart", ".scrollable", function(e){
		if (e.currentTarget.scrollTop === 0) {
			e.currentTarget.scrollTop = 1;
		} else if (e.currentTarget.scrollHeight === e.currentTarget.scrollTop + e.currentTarget.offsetHeight) {
			e.currentTarget.scrollTop -= 1;
		}

		touchStartX = e.originalEvent.touches[0].pageX;
		touchStartY = e.originalEvent.touches[0].pageY;
	});

	$('body').on('touchmove', ".scrollable", function(e) {
		e.stopPropagation();
	  	if(Math.abs(touchStartX - e.originalEvent.touches[0].pageX)
	    		> Math.abs(touchStartY - e.originalEvent.touches[0].pageY)) {
    		e.preventDefault();
    	}
	});

	$(document).on('touchmove', function(e) {
		e.preventDefault();
	});

	$(".nextPage").on("click", function(e) {

		e.preventDefault();

		goToNextPageHorizontal($(this));
	});

	$(".previousPage").on("click", function(e){

		e.preventDefault();

		goToPreviousPageHorizontal($(this));
	});

	$(".seeMore").on("click", function(e){

		e.preventDefault();

		goToNextPageVertical($(this));
	});

	$(".seeLess").on("click", function(e){

		e.preventDefault();

		goToPreviousPageVertical($(this));
	});

	$(".top-bar a, .anchor").on("click", function(e){

		e.preventDefault();

		var $linkTarget = $($(this).attr("href"));

		if($linkTarget && $linkTarget.offset()) {

			$(".activePage").addClass("animated fadeOut").one(animationEndVendors, function() {

				$(this).removeClass("animated fadeOut");

				$(window).scrollLeft($linkTarget.offset().left);
				$(window).scrollTop($linkTarget.offset().top);

				$(".activePage").addClass("animated fadeIn").one(animationEndVendors, function() {
					$(this).removeClass("animated fadeIn");
				});
			});

			setNewActivePage($(this));
		}
	});

	// listen to keydown event
	// to allow arrow navigation
	$("body").on("keydown", function(e){
		switch(e.keyCode) {
			case 37:
				console.log("left");
				if($(".activePage .previousPage").length > 0) {
					goToPreviousPageHorizontal($(".activePage .previousPage"));
				}
				break;
			case 38:
				console.log("up");
				// make sure the user hasn't scrolled down
				if($(".activePage > .pageContent").scrollTop() === 0) {
					if($(".activePage .seeLess").length > 0) {
						goToPreviousPageVertical($(".activePage .seeLess"));
					}
				}
				break;
			case 39:
				console.log("right");
				if($(".activePage .nextPage").length > 0) {
					goToNextPageHorizontal($(".activePage .nextPage"));
				}
				break;
			case 40:
				console.log("down");
				// make sure the user has scrolled down to the bottom
				if($(".activePage > .pageContent").prop("scrollHeight")
					=== $(".activePage > .pageContent").height() + $(".activePage > .pageContent").scrollTop()) {

					if($(".activePage .seeMore").length > 0) {
						goToNextPageVertical($(".activePage .seeMore"));
					}
				}
				break;
			default:
				return;
		}
	});

});

$(window).on("load", function(){

	setInitialActivePage();

});

function resizePages() {

	var viewport = getViewport();

	alert(JSON.stringify(viewport));

	$("html, body").css("min-width", viewport.width * 4);

	$(".page").each(function(){

		$(this).css("width", viewport.width);
		$(this).css("height", viewport.height);

		$(this).find(".pageContent").css("width", viewport.width);
		$(this).find(".pageContent").css("height", viewport.height);

		if($(this).hasClass("activePage")){
			var $activePageOffset = $(this).offset();
			$("html, body").scrollLeft($activePageOffset.left);
			$("html, body").scrollTop($activePageOffset.top);
		}

		if($(this).find(".pageContent").prop("scrollHeight") > viewport.height) {
			$(this).addClass("scrollable");
		} else {
			if($(this).hasClass("scrollable")) {
				$(this).removeClass("scrollable");
			}
		}
	});
}

function setInitialActivePage() {

	var windowScrollLeft = $(window).scrollLeft(),
		windowScrollTop = $(window).scrollTop();

	$(".page").each(function(){

		if(Math.abs($(this).offset().left - windowScrollLeft) < 1
			&& Math.abs($(this).offset().top - windowScrollTop) < 1) {
			$(this).addClass("activePage");
		}

	});
}

function setNewActivePage($link) {
	$(".activePage").removeClass("activePage");
	$($link.attr("href")).addClass("activePage");
}

function getViewport() {
    var container = window, property = "inner";
    if (!("innerWidth" in window )) {
       property = "client";
       container = document.documentElement || document.body;
    }
    return { width : container[property + "Width"], height : container[property + "Height"]};
}

function goToNextPageHorizontal($link) {

	if(!$(".content").hasClass("isPageScrolling")) {

		setNewActivePage($link);

		$(".content").addClass("isPageScrolling");

		$("html, body").animate({
			scrollLeft: $(window).scrollLeft() + $(".page").width()
		},
		{
			duration: 800,
			complete: function() {
				$(".content").removeClass("isPageScrolling");
			}
		});
	}
}

function goToPreviousPageHorizontal($link) {

	if(!$(".content").hasClass("isPageScrolling")) {

		setNewActivePage($link);

		$(".content").addClass("isPageScrolling");

		$("html, body").animate({
			scrollLeft: $(window).scrollLeft() - $(".page").width()
		},
		{
			duration: 800,
			complete: function() {
				$(".content").removeClass("isPageScrolling");
			}
		});
	}
}

function goToNextPageVertical($link) {

	if(!$(".content").hasClass("isPageScrolling")) {

		setNewActivePage($link);

		$(".content").addClass("isPageScrolling");

		$("html, body").animate({
			scrollTop: $(window).scrollTop() + $(".page").height()
		},
		{
			duration: 800,
			complete: function() {
				$(".content").removeClass("isPageScrolling");
			}
		});
	}
}

function goToPreviousPageVertical($link) {

	if(!$(".content").hasClass("isPageScrolling")) {

		setNewActivePage($link);

		$(".content").addClass("isPageScrolling");

		$("html, body").animate({
			scrollTop: $(window).scrollTop() - $(".page").height()
		},
		{
			duration: 800,
			complete: function() {
				$(".content").removeClass("isPageScrolling");
			}
		});
	}
}
<commit_msg>mobile debug<commit_after>"use strict";
$(function(){

	var touchStartX = 0;
	var touchStartY = 0;

	var animationEndVendors = "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend";
	var viewport = getViewport();

	$(window).on("resize", function(e){
		resizePages();
	});

	resizePages();

	$(".hollow.secondary").on("click", function(e){

		e.preventDefault();

		$("#testInput").css("-webkit-animation-duration", "0.5s");
		$("#testInput").css("-webkit-animation-delay", "0s");
		$("#testInput").addClass("animated fadeInUp").one(animationEndVendors, function() {
			$(this).removeClass("animated fadeInUp");
		});

	});

	$("body").on("touchstart", ".scrollable", function(e){
		if (e.currentTarget.scrollTop === 0) {
			e.currentTarget.scrollTop = 1;
		} else if (e.currentTarget.scrollHeight === e.currentTarget.scrollTop + e.currentTarget.offsetHeight) {
			e.currentTarget.scrollTop -= 1;
		}

		touchStartX = e.originalEvent.touches[0].pageX;
		touchStartY = e.originalEvent.touches[0].pageY;
	});

	$('body').on('touchmove', ".scrollable", function(e) {
		e.stopPropagation();
	  	if(Math.abs(touchStartX - e.originalEvent.touches[0].pageX)
	    		> Math.abs(touchStartY - e.originalEvent.touches[0].pageY)) {
    		e.preventDefault();
    	}
	});

	$(document).on('touchmove', function(e) {
		e.preventDefault();
	});

	$(".nextPage").on("click", function(e) {

		e.preventDefault();

		goToNextPageHorizontal($(this));
	});

	$(".previousPage").on("click", function(e){

		e.preventDefault();

		goToPreviousPageHorizontal($(this));
	});

	$(".seeMore").on("click", function(e){

		e.preventDefault();

		goToNextPageVertical($(this));
	});

	$(".seeLess").on("click", function(e){

		e.preventDefault();

		goToPreviousPageVertical($(this));
	});

	$(".top-bar a, .anchor").on("click", function(e){

		e.preventDefault();

		var $linkTarget = $($(this).attr("href"));

		if($linkTarget && $linkTarget.offset()) {

			$(".activePage").addClass("animated fadeOut").one(animationEndVendors, function() {

				$(this).removeClass("animated fadeOut");

				$(window).scrollLeft($linkTarget.offset().left);
				$(window).scrollTop($linkTarget.offset().top);

				$(".activePage").addClass("animated fadeIn").one(animationEndVendors, function() {
					$(this).removeClass("animated fadeIn");
				});
			});

			setNewActivePage($(this));
		}
	});

	// listen to keydown event
	// to allow arrow navigation
	$("body").on("keydown", function(e){
		switch(e.keyCode) {
			case 37:
				console.log("left");
				if($(".activePage .previousPage").length > 0) {
					goToPreviousPageHorizontal($(".activePage .previousPage"));
				}
				break;
			case 38:
				console.log("up");
				// make sure the user hasn't scrolled down
				if($(".activePage > .pageContent").scrollTop() === 0) {
					if($(".activePage .seeLess").length > 0) {
						goToPreviousPageVertical($(".activePage .seeLess"));
					}
				}
				break;
			case 39:
				console.log("right");
				if($(".activePage .nextPage").length > 0) {
					goToNextPageHorizontal($(".activePage .nextPage"));
				}
				break;
			case 40:
				console.log("down");
				// make sure the user has scrolled down to the bottom
				if($(".activePage > .pageContent").prop("scrollHeight")
					=== $(".activePage > .pageContent").height() + $(".activePage > .pageContent").scrollTop()) {

					if($(".activePage .seeMore").length > 0) {
						goToNextPageVertical($(".activePage .seeMore"));
					}
				}
				break;
			default:
				return;
		}
	});

});

$(window).on("load", function(){

	setInitialActivePage();

});

function resizePages() {

	var viewport = getViewport();

	// alert(JSON.stringify(viewport));

	$("html, body").css("min-width", viewport.width * 4);

	$(".page").each(function(){

		$(this).css("width", viewport.width);
		$(this).css("height", viewport.height);

		$(this).find(".pageContent").css("width", viewport.width);
		$(this).find(".pageContent").css("height", viewport.height);

		if($(this).hasClass("activePage")){
			var $activePageOffset = $(this).offset();
			// $("html, body").scrollLeft($activePageOffset.left);
			// $("html, body").scrollTop($activePageOffset.top);
			window.scrollTo($activePageOffset.left, $activePageOffset.top);
		}

		if($(this).find(".pageContent").prop("scrollHeight") > viewport.height) {
			$(this).addClass("scrollable");
		} else {
			if($(this).hasClass("scrollable")) {
				$(this).removeClass("scrollable");
			}
		}
	});
}

function setInitialActivePage() {

	var windowScrollLeft = $(window).scrollLeft(),
		windowScrollTop = $(window).scrollTop();

	$(".page").each(function(){

		if(Math.abs($(this).offset().left - windowScrollLeft) < 1
			&& Math.abs($(this).offset().top - windowScrollTop) < 1) {
			$(this).addClass("activePage");
		}

	});
}

function setNewActivePage($link) {
	$(".activePage").removeClass("activePage");
	$($link.attr("href")).addClass("activePage");
}

function getViewport() {
    var container = window, property = "inner";
    if (!("innerWidth" in window )) {
       property = "client";
       container = document.documentElement || document.body;
    }
    return { width : container[property + "Width"], height : container[property + "Height"]};
}

function goToNextPageHorizontal($link) {

	if(!$(".content").hasClass("isPageScrolling")) {

		setNewActivePage($link);

		$(".content").addClass("isPageScrolling");

		$("html, body").animate({
			scrollLeft: $(window).scrollLeft() + $(".page").width()
		},
		{
			duration: 800,
			complete: function() {
				$(".content").removeClass("isPageScrolling");
			}
		});
	}
}

function goToPreviousPageHorizontal($link) {

	if(!$(".content").hasClass("isPageScrolling")) {

		setNewActivePage($link);

		$(".content").addClass("isPageScrolling");

		$("html, body").animate({
			scrollLeft: $(window).scrollLeft() - $(".page").width()
		},
		{
			duration: 800,
			complete: function() {
				$(".content").removeClass("isPageScrolling");
			}
		});
	}
}

function goToNextPageVertical($link) {

	if(!$(".content").hasClass("isPageScrolling")) {

		setNewActivePage($link);

		$(".content").addClass("isPageScrolling");

		$("html, body").animate({
			scrollTop: $(window).scrollTop() + $(".page").height()
		},
		{
			duration: 800,
			complete: function() {
				$(".content").removeClass("isPageScrolling");
			}
		});
	}
}

function goToPreviousPageVertical($link) {

	if(!$(".content").hasClass("isPageScrolling")) {

		setNewActivePage($link);

		$(".content").addClass("isPageScrolling");

		$("html, body").animate({
			scrollTop: $(window).scrollTop() - $(".page").height()
		},
		{
			duration: 800,
			complete: function() {
				$(".content").removeClass("isPageScrolling");
			}
		});
	}
}
<|endoftext|>


<commit_before>'use strict';

const express = require('express');

const config;
config.Port = process.env.PORT || 3000;

//const app = express();
//app.set('view engine', 'ejs');
//app.use(express.static('public'));

var http = require('http');

var server = http.createServer(function(request, response) {

    response.writeHead(200, {"Content-Type": "text/plain"});
    response.end("Hello Azure: 1!");

});

server.listen(config.Port);

console.log("Server running at http://localhost:%d", port);
<commit_msg>syntax<commit_after>'use strict';

const express = require('express');

let config;
config.Port = process.env.PORT || 3000;

const app = express();
//app.set('view engine', 'ejs');
//app.use(express.static('public'));

var http = require('http');

var server = http.createServer(function(request, response) {

    response.writeHead(200, {"Content-Type": "text/plain"});
    response.end("Hello Azure: 1!");

});

server.listen(config.Port);

console.log("Server running at http://localhost:%d", port);
<|endoftext|>


<commit_before>let RxSlack = require('./lib/rxslack.js').RxSlack;
let fs = require('fs');
const token = process.env.RECV_TOKEN;
var Rx = require('rxjs/Rx');

let slack = new RxSlack(token);

slack.onMessage
    .subscribe(message => console.log(message.toString()) );

slack.start();

<commit_msg>Removed debugging code from index.js. Now exporting RxSlack.<commit_after>module.exports = {
    RxSlack: require('./lib/rxslack.js').RxSlack
};<|endoftext|>


<commit_before>var Ug = function($) {

  var autoScrolling = false;

  /* window querying */

  function $majorSectionBody($section) {
    return $section.closest('.js-ug-section-major').find('.js-ug-section-major-body');
  }

  function viewportWidth() {
    if ('innerWidth' in window) {
      return window.innerWidth;
    } else if ('documentElement' in document) {
      return document.documentElement.clientWidth;
    } else {
      return document.body.clientWidth;
    }
  }

  function wideView(width) {
    return (typeof width === 'undefined' ? $(window).width() : width) > 800;
  }

  function inViewport(elem) {
    var bounds = elem.getBoundingClientRect();
    return bounds.top < window.innerHeight && bounds.bottom > 0;
  };

  /* text manipulation */

  function squashedTextContent($element) {
    return $element.text().replace(/\s+/g, ' ');
  }

  /* menu and navigation - wide window */

  function scrollTo($section) {
    var targetPosition = $section.offset().top;
    autoScrolling = true;
    $('html, body').stop().animate(
      { 'scrollTop': targetPosition },
      'fast',
      function() {
        selectMenuItemFor($section);
        autoScrolling = false;
      }
    );
  }

  function $createInternalLink($header) {
    var text = squashedTextContent($header);
    var id = $header.closest('.js-ug-section').prop('id');
    return $('' + text + '');
  }

  function contractMenu() {
    $('nav ul ul').hide();

  }

  function expandMenuItem($menuListItem) {
    $menuListItem.parent().show();
    $menuListItem.children('ul').show();
  }

  function contractMenuItem($menuListItem) {
    $menuListItem.children('ul').hide();
  }

  function selectMenuItemFor($section) {
    var $link = $('nav [href="#' + $section.prop('id') + '"]');
    if ($link.size() === 0) {
      selectMenuItemFor($section.parent().closest('.js-ug-section'));
    } else {
      var $menuItem = $link.closest('li');
      contractMenu();
      expandMenuItem($menuItem);
      $menuItem.children('a').focus();
    }
  }

  function createMenu() {
    var $nav = $('nav');
    var $ul = $('

').appendTo($nav);
    $('h2').each(function(index, header) {
      var $header = $(header);
      var $listItem = $('

').append($createInternalLink($header)).appendTo($ul);
      var $subHeaders = $header.closest('.js-ug-section').find('h3');
      if ($subHeaders.size() !== 0) {
        var $subList = $('

');
        $subHeaders.each(function(index, subHeader) {
          var $subHeader = $(subHeader);
          $('

').
            append($createInternalLink($subHeader)).
            appendTo($subList);
        });
        $subList.appendTo($listItem);
      }
    });
    configureForSize();
    contractMenu();
  }

  function enableScrollToTop() {
    $('.js-ug-scroll-to-top').click(contractMenu);
  }

  function activateMenuItemsOnScroll() {
    $('.js-ug-section').waypoint(function(direction) {
      if (!autoScrolling) {
        var hash = window.location.hash;
        if (hash.length > 1) {
          var $hashSection = $(hash);
          if (inViewport($hashSection[0])) {
            selectMenuItemFor($hashSection);
            return;
          }
        }
        selectMenuItemFor($(this));
      }
    });
  }

  function expandMenuForHash() {
    var hash = window.location.hash;
    if (hash.length > 0) {
      var $hashSection = $(hash);
      selectMenuItemFor($hashSection);
      $majorSectionBody($hashSection).show();
    }
  }

  /* toggling sections - for narrow window */

  function toggleMajorSection(event) {
    event.preventDefault();
    event.stopPropagation();
    $majorSectionBody($(this)).toggle();
  }

  /* internal links to headed sections */

  function configureAutolinks() {
    $('.js-ug-internal-link').click(function(event) {
      var $section = $($(this).attr('href'));
      $majorSectionBody($section).show();
      scrollTo($section);
    });
  }

  /* set things up depending on the viewport width */

  function configureForSize() {
    var width = viewportWidth();
    var w = Math.max(width * 0.25, 200);
    if (wideView(width)) {
      $('#ug-left-sidebar, nav').width(w);
      $('#ug-left-sidebar').show();
      $('#ug-main').css({ 'margin-left': w + 20 + 'px' });
      $('.js-ug-section-major-body').show();
      $('.clickable-title').unwrap();
      $('.js-ug-section-major-title').each(function() {
        $(this).removeClass('clickable-title').off('click', toggleMajorSection);
      });
    } else {
      $('#ug-left-sidebar, nav').width(width);
      $('#ug-main').css({ 'margin-left': '0' });
      $('.js-ug-section-major-body').hide();
      $('.js-ug-section-major-title:not(.clickable-title)').each(function() {
        var $title = $(this);
        var $section = $title.closest('.js-ug-section');
        var sectionId = $section.prop('id');
        $title
          .on('click', toggleMajorSection)
          .addClass('clickable-title')
          .wrap('');
      });
    }
  }

  /* initialize */

  function initialize() {
    createMenu();
    activateMenuItemsOnScroll();
    configureAutolinks();
    contractMenu();
    expandMenuForHash();
    $(window).resize(configureForSize);
  }

  return {
    initialize: initialize
  }

}(jQuery);

$(document).ready(Ug.initialize);
<commit_msg>User guide: fix opening internal link in new tab for narrow screens.<commit_after>var Ug = function($) {

  var autoScrolling = false;

  /* window querying */

  function $majorSectionBody($section) {
    return $section.closest('.js-ug-section-major').find('.js-ug-section-major-body');
  }

  function viewportWidth() {
    if ('innerWidth' in window) {
      return window.innerWidth;
    } else if ('documentElement' in document) {
      return document.documentElement.clientWidth;
    } else {
      return document.body.clientWidth;
    }
  }

  function wideView(width) {
    return (typeof width === 'undefined' ? $(window).width() : width) > 800;
  }

  function inViewport(elem) {
    var bounds = elem.getBoundingClientRect();
    return bounds.top < window.innerHeight && bounds.bottom > 0;
  };

  /* text manipulation */

  function squashedTextContent($element) {
    return $element.text().replace(/\s+/g, ' ');
  }

  /* menu and navigation - wide window */

  function scrollTo($section) {
    var targetPosition = $section.offset().top;
    autoScrolling = true;
    $('html, body').stop().animate(
      { 'scrollTop': targetPosition },
      'fast',
      function() {
        selectMenuItemFor($section);
        autoScrolling = false;
      }
    );
  }

  function $createInternalLink($header) {
    var text = squashedTextContent($header);
    var id = $header.closest('.js-ug-section').prop('id');
    return $('' + text + '');
  }

  function contractMenu() {
    $('nav ul ul').hide();

  }

  function expandMenuItem($menuListItem) {
    $menuListItem.parent().show();
    $menuListItem.children('ul').show();
  }

  function contractMenuItem($menuListItem) {
    $menuListItem.children('ul').hide();
  }

  function selectMenuItemFor($section) {
    var $link = $('nav [href="#' + $section.prop('id') + '"]');
    if ($link.size() === 0) {
      selectMenuItemFor($section.parent().closest('.js-ug-section'));
    } else {
      var $menuItem = $link.closest('li');
      contractMenu();
      expandMenuItem($menuItem);
      $menuItem.children('a').focus();
    }
  }

  function createMenu() {
    var $nav = $('nav');
    var $ul = $('

').appendTo($nav);
    $('h2').each(function(index, header) {
      var $header = $(header);
      var $listItem = $('

').append($createInternalLink($header)).appendTo($ul);
      var $subHeaders = $header.closest('.js-ug-section').find('h3');
      if ($subHeaders.size() !== 0) {
        var $subList = $('

');
        $subHeaders.each(function(index, subHeader) {
          var $subHeader = $(subHeader);
          $('

').
            append($createInternalLink($subHeader)).
            appendTo($subList);
        });
        $subList.appendTo($listItem);
      }
    });
    configureForSize();
    contractMenu();
  }

  function enableScrollToTop() {
    $('.js-ug-scroll-to-top').click(contractMenu);
  }

  function activateMenuItemsOnScroll() {
    $('.js-ug-section').waypoint(function(direction) {
      if (!autoScrolling) {
        var hash = window.location.hash;
        if (hash.length > 1) {
          var $hashSection = $(hash);
          if (inViewport($hashSection[0])) {
            selectMenuItemFor($hashSection);
            return;
          }
        }
        selectMenuItemFor($(this));
      }
    });
  }

  function positionForHash() {
    var hash = window.location.hash;
    if (hash.length > 0) {
      var $hashSection = $(hash);
      $majorSectionBody($hashSection).show();
      scrollTo($hashSection);
    }
  }

  /* toggling sections - for narrow window */

  function toggleMajorSection(event) {
    event.preventDefault();
    event.stopPropagation();
    $majorSectionBody($(this)).toggle();
  }

  /* internal links to headed sections */

  function configureAutolinks() {
    $('.js-ug-internal-link').click(function(event) {
      var $section = $($(this).attr('href'));
      $majorSectionBody($section).show();
      scrollTo($section);
    });
  }

  /* set things up depending on the viewport width */

  function configureForSize() {
    var width = viewportWidth();
    var w = Math.max(width * 0.25, 200);
    if (wideView(width)) {
      $('#ug-left-sidebar, nav').width(w);
      $('#ug-left-sidebar').show();
      $('#ug-main').css({ 'margin-left': w + 20 + 'px' });
      $('.js-ug-section-major-body').show();
      $('.clickable-title').unwrap();
      $('.js-ug-section-major-title').each(function() {
        $(this).removeClass('clickable-title').off('click', toggleMajorSection);
      });
    } else {
      $('#ug-left-sidebar, nav').width(width);
      $('#ug-main').css({ 'margin-left': '0' });
      $('.js-ug-section-major-body').hide();
      $('.js-ug-section-major-title:not(.clickable-title)').each(function() {
        var $title = $(this);
        var $section = $title.closest('.js-ug-section');
        var sectionId = $section.prop('id');
        $title
          .on('click', toggleMajorSection)
          .addClass('clickable-title')
          .wrap('');
      });
    }
  }

  /* initialize */

  function initialize() {
    createMenu();
    activateMenuItemsOnScroll();
    configureAutolinks();
    contractMenu();
    positionForHash();
    $(window).resize(configureForSize);
  }

  return {
    initialize: initialize
  }

}(jQuery);

$(document).ready(Ug.initialize);
<|endoftext|>


<commit_before>var fs = require('fs');
var find = require("find");
var dummyjson = require('dummy-json');
var Promise = require('promise');
var sessionManagerModule = require(__dirname + '/../session-manager');
var Cookies = require( "cookies" );

// Best to use one shared session manager across requests
var sessionManager = sessionManagerModule.create({engine: 'memory'});
var User = require(__dirname+"/user");

if(!fs.existsSync('app')){
  fs.mkdirSync("app");
}
if(!fs.existsSync('app/data')){
  fs.mkdirSync("app/data");
}
if(!fs.existsSync('app/controller')){
  fs.mkdirSync("app/controller");
}

if(!fs.existsSync('app/helper.json')){
  fs.writeFileSync("app/helper.json", JSON.stringify({
    "name": ["Amar", "Akabar"]
  },null, "\t"));
}

var helperJSON = JSON.parse(fs.readFileSync("app/helper.json", {encoding: 'utf8'}));

var randomVal = function(type) {
	  return helperJSON[type][dummyjson.randomInt(0,helperJSON[type].length-1)];
};

var helpers = {};
Object.keys(helperJSON).map(function(key){
	helpers[key] = function(options){
		return randomVal(key);
	};
});

var MAPPERS = [];

function registerMapper(mapper,options){

  var matcher = new RegExp("^"+mapper.replace(/\{(.*?)\}/gi,'([a-z-A-Z])+').replace(/\//gi,"\/").replace(/\*/gi,"(.)*")+"$")
  var tokens =   (mapper).split(/[\/]+/gi);

  var placeholders = tokens.map(function(str,index){
    return {
      param : str.match(/(\{([^}]+)\}|\*)/g)
    }
  }).filter(function(obj,i){
    if(obj.param!=null && obj.param.length!=0){
      obj.index = i;
      obj.param = obj.param[0].substring(1, obj.param[0].length - 1)

      return true;
    }
    return false;
  });

  MAPPERS.push({
    mapper :  mapper,
    placeholders : placeholders,
    matcher : matcher, tokens : tokens,
    roles : options.roles || []
  });
  return MAPPERS[MAPPERS.length-1];
}

var router = {
  on : function(mapOrUrl,callback){
    var mapObj = {};
    if(typeof mapOrUrl === "string"){
      mapObj = registerMapper(mapOrUrl,{});
    } else {
      mapObj = registerMapper(mapOrUrl.url,mapOrUrl);
    }
    var headStr = callback.toString().split("{")[0]; //headStr will look like this: "function(jq, abc, xyz)">>string
    var headStrArg = headStr.substr(headStr.indexOf("(") + 1).split(")")[0]; //headStrArg will look like : "jq, abc, xyz">>string
    var depList;
    if (headStrArg === "") {
      depList = [];
    } else {
      depList = headStrArg.split(","); //deptList will look like: [jq, abc, xyz] >>array
    }
    for (var y = 0; y < depList.length; y++) {
      depList[y] = depList[y].trim(); //trim to remove whitespace from both ends of string
    }
    mapObj.argList = depList;
    mapObj.argParams = mapObj.argList.map(function(arg){
      return (mapObj.placeholders.filter(function(placeholder){
        return placeholder.param === arg;
      }) || [])[0];
    });
    mapObj.callback = callback;
  }
};

find.file("app/controller", function(files) {
  for(var i in files){
    var filez = files[i].split(/[\/]+/gi);
    require(process.env.PWD+"/"+files[i].replace(/\.js$/,""))(router);
  }
});

var Controller = require(__dirname+"/controller");

module.exports = function(req,resp,dir, next){
  var user;
  var cookies = new Cookies( req, resp);
  var session = sessionManager.start(req, resp);
  if(true){
    var dirs = req._parsedUrl.pathname.split("/");
    dirs.pop(); dirs = dirs.join("/");
    var session_id = session.getSessionId();
    cookies.set(sessionManagerModule.create.sessionIDCookieName,undefined,{ path : dirs });
    cookies.set(sessionManagerModule.create.sessionIDCookieName,session_id,{ path : "/" });
  }

  user = session.get("__USER__") || new User();
  user.__xscount__ ++;

	var method = "GET";//req.method;
  var pathname = req._parsedUrl.pathname;
  var PATHTokens = pathname.split(/[\/]+/gi);

  var tokenDiff = 10000;
  var MAPPER = null;
  for(var i in MAPPERS){
    var _tokenDiff = PATHTokens.length - MAPPERS[i].tokens.length;
    //console.log("======",MAPPERS[i].matcher,user.role,pathname);
    if(MAPPERS[i].matcher.test(pathname)
      && _tokenDiff<=tokenDiff && _tokenDiff>-1
      && (MAPPERS[i].roles.length==0 || MAPPERS[i].roles.indexOf(user.role) >= 0)){
      tokenDiff = _tokenDiff;
      MAPPER = MAPPERS[i];
    }
  }

  if(MAPPER){

    var controller = new Controller(req,resp,{
      helpers : helpers
    });

    //if(session){
      controller.user = user;
      controller.session = session;
      controller.cookies = cookies;
      session.set("__USER__", user);
    //}

    var retObj = MAPPER.callback.apply(controller,
      MAPPER.argParams.map(function(param){
        return PATHTokens[param.index];
      }));
    if(retObj !== undefined && typeof retObj.done === 'function' && typeof retObj.finally === 'function'){
      retObj.then(function(retresp){
        resp.write(retresp);
      }).finally(function(resp){
        console.log("finally",resp);
        next();
      });
    } else {
      next();
    }
  } else {
    console.error("No URL Mapping Found");
    //resp.write(JSON.stringify({ x : "No URL Mapping Found" }));
    var filepath = dir+req.originalUrl.split("?")[0]+".res";
    if(fs.existsSync(filepath)){
      resp.write(
        dummyjson.parse(
          fs.readFileSync(filepath, {encoding: 'utf8'}),
          {helpers: helpers}
        )
      );
    } else {
      console.error(filepath, "Not Found");
      resp.writeHead(404,{ message : " File Not Found", file : filepath});
    }
    next();
  }
};<commit_msg>token Type fix<commit_after>var fs = require('fs');
var find = require("find");
var dummyjson = require('dummy-json');
var Promise = require('promise');
var sessionManagerModule = require(__dirname + '/../session-manager');
var Cookies = require( "cookies" );

// Best to use one shared session manager across requests
var sessionManager = sessionManagerModule.create({engine: 'memory'});
var User = require(__dirname+"/user");

if(!fs.existsSync('app')){
  fs.mkdirSync("app");
}
if(!fs.existsSync('app/data')){
  fs.mkdirSync("app/data");
}
if(!fs.existsSync('app/controller')){
  fs.mkdirSync("app/controller");
}

if(!fs.existsSync('app/helper.json')){
  fs.writeFileSync("app/helper.json", JSON.stringify({
    "name": ["Amar", "Akabar"]
  },null, "\t"));
}

var helperJSON = JSON.parse(fs.readFileSync("app/helper.json", {encoding: 'utf8'}));

var randomVal = function(type) {
	  return helperJSON[type][dummyjson.randomInt(0,helperJSON[type].length-1)];
};

var helpers = {};
Object.keys(helperJSON).map(function(key){
	helpers[key] = function(options){
		return randomVal(key);
	};
});

var MAPPERS = [];

function registerMapper(mapper,options){

  var matcher = new RegExp("^"+mapper.replace(/\{(.*?)\}/gi,'([a-z-A-Z-0-9])+').replace(/\//gi,"\/").replace(/\*/gi,"(.)*")+"$")
  var tokens =   (mapper).split(/[\/]+/gi);

  var placeholders = tokens.map(function(str,index){
    return {
      param : str.match(/(\{([^}]+)\}|\*)/g)
    }
  }).filter(function(obj,i){
    if(obj.param!=null && obj.param.length!=0){
      obj.index = i;
      obj.param = obj.param[0].substring(1, obj.param[0].length - 1)

      return true;
    }
    return false;
  });

  MAPPERS.push({
    mapper :  mapper,
    placeholders : placeholders,
    matcher : matcher, tokens : tokens,
    roles : options.roles || []
  });
  return MAPPERS[MAPPERS.length-1];
}

var router = {
  on : function(mapOrUrl,callback){
    var mapObj = {};
    if(typeof mapOrUrl === "string"){
      mapObj = registerMapper(mapOrUrl,{});
    } else {
      mapObj = registerMapper(mapOrUrl.url,mapOrUrl);
    }
    var headStr = callback.toString().split("{")[0]; //headStr will look like this: "function(jq, abc, xyz)">>string
    var headStrArg = headStr.substr(headStr.indexOf("(") + 1).split(")")[0]; //headStrArg will look like : "jq, abc, xyz">>string
    var depList;
    if (headStrArg === "") {
      depList = [];
    } else {
      depList = headStrArg.split(","); //deptList will look like: [jq, abc, xyz] >>array
    }
    for (var y = 0; y < depList.length; y++) {
      depList[y] = depList[y].trim(); //trim to remove whitespace from both ends of string
    }
    mapObj.argList = depList;
    mapObj.argParams = mapObj.argList.map(function(arg){
      return (mapObj.placeholders.filter(function(placeholder){
        return placeholder.param === arg;
      }) || [])[0];
    });
    mapObj.callback = callback;
  }
};

find.file("app/controller", function(files) {
  for(var i in files){
    var filez = files[i].split(/[\/]+/gi);
    require(process.env.PWD+"/"+files[i].replace(/\.js$/,""))(router);
  }
});

var Controller = require(__dirname+"/controller");

module.exports = function(req,resp,dir, next){
  var user;
  var cookies = new Cookies( req, resp);
  var session = sessionManager.start(req, resp);
  if(true){
    var dirs = req._parsedUrl.pathname.split("/");
    dirs.pop(); dirs = dirs.join("/");
    var session_id = session.getSessionId();
    cookies.set(sessionManagerModule.create.sessionIDCookieName,undefined,{ path : dirs });
    cookies.set(sessionManagerModule.create.sessionIDCookieName,session_id,{ path : "/" });
  }

  user = session.get("__USER__") || new User();
  user.__xscount__ ++;

	var method = "GET";//req.method;
  var pathname = req._parsedUrl.pathname;
  var PATHTokens = pathname.split(/[\/]+/gi);

  var tokenDiff = 10000;
  var MAPPER = null;
  for(var i in MAPPERS){
    var _tokenDiff = PATHTokens.length - MAPPERS[i].tokens.length;
    //console.log("======",MAPPERS[i].matcher,user.role,pathname);
    if(MAPPERS[i].matcher.test(pathname)
      && _tokenDiff<=tokenDiff && _tokenDiff>-1
      && (MAPPERS[i].roles.length==0 || MAPPERS[i].roles.indexOf(user.role) >= 0)){
      tokenDiff = _tokenDiff;
      MAPPER = MAPPERS[i];
    }
  }

  if(MAPPER){

    var controller = new Controller(req,resp,{
      helpers : helpers
    });

    //if(session){
      controller.user = user;
      controller.session = session;
      controller.cookies = cookies;
      session.set("__USER__", user);
    //}

    var retObj = MAPPER.callback.apply(controller,
      MAPPER.argParams.map(function(param){
        return PATHTokens[param.index];
      }));
    if(retObj !== undefined && typeof retObj.done === 'function' && typeof retObj.finally === 'function'){
      retObj.then(function(retresp){
        resp.write(retresp);
      }).finally(function(resp){
        console.log("finally",resp);
        next();
      });
    } else {
      next();
    }
  } else {
    console.error("No URL Mapping Found");
    //resp.write(JSON.stringify({ x : "No URL Mapping Found" }));
    var filepath = dir+req.originalUrl.split("?")[0]+".res";
    if(fs.existsSync(filepath)){
      resp.write(
        dummyjson.parse(
          fs.readFileSync(filepath, {encoding: 'utf8'}),
          {helpers: helpers}
        )
      );
    } else {
      console.error(filepath, "Not Found");
      resp.writeHead(404,{ message : " File Not Found", file : filepath});
    }
    next();
  }
};<|endoftext|>