<commit_before>const NEW_API_FIREFOX_VERSION = 44;
const ONE_SECOND_IN_MILLISECONDS = 1000;
const URL_CHARS_LIMIT = 2000;

const { PrefsTarget } = require('sdk/preferences/event-target');
const { setInterval, clearInterval } = require('sdk/timers');
const { version } = require('sdk/system/xul-app');
const clipboard = require('sdk/clipboard');
const preferencesService = require('sdk/preferences/service');
const prefsTarget = PrefsTarget({ branchName: 'browser.startup.'});
const simplePrefs = require('sdk/simple-prefs');

const newtaboverride = {
  lastClipboardUrl : false,
  timer : false,
  version : parseFloat(version),

  init : function () {
    newtaboverride.onPrefChange();
  },

  override : function (newTabUrl) {
    if (this.version < NEW_API_FIREFOX_VERSION) {
      require('resource:///modules/NewTabURL.jsm').NewTabURL.override(newTabUrl);
    } else {
      const { Cc, Ci } = require('chrome');
      const aboutNewTabService = Cc['@mozilla.org/browser/aboutnewtab-service;1'].getService(Ci.nsIAboutNewTabService);

      aboutNewTabService.newTabURL = newTabUrl;
    }
  },

  reset : function () {
    if (this.version < NEW_API_FIREFOX_VERSION) {
      require('resource:///modules/NewTabURL.jsm').NewTabURL.reset();
    } else {
      const { Cc, Ci } = require('chrome');
      const aboutNewTabService = Cc['@mozilla.org/browser/aboutnewtab-service;1'].getService(Ci.nsIAboutNewTabService);

      aboutNewTabService.resetNewTabURL();
    }
  },

  onPrefChange : function () {
    var type = simplePrefs.prefs['type'];
    var newTabUrl;

    switch (type) {
      case 'about:blank':
      case 'about:home':
      case 'about:newtab':
      case 'about:sync-tabs':
        newTabUrl = type;
        break;
      case 'clipboard':
        newTabUrl = 'about:blank';
        // unfortunately there is no "clipboard changed" event…
        newtaboverride.timer = setInterval(newtaboverride.clipboardAction, ONE_SECOND_IN_MILLISECONDS / 2);
        break;
      case 'custom_url':
        var url = simplePrefs.prefs['url'];
        if (url === '') {
          newTabUrl = 'about:blank';
        }
        else if (newtaboverride.isValidUri(url)) {
          newTabUrl = url;
        } else {
          newTabUrl = 'about:newtab';
        }
        break;
      case 'homepage':
        newTabUrl = preferencesService.getLocalized('browser.startup.homepage', 'about:blank').split('|')[0];
        break;
      default:
        newTabUrl = 'about:newtab';
    }

    if (type !== 'clipboard') {
      clearInterval(newtaboverride.timer);
      newtaboverride.lastClipboardUrl = false;
    }

    newtaboverride.override(newTabUrl);
  },

  clipboardAction : function () {
    var clipboardContent = clipboard.get();

    if (clipboard.currentFlavors.indexOf('text') === -1) {
      return;
    }

    if (clipboardContent.length > URL_CHARS_LIMIT || !newtaboverride.isValidUri(clipboardContent)) {
      return;
    }

    if (!newtaboverride.lastClipboardUrl || clipboardContent !== newtaboverride.lastClipboardUrl) {
      newtaboverride.override(clipboardContent);
      newtaboverride.lastClipboardUrl = clipboardContent;
    }
  },

  /**
   * @see http://stackoverflow.com/a/9284473
   */
  isValidUri : function (string) {
    var website = /^(?:(?:https?):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
    var aboutpage = /^about:(about|accounts|addons|blank|buildconfig|cache|config|crashes|credits|customizing|debugging|downloads|healthreport|home|license|logo|memory|mozilla|networking|newtab|performance|plugins|preferences|privatebrowsing|profiles|remote-newtab|rights|robots|serviceworkers|support|sync-log|sync-tabs|telemetry|webrtc)?$/i;

    return website.test(string) || aboutpage.test(string);
  }
};

const main = () => {
  newtaboverride.init();

  simplePrefs.on('', newtaboverride.onPrefChange);
  prefsTarget.on('homepage', newtaboverride.onPrefChange);
};

exports.main = main;

exports.onUnload = function (reason) {
  if (reason === 'uninstall' || reason === 'disable') {
    clearInterval(newtaboverride.timer);
    newtaboverride.lastClipboardUrl = false;
    newtaboverride.reset();
  }
};
<commit_msg>Validierung nicht für Option "eigene URL" durchführen<commit_after>const NEW_API_FIREFOX_VERSION = 44;
const ONE_SECOND_IN_MILLISECONDS = 1000;
const URL_CHARS_LIMIT = 2000;

const { PrefsTarget } = require('sdk/preferences/event-target');
const { setInterval, clearInterval } = require('sdk/timers');
const { version } = require('sdk/system/xul-app');
const clipboard = require('sdk/clipboard');
const preferencesService = require('sdk/preferences/service');
const prefsTarget = PrefsTarget({ branchName: 'browser.startup.'});
const simplePrefs = require('sdk/simple-prefs');

const newtaboverride = {
  lastClipboardUrl : false,
  timer : false,
  version : parseFloat(version),

  init : function () {
    newtaboverride.onPrefChange();
  },

  override : function (newTabUrl) {
    if (this.version < NEW_API_FIREFOX_VERSION) {
      require('resource:///modules/NewTabURL.jsm').NewTabURL.override(newTabUrl);
    } else {
      const { Cc, Ci } = require('chrome');
      const aboutNewTabService = Cc['@mozilla.org/browser/aboutnewtab-service;1'].getService(Ci.nsIAboutNewTabService);

      aboutNewTabService.newTabURL = newTabUrl;
    }
  },

  reset : function () {
    if (this.version < NEW_API_FIREFOX_VERSION) {
      require('resource:///modules/NewTabURL.jsm').NewTabURL.reset();
    } else {
      const { Cc, Ci } = require('chrome');
      const aboutNewTabService = Cc['@mozilla.org/browser/aboutnewtab-service;1'].getService(Ci.nsIAboutNewTabService);

      aboutNewTabService.resetNewTabURL();
    }
  },

  onPrefChange : function () {
    var type = simplePrefs.prefs['type'];
    var newTabUrl;

    switch (type) {
      case 'about:blank':
      case 'about:home':
      case 'about:newtab':
      case 'about:sync-tabs':
        newTabUrl = type;
        break;
      case 'clipboard':
        newTabUrl = 'about:blank';
        // unfortunately there is no "clipboard changed" event…
        newtaboverride.timer = setInterval(newtaboverride.clipboardAction, ONE_SECOND_IN_MILLISECONDS / 2);
        break;
      case 'custom_url':
        var url = simplePrefs.prefs['url'];
        if (url === '') {
          newTabUrl = 'about:blank';
        } else {
          newTabUrl = url;
        }
        break;
      case 'homepage':
        newTabUrl = preferencesService.getLocalized('browser.startup.homepage', 'about:blank').split('|')[0];
        break;
      default:
        newTabUrl = 'about:newtab';
    }

    if (type !== 'clipboard') {
      clearInterval(newtaboverride.timer);
      newtaboverride.lastClipboardUrl = false;
    }

    newtaboverride.override(newTabUrl);
  },

  clipboardAction : function () {
    var clipboardContent = clipboard.get();

    if (clipboard.currentFlavors.indexOf('text') === -1) {
      return;
    }

    if (clipboardContent.length > URL_CHARS_LIMIT || !newtaboverride.isValidUri(clipboardContent)) {
      return;
    }

    if (!newtaboverride.lastClipboardUrl || clipboardContent !== newtaboverride.lastClipboardUrl) {
      newtaboverride.override(clipboardContent);
      newtaboverride.lastClipboardUrl = clipboardContent;
    }
  },

  /**
   * @see http://stackoverflow.com/a/9284473
   */
  isValidUri : function (string) {
    var website = /^(?:(?:https?):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
    var aboutpage = /^about:(about|accounts|addons|blank|buildconfig|cache|config|crashes|credits|customizing|debugging|downloads|healthreport|home|license|logo|memory|mozilla|networking|newtab|performance|plugins|preferences|privatebrowsing|profiles|remote-newtab|rights|robots|serviceworkers|support|sync-log|sync-tabs|telemetry|webrtc)?$/i;

    return website.test(string) || aboutpage.test(string);
  }
};

const main = () => {
  newtaboverride.init();

  simplePrefs.on('', newtaboverride.onPrefChange);
  prefsTarget.on('homepage', newtaboverride.onPrefChange);
};

exports.main = main;

exports.onUnload = function (reason) {
  if (reason === 'uninstall' || reason === 'disable') {
    clearInterval(newtaboverride.timer);
    newtaboverride.lastClipboardUrl = false;
    newtaboverride.reset();
  }
};
<|endoftext|>


<commit_before>'use strict'

require('dotenv').config()

const mongoose = require('mongoose')

const server = require('./server')
const signale = require('./signale')

const port = process.env.PORT || 3000
const url = `http://localhost:${ port }`

signale.start(`Starting the server`)

mongoose.connect(process.env.MONGODB)
server.listen(port)

signale.watch(`Listening on ${ url }`)<commit_msg>Fix mongoose warning<commit_after>'use strict'

require('dotenv').config()

const mongoose = require('mongoose')

const server = require('./server')
const signale = require('./signale')

const port = process.env.PORT || 3000
const url = `http://localhost:${ port }`

signale.start(`Starting the server`)

mongoose.connect(process.env.MONGODB, { useNewUrlParser: true })
server.listen(port)

signale.watch(`Listening on ${ url }`)<|endoftext|>


<commit_before>/**
 * 百度地图定位api和天气预报api
 */
// TODO: 完善功能
// 百度地图API功能
var map = new BMap.Map("allmap");
var point = new BMap.Point(116.331398, 39.897445);
map.centerAndZoom(point, 12);

var geolocation = new BMap.Geolocation();
geolocation.getCurrentPosition(function(r) {
    if (this.getStatus() == BMAP_STATUS_SUCCESS) {
      var mk = new BMap.Marker(r.point);
      map.addOverlay(mk);
      map.panTo(r.point);
      alert('您的位置：' + r.point.lng + ',' + r.point.lat);
    } else {
      alert('failed' + this.getStatus());
    }
  }, {
    enableHighAccuracy: true
  })
  //关于状态码
  //BMAP_STATUS_SUCCESS	检索成功。对应数值“0”。
  //BMAP_STATUS_CITY_LIST	城市列表。对应数值“1”。
  //BMAP_STATUS_UNKNOWN_LOCATION	位置结果未知。对应数值“2”。
  //BMAP_STATUS_UNKNOWN_ROUTE	导航结果未知。对应数值“3”。
  //BMAP_STATUS_INVALID_KEY	非法密钥。对应数值“4”。
  //BMAP_STATUS_INVALID_REQUEST	非法请求。对应数值“5”。
  //BMAP_STATUS_PERMISSION_DENIED	没有权限。对应数值“6”。(自 1.1 新增)
  //BMAP_STATUS_SERVICE_UNAVAILABLE	服务不可用。对应数值“7”。(自 1.1 新增)
  //BMAP_STATUS_TIMEOUT	超时。对应数值“8”。(自 1.1 新增)

// TODO: 获取天气，index.js,解决跨域请求问题
var xmlhttp = new XMLHttpRequest();
var weather_json = xmlhttp.open("GET", "http://api.map.baidu.com/telematics/v3/weather?location=%E6%9D%AD%E5%B7%9E&output=json&ak=U1fGe9lfreG6OzmxSWv237Gf", true);
xmlhttp.send(null);
alert(weather_json);

/**
 * chart.js
 * @type {Array}
 */
var doughnutData = [{
    value: 300,
    color: "#F7464A",
    highlight: "#FF5A5E",
    label: "Red"
  }, {
    value: 50,
    color: "#46BFBD",
    highlight: "#5AD3D1",
    label: "Green"
  }, {
    value: 100,
    color: "#FDB45C",
    highlight: "#FFC870",
    label: "Yellow"
  }, {
    value: 40,
    color: "#949FB1",
    highlight: "#A8B3C5",
    label: "Grey"
  }, {
    value: 120,
    color: "#4D5360",
    highlight: "#616774",
    label: "Dark Grey"
  }

];

var polarData = [{
    value: 300,
    color: "#F7464A",
    highlight: "#FF5A5E",
    label: "Red"
  }, {
    value: 50,
    color: "#46BFBD",
    highlight: "#5AD3D1",
    label: "Green"
  }, {
    value: 100,
    color: "#FDB45C",
    highlight: "#FFC870",
    label: "Yellow"
  }, {
    value: 40,
    color: "#949FB1",
    highlight: "#A8B3C5",
    label: "Grey"
  }, {
    value: 120,
    color: "#4D5360",
    highlight: "#616774",
    label: "Dark Grey"
  }

];

var radarChartData = {
  labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
  datasets: [{
    label: "My First dataset",
    fillColor: "rgba(220,220,220,0.2)",
    strokeColor: "rgba(220,220,220,1)",
    pointColor: "rgba(220,220,220,1)",
    pointStrokeColor: "#fff",
    pointHighlightFill: "#fff",
    pointHighlightStroke: "rgba(220,220,220,1)",
    data: [65, 59, 90, 81, 56, 55, 40]
  }, {
    label: "My Second dataset",
    fillColor: "rgba(151,187,205,0.2)",
    strokeColor: "rgba(151,187,205,1)",
    pointColor: "rgba(151,187,205,1)",
    pointStrokeColor: "#fff",
    pointHighlightFill: "#fff",
    pointHighlightStroke: "rgba(151,187,205,1)",
    data: [28, 48, 40, 19, 96, 27, 100]
  }]
};

var randomScalingFactor = function() {
  return Math.round(Math.random() * 100)
};

var barChartData = {
  labels: ["January", "February", "March", "April", "May", "June", "July"],
  datasets: [{
    fillColor: "rgba(220,220,220,0.5)",
    strokeColor: "rgba(220,220,220,0.8)",
    highlightFill: "rgba(220,220,220,0.75)",
    highlightStroke: "rgba(220,220,220,1)",
    data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
  }, {
    fillColor: "rgba(151,187,205,0.5)",
    strokeColor: "rgba(151,187,205,0.8)",
    highlightFill: "rgba(151,187,205,0.75)",
    highlightStroke: "rgba(151,187,205,1)",
    data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
  }]

};

// window.onload = function(){
//   //var ctx = document.getElementById("chart-area").getContext("2d");
//   window.myDoughnut = new Chart(ctx).Doughnut(doughnutData, {responsive : true});
// };

// TODO: 无法在模态框中显示
$('#business-statistics').on('click', function() {

  var canvas_holder_html = $('#canvas-holder').html();
  $('#modal-business-statistics').modal('show');
  var ctx = document.getElementById("chart-area-doughnut").getContext("2d");
  window.myDoughnut = new Chart(ctx).Doughnut(doughnutData, {
    responsive: true
  });

  ctx = document.getElementById("chart-area-polar-area").getContext("2d");
  window.myPolarArea = new Chart(ctx).PolarArea(polarData, {
    responsive:true
  });

  window.myRadar = new Chart(document.getElementById("chart-area-radar").getContext("2d")).Radar(radarChartData, {
    responsive: true
  });

  ctx = document.getElementById("chart-area-bar").getContext("2d");
  window.myBar = new Chart(ctx).Bar(barChartData, {
    responsive : true
  });

  var html = $('#chart-area-doughnut');
  $('#modal-chart-area-doughnut').html(html);

  html = $('#chart-area-polar-area');
  $('#modal-chart-area-polar-area').html(html);

  html = $('#chart-area-radar');
  $('#modal-chart-area-radar').html(html);

  html = $('#chart-area-bar');
  $('#modal-chart-area-bar').html(html);

  $('#canvas-holder').html(canvas_holder_html);
});

/**
 * 日期选择器绑定
 * @param  {[type]} '#modal-check-in-in-datetimepicker' [description]
 * @return {[type]}                                     [description]
 */
// TODO: 修改类名，通过子类统一
$('#modal-check-in-in-datetimepicker').datetimepicker({
  format: 'yyyy-mm-dd hh:ii',
  language:  'zh-CN',
  pickerPosition: 'top-right',
});
$('#modal-check-in-out-datetimepicker').datetimepicker({
  format: 'yyyy-mm-dd hh:ii',
  language:  'zh-CN',
  pickerPosition: 'top-right',
});
$('#modal-check-out-in-datetimepicker').datetimepicker({
  format: 'yyyy-mm-dd hh:ii',
  language:  'zh-CN',
  pickerPosition: 'top-right',
});
$('#modal-check-out-out-datetimepicker').datetimepicker({
  format: 'yyyy-mm-dd hh:ii',
  language:  'zh-CN',
  pickerPosition: 'top-right',
});
/**
 * 输入校验
 */
// TODO: 输入校验,关闭后输入信息是否清空
$('#modal-check-in-submit').on('click', function() {
  var state = false;
  if (!state) {
    if ($('#modal-check-in-name').val() == "") {
      alert("输入姓名");
      state = false;
      return;
    }

    if ($('#modal-check-in-tel').val() == "") {
      alert("输入手机号");
      state = false;
      return;
    } else if (true) {
      var tel = $('#modal-check-in-tel').val();
      var pattern = /^1[34578]\d{9}$/;
      if (!pattern.test(tel)) {
        alert("输入正确手机号");
        state = false;
        return;
      }
    }

    if ($('#modal-check-in-room').val() == "") {
      alert("选择房间号");
      state = false;
      return;
    }

    if ($('#modal-check-in-in-datetimepicker').val() == "") {
      alert("选择入住时间");
      state = false;
      return;
    }

    if ($('#modal-check-in-out-datetimepicker').val() == "") {
      alert("选择退房时间");
      state = false;
      return;
    }
  }
});

$('#modal-check-out-submit').on('click', function() {
  var state = false;
  if (!state) {
    if ($('#modal-check-out-name').val() == "") {
      alert("输入姓名");
      state = false;
      return;
    }

    if ($('#modal-check-out-tel').val() == "") {
      alert("输入手机号");
      state = false;
      return;
    } else if (true) {
      var tel = $('#modal-check-out-tel').val();
      var pattern = /^1[34578]\d{9}$/;
      if (!pattern.test(tel)) {
        alert("输入正确手机号");
        state = false;
        return;
      }
    }

    if ($('#modal-check-out-room').val() == "") {
      alert("选择房间号");
      state = false;
      return;
    }

    if ($('#modal-check-out-in-datetimepicker').val() == "") {
      alert("选择入住时间");
      state = false;
      return;
    }

    if ($('#modal-check-out-out-datetimepicker').val() == "") {
      alert("选择退房时间");
      state = false;
      return;
    }
  }
});
<commit_msg>调整时间选择，精确为 *天*<commit_after>/**
 * 百度地图定位api和天气预报api
 */
// TODO: 完善功能
// 百度地图API功能
var map = new BMap.Map("allmap");
var point = new BMap.Point(116.331398, 39.897445);
map.centerAndZoom(point, 12);

var geolocation = new BMap.Geolocation();
geolocation.getCurrentPosition(function(r) {
    if (this.getStatus() == BMAP_STATUS_SUCCESS) {
      var mk = new BMap.Marker(r.point);
      map.addOverlay(mk);
      map.panTo(r.point);
      alert('您的位置：' + r.point.lng + ',' + r.point.lat);
    } else {
      alert('failed' + this.getStatus());
    }
  }, {
    enableHighAccuracy: true
  })
  //关于状态码
  //BMAP_STATUS_SUCCESS	检索成功。对应数值“0”。
  //BMAP_STATUS_CITY_LIST	城市列表。对应数值“1”。
  //BMAP_STATUS_UNKNOWN_LOCATION	位置结果未知。对应数值“2”。
  //BMAP_STATUS_UNKNOWN_ROUTE	导航结果未知。对应数值“3”。
  //BMAP_STATUS_INVALID_KEY	非法密钥。对应数值“4”。
  //BMAP_STATUS_INVALID_REQUEST	非法请求。对应数值“5”。
  //BMAP_STATUS_PERMISSION_DENIED	没有权限。对应数值“6”。(自 1.1 新增)
  //BMAP_STATUS_SERVICE_UNAVAILABLE	服务不可用。对应数值“7”。(自 1.1 新增)
  //BMAP_STATUS_TIMEOUT	超时。对应数值“8”。(自 1.1 新增)

// TODO: 获取天气，index.js,解决跨域请求问题
var xmlhttp = new XMLHttpRequest();
var weather_json = xmlhttp.open("GET", "http://api.map.baidu.com/telematics/v3/weather?location=%E6%9D%AD%E5%B7%9E&output=json&ak=U1fGe9lfreG6OzmxSWv237Gf", true);
xmlhttp.send(null);
alert(weather_json);

/**
 * chart.js
 * @type {Array}
 */
var doughnutData = [{
    value: 300,
    color: "#F7464A",
    highlight: "#FF5A5E",
    label: "Red"
  }, {
    value: 50,
    color: "#46BFBD",
    highlight: "#5AD3D1",
    label: "Green"
  }, {
    value: 100,
    color: "#FDB45C",
    highlight: "#FFC870",
    label: "Yellow"
  }, {
    value: 40,
    color: "#949FB1",
    highlight: "#A8B3C5",
    label: "Grey"
  }, {
    value: 120,
    color: "#4D5360",
    highlight: "#616774",
    label: "Dark Grey"
  }

];

var polarData = [{
    value: 300,
    color: "#F7464A",
    highlight: "#FF5A5E",
    label: "Red"
  }, {
    value: 50,
    color: "#46BFBD",
    highlight: "#5AD3D1",
    label: "Green"
  }, {
    value: 100,
    color: "#FDB45C",
    highlight: "#FFC870",
    label: "Yellow"
  }, {
    value: 40,
    color: "#949FB1",
    highlight: "#A8B3C5",
    label: "Grey"
  }, {
    value: 120,
    color: "#4D5360",
    highlight: "#616774",
    label: "Dark Grey"
  }

];

var radarChartData = {
  labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
  datasets: [{
    label: "My First dataset",
    fillColor: "rgba(220,220,220,0.2)",
    strokeColor: "rgba(220,220,220,1)",
    pointColor: "rgba(220,220,220,1)",
    pointStrokeColor: "#fff",
    pointHighlightFill: "#fff",
    pointHighlightStroke: "rgba(220,220,220,1)",
    data: [65, 59, 90, 81, 56, 55, 40]
  }, {
    label: "My Second dataset",
    fillColor: "rgba(151,187,205,0.2)",
    strokeColor: "rgba(151,187,205,1)",
    pointColor: "rgba(151,187,205,1)",
    pointStrokeColor: "#fff",
    pointHighlightFill: "#fff",
    pointHighlightStroke: "rgba(151,187,205,1)",
    data: [28, 48, 40, 19, 96, 27, 100]
  }]
};

var randomScalingFactor = function() {
  return Math.round(Math.random() * 100)
};

var barChartData = {
  labels: ["January", "February", "March", "April", "May", "June", "July"],
  datasets: [{
    fillColor: "rgba(220,220,220,0.5)",
    strokeColor: "rgba(220,220,220,0.8)",
    highlightFill: "rgba(220,220,220,0.75)",
    highlightStroke: "rgba(220,220,220,1)",
    data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
  }, {
    fillColor: "rgba(151,187,205,0.5)",
    strokeColor: "rgba(151,187,205,0.8)",
    highlightFill: "rgba(151,187,205,0.75)",
    highlightStroke: "rgba(151,187,205,1)",
    data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
  }]

};

// window.onload = function(){
//   //var ctx = document.getElementById("chart-area").getContext("2d");
//   window.myDoughnut = new Chart(ctx).Doughnut(doughnutData, {responsive : true});
// };

// TODO: 无法在模态框中显示
$('#business-statistics').on('click', function() {

  var canvas_holder_html = $('#canvas-holder').html();
  $('#modal-business-statistics').modal('show');
  var ctx = document.getElementById("chart-area-doughnut").getContext("2d");
  window.myDoughnut = new Chart(ctx).Doughnut(doughnutData, {
    responsive: true
  });

  ctx = document.getElementById("chart-area-polar-area").getContext("2d");
  window.myPolarArea = new Chart(ctx).PolarArea(polarData, {
    responsive:true
  });

  window.myRadar = new Chart(document.getElementById("chart-area-radar").getContext("2d")).Radar(radarChartData, {
    responsive: true
  });

  ctx = document.getElementById("chart-area-bar").getContext("2d");
  window.myBar = new Chart(ctx).Bar(barChartData, {
    responsive : true
  });

  var html = $('#chart-area-doughnut');
  $('#modal-chart-area-doughnut').html(html);

  html = $('#chart-area-polar-area');
  $('#modal-chart-area-polar-area').html(html);

  html = $('#chart-area-radar');
  $('#modal-chart-area-radar').html(html);

  html = $('#chart-area-bar');
  $('#modal-chart-area-bar').html(html);

  $('#canvas-holder').html(canvas_holder_html);
});

/**
 * 日期选择器绑定
 * @param  {[type]} '#modal-check-in-in-datetimepicker' [description]
 * @return {[type]}                                     [description]
 */
// TODO: 修改类名，通过子类统一
$('#modal-check-in-in-datetimepicker').datetimepicker({
  format: 'yyyy-mm-dd',
  language:  'zh-CN',
  pickerPosition: 'top-right',
  autoclose: 'true',
  minView: '2'
});
$('#modal-check-in-out-datetimepicker').datetimepicker({
  format: 'yyyy-mm-dd',
  language:  'zh-CN',
  pickerPosition: 'top-right',
  autoclose: 'true',
  minView: '2'
});
$('#modal-check-out-in-datetimepicker').datetimepicker({
  format: 'yyyy-mm-dd',
  language:  'zh-CN',
  pickerPosition: 'top-right',
  autoclose: 'true',
  minView: '2'
});
$('#modal-check-out-out-datetimepicker').datetimepicker({
  format: 'yyyy-mm-dd',
  language:  'zh-CN',
  pickerPosition: 'top-right',
  autoclose: 'true',
  minView: '2'
});
/**
 * 输入校验
 */
// TODO: 输入校验,关闭后输入信息是否清空
$('#modal-check-in-submit').on('click', function() {
  var state = false;
  if (!state) {
    if ($('#modal-check-in-name').val() == "") {
      alert("输入姓名");
      state = false;
      return;
    }

    if ($('#modal-check-in-tel').val() == "") {
      alert("输入手机号");
      state = false;
      return;
    } else if (true) {
      var tel = $('#modal-check-in-tel').val();
      var pattern = /^1[34578]\d{9}$/;
      if (!pattern.test(tel)) {
        alert("输入正确手机号");
        state = false;
        return;
      }
    }

    if ($('#modal-check-in-room').val() == "") {
      alert("选择房间号");
      state = false;
      return;
    }

    if ($('#modal-check-in-in-datetimepicker').val() == "") {
      alert("选择入住时间");
      state = false;
      return;
    }

    if ($('#modal-check-in-out-datetimepicker').val() == "") {
      alert("选择退房时间");
      state = false;
      return;
    }
  }
});

$('#modal-check-out-submit').on('click', function() {
  var state = false;
  if (!state) {
    if ($('#modal-check-out-name').val() == "") {
      alert("输入姓名");
      state = false;
      return;
    }

    if ($('#modal-check-out-tel').val() == "") {
      alert("输入手机号");
      state = false;
      return;
    } else if (true) {
      var tel = $('#modal-check-out-tel').val();
      var pattern = /^1[34578]\d{9}$/;
      if (!pattern.test(tel)) {
        alert("输入正确手机号");
        state = false;
        return;
      }
    }

    if ($('#modal-check-out-room').val() == "") {
      alert("选择房间号");
      state = false;
      return;
    }

    if ($('#modal-check-out-in-datetimepicker').val() == "") {
      alert("选择入住时间");
      state = false;
      return;
    }

    if ($('#modal-check-out-out-datetimepicker').val() == "") {
      alert("选择退房时间");
      state = false;
      return;
    }
  }
});
<|endoftext|>


<commit_before>/* components */
export Tabs from './tabs'
export Pane from './pane'
<commit_msg>Remove main file<commit_after><|endoftext|>


<commit_before>var Alexa = require('alexa-sdk');
var googleMapsClient = require('@google/maps').createClient({
  key: 'Google Maps API key here'

});
var https = require('https');

var states = {
    SEARCHMODE: '_SEARCHMODE',
    TRAILINFO: '_TRAILINFO',
};

var welcomeMessage = "Welcome to MTB Trails. You can ask for trails near a city name and get more information about those trails.";

var welcomeReprompt = "Ask me for trails near any city";

var helpMessage = "Here is something you can ask me: Find me trails near Boulder, Colorado. After that, you can say: give me more information about trail number two. What do you want to do?";

var goodbyeMessage = "Thanks for using MTB trails. See you out on the bike!";

var noCityErrorMessage = "Sorry, I didn't recognize that city name. Please try again.";

var cityConversionErrorMessage = "Something went wrong while looking for trails. Please try again.";

var noTrailErrorMessage = "What trail was that? Please try again.";

var trailsMoreInfoMessage = "You can tell me a number for more information. For example, open number one.";

var hearMoreMessage = "Would you like to hear about another trail?";

var numberOfTrails = 3;

var output = "";

var responseData;

var city;

var alexa;

var newSessionHandlers = {
  'LaunchRequest': function () {
      this.handler.state = states.SEARCHMODE;
      this.emit(':ask', welcomeMessage, welcomeReprompt);
  },
  'getTrailsIntent': function () {
      this.handler.state = states.SEARCHMODE;
      this.emitWithState('getTrailsIntent');
  },
  'AMAZON.StopIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'AMAZON.CancelIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'SessionEndedRequest': function () {
      this.emit('AMAZON.StopIntent');
  },
  'Unhandled': function () {
      this.emit(':ask', helpMessage, welcomeReprompt);
  }
};

var searchHandlers = Alexa.CreateStateHandler(states.SEARCHMODE, {
  'getTrailsIntent': function () {
      this.handler.state = states.TRAILINFO;
      city = '';
      var lat = 0;
      var lng = 0;
      if (this.event.request.intent.slots.city) {
          if (this.event.request.intent.slots.city.value) {
              city = this.event.request.intent.slots.city.value;
          }
      }

      if (city) {
        googleMapsClient.geocode({
          address: city
        }, function(err, response) {
          if (!err) {
            console.log(response.json.results);
            console.log(response.json.results[0].geometry);
            lat = parseFloat(response.json.results[0].geometry.location.lat);
            lng = parseFloat(response.json.results[0].geometry.location.lng);
          } else {
            console.error(err);
          }
          if (lat != 0 && lng != 0) {
            var loc = [lat, lng];
            console.log(loc);
            httpsGet(loc, function (response) {
              responseData = JSON.parse(response);
              var cardContent = "Data provided by MTB Project\n\n";

              if (responseData == null) {
                output = "There was a problem getting trail data. Please try again.";
              } else {
                output = "There are " + responseData.trails.length + " trails near " + city + ".";
                if (responseData.trails.length > numberOfTrails) {
                  output += " Here are the top " + numberOfTrails + ".";
                }
                output += " See your Alexa app for more information and more trails. ";

                for (var i = 0; i < responseData.trails.length; i++) {
                  if (i < numberOfTrails) {
                    var name = responseData.trails[i].name;
                    var summary = responseData.trails[i].summary;
                    var difficulty = responseData.trails[i].difficulty;
                    var index = i + 1;
                    output += "Trail " + index + ";";

                    output += name + ". " + summary + " Difficulty: " + difficulty + ";";
                  }
                  cardContent += name + "\n" + summary + "\n" + "Difficulty: " + difficulty + "\n\n";
                }

              }
              var cardTitle = city + " Trails";
              output += "\n" + trailsMoreInfoMessage;
              output = output.replace(/&/, 'and');
              alexa.emit(':askWithCard', output, trailsMoreInfoMessage, cardTitle, cardContent);
            });
          } else {
            alexa.emit(':ask', cityConversionErrorMessage);
          }
        });
      } else {
        this.emit(':ask', noCityErrorMessage);
      }
  },

  'AMAZON.YesIntent': function () {
      this.emit(':ask', helpMessage, helpMessage);
  },
  'AMAZON.NoIntent': function () {
      this.emit(':ask', helpMessage, helpMessage);
  },
  'AMAZON.StopIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'AMAZON.HelpIntent': function () {
      this.emit(':ask', helpMessage, helpMessage);
  },
  'AMAZON.RepeatIntent': function () {
      this.emit(':ask', output, helpMessage);
  },
  'AMAZON.CancelIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'SessionEndedRequest': function () {
      this.emit('AMAZON.StopIntent');
  },
  'Unhandled': function () {
      this.emit(':ask', helpMessage, welcomeReprompt);
  }
});

