<commit_before>/*
  Module dependencies
*/
var ElementType = require('domelementtype');
var entities = require('entities');

/*
  Boolean Attributes
*/
var booleanAttributes = {
  __proto__: null,
  allowfullscreen: true,
  async: true,
  autofocus: true,
  autoplay: true,
  checked: true,
  controls: true,
  default: true,
  defer: true,
  disabled: true,
  hidden: true,
  ismap: true,
  loop: true,
  multiple: true,
  muted: true,
  open: true,
  readonly: true,
  required: true,
  reversed: true,
  scoped: true,
  seamless: true,
  selected: true,
  typemustmatch: true
};

var unencodedElements = {
  __proto__: null,
  style: true,
  script: true,
  xmp: true,
  iframe: true,
  noembed: true,
  noframes: true,
  plaintext: true,
  noscript: true
};

/*
  Format attributes
*/
function formatAttrs(attributes, opts) {
  if (!attributes) return;

  var output = '',
      value;

  // Loop through the attributes
  for (var key in attributes) {
    value = attributes[key];
    if (output) {
      output += ' ';
    }

    if (!value && booleanAttributes[key]) {
      output += key;
    } else {
      output += key + '="' + (opts.decodeEntities ? entities.encodeXML(value) : value) + '"';
    }
  }

  return output;
}

/*
  Self-enclosing tags (stolen from node-htmlparser)
*/
var singleTag = {
  __proto__: null,
  area: true,
  base: true,
  basefont: true,
  br: true,
  col: true,
  command: true,
  embed: true,
  frame: true,
  hr: true,
  img: true,
  input: true,
  isindex: true,
  keygen: true,
  link: true,
  meta: true,
  param: true,
  source: true,
  track: true,
  wbr: true,
};

var render = module.exports = function(dom, opts) {
  if (!Array.isArray(dom) && !dom.cheerio) dom = [dom];
  opts = opts || {};

  var output = '';

  for(var i = 0; i < dom.length; i++){
    var elem = dom[i];

    if (elem.type === 'root')
      output += render(elem.children, opts);
    else if (ElementType.isTag(elem))
      output += renderTag(elem, opts);
    else if (elem.type === ElementType.Directive)
      output += renderDirective(elem);
    else if (elem.type === ElementType.Comment)
      output += renderComment(elem);
    else if (elem.type === ElementType.CDATA)
      output += renderCdata(elem);
    else
      output += renderText(elem, opts);
  }

  return output;
};

function renderTag(elem, opts) {
  // Handle SVG
  if (elem.name === "svg") opts = {decodeEntities: opts.decodeEntities, xmlMode: true};

  var tag = '<' + elem.name,
      attribs = formatAttrs(elem.attribs, opts);

  if (attribs) {
    tag += ' ' + attribs;
  }

  if (
    opts.xmlMode
    && (!elem.children || elem.children.length === 0)
  ) {
    tag += '/>';
  } else {
    tag += '>';
    if (elem.children) {
      tag += render(elem.children, opts);
    }

    if (!singleTag[elem.name] || opts.xmlMode) {
      tag += '</' + elem.name + '>';
    }
  }

  return tag;
}

function renderDirective(elem) {
  return '<' + elem.data + '>';
}

function renderText(elem, opts) {
  var data = elem.data || '';

  // if entities weren't decoded, no need to encode them back
  if (opts.decodeEntities && !(elem.parent && elem.parent.name in unencodedElements)) {
    data = entities.encodeXML(data);
  }

  return data;
}

function renderCdata(elem) {
  return '<![CDATA[' + elem.children[0].data + ']]>';
}

function renderComment(elem) {
  return '<!--' + elem.data + '-->';
}
<commit_msg>Wrap `default` in quotes<commit_after>/*
  Module dependencies
*/
var ElementType = require('domelementtype');
var entities = require('entities');

/*
  Boolean Attributes
*/
var booleanAttributes = {
  __proto__: null,
  allowfullscreen: true,
  async: true,
  autofocus: true,
  autoplay: true,
  checked: true,
  controls: true,
  'default': true,
  defer: true,
  disabled: true,
  hidden: true,
  ismap: true,
  loop: true,
  multiple: true,
  muted: true,
  open: true,
  readonly: true,
  required: true,
  reversed: true,
  scoped: true,
  seamless: true,
  selected: true,
  typemustmatch: true
};

var unencodedElements = {
  __proto__: null,
  style: true,
  script: true,
  xmp: true,
  iframe: true,
  noembed: true,
  noframes: true,
  plaintext: true,
  noscript: true
};

/*
  Format attributes
*/
function formatAttrs(attributes, opts) {
  if (!attributes) return;

  var output = '',
      value;

  // Loop through the attributes
  for (var key in attributes) {
    value = attributes[key];
    if (output) {
      output += ' ';
    }

    if (!value && booleanAttributes[key]) {
      output += key;
    } else {
      output += key + '="' + (opts.decodeEntities ? entities.encodeXML(value) : value) + '"';
    }
  }

  return output;
}

/*
  Self-enclosing tags (stolen from node-htmlparser)
*/
var singleTag = {
  __proto__: null,
  area: true,
  base: true,
  basefont: true,
  br: true,
  col: true,
  command: true,
  embed: true,
  frame: true,
  hr: true,
  img: true,
  input: true,
  isindex: true,
  keygen: true,
  link: true,
  meta: true,
  param: true,
  source: true,
  track: true,
  wbr: true,
};

var render = module.exports = function(dom, opts) {
  if (!Array.isArray(dom) && !dom.cheerio) dom = [dom];
  opts = opts || {};

  var output = '';

  for(var i = 0; i < dom.length; i++){
    var elem = dom[i];

    if (elem.type === 'root')
      output += render(elem.children, opts);
    else if (ElementType.isTag(elem))
      output += renderTag(elem, opts);
    else if (elem.type === ElementType.Directive)
      output += renderDirective(elem);
    else if (elem.type === ElementType.Comment)
      output += renderComment(elem);
    else if (elem.type === ElementType.CDATA)
      output += renderCdata(elem);
    else
      output += renderText(elem, opts);
  }

  return output;
};

function renderTag(elem, opts) {
  // Handle SVG
  if (elem.name === "svg") opts = {decodeEntities: opts.decodeEntities, xmlMode: true};

  var tag = '<' + elem.name,
      attribs = formatAttrs(elem.attribs, opts);

  if (attribs) {
    tag += ' ' + attribs;
  }

  if (
    opts.xmlMode
    && (!elem.children || elem.children.length === 0)
  ) {
    tag += '/>';
  } else {
    tag += '>';
    if (elem.children) {
      tag += render(elem.children, opts);
    }

    if (!singleTag[elem.name] || opts.xmlMode) {
      tag += '</' + elem.name + '>';
    }
  }

  return tag;
}

function renderDirective(elem) {
  return '<' + elem.data + '>';
}

function renderText(elem, opts) {
  var data = elem.data || '';

  // if entities weren't decoded, no need to encode them back
  if (opts.decodeEntities && !(elem.parent && elem.parent.name in unencodedElements)) {
    data = entities.encodeXML(data);
  }

  return data;
}

function renderCdata(elem) {
  return '<![CDATA[' + elem.children[0].data + ']]>';
}

function renderComment(elem) {
  return '<!--' + elem.data + '-->';
}
<|endoftext|>


<commit_before>const request = require("request")
const fs = require("fs")
const dots = require("dot").process({ path: "./views", templateSettings: { strip: false } })
const mkdirp = require('mkdirp')

function fetchData(levelId) {
  let url = `http://elmaonline.net/API/times/${levelId}?bestall=all&noorder=0&timeformat=hs`
  return new Promise((resolve, reject) => {
    request(url, (error, response, body) => {
      if (error) return reject(error)
      return resolve(Object.values(JSON.parse(body)))
    })
  })
}

function leading0(number) { return number < 10 ? "0" : "" }

function hsToFormatted(hs) {
  let mins = parseInt((hs / 100) / 60)
  let secs = parseInt((hs / 100) % 60)
  let huns = parseInt(hs % 100)
  return leading0(mins) + mins + ":" + leading0(secs) + secs + "," + leading0(huns) + huns
}

function writeHTML(data) {
  data = dots.index(data, { strip: false })
  mkdirp('./dist', err => {
      if (err) console.error(err)
      fs.writeFileSync('./dist/index.html', data)
  })
}

function calculateStats(data, deadline) {
  // convert string dates to Date objects, make up for -7hr timezone difference to UTC (?)
  // might need to edit this to take into consideration something, not sure yet
  data.forEach(val => {
    val.datetime = new Date(val.datetime)
    val.datetime.setHours(val.datetime.getHours() + 7)
  })

  data.sort((a, b) => {
    return a.datetime - b.datetime
  })

  let leaders = []
  let durations = {}
  let times = {}

  data.forEach(entry => {
    let lead = false

    // check if before deadline
    if (entry.datetime.getTime() < deadline.getTime()) {
      // leader checks
      if (leaders.length > 0) {
        if (parseInt(entry.time) < parseInt(leaders[leaders.length-1].time)) { // better than last leading time
          lead = true
          if (durations[entry.kuski] === undefined) durations[entry.kuski] = 0
          durations[leaders[leaders.length-1].name] += Math.abs(leaders[leaders.length-1].date - entry.datetime)
          leaders.push({ name: entry.kuski, time: parseInt(entry.time), date: entry.datetime })
        }
      } else { // first time
        leaders.push({ name: entry.kuski, time: parseInt(entry.time), date: entry.datetime })
        durations[entry.kuski] = 0
      }

      // add new nick to times list if not exist
      if (!times[entry.kuski]) {
        times[entry.kuski] = [{ time: parseInt(entry.time), date: entry.datetime, leader: lead }]

      } else if (parseInt(entry.time) < times[entry.kuski][times[entry.kuski].length - 1].time) { // if nick exist, check if time better
        times[entry.kuski].push({ time: parseInt(entry.time), date: entry.datetime, leader: lead })
      }
    }
  })

  // finally add remaining time up to deadline to leader
  durations[leaders[leaders.length-1].name] += Math.abs(leaders[leaders.length-1].date - deadline)

  // order durations
  const orderedDurations = {}
  Object.keys(durations).sort((a, b) => {
    return durations[b] - durations[a]
  }).forEach(key => {
    let date = new Date(durations[key])
    orderedDurations[key] = {
      ms: durations[key],
      days: date.getUTCDate()-1,
      hours: date.getUTCHours(),
      mins: date.getUTCMinutes(),
      secs: date.getUTCSeconds()
    }
  })

  // order times by nick for chart
  const orderedTimes = {}
  Object.keys(times).sort((a, b) => {
    return a.toLowerCase().localeCompare(b.toLowerCase())
  }).forEach(key => {
    orderedTimes[key] = times[key]
  })

  return { leaders: leaders, durations: orderedDurations, times: orderedTimes }
}

function hashColor(str) {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash)
  }
  let colour = '#'
  for (let i = 0; i < 3; i++) {
    let value = (hash >> (i * 8)) & 0xFF
    colour += ('00' + value.toString(16)).substr(-2)
  }
  return colour
}

