<commit_before>import once from 'one-event';
import {getScrollTop, getScrollLeft} from 'get-scroll';

let state = 'auto';

function waitForScroll() {
	once(window, 'scroll', scrollTo.bind(window, getScrollLeft(), getScrollTop()));
}

if (!('scrollRestoration' in history)) {
	Object.defineProperty(history, 'scrollRestoration', {
		enumerable: true,
		get: () => state,
		set: requestedState => {
			if (requestedState === state) {
				return;
			}
			if (requestedState === 'auto') {
				window.removeEventListener('popstate', waitForScroll);
				state = requestedState;
			} else if (requestedState === 'manual') {
				window.addEventListener('popstate', waitForScroll);
				state = requestedState;
			}
		}
	});
}
<commit_msg>Remove scroll listener if it's still there<commit_after>import once from 'one-event';
import {getScrollTop, getScrollLeft} from 'get-scroll';

let state = 'auto';
let left = 0;
let top = 0;

function restoreScroll() {
	window.scrollTo(left, top);
}

function waitForScroll() {
	left = getScrollLeft();
	top = getScrollTop();
	once(window, 'scroll', restoreScroll);
}

if (!('scrollRestoration' in history)) {
	Object.defineProperty(history, 'scrollRestoration', {
		enumerable: true,
		get: () => state,
		set: requestedState => {
			if (requestedState === state) {
				return;
			}
			if (requestedState === 'auto') {
				window.removeEventListener('popstate', waitForScroll);
				window.removeEventListener('scroll', restoreScroll);
				state = requestedState;
			} else if (requestedState === 'manual') {
				window.addEventListener('popstate', waitForScroll);
				state = requestedState;
			}
		}
	});
}
<|endoftext|>


<commit_before>'use strict'

const express = require('express')
const bodyParser = require('body-parser')
const request = require('request')
const app = express()
const config = require('config')
const fs = require('fs')

// const hubVerifyToken = process.env.HUB_VERIFY_TOKEN || config.hubVerifyToken
const token = process.env.PAGE_ACCESS_TOKEN || config.pageToken

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}))

// parse application/json
app.use(bodyParser.json())

// index
app.get('/', (req, res) => {
  res.send('hello world i am mawhai bot')
})

app.post('/location', (req, res) => {
  const { lat, long } = req.body
  console.log(`lat: ${lat}, long: ${long}`)
  const data = { lat, long }
  fs.writeFile('./data', JSON.stringify(data), (err) => {
    if (err) {
      res.status(500).send(err || { message: 'Internal Error' })
    } else {
      res.status(200).send({ message: 'Success' })
    }
  })
})

app.get('/location', (req, res) => {
  fs.readFile('./data', 'utf8', (err, data) => {
    if (err) {
      res.status(500).send(err || { message: 'Internal Error' })
    } else {
      res.status(200).send(JSON.parse(data))
    }
  })
})
app.get('/data', (req, res) => {
  const location = new Promise(getData)
  location.then((location) => {
    if (location.lat && location.long) {
      res.status(200).send(location)
    }
  })
  .catch((err) => {
    res.status(500).send(err || { message: 'Internal Error' })
  })
})

function getData (resolve, reject) {
  fs.readFile(`./data`, 'utf8', (err, data) => {
    if (err) {
      reject(err)
    } else {
      resolve(JSON.parse(data))
    }
  })
}

let interval;

app.post('/webhook/', function (req, res) {
  let messagingEvents = req.body.entry[0].messaging
  for (let i = 0; i < messagingEvents.length; i++) {
    let event = req.body.entry[0].messaging[i]
    let sender = event.sender.id
    if (event.message && event.message.text) {
      let text = event.message.text
      if (text.substring(0, 200).indexOf('หาแมว') !== -1) {
        const location = new Promise(getData)
        location.then((location) => {
          console.log('location: ', location)
          if (location.lat && location.long) {
            sendGenericMessage(sender, location)
          }
        })
      } else if (text.substring(0, 200).indexOf('หารัวๆ') !== -1) {
        interval = setInterval(() => {
          const location = new Promise(getData)
          location.then((location) => {
            console.log('location: ', location)
            if (location.lat && location.long) {
              sendGenericMessage(sender, location)
            }
          })
        }, 2000);
      } else if (text.substring(0, 200).indexOf('หยุดหา') !== -1) {
        clearInterval(interval);
      } else {
        sendTextMessage(sender, 'meow meow~*')
      }
    } else if (event.postback && event.postback.payload) {
      if (event.postback.payload.indexOf('หาเจอแล้ว') > -1) {
        sendTextMessage(sender, 'ขอบคุณที่ใช้บริการน้า meow~*')
      }
    }
  }
  res.sendStatus(200)
})

function sendTextMessage (sender, text) {
  let messageData = { text: text }

  request({
    url: 'https://graph.facebook.com/v2.6/me/messages',
    qs: {access_token: token},
    method: 'POST',
    json: {
      recipient: {id: sender},
      message: messageData
    }
  }, function (error, response, body) {
    if (error) {
      console.log('Error sending messages: ', error)
    } else if (response.body.error) {
      console.log('Error: ', response.body.error)
    } else {
      console.log('success sending to', sender)
    }
  })
}

function sendGenericMessage (sender, location) {
  const zoom = 18
  const { lat, long } = location
  let messageData = {
    'attachment': {
      'type': 'template',
      'payload': {
        'template_type': 'generic',
        'elements': [{
          'title': 'Location',
          'subtitle': 'Bangkhen',
          'image_url': `http://staticmap.openstreetmap.de/staticmap.php?center=${lat},${long}&zoom=${zoom}&size=865x512&maptype=mapnik`,
          'buttons': [{
            'type': 'web_url',
            'url': `http://maps.google.com/maps?q=loc:${lat},${long}`,
            'title': 'view full map'
          }, {
            'type': 'postback',
            'title': 'หาเจอแล้ว',
            'payload': 'หาเจอแล้ว'
          }]
        }]
      }
    }
  }
  request({
    url: 'https://graph.facebook.com/v2.6/me/messages',
    qs: {access_token: token},
    method: 'POST',
    json: {
      recipient: {id: sender},
      message: messageData
    }
  }, function (error, response, body) {
    if (error) {
      console.log('Error sending messages: ', error)
    } else if (response.body.error) {
      console.log('Error: ', response.body.error)
    }
  })
}

// spin spin sugar
const port = process.env.PORT || 5000
app.listen(port, function () {
  console.log('running on port', port)
})
<commit_msg>fixed eslint<commit_after>'use strict'

const express = require('express')
const bodyParser = require('body-parser')
const request = require('request')
const app = express()
const config = require('config')
const fs = require('fs')

// const hubVerifyToken = process.env.HUB_VERIFY_TOKEN || config.hubVerifyToken
const token = process.env.PAGE_ACCESS_TOKEN || config.pageToken

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}))

// parse application/json
app.use(bodyParser.json())

// index
app.get('/', (req, res) => {
  res.send('hello world i am mawhai bot')
})

app.post('/location', (req, res) => {
  const { lat, long } = req.body
  console.log(`lat: ${lat}, long: ${long}`)
  const data = { lat, long }
  fs.writeFile('./data', JSON.stringify(data), (err) => {
    if (err) {
      res.status(500).send(err || { message: 'Internal Error' })
    } else {
      res.status(200).send({ message: 'Success' })
    }
  })
})

app.get('/location', (req, res) => {
  fs.readFile('./data', 'utf8', (err, data) => {
    if (err) {
      res.status(500).send(err || { message: 'Internal Error' })
    } else {
      res.status(200).send(JSON.parse(data))
    }
  })
})
app.get('/data', (req, res) => {
  const location = new Promise(getData)
  location.then((location) => {
    if (location.lat && location.long) {
      res.status(200).send(location)
    }
  })
  .catch((err) => {
    res.status(500).send(err || { message: 'Internal Error' })
  })
})

function getData (resolve, reject) {
  fs.readFile(`./data`, 'utf8', (err, data) => {
    if (err) {
      reject(err)
    } else {
      resolve(JSON.parse(data))
    }
  })
}

let interval

app.post('/webhook/', function (req, res) {
  let messagingEvents = req.body.entry[0].messaging
  for (let i = 0; i < messagingEvents.length; i++) {
    let event = req.body.entry[0].messaging[i]
    let sender = event.sender.id
    if (event.message && event.message.text) {
      let text = event.message.text
      if (text.substring(0, 200).indexOf('หาแมว') !== -1) {
        const location = new Promise(getData)
        location.then((location) => {
          console.log('location: ', location)
          if (location.lat && location.long) {
            sendGenericMessage(sender, location)
          }
        })
      } else if (text.substring(0, 200).indexOf('หารัวๆ') !== -1) {
        interval = setInterval(() => {
          const location = new Promise(getData)
          location.then((location) => {
            console.log('location: ', location)
            if (location.lat && location.long) {
              sendGenericMessage(sender, location)
            }
          })
        }, 2000)
      } else if (text.substring(0, 200).indexOf('หยุดหา') !== -1) {
        clearInterval(interval)
      } else {
        sendTextMessage(sender, 'meow meow~*')
      }
    } else if (event.postback && event.postback.payload) {
      if (event.postback.payload.indexOf('หาเจอแล้ว') > -1) {
        sendTextMessage(sender, 'ขอบคุณที่ใช้บริการน้า meow~*')
      }
    }
  }
  res.sendStatus(200)
})

function sendTextMessage (sender, text) {
  let messageData = { text: text }

  request({
    url: 'https://graph.facebook.com/v2.6/me/messages',
    qs: {access_token: token},
    method: 'POST',
    json: {
      recipient: {id: sender},
      message: messageData
    }
  }, function (error, response, body) {
    if (error) {
      console.log('Error sending messages: ', error)
    } else if (response.body.error) {
      console.log('Error: ', response.body.error)
    } else {
      console.log('success sending to', sender)
    }
  })
}

function sendGenericMessage (sender, location) {
  const zoom = 18
  const { lat, long } = location
  let messageData = {
    'attachment': {
      'type': 'template',
      'payload': {
        'template_type': 'generic',
        'elements': [{
          'title': 'Location',
          'subtitle': 'Bangkhen',
          'image_url': `http://staticmap.openstreetmap.de/staticmap.php?center=${lat},${long}&zoom=${zoom}&size=865x512&maptype=mapnik`,
          'buttons': [{
            'type': 'web_url',
            'url': `http://maps.google.com/maps?q=loc:${lat},${long}`,
            'title': 'view full map'
          }, {
            'type': 'postback',
            'title': 'หาเจอแล้ว',
            'payload': 'หาเจอแล้ว'
          }]
        }]
      }
    }
  }
  request({
    url: 'https://graph.facebook.com/v2.6/me/messages',
    qs: {access_token: token},
    method: 'POST',
    json: {
      recipient: {id: sender},
      message: messageData
    }
  }, function (error, response, body) {
    if (error) {
      console.log('Error sending messages: ', error)
    } else if (response.body.error) {
      console.log('Error: ', response.body.error)
    }
  })
}