var trailInfoHandlers = Alexa.CreateStateHandler(states.TRAILINFO, {
  'getTrailsIntent': function () {
    this.handler.state = states.SEARCHMODE;
    this.emitWithState('getTrailsIntent');
  },
  'getMoreInfoIntent': function () {
    var trail = 0;
    if (this.event.request.intent.slots.trail) {
      if (this.event.request.intent.slots.trail.value) {
        trail = this.event.request.intent.slots.trail.value;
      }
    }

    if (trail > 0 && trail <= responseData.trails.length) {
      var selectedTrail = responseData.trails[parseInt(trail) - 1];
      output = selectedTrail.name + ". " + selectedTrail.summary + ';';
      output += " It has " + selectedTrail.stars + " stars and a difficulty rating of " + selectedTrail.difficulty + ". ";
      output += "It is " + selectedTrail.length + " miles long, has " + selectedTrail.ascent + " feet of climbing, and reaches a high point of " + selectedTrail.high + " feet.  ";
      output += hearMoreMessage;
      output = output.replace(/&/, 'and');
      this.emit(':ask', output, hearMoreMessage);
    } else {
      this.emit(':ask', noTrailErrorMessage, trailsMoreInfoMessage);
    }
  },
  'AMAZON.YesIntent': function () {
      this.emit(':ask', trailsMoreInfoMessage, trailsMoreInfoMessage);
  },
  'AMAZON.NoIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'AMAZON.StopIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'AMAZON.HelpIntent': function () {
      this.emit(':ask', helpMessage, helpMessage);
  },
  'AMAZON.RepeatIntent': function () {
      this.emit(':ask', output, helpMessage);
  },
  'AMAZON.CancelIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'SessionEndedRequest': function () {
      this.emit('AMAZON.StopIntent');
  },
  'Unhandled': function () {
      this.emit(':ask', helpMessage, welcomeReprompt);
  }
});