function produceRegularChart(data, startDate, endDate) {
  let startFormatted = Date.UTC(startDate.getUTCFullYear(), startDate.getUTCMonth(), startDate.getUTCDate(),
    startDate.getUTCHours()-1, startDate.getUTCMinutes())
  let endFormatted = Date.UTC(endDate.getUTCFullYear(), endDate.getUTCMonth(), endDate.getUTCDate(),
    endDate.getUTCHours()+1, endDate.getUTCMinutes())
  let { leaders, durations, times } = data

  let chartData = { series: [], startFormatted: startFormatted, endFormatted: endFormatted, winTime: leaders[leaders.length-1].time }

  for (name in times) {
    let data = []
    times[name].forEach(time => {
      let dateFormatted = Date.UTC(time.date.getUTCFullYear(), time.date.getUTCMonth(), time.date.getUTCDate(),
        time.date.getUTCHours(), time.date.getUTCMinutes())
      if (time.leader) {
        data.push({ y: time.time, x: dateFormatted, formatted: hsToFormatted(time.time), dataLabels: {
          format: `${hsToFormatted(time.time)}`, style: { color: '#ab2020', fontSize: '13px' }, zIndex: 10, allowOverlap: true }
        })
      } else {
        data.push({ y: time.time, x: dateFormatted, formatted: hsToFormatted(time.time) })
      }
    })
    // pad to past end date
    data.push({ y: data[data.length-1].y, x: endFormatted + 86400000, formatted: hsToFormatted(data[data.length-1].y) })

    chartData.series.push({ name: name, data: data, visible: durations[name] !== undefined, step: 'left', marker: { enabled: true }, color: hashColor(name) })
  }

  return chartData
}

function createHTML(events) {
  let eh = events.map(event => {
    return fetchData(event.levelId).then(result => {
      let { leaders, durations, times } = calculateStats(result, event.endDate)
      let chartData = produceRegularChart({ leaders, durations, times }, event.startDate, event.endDate)
      return {
        title: event.title || '',
        startFormatted: JSON.stringify(chartData.startFormatted, null, 2),
        endFormatted: JSON.stringify(chartData.endFormatted, null, 2),
        winTime: JSON.stringify(chartData.winTime, null, 2),
        series: JSON.stringify(chartData.series, null, 2),
        durations: durations
      }
    })
  })

  Promise.all(eh).then(result => {
    writeHTML(result)
  }).catch(e => { console.log(e) })
}

let events = [
  { title: "WCup701", startDate: new Date('2017-02-19 19:00'), endDate: new Date('2017-02-26 17:00'), levelId: 371127 },
  { title: "WCup702", startDate: new Date('2017-02-26 17:00'), endDate: new Date('2017-03-05 17:00'), levelId: 371726 },
  { title: "WCup703", startDate: new Date('2017-03-05 17:00'), endDate: new Date('2017-03-12 18:00'), levelId: 372197 },
  { title: "WCup704", startDate: new Date('2017-03-12 18:00'), endDate: new Date('2017-03-19 18:00'), levelId: 372760 },
  { title: "WCup706", startDate: new Date('2017-03-26 17:00'), endDate: new Date('2017-04-02 17:00'), levelId: 374120 },
  { title: "WCup707", startDate: new Date('2017-04-02 17:00'), endDate: new Date('2017-04-09 17:00'), levelId: 374907 },
  { title: "WCup708", startDate: new Date('2017-04-09 17:00'), endDate: new Date('2017-04-16 17:00'), levelId: 376243 },
  { title: "WCup709", startDate: new Date('2017-04-16 17:00'), endDate: new Date('2017-04-20 17:00'), levelId: 376749 },
  { title: "WCup710", startDate: new Date('2017-04-20 17:00'), endDate: new Date('2017-04-23 17:00'), levelId: 376988 },
]

createHTML(events)
<commit_msg>add: 11th event<commit_after>const request = require("request")
const fs = require("fs")
const dots = require("dot").process({ path: "./views", templateSettings: { strip: false } })
const mkdirp = require('mkdirp')

function fetchData(levelId) {
  let url = `http://elmaonline.net/API/times/${levelId}?bestall=all&noorder=0&timeformat=hs`
  return new Promise((resolve, reject) => {
    request(url, (error, response, body) => {
      if (error) return reject(error)
      return resolve(Object.values(JSON.parse(body)))
    })
  })
}

function leading0(number) { return number < 10 ? "0" : "" }

function hsToFormatted(hs) {
  let mins = parseInt((hs / 100) / 60)
  let secs = parseInt((hs / 100) % 60)
  let huns = parseInt(hs % 100)
  return leading0(mins) + mins + ":" + leading0(secs) + secs + "," + leading0(huns) + huns
}

function writeHTML(data) {
  data = dots.index(data, { strip: false })
  mkdirp('./dist', err => {
      if (err) console.error(err)
      fs.writeFileSync('./dist/index.html', data)
  })
}

function calculateStats(data, deadline) {
  // convert string dates to Date objects, make up for -7hr timezone difference to UTC (?)
  // might need to edit this to take into consideration something, not sure yet
  data.forEach(val => {
    val.datetime = new Date(val.datetime)
    val.datetime.setHours(val.datetime.getHours() + 7)
  })

  data.sort((a, b) => {
    return a.datetime - b.datetime
  })

  let leaders = []
  let durations = {}
  let times = {}

  data.forEach(entry => {
    let lead = false

    // check if before deadline
    if (entry.datetime.getTime() < deadline.getTime()) {
      // leader checks
      if (leaders.length > 0) {
        if (parseInt(entry.time) < parseInt(leaders[leaders.length-1].time)) { // better than last leading time
          lead = true
          if (durations[entry.kuski] === undefined) durations[entry.kuski] = 0
          durations[leaders[leaders.length-1].name] += Math.abs(leaders[leaders.length-1].date - entry.datetime)
          leaders.push({ name: entry.kuski, time: parseInt(entry.time), date: entry.datetime })
        }
      } else { // first time
        leaders.push({ name: entry.kuski, time: parseInt(entry.time), date: entry.datetime })
        durations[entry.kuski] = 0
      }

      // add new nick to times list if not exist
      if (!times[entry.kuski]) {
        times[entry.kuski] = [{ time: parseInt(entry.time), date: entry.datetime, leader: lead }]

      } else if (parseInt(entry.time) < times[entry.kuski][times[entry.kuski].length - 1].time) { // if nick exist, check if time better
        times[entry.kuski].push({ time: parseInt(entry.time), date: entry.datetime, leader: lead })
      }
    }
  })

  // finally add remaining time up to deadline to leader
  durations[leaders[leaders.length-1].name] += Math.abs(leaders[leaders.length-1].date - deadline)

  // order durations
  const orderedDurations = {}
  Object.keys(durations).sort((a, b) => {
    return durations[b] - durations[a]
  }).forEach(key => {
    let date = new Date(durations[key])
    orderedDurations[key] = {
      ms: durations[key],
      days: date.getUTCDate()-1,
      hours: date.getUTCHours(),
      mins: date.getUTCMinutes(),
      secs: date.getUTCSeconds()
    }
  })

  // order times by nick for chart
  const orderedTimes = {}
  Object.keys(times).sort((a, b) => {
    return a.toLowerCase().localeCompare(b.toLowerCase())
  }).forEach(key => {
    orderedTimes[key] = times[key]
  })

  return { leaders: leaders, durations: orderedDurations, times: orderedTimes }
}

function hashColor(str) {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash)
  }
  let colour = '#'
  for (let i = 0; i < 3; i++) {
    let value = (hash >> (i * 8)) & 0xFF
    colour += ('00' + value.toString(16)).substr(-2)
  }
  return colour
}

function produceRegularChart(data, startDate, endDate) {
  let startFormatted = Date.UTC(startDate.getUTCFullYear(), startDate.getUTCMonth(), startDate.getUTCDate(),
    startDate.getUTCHours()-1, startDate.getUTCMinutes())
  let endFormatted = Date.UTC(endDate.getUTCFullYear(), endDate.getUTCMonth(), endDate.getUTCDate(),
    endDate.getUTCHours()+1, endDate.getUTCMinutes())
  let { leaders, durations, times } = data

  let chartData = { series: [], startFormatted: startFormatted, endFormatted: endFormatted, winTime: leaders[leaders.length-1].time }

  for (name in times) {
    let data = []
    times[name].forEach(time => {
      let dateFormatted = Date.UTC(time.date.getUTCFullYear(), time.date.getUTCMonth(), time.date.getUTCDate(),
        time.date.getUTCHours(), time.date.getUTCMinutes())
      if (time.leader) {
        data.push({ y: time.time, x: dateFormatted, formatted: hsToFormatted(time.time), dataLabels: {
          format: `${hsToFormatted(time.time)}`, style: { color: '#ab2020', fontSize: '13px' }, zIndex: 10, allowOverlap: true }
        })
      } else {
        data.push({ y: time.time, x: dateFormatted, formatted: hsToFormatted(time.time) })
      }
    })
    // pad to past end date
    data.push({ y: data[data.length-1].y, x: endFormatted + 86400000, formatted: hsToFormatted(data[data.length-1].y) })

    chartData.series.push({ name: name, data: data, visible: durations[name] !== undefined, step: 'left', marker: { enabled: true }, color: hashColor(name) })
  }

  return chartData
}

function createHTML(events) {
  let eh = events.map(event => {
    return fetchData(event.levelId).then(result => {
      let { leaders, durations, times } = calculateStats(result, event.endDate)
      let chartData = produceRegularChart({ leaders, durations, times }, event.startDate, event.endDate)
      return {
        title: event.title || '',
        startFormatted: JSON.stringify(chartData.startFormatted, null, 2),
        endFormatted: JSON.stringify(chartData.endFormatted, null, 2),
        winTime: JSON.stringify(chartData.winTime, null, 2),
        series: JSON.stringify(chartData.series, null, 2),
        durations: durations
      }
    })
  })

  Promise.all(eh).then(result => {
    writeHTML(result)
  }).catch(e => { console.log(e) })
}

let events = [
  { title: "WCup701", startDate: new Date('2017-02-19 19:00'), endDate: new Date('2017-02-26 17:00'), levelId: 371127 },
  { title: "WCup702", startDate: new Date('2017-02-26 17:00'), endDate: new Date('2017-03-05 17:00'), levelId: 371726 },
  { title: "WCup703", startDate: new Date('2017-03-05 17:00'), endDate: new Date('2017-03-12 18:00'), levelId: 372197 },
  { title: "WCup704", startDate: new Date('2017-03-12 18:00'), endDate: new Date('2017-03-19 18:00'), levelId: 372760 },
  { title: "WCup706", startDate: new Date('2017-03-26 17:00'), endDate: new Date('2017-04-02 17:00'), levelId: 374120 },
  { title: "WCup707", startDate: new Date('2017-04-02 17:00'), endDate: new Date('2017-04-09 17:00'), levelId: 374907 },
  { title: "WCup708", startDate: new Date('2017-04-09 17:00'), endDate: new Date('2017-04-16 17:00'), levelId: 376243 },
  { title: "WCup709", startDate: new Date('2017-04-16 17:00'), endDate: new Date('2017-04-20 17:00'), levelId: 376749 },
  { title: "WCup710", startDate: new Date('2017-04-20 17:00'), endDate: new Date('2017-04-23 17:00'), levelId: 376988 },
  { title: "WCup711", startDate: new Date('2017-04-23 17:00'), endDate: new Date('2017-04-30 17:00'), levelId: 377165 },
]