// spin spin sugar
const port = process.env.PORT || 5000
app.listen(port, function () {
  console.log('running on port', port)
})
<|endoftext|>


<commit_before>var slack = require('slack')
var bot = slack.rtm.client()
var env = require('node-env-file')
var channels = require('./channels')
var admins = require('./admins')

env(__dirname + '/.env')
var token = process.env.SLACK_TOKEN

var commands = []

// auto rejoin
bot.channel_left(function(msg) {
  var toJoin = channels.whitelist.find((chan) => {
    return chan.id === msg.channel && chan.always
  })
  if (toJoin !== undefined) {
    slack.channels.join(
      {token: token, name: toJoin.name}, (err, data) => {
        if (data) { console.log(`auto rejoined #${toJoin.name}`) }
        if (err) { console.log(err) }
      }
    )
  }
})

// auto leave
bot.channel_joined(function(msg) {
  if (channels.whitelist.find((chan) => {
    return chan.id === msg.channel.id
  }) === undefined) {
    slack.channels.leave(
      {token: token, channel: msg.channel.id}, (err, data) => {
        if (data) { console.log(`auto left #${msg.channel.name}`) }
        if (err) { console.log(err) }
      }
    )
  }
})

// list admins
function cmd_admins(arg) {
  var text = '<@' + arg.from + '>: ' +
    admins.map((admin) => {return '<@' + admin.name + '>'}).join('\n')
  slack.chat.postMessage(
    {token: token, as_user: true, channel: arg.in, text: text}, (err, data) => {
      if (data) { console.log(`cmd_admins from ${arg.from} to ${arg.in}`) }
      if (err) { console.log(err) }
    }
  )
}
commands.push({
  cmd: cmd_admins,
  names: ['!admins', '!admin'],
  description: 'Lists admins.\n'
  + 'Options: `add`/`remove` + nick to add or remove an admin.'
})

// list commands and print help messages
function cmd_help(arg) {
  var text = '<@' + arg.from + '>: '
  if (arg.message === undefined) {
    text += commands.map((command) => {
      return command.names.join(', ')
    }).join('\n')
  } else {
    var cmd = commands.find((command) => {
      return command.names.includes(arg.cmd)
    })
    if (cmd !== undefined) {
      text += cmd.names.join(', ') + '\n' + cmd.description
    } else {
      text += 'Command not recognized.'
    }
  }
  slack.chat.postMessage(
    {token: token, as_user: true, channel: arg.in, text: text}, (err, data) => {
      if (data) { console.log(`cmd_help from ${arg.from} to ${arg.in}`) }
      if (err) { console.log(err) }
    }
  )
}
commands.push({
  cmd: cmd_help,
  names: ['!help', '!command', '!commands'],
  description: 'Lists commands. Add a command name for more specific help.'
})

// tell time and date
function cmd_time(arg) {
  var now = new Date()
  var text = `<@${arg.from}>: ${now.toDateString()} ${now.toTimeString()}`
  slack.chat.postMessage(
    {token: token, as_user: true, channel: arg.in, text: text}, (err, data) => {
      if (data) { console.log(`cmd_time from ${arg.from} to ${arg.in}`) }
      if (err) { console.log(err) }
    }
  )
}
commands.push({
  cmd: cmd_time,
  names: ['!time', '!date'],
  description: 'Prints the current date and time.'
})

// repeat with @channel
function cmd_announce(arg) {
  var text = `<!channel>: ${arg.message}\n(<@${arg.from}>)`
  slack.chat.postMessage(
    {token: token, as_user: true, channel: arg.to, text: text}, (err, data) => {
      if (data) { console.log(`cmd_announce to ${arg.to}\n${text}`) }
      if (err) { console.log(err) }
    }
  )
}
commands.push({
  cmd: cmd_announce,
  names: ['!annonces', '!libre', '!lockpicking', '!secu'],
  description: 'Annoncement on the specified channel '
  + '(#annonces, #libre, #lockpicking or #secu) '
  + 'with your nick at the end of the message.'
})

// commands
bot.message(function(msg) {
  var from = admins.find((user) => {
    return user.id === msg.user
  })
  if (from !== undefined) {
    if (msg.text.startsWith('!admin')) {
      cmd_admins({name: '!admin', from: from.name, in: msg.channel})
    }
    if (msg.text.startsWith('!command') || msg.text.startsWith('!help')) {
      cmd_help({name: '!help', from: from.name, in: msg.channel})
    }
    if (msg.text.startsWith('!time') || msg.text.startsWith('!date')) {
      cmd_time({name: '!time', from: from.name, in: msg.channel})
    }
    if (msg.text.startsWith('!secu ')) {
      cmd_announce({name: '!secu', from: from.name, to: '#asn-secu', message: msg.text.slice(6)})
    }
    if (msg.text.startsWith('!lockpicking ')) {
      cmd_announce({name: '!lockpicking', from: from.name, to: '#asn-lockpicking', message: msg.text.slice(13)})
    }
    if (msg.text.startsWith('!libre ')) {
      cmd_announce({name: '!libre', from: from.name, to: '#asn-libre', message: msg.text.slice(7)})
    }
    if (msg.text.startsWith('!annonces ')) {
      cmd_announce({name: '!annonces', from: from.name, to: '#annonces', message: msg.text.slice(6)})
    }
  }
})

// start listening to the slack team associated to the token
bot.listen({token:token})
<commit_msg>rename `cmd` to `func`<commit_after>var slack = require('slack')
var bot = slack.rtm.client()
var env = require('node-env-file')
var channels = require('./channels')
var admins = require('./admins')

env(__dirname + '/.env')
var token = process.env.SLACK_TOKEN

var commands = []

// auto rejoin
bot.channel_left(function(msg) {
  var toJoin = channels.whitelist.find((chan) => {
    return chan.id === msg.channel && chan.always
  })
  if (toJoin !== undefined) {
    slack.channels.join(
      {token: token, name: toJoin.name}, (err, data) => {
        if (data) { console.log(`auto rejoined #${toJoin.name}`) }
        if (err) { console.log(err) }
      }
    )
  }
})

// auto leave
bot.channel_joined(function(msg) {
  if (channels.whitelist.find((chan) => {
    return chan.id === msg.channel.id
  }) === undefined) {
    slack.channels.leave(
      {token: token, channel: msg.channel.id}, (err, data) => {
        if (data) { console.log(`auto left #${msg.channel.name}`) }
        if (err) { console.log(err) }
      }
    )
  }
})

// list admins
function cmd_admins(arg) {
  var text = '<@' + arg.from + '>: ' +
    admins.map((admin) => {return '<@' + admin.name + '>'}).join('\n')
  slack.chat.postMessage(
    {token: token, as_user: true, channel: arg.in, text: text}, (err, data) => {
      if (data) { console.log(`cmd_admins from ${arg.from} to ${arg.in}`) }
      if (err) { console.log(err) }
    }
  )
}
commands.push({
  func: cmd_admins,
  names: ['!admins', '!admin'],
  description: 'Lists admins.\n'
  + 'Options: `add`/`remove` + nick to add or remove an admin.'
})

// list commands and print help messages
function cmd_help(arg) {
  var text = '<@' + arg.from + '>: '
  if (arg.message === undefined) {
    text += commands.map((command) => {
      return command.names.join(', ')
    }).join('\n')
  } else {
    var cmd = commands.find((command) => {
      return command.names.includes(arg.cmd)
    })
    if (cmd !== undefined) {
      text += cmd.names.join(', ') + '\n' + cmd.description
    } else {
      text += 'Command not recognized.'
    }
  }
  slack.chat.postMessage(
    {token: token, as_user: true, channel: arg.in, text: text}, (err, data) => {
      if (data) { console.log(`cmd_help from ${arg.from} to ${arg.in}`) }
      if (err) { console.log(err) }
    }
  )
}
commands.push({
  func: cmd_help,
  names: ['!help', '!command', '!commands'],
  description: 'Lists commands. Add a command name for more specific help.'
})

// tell time and date
function cmd_time(arg) {
  var now = new Date()
  var text = `<@${arg.from}>: ${now.toDateString()} ${now.toTimeString()}`
  slack.chat.postMessage(
    {token: token, as_user: true, channel: arg.in, text: text}, (err, data) => {
      if (data) { console.log(`cmd_time from ${arg.from} to ${arg.in}`) }
      if (err) { console.log(err) }
    }
  )
}
commands.push({
  func: cmd_time,
  names: ['!time', '!date'],
  description: 'Prints the current date and time.'
})

// repeat with @channel
function cmd_announce(arg) {
  var text = `<!channel>: ${arg.message}\n(<@${arg.from}>)`
  slack.chat.postMessage(
    {token: token, as_user: true, channel: arg.to, text: text}, (err, data) => {
      if (data) { console.log(`cmd_announce to ${arg.to}\n${text}`) }
      if (err) { console.log(err) }
    }
  )
}
commands.push({
  func: cmd_announce,
  names: ['!annonces', '!libre', '!lockpicking', '!secu'],
  description: 'Annoncement on the specified channel '
  + '(#annonces, #libre, #lockpicking or #secu) '
  + 'with your nick at the end of the message.'
})

// commands
bot.message(function(msg) {
  var from = admins.find((user) => {
    return user.id === msg.user
  })
  if (from !== undefined) {
    if (msg.text.startsWith('!admin')) {
      cmd_admins({name: '!admin', from: from.name, in: msg.channel})
    }
    if (msg.text.startsWith('!command') || msg.text.startsWith('!help')) {
      cmd_help({name: '!help', from: from.name, in: msg.channel})
    }
    if (msg.text.startsWith('!time') || msg.text.startsWith('!date')) {
      cmd_time({name: '!time', from: from.name, in: msg.channel})
    }
    if (msg.text.startsWith('!secu ')) {
      cmd_announce({name: '!secu', from: from.name, to: '#asn-secu', message: msg.text.slice(6)})
    }
    if (msg.text.startsWith('!lockpicking ')) {
      cmd_announce({name: '!lockpicking', from: from.name, to: '#asn-lockpicking', message: msg.text.slice(13)})
    }
    if (msg.text.startsWith('!libre ')) {
      cmd_announce({name: '!libre', from: from.name, to: '#asn-libre', message: msg.text.slice(7)})
    }
    if (msg.text.startsWith('!annonces ')) {
      cmd_announce({name: '!annonces', from: from.name, to: '#annonces', message: msg.text.slice(6)})
    }
  }
})