function httpsGet(query, callback) {
  var options = {
    host: 'www.mtbproject.com',
    path: '/data/get-trails?lat=' + query[0] + '&lon=' + query[1] + '&key=MTB Project API key here',
    method: 'GET'
  };

  var req = https.request(options, (res) => {
    var body = '';
    res.on('data', (d) => {
      body += d;
    });
    res.on('end', function () {
      callback(body);
    });
  });
  req.end();
  req.on('error', (e) => {
    console.error(e);
  });
}

exports.handler = function (event, context, callback) {
  alexa = Alexa.handler(event, context, callback);
  alexa.registerHandlers(newSessionHandlers, searchHandlers, trailInfoHandlers);
  alexa.execute();
};
<commit_msg>Add trail conditions intent<commit_after>var Alexa = require('alexa-sdk');
var googleMapsClient = require('@google/maps').createClient({
  key: 'Google Maps API Key here'

});
var https = require('https');

var states = {
    SEARCHMODE: '_SEARCHMODE',
    TRAILINFO: '_TRAILINFO',
};

var MTBProjectAPIKey = 'MTB Project API Key here';

var welcomeMessage = "Welcome to MTB Trails. You can ask for trails near a city name and get more information about those trails.";

var welcomeReprompt = "Ask me for trails near any city";