createHTML(events)
<|endoftext|>


<commit_before>'use strict';

var kraken = require('kraken-js'),
    app = {};

app.configure = function configure(nconf, next) {
    // Async method run on startup.
    next(null);
};

app.requestStart = function requestStart(server) {
    // Run before most express middleware has been registered.
};

app.requestBeforeRoute = function requestBeforeRoute(server) {
    // Run before any routes have been added.
};

app.requestAfterRoute = function requestAfterRoute(server) {
    // Run after all routes have been added.
};

if (require.main === module) {
    kraken.create(app).listen(process.env.VCAP_APP_PORT || 8000, function (err) {
        if (err) {
            console.error(err.stack);
        }
    });
}

module.exports = app;
<commit_msg>added tracking<commit_after>'use strict';

var kraken = require('kraken-js'),
    app = {};

app.configure = function configure(nconf, next) {
    // Async method run on startup.
    next(null);
};

app.requestStart = function requestStart(server) {
    // Run before most express middleware has been registered.
};

app.requestBeforeRoute = function requestBeforeRoute(server) {
    // Run before any routes have been added.
};

app.requestAfterRoute = function requestAfterRoute(server) {
    // Run after all routes have been added.
};

if (require.main === module) {
    kraken.create(app).listen(process.env.VCAP_APP_PORT || 8000, function (err) {
        if (err) {
            console.error(err.stack);
        }
    });
}

//remove the following to disable tracking
require("cf-deployment-tracker-client").track();

module.exports = app;
<|endoftext|>


<commit_before>'use strict';

import {
  DeviceEventEmitter,
  NativeModules
} from 'react-native';

const {MobileDeviceManager} = NativeModules;

export default {
  ...MobileDeviceManager,
  addListener (callback) {
    return DeviceEventEmitter.addListener(
      MobileDeviceManager.APP_CONFIG_CHANGED,
      callback
    );
  }
};
<commit_msg>index.js add new listener<commit_after>'use strict';

import {
  DeviceEventEmitter,
  NativeModules
} from 'react-native';

const {MobileDeviceManager} = NativeModules;

export default {
  ...MobileDeviceManager,
  addAppConfigListener (callback) {
    return DeviceEventEmitter.addListener(
      MobileDeviceManager.APP_CONFIG_CHANGED,
      callback
    );
  },
  addScreenLockListener (callback) {
    return DeviceEventEmitter.addListener(
      MobileDeviceManager.APP_LOCK_STATUS_CHANGED,
      callback
    );
  }
};
<|endoftext|>


<commit_before>module.exports =
{
	Context:	require('./iBot-Context'),
	Server:		require('./iBot-Server'),
	User:		require('./iBot-User'),
	Channel:	require('./iBot-Channel'),
	Mode:		require('./iBot-Mode'),
	start: function(path)
	{
		var fs = require('fs');

		var ctx = undefined;

		if(path === undefined) path = process.cwd() + '/config.json';

		fs.readFile(path, function(err, data)
		{
			if(err) console.log(err);
			else
			{
				try
				{
					var config = JSON.parse(data);
					ctx = new module.exports.Context(config);
					ctx.start();
				}
				catch(e)
				{
					console.log('Errors parsing config file:');
					console.log(e.stack);
				}
			}
		});
	}
};
<commit_msg>Fixed permissions on index.js since executable flag not required.<commit_after>module.exports =
{
	Context:	require('./iBot-Context'),
	Server:		require('./iBot-Server'),
	User:		require('./iBot-User'),
	Channel:	require('./iBot-Channel'),
	Mode:		require('./iBot-Mode'),
	start: function(path)
	{
		var fs = require('fs');

		var ctx = undefined;

		if(path === undefined) path = process.cwd() + '/config.json';

		fs.readFile(path, function(err, data)
		{
			if(err) console.log(err);
			else
			{
				try
				{
					var config = JSON.parse(data);
					ctx = new module.exports.Context(config);
					ctx.start();
				}
				catch(e)
				{
					console.log('Errors parsing config file:');
					console.log(e.stack);
				}
			}
		});
	}
};
<|endoftext|>


<commit_before>function head (a) {
  return a[0]
}

function last (a) {
  return a[a.length - 1]
}

function tail(a) {
  return a.slice(1)
}

function retreat (e) {
  return e.pop()
}

function hasLength (e) {
  return e.length
}

function any(ary, test) {
  for(var i in ary)
    if(test(ary[i]))
      return true
  return false
}

var _rules // set at the bottom

// note, naive implementation. will break on circular objects.

function _equal(a, b) {
  if(a && !b) return false
  if(Array.isArray(a))
    if(a.length != b.length) return false
  if(a && 'object' == typeof a) {
    for(var i in a)
      if(!equal(a[i], b[i])) return false
    return true
  }
  return a == b
}

function getArgs(args) {
  return args.length == 1 ? args[0] : [].slice.call(args)
}

// return the index of the element not like the others, or -1
function oddElement(ary, cmp) {
  var c
  function guess(a) {
    var odd = -1
    c = 0
    for (var i = a; i < ary.length; i ++) {
      if(!cmp(ary[a], ary[i])) {
        odd = i, c++
      }
    }
    return c > 1 ? -1 : odd
  }
  //assume that it is the first element.
  var g = guess(0)
  if(-1 != g) return g
  //0 was the odd one, then all the other elements are equal
  //else there more than one different element
  guess(1)
  return c == 0 ? 0 : -1
}
var exports = module.exports = function (deps, exports) {
  var equal = (deps && deps.equal) || _equal
  exports = exports || {}
  exports.lcs =
  function lcs() {
    var cache = {}
    var args = getArgs(arguments)

    function key (a,b){
      return a.length + ':' + b.length
    }

    function recurse (a, b) {

      if(!a.length || !b.length) return []
      //avoid exponential time by caching the results
      if(cache[key(a, b)]) return cache[key(a, b)]

      if(equal(a[0], b[0]))
        return [head(a)].concat(recurse(tail(a), tail(b)))
      else {
        var _a = recurse(tail(a), b)
        var _b = recurse(a, tail(b))
        return cache[key(a,b)] = _a.length > _b.length ? _a : _b
      }
    }

    if(args.length > 2) {
      //if called with multiple sequences
      //recurse, since lcs(a, b, c, d) == lcs(lcs(a,b), lcs(c,d))
      args.push(lcs(args.shift(), args.shift()))
      return lcs(args)
    }
    return recurse(args[0], args[1])
  }

  // given n sequences, calc the lcs, and then chunk strings into stable and unstable sections.
  // unstable chunks are passed to build
  exports.chunk =
  function (q, build) {
    var q = q.map(function (e) { return e.slice() })
    var lcs = exports.lcs.apply(null, q)
    var all = [lcs].concat(q)

    function matchLcs (e) {
      return last(e) == last(lcs) || ((e.length + lcs.length) === 0)
    }

    while(any(q, hasLength)) {
      //if each element is at the lcs then this chunk is stable.
      while(q.every(matchLcs) && q.every(hasLength))
        all.forEach(retreat)

      //collect the changes in each array upto the next match with the lcs
      var c = false
      var unstable = q.map(function (e) {
        var change = []
        while(!matchLcs(e)) {
          change.unshift(retreat(e))
          c = true
        }
        return change
      })
      if(c) build(q[0].length, unstable)
    }
  }

  exports.diff =
  function (a, b) {
    var changes = []
    exports.chunk([a, b], function (index, unstable) {
      var del = unstable.shift().length
      var insert = unstable.shift()
      changes.push([index, del].concat(insert))
    })
    return changes
  }

  exports.patch = function (a, changes, mutate) {
    if(mutate !== true) a = a.slice(a)//copy a
    changes.forEach(function (change) {
      [].splice.apply(a, change)
    })
    return a
  }

  // http://en.wikipedia.org/wiki/Concestor
  // me, concestor, you...
  exports.merge = function () {
    var args = getArgs(arguments)
    var patch = exports.diff3(args)
    return exports.patch(args[0], patch)
  }

  exports.diff3 = function () {
    var args = getArgs(arguments)
    var r = []
    exports.chunk(args, function (index, unstable) {
      var mine = unstable[0]
      var insert = resolve(unstable)
      if(equal(mine, insert)) return
      r.push([index, mine.length].concat(insert))
    })
    return r
  }
  exports.oddOneOut =
    function oddOneOut (changes) {
      changes = changes.slice()
      //put the concestor first
      changes.unshift(changes.splice(1,1)[0])
      var i = oddElement(changes, equal)
      if(i == 0) // concestor was different, 'false conflict'
        return changes[1]
      if (~i)
        return changes[i]
    }
  exports.insertMergeOverDelete =
    //i've implemented this as a seperate rule,
    //because I had second thoughts about this.
    function insertMergeOverDelete (changes) {
      changes = changes.slice()
      changes.splice(1,1)// remove concestor

      //if there is only one non empty change thats okay.
      //else full confilct
      for (var i = 0, nonempty; i < changes.length; i++)
        if(changes[i].length)
          if(!nonempty) nonempty = changes[i]
          else return // full conflict
      return nonempty
    }

  var rules = (deps && deps.rules) || [exports.oddOneOut, exports.insertMergeOverDelete]

  function resolve (changes) {
    var l = rules.length
    for (var i in rules) { // first

      var c = rules[i] && rules[i](changes)
      if(c) return c
    }
    changes.splice(1,1) // remove concestor
    //returning the conflicts as an object is a really bad idea,
    // because == will not detect they are the same. and conflicts build.
    // better to use
    // '<<<<<<<<<<<<<'
    // of course, i wrote this before i started on snob, so i didn't know that then.
    /*var conflict = ['>>>>>>>>>>>>>>>>']
    while(changes.length)
      conflict = conflict.concat(changes.shift()).concat('============')
    conflict.pop()
    conflict.push          ('<<<<<<<<<<<<<<<')
    changes.unshift       ('>>>>>>>>>>>>>>>')
    return conflict*/
    //nah, better is just to use an equal can handle objects
    return {'?': changes}
  }
  return exports
}
exports(null, exports)
<commit_msg>fix bug with recursive equals<commit_after>function head (a) {
  return a[0]
}

function last (a) {
  return a[a.length - 1]
}

function tail(a) {
  return a.slice(1)
}

function retreat (e) {
  return e.pop()
}

function hasLength (e) {
  return e.length
}

function any(ary, test) {
  for(var i in ary)
    if(test(ary[i]))
      return true
  return false
}

var _rules // set at the bottom

// note, naive implementation. will break on circular objects.

function _equal(a, b) {
  if(a && !b) return false
  if(Array.isArray(a))
    if(a.length != b.length) return false
  if(a && 'object' == typeof a) {
    for(var i in a)
      if(!_equal(a[i], b[i])) return false
    return true
  }
  return a == b
}

function getArgs(args) {
  return args.length == 1 ? args[0] : [].slice.call(args)
}