// start listening to the slack team associated to the token
bot.listen({token:token})
<|endoftext|>


<commit_before>/*!
 * layouts <https://github.com/jonschlinkert/layouts>
 *
 * Copyright (c) 2014 Jon Schlinkert, contributors
 * Licensed under the MIT License (MIT)
 */

'use strict';

var util = require('util');
var isFalsey = require('falsey');
var Cache = require('config-cache');
var _ = require('lodash');
var delims = new (require('delims'))();

/**
 * ## Layouts
 *
 * Create a new instance of `Layouts`, optionally passing the default
 * `cache` and `options` to use.
 *
 * **Example:**
 *
 * ```js
 * var Layouts = require('layouts');
 * var layouts = new Layouts();
 * ```
 *
 * @param {Object} `cache` A template cache. See [Layouts#set](#set) for object details.
 * @param {Object} `options` Options to use.
 * @param {Array} `options.delims` Template delimiters to use formatted as an array (`['{{', '}}']`)
 * @param {String} `options.tag` The tag name to use. Default is `body` (e.g. `{{ body }}`)
 */

function Layouts(options) {
  Cache.call(this, options);
  this.options = _.extend({}, options);
  this.defaultTag = this.makeTag(this.options);
  this._extendMethod = this.options.extend || _.extend;
  _.extend(this.cache, this.options.cache, this.options.layouts);
  this.context = _.extend({}, this.options.locals);

  delete this.options.cache;
  delete this.cache.data;
  this.flattenData(this.cache, 'cache');
}

util.inherits(Layouts, Cache);

/**
 * ## .makeTag
 *
 * Generate the default body tag to use as a fallback, based on the
 * `tag` and `delims` defined in the options.
 *
 * @param  {Object} options
 * @return {String} The actual body tag, e.g. `{{ body }}`
 * @api private
 */

Layouts.prototype.makeTag = function (options) {
  var opts = _.extend({}, this.options, options);
  opts.delims = opts.delims || ['{{', '}}'];
  opts.tag = opts.tag || 'body';

  return [
    opts.delims[0],
    opts.tag,
    opts.delims[1]
  ].join(opts.sep || ' ');
};

/**
 * ## .makeRegex
 *
 * Return a regular expression for the "body" tag based on the
 * `tag` and `delims` defined in the options.
 *
 * @param  {Object} `options`
 * @return {RegExp}
 * @api private
 */

Layouts.prototype.makeRegex = function (options) {
  var opts = _.extend({sep: '\\s*'}, this.options, options);
  var tag = this.makeTag(opts).replace(/[\]()[{|}]/g, '\\$&');
  return new RegExp(tag, opts.flags || 'g');
};

/**
 * ## .setLayout
 *
 * Store a template on the cache by its `name`, the `layout` to use,
 * and the template's `content.
 *
 * **Example:**
 *
 * ```js
 * layouts.setLayout('a', 'b', '<h1>Foo</h1>\n{{body}}\n');
 * ```
 *
 * @param {String|Object} `name` If `name` is a string, `layout` and `content` are required.
 * @param {String|Object} `data` Pass a string defining the name of layout to use for the given
 *                               template, or pass an object with a `layout` property.
 * @param {String} `content` The template "content", this will not be compiled or rendered.
 * @api public
 */

Layouts.prototype.setLayout = function (name, data, content) {
  if (arguments.length === 1 && typeof name === 'object') {
    this.cache = _.extend({}, this.cache, name);
    return this;
  }
  this.cache[name] = {
    layout: (data && data.layout) ? data.layout : data,
    content: (data && data.content) ? data.content : content,
    data: data
  };

  return this;
};

/**
 * ## .getLayout
 *
 * Get a cached template by `name`.
 *
 * **Example:**
 *
 * ```js
 * layouts.getLayout('a');
 * //=> { layout: 'b', content: '<h1>Foo</h1>\n{{body}}\n' }
 * ```
 *
 * @param  {String} `name`
 * @return {Object} The template object to return.
 */

Layouts.prototype.getLayout = function (name) {
  if (!name) {
    return this.cache;
  }
  return this.cache[name];
};

/**
 * ## .assertLayout
 *
 * Assert whether or not a layout should be used based on
 * the given `value`. If a layout should be used, the name of the
 * layout is returned, if not `null` is returned.
 *
 * @param  {*} `value`
 * @return {String|Null} Returns `true` or `null`.
 * @api private
 */

Layouts.prototype.assertLayout = function (value, defaultLayout) {
  if (value === false || (value && isFalsey(value))) {
    return null;
  } else if (!value || value === true) {
    return defaultLayout || null;
  } else {
    return value;
  }
};

/**
 * ## ._mergeData
 *
 * Extend `data` with the given `obj. A custom `_extendMethod` can be
 * passed on `options.extend` to change how data is merged.
 *
 * @param  {Object} `opts` Pass an options object with `data` or `locals`
 * @return {Object} `file` A `file` to with `data` to be merged.
 * @api private
 */

Layouts.prototype._mergeData = function (opts, file) {
  var data = {};

  // build up the `data` object
  _.extend(data, opts, opts.locals, opts.data);
  _.extend(data, file, file.data);

  // Flatten nested `data` objects
  this.flattenData(data);

  // Extend the context
  this._extendMethod(this.context, _.omit(data, [
    'extend',
    'content',
    'delims',
    'layout'
  ]));

  return this;
};

/**
 * ## .createStack
 *
 * Build a layout stack.
 *
 * @param  {String} `name` The name of the layout to add to the stack.
 * @return {String}
 * @api private
 */

Layouts.prototype.createStack = function (name, options) {
  var opts = _.extend({}, this.options, options);
  name = this.assertLayout(name, opts.defaultLayout);
  var template = Object.create(null);
  var stack = [];

  var prev = null;
  while (name && (prev !== name) && (template = this.cache[name])) {
    stack.unshift(name);
    prev = name;
    var layout = template.layout || (template.data && template.data.layout);
    name = this.assertLayout(layout, opts.defaultLayout);
  }
  return stack;
};

/**
 * ## .stack
 *
 * Flatten nested layouts.
 *
 * **Example:**
 *
 * ```js
 * var layout = layouts.stack('base');
 * ```
 *
 * @param  {String} `name` The layout to start with.
 * @return {String} Resulting flattened layout.
 * @api private
 */

Layouts.prototype.stack = function (name, options) {
  var stack = this.createStack(name, options);
  var opts = _.extend(this.options, options);

  var tag = this.makeTag(opts) || this.defaultTag;
  this.regex = this.makeRegex(opts);

  return _.reduce(stack, function (acc, layout) {
    var content = acc.content || tag;
    var tmpl = this.cache[layout];
    this._mergeData(opts, tmpl);

    var data = opts;
    content = content.replace(this.regex, tmpl.content);
    content = this.renderLayout(content, data, opts);

    return {
      data: this.context,
      content: content,
      regex: this.regex,
      tag: tag
    };
  }.bind(this), {});
};

/**
 * ## .renderLayout
 *
 * Render an individual layout layer with it's current context.
 *
 * **Example:**
 *
 * ```js
 * content = this.renderLayout(content, options);
 * ```
 * @param  {String} `content` content for the layout to render
 * @param  {Object} `options` additional options used for building the render settings
 * @return {String} rendered content
 */

Layouts.prototype.renderLayout = function (content, data, options) {
  var tag = (this.makeTag(options) || this.defaultTag).replace(/\s/g, '');
  var body = options.tag || 'body';
  var settings = _.extend(delims.templates(options.delims || ['{{','}}']), options);
  settings.interpolate = settings.evaluate;
  this.context[body] = tag;
  var ctx = _.extend({}, this.context, data);

  content = _.template(content, this.context, settings);
  delete this.context[body];

  return content
};

/**
 * ## .replaceTag
 *
 * Replace a `{{body}}` tag (or equivalent if custom delims are used) in `content`
 * with the given `str`.
 *
 * **Example:**
 *
 * ```js
 * console.log(layouts.replaceTag('ABC', 'Before {{body}} After'));
 * //=> 'Before ABC After'
 * ```
 *
 * @param  {String} `str` The string to use as a replacement value.
 * @param  {String} `content` A string with a `{{body}}` tag where the `str` should be injected.
 * @return {String} Resulting flattened content.
 * @api public
 */

Layouts.prototype.replaceTag = function (str, content, options) {
  return content.replace(this.makeRegex(options), str);
};

/**
 * ## .inject
 *
 * Inject content into a layout stack.
 *
 * **Example:**
 *
 * ```js
 * var page = layouts.inject(str, 'base');
 * var tmpl = _.template(page, context);
 * ```
 *
 * @param  {String} `str` The content to inject into the layout.
 * @param  {String} `name` The layout to start with.
 * @return {String} Resulting flattened layout.
 * @api public
 */

Layouts.prototype.inject = function (str, name, options) {
  var layout = this.stack(name, options);

  if (layout.content) {
    str = layout.content.replace(this.regex, str);
  }
  return {data: layout.data, content: str};
};

module.exports = Layouts;
<commit_msg>adds `_defaultLayout` method as a step towards externalizing or compartmentalizing that logic. also adds updated code comments for methods.<commit_after>/*!
 * layouts <https://github.com/jonschlinkert/layouts>
 *
 * Copyright (c) 2014 Jon Schlinkert, contributors
 * Licensed under the MIT License (MIT)
 */

'use strict';

var util = require('util');
var isFalsey = require('falsey');
var Cache = require('config-cache');
var _ = require('lodash');
var delims = new (require('delims'))();

/**
 * Create a new instance of `Layouts`, optionally passing the default
 * `cache` and `options` to use.
 *
 * **Example:**
 *
 * ```js
 * var Layouts = require('layouts');
 * var layouts = new Layouts();
 * ```
 *
 * @param {Object} `cache` A template cache. See [Layouts#set](#set) for object details.
 * @param {Object} `options` Options to use.
 * @param {Array} `options.delims` Template delimiters to use formatted as an array (`['{{', '}}']`)
 * @param {String} `options.tag` The tag name to use. Default is `body` (e.g. `{{ body }}`)
 */