var helpMessage = "Here is something you can ask me: Find me trails near Boulder, Colorado. After that, you can say: give me more information about trail number two, or what are the conditions of trail two. What do you want to do?";

var goodbyeMessage = "Thanks for using MTB trails. See you out on the bike!";

var noCityErrorMessage = "Sorry, I didn't recognize that city name. Please try again.";

var cityConversionErrorMessage = "Something went wrong while looking for trails. Please try again.";

var noTrailErrorMessage = "What trail was that? Please try again.";

var trailsMoreInfoMessage = "You can tell me a number for more information. For example, open number one, or what are the conditions of number one.";

var hearMoreMessage = "Would you like to hear about another trail?";

var numberOfTrails = 3;

var output = "";

var responseData;

var city;

var alexa;

var newSessionHandlers = {
  'LaunchRequest': function () {
      this.handler.state = states.SEARCHMODE;
      this.emit(':ask', welcomeMessage, welcomeReprompt);
  },
  'getTrailsIntent': function () {
      this.handler.state = states.SEARCHMODE;
      this.emitWithState('getTrailsIntent');
  },
  'AMAZON.StopIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'AMAZON.CancelIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'SessionEndedRequest': function () {
      this.emit('AMAZON.StopIntent');
  },
  'Unhandled': function () {
      this.emit(':ask', helpMessage, welcomeReprompt);
  }
};

var searchHandlers = Alexa.CreateStateHandler(states.SEARCHMODE, {
  'getTrailsIntent': function () {
      this.handler.state = states.TRAILINFO;
      city = '';
      var lat = 0;
      var lng = 0;
      if (this.event.request.intent.slots.city) {
          if (this.event.request.intent.slots.city.value) {
              city = this.event.request.intent.slots.city.value;
          }
      }

      if (city) {
        googleMapsClient.geocode({
          address: city
        }, function(err, response) {
          if (!err) {
            console.log(response.json.results);
            console.log(response.json.results[0].geometry);
            lat = parseFloat(response.json.results[0].geometry.location.lat);
            lng = parseFloat(response.json.results[0].geometry.location.lng);
          } else {
            console.error(err);
          }
          if (lat != 0 && lng != 0) {
            var loc = [lat, lng];
            console.log(loc);
            httpsGetTrails(loc, function (response) {
              responseData = JSON.parse(response);
              var cardContent = "Data provided by MTB Project\n\n";

              if (responseData == null) {
                output = "There was a problem getting trail data. Please try again.";
              } else {
                output = "There are " + responseData.trails.length + " trails near " + city + ".";
                if (responseData.trails.length > numberOfTrails) {
                  output += " Here are the top " + numberOfTrails + ".";
                }
                output += " See your Alexa app for more information and more trails. ";

                for (var i = 0; i < responseData.trails.length; i++) {
                  if (i < numberOfTrails) {
                    var name = responseData.trails[i].name;
                    var summary = responseData.trails[i].summary;
                    var difficulty = responseData.trails[i].difficulty;
                    var index = i + 1;
                    output += "Trail " + index + ";";

                    output += name + ". " + summary + " Difficulty: " + difficulty + ";";
                  }
                  cardContent += name + "\n" + summary + "\n" + "Difficulty: " + difficulty + "\n\n";
                }

              }
              var cardTitle = city + " Trails";
              output += "\n" + trailsMoreInfoMessage;
              output = output.replace(/&/, 'and');
              alexa.emit(':askWithCard', output, trailsMoreInfoMessage, cardTitle, cardContent);
            });
          } else {
            alexa.emit(':ask', cityConversionErrorMessage);
          }
        });
      } else {
        this.emit(':ask', noCityErrorMessage);
      }
  },

  'AMAZON.YesIntent': function () {
      this.emit(':ask', helpMessage, helpMessage);
  },
  'AMAZON.NoIntent': function () {
      this.emit(':ask', helpMessage, helpMessage);
  },
  'AMAZON.StopIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'AMAZON.HelpIntent': function () {
      this.emit(':ask', helpMessage, helpMessage);
  },
  'AMAZON.RepeatIntent': function () {
      this.emit(':ask', output, helpMessage);
  },
  'AMAZON.CancelIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'SessionEndedRequest': function () {
      this.emit('AMAZON.StopIntent');
  },
  'Unhandled': function () {
      this.emit(':ask', helpMessage, welcomeReprompt);
  }
});

var trailInfoHandlers = Alexa.CreateStateHandler(states.TRAILINFO, {
  'getTrailsIntent': function () {
    this.handler.state = states.SEARCHMODE;
    this.emitWithState('getTrailsIntent');
  },
  'getMoreInfoIntent': function () {
    var trail = 0;
    if (this.event.request.intent.slots.trail) {
      if (this.event.request.intent.slots.trail.value) {
        trail = this.event.request.intent.slots.trail.value;
      }
    }

    if (trail > 0 && trail <= responseData.trails.length) {
      var selectedTrail = responseData.trails[parseInt(trail) - 1];
      output = selectedTrail.name + ". " + selectedTrail.summary + ';';
      output += " It has " + selectedTrail.stars + " stars and a difficulty rating of " + selectedTrail.difficulty + ". ";
      output += "It is " + selectedTrail.length + " miles long, has " + selectedTrail.ascent + " feet of climbing, and reaches a high point of " + selectedTrail.high + " feet.  ";
      output += hearMoreMessage;
      output = output.replace(/&/, 'and');
      this.emit(':ask', output, hearMoreMessage);
    } else {
      this.emit(':ask', noTrailErrorMessage, trailsMoreInfoMessage);
    }
  },
  'getConditionsIntent': function () {
    var trail = 0;
    if (this.event.request.intent.slots.trail) {
      if (this.event.request.intent.slots.trail.value) {
        trail = this.event.request.intent.slots.trail.value;
      }
    }

    if (trail > 0 && trail <= responseData.trails.length) {
      var id = responseData.trails[trail - 1].id;
      httpsGetConditions(id, function (response) {
        var trailCondition = JSON.parse(response);
        if (trailCondition == null) {
          output = "There was a problem getting trails data. Please try again.";
        } else {
          output = 'As of ' + trailCondition["0"].conditionDate + ', ' + trailCondition["0"].name + ' has a condition of ' + trailCondition["0"].conditionStatus + '. ';
          output += hearMoreMessage;
          alexa.emit(':ask', output, hearMoreMessage);
        }
      });
    } else {
      this.emit(':ask', noTrailErrorMessage, trailsMoreInfoMessage);
    }
  },
  'AMAZON.YesIntent': function () {
      this.emit(':ask', trailsMoreInfoMessage, trailsMoreInfoMessage);
  },
  'AMAZON.NoIntent': function () {
      this.emit(':ask', welcomeReprompt, welcomeReprompt);
  },
  'AMAZON.StopIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'AMAZON.HelpIntent': function () {
      this.emit(':ask', helpMessage, helpMessage);
  },
  'AMAZON.RepeatIntent': function () {
      this.emit(':ask', output, helpMessage);
  },
  'AMAZON.CancelIntent': function () {
      this.emit(':tell', goodbyeMessage);
  },
  'SessionEndedRequest': function () {
      this.emit('AMAZON.StopIntent');
  },
  'Unhandled': function () {
      this.emit(':ask', helpMessage, welcomeReprompt);
  }
});

function httpsGetTrails(query, callback) {
  var options = {
    host: 'www.mtbproject.com',
    path: '/data/get-trails?lat=' + query[0] + '&lon=' + query[1] + '&key=' + MTBProjectAPIKey,
    method: 'GET'
  };

  var req = https.request(options, (res) => {
    var body = '';
    res.on('data', (d) => {
      body += d;
    });
    res.on('end', function () {
      callback(body);
    });
  });
  req.end();
  req.on('error', (e) => {
    console.error(e);
  });
}

function httpsGetConditions(query, callback) {
  var options = {
    host: 'www.mtbproject.com',
    path: '/data/get-conditions?ids=' + query + '&key=' + MTBProjectAPIKey,
    method: 'GET'
  };

  var req = https.request(options, (res) => {
    var body = '';
    res.on('data', (d) => {
      body += d;
    });
    res.on('end', function () {
      callback(body);
    });
  });
  req.end();
  req.on('error', (e) => {
    console.error(e);
  });
}

exports.handler = function (event, context, callback) {
  alexa = Alexa.handler(event, context, callback);
  alexa.registerHandlers(newSessionHandlers, searchHandlers, trailInfoHandlers);
  alexa.execute();
};
<|endoftext|>


<commit_before>var hzLinks = document.getElementsByTagName('a');
for (var i=0, l=hzLinks.length; i < l; i++) {
	hzLinks[i].addEventListener('mouseenter', hzMouseOn, false);
	hzLinks[i].addEventListener('mouseleave', hzMouseOff, false);
}

var hzDiv = document.createElement('div');
hzDiv.id = 'hzDiv';
hzDiv.resize = function(width, height){
	var x = width;
	var y = height;
	var maxX = document.documentElement.clientWidth * window.devicePixelRatio * (self.options.maxSize / 100);
	var maxY = document.documentElement.clientHeight * window.devicePixelRatio * (self.options.maxSize / 100);
	if((x > maxX) || (y > maxY)){
		var rX = maxX / x;
		var rY = maxY / y;
		if(rX < rY){
			x = Math.floor(x * rX);
			y = Math.floor(y * rX);
		}else{
			x = Math.floor(x * rY);
			y = Math.floor(y * rY);
		}
	}
	this.style.width = x+"px";
	this.style.height = y+"px";
	this.style.marginLeft = Math.floor(x / -2)+"px";
	this.style.marginTop = Math.floor(y / -2)+"px";
}
hzDiv.show = function(el){
	switch(el.toLowerCase()){
		case 'image':
			hzVideo.style.display = 'none';
			hzImg.style.display = 'block';
			break;
		case 'video':
			hzImg.style.display = 'none';
			hzVideo.style.display = 'block';
			break;
		default:
			console.log('panel "show" called with no valid options, oops!');
			return;
	}
	this.style.display = 'block';
	hzText.set();
	if(self.options.keys){ window.addEventListener('keydown', hzKey, false) }
	window.addEventListener('scroll', hzMouseOff, false);
	window.addEventListener('wheel', hzWheel, false);
	hzWait = setTimeout( function(){ self.port.emit('visit', hzCurUrl) }, 500);
}
hzDiv.hide = function(){
	window.removeEventListener('keydown', hzKey, false);
	window.removeEventListener('scroll', hzMouseOff, false);
	window.removeEventListener('wheel', hzWheel, false);
	hzDiv.style.display = 'none';
	hzImg.src = null;
	hzVideo.src = null;
}
document.body.appendChild(hzDiv);

var hzImg = document.createElement('img');
hzImg.load = function(url, src) {
	var i = document.createElement('img');
	i.url = url;
	i.addEventListener('load', function(){ hzImg.show(this.url, this.src) });
	i.src = src;
}
hzImg.show = function(url, src){
	if(url == hzCurUrl){
		var i = self.options.delay - (new Date().getTime() - hzMark);
		if(i > 0) {
			hzWait = setTimeout( function(){ hzImg.show(url, src) }, i);
		} else {
			this.src = src;
			hzDiv.show('image');
			hzDiv.resize(this.naturalWidth, this.naturalHeight);
		}
	}
}
hzDiv.appendChild(hzImg);