// return the index of the element not like the others, or -1
function oddElement(ary, cmp) {
  var c
  function guess(a) {
    var odd = -1
    c = 0
    for (var i = a; i < ary.length; i ++) {
      if(!cmp(ary[a], ary[i])) {
        odd = i, c++
      }
    }
    return c > 1 ? -1 : odd
  }
  //assume that it is the first element.
  var g = guess(0)
  if(-1 != g) return g
  //0 was the odd one, then all the other elements are equal
  //else there more than one different element
  guess(1)
  return c == 0 ? 0 : -1
}
var exports = module.exports = function (deps, exports) {
  var equal = (deps && deps.equal) || _equal
  exports = exports || {}
  exports.lcs =
  function lcs() {
    var cache = {}
    var args = getArgs(arguments)

    function key (a,b){
      return a.length + ':' + b.length
    }

    function recurse (a, b) {

      if(!a.length || !b.length) return []
      //avoid exponential time by caching the results
      if(cache[key(a, b)]) return cache[key(a, b)]

      if(equal(a[0], b[0]))
        return [head(a)].concat(recurse(tail(a), tail(b)))
      else {
        var _a = recurse(tail(a), b)
        var _b = recurse(a, tail(b))
        return cache[key(a,b)] = _a.length > _b.length ? _a : _b
      }
    }

    if(args.length > 2) {
      //if called with multiple sequences
      //recurse, since lcs(a, b, c, d) == lcs(lcs(a,b), lcs(c,d))
      args.push(lcs(args.shift(), args.shift()))
      return lcs(args)
    }
    return recurse(args[0], args[1])
  }

  // given n sequences, calc the lcs, and then chunk strings into stable and unstable sections.
  // unstable chunks are passed to build
  exports.chunk =
  function (q, build) {
    var q = q.map(function (e) { return e.slice() })
    var lcs = exports.lcs.apply(null, q)
    var all = [lcs].concat(q)

    function matchLcs (e) {
      return last(e) == last(lcs) || ((e.length + lcs.length) === 0)
    }

    while(any(q, hasLength)) {
      //if each element is at the lcs then this chunk is stable.
      while(q.every(matchLcs) && q.every(hasLength))
        all.forEach(retreat)

      //collect the changes in each array upto the next match with the lcs
      var c = false
      var unstable = q.map(function (e) {
        var change = []
        while(!matchLcs(e)) {
          change.unshift(retreat(e))
          c = true
        }
        return change
      })
      if(c) build(q[0].length, unstable)
    }
  }

  exports.diff =
  function (a, b) {
    var changes = []
    exports.chunk([a, b], function (index, unstable) {
      var del = unstable.shift().length
      var insert = unstable.shift()
      changes.push([index, del].concat(insert))
    })
    return changes
  }

  exports.patch = function (a, changes, mutate) {
    if(mutate !== true) a = a.slice(a)//copy a
    changes.forEach(function (change) {
      [].splice.apply(a, change)
    })
    return a
  }

  // http://en.wikipedia.org/wiki/Concestor
  // me, concestor, you...
  exports.merge = function () {
    var args = getArgs(arguments)
    var patch = exports.diff3(args)
    return exports.patch(args[0], patch)
  }

  exports.diff3 = function () {
    var args = getArgs(arguments)
    var r = []
    exports.chunk(args, function (index, unstable) {
      var mine = unstable[0]
      var insert = resolve(unstable)
      if(equal(mine, insert)) return
      r.push([index, mine.length].concat(insert))
    })
    return r
  }
  exports.oddOneOut =
    function oddOneOut (changes) {
      changes = changes.slice()
      //put the concestor first
      changes.unshift(changes.splice(1,1)[0])
      var i = oddElement(changes, equal)
      if(i == 0) // concestor was different, 'false conflict'
        return changes[1]
      if (~i)
        return changes[i]
    }
  exports.insertMergeOverDelete =
    //i've implemented this as a seperate rule,
    //because I had second thoughts about this.
    function insertMergeOverDelete (changes) {
      changes = changes.slice()
      changes.splice(1,1)// remove concestor

      //if there is only one non empty change thats okay.
      //else full confilct
      for (var i = 0, nonempty; i < changes.length; i++)
        if(changes[i].length)
          if(!nonempty) nonempty = changes[i]
          else return // full conflict
      return nonempty
    }

  var rules = (deps && deps.rules) || [exports.oddOneOut, exports.insertMergeOverDelete]

  function resolve (changes) {
    var l = rules.length
    for (var i in rules) { // first

      var c = rules[i] && rules[i](changes)
      if(c) return c
    }
    changes.splice(1,1) // remove concestor
    //returning the conflicts as an object is a really bad idea,
    // because == will not detect they are the same. and conflicts build.
    // better to use
    // '<<<<<<<<<<<<<'
    // of course, i wrote this before i started on snob, so i didn't know that then.
    /*var conflict = ['>>>>>>>>>>>>>>>>']
    while(changes.length)
      conflict = conflict.concat(changes.shift()).concat('============')
    conflict.pop()
    conflict.push          ('<<<<<<<<<<<<<<<')
    changes.unshift       ('>>>>>>>>>>>>>>>')
    return conflict*/
    //nah, better is just to use an equal can handle objects
    return {'?': changes}
  }
  return exports
}
exports(null, exports)
<|endoftext|>


<commit_before>var httpProxy   = require('http-proxy');

var httpProxyMiddleware = function (context, opts) {

    var proxyOptions = opts || {};
    var proxy = httpProxy.createProxyServer(proxyOptions);

    console.log('[http-proxy-middleware] Proxy created:', context, proxyOptions.target);

    return fnProxyMiddleWare;

    function fnProxyMiddleWare (req, res, next) {
       if (hasContextInUrl(context, req.url)) {
           proxy.web(req, res);
       } else {
           next();
       }
    }

    function hasContextInUrl (context, url) {
        return url.indexOf(context) > -1;
    }

};

module.exports = httpProxyMiddleware;
<commit_msg>Proxy 'host' in request headers<commit_after>var httpProxy   = require('http-proxy');

var httpProxyMiddleware = function (context, opts) {

    var proxyOptions = opts || {};
    var proxy = httpProxy.createProxyServer(proxyOptions);

    console.log('[http-proxy-middleware] Proxy created:', context, proxyOptions.target);

    proxy.on('proxyReq', proxyReqHost);

    return fnProxyMiddleWare;

    function fnProxyMiddleWare (req, res, next) {
       if (hasContextInUrl(context, req.url)) {
           proxy.web(req, res);
       } else {
           next();
       }
    }

    function hasContextInUrl (context, url) {
        return url.indexOf(context) > -1;
    }

    function proxyReqHost (proxyReq, req, res, options) {
        var host = options.target.host;
        if (host) {
            proxyReq.setHeader('host', host);
        }
    }

};

module.exports = httpProxyMiddleware;
<|endoftext|>


<commit_before>'use strict';

if (!process.version ||
    process.version.indexOf('v0.') === 0 ||
    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
  module.exports = { nextTick: nextTick };
} else {
  module.exports = process
}

function nextTick(fn, arg1, arg2, arg3) {
  if (typeof fn !== 'function') {
    throw new TypeError('"callback" argument must be a function');
  }
  var len = arguments.length;
  var args, i;
  switch (len) {
  case 0:
  case 1:
    return process.nextTick(fn);
  case 2:
    return process.nextTick(function afterTickOne() {
      fn.call(null, arg1);
    });
  case 3:
    return process.nextTick(function afterTickTwo() {
      fn.call(null, arg1, arg2);
    });
  case 4:
    return process.nextTick(function afterTickThree() {
      fn.call(null, arg1, arg2, arg3);
    });
  default:
    args = new Array(len - 1);
    i = 0;
    while (i < args.length) {
      args[i++] = arguments[i];
    }
    return process.nextTick(function afterTick() {
      fn.apply(null, args);
    });
  }
}