function Layouts(options) {
  Cache.call(this, options);
  this.options = _.extend({}, options);
  this.defaultTag = this.makeTag(this.options);
  this._extendMethod = this.options.extend || _.extend;
  _.extend(this.cache, this.options.cache, this.options.layouts);
  this.context = _.extend({}, this.options.locals);

  delete this.options.cache;
  delete this.cache.data;
  this.flattenData(this.cache, 'cache');
}

util.inherits(Layouts, Cache);

/**
 * Generate the default body tag to use as a fallback, based on the
 * `tag` and `delims` defined in the options.
 *
 * @param  {Object} options
 * @return {String} The actual body tag, e.g. `{{ body }}`
 * @api private
 */

Layouts.prototype.makeTag = function (options) {
  var opts = _.extend({}, this.options, options);
  opts.delims = opts.delims || ['{{', '}}'];
  opts.tag = opts.tag || 'body';

  return [
    opts.delims[0],
    opts.tag,
    opts.delims[1]
  ].join(opts.sep || ' ');
};

/**
 * Return a regular expression for the "body" tag based on the
 * `tag` and `delims` defined in the options.
 *
 * @param  {Object} `options`
 * @return {RegExp}
 * @api private
 */

Layouts.prototype.makeRegex = function (options) {
  var opts = _.extend({sep: '\\s*'}, this.options, options);
  var tag = this.makeTag(opts).replace(/[\]()[{|}]/g, '\\$&');
  return new RegExp(tag, opts.flags || 'g');
};

/**
 * Store a template on the cache by its `name`, the `layout` to use,
 * and the template's `content.
 *
 * **Example:**
 *
 * ```js
 * layouts.setLayout('a', 'b', '<h1>Foo</h1>\n{{body}}\n');
 * ```
 *
 * @param {String|Object} `name` If `name` is a string, `layout` and `content` are required.
 * @param {String|Object} `data` Pass a string defining the name of layout to use for the given
 *                               template, or pass an object with a `layout` property.
 * @param {String} `content` The template "content", this will not be compiled or rendered.
 * @api public
 */

Layouts.prototype.setLayout = function (name, data, content) {
  if (arguments.length === 1 && typeof name === 'object') {
    this.cache = _.extend({}, this.cache, name);
    return this;
  }
  this.cache[name] = {
    layout: (data && data.layout) ? data.layout : data,
    content: (data && data.content) ? data.content : content,
    data: data
  };

  return this;
};

/**
 * Define the default layout variable and delimiters to be used.
 */

Layouts.prototype._defaultLayout = function (str, context, options) {
  var opts = _.extend({}, options);
  var tag = (this.makeTag(options) || this.defaultTag).replace(/\s/g, '');

  var variable = options.tag || 'body';
  var settings = _.extend(delims.templates(options.delims || ['{{','}}']), options);

  settings.interpolate = settings.evaluate;

  return {
    variable: tag,
    context: opts,
    settings: settings
  };
};

/**
 * Get a cached template by `name`.
 *
 * **Example:**
 *
 * ```js
 * layouts.getLayout('a');
 * //=> { layout: 'b', content: '<h1>Foo</h1>\n{{body}}\n' }
 * ```
 *
 * @param  {String} `name`
 * @return {Object} The template object to return.
 */

Layouts.prototype.getLayout = function (name) {
  if (!name) {
    return this.cache;
  }
  return this.cache[name];
};

/**
 * Assert whether or not a layout should be used based on
 * the given `value`. If a layout should be used, the name of the
 * layout is returned, if not `null` is returned.
 *
 * @param  {*} `value`
 * @return {String|Null} Returns `true` or `null`.
 * @api private
 */

Layouts.prototype.assertLayout = function (value, defaultLayout) {
  if (value === false || (value && isFalsey(value))) {
    return null;
  } else if (!value || value === true) {
    return defaultLayout || null;
  } else {
    return value;
  }
};

/**
 * Extend `data` with the given `obj. A custom `_extendMethod` can be
 * passed on `options.extend` to change how data is merged.
 *
 * @param  {Object} `opts` Pass an options object with `data` or `locals`
 * @return {Object} `file` A `file` to with `data` to be merged.
 * @api private
 */

Layouts.prototype._mergeData = function (opts, file) {
  var data = {};

  // build up the `data` object
  _.extend(data, opts, opts.locals, opts.data);
  _.extend(data, file, file.data);

  // Flatten nested `data` objects
  this.flattenData(data);

  // Extend the context
  this._extendMethod(this.context, _.omit(data, [
    'extend',
    'content',
    'delims',
    'layout'
  ]));

  return this;
};

/**
 * Build a layout stack.
 *
 * @param  {String} `name` The name of the layout to add to the stack.
 * @param  {Object} `options` Options to pass to `assertLayout`.
 * @return {Array}
 * @api private
 */

Layouts.prototype.createStack = function (name, options) {
  var opts = _.extend({}, this.options, options);
  name = this.assertLayout(name, opts.defaultLayout);

  var template = {};
  var stack = [];
  var prev = null;

  while (name && (prev !== name) && (template = this.cache[name])) {
    stack.unshift(name);
    prev = name;
    var layout = template.layout || (template.data && template.data.layout);
    name = this.assertLayout(layout, opts.defaultLayout);
  }

  return stack;
};

/**
 * Reduce a layout stack for a template into a single flattened
 * layout. Pass the `name` of the layout defined for the template
 * (e.g. the first layout in the stack).
 *
 * **Example:**
 *
 * ```js
 * layouts.stack('base');
 * ```
 *
 * @param  {String} `name` The layout to start with.
 * @param  {Object} `options`
 * @return {Array} The file's layout stack is returned as an array.
 * @api private
 */

Layouts.prototype.stack = function (name, options) {
  var stack = this.createStack(name, options);
  var opts = _.extend(this.options, options);

  var tag = this.makeTag(opts) || this.defaultTag;
  this.regex = this.makeRegex(opts);

  return _.reduce(stack, function (acc, layout) {
    var content = acc.content || tag;
    var tmpl = this.cache[layout];

    var data = this._mergeData(opts, tmpl);
    content = content.replace(this.regex, tmpl.content);
    content = this.renderLayout(content, data, opts);

    return {
      data: this.context,
      content: content,
      regex: this.regex,
      tag: tag
    };
  }.bind(this), {});
};

/**
 * Render a layout using Lo-Dash, by passing content (`str`), `context`
 * and `options`.
 *
 * **Example:**
 *
 * ```js
 * layouts.renderLayout(str, context, options);
 * ```
 *
 * Since this method uses Lo-Dash to process templates custom delimiters
 * may be passed on the `options.delims` property. This allows layouts to
 * be rendered prior to injecting "pages" or other str with templates that
 * _should not_ be rendered when the layout stack is processed.
 *
 * **Example:**
 *
 * ```js
 * layouts.renderLayout(str, context, {
 *   delims: ['<%','%>']
 * });
 * ```
 *
 * @param  {String} `str` Content for the layout to render.
 * @param  {Object} `options` Additional options used for building the render settings.
 * @return {String} Rendered string.
 */

Layouts.prototype.renderLayout = function (str, context, options) {
  var layout = this._defaultLayout(str, context, options);

  var ctx = _.extend({}, context, this.context, {
    body: layout.variable
  });

  return _.template(str, ctx, layout.settings);
};

/**
 * Replace a `{{body}}` tag with the given `str`. Custom delimiters
 * and/or variable may be passed on the `options`. Unlike `renderLayout`,
 * this method does not render templates, it only peforms a basic regex
 * replacement.
 *
 * **Example:**
 *
 * ```js
 * layouts.replaceTag('ABC', 'Before {{body}} After');
 * //=> 'Before ABC After'
 * ```
 *
 * @param  {String} `str` The string to use as a replacement value.
 * @param  {String} `content` A string with a `{{body}}` tag where the `str` should be injected.
 * @return {String} Resulting flattened content.
 * @api public
 */

Layouts.prototype.replaceTag = function (str, content, options) {
  return content.replace(this.makeRegex(options), str);
};

/**
 * Return an object with the string (`str`) and `data` required
 * to build a final layout. This is useful if you need to use
 * your own template engine to handle this final step.
 *
 * **Example:**
 *
 * ```js
 * var page = layouts.inject(str, 'base');
 * var tmpl = _.template(page, context);
 * ```
 *
 * @param  {String} `str` The string to be injected into the layout. Usually a page, or inner layout, etc.
 * @param  {String} `name` The name of the first layout to use to build the stack.
 * @return {Object} Resulting flattened layout.
 * @api public
 */

Layouts.prototype.inject = function (str, name, options) {
  var layout = this.stack(name, options);

  if (layout.content) {
    str = layout.content.replace(this.regex, str);
  }
  return {data: layout.data, content: str};
};

module.exports = Layouts;
<|endoftext|>


<commit_before>"use strict";
var nodecss = require("node-css"),
  _ = require("lodash"),
  libpath = require("path");

var CSS = nodecss.CSS;
var rxReplacePath = /(\/|\\)/g;
var MEDIA_QUERY = "(min-device-pixel-ratio: 2) and (min-resolution: 192dpi)";
var css = new CSS();

function CSSImage() {
}

CSSImage.prototype.css = function(filepath, width, height, root, options) {
  var classname = "." + this.name(filepath, options);
  if (!options) { options = {}; }
  if (options.retina) {
    options.media = MEDIA_QUERY;
  }
  var squeeze = !!options.squeeze ? +options.squeeze : 1;
  var _width = Math.floor(width / squeeze);
  var _height = Math.floor(height / squeeze);
  return css.statement(classname, {
    width: _width + "px",
    height: _height + "px",
    "background-image": this.url(filepath, root, options.retina),
    "background-size": "" + _width  + "px " + _height + "px"
  }, options);
};

CSSImage.prototype.scssVars = function(filepath, _width, _height, options) {
  var name = this.name(filepath, options);
  var squeeze = (options && !!options.squeeze) ? +options.squeeze : 1;
  var width = Math.floor(_width / squeeze);
  var height = Math.floor(_height / squeeze);
  var root = (options && options.root) || "";
  var retina = options && !!options.retina;

  return "$" + name + "__width: " + width + "px;\n" +
         "$" + name + "__height: " + height + "px;\n" +
         "$" + name + "__path: '" + this.normalizePath(filepath, root, retina) + "';\n";
};