var hzText = document.createElement('div');
hzText.set = function(){
	while(this.firstChild){ this.removeChild(this.firstChild) }
	if(hzAlbumImgs.length > 1){
		this.appendChild(document.createTextNode((hzAlbumImgIndex+1)+"/"+hzAlbumImgs.length));
	}else{
		this.appendChild(document.createTextNode(""));
	}
}
hzDiv.appendChild(hzText);

var hzVideo = document.createElement('video');
hzVideo.load = function(url, src){
	var v = document.createElement('video');
	v.url = url;
	v.addEventListener('canplay', function(){ hzVideo.show(this.url, this.src) });
	v.src = src;
	v.play();
}
hzVideo.show = function(url, src){
	if(url == hzCurUrl) {
		var i = self.options.delay - (new Date().getTime() - hzMark);
		if(i > 0) {
			hzWait = setTimeout( function(){ hzVideo.show(url, src) }, i);
		} else {
			this.src = src;
			hzDiv.show('video');
		}
	}
}
hzVideo.addEventListener('canplay', function(e){
	hzDiv.resize(this.videoWidth, this.videoHeight);
});
hzVideo.autoplay = true;
hzVideo.loop = true;
hzVideo.muted = true;
hzDiv.appendChild(hzVideo);

function hzKey(e){
	switch(e.keyCode){
		case 37:
			e.deltaY = -1; //left
			break;
		case 39:
			e.deltaY = 1; //right
			break;
	}
	if(e.deltaY){ hzWheel(e) }
}
function hzWheel(e){
	if(hzAlbumImgs.length > 1){
		e.preventDefault();
		e.stopPropagation();
		if(e.deltaY > 0){
			++hzAlbumImgIndex;
			if(hzAlbumImgIndex > hzAlbumImgs.length - 1) { hzAlbumImgIndex = 0 }
		} else if(e.deltaY < 0){
			--hzAlbumImgIndex;
			if(hzAlbumImgIndex < 0){ hzAlbumImgIndex = hzAlbumImgs.length - 1 }
		}
		hzImg.show(hzCurUrl, hzAlbumImgs[hzAlbumImgIndex]);
	}
}

var hzTarget = document.createElement('a');
var hzAlbumImgs, hzAlbumImgIndex, hzCurUrl, hzMark, hzWait;
function hzMouseOn(e){
	if(hzWait){ if(hzWait.abort){ hzWait.abort() }else{ clearTimeout(hzWait) } }
	hzDiv.hide();
	hzCurUrl = '';
	hzAlbumImgs = [];
	if(e){
		hzMark = new Date().getTime();
		hzCurUrl = e.target.toString();
		hzTarget.href = hzCurUrl;
		var p = hzTarget.pathname.split('.').reverse();
		if(/bmp|jpeg|jpg|png/i.test(p[0])){ hzImg.load(hzCurUrl, hzTarget.href) }
		else if(/mp4|webm/i.test(p[0])){ hzVideo.load(hzCurUrl, hzTarget.href) }
		else{
			p = hzTarget.hostname.split('.').reverse();
			switch((p[1]+"."+p[0]).toLowerCase()){
				case 'gfycat.com':
					self.port.emit('load', hzCurUrl, hzTarget.protocol+"//gfycat.com/"+hzTarget.pathname.split('.')[0]);
					break;
				case 'imgflip.com':
					p = hzTarget.pathname.split('/');
					if(p.length > 2){ hzTarget.href = hzTarget.protocol+"//i.imgflip.com/"+p[2].split('#')[0]+".jpg" }
					break;
				case 'imgur.com':
					var alb = "";
	 				p = hzTarget.pathname.split('/');
					switch(p[1].toLowerCase()){
						case 'a':
							alb = "https://api.imgur.com/3/album/"+p[2]
						case 'gallery':
							alb = alb || "https://api.imgur.com/3/gallery/"+p[2]
							hzWait = $.ajax({ src:hzCurUrl, url:alb, type:'GET', datatype:'json', beforeSend:function(h){ h.setRequestHeader('Authorization', 'Client-ID f781dcd19302057') },
								success:function(d){
									var delay = 0;
									if(d['data']['images']){
										$.each(d['data']['images'], function(i,v){
											setTimeout( function(){ new Image().src = v['link'] }, delay);
											delay += 1000;
											hzAlbumImgs.push(v['link']);
										});
									} else if(d['data']['link']){
										hzAlbumImgs.push(d['data']['link']);
									}
									if(hzAlbumImgs.length > 0){
										hzImg.load(this.src, hzAlbumImgs[0]);
										hzAlbumImgIndex = 0;
									}
								}
							});
							return;
					}
					hzTarget.pathname = hzTarget.pathname.split('/').pop();
					hzTarget.href = hzTarget.href.split('?')[0].split(',')[0].split('#')[0];
					if(hzTarget.pathname.split('.').length == 1){ hzTarget.href += ".jpg" }
					switch(hzTarget.pathname.split('.').reverse()[0].toLowerCase()) {
						case 'gif':
							hzTarget.href += "v";
						case 'gifv':
							self.port.emit('load', hzCurUrl, hzTarget.href);
							break;
					}
					break;
				case 'livememe.com':
					hzTarget.href = hzTarget.protocol+"//i.lvme.me"+hzTarget.pathname+".jpg";
					break;
				case 'vidble.com':
					hzWait = $.ajax({ src:hzCurUrl, url:hzTarget.href+'?json=1', type:'GET', datatype:'json',
						success:function(d){
							var delay = 0;
							$.each(d['pics'], function(i,v){
								setTimeout( function(){ new Image().src = v }, delay);
								delay += 1000;
								hzAlbumImgs.push(v);
							});
							if(hzAlbumImgs.length > 0) {
								hzImg.load(this.src, hzAlbumImgs[0]);
								hzAlbumImgIndex = 0;
							}
						}
					});
					return;
				case 'craigslist.org':
				case 'deviantart.com':
				case 'explosm.net':
				case 'facebook.com':
				case 'flic.kr':
				case 'flickr.com':
				case 'gifyoutube.com':
				case 'gyazo.com':
				case 'instagram.com':
				case 'makeameme.org':
				case 'mypixa.com':
				case 'swirl.xyz':
				case 'tumblr.com':
				case 'twitter.com':
				case 'vid.me':
				case 'vine.co':
					self.port.emit('load', hzCurUrl, hzTarget.href);
					break;
			}
			hzImg.load(hzCurUrl, hzTarget.href);
//console.log(hzTarget.href);
		}
	}
}
function hzMouseOff(e){ hzMouseOn(null) }

self.port.on('image', function(url, imgs){
	hzAlbumImgs = imgs;
	hzAlbumImgIndex = 0;
	hzImg.load(url, hzAlbumImgs[0]);
});

self.port.on('video', hzVideo.load);
<commit_msg>fix for image resizing on load<commit_after>var hzLinks = document.getElementsByTagName('a');
for (var i=0, l=hzLinks.length; i < l; i++) {
	hzLinks[i].addEventListener('mouseenter', hzMouseOn, false);
	hzLinks[i].addEventListener('mouseleave', hzMouseOff, false);
}

var hzDiv = document.createElement('div');
hzDiv.id = 'hzDiv';
hzDiv.resize = function(width, height){
	var x = width;
	var y = height;
	var maxX = document.documentElement.clientWidth * window.devicePixelRatio * (self.options.maxSize / 100);
	var maxY = document.documentElement.clientHeight * window.devicePixelRatio * (self.options.maxSize / 100);
	if((x > maxX) || (y > maxY)){
		var rX = maxX / x;
		var rY = maxY / y;
		if(rX < rY){
			x = Math.floor(x * rX);
			y = Math.floor(y * rX);
		}else{
			x = Math.floor(x * rY);
			y = Math.floor(y * rY);
		}
	}
	this.style.width = x+"px";
	this.style.height = y+"px";
	this.style.marginLeft = Math.floor(x / -2)+"px";
	this.style.marginTop = Math.floor(y / -2)+"px";
}
hzDiv.show = function(el){
	switch(el.toLowerCase()){
		case 'image':
			hzVideo.style.display = 'none';
			hzImg.style.display = 'block';
			break;
		case 'video':
			hzImg.style.display = 'none';
			hzVideo.style.display = 'block';
			break;
		default:
			console.log('panel "show" called with no valid options, oops!');
			return;
	}
	this.style.display = 'block';
	hzText.set();
	if(self.options.keys){ window.addEventListener('keydown', hzKey, false) }
	window.addEventListener('scroll', hzMouseOff, false);
	window.addEventListener('wheel', hzWheel, false);
	hzWait = setTimeout( function(){ self.port.emit('visit', hzCurUrl) }, 500);
}
hzDiv.hide = function(){
	window.removeEventListener('keydown', hzKey, false);
	window.removeEventListener('scroll', hzMouseOff, false);
	window.removeEventListener('wheel', hzWheel, false);
	hzDiv.style.display = 'none';
	hzImg.src = null;
	hzVideo.src = null;
}
document.body.appendChild(hzDiv);

var hzImg = document.createElement('img');
hzImg.load = function(url, src) {
	var i = document.createElement('img');
	i.url = url;
	i.addEventListener('load', function(){ hzImg.show(this.url, this.src) });
	i.src = src;
}
hzImg.show = function(url, src){
	if(url == hzCurUrl){
		var i = self.options.delay - (new Date().getTime() - hzMark);
		if(i > 0) {
			hzWait = setTimeout( function(){ hzImg.show(url, src) }, i);
		} else {
			this.src = src;
			hzDiv.show('image');
		}
	}
}
hzImg.addEventListener('load', function(e){
	hzDiv.resize(this.naturalWidth, this.naturalHeight);
});
hzDiv.appendChild(hzImg);

var hzText = document.createElement('div');
hzText.set = function(){
	while(this.firstChild){ this.removeChild(this.firstChild) }
	if(hzAlbumImgs.length > 1){
		this.appendChild(document.createTextNode((hzAlbumImgIndex+1)+"/"+hzAlbumImgs.length));
	}else{
		this.appendChild(document.createTextNode(""));
	}
}
hzDiv.appendChild(hzText);

var hzVideo = document.createElement('video');
hzVideo.load = function(url, src){
	var v = document.createElement('video');
	v.url = url;
	v.addEventListener('canplay', function(){ hzVideo.show(this.url, this.src) });
	v.src = src;
	v.play();
}
hzVideo.show = function(url, src){
	if(url == hzCurUrl) {
		var i = self.options.delay - (new Date().getTime() - hzMark);
		if(i > 0) {
			hzWait = setTimeout( function(){ hzVideo.show(url, src) }, i);
		} else {
			this.src = src;
			hzDiv.show('video');
		}
	}
}
hzVideo.addEventListener('canplay', function(e){
	hzDiv.resize(this.videoWidth, this.videoHeight);
});
hzVideo.autoplay = true;
hzVideo.loop = true;
hzVideo.muted = true;
hzDiv.appendChild(hzVideo);

function hzKey(e){
	switch(e.keyCode){
		case 37:
			e.deltaY = -1; //left
			break;
		case 39:
			e.deltaY = 1; //right
			break;
	}
	if(e.deltaY){ hzWheel(e) }
}
function hzWheel(e){
	if(hzAlbumImgs.length > 1){
		e.preventDefault();
		e.stopPropagation();
		if(e.deltaY > 0){
			++hzAlbumImgIndex;
			if(hzAlbumImgIndex > hzAlbumImgs.length - 1) { hzAlbumImgIndex = 0 }
		} else if(e.deltaY < 0){
			--hzAlbumImgIndex;
			if(hzAlbumImgIndex < 0){ hzAlbumImgIndex = hzAlbumImgs.length - 1 }
		}
		hzImg.show(hzCurUrl, hzAlbumImgs[hzAlbumImgIndex]);
	}
}