<commit_msg>Check for existence of `process` object (#12)<commit_after>'use strict';

if (typeof process === 'undefined' ||
    !process.version ||
    process.version.indexOf('v0.') === 0 ||
    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
  module.exports = { nextTick: nextTick };
} else {
  module.exports = process
}

function nextTick(fn, arg1, arg2, arg3) {
  if (typeof fn !== 'function') {
    throw new TypeError('"callback" argument must be a function');
  }
  var len = arguments.length;
  var args, i;
  switch (len) {
  case 0:
  case 1:
    return process.nextTick(fn);
  case 2:
    return process.nextTick(function afterTickOne() {
      fn.call(null, arg1);
    });
  case 3:
    return process.nextTick(function afterTickTwo() {
      fn.call(null, arg1, arg2);
    });
  case 4:
    return process.nextTick(function afterTickThree() {
      fn.call(null, arg1, arg2, arg3);
    });
  default:
    args = new Array(len - 1);
    i = 0;
    while (i < args.length) {
      args[i++] = arguments[i];
    }
    return process.nextTick(function afterTick() {
      fn.apply(null, args);
    });
  }
}

<|endoftext|>


<commit_before>'use strict';

var img = require('img');
var linkify = require('html-linkify');

module.exports = widget;

function widget (post, opt, callback) {
  if (typeof opt === 'function') {
    callback = opt;
    opt = undefined;
  }
  if (!opt) opt = {};

  var client = opt.client;

  var postActions = {
    like: function(has_liked, callback) {
      if (has_liked) {
        client.unlikePost(opt.project, opt.feed, post.id, callback);
      }
      else {
        client.likePost(opt.project, opt.feed, post.id, callback);
      }
    },

    flag: function(has_flagged, callback) {
      if (has_flagged) {
        client.unflagPost(opt.project, opt.feed, post.id, callback);
      }
      else {
        client.flagPost(opt.project, opt.feed, post.id, callback);
      }
    },
  };

  var container = document.createElement('div');
  container.setAttribute('class', 'tagplay-media-container tagplay-media-' + post.provider.name);

  var postElem = document.createElement('div');
  postElem.setAttribute('class', 'tagplay-media-inner');

  if (opt['include-usernames']) {
    postElem.appendChild(text(post.provider.username, 'tagplay-media-username'));
  }

  if (opt['no-images']) {
    // do nothing
  } else if (post.image) {
    postElem.appendChild(media(post, opt['no-videos']));
  }

  var postText = (opt['text'] === 'normalized' ? post.normalized_text : opt['text'] === 'stripped' ? post.stripped_text : opt['text'] === 'tagless' ? post.tagless_text : post.text) || '';

  if (opt['include-captions'] || opt['no-images'] || post.type === 'text') {
    var textElem = text(postText, 'tagplay-media-text');
    if (post.linked_metadata && !opt['include-link-metadata'] && post.text.indexOf(post.linked_metadata.href) === -1) {
      // Add link to text
      if (postText) {
        textElem.appendChild(document.createElement('br'));
        textElem.appendChild(document.createElement('br'));
      }
      var linkElem = document.createElement('a');
      linkElem.setAttribute('href', post.linked_metadata.href);
      linkElem.setAttribute('target', '_blank');
      linkElem.appendChild(document.createTextNode(post.linked_metadata.title || post.linked_metadata.href));

      textElem.appendChild(linkElem);
    }
    postElem.appendChild(textElem);
  }
  if (post.linked_metadata && opt['include-link-metadata']) {
    postElem.appendChild(linkInfo(post, !opt['no-link-image'], !opt['no-link-description']));
  }
  if (opt['include-like'] || opt['include-flag']) {
    postElem.appendChild(postOptions(post, opt['include-like'], opt['include-flag'], postActions));
  }
  if (opt['include-dates'] || opt['include-times']) {
    postElem.appendChild(text(timestamp(post, opt['include-dates'], opt['include-times']), 'tagplay-media-date'));
  }

  container.appendChild(postElem);

  return container;
}

function icon(iconName, iconText) {
  var el = document.createElement('i');
  el.setAttribute('class', 'tagplay-icon tagplay-icon-' + iconName);
  el.appendChild(document.createTextNode(iconText));
  return el;
}

function likeButton(has_liked, likes, handleClick) {
  var el = document.createElement('span');
  el.setAttribute('class', 'tagplay-like' + (has_liked ? ' tagplay-user-liked' : ''));
  el.appendChild(icon('like', '❤'));
  var textNode = document.createTextNode(' ' + likes);
  el.appendChild(textNode);
  el.onclick = function() {
    handleClick(has_liked, function(err) {
      if (err) {
        alert(err.message);
        return;
      }
      el.parentNode.replaceChild(likeButton(!has_liked, likes + (has_liked ? -1 : 1), handleClick), el);
    });
  };
  return el;
}

function flagButton(has_flagged, handleClick) {
  var el = document.createElement('span');
  el.setAttribute('class', 'tagplay-flag' + (has_flagged ? ' tagplay-user-flagged' : ''));
  el.appendChild(icon('flag', 'Flag'));
  el.onclick = function() {
    handleClick(has_flagged, function(err) {
      if (err) {
        alert(err.message);
        return;
      }
      el.parentNode.replaceChild(flagButton(!has_flagged, handleClick), el);
    });
  };
  return el;
}

function postOptions(post, includeLike, includeFlag, postActions) {
  var el = document.createElement('p');
  el.setAttribute('class', 'tagplay-media-options');
  if (includeLike) {
    el.appendChild(likeButton(post.meta.has_liked, post.meta.likes, postActions.like));
  }
  if (includeFlag) {
    el.appendChild(flagButton(post.meta.has_flagged, postActions.flag));
  }
  return el;
}

function linkInfoLink(post) {
  var el = document.createElement('a');
  el.setAttribute('class', 'tagplay-link-info-link');
  el.setAttribute('href', post.linked_metadata.href);
  el.setAttribute('target', '_blank');

  return el;
}

function linkInfoImage(post) {
  var image = img(post.linked_metadata.image.sources[0].url);
  image.setAttribute('class', 'tagplay-link-info-image');
  var link = linkInfoLink(post);
  link.appendChild(image);

  return link;
}

function linkInfoTitle(post) {
  var el = document.createElement('h4');
  el.setAttribute('class', 'tagplay-link-info-title');

  var link = linkInfoLink(post);
  link.appendChild(document.createTextNode(post.linked_metadata.title));

  el.appendChild(link);
  return el;
}

function linkInfoDescription(post) {
  var el = document.createElement('p');
  el.setAttribute('class', 'tagplay-link-info-description');

  var link = linkInfoLink(post);
  link.appendChild(document.createTextNode(post.linked_metadata.description));

  el.appendChild(link);
  return el;
}

function linkInfo(post, includeImage, includeDescription) {
  var el = document.createElement('div');
  el.setAttribute('class', 'tagplay-link-info');
  if (includeImage) {
    el.appendChild(linkInfoImage(post));
  }
  el.appendChild(linkInfoTitle(post));
  if (includeDescription) {
    el.appendChild(linkInfoDescription(post));
  }
  return el;
}

function timestamp(post, includeDates, includeTimes) {
  var createdTime = new Date(post.provider.created_time);
  var now = new Date();
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
  var timeComponents = [];

  if (includeDates) {
    var yearCreatedString = createdTime.getFullYear().toString();
    var yearNowString = now.getFullYear().toString();
    timeComponents.push(createdTime.getDate());
    timeComponents.push(months[createdTime.getMonth()]);
    if (yearCreatedString !== yearNowString) {
      if (yearCreatedString.substring(0, 2) === yearNowString.substring(0, 2)) {
        timeComponents.push(yearCreatedString.substring(2));
      }
      else {
        timeComponents.push(yearCreatedString);
      }
    }
  }
  if (includeTimes) {
    var hours = createdTime.getHours();
    var minutes = createdTime.getMinutes();
    if (minutes < 10) {
      minutes = "0" + minutes;
    }
    timeComponents.push((hours > 12 ? hours - 12 : hours) + ":" + minutes + (hours >= 12 ? "pm" : "am"));
  }
  return timeComponents.join(" ");
}

function media(post, noVideo) {
  var imgSrc = post.image.sources[0].url;

  var mediaElem = document.createElement('div');
  mediaElem.setAttribute('class', 'tagplay-media');

  var image = img(imgSrc);
  image.setAttribute('class', 'tagplay-media-object');
  var a = link(post.provider.origin || imgSrc);
  a.appendChild(image);

  if (post.type === 'video' && !noVideo) {
    var video = vid(post.video.sources[0].url, imgSrc);
    video.appendChild(a);
    mediaElem.appendChild(video);
  } else {
    mediaElem.appendChild(a);
  }
  return mediaElem;
}

function vid(src, poster) {
  var video = document.createElement('video');
  video.setAttribute('class', 'tagplay-media-object');
  video.setAttribute('src', src);
  video.setAttribute('controls', true);
  video.setAttribute('preload', 'auto');
  if (poster) video.setAttribute('poster', poster);
  return video;
}

function text(txt, className) {
  var el = document.createElement('p');
  el.setAttribute('class', className);
  if (txt) txt = linkify(txt);
  el.innerHTML = txt;
  return el;
}

function link(href) {
  var linkElem = document.createElement('a');
  linkElem.setAttribute('href', href);
  linkElem.setAttribute('class', 'tagplay-media-link');
  linkElem.setAttribute('target', '_blank');
  return linkElem;
}
<commit_msg>Make sure we deal correctly with links that have no image.<commit_after>'use strict';

var img = require('img');
var linkify = require('html-linkify');

module.exports = widget;

function widget (post, opt, callback) {
  if (typeof opt === 'function') {
    callback = opt;
    opt = undefined;
  }
  if (!opt) opt = {};

  var client = opt.client;

  var postActions = {
    like: function(has_liked, callback) {
      if (has_liked) {
        client.unlikePost(opt.project, opt.feed, post.id, callback);
      }
      else {
        client.likePost(opt.project, opt.feed, post.id, callback);
      }
    },

    flag: function(has_flagged, callback) {
      if (has_flagged) {
        client.unflagPost(opt.project, opt.feed, post.id, callback);
      }
      else {
        client.flagPost(opt.project, opt.feed, post.id, callback);
      }
    },
  };

  var container = document.createElement('div');
  container.setAttribute('class', 'tagplay-media-container tagplay-media-' + post.provider.name);

  var postElem = document.createElement('div');
  postElem.setAttribute('class', 'tagplay-media-inner');

  if (opt['include-usernames']) {
    postElem.appendChild(text(post.provider.username, 'tagplay-media-username'));
  }

  if (opt['no-images']) {
    // do nothing
  } else if (post.image) {
    postElem.appendChild(media(post, opt['no-videos']));
  }

  var postText = (opt['text'] === 'normalized' ? post.normalized_text : opt['text'] === 'stripped' ? post.stripped_text : opt['text'] === 'tagless' ? post.tagless_text : post.text) || '';

  if (opt['include-captions'] || opt['no-images'] || post.type === 'text') {
    var textElem = text(postText, 'tagplay-media-text');
    if (post.linked_metadata && !opt['include-link-metadata'] && post.text.indexOf(post.linked_metadata.href) === -1) {
      // Add link to text
      if (postText) {
        textElem.appendChild(document.createElement('br'));
        textElem.appendChild(document.createElement('br'));
      }
      var linkElem = document.createElement('a');
      linkElem.setAttribute('href', post.linked_metadata.href);
      linkElem.setAttribute('target', '_blank');
      linkElem.appendChild(document.createTextNode(post.linked_metadata.title || post.linked_metadata.href));

      textElem.appendChild(linkElem);
    }
    postElem.appendChild(textElem);
  }
  if (post.linked_metadata && opt['include-link-metadata']) {
    postElem.appendChild(linkInfo(post, !opt['no-link-image'], !opt['no-link-description']));
  }
  if (opt['include-like'] || opt['include-flag']) {
    postElem.appendChild(postOptions(post, opt['include-like'], opt['include-flag'], postActions));
  }
  if (opt['include-dates'] || opt['include-times']) {
    postElem.appendChild(text(timestamp(post, opt['include-dates'], opt['include-times']), 'tagplay-media-date'));
  }

  container.appendChild(postElem);

  return container;
}

function icon(iconName, iconText) {
  var el = document.createElement('i');
  el.setAttribute('class', 'tagplay-icon tagplay-icon-' + iconName);
  el.appendChild(document.createTextNode(iconText));
  return el;
}

function likeButton(has_liked, likes, handleClick) {
  var el = document.createElement('span');
  el.setAttribute('class', 'tagplay-like' + (has_liked ? ' tagplay-user-liked' : ''));
  el.appendChild(icon('like', '❤'));
  var textNode = document.createTextNode(' ' + likes);
  el.appendChild(textNode);
  el.onclick = function() {
    handleClick(has_liked, function(err) {
      if (err) {
        alert(err.message);
        return;
      }
      el.parentNode.replaceChild(likeButton(!has_liked, likes + (has_liked ? -1 : 1), handleClick), el);
    });
  };
  return el;
}

function flagButton(has_flagged, handleClick) {
  var el = document.createElement('span');
  el.setAttribute('class', 'tagplay-flag' + (has_flagged ? ' tagplay-user-flagged' : ''));
  el.appendChild(icon('flag', 'Flag'));
  el.onclick = function() {
    handleClick(has_flagged, function(err) {
      if (err) {
        alert(err.message);
        return;
      }
      el.parentNode.replaceChild(flagButton(!has_flagged, handleClick), el);
    });
  };
  return el;
}

function postOptions(post, includeLike, includeFlag, postActions) {
  var el = document.createElement('p');
  el.setAttribute('class', 'tagplay-media-options');
  if (includeLike) {
    el.appendChild(likeButton(post.meta.has_liked, post.meta.likes, postActions.like));
  }
  if (includeFlag) {
    el.appendChild(flagButton(post.meta.has_flagged, postActions.flag));
  }
  return el;
}

function linkInfoLink(post) {
  var el = document.createElement('a');
  el.setAttribute('class', 'tagplay-link-info-link');
  el.setAttribute('href', post.linked_metadata.href);
  el.setAttribute('target', '_blank');

  return el;
}

function linkInfoImage(post) {
  var image = img(post.linked_metadata.image.sources[0].url);
  image.setAttribute('class', 'tagplay-link-info-image');
  var link = linkInfoLink(post);
  link.appendChild(image);

  return link;
}

function linkInfoTitle(post) {
  var el = document.createElement('h4');
  el.setAttribute('class', 'tagplay-link-info-title');

  var link = linkInfoLink(post);
  link.appendChild(document.createTextNode(post.linked_metadata.title || post.linked_metadata.href));

  el.appendChild(link);
  return el;
}

function linkInfoDescription(post) {
  var el = document.createElement('p');
  el.setAttribute('class', 'tagplay-link-info-description');

  var link = linkInfoLink(post);
  link.appendChild(document.createTextNode(post.linked_metadata.description));

  el.appendChild(link);
  return el;
}

function linkInfo(post, includeImage, includeDescription) {
  var el = document.createElement('div');
  el.setAttribute('class', 'tagplay-link-info');
  if (includeImage && post.linked_metadata.image) {
    el.appendChild(linkInfoImage(post));
  }
  el.appendChild(linkInfoTitle(post));
  if (includeDescription && post.linked_metadata.description) {
    el.appendChild(linkInfoDescription(post));
  }
  return el;
}

function timestamp(post, includeDates, includeTimes) {
  var createdTime = new Date(post.provider.created_time);
  var now = new Date();
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
  var timeComponents = [];

  if (includeDates) {
    var yearCreatedString = createdTime.getFullYear().toString();
    var yearNowString = now.getFullYear().toString();
    timeComponents.push(createdTime.getDate());
    timeComponents.push(months[createdTime.getMonth()]);
    if (yearCreatedString !== yearNowString) {
      if (yearCreatedString.substring(0, 2) === yearNowString.substring(0, 2)) {
        timeComponents.push(yearCreatedString.substring(2));
      }
      else {
        timeComponents.push(yearCreatedString);
      }
    }
  }
  if (includeTimes) {
    var hours = createdTime.getHours();
    var minutes = createdTime.getMinutes();
    if (minutes < 10) {
      minutes = "0" + minutes;
    }
    timeComponents.push((hours > 12 ? hours - 12 : hours) + ":" + minutes + (hours >= 12 ? "pm" : "am"));
  }
  return timeComponents.join(" ");
}

function media(post, noVideo) {
  var imgSrc = post.image.sources[0].url;

  var mediaElem = document.createElement('div');
  mediaElem.setAttribute('class', 'tagplay-media');

  var image = img(imgSrc);
  image.setAttribute('class', 'tagplay-media-object');
  var a = link(post.provider.origin || imgSrc);
  a.appendChild(image);

  if (post.type === 'video' && !noVideo) {
    var video = vid(post.video.sources[0].url, imgSrc);
    video.appendChild(a);
    mediaElem.appendChild(video);
  } else {
    mediaElem.appendChild(a);
  }
  return mediaElem;
}

function vid(src, poster) {
  var video = document.createElement('video');
  video.setAttribute('class', 'tagplay-media-object');
  video.setAttribute('src', src);
  video.setAttribute('controls', true);
  video.setAttribute('preload', 'auto');
  if (poster) video.setAttribute('poster', poster);
  return video;
}

function text(txt, className) {
  var el = document.createElement('p');
  el.setAttribute('class', className);
  if (txt) txt = linkify(txt);
  el.innerHTML = txt;
  return el;
}

function link(href) {
  var linkElem = document.createElement('a');
  linkElem.setAttribute('href', href);
  linkElem.setAttribute('class', 'tagplay-media-link');
  linkElem.setAttribute('target', '_blank');
  return linkElem;
}
<|endoftext|>


<commit_before>var executeScripts = require("./lib/execute-scripts.js")
var forEachEls = require("./lib/foreach-els.js")
var parseOptions = require("./lib/parse-options.js")
var switches = require("./lib/switches")
var newUid = require("./lib/uniqueid.js")

var on = require("./lib/events/on.js")
var trigger = require("./lib/events/trigger.js")

var clone = require("./lib/util/clone.js")
var contains = require("./lib/util/contains.js")
var extend = require("./lib/util/extend.js")
var noop = require("./lib/util/noop")

var Pjax = function(options) {
    this.state = {
      numPendingSwitches: 0,
      href: null,
      options: null
    }

    this.options = parseOptions(options)
    this.log("Pjax options", this.options)

    if (this.options.scrollRestoration && "scrollRestoration" in history) {
      history.scrollRestoration = "manual"
    }

    this.maxUid = this.lastUid = newUid()

    this.parseDOM(document)

    on(window, "popstate", function(st) {
      if (st.state) {
        var opt = clone(this.options)
        opt.url = st.state.url
        opt.title = st.state.title
        opt.history = false
        opt.scrollPos = st.state.scrollPos
        if (st.state.uid < this.lastUid) {
          opt.backward = true
        }
        else {
          opt.forward = true
        }
        this.lastUid = st.state.uid

        // @todo implement history cache here, based on uid
        this.loadUrl(st.state.url, opt)
      }
    }.bind(this))
  }

Pjax.switches = switches

Pjax.prototype = {
  log: require("./lib/proto/log.js"),

  getElements: function(el) {
    return el.querySelectorAll(this.options.elements)
  },

  parseDOM: function(el) {
    var parseElement = require("./lib/proto/parse-element")
    forEachEls(this.getElements(el), parseElement, this)
  },

  refresh: function(el) {
    this.parseDOM(el || document)
  },

  reload: function() {
    window.location.reload()
  },

  attachLink: require("./lib/proto/attach-link.js"),

  attachForm: require("./lib/proto/attach-form.js"),

  forEachSelectors: function(cb, context, DOMcontext) {
    return require("./lib/foreach-selectors.js").bind(this)(this.options.selectors, cb, context, DOMcontext)
  },

  switchSelectors: function(selectors, fromEl, toEl, options) {
    return require("./lib/switches-selectors.js").bind(this)(this.options.switches, this.options.switchesOptions, selectors, fromEl, toEl, options)
  },

  latestChance: function(href) {
    window.location = href
  },

  onSwitch: function() {
    trigger(window, "resize scroll")

    this.state.numPendingSwitches--

    // debounce calls, so we only run this once after all switches are finished.
    if (this.state.numPendingSwitches === 0) {
      this.afterAllSwitches()
    }
  },

  loadContent: function(html, options) {
    var tmpEl = document.implementation.createHTMLDocument("pjax")

    // parse HTML attributes to copy them
    // since we are forced to use documentElement.innerHTML (outerHTML can't be used for <html>)
    var htmlRegex = /<html[^>]+>/gi
    var htmlAttribsRegex = /\s?[a-z:]+(?:\=(?:\'|\")[^\'\">]+(?:\'|\"))*/gi
    var matches = html.match(htmlRegex)
    if (matches && matches.length) {
      matches = matches[0].match(htmlAttribsRegex)
      if (matches.length) {
        matches.shift()
        matches.forEach(function(htmlAttrib) {
          var attr = htmlAttrib.trim().split("=")
          if (attr.length === 1) {
            tmpEl.documentElement.setAttribute(attr[0], true)
          }
          else {
            tmpEl.documentElement.setAttribute(attr[0], attr[1].slice(1, -1))
          }
        })
      }
    }

    tmpEl.documentElement.innerHTML = html
    this.log("load content", tmpEl.documentElement.attributes, tmpEl.documentElement.innerHTML.length)

    // Clear out any focused controls before inserting new page contents.
    if (document.activeElement && contains(this.options.selectors, document.activeElement)) {
      try {
        document.activeElement.blur()
      } catch (e) { }
    }

    this.switchSelectors(this.options.selectors, tmpEl, document, options)
  },

  abortRequest: require("./lib/abort-request.js"),

  doRequest: require("./lib/send-request.js"),

  loadUrl: function(href, options) {
    options = typeof options === "object" ?
      extend({}, this.options, options) :
      clone(this.options)

    this.log("load href", href, options)

    // Abort any previous request
    this.abortRequest(this.request)

    trigger(document, "pjax:send", options)

    // Do the request
    this.request = this.doRequest(href, options, function(html, request) {
      // Fail if unable to load HTML via AJAX
      if (html === false) {
        trigger(document, "pjax:complete pjax:error", options)

        return
      }

      // push scroll position to history
      var currentState = window.history.state || {}
      window.history.replaceState({
          url: currentState.url || window.location.href,
          title: currentState.title || document.title,
          uid: currentState.uid || newUid(),
          scrollPos: [document.documentElement.scrollLeft || document.body.scrollLeft,
            document.documentElement.scrollTop || document.body.scrollTop]
        },
        document.title, window.location)

      var oldHref = href
      if (request.responseURL) {
        if (href !== request.responseURL) {
          href = request.responseURL
        }
      }
      else if (request.getResponseHeader("X-PJAX-URL")) {
        href = request.getResponseHeader("X-PJAX-URL")
      }
      else if (request.getResponseHeader("X-XHR-Redirected-To")) {
        href = request.getResponseHeader("X-XHR-Redirected-To")
      }

      // Add back the hash if it was removed
      var a = document.createElement("a")
      a.href = oldHref
      var oldHash = a.hash
      a.href = href
      if (oldHash && !a.hash) {
        a.hash = oldHash
        href = a.href
      }

      this.state.href = href
      this.state.options = clone(options)

      try {
        this.loadContent(html, options)
      }
      catch (e) {
        if (!this.options.debug) {
          if (console && console.error) {
            console.error("Pjax switch fail: ", e)
          }
          return this.latestChance(href)
        }
        else {
          throw e
        }
      }
    }.bind(this))
  },

  afterAllSwitches: function() {
    // FF bug: Won’t autofocus fields that are inserted via JS.
    // This behavior is incorrect. So if theres no current focus, autofocus
    // the last field.
    //
    // http://www.w3.org/html/wg/drafts/html/master/forms.html
    var autofocusEl = Array.prototype.slice.call(document.querySelectorAll("[autofocus]")).pop()
    if (autofocusEl && document.activeElement !== autofocusEl) {
      autofocusEl.focus()
    }

    // execute scripts when DOM have been completely updated
    this.options.selectors.forEach(function(selector) {
      forEachEls(document.querySelectorAll(selector), function(el) {
        executeScripts(el)
      })
    })

    var state = this.state

    if (state.options.history) {
      if (!window.history.state) {
        this.lastUid = this.maxUid = newUid()
        window.history.replaceState({
            url: window.location.href,
            title: document.title,
            uid: this.maxUid,
            scrollPos: [0, 0]
          },
          document.title)
      }

      // Update browser history
      this.lastUid = this.maxUid = newUid()

      window.history.pushState({
          url: state.href,
          title: state.options.title,
          uid: this.maxUid,
          scrollPos: [0, 0]
        },
        state.options.title,
        state.href)
    }

    this.forEachSelectors(function(el) {
      this.parseDOM(el)
    }, this)

    // Fire Events
    trigger(document,"pjax:complete pjax:success", state.options)

    if (typeof state.options.analytics === "function") {
      state.options.analytics()
    }

    if (state.options.history) {
      // First parse url and check for hash to override scroll
      var a = document.createElement("a")
      a.href = this.state.href
      if (a.hash) {
        var name = a.hash.slice(1)
        name = decodeURIComponent(name)

        var curtop = 0
        var target = document.getElementById(name) || document.getElementsByName(name)[0]
        if (target) {
          // http://stackoverflow.com/questions/8111094/cross-browser-javascript-function-to-find-actual-position-of-an-element-in-page
          if (target.offsetParent) {
            do {
              curtop += target.offsetTop

              target = target.offsetParent
            } while (target)
          }
        }
        window.scrollTo(0, curtop)
      }
      else if (state.options.scrollTo !== false) {
        // Scroll page to top on new page load
        if (state.options.scrollTo.length > 1) {
          window.scrollTo(state.options.scrollTo[0], state.options.scrollTo[1])
        }
        else {
          window.scrollTo(0, state.options.scrollTo)
        }
      }
    }
    else if (state.options.scrollRestoration && state.options.scrollPos) {
      window.scrollTo(state.options.scrollPos[0], state.options.scrollPos[1])
    }

    this.state = {
      numPendingSwitches: 0,
      href: null,
      options: null
    }
  }
}

Pjax.isSupported = require("./lib/is-supported.js")

// arguably could do `if( require("./lib/is-supported.js")()) {` but that might be a little to simple
if (Pjax.isSupported()) {
  module.exports = Pjax
}
// if there isn’t required browser functions, returning stupid api
else {
  var stupidPjax = noop
  for (var key in Pjax.prototype) {
    if (Pjax.prototype.hasOwnProperty(key) && typeof Pjax.prototype[key] === "function") {
      stupidPjax[key] = noop
    }
  }

  module.exports = stupidPjax
}
<commit_msg>Fix bug in contains() argument list<commit_after>var executeScripts = require("./lib/execute-scripts.js")
var forEachEls = require("./lib/foreach-els.js")
var parseOptions = require("./lib/parse-options.js")
var switches = require("./lib/switches")
var newUid = require("./lib/uniqueid.js")

var on = require("./lib/events/on.js")
var trigger = require("./lib/events/trigger.js")

var clone = require("./lib/util/clone.js")
var contains = require("./lib/util/contains.js")
var extend = require("./lib/util/extend.js")
var noop = require("./lib/util/noop")

var Pjax = function(options) {
    this.state = {
      numPendingSwitches: 0,
      href: null,
      options: null
    }

    this.options = parseOptions(options)
    this.log("Pjax options", this.options)

    if (this.options.scrollRestoration && "scrollRestoration" in history) {
      history.scrollRestoration = "manual"
    }

    this.maxUid = this.lastUid = newUid()

    this.parseDOM(document)

    on(window, "popstate", function(st) {
      if (st.state) {
        var opt = clone(this.options)
        opt.url = st.state.url
        opt.title = st.state.title
        opt.history = false
        opt.scrollPos = st.state.scrollPos
        if (st.state.uid < this.lastUid) {
          opt.backward = true
        }
        else {
          opt.forward = true
        }
        this.lastUid = st.state.uid

        // @todo implement history cache here, based on uid
        this.loadUrl(st.state.url, opt)
      }
    }.bind(this))
  }

Pjax.switches = switches

Pjax.prototype = {
  log: require("./lib/proto/log.js"),

  getElements: function(el) {
    return el.querySelectorAll(this.options.elements)
  },

  parseDOM: function(el) {
    var parseElement = require("./lib/proto/parse-element")
    forEachEls(this.getElements(el), parseElement, this)
  },

  refresh: function(el) {
    this.parseDOM(el || document)
  },

  reload: function() {
    window.location.reload()
  },

  attachLink: require("./lib/proto/attach-link.js"),

  attachForm: require("./lib/proto/attach-form.js"),

  forEachSelectors: function(cb, context, DOMcontext) {
    return require("./lib/foreach-selectors.js").bind(this)(this.options.selectors, cb, context, DOMcontext)
  },

  switchSelectors: function(selectors, fromEl, toEl, options) {
    return require("./lib/switches-selectors.js").bind(this)(this.options.switches, this.options.switchesOptions, selectors, fromEl, toEl, options)
  },

  latestChance: function(href) {
    window.location = href
  },

  onSwitch: function() {
    trigger(window, "resize scroll")

    this.state.numPendingSwitches--

    // debounce calls, so we only run this once after all switches are finished.
    if (this.state.numPendingSwitches === 0) {
      this.afterAllSwitches()
    }
  },

  loadContent: function(html, options) {
    var tmpEl = document.implementation.createHTMLDocument("pjax")

    // parse HTML attributes to copy them
    // since we are forced to use documentElement.innerHTML (outerHTML can't be used for <html>)
    var htmlRegex = /<html[^>]+>/gi
    var htmlAttribsRegex = /\s?[a-z:]+(?:\=(?:\'|\")[^\'\">]+(?:\'|\"))*/gi
    var matches = html.match(htmlRegex)
    if (matches && matches.length) {
      matches = matches[0].match(htmlAttribsRegex)
      if (matches.length) {
        matches.shift()
        matches.forEach(function(htmlAttrib) {
          var attr = htmlAttrib.trim().split("=")
          if (attr.length === 1) {
            tmpEl.documentElement.setAttribute(attr[0], true)
          }
          else {
            tmpEl.documentElement.setAttribute(attr[0], attr[1].slice(1, -1))
          }
        })
      }
    }

    tmpEl.documentElement.innerHTML = html
    this.log("load content", tmpEl.documentElement.attributes, tmpEl.documentElement.innerHTML.length)

    // Clear out any focused controls before inserting new page contents.
    if (document.activeElement && contains(document, this.options.selectors, document.activeElement)) {
      try {
        document.activeElement.blur()
      } catch (e) { }
    }

    this.switchSelectors(this.options.selectors, tmpEl, document, options)
  },

  abortRequest: require("./lib/abort-request.js"),

  doRequest: require("./lib/send-request.js"),

  loadUrl: function(href, options) {
    options = typeof options === "object" ?
      extend({}, this.options, options) :
      clone(this.options)

    this.log("load href", href, options)

    // Abort any previous request
    this.abortRequest(this.request)

    trigger(document, "pjax:send", options)

    // Do the request
    this.request = this.doRequest(href, options, function(html, request) {
      // Fail if unable to load HTML via AJAX
      if (html === false) {
        trigger(document, "pjax:complete pjax:error", options)

        return
      }

      // push scroll position to history
      var currentState = window.history.state || {}
      window.history.replaceState({
          url: currentState.url || window.location.href,
          title: currentState.title || document.title,
          uid: currentState.uid || newUid(),
          scrollPos: [document.documentElement.scrollLeft || document.body.scrollLeft,
            document.documentElement.scrollTop || document.body.scrollTop]
        },
        document.title, window.location)

      var oldHref = href
      if (request.responseURL) {
        if (href !== request.responseURL) {
          href = request.responseURL
        }
      }
      else if (request.getResponseHeader("X-PJAX-URL")) {
        href = request.getResponseHeader("X-PJAX-URL")
      }
      else if (request.getResponseHeader("X-XHR-Redirected-To")) {
        href = request.getResponseHeader("X-XHR-Redirected-To")
      }

      // Add back the hash if it was removed
      var a = document.createElement("a")
      a.href = oldHref
      var oldHash = a.hash
      a.href = href
      if (oldHash && !a.hash) {
        a.hash = oldHash
        href = a.href
      }

      this.state.href = href
      this.state.options = clone(options)

      try {
        this.loadContent(html, options)
      }
      catch (e) {
        if (!this.options.debug) {
          if (console && console.error) {
            console.error("Pjax switch fail: ", e)
          }
          return this.latestChance(href)
        }
        else {
          throw e
        }
      }
    }.bind(this))
  },

  afterAllSwitches: function() {
    // FF bug: Won’t autofocus fields that are inserted via JS.
    // This behavior is incorrect. So if theres no current focus, autofocus
    // the last field.
    //
    // http://www.w3.org/html/wg/drafts/html/master/forms.html
    var autofocusEl = Array.prototype.slice.call(document.querySelectorAll("[autofocus]")).pop()
    if (autofocusEl && document.activeElement !== autofocusEl) {
      autofocusEl.focus()
    }

    // execute scripts when DOM have been completely updated
    this.options.selectors.forEach(function(selector) {
      forEachEls(document.querySelectorAll(selector), function(el) {
        executeScripts(el)
      })
    })

    var state = this.state

    if (state.options.history) {
      if (!window.history.state) {
        this.lastUid = this.maxUid = newUid()
        window.history.replaceState({
            url: window.location.href,
            title: document.title,
            uid: this.maxUid,
            scrollPos: [0, 0]
          },
          document.title)
      }

      // Update browser history
      this.lastUid = this.maxUid = newUid()

      window.history.pushState({
          url: state.href,
          title: state.options.title,
          uid: this.maxUid,
          scrollPos: [0, 0]
        },
        state.options.title,
        state.href)
    }

    this.forEachSelectors(function(el) {
      this.parseDOM(el)
    }, this)

    // Fire Events
    trigger(document,"pjax:complete pjax:success", state.options)

    if (typeof state.options.analytics === "function") {
      state.options.analytics()
    }

    if (state.options.history) {
      // First parse url and check for hash to override scroll
      var a = document.createElement("a")
      a.href = this.state.href
      if (a.hash) {
        var name = a.hash.slice(1)
        name = decodeURIComponent(name)

        var curtop = 0
        var target = document.getElementById(name) || document.getElementsByName(name)[0]
        if (target) {
          // http://stackoverflow.com/questions/8111094/cross-browser-javascript-function-to-find-actual-position-of-an-element-in-page
          if (target.offsetParent) {
            do {
              curtop += target.offsetTop

              target = target.offsetParent
            } while (target)
          }
        }
        window.scrollTo(0, curtop)
      }
      else if (state.options.scrollTo !== false) {
        // Scroll page to top on new page load
        if (state.options.scrollTo.length > 1) {
          window.scrollTo(state.options.scrollTo[0], state.options.scrollTo[1])
        }
        else {
          window.scrollTo(0, state.options.scrollTo)
        }
      }
    }
    else if (state.options.scrollRestoration && state.options.scrollPos) {
      window.scrollTo(state.options.scrollPos[0], state.options.scrollPos[1])
    }

    this.state = {
      numPendingSwitches: 0,
      href: null,
      options: null
    }
  }
}

Pjax.isSupported = require("./lib/is-supported.js")

// arguably could do `if( require("./lib/is-supported.js")()) {` but that might be a little to simple
if (Pjax.isSupported()) {
  module.exports = Pjax
}
// if there isn’t required browser functions, returning stupid api
else {
  var stupidPjax = noop
  for (var key in Pjax.prototype) {
    if (Pjax.prototype.hasOwnProperty(key) && typeof Pjax.prototype[key] === "function") {
      stupidPjax[key] = noop
    }
  }

  module.exports = stupidPjax
}
<|endoftext|>


<commit_before>/*jshint unused:false*/
var express = require('express');
var morgan = require('morgan');
var fs = require('fs');
var FileStreamRotator = require('file-stream-rotator');

var config = require('./config.json');

// express.js application
var app = express();

var logDirectory = __dirname + '/log';
// ensure log directory exists
fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);

// create a rotating write stream
var accessLogStream = FileStreamRotator.getStream({
    filename: logDirectory + '/access-%DATE%.log',
    frequency: 'daily',
    verbose: false
});

// setup the logger
app.use(morgan('combined', {stream: accessLogStream}));

// express.js router class
var router = express.Router();

router.get('/teapot', function(req, res) {
    res.status(418);
    res.send('I\'m a teapot!');
});

router.get('/talks', function(req, res) {

});

app.use('/', router);

// start the HTTP server
var server = app.listen(config.port, function() {
    "use strict";
    var host = server.address().address;
    var port = server.address().port;
    console.log('tlks.io api listening at http://%s:%s', host, port);
});
<commit_msg>Fixed log rotation<commit_after>/*jshint unused:false*/
var express = require('express');
var morgan = require('morgan');
var fs = require('fs');
var FileStreamRotator = require('file-stream-rotator');

var config = require('./config.json');

// express.js application
var app = express();

var logDirectory = __dirname + '/log';
// ensure log directory exists
fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);

// create a rotating write stream
var accessLogStream = FileStreamRotator.getStream({
    filename: logDirectory + '/access.%DATE%.log',
    frequency: 'daily',
    verbose: false,
    date_format: "YYYY-MM-DD"
});

// setup the logger
app.use(morgan('combined', {stream: accessLogStream}));

// express.js router class
var router = express.Router();

router.get('/teapot', function(req, res) {
    res.status(418);
    res.send('I\'m a teapot!');
});

router.get('/talks', function(req, res) {

});

app.use('/', router);

// start the HTTP server
var server = app.listen(config.port, function() {
    "use strict";
    var host = server.address().address;
    var port = server.address().port;
    console.log('tlks.io api listening at http://%s:%s', host, port);
});
<|endoftext|>


<commit_before>var Prism = require('prismjs');
var languages = require('prismjs').languages;
var path = require('path');
var fs = require('fs');
var cheerio = require('cheerio');
var mkdirp = require('mkdirp');

var DEFAULT_LANGUAGE = 'markup';
var MAP_LANGUAGES = {
  'py': 'python',
  'js': 'javascript',
  'rb': 'ruby',
  'cs': 'csharp',
  'sh': 'bash',
  'html': 'markup'
};

// Base languages syntaxes (as of prism@1.6.0), extended by other syntaxes.
// They need to be required before the others.
var PRELUDE = [
  'clike', 'javascript', 'markup', 'c', 'ruby', 'css',
  // The following depends on previous ones
  'java', 'php'
];
PRELUDE.map(requireSyntax);

/**
 * Load the syntax definition for a language id
 */
function requireSyntax(lang) {
  require('prismjs/components/prism-' + lang + '.js');
}

function getConfig(context, property, defaultValue) {
  var config = context.config ? /* 3.x */ context.config : /* 2.x */ context.book.config;
  return config.get(property, defaultValue);
}

function isEbook(book) {
  // 2.x
  if (book.options && book.options.generator) {
    return book.options.generator === 'ebook';
  }

  // 3.x
  return book.output.name === 'ebook';
}

function getAssets() {

  var cssFiles = getConfig(this, 'pluginsConfig.prism.css', []);
  var cssFolder = null;
  var cssNames = [];
  var cssName = null;

  if (cssFiles.length === 0) {
    cssFiles.push('prismjs/themes/prism.css');
  }

  cssFiles.forEach(function(cssFile) {
    var cssPath = require.resolve(cssFile);
    cssFolder = path.dirname(cssPath);
    cssName = path.basename(cssPath);
    cssNames.push(cssName);
  });

  return {
    assets: cssFolder,
    css: cssNames
  };
}

module.exports = {
  book: getAssets,
  ebook: function() {

    // Adding prism-ebook.css to the CSS collection forces Gitbook
    // reference to it in the html markup that is converted into a PDF.
    var assets = getAssets.call(this);
    assets.css.push('prism-ebook.css');
    return assets;

  },
  blocks: {
    code: function(block) {

      var highlighted = '';
      var userDefined = getConfig(this, 'pluginsConfig.prism.lang', {});
      var userIgnored = getConfig(this, 'pluginsConfig.prism.ignore', []);

      // Normalize language id
      var lang = block.kwargs.language || DEFAULT_LANGUAGE;
      lang = userDefined[lang] || MAP_LANGUAGES[lang] || lang;

      // Check to see if the lang is ignored
      if (userIgnored.indexOf(lang) === -1) {
        return block.body
      }

      // Try and find the language definition in components folder
      if (!languages[lang]) {
        try {
          requireSyntax(lang);
        } catch (e) {
          console.warn('Failed to load prism syntax: ' + lang);
          console.warn(e);
        }
      }

      if (!languages[lang]) lang = DEFAULT_LANGUAGE;

      // Check against html, prism "markup" works for this
      if (lang === 'html') {
        lang = 'markup';
      }

      try {
        // The process can fail (failed to parse)
        highlighted = Prism.highlight(block.body, languages[lang]);
      } catch (e) {
        console.warn('Failed to highlight:');
        console.warn(e);
        highlighted = block.body;
      }

      return highlighted;

    }
  },
  hooks: {

    // Manually copy prism-ebook.css into the temporary directory that Gitbook uses for inlining
    // styles from this plugin. The getAssets() (above) function can't be leveraged because
    // ebook-prism.css lives outside the folder referenced by this plugin's config.
    //
    // @Inspiration https://github.com/GitbookIO/plugin-styles-less/blob/master/index.js#L8
    init: function() {

      var book = this;

      if (!isEbook(book)) {
        return;
      }

      var outputDirectory = path.join(book.output.root(), '/gitbook/gitbook-plugin-prism');
      var outputFile = path.resolve(outputDirectory, 'prism-ebook.css');
      var inputFile = path.resolve(__dirname, './prism-ebook.css');
      mkdirp.sync(outputDirectory);

      try {
        fs.writeFileSync(outputFile, fs.readFileSync(inputFile));
      } catch (e) {
        console.warn('Failed to write prism-ebook.css. See https://git.io/v1LHY for side effects.');
        console.warn(e);
      }

    },
    page: function(page) {

      var highlighted = false;

      var $ = cheerio.load(page.content);

      // Prism css styles target the <code> and <pre> blocks using
      // a substring CSS selector:
      //
      //    code[class*="language-"], pre[class*="language-"]
      //
      // Adding "language-" to <pre> element should be sufficient to trigger
      // correct color theme.
      $('pre').each(function() {
        highlighted = true;
        const $this = $(this);
        $this.addClass('language-');
      });

      if (highlighted) {
        page.content = $.html();
      }

      return page;
    }
  }
};
<commit_msg>fixed logic error<commit_after>var Prism = require('prismjs');
var languages = require('prismjs').languages;
var path = require('path');
var fs = require('fs');
var cheerio = require('cheerio');
var mkdirp = require('mkdirp');

var DEFAULT_LANGUAGE = 'markup';
var MAP_LANGUAGES = {
  'py': 'python',
  'js': 'javascript',
  'rb': 'ruby',
  'cs': 'csharp',
  'sh': 'bash',
  'html': 'markup'
};

// Base languages syntaxes (as of prism@1.6.0), extended by other syntaxes.
// They need to be required before the others.
var PRELUDE = [
  'clike', 'javascript', 'markup', 'c', 'ruby', 'css',
  // The following depends on previous ones
  'java', 'php'
];
PRELUDE.map(requireSyntax);

/**
 * Load the syntax definition for a language id
 */
function requireSyntax(lang) {
  require('prismjs/components/prism-' + lang + '.js');
}

function getConfig(context, property, defaultValue) {
  var config = context.config ? /* 3.x */ context.config : /* 2.x */ context.book.config;
  return config.get(property, defaultValue);
}

function isEbook(book) {
  // 2.x
  if (book.options && book.options.generator) {
    return book.options.generator === 'ebook';
  }

  // 3.x
  return book.output.name === 'ebook';
}

function getAssets() {

  var cssFiles = getConfig(this, 'pluginsConfig.prism.css', []);
  var cssFolder = null;
  var cssNames = [];
  var cssName = null;

  if (cssFiles.length === 0) {
    cssFiles.push('prismjs/themes/prism.css');
  }

  cssFiles.forEach(function(cssFile) {
    var cssPath = require.resolve(cssFile);
    cssFolder = path.dirname(cssPath);
    cssName = path.basename(cssPath);
    cssNames.push(cssName);
  });

  return {
    assets: cssFolder,
    css: cssNames
  };
}

module.exports = {
  book: getAssets,
  ebook: function() {

    // Adding prism-ebook.css to the CSS collection forces Gitbook
    // reference to it in the html markup that is converted into a PDF.
    var assets = getAssets.call(this);
    assets.css.push('prism-ebook.css');
    return assets;

  },
  blocks: {
    code: function(block) {

      var highlighted = '';
      var userDefined = getConfig(this, 'pluginsConfig.prism.lang', {});
      var userIgnored = getConfig(this, 'pluginsConfig.prism.ignore', []);

      // Normalize language id
      var lang = block.kwargs.language || DEFAULT_LANGUAGE;
      lang = userDefined[lang] || MAP_LANGUAGES[lang] || lang;

      // Check to see if the lang is ignored
      if (userIgnored.indexOf(lang) > -1) {
        return block.body
      }

      // Try and find the language definition in components folder
      if (!languages[lang]) {
        try {
          requireSyntax(lang);
        } catch (e) {
          console.warn('Failed to load prism syntax: ' + lang);
          console.warn(e);
        }
      }

      if (!languages[lang]) lang = DEFAULT_LANGUAGE;

      // Check against html, prism "markup" works for this
      if (lang === 'html') {
        lang = 'markup';
      }

      try {
        // The process can fail (failed to parse)
        highlighted = Prism.highlight(block.body, languages[lang]);
      } catch (e) {
        console.warn('Failed to highlight:');
        console.warn(e);
        highlighted = block.body;
      }

      return highlighted;

    }
  },
  hooks: {

    // Manually copy prism-ebook.css into the temporary directory that Gitbook uses for inlining
    // styles from this plugin. The getAssets() (above) function can't be leveraged because
    // ebook-prism.css lives outside the folder referenced by this plugin's config.
    //
    // @Inspiration https://github.com/GitbookIO/plugin-styles-less/blob/master/index.js#L8
    init: function() {

      var book = this;

      if (!isEbook(book)) {
        return;
      }

      var outputDirectory = path.join(book.output.root(), '/gitbook/gitbook-plugin-prism');
      var outputFile = path.resolve(outputDirectory, 'prism-ebook.css');
      var inputFile = path.resolve(__dirname, './prism-ebook.css');
      mkdirp.sync(outputDirectory);

      try {
        fs.writeFileSync(outputFile, fs.readFileSync(inputFile));
      } catch (e) {
        console.warn('Failed to write prism-ebook.css. See https://git.io/v1LHY for side effects.');
        console.warn(e);
      }

    },
    page: function(page) {

      var highlighted = false;

      var $ = cheerio.load(page.content);

      // Prism css styles target the <code> and <pre> blocks using
      // a substring CSS selector:
      //
      //    code[class*="language-"], pre[class*="language-"]
      //
      // Adding "language-" to <pre> element should be sufficient to trigger
      // correct color theme.
      $('pre').each(function() {
        highlighted = true;
        const $this = $(this);
        $this.addClass('language-');
      });

      if (highlighted) {
        page.content = $.html();
      }

      return page;
    }
  }
};
<|endoftext|>