CSSImage.prototype.scssMixin = function(filepath, _width, _height, root, options) {
  var name = this.name(filepath, options);
  if (!options) { options = {}; }
  var classname = "@mixin " + name + "()";
  var isRetina = !!options.retina;
  var indent = css.options(options, "indent");
  var squeeze = (options && !!options.squeeze) ? +options.squeeze : 1;
  var width = Math.floor(_width / squeeze);
  var height = Math.floor(_height / squeeze);

  var scssMixin = css.body({
    width: width + "px",
    height: height + "px",
    "background-image": this.url(filepath, root),
    "background-size": "" + width  + "px " + height + "px"
  }, {indent: indent});

  if (isRetina) {
    var body = css.body({
      width: width + "px",
      height: height + "px",
      "background-image": this.url(filepath, root, options.retina),
      "background-size": "" + width  + "px " + height + "px"
    }, {indent: indent + indent});
    scssMixin += indent + "@media " + MEDIA_QUERY + " {\n" + body + indent + "}\n";
  }
  return classname + " {\n" + scssMixin + "}\n";
};

CSSImage.prototype.scss = function(filepath, width, height, root, options) {
  return this.scssMixin(filepath, width, height, root, options) +
         this.scssVars(filepath, width, height, options);
};

CSSImage.prototype.url = function(filepath, root, retina) {
  return "url(" + this.normalizePath(filepath, root, retina) + ")";
};

CSSImage.prototype.normalizePath = function(filepath, root, retina) {
  var name = libpath.basename(filepath);
  var ext = libpath.extname(filepath);
  if (!!retina) {
    var postfix = (typeof retina === "string") ? retina : "-50pc";
    name = name.replace(ext, postfix + ext);
  }
  var normalizedPath = libpath.join(this.normalizeFolder(filepath, root), name);
  normalizedPath = normalizedPath.replace(rxReplacePath, "/");
  return normalizedPath;
};

CSSImage.prototype.normalizeFolder = function(filepath, root) {
  var folder = libpath.dirname(filepath);
  if (folder[0] === "." && folder[1] !== ".") { folder = folder.slice(1); }
  if (folder[0] === "/") { folder = folder.slice(1); }
  var result = root ? libpath.join(root, folder) : folder;
  return result.replace(rxReplacePath, "/");
};

CSSImage.prototype.name = function(filepath, options) {
  var postfix = options && options.postfix ? options.postfix : "";
  if (options && options.squeeze) { postfix += "-s" + options.squeeze; }
  var prefix = options && (typeof options.prefix !== "undefined") ? options.prefix : "img_";
  var separator = (options && options.separator) || "_";
  var filename = libpath.basename(filepath);
  var ext = libpath.extname(filepath);
  var name = filename.slice(0, filename.length - ext.length).replace(/\./, "");
  var folder = this.normalizeFolder(filepath);
  if (folder === "") { return prefix + name + postfix; }

  // windows fix
  folder = folder.replace(rxReplacePath, separator);
  return prefix + folder + separator + name + postfix;
};

var _cssImage = new CSSImage();
function cssimage(images, _options) {
  var options = _.omit(_options, ["retina", "squeeze"]);
  var isCss = !!options.css;
  var isScss = !!options.scss;
  var root = options.root || "";
  var result = "";
  var isRetina = _options && !!_options.retina;
  var squeeze = (_options && _options.squeeze) || 1;
  for (var i = 0; i < images.length; i++) {
    var img = images[i];
    if (isCss) {
      result += _cssImage.css(img.file, img.width, img.height, root, options);
      if (isRetina) {
        result += _cssImage.css(img.file, img.width, img.height, root, _.extend({
          retina: true
        }, options));
      }
      if (squeeze !== 1) {
        result += _cssImage.css(img.file, img.width, img.height, root, _.extend({
          squeeze: squeeze
        }, options));
      }
    }
    if (isScss) {
      result += _cssImage.scss(img.file, img.width, img.height, root, _.extend({
        retina: isRetina
      }, options));
      if (squeeze !== 1) {
        result += _cssImage.scss(img.file, img.width, img.height, root, _.extend({
          squeeze: squeeze
        }, options));
      }
    }
  }
  return result;
}

module.exports = cssimage;
module.exports.CSSImage = CSSImage;
<commit_msg>Exporting sass list of values for each image<commit_after>"use strict";
var nodecss = require("node-css"),
  _ = require("lodash"),
  libpath = require("path");

var CSS = nodecss.CSS;
var rxReplacePath = /(\/|\\)/g;
var MEDIA_QUERY = "(min-device-pixel-ratio: 2) and (min-resolution: 192dpi)";
var css = new CSS();

function CSSImage() {
}

CSSImage.prototype.css = function(filepath, width, height, root, options) {
  var classname = "." + this.name(filepath, options);
  if (!options) { options = {}; }
  if (options.retina) {
    options.media = MEDIA_QUERY;
  }
  var squeeze = !!options.squeeze ? +options.squeeze : 1;
  var _width = Math.floor(width / squeeze);
  var _height = Math.floor(height / squeeze);
  return css.statement(classname, {
    width: _width + "px",
    height: _height + "px",
    "background-image": this.url(filepath, root, options.retina),
    "background-size": "" + _width  + "px " + _height + "px"
  }, options);
};

CSSImage.prototype.scssVars = function(filepath, _width, _height, options) {
  var name = this.name(filepath, options);
  var squeeze = (options && !!options.squeeze) ? +options.squeeze : 1;
  var width = Math.floor(_width / squeeze);
  var height = Math.floor(_height / squeeze);
  var root = (options && options.root) || "";
  var retina = options && !!options.retina;

  return "$" + name + ": (\n" +
         "\twidth: " + width + "px,\n" +
         "\theight: " + height + "px\n" +
         ");\n" +
         "$" + name + "__width: " + width + "px;\n" +
         "$" + name + "__height: " + height + "px;\n" +
         "$" + name + "__path: '" + this.normalizePath(filepath, root, retina) + "';\n\n";
};

CSSImage.prototype.scssMixin = function(filepath, _width, _height, root, options) {
  var name = this.name(filepath, options);
  if (!options) { options = {}; }
  var classname = "@mixin " + name + "()";
  var isRetina = !!options.retina;
  var indent = css.options(options, "indent");
  var squeeze = (options && !!options.squeeze) ? +options.squeeze : 1;
  var width = Math.floor(_width / squeeze);
  var height = Math.floor(_height / squeeze);

  var scssMixin = css.body({
    width: width + "px",
    height: height + "px",
    "background-image": this.url(filepath, root),
    "background-size": "" + width  + "px " + height + "px"
  }, {indent: indent});

  if (isRetina) {
    var body = css.body({
      width: width + "px",
      height: height + "px",
      "background-image": this.url(filepath, root, options.retina),
      "background-size": "" + width  + "px " + height + "px"
    }, {indent: indent + indent});
    scssMixin += indent + "@media " + MEDIA_QUERY + " {\n" + body + indent + "}\n";
  }
  return classname + " {\n" + scssMixin + "}\n";
};

CSSImage.prototype.scss = function(filepath, width, height, root, options) {
  return this.scssMixin(filepath, width, height, root, options) +
         this.scssVars(filepath, width, height, options);
};

CSSImage.prototype.url = function(filepath, root, retina) {
  return "url(" + this.normalizePath(filepath, root, retina) + ")";
};

CSSImage.prototype.normalizePath = function(filepath, root, retina) {
  var name = libpath.basename(filepath);
  var ext = libpath.extname(filepath);
  if (!!retina) {
    var postfix = (typeof retina === "string") ? retina : "-50pc";
    name = name.replace(ext, postfix + ext);
  }
  var normalizedPath = libpath.join(this.normalizeFolder(filepath, root), name);
  normalizedPath = normalizedPath.replace(rxReplacePath, "/");
  return normalizedPath;
};

CSSImage.prototype.normalizeFolder = function(filepath, root) {
  var folder = libpath.dirname(filepath);
  if (folder[0] === "." && folder[1] !== ".") { folder = folder.slice(1); }
  if (folder[0] === "/") { folder = folder.slice(1); }
  var result = root ? libpath.join(root, folder) : folder;
  return result.replace(rxReplacePath, "/");
};

CSSImage.prototype.name = function(filepath, options) {
  var postfix = options && options.postfix ? options.postfix : "";
  if (options && options.squeeze) { postfix += "-s" + options.squeeze; }
  var prefix = options && (typeof options.prefix !== "undefined") ? options.prefix : "img_";
  var separator = (options && options.separator) || "_";
  var filename = libpath.basename(filepath);
  var ext = libpath.extname(filepath);
  var name = filename.slice(0, filename.length - ext.length).replace(/\./, "");
  var folder = this.normalizeFolder(filepath);
  if (folder === "") { return prefix + name + postfix; }

  // windows fix
  folder = folder.replace(rxReplacePath, separator);
  return prefix + folder + separator + name + postfix;
};

var _cssImage = new CSSImage();
function cssimage(images, _options) {
  var options = _.omit(_options, ["retina", "squeeze"]);
  var isCss = !!options.css;
  var isScss = !!options.scss;
  var root = options.root || "";
  var result = "";
  var isRetina = _options && !!_options.retina;
  var squeeze = (_options && _options.squeeze) || 1;
  for (var i = 0; i < images.length; i++) {
    var img = images[i];
    if (isCss) {
      result += _cssImage.css(img.file, img.width, img.height, root, options);
      if (isRetina) {
        result += _cssImage.css(img.file, img.width, img.height, root, _.extend({
          retina: true
        }, options));
      }
      if (squeeze !== 1) {
        result += _cssImage.css(img.file, img.width, img.height, root, _.extend({
          squeeze: squeeze
        }, options));
      }
    }
    if (isScss) {
      result += _cssImage.scss(img.file, img.width, img.height, root, _.extend({
        retina: isRetina
      }, options));
      if (squeeze !== 1) {
        result += _cssImage.scss(img.file, img.width, img.height, root, _.extend({
          squeeze: squeeze
        }, options));
      }
    }
  }
  return result;
}

module.exports = cssimage;
module.exports.CSSImage = CSSImage;
<|endoftext|>


<commit_before>exports.init        = require('./lib/middleware/init');
exports.context     = require('./lib/middleware/context');
exports.decode      = require('./lib/middleware/decode');
exports.validate    = require('./lib/middleware/validate');
exports.url         = require('./lib/middleware/url');
exports.esi         = require('./lib/middleware/esi');
exports.done        = require('./lib/middleware/done');