var hzTarget = document.createElement('a');
var hzAlbumImgs, hzAlbumImgIndex, hzCurUrl, hzMark, hzWait;
function hzMouseOn(e){
	if(hzWait){ if(hzWait.abort){ hzWait.abort() }else{ clearTimeout(hzWait) } }
	hzDiv.hide();
	hzCurUrl = '';
	hzAlbumImgs = [];
	if(e){
		hzMark = new Date().getTime();
		hzCurUrl = e.target.toString();
		hzTarget.href = hzCurUrl;
		var p = hzTarget.pathname.split('.').reverse();
		if(/bmp|jpeg|jpg|png/i.test(p[0])){ hzImg.load(hzCurUrl, hzTarget.href) }
		else if(/mp4|webm/i.test(p[0])){ hzVideo.load(hzCurUrl, hzTarget.href) }
		else{
			p = hzTarget.hostname.split('.').reverse();
			switch((p[1]+"."+p[0]).toLowerCase()){
				case 'gfycat.com':
					self.port.emit('load', hzCurUrl, hzTarget.protocol+"//gfycat.com/"+hzTarget.pathname.split('.')[0]);
					break;
				case 'imgflip.com':
					p = hzTarget.pathname.split('/');
					if(p.length > 2){ hzTarget.href = hzTarget.protocol+"//i.imgflip.com/"+p[2].split('#')[0]+".jpg" }
					break;
				case 'imgur.com':
					var alb = "";
	 				p = hzTarget.pathname.split('/');
					switch(p[1].toLowerCase()){
						case 'a':
							alb = "https://api.imgur.com/3/album/"+p[2]
						case 'gallery':
							alb = alb || "https://api.imgur.com/3/gallery/"+p[2]
							hzWait = $.ajax({ src:hzCurUrl, url:alb, type:'GET', datatype:'json', beforeSend:function(h){ h.setRequestHeader('Authorization', 'Client-ID f781dcd19302057') },
								success:function(d){
									var delay = 0;
									if(d['data']['images']){
										$.each(d['data']['images'], function(i,v){
											setTimeout( function(){ new Image().src = v['link'] }, delay);
											delay += 1000;
											hzAlbumImgs.push(v['link']);
										});
									} else if(d['data']['link']){
										hzAlbumImgs.push(d['data']['link']);
									}
									if(hzAlbumImgs.length > 0){
										hzImg.load(this.src, hzAlbumImgs[0]);
										hzAlbumImgIndex = 0;
									}
								}
							});
							return;
					}
					hzTarget.pathname = hzTarget.pathname.split('/').pop();
					hzTarget.href = hzTarget.href.split('?')[0].split(',')[0].split('#')[0];
					if(hzTarget.pathname.split('.').length == 1){ hzTarget.href += ".jpg" }
					switch(hzTarget.pathname.split('.').reverse()[0].toLowerCase()) {
						case 'gif':
							hzTarget.href += "v";
						case 'gifv':
							self.port.emit('load', hzCurUrl, hzTarget.href);
							break;
					}
					break;
				case 'livememe.com':
					hzTarget.href = hzTarget.protocol+"//i.lvme.me"+hzTarget.pathname+".jpg";
					break;
				case 'vidble.com':
					hzWait = $.ajax({ src:hzCurUrl, url:hzTarget.href+'?json=1', type:'GET', datatype:'json',
						success:function(d){
							var delay = 0;
							$.each(d['pics'], function(i,v){
								setTimeout( function(){ new Image().src = v }, delay);
								delay += 1000;
								hzAlbumImgs.push(v);
							});
							if(hzAlbumImgs.length > 0) {
								hzImg.load(this.src, hzAlbumImgs[0]);
								hzAlbumImgIndex = 0;
							}
						}
					});
					return;
				case 'craigslist.org':
				case 'deviantart.com':
				case 'explosm.net':
				case 'facebook.com':
				case 'flic.kr':
				case 'flickr.com':
				case 'gifyoutube.com':
				case 'gyazo.com':
				case 'instagram.com':
				case 'makeameme.org':
				case 'mypixa.com':
				case 'swirl.xyz':
				case 'tumblr.com':
				case 'twitter.com':
				case 'vid.me':
				case 'vine.co':
					self.port.emit('load', hzCurUrl, hzTarget.href);
					break;
			}
			hzImg.load(hzCurUrl, hzTarget.href);
//console.log(hzTarget.href);
		}
	}
}
function hzMouseOff(e){ hzMouseOn(null) }

self.port.on('image', function(url, imgs){
	hzAlbumImgs = imgs;
	hzAlbumImgIndex = 0;
	hzImg.load(url, hzAlbumImgs[0]);
});

self.port.on('video', hzVideo.load);
<|endoftext|>


<commit_before><commit_msg>Setup the `jmp` sockets<commit_after>import * as jmp from 'jmp';
import * as uuid from 'uuid';

function formConnectionString(config, channel) {
  const portDelimiter = config.transport === 'tcp' ? ':' : '-';
  const port = config[channel + '_port'];
  if (! port) {
    throw new Error(`Port not found for channel "${channel}"`);
  }
  return `${config.transport}://${config.ip}${portDelimiter}${port}`;
}

function sendMessage(socket, messageObject) {
  const message = new jmp.Message(messageObject);
  socket.send(message);
}

export default class EnchannelZMQ {
  constructor(config) {
    const scheme = config.signature_scheme.slice('hmac-'.length);

    this.shellSocket = new jmp.Socket('dealer', scheme, config.key);
    this.controlSocket = new jmp.Socket('dealer', scheme, config.key);
    this.ioSocket = new jmp.Socket('sub', config.signature_scheme, config.key);

    this.shellSocket.identity = 'dealer' + uuid.v4();
    this.controlSocket.identity = 'control' + uuid.v4();
    this.ioSocket.identity = 'sub' + uuid.v4();

    this.shellSocket.connect(formConnectionString(config, 'shell'));
    this.controlSocket.connect(formConnectionString(config, 'control'));
    this.ioSocket.connect(formConnectionString(config, 'iopub'));

    this.ioSocket.subscribe('');
  }

  dispose() {
    this.shellSocket.close();
    this.ioSocket.close();
    this.controlSocket.close();
  }
}
<|endoftext|>


<commit_before>// Copyright 2016 wkh237@github. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// @flow

import {
  NativeModules,
  DeviceEventEmitter,
  NativeAppEventEmitter,
  Platform,
  AsyncStorage,
} from 'react-native'
import type {
  RNFetchBlobNative,
  RNFetchBlobConfig,
  RNFetchBlobStream,
  RNFetchBlobResponseInfo
} from './types'
import StatefulPromise from './class/StatefulPromise.js'
import fs from './fs'
import getUUID from './utils/uuid'
import base64 from 'base-64'
import polyfill from './polyfill'
import android from './android'
const {
  RNFetchBlobSession,
  readStream,
  createFile,
  unlink,
  exists,
  mkdir,
  session,
  writeStream,
  readFile,
  ls,
  isDir,
  mv,
  cp
} = fs

const Blob = polyfill.Blob
const emitter = DeviceEventEmitter
const RNFetchBlob:RNFetchBlobNative = NativeModules.RNFetchBlob

// register message channel event handler.
emitter.addListener("RNFetchBlobMessage", (e) => {
  if(e.event === 'warn') {
    console.warn(e.detail)
  }
  else if (e.event === 'error') {
    throw e.detail
  }
  else {
    console.log("RNFetchBlob native message", e.detail)
  }
})

// Show warning if native module not detected
if(!RNFetchBlob || !RNFetchBlob.fetchBlobForm || !RNFetchBlob.fetchBlob) {
  console.warn(
    'react-native-fetch-blob could not find valid native module.',
    'please make sure you have linked native modules using `rnpm link`,',
    'and restart RN packager or manually compile IOS/Android project.'
  )
}

function wrap(path:string):string {
  return 'RNFetchBlob-file://' + path
}

/**
 * Calling this method will inject configurations into followed `fetch` method.
 * @param  {RNFetchBlobConfig} options
 *         Fetch API configurations, contains the following options :
 *         @property {boolean} fileCache
 *                   When fileCache is `true`, response data will be saved in
 *                   storage with a random generated file name, rather than
 *                   a BASE64 encoded string.
 *         @property {string} appendExt
 *                   Set this property to change file extension of random-
 *                   generated file name.
 *         @property {string} path
 *                   If this property has a valid string format, resonse data
 *                   will be saved to specific file path. Default string format
 *                   is : `RNFetchBlob-file://path-to-file`
 *         @property {string} key
 *                   If this property is set, it will be converted to md5, to
 *                   check if a file with this name exists.
 *                   If it exists, the absolute path is returned (no network
 *                   activity takes place )
 *                   If it doesn't exist, the file is downloaded as usual
 *         @property {number} timeout
 *                   Request timeout in millionseconds, by default it's 30000ms.
 *
 * @return {function} This method returns a `fetch` method instance.
 */
function config (options:RNFetchBlobConfig) {
  return { fetch : fetch.bind(options) }
}

/**
 * Create a HTTP request by settings, the `this` context is a `RNFetchBlobConfig` object.
 * @param  {string} method HTTP method, should be `GET`, `POST`, `PUT`, `DELETE`
 * @param  {string} url Request target url string.
 * @param  {object} headers HTTP request headers.
 * @param  {string} body
 *         Request body, can be either a BASE64 encoded data string,
 *         or a file path with prefix `RNFetchBlob-file://` (can be changed)
 * @return {Promise}
 *         This promise instance also contains a Customized method `progress`for
 *         register progress event handler.
 */
function fetch(...args:any):Promise {

  // create task ID for receiving progress event
  let taskId = getUUID()
  let options = this || {}
  let subscription, subscriptionUpload, stateEvent
  let respInfo = {}

  let promise = new Promise((resolve, reject) => {
    let [method, url, headers, body] = [...args]
    let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob'

    // on progress event listener
    subscription = emitter.addListener('RNFetchBlobProgress', (e) => {
      if(e.taskId === taskId && promise.onProgress) {
        promise.onProgress(e.written, e.total)
      }
    })

    subscriptionUpload = emitter.addListener('RNFetchBlobProgress-upload', (e) => {
      if(e.taskId === taskId && promise.onUploadProgress) {
        promise.onUploadProgress(e.written, e.total)
      }
    })

    stateEvent = emitter.addListener('RNFetchBlobState', (e) => {
      respInfo = e
      if(e.taskId === taskId && promise.onStateChange) {
        promise.onStateChange(e)
      }
    })

    // When the request body comes from Blob polyfill, we should use special its ref
    // as the request body
    if( body instanceof Blob && body.isRNFetchBlobPolyfill) {
      body = body.getRNFetchBlobRef()
    }

    let req = RNFetchBlob[nativeMethodName]

    /**
     * Send request via native module, the response callback accepts three arguments
     * @callback
     * @param err {any} Error message or object, when the request success, this
     *                  parameter should be `null`.
     * @param rawType { 'utf8' | 'base64' | 'path'} RNFB request will be stored
     *                  as UTF8 string, BASE64 string, or a file path reference
     *                  in JS context, and this parameter indicates which one
     *                  dose the response data presents.
     * @param data {string} Response data or its reference.
     */
    req(options, taskId, method, url, headers || {}, body, (err, rawType, data) => {

      // task done, remove event listeners
      subscription.remove()
      subscriptionUpload.remove()
      stateEvent.remove()
      delete promise['progress']
      delete promise['uploadProgress']
      delete promise['stateChange']
      delete promise['cancel']
      promise.cancel = () => {}

      if(err)
        reject(new Error(err, respInfo))
      else {
        // response data is saved to storage, create a session for it
        if(options.path || options.fileCache || options.addAndroidDownloads
          || options.key || options.auto && respInfo.respType === 'blob') {
          if(options.session)
            session(options.session).add(data)
        }
        respInfo.rnfbEncode = rawType
        resolve(new FetchBlobResponse(taskId, respInfo, data))
      }

    })

  })

  // extend Promise object, add `progress`, `uploadProgress`, and `cancel`
  // method for register progress event handler and cancel request.
  // Add second parameter for performance purpose #140
  // When there's only one argument pass to this method, use default `interval`
  // and `count`, otherwise use the given on.
  // TODO : code refactor, move `uploadProgress` and `progress` to StatefulPromise
  promise.progress = (...args) => {
    let interval = 250
    let count = -1
    let fn = () => {}
    if(args.length === 2) {
      interval = args[0].interval
      interval = args[0].count
      fn = args[1]
    }
    else {
      fn = args[0]
    }
    promise.onProgress = fn
    RNFetchBlob.enableProgressReport(taskId, interval, count)
    return promise
  }
  promise.uploadProgress = (...args) => {
    let interval = 250
    let count = -1
    let fn = () => {}
    if(args.length === 2) {
      interval = args[0].interval
      interval = args[0].count
      fn = args[1]
    }
    else {
      fn = args[0]
    }
    promise.onUploadProgress = fn
    RNFetchBlob.enableUploadProgressReport(taskId, interval, count)
    return promise
  }
  promise.stateChange = (fn) => {
    promise.onStateChange = fn
    return promise
  }
  promise.cancel = (fn) => {
    fn = fn || function(){}
    subscription.remove()
    subscriptionUpload.remove()
    stateEvent.remove()
    RNFetchBlob.cancelRequest(taskId, fn)
  }
  promise.taskId = taskId

  return promise

}