/**
Create composite middleware.
@method createComposite
@param {Function|Array} middleware* One or more middleware to combine.
@return {Function} Composite middleware.
**/
exports.createComposite = function () {
    var args     = Array.prototype.slice.apply(arguments),
        handlers = [];

    args.forEach(function (arg) {
        if (Array.isArray(arg)) {
            handlers.concat(arg);
        } else {
            handlers.push(arg);
        }
    });

    return function (req, res, next) {
        function run(index) {
            if (index < handlers.length) {
                handlers[index](req, res, function (err) {
                    if (err) {
                        return next(err);
                    }
                    index += 1;
                    run(index);
                });
            } else {
                next();
            }
        }
        run(0);
    };
};

/**
Middleware that decodes combo urls into ESI documents.
@method decodeToESI
@param {Object} config Configuration object.
@return {Function} Composite middleware that decodes combo urls into ESI docs.
**/
exports.decodeToESI = function (config) {
    return exports.createComposite([
        exports.init(config),
        exports.context(config),
        exports.decode(config),
        exports.validate(config),
        exports.url(config),
        exports.esi(config),
        exports.done(config)
    ]);
};
<commit_msg>fix bug in handler data struct normalization<commit_after>exports.init        = require('./lib/middleware/init');
exports.context     = require('./lib/middleware/context');
exports.decode      = require('./lib/middleware/decode');
exports.validate    = require('./lib/middleware/validate');
exports.url         = require('./lib/middleware/url');
exports.esi         = require('./lib/middleware/esi');
exports.done        = require('./lib/middleware/done');

/**
Create composite middleware.
@method createComposite
@param {Function|Array} middleware* One or more middleware to combine.
@return {Function} Composite middleware.
**/
exports.createComposite = function () {
    var args     = Array.prototype.slice.apply(arguments),
        handlers = [];

    args.forEach(function (arg) {
        if (Array.isArray(arg)) {
            handlers = handlers.concat(arg);
        } else {
            handlers.push(arg);
        }
    });

    return function (req, res, next) {
        function run(index) {
            if (index < handlers.length) {
                handlers[index](req, res, function (err) {
                    if (err) {
                        return next(err);
                    }
                    index += 1;
                    run(index);
                });
            } else {
                next();
            }
        }
        run(0);
    };
};

/**
Middleware that decodes combo urls into ESI documents.
@method decodeToESI
@param {Object} config Configuration object.
@return {Function} Composite middleware that decodes combo urls into ESI docs.
**/
exports.decodeToESI = function (config) {
    return exports.createComposite([
        exports.init(config),
        exports.context(config),
        exports.decode(config),
        exports.validate(config),
        exports.url(config),
        exports.esi(config),
        exports.done(config)
    ]);
};
<|endoftext|>


<commit_before>$(function(){

	var lastX = -1;
	var touchStartX = 0;

	var lastY = 0;
	var lastY_timestamp = 10000;

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

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

	$(".page").css("width", viewport.width);
	$(".page").css("height", viewport.height);
	$(".page").css("overflow-y", "auto");

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

		if($(this).height() > viewport.height) {
			$(this).addClass("scrollable");
		}

	});

	// $(".page").each(function(){
	// 	$(this).css("height", $(this).css("height"));
	// });

	// $(".page").each(function(){
	// 	if($(this).height() > viewport.height){
	// 		$(this).css("overflow-y", "auto");
	// 	}
	// });

	$(".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");
		});

	});

	// $(document).on("swipe", function(e){
	// 	e.preventDefault();
	// });

	$(document).on('touchmove', function(e) {
		e.preventDefault();
	    if ($(e.target).parents('#projectDetails')[0] ) {

	    	// if(e.originalEvent.touches[0].pageY - lastY > 0) {
	    	// 	$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - (e.originalEvent.touches[0].pageY + lastY));
	    	// } else {
	    	// 	$("#projectDetails").scrollTop($("#projectDetails").scrollTop() + (e.originalEvent.touches[0].pageY - lastY));
	    	// }
	    	if(Math.abs(e.timeStamp - lastY_timestamp) < 200) {
    		 	$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - (e.originalEvent.touches[0].pageY - lastY));
	    	}
	    	else if(Math.abs(e.timeStamp - lastY_timestamp) < 1000) {
				if(e.originalEvent.touches[0].pageY - lastY > 0) {
		    		$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - 25);
		    	}
		    	else if(e.originalEvent.touches[0].pageY - lastY < 0) {
		    		$("#projectDetails").scrollTop($("#projectDetails").scrollTop() + 25);
		    	}
	    	}

	    	lastY = e.originalEvent.touches[0].pageY;
	    	lastY_timestamp = e.timeStamp;
	    }
	});

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

		e.preventDefault();

		$("html, body").animate({
			scrollLeft: $($(this).attr("href")).offset().left
		}, 1000);

	});

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

		e.preventDefault();

		$("html, body").animate({
			scrollLeft: $($(this).attr("href")).offset().left
		}, 1000);

	});

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

		e.preventDefault();

		$("html, body").animate({
			scrollTop: $($(this).attr("href")).offset().top
		}, 1000);

	});

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

		e.preventDefault();

		$("html, body").animate({
			scrollTop: $($(this).attr("href")).offset().top
		}, 1000);

	});

});

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"]};
}<commit_msg>jkljlkl<commit_after>$(function(){

	var lastX = -1;
	var touchStartX = 0;

	var lastY = 0;
	var lastY_timestamp = 10000;

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

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

	$(".page").css("width", viewport.width);
	$(".page").css("height", viewport.height);
	$(".page").css("overflow-y", "auto");

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

		if($(this).height() > viewport.height) {
			$(this).addClass("scrollable");
		}

	});

	// $(".page").each(function(){
	// 	$(this).css("height", $(this).css("height"));
	// });

	// $(".page").each(function(){
	// 	if($(this).height() > viewport.height){
	// 		$(this).css("overflow-y", "auto");
	// 	}
	// });

	$(".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");
		});

	});

	// $(document).on("swipe", function(e){
	// 	e.preventDefault();
	// });

	$(document).on('touchmove', function(e) {
		e.preventDefault();
	    if ($(e.target).parents('#projectDetails')[0] ) {

	    	if(e.originalEvent.touches[0].pageY - lastY > 0) {
	    		$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - 25);
	    	} else {
	    		$("#projectDetails").scrollTop($("#projectDetails").scrollTop() + 25);
	    	}

	    	// if(e.originalEvent.touches[0].pageY - lastY > 0) {
	    	// 	$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - (e.originalEvent.touches[0].pageY + lastY));
	    	// } else {
	    	// 	$("#projectDetails").scrollTop($("#projectDetails").scrollTop() + (e.originalEvent.touches[0].pageY - lastY));
	    	// }
	   //  	if(Math.abs(e.timeStamp - lastY_timestamp) < 200) {
    // 		 	$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - (e.originalEvent.touches[0].pageY - lastY));
	   //  	}
	   //  	else if(Math.abs(e.timeStamp - lastY_timestamp) < 1000) {
				// if(e.originalEvent.touches[0].pageY - lastY > 0) {
		  //   		$("#projectDetails").scrollTop($("#projectDetails").scrollTop() - 25);
		  //   	}
		  //   	else if(e.originalEvent.touches[0].pageY - lastY < 0) {
		  //   		$("#projectDetails").scrollTop($("#projectDetails").scrollTop() + 25);
		  //   	}
	   //  	}

	    	// lastY = e.originalEvent.touches[0].pageY;
	    	// lastY_timestamp = e.timeStamp;
	    }
	});

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

		e.preventDefault();

		$("html, body").animate({
			scrollLeft: $($(this).attr("href")).offset().left
		}, 1000);

	});

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

		e.preventDefault();

		$("html, body").animate({
			scrollLeft: $($(this).attr("href")).offset().left
		}, 1000);

	});

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

		e.preventDefault();

		$("html, body").animate({
			scrollTop: $($(this).attr("href")).offset().top
		}, 1000);

	});

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

		e.preventDefault();

		$("html, body").animate({
			scrollTop: $($(this).attr("href")).offset().top
		}, 1000);

	});

});

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"]};
}<|endoftext|>


<commit_before>var Fuse = require('fuse.js');

var fuzzyFilter = function(value, options) {
  if (!options) {
    options = {};
  }
  var defaultOptions = {
    threshold: 0.4,
    location: 0,
    distance: 100,
    maxPatternLength: 32,
    keys: []
  };

  var fuse = null;
  var result = null;

  return function(val, key, array) {
    if (!fuse || !result) {
      fuse = new Fuse(array, Object.assign(defaultOptions, options))
      result = fuse.search(value);
    }
    if (typeof val === 'object') {
      var idValues = val;
      options.id.split('.').forEach(key => idValues = idValues[key])
      if (Array.isArray(idValues)) {
        var temp = idValues.reduce((prev, idValue) => (result.indexOf(idValue) !== -1 || prev), false)
        return temp;
      }
      return result.indexOf(idValues) !== -1;
    }
    return result.indexOf(key) !== -1;
  };
}

module.exports = fuzzyFilter;<commit_msg>return true if no value provided<commit_after>var Fuse = require('fuse.js');

var fuzzyFilter = function(value, options) {
  if (!value) {
    return function() {
      return true;
    }
  }
  if (!options) {
    options = {};
  }
  var defaultOptions = {
    threshold: 0.4,
    location: 0,
    distance: 100,
    maxPatternLength: 32,
    keys: []
  };

  var fuse = null;
  var result = null;

  return function(val, key, array) {
    if (!fuse || !result) {
      fuse = new Fuse(array, Object.assign(defaultOptions, options))
      result = fuse.search(value);
    }
    if (typeof val === 'object') {
      var idValues = val;
      options.id.split('.').forEach(key => idValues = idValues[key])
      if (Array.isArray(idValues)) {
        var temp = idValues.reduce((prev, idValue) => (result.indexOf(idValue) !== -1 || prev), false)
        return temp;
      }
      return result.indexOf(idValues) !== -1;
    }
    return result.indexOf(key) !== -1;
  };
}

module.exports = fuzzyFilter;<|endoftext|>


<commit_before>/**
 * @author Eoin Hennessy
 * @author Erik Desjardins
 * See LICENSE file in root directory for full license.
 */

'use strict';

var path = require('path');
var loaderUtils = require('loader-utils');
var SingleEntryPlugin = require('webpack').SingleEntryPlugin;
var InertEntryPlugin = require('inert-entry-webpack-plugin');

module.exports = function() {};