/**
 * RNFetchBlob response object class.
 */
class FetchBlobResponse {

  taskId : string;
  path : () => string | null;
  type : 'base64' | 'path' | 'utf8';
  data : any;
  blob : (contentType:string, sliceSize:number) => Promise<Blob>;
  text : () => string | Promise<any>;
  json : () => any;
  base64 : () => any;
  flush : () => void;
  respInfo : RNFetchBlobResponseInfo;
  session : (name:string) => RNFetchBlobSession | null;
  readFile : (encode: 'base64' | 'utf8' | 'ascii') => ?Promise<any>;
  readStream : (
    encode: 'utf8' | 'ascii' | 'base64',
  ) => RNFetchBlobStream | null;

  constructor(taskId:string, info:RNFetchBlobResponseInfo, data:any) {
    this.data = data
    this.taskId = taskId
    this.type = info.rnfbEncode
    this.respInfo = info

    this.info = ():RNFetchBlobResponseInfo => {
      return this.respInfo
    }
    /**
     * Convert result to javascript RNFetchBlob object.
     * @return {Promise<Blob>} Return a promise resolves Blob object.
     */
    this.blob = ():Promise<Blob> => {
      let Blob = polyfill.Blob
      let cType = info.headers['Content-Type'] || info.headers['content-type']
      return new Promise((resolve, reject) => {
        switch(this.type) {
          case 'base64':
            Blob.build(this.data, { type : cType + ';BASE64' }).then(resolve)
          break
          case 'path':
            polyfill.Blob.build(wrap(this.data), { type : cType }).then(resolve)
          break
          default:
            polyfill.Blob.build(this.data, { type : 'text/plain' }).then(resolve)
          break
        }
      })
    }
    /**
     * Convert result to text.
     * @return {string} Decoded base64 string.
     */
    this.text = ():string | Promise<any> => {
      let res = this.data
      switch(this.type) {
        case 'base64':
          return base64.decode(this.data)
        case 'path':
          return fs.readFile(this.data, 'base64').then((b64) => Promise.resolve(base64.decode(b64)))
        default:
          return this.data
      }
    }
    /**
     * Convert result to JSON object.
     * @return {object} Parsed javascript object.
     */
    this.json = ():any => {
      switch(this.type) {
        case 'base64':
          return JSON.parse(base64.decode(this.data))
        case 'path':
          return fs.readFile(this.data, 'utf8')
                   .then((text) => Promise.resolve(JSON.parse(text)))
        default:
          return JSON.parse(this.data)
      }
    }
    /**
     * Return BASE64 string directly.
     * @return {string} BASE64 string of response body.
     */
    this.base64 = ():string | Promise<any> => {
      switch(this.type) {
        case 'base64':
          return this.data
        case 'path':
          return fs.readFile(this.data, 'base64')
        default:
          return base64.encode(this.data)
      }
    }
    /**
     * Remove cahced file
     * @return {Promise}
     */
    this.flush = () => {
      let path = this.path()
      if(!path || this.type !== 'path')
        return
      return unlink(path)
    }
    /**
     * get path of response temp file
     * @return {string} File path of temp file.
     */
    this.path = () => {
      if(this.type === 'path')
        return this.data
      return null
    }

    this.session = (name:string):RNFetchBlobSession | null => {
      if(this.type === 'path')
        return session(name).add(this.data)
      else {
        console.warn('only file paths can be add into session.')
        return null
      }
    }
    /**
     * Start read stream from cached file
     * @param  {String} encoding Encode type, should be one of `base64`, `ascrii`, `utf8`.
     * @param  {Function} fn On data event handler
     * @return {void}
     */
    this.readStream = (encode: 'base64' | 'utf8' | 'ascii'):RNFetchBlobStream | null => {
      if(this.type === 'path') {
        return readStream(this.data, encode)
      }
      else {
        console.warn('RNFetchblob', 'this response data does not contains any available stream')
        return null
      }
    }
    /**
     * Read file content with given encoding, if the response does not contains
     * a file path, show warning message
     * @param  {String} encoding Encode type, should be one of `base64`, `ascrii`, `utf8`.
     * @return {String}
     */
    this.readFile = (encode: 'base64' | 'utf8' | 'ascii') => {
      if(this.type === 'path') {
        encode = encode || 'utf8'
        return readFile(this.data, encode)
      }
      else {
        console.warn('RNFetchblob', 'this response does not contains a readable file')
        return null
      }
    }
  }

}

export default {
  fetch,
  base64,
  android,
  config,
  session,
  fs,
  wrap,
  polyfill
}
<commit_msg>Add #140 JS implementation, support interval and division for progress event<commit_after>// Copyright 2016 wkh237@github. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// @flow

import {
  NativeModules,
  DeviceEventEmitter,
  NativeAppEventEmitter,
  Platform,
  AsyncStorage,
} from 'react-native'
import type {
  RNFetchBlobNative,
  RNFetchBlobConfig,
  RNFetchBlobStream,
  RNFetchBlobResponseInfo
} from './types'
import StatefulPromise from './class/StatefulPromise.js'
import fs from './fs'
import getUUID from './utils/uuid'
import base64 from 'base-64'
import polyfill from './polyfill'
import android from './android'
const {
  RNFetchBlobSession,
  readStream,
  createFile,
  unlink,
  exists,
  mkdir,
  session,
  writeStream,
  readFile,
  ls,
  isDir,
  mv,
  cp
} = fs

const Blob = polyfill.Blob
const emitter = DeviceEventEmitter
const RNFetchBlob:RNFetchBlobNative = NativeModules.RNFetchBlob

// register message channel event handler.
emitter.addListener("RNFetchBlobMessage", (e) => {
  if(e.event === 'warn') {
    console.warn(e.detail)
  }
  else if (e.event === 'error') {
    throw e.detail
  }
  else {
    console.log("RNFetchBlob native message", e.detail)
  }
})

// Show warning if native module not detected
if(!RNFetchBlob || !RNFetchBlob.fetchBlobForm || !RNFetchBlob.fetchBlob) {
  console.warn(
    'react-native-fetch-blob could not find valid native module.',
    'please make sure you have linked native modules using `rnpm link`,',
    'and restart RN packager or manually compile IOS/Android project.'
  )
}

function wrap(path:string):string {
  return 'RNFetchBlob-file://' + path
}

/**
 * Calling this method will inject configurations into followed `fetch` method.
 * @param  {RNFetchBlobConfig} options
 *         Fetch API configurations, contains the following options :
 *         @property {boolean} fileCache
 *                   When fileCache is `true`, response data will be saved in
 *                   storage with a random generated file name, rather than
 *                   a BASE64 encoded string.
 *         @property {string} appendExt
 *                   Set this property to change file extension of random-
 *                   generated file name.
 *         @property {string} path
 *                   If this property has a valid string format, resonse data
 *                   will be saved to specific file path. Default string format
 *                   is : `RNFetchBlob-file://path-to-file`
 *         @property {string} key
 *                   If this property is set, it will be converted to md5, to
 *                   check if a file with this name exists.
 *                   If it exists, the absolute path is returned (no network
 *                   activity takes place )
 *                   If it doesn't exist, the file is downloaded as usual
 *         @property {number} timeout
 *                   Request timeout in millionseconds, by default it's 30000ms.
 *
 * @return {function} This method returns a `fetch` method instance.
 */
function config (options:RNFetchBlobConfig) {
  return { fetch : fetch.bind(options) }
}

/**
 * Create a HTTP request by settings, the `this` context is a `RNFetchBlobConfig` object.
 * @param  {string} method HTTP method, should be `GET`, `POST`, `PUT`, `DELETE`
 * @param  {string} url Request target url string.
 * @param  {object} headers HTTP request headers.
 * @param  {string} body
 *         Request body, can be either a BASE64 encoded data string,
 *         or a file path with prefix `RNFetchBlob-file://` (can be changed)
 * @return {Promise}
 *         This promise instance also contains a Customized method `progress`for
 *         register progress event handler.
 */
function fetch(...args:any):Promise {

  // create task ID for receiving progress event
  let taskId = getUUID()
  let options = this || {}
  let subscription, subscriptionUpload, stateEvent
  let respInfo = {}

  let promise = new Promise((resolve, reject) => {
    let [method, url, headers, body] = [...args]
    let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob'

    // on progress event listener
    subscription = emitter.addListener('RNFetchBlobProgress', (e) => {
      if(e.taskId === taskId && promise.onProgress) {
        promise.onProgress(e.written, e.total)
      }
    })

    subscriptionUpload = emitter.addListener('RNFetchBlobProgress-upload', (e) => {
      if(e.taskId === taskId && promise.onUploadProgress) {
        promise.onUploadProgress(e.written, e.total)
      }
    })

    stateEvent = emitter.addListener('RNFetchBlobState', (e) => {
      respInfo = e
      if(e.taskId === taskId && promise.onStateChange) {
        promise.onStateChange(e)
      }
    })

    // When the request body comes from Blob polyfill, we should use special its ref
    // as the request body
    if( body instanceof Blob && body.isRNFetchBlobPolyfill) {
      body = body.getRNFetchBlobRef()
    }

    let req = RNFetchBlob[nativeMethodName]

    /**
     * Send request via native module, the response callback accepts three arguments
     * @callback
     * @param err {any} Error message or object, when the request success, this
     *                  parameter should be `null`.
     * @param rawType { 'utf8' | 'base64' | 'path'} RNFB request will be stored
     *                  as UTF8 string, BASE64 string, or a file path reference
     *                  in JS context, and this parameter indicates which one
     *                  dose the response data presents.
     * @param data {string} Response data or its reference.
     */
    req(options, taskId, method, url, headers || {}, body, (err, rawType, data) => {

      // task done, remove event listeners
      subscription.remove()
      subscriptionUpload.remove()
      stateEvent.remove()
      delete promise['progress']
      delete promise['uploadProgress']
      delete promise['stateChange']
      delete promise['cancel']
      promise.cancel = () => {}

      if(err)
        reject(new Error(err, respInfo))
      else {
        // response data is saved to storage, create a session for it
        if(options.path || options.fileCache || options.addAndroidDownloads
          || options.key || options.auto && respInfo.respType === 'blob') {
          if(options.session)
            session(options.session).add(data)
        }
        respInfo.rnfbEncode = rawType
        resolve(new FetchBlobResponse(taskId, respInfo, data))
      }

    })

  })

  // extend Promise object, add `progress`, `uploadProgress`, and `cancel`
  // method for register progress event handler and cancel request.
  // Add second parameter for performance purpose #140
  // When there's only one argument pass to this method, use default `interval`
  // and `count`, otherwise use the given on.
  // TODO : code refactor, move `uploadProgress` and `progress` to StatefulPromise
  promise.progress = (...args) => {
    let interval = 250
    let count = -1
    let fn = () => {}
    if(args.length === 2) {
      interval = args[0].interval || interval
      count = args[0].count || count
      fn = args[1]
    }
    else {
      fn = args[0]
    }
    promise.onProgress = fn
    RNFetchBlob.enableProgressReport(taskId, interval, count)
    return promise
  }
  promise.uploadProgress = (...args) => {
    let interval = 250
    let count = -1
    let fn = () => {}
    if(args.length === 2) {
      interval = args[0].interval || interval
      count = args[0].count || count
      fn = args[1]
    }
    else {
      fn = args[0]
    }
    promise.onUploadProgress = fn
    RNFetchBlob.enableUploadProgressReport(taskId, interval, count)
    return promise
  }
  promise.stateChange = (fn) => {
    promise.onStateChange = fn
    return promise
  }
  promise.cancel = (fn) => {
    fn = fn || function(){}
    subscription.remove()
    subscriptionUpload.remove()
    stateEvent.remove()
    RNFetchBlob.cancelRequest(taskId, fn)
  }
  promise.taskId = taskId

  return promise

}

/**
 * RNFetchBlob response object class.
 */
class FetchBlobResponse {

  taskId : string;
  path : () => string | null;
  type : 'base64' | 'path' | 'utf8';
  data : any;
  blob : (contentType:string, sliceSize:number) => Promise<Blob>;
  text : () => string | Promise<any>;
  json : () => any;
  base64 : () => any;
  flush : () => void;
  respInfo : RNFetchBlobResponseInfo;
  session : (name:string) => RNFetchBlobSession | null;
  readFile : (encode: 'base64' | 'utf8' | 'ascii') => ?Promise<any>;
  readStream : (
    encode: 'utf8' | 'ascii' | 'base64',
  ) => RNFetchBlobStream | null;

  constructor(taskId:string, info:RNFetchBlobResponseInfo, data:any) {
    this.data = data
    this.taskId = taskId
    this.type = info.rnfbEncode
    this.respInfo = info

    this.info = ():RNFetchBlobResponseInfo => {
      return this.respInfo
    }

    this.array = ():Promise<Array> => {
      let cType = info.headers['Content-Type'] || info.headers['content-type']
      return new Promise((resolve, reject) => {
        switch(this.type) {
          case 'base64':
            // TODO : base64 to array buffer
          break
          case 'path':
            fs.readFile(this.data, 'ascii').then(resolve)
          break
          default:
            // TODO : text to array buffer
          break
        }
      })
    }

    /**
     * Convert result to javascript RNFetchBlob object.
     * @return {Promise<Blob>} Return a promise resolves Blob object.
     */
    this.blob = ():Promise<Blob> => {
      let Blob = polyfill.Blob
      let cType = info.headers['Content-Type'] || info.headers['content-type']
      return new Promise((resolve, reject) => {
        switch(this.type) {
          case 'base64':
            Blob.build(this.data, { type : cType + ';BASE64' }).then(resolve)
          break
          case 'path':
            polyfill.Blob.build(wrap(this.data), { type : cType }).then(resolve)
          break
          default:
            polyfill.Blob.build(this.data, { type : 'text/plain' }).then(resolve)
          break
        }
      })
    }
    /**
     * Convert result to text.
     * @return {string} Decoded base64 string.
     */
    this.text = ():string | Promise<any> => {
      let res = this.data
      switch(this.type) {
        case 'base64':
          return base64.decode(this.data)
        case 'path':
          return fs.readFile(this.data, 'base64').then((b64) => Promise.resolve(base64.decode(b64)))
        default:
          return this.data
      }
    }
    /**
     * Convert result to JSON object.
     * @return {object} Parsed javascript object.
     */
    this.json = ():any => {
      switch(this.type) {
        case 'base64':
          return JSON.parse(base64.decode(this.data))
        case 'path':
          return fs.readFile(this.data, 'utf8')
                   .then((text) => Promise.resolve(JSON.parse(text)))
        default:
          return JSON.parse(this.data)
      }
    }
    /**
     * Return BASE64 string directly.
     * @return {string} BASE64 string of response body.
     */
    this.base64 = ():string | Promise<any> => {
      switch(this.type) {
        case 'base64':
          return this.data
        case 'path':
          return fs.readFile(this.data, 'base64')
        default:
          return base64.encode(this.data)
      }
    }
    /**
     * Remove cahced file
     * @return {Promise}
     */
    this.flush = () => {
      let path = this.path()
      if(!path || this.type !== 'path')
        return
      return unlink(path)
    }
    /**
     * get path of response temp file
     * @return {string} File path of temp file.
     */
    this.path = () => {
      if(this.type === 'path')
        return this.data
      return null
    }

    this.session = (name:string):RNFetchBlobSession | null => {
      if(this.type === 'path')
        return session(name).add(this.data)
      else {
        console.warn('only file paths can be add into session.')
        return null
      }
    }
    /**
     * Start read stream from cached file
     * @param  {String} encoding Encode type, should be one of `base64`, `ascrii`, `utf8`.
     * @param  {Function} fn On data event handler
     * @return {void}
     */
    this.readStream = (encode: 'base64' | 'utf8' | 'ascii'):RNFetchBlobStream | null => {
      if(this.type === 'path') {
        return readStream(this.data, encode)
      }
      else {
        console.warn('RNFetchblob', 'this response data does not contains any available stream')
        return null
      }
    }
    /**
     * Read file content with given encoding, if the response does not contains
     * a file path, show warning message
     * @param  {String} encoding Encode type, should be one of `base64`, `ascrii`, `utf8`.
     * @return {String}
     */
    this.readFile = (encode: 'base64' | 'utf8' | 'ascii') => {
      if(this.type === 'path') {
        encode = encode || 'utf8'
        return readFile(this.data, encode)
      }
      else {
        console.warn('RNFetchblob', 'this response does not contains a readable file')
        return null
      }
    }
  }

}

export default {
  fetch,
  base64,
  android,
  config,
  session,
  fs,
  wrap,
  polyfill
}
<|endoftext|>


<commit_before>import path from 'path';

const errors = [];

import { assign, exists } from './utils';

function getPackageJson(dir) {
  const pkg = path.join(dir, 'package.json')
  return exists(pkg) ? require(pkg) : false
}

function getRoot () {
  let pkgJson = false;

  if (__dirname.indexOf('node_modules') !== -1) {
    let dir = module.id;

    while (path.basename(dir) !== 'node_modules') {
      dir = path.dirname(dir);
    }
    return { rootPath: path.dirname(dir), pkgJson };
  }

  let dir = module;

  while (dir.parent && !pkgJson) {
    dir = dir.parent;
    pkgJson = getPackageJson(path.dirname(dir.filename));
  }
  return { rootPath: path.dirname(dir.filename), pkgJson };
}

function getBaseInfo () {
  const { rootPath, pkgJson } = getRoot();

  return {
    env: process.env.NODE_ENV || 'development',
    root: rootPath,
    pkgJson: pkgJson || getPackageJson(rootPath)
  };
}

function deling () {
  const { env, root, pkgJson } = getBaseInfo();

  const config = {
    root,
    env,
    name: pkgJson.name || '',
    version: pkgJson.version || ''
  };

  const files = [];

  // Located in config-directory
  if (exists(path.join(root, 'config'))) {
    files.push(
      path.join(root, 'config', 'default'),
      path.join(root, 'config', env),
      path.join(root, 'config', 'local')
    );
  }
  // Located in root
  else {
    files.push(
      path.join(root, 'config'),
      path.join(root, 'config.' + env),
      path.join(root, 'config.local')
    );
  }

  function readFile (file) {
    try {
      return require(file);
    }
    catch (err) {
      errors.push(err);
      return {};
    }
  }

  files.map(readFile).reduce(assign, config);

  return config;
}

const config = deling();

export default config;

export function includePkgJson( key = 'pkgJson' ) {
  config[key] = getBaseInfo().pkgJson;
}

export function getErrors() {
  return errors;
}

<commit_msg>src: assign getErrors and includePkgJson directly to the config object for es5 comp.<commit_after>import path from 'path';

const errors = [];

import { assign, exists } from './utils';

function getPackageJson(dir) {
  const pkg = path.join(dir, 'package.json')
  return exists(pkg) ? require(pkg) : false
}

function getRoot () {
  let pkgJson = false;

  if (__dirname.indexOf('node_modules') !== -1) {
    let dir = module.id;

    while (path.basename(dir) !== 'node_modules') {
      dir = path.dirname(dir);
    }
    return { rootPath: path.dirname(dir), pkgJson };
  }

  let dir = module;

  while (dir.parent && !pkgJson) {
    dir = dir.parent;
    pkgJson = getPackageJson(path.dirname(dir.filename));
  }
  return { rootPath: path.dirname(dir.filename), pkgJson };
}

function getBaseInfo () {
  const { rootPath, pkgJson } = getRoot();

  return {
    env: process.env.NODE_ENV || 'development',
    root: rootPath,
    pkgJson: pkgJson || getPackageJson(rootPath)
  };
}

function deling () {
  const { env, root, pkgJson } = getBaseInfo();

  const config = {
    root,
    env,
    name: pkgJson.name || '',
    version: pkgJson.version || ''
  };

  const files = [];

  // Located in config-directory
  if (exists(path.join(root, 'config'))) {
    files.push(
      path.join(root, 'config', 'default'),
      path.join(root, 'config', env),
      path.join(root, 'config', 'local')
    );
  }
  // Located in root
  else {
    files.push(
      path.join(root, 'config'),
      path.join(root, 'config.' + env),
      path.join(root, 'config.local')
    );
  }

  function readFile (file) {
    try {
      return require(file);
    }
    catch (err) {
      errors.push(err);
      return {};
    }
  }

  files.map(readFile).reduce(assign, config);

  return config;
}

const config = deling();

config.includePkgJson = function includePkgJson( key = 'pkgJson' ) {
  config[key] = getBaseInfo().pkgJson;
}

config.getErrors = function getErrors() {
  return errors;
}

export default config;

<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducers'
import { Provider } from 'react-redux'

const logger = store => next => action => {
    console.group(action.type)
    console.info('dispatching', action)
    let result = next(action)
    console.log('next state', store.getState())
    console.groupEnd(action.type)
    return result
  }

  const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

  const store = createStore(
    reducer,
    composeEnhancers(
      applyMiddleware(logger)
    )
  )

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
);
registerServiceWorker();
<commit_msg>indentation<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducers'
import { Provider } from 'react-redux'

const logger = store => next => action => {
  console.group(action.type)
  console.info('dispatching', action)
  let result = next(action)
  console.log('next state', store.getState())
  console.groupEnd(action.type)
  return result
}

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

const store = createStore(
  reducer,
  composeEnhancers(
    applyMiddleware(logger)
  )
)

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
registerServiceWorker();
<|endoftext|>


<commit_before>/* @flow */
import WatchmanPlugin from './WatchmanPlugin';

module.exports = WatchmanPlugin;
<commit_msg>Add comment<commit_after>/* @flow */
import WatchmanPlugin from './WatchmanPlugin';

// Do this here to be compatible with require();
module.exports = WatchmanPlugin;
<|endoftext|>