module.exports.pitch = function(request) {
	var callback = this.async();

	var options = loaderUtils.getOptions(this) || {};
	var filename = options.name || path.basename(this.resourcePath);
	var outputDir = options.path || '.';
	var plugins = options.plugins || [];
	if (options.inert) {
		plugins.push(new InertEntryPlugin());
	}

	// name of the entry and compiler (in logs)
	var debugName = loaderUtils.interpolateName(this, '[name]', {});

	// create a child compiler (hacky)
	var compiler = this._compilation.createChildCompiler(debugName, { filename: filename }, plugins);
	new SingleEntryPlugin(this.context, '!!' + request, debugName).apply(compiler);

	// add a dependency on the entry point of the child compiler, so watch mode works
	this.addDependency(request);

	// like compiler.runAsChild(), but remaps paths if necessary
	// https://github.com/webpack/webpack/blob/f6e366b4be1cfe2770251a890d93081824789209/lib/Compiler.js#L206
	compiler.compile(function(err, compilation) {
		if (err) return callback(err);

		this.parentCompilation.children.push(compilation);
		for (const name of Object.keys(compilation.assets)) {
			this.parentCompilation.assets[path.join(outputDir, name)] = compilation.assets[name];
		}

		// the first file in the first chunk of the first (should only be one) entry point is the real file
		// see https://github.com/webpack/webpack/blob/f6e366b4be1cfe2770251a890d93081824789209/lib/Compiler.js#L215
		var outputFilename = compilation.entrypoints.values().next().value.chunks[0].files[0];

		callback(null, 'module.exports = __webpack_public_path__ + ' + JSON.stringify(path.join(outputDir, outputFilename)) + ';')
	}.bind(compiler));
};
<commit_msg>plugins option: prepend to array, create new array<commit_after>/**
 * @author Eoin Hennessy
 * @author Erik Desjardins
 * See LICENSE file in root directory for full license.
 */

'use strict';

var path = require('path');
var loaderUtils = require('loader-utils');
var SingleEntryPlugin = require('webpack').SingleEntryPlugin;
var InertEntryPlugin = require('inert-entry-webpack-plugin');

module.exports = function() {};

module.exports.pitch = function(request) {
	var callback = this.async();

	var options = loaderUtils.getOptions(this) || {};
	var filename = options.name || path.basename(this.resourcePath);
	var outputDir = options.path || '.';
	var plugins = options.plugins || [];
	if (options.inert) {
		plugins = [new InertEntryPlugin()].concat(plugins);
	}

	// name of the entry and compiler (in logs)
	var debugName = loaderUtils.interpolateName(this, '[name]', {});

	// create a child compiler (hacky)
	var compiler = this._compilation.createChildCompiler(debugName, { filename: filename }, plugins);
	new SingleEntryPlugin(this.context, '!!' + request, debugName).apply(compiler);

	// add a dependency on the entry point of the child compiler, so watch mode works
	this.addDependency(request);

	// like compiler.runAsChild(), but remaps paths if necessary
	// https://github.com/webpack/webpack/blob/f6e366b4be1cfe2770251a890d93081824789209/lib/Compiler.js#L206
	compiler.compile(function(err, compilation) {
		if (err) return callback(err);

		this.parentCompilation.children.push(compilation);
		for (const name of Object.keys(compilation.assets)) {
			this.parentCompilation.assets[path.join(outputDir, name)] = compilation.assets[name];
		}

		// the first file in the first chunk of the first (should only be one) entry point is the real file
		// see https://github.com/webpack/webpack/blob/f6e366b4be1cfe2770251a890d93081824789209/lib/Compiler.js#L215
		var outputFilename = compilation.entrypoints.values().next().value.chunks[0].files[0];

		callback(null, 'module.exports = __webpack_public_path__ + ' + JSON.stringify(path.join(outputDir, outputFilename)) + ';')
	}.bind(compiler));
};
<|endoftext|>


<commit_before>/**
 *
 * DDBRest
 *
 * js client for the DDB API
 * @see  https://api.deutsche-digitale-bibliothek.de
 *
 */

var Q = require('q'),
    fs = require('fs'),
    util = require('util'),
    path = require('path'),
    merge = require('deepmerge'),
    request = require('request'),

    // models
    sectorTypes = require('./lib/models/sectorTypes'),
    hirarchyTypes = require('./lib/models/hierarchyTypes');

var DDBRest = module.exports = function(token, secure) {

    if (typeof token !== 'string') {
        throw new Error('API token is required to have access to the DBB API\nSee https://api.deutsche-digitale-bibliothek.de/doku/display/ADD/Autorisierung');
    }

    this.protocol = typeof secure === 'boolean' && secure ? 'https' : 'http';
    this.host = 'api.deutsche-digitale-bibliothek.de';
    this.oauth = {
        consumer_key: token
    };

};

DDBRest.prototype.search = function(query) {

    if (typeof query !== 'string') {
        throw new Error('search query needs to be a string');
    }

    var self = this,
        q = query,
        facets = [];

    return {
        from: function(date) {
            var facet = 'begin_time';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + date);
            return this;
        },
        to: function(date) {
            var facet = 'end_time';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + date);
            return this;
        },
        place: function(location) {
            var facet = 'place_fct';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + location);
            return this;
        },
        role: function(role) {
            var facet = 'affiliate_fct_role';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + role);
            return this;
        },
        keywords: function(keywords) {
            var facet = 'keywords_fct';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + keywords);
            return this;
        },
        language: function(language) {
            var facet = 'language_fct';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + language);
            return this;
        },
        type: function(type) {
            var facet = 'type_fct';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + type);
            return this;
        },
        sector: function(sector) {
            var facet = 'sector_fct',
                facetValue = sectorTypes[sector.toLowerCase()];

            if (typeof sector !== 'string') {
                throw new Error('sector facet should be type of string');
            }

            if (!facetValue) {
                throw new Error('sector ' + sector + ' couldn\'t be found!\nPlease try one of the following: ' + Object.keys(sectorTypes));
            }

            facets.push('facet=' + facet);
            facets.push(facet + '=' + facetValue.element);
            return this;
        },
        provider: function(provider) {
            var facet = 'provider_fct';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + provider);
            return this;
        },
        then: function(success, failure) {

            /**
             * concatinate query
             */
            var query = 'query=' + q + '&' + facets.join('&'),
                deferred = Q.defer();

            self.request('search', '', query, { json: true }, function(err, httpResponse, body) {

                if (err) {
                    return failure(new Error(err));
                }

                success(body, httpResponse);

            });

        }
    };
};

DDBRest.prototype.binary = function(identifier, binaryPathFile) {

    var self = this;

    /**
     * check required parameters
     */
    if (typeof identifier !== 'string' || typeof binaryPathFile !== 'string') {
        throw new Error('number or type of arguments don\'t agree with binary search');
    }

    return {
        then: function(success, failure) {
            return self.request('binary', path.join(identifier, binaryPathFile), '', { headers: { 'Accept': 'application/octet-stream' } }, function(err, httpResponse, body) {

                if (err) {
                    return failure(new Error(err));
                }

                if(typeof body === 'string' && body.indexOf('not found') > -1) {
                    err = JSON.parse(body);
                    return failure(new Error(err.name + ': ' + err.message));
                }

                success(body, httpResponse);

            });
        },
        toFile: function(fileName, cb) {

            if(typeof fileName !== 'string' || (cb && typeof cb !== 'function')) {
                throw new Error('number or type of arguments don\'t agree with binary.toFile command');
            }

            var req = self.request('binary', path.join(identifier, binaryPathFile), '', { headers: { 'Accept': 'application/octet-stream' } }, function(err, httpResponse, body) {

                if(err) {
                    throw new Error(err);
                }

                if(typeof body === 'string' && body.indexOf('not found') > -1) {
                    err = JSON.parse(body);
                    throw new Error(err.name + ': ' + err.message);
                }

                cb(err, httpResponse, body);

            }).pipe(fs.createWriteStream(fileName));

        }
    };
};

DDBRest.prototype.request = function(method, path, query, opts, cb) {
    var url = this.protocol + '://' + this.host + '/' + method + '/' + path,
        params = merge({ url: url, oauth: this.oauth }, opts || {});

    return request.get(params, cb);
};
<commit_msg>implemented institution method<commit_after>/**
 *
 * DDBRest
 *
 * js client for the DDB API
 * @see  https://api.deutsche-digitale-bibliothek.de
 *
 */

var Q = require('q'),
    fs = require('fs'),
    util = require('util'),
    path = require('path'),
    merge = require('deepmerge'),
    request = require('request'),

    // models
    sectorTypes = require('./lib/models/sectorTypes'),
    hirarchyTypes = require('./lib/models/hierarchyTypes');

var DDBRest = module.exports = function(token, secure) {

    if (typeof token !== 'string') {
        throw new Error('API token is required to have access to the DBB API\nSee https://api.deutsche-digitale-bibliothek.de/doku/display/ADD/Autorisierung');
    }

    this.protocol = typeof secure === 'boolean' && secure ? 'https' : 'http';
    this.host = 'api.deutsche-digitale-bibliothek.de';
    this.oauth = {
        consumer_key: token
    };

};

DDBRest.prototype.search = function(query) {

    if (typeof query !== 'string') {
        throw new Error('search query needs to be a string');
    }

    var self = this,
        q = query,
        facets = [];

    return {
        from: function(date) {
            var facet = 'begin_time';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + date);
            return this;
        },
        to: function(date) {
            var facet = 'end_time';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + date);
            return this;
        },
        place: function(location) {
            var facet = 'place_fct';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + location);
            return this;
        },
        role: function(role) {
            var facet = 'affiliate_fct_role';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + role);
            return this;
        },
        keywords: function(keywords) {
            var facet = 'keywords_fct';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + keywords);
            return this;
        },
        language: function(language) {
            var facet = 'language_fct';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + language);
            return this;
        },
        type: function(type) {
            var facet = 'type_fct';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + type);
            return this;
        },
        sector: function(sector) {
            var facet = 'sector_fct',
                facetValue = sectorTypes[sector.toLowerCase()];

            if (typeof sector !== 'string') {
                throw new Error('sector facet should be type of string');
            }

            if (!facetValue) {
                throw new Error('sector ' + sector + ' couldn\'t be found!\nPlease try one of the following: ' + Object.keys(sectorTypes));
            }

            facets.push('facet=' + facet);
            facets.push(facet + '=' + facetValue.element);
            return this;
        },
        provider: function(provider) {
            var facet = 'provider_fct';
            facets.push('facet=' + facet);
            facets.push(facet + '=' + provider);
            return this;
        },
        then: function(success, failure) {

            /**
             * concatinate query
             */
            var query = 'query=' + q + '&' + facets.join('&'),
                deferred = Q.defer();

            self.request('search', '', query, {
                json: true
            }, function(err, httpResponse, body) {

                if (!success) {
                    return;
                }

                if (err && failure) {
                    return failure(new Error(err));
                }

                success(body, httpResponse);

            });

        }
    };
};

DDBRest.prototype.binary = function(identifier, binaryPathFile) {

    var self = this;

    /**
     * check required parameters
     */
    if (typeof identifier !== 'string' || typeof binaryPathFile !== 'string') {
        throw new Error('number or type of arguments don\'t agree with binary search');
    }

    return {
        then: function(success, failure) {
            return self.request('binary', path.join(identifier, binaryPathFile), '', {
                headers: {
                    'Accept': 'application/octet-stream'
                }
            }, function(err, httpResponse, body) {

                if (!success) {
                    return;
                }

                if (err && failure) {
                    return failure(new Error(err));
                }

                if (typeof body === 'string' && body.indexOf('not found') > -1) {
                    err = JSON.parse(body);
                    return failure(new Error(err.name + ': ' + err.message));
                }

                success(body, httpResponse);

            });
        },
        toFile: function(fileName, cb) {

            if (typeof fileName !== 'string' || (cb && typeof cb !== 'function')) {
                throw new Error('number or type of arguments don\'t agree with binary.toFile command');
            }

            self.request('binary', path.join(identifier, binaryPathFile), '', {
                headers: {
                    'Accept': 'application/octet-stream'
                }
            }, function(err, httpResponse, body) {

                if (err) {
                    throw new Error(err);
                }

                if (typeof body === 'string' && body.indexOf('not found') > -1) {
                    err = JSON.parse(body);
                    throw new Error(err.name + ': ' + err.message);
                }

                cb(err, httpResponse, body);

            }).pipe(fs.createWriteStream(fileName));

        }
    };
};

DDBRest.prototype.institutions = function(type) {

    var self = this,
        sector = this.findSectorByTerm(type);

    return {
        then: function(success, failure) {

            var query = '';

            if (sector) {
                query = 'sector=' + sector.element;
            }

            self.request('institutions', '', query, {
                json: true
            }, function(err, httpResponse, body) {

                if (err && faliure) {
                    return failure(err);
                }

                if (typeof body === 'string' && body.indexOf('not found') > -1) {
                    err = JSON.parse(body);
                    return failure(err.name + ': ' + err.message);
                }

                success(body, httpResponse);

            });
        }
    };

};

DDBRest.prototype.request = function(method, path, query, opts, cb) {

    /**
     * check for obsolete args
     */
    if (typeof opts === 'function') {
        cb = opts;
        opts = {};
    } else if (typeof query === 'function') {
        cb = query;
        opts = {};
        query = '';
    }

    var url = this.protocol + '://' + this.host + '/' + method + '/' + path + '?' + query,
        params = merge({
            url: url,
            oauth: this.oauth
        }, opts || {});

    return request.get(params, cb);

};

DDBRest.prototype.findSectorByTerm = function(term) {

    if (!term) {
        return null;
    }

    var deElements = Object.keys(sectorTypes.de),
        enElements = Object.keys(sectorTypes.en),
        length = Math.max(deElements.length, enElements.length),
        enKey, deKey, i;

    for (i = 0; i < length; ++i) {

        enKey = enElements[i];
        deKey = deElements[i];

        if (sectorTypes.de[deKey] && sectorTypes.de[deKey].term === term) {
            sectorTypes.de[deKey].element = deKey;
            return sectorTypes.de[deKey];
        } else if (sectorTypes.de[enKey] && sectorTypes.en[enKey].term === term) {
            sectorTypes.en[enKey].element = enKey;
            return sectorTypes.en[enKey];
        }

    }

    return null;

};<|endoftext|>


<commit_before>// Register that we're using es6, so babel can compile import statements.
// The `ignore` set to false allows babel to compile npm modules, and the `only`
// forces it to only compile files with a `.es6.js` or `.jsx` extension.
require('babel/register')({
  ignore: false,
  only: /.+(?:(?:\.es6\.js)|(?:.jsx))$/,
  extensions: ['.js', '.es6.js', '.jsx' ],
  sourceMap: true,
});

var config;
var errorLog = require('./src/lib/errorLog');

process.on('uncaughtException', function (err) {
  var url;
  var line;

  if (err.stack) {
    var location = err.stack.split('\n')[1];
    url = location.split(':')[0];
    line = location.split(':')[1];
  }

  if (config) {
    errorLog({
      error: err,
      userAgent: 'SERVER',
      message: err.message,
      line: line,
      url: url,
    }, {
      hivemind: config.statsDomain,
    });
  }

  console.log('Caught exception: ' + err);
  process.exit();
});

// Check node version
require('./version');

// Require in the express server.
var Server = require('./src/server');

var cluster = require('cluster');
var numCPUs = process.env.PROCESSES || require('os').cpus().length;

// App config
var defaultConfig = require('./src/config');
var config = defaultConfig();

// Import built-asset manifests for passing to layouts
var jsManifest = require('./build/js/client-manifest.json');
var cssManifest = require('./build/css/css-manifest.json');
var servers = [];

var failedProcesses = 0;

// Then merge them into a single object for ease of use later
config.manifest = {};
config.processes = numCPUs;

function parseObject (list) {
  if (!list) { return; }
  var obj = {};
  var key;
  var value;
  var split;

  list.split(';').forEach(function (l) {
    if (l && l.indexOf('=')) {
      var split = l.split('=');
      obj[split[0].trim()] = split[1].trim();
    }
  });

  return obj;
}

function parseList (list) {
  if (!list) { return; }
  return list.split(';');
}

config.apiHeaders = parseObject(process.env.API_HEADERS);
config.apiPassThroughHeaders = parseList(process.env.API_PASS_THROUGH_HEADERS);
config.actionNameSecret = process.env.ACTION_NAME_SECRET;

config.experiments = parseObject(process.env.EXPERIMENTS);

Object.assign(config.manifest, jsManifest, cssManifest);

function start(config) {
  var server = new Server(config);
  server.start();
  return server;
}

// Private, server-only config that we don't put in config.js, which is shared
config.liveReload = process.env.LIVERELOAD === 'true';
config.oauth = {
  clientId: process.env.OAUTH_CLIENT_ID || '',
  secret: process.env.OAUTH_SECRET || '',

  secretClientId: process.env.SECRET_OAUTH_CLIENT_ID || '',
  secretSecret: process.env.SECRET_OAUTH_SECRET || '',
};

config.keys = [ process.env.SERVER_SIGNED_COOKIE_KEY || 'lambeosaurus' ];

if (cluster.isMaster) {
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  Server.info(config);

  cluster.on('exit', function(worker, code, signal) {
    if (failedProcesses < 20) {
      console.log('Worker ' + worker.process.pid + ' died, restarting.');
      cluster.fork();
      failedProcesses++;
    } else {
      console.log('Workers died too many times, exiting.');
      process.exit();
    }
  });
} else {
  servers.push(start(config));
}
<commit_msg>Server: use babel stage 0<commit_after>// Register that we're using es6, so babel can compile import statements.
// The `ignore` set to false allows babel to compile npm modules, and the `only`
// forces it to only compile files with a `.es6.js` or `.jsx` extension.
require('babel/register')({
  ignore: false,
  only: /.+(?:(?:\.es6\.js)|(?:.jsx))$/,
  extensions: ['.js', '.es6.js', '.jsx' ],
  sourceMap: true,
  stage: 0,
});

var config;
var errorLog = require('./src/lib/errorLog');

process.on('uncaughtException', function (err) {
  var url;
  var line;

  if (err.stack) {
    var location = err.stack.split('\n')[1];
    url = location.split(':')[0];
    line = location.split(':')[1];
  }

  if (config) {
    errorLog({
      error: err,
      userAgent: 'SERVER',
      message: err.message,
      line: line,
      url: url,
    }, {
      hivemind: config.statsDomain,
    });
  }

  console.log('Caught exception: ' + err);
  process.exit();
});

// Check node version
require('./version');

// Require in the express server.
var Server = require('./src/server');

var cluster = require('cluster');
var numCPUs = process.env.PROCESSES || require('os').cpus().length;

// App config
var defaultConfig = require('./src/config');
var config = defaultConfig();

// Import built-asset manifests for passing to layouts
var jsManifest = require('./build/js/client-manifest.json');
var cssManifest = require('./build/css/css-manifest.json');
var servers = [];

var failedProcesses = 0;

// Then merge them into a single object for ease of use later
config.manifest = {};
config.processes = numCPUs;

function parseObject (list) {
  if (!list) { return; }
  var obj = {};
  var key;
  var value;
  var split;

  list.split(';').forEach(function (l) {
    if (l && l.indexOf('=')) {
      var split = l.split('=');
      obj[split[0].trim()] = split[1].trim();
    }
  });

  return obj;
}

function parseList (list) {
  if (!list) { return; }
  return list.split(';');
}

config.apiHeaders = parseObject(process.env.API_HEADERS);
config.apiPassThroughHeaders = parseList(process.env.API_PASS_THROUGH_HEADERS);
config.actionNameSecret = process.env.ACTION_NAME_SECRET;

config.experiments = parseObject(process.env.EXPERIMENTS);

Object.assign(config.manifest, jsManifest, cssManifest);

function start(config) {
  var server = new Server(config);
  server.start();
  return server;
}

// Private, server-only config that we don't put in config.js, which is shared
config.liveReload = process.env.LIVERELOAD === 'true';
config.oauth = {
  clientId: process.env.OAUTH_CLIENT_ID || '',
  secret: process.env.OAUTH_SECRET || '',

  secretClientId: process.env.SECRET_OAUTH_CLIENT_ID || '',
  secretSecret: process.env.SECRET_OAUTH_SECRET || '',
};

config.keys = [ process.env.SERVER_SIGNED_COOKIE_KEY || 'lambeosaurus' ];

if (cluster.isMaster) {
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  Server.info(config);

  cluster.on('exit', function(worker, code, signal) {
    if (failedProcesses < 20) {
      console.log('Worker ' + worker.process.pid + ' died, restarting.');
      cluster.fork();
      failedProcesses++;
    } else {
      console.log('Workers died too many times, exiting.');
      process.exit();
    }
  });
} else {
  servers.push(start(config));
}
<|endoftext|>