<commit_before>/**
 * Awesome Nested Fields
 *
 * Requires jquery-ujs adapter.
 * https://github.com/lailsonbm/awesome_nested_fields
 */
(function(h){var i={beforeInsert:function(q,r){r()},afterInsert:function(q){},beforeRemove:function(q,r){r()},afterRemove:function(q){},itemTemplateSelector:".item.template",emptyTemplateSelector:".empty.template",containerSelector:".items, .container",itemSelector:".item",emptySelector:".empty",addSelector:".add",removeSelector:".remove",newItemIndex:"new_nested_item",unescapeTemplate:true};var d={init:function(q){return this.each(function(){var r=h(this);if(r.data("nested-fields.options")){g("Nested fields already defined for this element. If you want to redefine options, destroy it and init again.");return r}q=h.extend({},i,q);q.itemTemplate=h(q.itemTemplateSelector,r);q.emptyTemplate=h(q.emptyTemplateSelector,r);q.container=h(q.containerSelector,r);q.add=h(q.addSelector,r);r.data("nested-fields.options",q);l(q);b(q,r)})},insert:function(r,q){q=h.extend({},j(this),q);return f(r,q)},remove:function(r,q){q=h.extend({},j(this),q);return e(r,q)},removeAll:function(q){q=h.extend({},j(this),q);h(d.items.apply(this)).each(function(r,s){d.remove(s,q)})},items:function(){return c(j(this))},destroy:function(){h(this).removeData("nested-fields.options");h("*",this).unbind(".nested-fields")}};h.fn.nestedFields=function(q){if(d[q]){return d[q].apply(this,Array.prototype.slice.call(arguments,1))}else{if(typeof q==="object"||!q){return d.init.apply(this,arguments)}else{h.error("Method "+q+" does not exist on jQuery.nestedFields")}}};function j(r){var q=h(r);while(q.length>0){var s=q.data("nested-fields.options");if(s){return s}else{q=q.parent()}}return null}function l(q){q.add.bind("click.nested-fields",function(r){r.preventDefault();f(null,q)})}function b(q,r){h(q.itemSelector,r).each(function(s,t){k(t,q)})}function m(r){var u=new RegExp(r.newItemIndex,"g");var q=new Date().getTime();var t=r.itemTemplate.html();if(r.unescapeTemplate){t=o(t)}var s=h(t.replace(u,q));s.attr("data-new-record",true);s.attr("data-record-id",q);k(s,r);return s}function f(q,r){var s=m(r);function t(){if(q){q(s)}a(r);r.container.append(s)}if(!r.skipBefore){r.beforeInsert(s,t);if(r.beforeInsert.length<=1){t()}}else{t()}if(!r.skipAfter){r.afterInsert(s)}return s}function a(q){p(q).remove()}function e(t,s){function q(){if(r.attr("data-new-record")){r.remove()}else{r.find("INPUT[name$='[_destroy]']").val("true");r.hide()}n(s)}var r=h(t);if(!s.skipBefore){s.beforeRemove(r,q);if(s.beforeRemove.length<=1){q()}}else{q()}if(!s.skipAfter){s.afterRemove(r)}return r}function n(q){if(c(q).length===0){var r=q.emptyTemplate.html();if(q.unescapeTemplate){r=o(r)}q.container.append(r)}}function k(t,r){var q=h(t).find(r.removeSelector);var u=q.attr("data-confirm");var s=u?"confirm:complete":"click";q.bind(s+".nested-fields",function(v,w){v.preventDefault();if(w===undefined||w===true){e(t,r)}})}function c(q){return q.container.find(q.itemSelector+":visible")}function p(q){return q.container.find(q.emptySelector)}function o(q){var r=document.createElement("div");r.innerHTML=q;return r.childNodes.length===0?"":r.childNodes[0].nodeValue.trim()}function g(q){if(console&&console.log){console.log(q)}}})(jQuery);
<commit_msg>Update vendor/assets/javascripts/jquery.nested-fields.min.js<commit_after>/**
 * Awesome Nested Fields
 *
 * Requires jquery-ujs adapter.
 * https://github.com/lailsonbm/awesome_nested_fields
 */
(function(h){var i={beforeInsert:function(q,r){r()},afterInsert:function(q){},beforeRemove:function(q,r){r()},afterRemove:function(q){},itemTemplateSelector:".item.template",emptyTemplateSelector:".empty.template",containerSelector:".items, .container",itemSelector:".item",emptySelector:".empty",addSelector:".add",removeSelector:".remove",newItemIndex:"new_nested_item",unescapeTemplate:true};var d={init:function(q){return this.each(function(){var r=h(this);if(r.data("nested-fields.options")){g("Nested fields already defined for this element. If you want to redefine options, destroy it and init again.");return r}q=h.extend({},i,q);q.itemTemplate=h(q.itemTemplateSelector,r);q.emptyTemplate=h(q.emptyTemplateSelector,r);q.container=h(q.containerSelector,r);q.add=h(q.addSelector,r);r.data("nested-fields.options",q);l(q);b(q,r)})},insert:function(r,q){q=h.extend({},j(this),q);return f(r,q)},remove:function(r,q){q=h.extend({},j(this),q);return e(r,q)},removeAll:function(q){q=h.extend({},j(this),q);h(d.items.apply(this)).each(function(r,s){d.remove(s,q)})},items:function(){return c(j(this))},destroy:function(){h(this).removeData("nested-fields.options");h("*",this).unbind(".nested-fields")}};h.fn.nestedFields=function(q){if(d[q]){return d[q].apply(this,Array.prototype.slice.call(arguments,1))}else{if(typeof q==="object"||!q){return d.init.apply(this,arguments)}else{h.error("Method "+q+" does not exist on jQuery.nestedFields")}}};function j(r){var q=h(r);while(q.length>0){var s=q.data("nested-fields.options");if(s){return s}else{q=q.parent()}}return null}function l(q){q.add.bind("click.nested-fields",function(r){r.preventDefault();f(null,q)})}function b(q,r){h(q.itemSelector,r).each(function(s,t){k(t,q)})}function m(r){var u=new RegExp(r.newItemIndex,"g");var q=new Date().getTime();var t=r.itemTemplate.html();if(r.unescapeTemplate){t=o(t)}var s=h(t.replace(u,q));s.attr("data-new-record",true);s.attr("data-record-id",q);k(s,r);return s}function f(q,r){var s=m(r);function t(){if(q){q(s)}a(r);r.container.append(s)}if(!r.skipBefore){r.beforeInsert(s,t);if(r.beforeInsert.length<=1){t()}}else{t()}if(!r.skipAfter){r.afterInsert(s)}return s}function a(q){p(q).remove()}function e(t,s){function q(){if(r.attr("data-new-record")){r.remove()}else{r.find("INPUT[name$='[_destroy]']").val("true");r.hide()}n(s)}var r=h(t);if(!s.skipBefore){s.beforeRemove(r,q);if(s.beforeRemove.length<=1){q()}}else{q()}if(!s.skipAfter){s.afterRemove(r)}return r}function n(q){if(c(q).length===0){var r=q.emptyTemplate.html();if(q.unescapeTemplate){r=o(r)}q.container.append(r)}}function k(t,r){var q=h(t).find(r.removeSelector);var u=q.attr("data-confirm");var s=u?"confirm:complete":"click";q.bind(s+".nested-fields",function(v,w){v.preventDefault();if(w===undefined||w===true){e(t,r)}})}function c(q){return q.container.find(q.itemSelector+":visible")}function p(q){return q.container.find(q.emptySelector)}function o(q){var r=document.createElement("div");r.innerHTML=q;return r.childNodes.length===0?"":jQuery.trim(r.childNodes[0].nodeValue)}function g(q){if(console&&console.log){console.log(q)}}})(jQuery);
<|endoftext|>


<commit_before>/**
 * `Module` Dependencies
 */
var httpsync;

try {
    httpsync = require('httpsync');
} catch (e) {
    if (e.code === 'MODULE_NOT_FOUND') {
        httpsync = require('http-sync-win');
    } else {
        throw e;
    }
}

/**
 * `Request` Object, to help with
 * preparing Request options.
 */
exports.Request = function() {
    var args = Array.prototype.slice.call(arguments)
      , path = args.shift()
      , meth = args.shift() || 'GET'
      , hdrs = args.shift() || {}
      , data = args.shift() || {};

    return {
        url: path,
        method: meth,
        headers: hdrs,
        body: data
    };
};

/**
 * `Message` Object, to hold HttpClient
 * response Objects etc
 *
 * @param opts [HttpClient Response Object]
 */
function Message(opts) {
    this.response = opts;

    if (this.response.statusCode.range(200, 399)) {
        this._isSuccess = true,
        this.status = 'OK';
    } else {
        this._isSuccess = false,
        this.status = 'NOT_OK'; // is this spec ?
    }
};

/**
 * nothing to do here, just a mock !!
 */
Message.prototype.waitForComplete = function() {
    return;
};

/**
 * to know, if the request succeeded,
 * based on HTTP Response Codes
 *
 * @return {Boolean}
 */
Message.prototype.isSuccess = function() {
    return this._isSuccess;
};

/**
 * `getResponse` would return Response
 * Object, with all needed information
 *
 * @return {Object}
 */
Message.prototype.getResponse = function() {
    return {
        status: this.status,
        success: this._isSuccess,
        headers: this.response.headers,
        statusCode: this.response.statusCode,
        content: this.response.data.toString()
    }
};

/**
 * `HttpClient`
 */
var Client = exports.Client = {};

/**
 * `send` instead of using get.
 * useful for methods other than get.
 *
 * @return {Message Object}
 */
Client.send = function () {
    var args = Array.prototype.slice.call(arguments)
      , opts = args.shift();

    if (!(args.length == 1 && opts instanceof Object)) {
        throw new Error('Bad arguments to send function');
    };

    var request = httpsync.request(opts)
      , response = request.end();

    return new Message(response);
};

/**
 * useful for method: get.
 *
 * @return {Message Object}
 */
Client.get = function () {
    var args = Array.prototype.slice.call(arguments)
      , opts = args.shift();

    if (typeof(opts) === 'string') {
        opts = {
            url: opts
        }
    } else if (typeof(opts) !== 'object') {
        throw new Error('Bad arguments to get function');
    };

    var request = httpsync.get(opts)
      , response = request.end();

    return new Message(response);
}<commit_msg>windows support<commit_after>/**
 * `Module` Dependencies
 */
var httpsync, __WINDOWS;
var parse_url = require('url').parse;

try {
    __WINDOWS = !!process.platform.match(/^win/);
    httpsync = require('httpsync');
} catch (e) {
    if ((e.code === 'MODULE_NOT_FOUND') && __WINDOWS) {
        httpsync = require('http-sync-win');
    } else {
        throw e;
    }
}

/**
 * `Request` Object, to help with
 * preparing Request options.
 */
exports.Request = function() {
    var args = Array.prototype.slice.call(arguments)
      , path = args.shift()
      , meth = args.shift() || 'GET'
      , hdrs = args.shift() || {}
      , data = args.shift() || {};

    return {
        url: path,
        method: meth,
        headers: hdrs,
        body: data
    };
};

/**
 * `Message` Object, to hold HttpClient
 * response Objects etc
 *
 * @param opts [HttpClient Response Object]
 */
function Message(opts) {
    this.response = opts;

    if (this.response.statusCode.range(200, 399)) {
        this._isSuccess = true,
        this.status = 'OK';
    } else {
        this._isSuccess = false,
        this.status = 'NOT_OK'; // is this spec ?
    }
};

/**
 * nothing to do here, just a mock !!
 */
Message.prototype.waitForComplete = function() {
    return;
};

/**
 * to know, if the request succeeded,
 * based on HTTP Response Codes
 *
 * @return {Boolean}
 */
Message.prototype.isSuccess = function() {
    return this._isSuccess;
};

/**
 * `getResponse` would return Response
 * Object, with all needed information
 *
 * @return {Object}
 */
Message.prototype.getResponse = function() {
    return {
        status: this.status,
        success: this._isSuccess,
        headers: this.response.headers,
        statusCode: this.response.statusCode,
        content: this.response.data.toString()
    }
};

/**
 * `HttpClient`
 */
var Client = exports.Client = {};

/**
 * `send` instead of using get.
 * useful for methods other than get.
 *
 * @return {Message Object}
 */
Client.send = function () {
    var args = Array.prototype.slice.call(arguments)
      , opts = args.shift();

    if (!(args.length == 1 && opts instanceof Object)) {
        throw new Error('Bad arguments to send function');
    };

    if (__WINDOWS) {
        var _uri = parse_url(opts.url);
        opts.host = _uri.hostname;
        opts.port = _uri.port;
        opts.path = _uri.pathname;
        opts.protocol = _uri.protocol.replace(':', '');
    }

    var request = httpsync.request(opts)
      , response = request.end();

    if (__WINDOWS) {
        response.data = response.body;
    }

    return new Message(response);
};

/**
 * useful for method: get.
 *
 * @return {Message Object}
 */
Client.get = function () {
    var args = Array.prototype.slice.call(arguments)
      , opts = args.shift();

    if (typeof(opts) === 'string') {
        opts = {
            url: opts
        }
    } else if (typeof(opts) !== 'object') {
        throw new Error('Bad arguments to get function');
    };

    if (!opts.method) opts.method = 'GET';

    if (__WINDOWS) {
        var _uri = parse_url(opts.url);
        opts.host = _uri.hostname;
        opts.port = _uri.port;
        opts.path = _uri.path;
        opts.protocol = _uri.protocol.replace(':', '');
    }

    var request = httpsync.request(opts)
      , response = request.end();

    if (__WINDOWS) {
        response.data = response.body;
    }

    return new Message(response);
}<|endoftext|>


<commit_before>'use strict'
const tools = require('./tools/index')
const fake = require('./fake/index')

/**
 * @namespace Mock
 */

function genEnum (a = []) {
  /**
   * @memberof Mock#
   * @param {Array} a - 数组
   * @description 随机获取数组中元素
   * @function genEnum
   * @return {string}
   * @example
   * genEnum([2, 1, 8.1, 3, 4, 5.1, 6.7])
   * // 3
   */

  return a[tools.rnd(0, a.length - 1)]
}

function genBool () {
  /**
   * @memberof Mock#
   * @description 随机bool值
   * @function genBool
   * @return {number}
   * @example
   * genBool()
   * // 1
   */

  return genEnum([0, 1])
}

function genWord (n = 1) {
  /**
   * @memberof Mock#
   * @description n个随机汉字
   * @param {number} n - 汉字个数
   * @function genWord
   * @return {string}
   * @example
   * genWord(5)
   * // 用们生到作
   */

  const word =
    '的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发年动同工也能下过子说产种面而方后多定行学法所民得经十三之进着等部度家电力里如水化高自二理起小物现实加量都两体制机当使点从业本去把性好应开它合还因由其些然前外天政四日那社义事平形相全表间样与关各重新线内数正心反你明看原又么利比或但质气第向道命此变条只没结解问意建月公无系军很情者最立代想已通并提直题党程展五果料象员革位入常文总次品式活设及管特件长求老头基资边流路级少图山统接知较将组见计别她手角期根论运农指几九区强放决西被干做必战先回则任取据处队南给色光门即保治北造百规热领七海口东导器压志世金增争济阶油思术极交受联什认六共权收证改清己美再采转更单风切打白教速花带安场身车例真务具万每目至达走积示议声报斗完类八离华名确才科张信马节话米整空元况今集温传土许步群广石记需段研界拉林律叫且究观越织装影算低持音众书布复容儿须际商非验连断深难近矿千周委素技备半办青省列习响约支般史感劳便团往酸历市克何除消构府称太准精值号率族维划选标写存候毛亲快效斯院查江型眼王按格养易置派层片始却专状育厂京识适属圆包火住调满县局照参红细引听该铁价严龙飞'
  return fake.randData(word, n)
}

function genText (n = 20) {
  /**
   * @memberof Mock#
   * @description n个随机汉字
   * @param {number} n - 汉字个数
   * @function genText
   * @return {string}
   * @example
   * genText(5) //默认是长度为20的一段文字
   * // 用社员际个
   */

  if (n >= 20) {
    const len1 = ~~(n / 3)
    const len2 = ~~((n - len1) / 2)
    const len3 = n - len1 - len2 - 3
    return genWord(len1) + '，' + genWord(len2) + '，' + genWord(len3) + '。'
  }
  return genWord(n)
}

function genConstellation () {
  /**
   * @memberof Mock#
   * @description 随机星座
   * @function genConstellation
   * @return {string}
   * @example
   * genConstellation()
   * // 狮子座
   */

  return genEnum([
    '白羊座',
    '金牛座',
    '双子座',
    '巨蟹座',
    '狮子座',
    '处女座',
    '天秤座',
    '天蝎座',
    '射手座',
    '摩羯座',
    '水瓶座',
    '双鱼座'
  ])
}
function genBeautyText () {
  const text = require('./fake/beautySentence.json')
  return text.pick()
}
const extObj = {
  genDatetime: function (params) {
    /**
     * @memberof fake#
     * @description 在某一时间段内随机生成日期,"2013-02-15 21:00:00",返回值类型为字符串
     * @function randTime
     * @param {String|Date} startTime - 开始时间
     * @param {String|Date} endTime - 结束时间
     * @return {String}
     * @example
     * console.log($.fake.randTime("2013-02-15 21:00:00", "2014-02-15 21:00:00"))
     */

    return fake.randTime(params)
  },
  genData: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成长度为n的字符串
     * @function randData
     * @param {Number} o - 数据源
     * @param {Number} n - 长度
     * @return {String}
     * @example
     * console.log($.fake.randData(0,10))
     */

    return fake.randData(params)
  },
  genName: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成姓名,长度为2或3
     * @function randName
     * @return {String}
     * @example
     * console.log($.fake.randName())
     */

    return fake.randName(params)
  },
  genCard: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成中国身份证号码
     * @function idCard
     * @return {String}
     * @example
     * console.log($.fake.idCard())
     */

    return fake.idCard(params)
  },
  genIp: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成ip地址
     * @function randIp
     * @return {String}
     * @example
     * console.log($.fake.randIp())
     */

    return fake.randIp(params)
  },
  genUrl: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成url
     * @function randUrl
     * @param {Number} n - 域名长度
     * @return {String}
     * @example
     * console.log($.fake.randUrl(12))
     */

    return fake.randUrl(params)
  },
  genPhone: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成中国手机号
     * @function phoneNum
     * @return {String}
     * @example
     * console.log($.fake.phoneNum())
     */

    return fake.phoneNum(params)
  },
  genColor: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成颜色,
     * @function randColor
     * @param {String | null} colorType - 参数二选一  [null|'rgba']
     * @return {String}
     * @example
     * console.log($.fake.randColor('rgba'))
     */

    return fake.randColor(params)
  },
  genWord: genWord,
  genText: genText,
  genConstellation: genConstellation,
  genBool: genBool,
  genEnum: genEnum,
  genBeautyText: genBeautyText
}
module.exports = extObj
<commit_msg>:memo:<commit_after>'use strict'
const tools = require('./tools/index')
const fake = require('./fake/index')

/**
 * @namespace Mock
 */

function genEnum (a = []) {
  /**
   * @memberof Mock#
   * @param {Array} a - 数组
   * @description 随机获取数组中元素
   * @function genEnum
   * @return {string}
   * @example
   * genEnum([2, 1, 8.1, 3, 4, 5.1, 6.7])
   * // 3
   */

  return a[tools.rnd(0, a.length - 1)]
}

function genBool () {
  /**
   * @memberof Mock#
   * @description 随机bool值
   * @function genBool
   * @return {number}
   * @example
   * genBool()
   * // 1
   */

  return genEnum([0, 1])
}

function genWord (n = 1) {
  /**
   * @memberof Mock#
   * @description n个随机汉字
   * @param {number} n - 汉字个数
   * @function genWord
   * @return {string}
   * @example
   * genWord(5)
   * // 用们生到作
   */

  const word =
    '的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发年动同工也能下过子说产种面而方后多定行学法所民得经十三之进着等部度家电力里如水化高自二理起小物现实加量都两体制机当使点从业本去把性好应开它合还因由其些然前外天政四日那社义事平形相全表间样与关各重新线内数正心反你明看原又么利比或但质气第向道命此变条只没结解问意建月公无系军很情者最立代想已通并提直题党程展五果料象员革位入常文总次品式活设及管特件长求老头基资边流路级少图山统接知较将组见计别她手角期根论运农指几九区强放决西被干做必战先回则任取据处队南给色光门即保治北造百规热领七海口东导器压志世金增争济阶油思术极交受联什认六共权收证改清己美再采转更单风切打白教速花带安场身车例真务具万每目至达走积示议声报斗完类八离华名确才科张信马节话米整空元况今集温传土许步群广石记需段研界拉林律叫且究观越织装影算低持音众书布复容儿须际商非验连断深难近矿千周委素技备半办青省列习响约支般史感劳便团往酸历市克何除消构府称太准精值号率族维划选标写存候毛亲快效斯院查江型眼王按格养易置派层片始却专状育厂京识适属圆包火住调满县局照参红细引听该铁价严龙飞'
  return fake.randData(word, n)
}

function genText (n = 20) {
  /**
   * @memberof Mock#
   * @description n个随机汉字
   * @param {number} n - 汉字个数
   * @function genText
   * @return {string}
   * @example
   * genText(5) //默认是长度为20的一段文字
   * // 用社员际个
   */

  if (n >= 20) {
    const len1 = ~~(n / 3)
    const len2 = ~~((n - len1) / 2)
    const len3 = n - len1 - len2 - 3
    return genWord(len1) + '，' + genWord(len2) + '，' + genWord(len3) + '。'
  }
  return genWord(n)
}

function genConstellation () {
  /**
   * @memberof Mock#
   * @description 随机星座
   * @function genConstellation
   * @return {string}
   * @example
   * genConstellation()
   * // 狮子座
   */

  return genEnum([
    '白羊座',
    '金牛座',
    '双子座',
    '巨蟹座',
    '狮子座',
    '处女座',
    '天秤座',
    '天蝎座',
    '射手座',
    '摩羯座',
    '水瓶座',
    '双鱼座'
  ])
}
function genBeautyText () {
  /**
     * @memberof fake#
     * @description 随机抽取一句唯美句子
     * @function genBeautyText
     * @return {String}
     * @example
     * console.log($.fake.genBeautyText())
     */
  const text = require('./fake/beautySentence.json')
  return text.pick()
}
const extObj = {
  genDatetime: function (params) {
    /**
     * @memberof fake#
     * @description 在某一时间段内随机生成日期,"2013-02-15 21:00:00",返回值类型为字符串
     * @function randTime
     * @param {String|Date} startTime - 开始时间
     * @param {String|Date} endTime - 结束时间
     * @return {String}
     * @example
     * console.log($.fake.randTime("2013-02-15 21:00:00", "2014-02-15 21:00:00"))
     */

    return fake.randTime(params)
  },
  genData: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成长度为n的字符串
     * @function randData
     * @param {Number} o - 数据源
     * @param {Number} n - 长度
     * @return {String}
     * @example
     * console.log($.fake.randData(0,10))
     */

    return fake.randData(params)
  },
  genName: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成姓名,长度为2或3
     * @function randName
     * @return {String}
     * @example
     * console.log($.fake.randName())
     */

    return fake.randName(params)
  },
  genCard: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成中国身份证号码
     * @function idCard
     * @return {String}
     * @example
     * console.log($.fake.idCard())
     */

    return fake.idCard(params)
  },
  genIp: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成ip地址
     * @function randIp
     * @return {String}
     * @example
     * console.log($.fake.randIp())
     */

    return fake.randIp(params)
  },
  genUrl: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成url
     * @function randUrl
     * @param {Number} n - 域名长度
     * @return {String}
     * @example
     * console.log($.fake.randUrl(12))
     */

    return fake.randUrl(params)
  },
  genPhone: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成中国手机号
     * @function phoneNum
     * @return {String}
     * @example
     * console.log($.fake.phoneNum())
     */

    return fake.phoneNum(params)
  },
  genColor: function (params) {
    /**
     * @memberof Mock#
     * @description 随机生成颜色,
     * @function randColor
     * @param {String | null} colorType - 参数二选一  [null|'rgba']
     * @return {String}
     * @example
     * console.log($.fake.randColor('rgba'))
     */

    return fake.randColor(params)
  },
  genWord: genWord,
  genText: genText,
  genConstellation: genConstellation,
  genBool: genBool,
  genEnum: genEnum,
  genBeautyText: genBeautyText
}
module.exports = extObj
<|endoftext|>


<commit_before>var path = require('path'),
	fs = require('fs'),
	parsers = require('./parsers'),
	woods = require('./woods'),
	Site = require('./Site'),
	Showdown = require('showdown'),
	converter = new Showdown.converter(),
	express = require('express');

var Page = function(site, parent, directory) {
	var that = this;
	this.site = site;
	if (parent)
		this.parent = parent;
	this.directory = directory;

	// Remove numbers in path, since they are only used for order:
	this.url = this.getUri(true).replace(/\/[0-9]+-/g,'/')
				.replace(/\s/g, '-');

	site.pageByUrl[this.url] = this;
	this.name = this.directory == ''
			? 'home'
			: path.basename(this.url).replace(/\/$/, '');

	installRoute(this);
	addChildren(this);
	addResources(this);
	parseContent(this);
};

Page.prototype.getTemplate = function(name) {
	var type = this.data.type,
		types = this.site.types;
	return type && types[type][name]
		? types[type][name]
		: types['default'][name] || function(param) {
			return 'Template not found: ' + name;
		};
};

Page.prototype.getTemplateLocation = function(name) {
	var templateLocations = this.site.templateLocations,
		type = this.data.type;
	return this.data.type && templateLocations[type][name]
		? templateLocations[type][name]
		: templateLocations['default'][name];
};

Page.prototype.renderTemplate = function(name) {
	return this.getTemplate(name)({
		page: this,
		parse: function(content, param) {
			return converter.makeHtml(content);
		}
	});
};

Page.prototype.getUri = function(url) {
	var uri = this.directory,
		parent = this.parent;
	while (parent) {
		uri = path.join(parent.directory, uri);
		parent = parent.parent;
	}
	var site = url ? this.site.getUrl() : this.site.getUri('content');
	var resolved = path.resolve(site, uri);
	return resolved;
};

Page.prototype.getTitle = function() {
	return this.data.title || this.name;
};

var reservedNames = {resources: true, error: true, home: true};
Page.nameIsReserved = function(name) {
	return !!name && !!reservedNames[name];
};

var addResources = function(page) {
	var routeUrl = path.join(page.url, 'resources'),
		resourcesDir = path.join(page.getUri(), 'resources'),
		images = page.images = [],
		resources = page.resources = [];

	woods.express.use(routeUrl, express.static(resourcesDir));

	var addFile = function(file) {
		if (/jpg|jpeg|png|gif/.test(file)) {
			images.push(file);
		} else {
			resources.push(file);
		}
	};

	var addFiles = function() {
		fs.readdir(resourcesDir, function(err, files) {
			files.forEach(addFile);
		});
	};

	fs.exists(resourcesDir, function(err, exists) {
		if (!exists) return;
		addFiles();
	});
};

var addChildren = function(page) {
	// Read the directory and add child pagees (if any):
	var children = page.children = [];
	var uri = page.getUri();
	var files = fs.readdirSync(uri);
	var index = 0;
	for (var i in files) {
		var file = path.resolve(uri, files[i]);
		var name = path.basename(file);
		var isDirectory = fs.statSync(file).isDirectory();
		if (isDirectory && !Page.nameIsReserved(name)) {
			var isChild = /^[0-9]+\-/.test(name);
			var childPage = new Page(page.site, page, path.relative(uri, file));
			childPage.index = index++;
			// Only add to children list if it is a child
			// - i.e. its name starts in the style of: 01- or 02-
			if (isChild)
				children.push(childPage);
		}
	}
};

var parseContent = function(page) {
	// Parse the content file and place values in page.data:
	page.data = {};
	var contentPath = path.join(page.getUri(), 'content.md');
	parsers.parse(contentPath, page);
};

var installRoute = function(page) {
	// Install the path in express:
	woods.express.get(page.url, function(req, res) {
		var template = page.getTemplateLocation('html');
		res.render(template, {
			title: page.data.title,
			text: page.data.text || '',
			site: page.site,
			base: page.site.getUrl(),
			page: page,
			parse: function(content, param) {
				return converter.makeHtml(content);
			}
		});
	});
};

module.exports = Page;<commit_msg>Rename variable.<commit_after>var path = require('path'),
	fs = require('fs'),
	parsers = require('./parsers'),
	woods = require('./woods'),
	Site = require('./Site'),
	Showdown = require('showdown'),
	converter = new Showdown.converter(),
	express = require('express');

var Page = function(site, parent, directory) {
	var that = this;
	this.site = site;
	if (parent)
		this.parent = parent;
	this.directory = directory;

	// Remove numbers in path, since they are only used for order:
	this.url = this.getUri(true).replace(/\/[0-9]+-/g,'/')
				.replace(/\s/g, '-');

	site.pageByUrl[this.url] = this;
	this.name = this.directory == ''
			? 'home'
			: path.basename(this.url).replace(/\/$/, '');

	installRoute(this);
	addChildren(this);
	addResources(this);
	parseContent(this);
};

Page.prototype.getTemplate = function(name) {
	var type = this.data.type,
		types = this.site.types;
	return type && types[type][name]
		? types[type][name]
		: types['default'][name] || function(param) {
			return 'Template not found: ' + name;
		};
};

Page.prototype.getTemplateLocation = function(name) {
	var templateLocations = this.site.templateLocations,
		type = this.data.type;
	return this.data.type && templateLocations[type][name]
		? templateLocations[type][name]
		: templateLocations['default'][name];
};

Page.prototype.renderTemplate = function(name) {
	return this.getTemplate(name)({
		page: this,
		parse: function(content, param) {
			return converter.makeHtml(content);
		}
	});
};

Page.prototype.getUri = function(url) {
	var uri = this.directory,
		parent = this.parent;
	while (parent) {
		uri = path.join(parent.directory, uri);
		parent = parent.parent;
	}
	var site = url ? this.site.getUrl() : this.site.getUri('content');
	var resolved = path.resolve(site, uri);
	return resolved;
};

Page.prototype.getTitle = function() {
	return this.data.title || this.name;
};

var reservedNames = {resources: true, error: true, home: true};
Page.nameIsReserved = function(name) {
	return !!name && !!reservedNames[name];
};

var addResources = function(page) {
	var routeUrl = path.join(page.url, 'resources'),
		resourcesDir = path.join(page.getUri(), 'resources'),
		images = page.images = [],
		resources = page.resources = [];

	woods.express.use(routeUrl, express.static(resourcesDir));

	var addFile = function(file) {
		if (/jpg|jpeg|png|gif/.test(file)) {
			images.push(file);
		} else {
			resources.push(file);
		}
	};

	var addFiles = function() {
		fs.readdir(resourcesDir, function(err, files) {
			files.forEach(addFile);
		});
	};

	fs.exists(resourcesDir, function(err, exists) {
		if (!exists) return;
		addFiles();
	});
};

var addChildren = function(page) {
	// Read the directory and add child pagees (if any):
	var children = page.children = [];
	var uri = page.getUri();
	var files = fs.readdirSync(uri);
	var index = 0;
	for (var i in files) {
		var file = path.resolve(uri, files[i]);
		var name = path.basename(file);
		var isDirectory = fs.statSync(file).isDirectory();
		if (isDirectory && !Page.nameIsReserved(name)) {
			var isChild = /^[0-9]+\-/.test(name);
			var child = new Page(page.site, page, path.relative(uri, file));
			child.index = index++;
			// Only add to children list if it is a child
			// - i.e. its name starts in the style of: 01- or 02-
			if (isChild)
				children.push(child);
		}
	}
};

var parseContent = function(page) {
	// Parse the content file and place values in page.data:
	page.data = {};
	var contentPath = path.join(page.getUri(), 'content.md');
	parsers.parse(contentPath, page);
};

var installRoute = function(page) {
	// Install the path in express:
	woods.express.get(page.url, function(req, res) {
		var template = page.getTemplateLocation('html');
		res.render(template, {
			title: page.data.title,
			text: page.data.text || '',
			site: page.site,
			base: page.site.getUrl(),
			page: page,
			parse: function(content, param) {
				return converter.makeHtml(content);
			}
		});
	});
};

module.exports = Page;<|endoftext|>


<commit_before>

/// <reference name="MicrosoftAjax.debug.js" />
/// <reference path="../ExtenderBase/BaseScripts.js" />
/// <reference path="../Common/Common.js" />
/// <reference path="../RoundedCorners/RoundedCornersBehavior.js" />
/// <reference path="../Compat/Timer/Timer.js" />

(function() {
var scriptName = "ExtendedDropShadow";

function execute() {

Type.registerNamespace('Sys.Extended.UI');

Sys.Extended.UI.DropShadowBehavior = function(element) {
    /// <summary>
    /// The DropShadowBehavior is used to attach a drop shadow to the element
    /// </summary>
    /// <param name="element" type="Sys.UI.DomElement" domElement="true">
    /// DOM Element the behavior is associated with
    /// </param>
    Sys.Extended.UI.DropShadowBehavior.initializeBase(this, [element]);

    // our property values
    this._opacity = 1.0;
    this._width = 5;

    // the div we create for the shadow.
    this._shadowDiv = null;

    // our timer for tracking position
    this._trackPosition = null;
    this._trackPositionDelay = 50;
    this._timer = null;
    this._tickHandler = null;
    this._roundedBehavior = null;
    this._shadowRoundedBehavior = null;

    this._rounded = false;
    this._radius = 5;

    // our cache of our last size and position for tracking
    this._lastX = null;
    this._lastY = null;
    this._lastW = null;
    this._lastH = null;
}
Sys.Extended.UI.DropShadowBehavior.prototype = {
    initialize : function() {
        /// <summary>
        /// Initialize the behavior
        /// </summary>
        Sys.Extended.UI.DropShadowBehavior.callBaseMethod(this, 'initialize');

        var e = this.get_element();

        // flip the styles position to relative so that we z-order properly.
        if ($common.getCurrentStyle(e, 'position', e.style.position) != "absolute") {
            e.style.position = "relative";
        }

        // set up our initial state
        if (this._rounded) {
            this.setupRounded();
        }
        if (this._trackPosition) {
            this.startTimer();
        }
        this.setShadow();
    },

    dispose : function() {
        /// <summary>
        /// Dispose the behavior
        /// </summary>
        this.stopTimer();
        this.disposeShadowDiv();
        Sys.Extended.UI.DropShadowBehavior.callBaseMethod(this, 'dispose');
    },

    buildShadowDiv : function() {
        /// <summary>
        /// Create the div that we'll use as the shadow
        /// </summary>

        var e = this.get_element();

        if (!this.get_isInitialized() || !e || !this._width) return;

        var div = document.createElement("DIV");
        div.style.backgroundColor = "black";
        div.style.position= "absolute";

        if (e.id) {
            div.id = e.id + "_DropShadow";
        }

        // initialize a control around it, and
        // set up the opacity behavior and rounding
        this._shadowDiv = div;

       e.parentNode.appendChild(div);

       if (this._rounded ) {
            this._shadowDiv.style.height = Math.max(0, e.offsetHeight - (2*this._radius)) + "px";
            if (!this._shadowRoundedBehavior) {
                this._shadowRoundedBehavior = $create(Sys.Extended.UI.RoundedCornersBehavior, {"Radius": this._radius}, null, null, this._shadowDiv);
            } else {
                this._shadowRoundedBehavior.set_Radius(this._radius);
            }
        } else if (this._shadowRoundedBehavior) {
            this._shadowRoundedBehavior.set_Radius(0);
        }

        if (this._opacity != 1.0) {
            this.setupOpacity();
        }

        this.setShadow(false, true);
        this.updateZIndex();
    },

    disposeShadowDiv : function() {
        /// <summary>
        /// Dispose of the div we use as the shadow
        /// </summary>

        if (this._shadowDiv) {
            // on page teardown (or in an update panel, this may already
            // be gone)
            //
            if (this._shadowDiv.parentNode) {
                this._shadowDiv.parentNode.removeChild(this._shadowDiv);
            }
            this._shadowDiv = null;
        }

        if (this._shadowRoundedBehavior) {
            this._shadowRoundedBehavior.dispose();
            this._shadowRoundedBehavior = null;
        }
    },

    onTimerTick : function() {
        /// <summary>
        /// Timer's tick handler that is used to position the shadow when its target moves
        /// </summary>
        this.setShadow();
    },

    startTimer : function() {
        /// <summary>
        /// Start the timer (and hence start tracking the bounds of the target element)
        /// </summary>

        if (!this._timer) {
            if (!this._tickHandler) {
                this._tickHandler = Function.createDelegate(this, this.onTimerTick);
            }
            this._timer = new Sys.Timer();
            this._timer.set_interval(this._trackPositionDelay);
            this._timer.add_tick(this._tickHandler);
            this._timer.set_enabled(true);
        }
    },

    stopTimer : function() {
        /// <summary>
        /// Stop the timer (and hence stop tracking the bounds of the target element)
        /// </summary>

        // on stop, just clean the thing up completely
        if (this._timer) {
            this._timer.remove_tick(this._tickHandler);
            this._timer.set_enabled(false);
            this._timer.dispose();
            this._timer = null;
        }
    },

    setShadow : function(force, norecurse) {
        /// <summary>
        /// This function does the heavy lifting of positioning and sizing the shadow.
        /// It caches values to avoid extra work - it's called on a timer so we need to
        /// keep it light weight.
        /// </summary>
        /// <param name="force" type="Boolean">
        /// Whether to force the bounds change
        /// </param>
        /// <param name="norecurse" type="Boolean">
        /// Whether to recurse if we need to recreate the shadow div
        /// </param>

        var e = this.get_element();
        if (!this.get_isInitialized() || !e || (!this._width && !force)) return;

        var existingShadow = this._shadowDiv;
        if (!existingShadow) {
            this.buildShadowDiv();
        }

        var location = { x: e.offsetLeft, y: e.offsetTop };

        if (force || this._lastX != location.x || this._lastY != location.y || !existingShadow) {
            this._lastX = location.x;
            this._lastY = location.y;

            var w = this.get_Width();

            location.x += w;
            location.y += w;

            $common.setLocation(this._shadowDiv, location);
        }

        var h = e.offsetHeight;
        var w = e.offsetWidth;

        if (force || h != this._lastH || w != this._lastW || !existingShadow) {
            this._lastW = w;
            this._lastH = h;
            if (!this._rounded || !existingShadow || norecurse) {
               this._shadowDiv.style.width = w + "px";
               this._shadowDiv.style.height = h + "px";
            } else {
                // recurse if we need to redo the div
                this.disposeShadowDiv();
                this.setShadow();
            }
        }

        if (this._shadowDiv) {
            this._shadowDiv.style.visibility = $common.getCurrentStyle(e, 'visibility');
        }
    },

    setupOpacity : function() {
        /// <summary>
        /// Set the opacity of the shadow div
        /// </summary>
        if (this.get_isInitialized() && this._shadowDiv) {
            $common.setElementOpacity(this._shadowDiv, this._opacity);
        }
    },

    setupRounded : function() {
        /// <summary>
        /// Demand create and initialize the RoundedCornersBehavior
        /// </summary>

        if (!this._roundedBehavior && this._rounded) {
            this._roundedBehavior = $create(Sys.Extended.UI.RoundedCornersBehavior, null, null, null, this.get_element());
        }
        if (this._roundedBehavior) {
            this._roundedBehavior.set_Radius(this._rounded ? this._radius : 0);
        }
    },

    updateZIndex : function() {
        /// <summary>
        /// Update the z-Index so the shadow div remains behind the target element
        /// </summary>

        if (!this._shadowDiv) return;

        var e = this.get_element();
        var targetZIndex = e.style.zIndex;
        var shadowZIndex = this._shadowDiv.style.zIndex;

        if (shadowZIndex && targetZIndex && targetZIndex > shadowZIndex) {
            return;
        } else {
           targetZIndex = Math.max(2, targetZIndex);
           shadowZIndex = targetZIndex - 1;
        }
        e.style.zIndex = targetZIndex;
        this._shadowDiv.style.zIndex = shadowZIndex;
    },

    updateRoundedCorners : function() {
        /// <summary>
        /// Update the RoundedCorndersBehavior and recreate the shadow div so its corners are rounded as well
        /// </summary>
        if (this.get_isInitialized()) {
            this.setupRounded();
            this.disposeShadowDiv();
            this.setShadow();
        }
    },

    get_Opacity : function() {
        /// <value type="Number">
        /// The opacity of the drop shadow, from 0 (fully transparent) to 1.0 (fully opaque). The default value is .5.
        /// </value>
        return this._opacity;
    },
    set_Opacity : function(value) {
        if (this._opacity != value) {
            this._opacity = value;
            this.setupOpacity();
            this.raisePropertyChanged('Opacity');
        }
    },

    get_Rounded : function() {
        /// <value type="Boolean">
        /// Whether or not the corners of the target and drop shadow should be rounded
        /// </value>
        return this._rounded;
    },
    set_Rounded : function(value) {
        if (value != this._rounded) {
            this._rounded = value;
            this.updateRoundedCorners();
            this.raisePropertyChanged('Rounded');
        }
    },

    get_Radius : function() {
        /// <value type="Number" integer="true">
        /// Radius, in pixels, of the rounded corners
        /// </value>
        return this._radius;
    },
    set_Radius : function(value) {
        if (value != this._radius) {
            this._radius = value;
            this.updateRoundedCorners();
            this.raisePropertyChanged('Radius');
        }
    },

    get_Width : function() {
        /// <value type="Number" integer="true">
        /// Width in pixels of the drop shadow.  The default value is 5 pixels.
        /// </value>
        return this._width;
    },
    set_Width : function(value) {
        if (value != this._width) {
            this._width = value;

            if (this._shadowDiv) {
                $common.setVisible(this._shadowDiv, value > 0);
            }

            this.setShadow(true);
            this.raisePropertyChanged('Width');
        }
    },

    get_TrackPositionDelay : function() {
        /// <value type="Number">
        /// Length of the timer interval used when tracking the position of the target
        /// </value>
        return this._trackPositionDelay;
    },
    set_TrackPositionDelay : function(value) {
        if (value != this._trackPositionDelay) {
            this._trackPositionDelay = value;
            if (this._trackPosition) {
                this.stopTimer();
                this.startTimer();
            }
            this.raisePropertyChanged('TrackPositionDelay');
        }
    },

    get_TrackPosition : function() {
        /// <value type="Boolean">
        /// Whether the drop shadow should track the position of the panel it is attached to. Use this if the panel is absolutely positioned or will otherwise move.
        /// </value>
        return this._trackPosition;
    },
    set_TrackPosition : function(value) {
        if (value != this._trackPosition) {
            this._trackPosition = value;
            if (this.get_element()) {
                if (value) {
                    this.startTimer();
                } else {
                    this.stopTimer();
                }
            }
            this.raisePropertyChanged('TrackPosition');
        }
    }
}
Sys.Extended.UI.DropShadowBehavior.registerClass('Sys.Extended.UI.DropShadowBehavior', Sys.Extended.UI.BehaviorBase);
Sys.registerComponent(Sys.Extended.UI.DropShadowBehavior, { name: "dropShadow" });
//    getDescriptor : function() {
//        var td = Sys.Extended.UI.DropShadowBehavior.callBaseMethod(this, 'getDescriptor');
//        td.addProperty('Opacity', Number);
//        td.addProperty('Width', Number);
//        td.addProperty('TrackPosition', Boolean);
//        td.addProperty('TrackPositionDelay', Number);
//        td.addProperty('Rounded', Boolean);
//        td.addProperty('Radius', Number);
//        return td;
//    },

} // execute

if (window.Sys && Sys.loader) {
    Sys.loader.registerScript(scriptName, ["ExtendedBase", "ExtendedCommon", "ExtendedTimer", "ExtendedRoundedCorners"], execute);
}
else {
    execute();
}

})();
<commit_msg>Superexpert: Enhanced DropShadow extender with support for CSS 3<commit_after>

/// <reference name="MicrosoftAjax.debug.js" />
/// <reference path="../ExtenderBase/BaseScripts.js" />
/// <reference path="../Common/Common.js" />
/// <reference path="../RoundedCorners/RoundedCornersBehavior.js" />
/// <reference path="../Compat/Timer/Timer.js" />

(function () {
    var scriptName = "ExtendedDropShadow";
    var e = null;

    function execute() {

        Type.registerNamespace('Sys.Extended.UI');

        Sys.Extended.UI.DropShadowBehavior = function (element) {
            /// <summary>
            /// The DropShadowBehavior is used to attach a drop shadow to the element
            /// </summary>
            /// <param name="element" type="Sys.UI.DomElement" domElement="true">
            /// DOM Element the behavior is associated with
            /// </param>
            Sys.Extended.UI.DropShadowBehavior.initializeBase(this, [element]);

            // our property values
            this._opacity = 1.0;
            this._width = 5;

            // the div we create for the shadow.
            this._shadowDiv = null;

            // our timer for tracking position
            this._trackPosition = null;
            this._trackPositionDelay = 50;
            this._timer = null;
            this._tickHandler = null;
            this._roundedBehavior = null;
            this._shadowRoundedBehavior = null;

            this._rounded = false;
            this._radius = 5;

            // our cache of our last size and position for tracking
            this._lastX = null;
            this._lastY = null;
            this._lastW = null;
            this._lastH = null;
        }
        Sys.Extended.UI.DropShadowBehavior.prototype = {
            initialize: function () {
                /// <summary>
                /// Initialize the behavior
                /// </summary>
                Sys.Extended.UI.DropShadowBehavior.callBaseMethod(this, 'initialize');

                e = this.get_element();

                // flip the styles position to relative so that we z-order properly.
                if ($common.getCurrentStyle(e, 'position', e.style.position) != "absolute") {
                    e.style.position = "relative";
                }

                // set up our initial state
                if (this._rounded) {
                    this.setupRounded();
                }

                // execute if browser does not support css3
                if (e.style.boxShadow == undefined && e.style.MozBoxShadow == undefined && e.style.WebkitBoxShadow == undefined) {
                    if (this._trackPosition) {
                        this.startTimer();
                    }
                }
                this.setShadow();

            },

            dispose: function () {
                /// <summary>
                /// Dispose the behavior
                /// </summary>
                if (!e)
                    e = this.get_element();

                // execute if browser does not support css3
                if (e.style.boxShadow == undefined && e.style.MozBoxShadow == undefined && e.style.WebkitBoxShadow == undefined) {
                    this.stopTimer();
                    this.disposeShadowDiv();
                    Sys.Extended.UI.DropShadowBehavior.callBaseMethod(this, 'dispose');
                }
            },

            buildShadowDiv: function () {
                /// <summary>
                /// Create the div that we'll use as the shadow
                /// </summary>

                e = this.get_element();

                if (!this.get_isInitialized() || !e || !this._width) return;

                // check if browser does not support css3
                if (e.style.boxShadow == undefined && e.style.MozBoxShadow == undefined && e.style.WebkitBoxShadow == undefined) {

                    var div = document.createElement("DIV");
                    div.style.backgroundColor = "black";
                    div.style.position = "absolute";

                    if (e.id) {
                        div.id = e.id + "_DropShadow";
                    }

                    // initialize a control around it, and
                    // set up the opacity behavior and rounding
                    this._shadowDiv = div;

                    e.parentNode.appendChild(div);

                    if (this._rounded) {
                        this._shadowDiv.style.height = Math.max(0, e.offsetHeight - (2 * this._radius)) + "px";
                        if (!this._shadowRoundedBehavior) {
                            this._shadowRoundedBehavior = $create(Sys.Extended.UI.RoundedCornersBehavior, { "Radius": this._radius }, null, null, this._shadowDiv);
                        } else {
                            this._shadowRoundedBehavior.set_Radius(this._radius);
                        }
                    } else if (this._shadowRoundedBehavior) {
                        this._shadowRoundedBehavior.set_Radius(0);
                    }

                    if (this._opacity != 1.0) {
                        this.setupOpacity();
                    }

                    this.setShadow(false, true);
                    this.updateZIndex();
                }

            },

            disposeShadowDiv: function () {
                /// <summary>
                /// Dispose of the div we use as the shadow
                /// </summary>

                // execute if browser does not support css3
                if (e.style.boxShadow == undefined && e.style.MozBoxShadow == undefined && e.style.WebkitBoxShadow == undefined) {
                    if (this._shadowDiv) {
                        // on page teardown (or in an update panel, this may already
                        // be gone)
                        //
                        if (this._shadowDiv.parentNode) {
                            this._shadowDiv.parentNode.removeChild(this._shadowDiv);
                        }
                        this._shadowDiv = null;
                    }

                    if (this._shadowRoundedBehavior) {
                        this._shadowRoundedBehavior.dispose();
                        this._shadowRoundedBehavior = null;
                    }
                }
            },

            onTimerTick: function () {
                /// <summary>
                /// Timer's tick handler that is used to position the shadow when its target moves
                /// </summary>
                this.setShadow();
            },

            startTimer: function () {
                /// <summary>
                /// Start the timer (and hence start tracking the bounds of the target element)
                /// </summary>

                if (!this._timer) {
                    if (!this._tickHandler) {
                        this._tickHandler = Function.createDelegate(this, this.onTimerTick);
                    }
                    this._timer = new Sys.Timer();
                    this._timer.set_interval(this._trackPositionDelay);
                    this._timer.add_tick(this._tickHandler);
                    this._timer.set_enabled(true);
                }
            },

            stopTimer: function () {
                /// <summary>
                /// Stop the timer (and hence stop tracking the bounds of the target element)
                /// </summary>

                // on stop, just clean the thing up completely
                if (this._timer) {
                    this._timer.remove_tick(this._tickHandler);
                    this._timer.set_enabled(false);
                    this._timer.dispose();
                    this._timer = null;
                }
            },

            setShadow: function (force, norecurse) {
                /// <summary>
                /// This function does the heavy lifting of positioning and sizing the shadow.
                /// It caches values to avoid extra work - it's called on a timer so we need to
                /// keep it light weight.
                /// </summary>
                /// <param name="force" type="Boolean">
                /// Whether to force the bounds change
                /// </param>
                /// <param name="norecurse" type="Boolean">
                /// Whether to recurse if we need to recreate the shadow div
                /// </param>

                e = this.get_element();

                if (!this.get_isInitialized() || !e || (!this._width && !force)) return;

                // execute if browser does not support css3
                if (e.style.boxShadow == undefined && e.style.MozBoxShadow == undefined && e.style.WebkitBoxShadow == undefined) {

                    var existingShadow = this._shadowDiv;
                    if (!existingShadow) {
                        this.buildShadowDiv();
                    }

                    var location = { x: e.offsetLeft, y: e.offsetTop };

                    if (force || this._lastX != location.x || this._lastY != location.y || !existingShadow) {
                        this._lastX = location.x;
                        this._lastY = location.y;

                        var w = this.get_Width();

                        location.x += w;
                        location.y += w;

                        $common.setLocation(this._shadowDiv, location);
                    }

                    var h = e.offsetHeight;
                    var w = e.offsetWidth;

                    if (force || h != this._lastH || w != this._lastW || !existingShadow) {
                        this._lastW = w;
                        this._lastH = h;
                        if (!this._rounded || !existingShadow || norecurse) {
                            this._shadowDiv.style.width = w + "px";
                            this._shadowDiv.style.height = h + "px";
                        } else {
                            // recurse if we need to redo the div
                            this.disposeShadowDiv();
                            this.setShadow();
                        }
                    }

                    if (this._shadowDiv) {
                        this._shadowDiv.style.visibility = $common.getCurrentStyle(e, 'visibility');
                    }
                }
            },

            setupOpacity: function () {
                /// <summary>
                /// Set the opacity of the shadow div
                /// </summary>
                if (this.get_isInitialized() && this._shadowDiv) {
                    $common.setElementOpacity(this._shadowDiv, this._opacity);
                }

            },

            setupRounded: function () {
                /// <summary>
                /// Demand create and initialize the RoundedCornersBehavior
                /// </summary>

                if (!this._roundedBehavior && this._rounded) {
                    this._roundedBehavior = $create(Sys.Extended.UI.RoundedCornersBehavior, null, null, null, this.get_element());
                }
                if (this._roundedBehavior) {
                    this._roundedBehavior.set_Radius(this._rounded ? this._radius : 0);
                }
            },

            updateZIndex: function () {
                /// <summary>
                /// Update the z-Index so the shadow div remains behind the target element
                /// </summary>

                if (!this._shadowDiv) return;

                var e = this.get_element();
                var targetZIndex = e.style.zIndex;
                var shadowZIndex = this._shadowDiv.style.zIndex;

                if (shadowZIndex && targetZIndex && targetZIndex > shadowZIndex) {
                    return;
                } else {
                    targetZIndex = Math.max(2, targetZIndex);
                    shadowZIndex = targetZIndex - 1;
                }
                e.style.zIndex = targetZIndex;
                this._shadowDiv.style.zIndex = shadowZIndex;
            },

            updateRoundedCorners: function () {
                /// <summary>
                /// Update the RoundedCorndersBehavior and recreate the shadow div so its corners are rounded as well
                /// </summary>
                if (this.get_isInitialized()) {
                    this.setupRounded();
                    this.disposeShadowDiv();
                    this.setShadow();
                }
            },

            get_Opacity: function () {
                /// <value type="Number">
                /// The opacity of the drop shadow, from 0 (fully transparent) to 1.0 (fully opaque). The default value is .5.
                /// </value>
                return this._opacity;
            },
            set_Opacity: function (value) {
                if (this._opacity != value) {
                    this._opacity = value;

                    // get element to set drop shadow
                    if (!e)
                        e = this.get_element();

                    var boxShadowVals;

                    //To display effect of opacity set different color
                    // on the basis of selected % of opacity
                    if (this._opacity == ".25")
                        boxShadowVals = this._width + "px " + this._width + "px " + this._width + "px " + "#D3D3D3";
                    else if (this._opacity == ".5")
                        boxShadowVals = this._width + "px " + this._width + "px " + this._width + "px " + "#778899";
                    else if (this._opacity == ".75")
                        boxShadowVals = this._width + "px " + this._width + "px " + this._width + "px " + "#808080";
                    else
                        boxShadowVals = this._width + "px " + this._width + "px " + this._width + "px " + "#000";

                    // this works in IE9 and Chrome latest versions
                    if (e.style.boxShadow != undefined) {
                        e.style.boxShadow = boxShadowVals;
                    }
                    // this works for Mozila Firefox
                    else if (e.style.MozBoxShadow != undefined) {
                        e.style.MozBoxShadow = boxShadowVals;
                    }
                    // this works for Chrome older version, Safari
                    else if (e.style.WebkitBoxShadow != undefined) {
                        e.style.WebkitBoxShadow = boxShadowVals;
                    }
                    else {
                        this.setupOpacity();

                        this.raisePropertyChanged('Opacity');
                    }
                }
            },

            get_Rounded: function () {
                /// <value type="Boolean">
                /// Whether or not the corners of the target and drop shadow should be rounded
                /// </value>
                return this._rounded;
            },
            set_Rounded: function (value) {

                if (value != this._rounded) {
                    this._rounded = value;

                    this.updateRoundedCorners();
                    this.raisePropertyChanged('Rounded');
                }
            },

            get_Radius: function () {
                /// <value type="Number" integer="true">
                /// Radius, in pixels, of the rounded corners
                /// </value>
                return this._radius;
            },
            set_Radius: function (value) {
                if (value != this._radius) {
                    this._radius = value;

                    this.updateRoundedCorners();
                    this.raisePropertyChanged('Radius');
                }
            },

            get_Width: function () {
                /// <value type="Number" integer="true">
                /// Width in pixels of the drop shadow.  The default value is 5 pixels.
                /// </value>
                return this._width;
            },
            set_Width: function (value) {

                if (value != this._width) {
                    this._width = value;

                    // Get element to set drop shadow
                    if (!e)
                        e = this.get_element();

                    var boxShadowVals;

                    //To display effect of opacity set different color
                    // on the basis of selected % of opacity
                    if (this._opacity == ".25")
                        boxShadowVals = this._width + "px " + this._width + "px " + this._width + "px " + "#D3D3D3";
                    else if (this._opacity == ".5")
                        boxShadowVals = this._width + "px " + this._width + "px " + this._width + "px " + "#778899";
                    else if (this._opacity == ".75")
                        boxShadowVals = this._width + "px " + this._width + "px " + this._width + "px " + "#808080";
                    else
                        boxShadowVals = this._width + "px " + this._width + "px " + this._width + "px " + "#000000";

                    // this works in IE9 and Chrome latest versions
                    if (e.style.boxShadow != undefined) {
                        e.style.boxShadow = boxShadowVals;
                    }
                    // this works for Mozila Firefox
                    else if (e.style.MozBoxShadow != undefined) {
                        e.style.MozBoxShadow = boxShadowVals;
                    }
                    // this works for Chrome older version, Safari
                    else if (e.style.WebkitBoxShadow != undefined) {
                        e.style.WebkitBoxShadow = boxShadowVals;
                    }
                    else {

                        if (this._shadowDiv) {
                            $common.setVisible(this._shadowDiv, value > 0);
                        }

                        this.setShadow(true);
                        this.raisePropertyChanged('Width');
                    }
                }
            },

            get_TrackPositionDelay: function () {
                /// <value type="Number">
                /// Length of the timer interval used when tracking the position of the target
                /// </value>
                return this._trackPositionDelay;
            },
            set_TrackPositionDelay: function (value) {
                if (value != this._trackPositionDelay) {
                    this._trackPositionDelay = value;

                    if (!e)
                        e = this.get_element();

                    // execute if browser does not support css3
                    if (e.style.boxShadow == undefined && e.style.MozBoxShadow == undefined && e.style.WebkitBoxShadow == undefined) {
                        if (this._trackPosition) {
                            this.stopTimer();
                            this.startTimer();
                        }
                        this.raisePropertyChanged('TrackPositionDelay');
                    }
                }
            },

            get_TrackPosition: function () {
                /// <value type="Boolean">
                /// Whether the drop shadow should track the position of the panel it is attached to. Use this if the panel is absolutely positioned or will otherwise move.
                /// </value>
                return this._trackPosition;
            },
            set_TrackPosition: function (value) {
                if (value != this._trackPosition) {
                    this._trackPosition = value;

                    if (!e)
                        e = this.get_element();

                    // execute if browser does not support css3
                    if (e.style.boxShadow == undefined && e.style.MozBoxShadow == undefined && e.style.WebkitBoxShadow == undefined) {
                        if (this.get_element()) {
                            if (value) {
                                this.startTimer();
                            } else {
                                this.stopTimer();
                            }
                        }
                        this.raisePropertyChanged('TrackPosition');
                    }
                }
            }
        }
        Sys.Extended.UI.DropShadowBehavior.registerClass('Sys.Extended.UI.DropShadowBehavior', Sys.Extended.UI.BehaviorBase);
        Sys.registerComponent(Sys.Extended.UI.DropShadowBehavior, { name: "dropShadow" });
        //    getDescriptor : function() {
        //        var td = Sys.Extended.UI.DropShadowBehavior.callBaseMethod(this, 'getDescriptor');
        //        td.addProperty('Opacity', Number);
        //        td.addProperty('Width', Number);
        //        td.addProperty('TrackPosition', Boolean);
        //        td.addProperty('TrackPositionDelay', Number);
        //        td.addProperty('Rounded', Boolean);
        //        td.addProperty('Radius', Number);
        //        return td;
        //    },

    } // execute

    if (window.Sys && Sys.loader) {
        Sys.loader.registerScript(scriptName, ["ExtendedBase", "ExtendedCommon", "ExtendedTimer", "ExtendedRoundedCorners"], execute);
    }
    else {
        execute();
    }

})();
<|endoftext|>


<commit_before>import { shallow } from "enzyme";
import { shallowToJson } from "enzyme-to-json";
import Tabs from "../tabs";

const defaultProps = {
  items: [jest.fn(), jest.fn()],
  toggle: jest.fn(),
  state: 0,
};

const generateComponent = (additionalProps = {}) => {
  const newProps = {
    ...defaultProps,
    ...additionalProps,
  };
  return <Tabs { ...newProps } />;
};

it("renders with props", () => {
  const wrapper = shallow(generateComponent());
  expect(shallowToJson(wrapper)).toMatchSnapshot();
});

it("updates active on mount", () => {
  const wrapper = shallow(generateComponent({
    state: 1,
  }));
  expect(wrapper.state().active).toBe(1);
});

it("updates active when recieving props", () => {
  const wrapper = shallow(generateComponent({
    state: 1,
  }));
  wrapper.setProps({ state: 2 });
  expect(wrapper.state().active).toBe(2);
});

it("toggle uses event to update state", () => {
  const mockTabs = jest.fn();
  const mockEvent = {
    target: {
      dataset: {
        toggle: 2,
      },
    },
  };
  const wrapper = shallow(generateComponent({
    toggle: mockTabs,
  }));
  wrapper.instance().toggle(mockEvent);
  expect(mockTabs).toHaveBeenCalledTimes(1);
  expect(mockTabs).toHaveBeenCalledWith(2);
  expect(wrapper.state().active).toBe(2);
});

it("toggleClasses renders default classes", () => {
  const wrapper = shallow(generateComponent());
  const result = wrapper.instance().toggleClasses();
  expect(result).toMatchSnapshot();
});

it("toggleClasses renders active classes", () => {
  const wrapper = shallow(generateComponent());
  const result = wrapper.instance().toggleClasses(0);
  expect(result).toMatchSnapshot();
});

it("toggleWidth determins size for toggle", () => {
  const wrapper = shallow(generateComponent());
  expect(wrapper.instance().toggleWidth()).toBe(50);
});

it("toggleStyle returns css for toggle width", () => {
  const wrapper = shallow(generateComponent());
  expect(wrapper.instance().toggleStyle).toEqual({
    width: "50%",
  });
});

it("arrowStyle returns css for arrow placement", () => {
  const wrapper = shallow(generateComponent());
  expect(wrapper.instance().arrowStyle()).toMatchSnapshot();
  wrapper.setState({ active: 1 });
  expect(wrapper.instance().arrowStyle()).toMatchSnapshot();
});
<commit_msg>fixed bad import<commit_after>import { shallow } from "enzyme";
import { shallowToJson } from "enzyme-to-json";
import Tabs from "../Tabs";

const defaultProps = {
  items: [jest.fn(), jest.fn()],
  toggle: jest.fn(),
  state: 0,
};

const generateComponent = (additionalProps = {}) => {
  const newProps = {
    ...defaultProps,
    ...additionalProps,
  };
  return <Tabs { ...newProps } />;
};

it("renders with props", () => {
  const wrapper = shallow(generateComponent());
  expect(shallowToJson(wrapper)).toMatchSnapshot();
});

it("updates active on mount", () => {
  const wrapper = shallow(generateComponent({
    state: 1,
  }));
  expect(wrapper.state().active).toBe(1);
});

it("updates active when recieving props", () => {
  const wrapper = shallow(generateComponent({
    state: 1,
  }));
  wrapper.setProps({ state: 2 });
  expect(wrapper.state().active).toBe(2);
});

it("toggle uses event to update state", () => {
  const mockTabs = jest.fn();
  const mockEvent = {
    target: {
      dataset: {
        toggle: 2,
      },
    },
  };
  const wrapper = shallow(generateComponent({
    toggle: mockTabs,
  }));
  wrapper.instance().toggle(mockEvent);
  expect(mockTabs).toHaveBeenCalledTimes(1);
  expect(mockTabs).toHaveBeenCalledWith(2);
  expect(wrapper.state().active).toBe(2);
});

it("toggleClasses renders default classes", () => {
  const wrapper = shallow(generateComponent());
  const result = wrapper.instance().toggleClasses();
  expect(result).toMatchSnapshot();
});

it("toggleClasses renders active classes", () => {
  const wrapper = shallow(generateComponent());
  const result = wrapper.instance().toggleClasses(0);
  expect(result).toMatchSnapshot();
});

it("toggleWidth determins size for toggle", () => {
  const wrapper = shallow(generateComponent());
  expect(wrapper.instance().toggleWidth()).toBe(50);
});

it("toggleStyle returns css for toggle width", () => {
  const wrapper = shallow(generateComponent());
  expect(wrapper.instance().toggleStyle).toEqual({
    width: "50%",
  });
});

it("arrowStyle returns css for arrow placement", () => {
  const wrapper = shallow(generateComponent());
  expect(wrapper.instance().arrowStyle()).toMatchSnapshot();
  wrapper.setState({ active: 1 });
  expect(wrapper.instance().arrowStyle()).toMatchSnapshot();
});
<|endoftext|>


<commit_before>/**
 * We.js notification object for controll notifications
 *
 *
 */
window.WeNotification = Ember.Object.extend({
  notificationCount: 0,

  readNotificationCount: 0,

  notificationHost: '',

  defaultTitle: '',
  // flag to check if user is on page
  isActiveTab: true,

  newMessageAudio: null,
  notificationAudioUrl: '/core/sounds/new-message.mp3',
  playNotificationSound: function() {
    if (this.get('newMessageAudio') && !this.get('isActiveTab')) {
      this.get('newMessageAudio').play();
    }
  },

  titleNotificator: function() {
    $('title').text(this.formatTitle());
  }.observes('notificationCount'),

  formatTitle: function() {
    if (!this.get('notificationCount')) {
      return this.get('defaultTitle')
    }
    return '('+this.get('notificationCount')+') | ' + this.get('defaultTitle')
  },

  hasBrowserNotificationsPermissions: false,

  authenticatedUser: function(){
    return App.get('currentUser');
  }.property('App.currentUser'),

  init: function() {
    var self = this;
    we.events.on('sails:created:notification', function (){
      self.incrementProperty('notificationCount');

      // TODO add suport to browser notifications
      // var title = 'Novo conteúdo';
      // var icon = '/core/images/we-logo-branco-small.png';

      // if ( message.data.model == 'post' ) {
      //   if( message.data.action == 'created' ) {
      //     title = 'Novo conteúdo';
      //     icon = '/core/images/we-logo-branco-small.png';
      //   }
      // }

      // if ( message.data.model == 'post' ) {
      //   if( message.data.action == 'created' ) {
      //     title = 'Novo conteúdo';
      //     icon = '/core/images/we-logo-branco-small.png';
      //   }
      // }

      // self.createNotification(title, {
      //   icon: icon,
      //   body: message.data.textClean,
      //   onclick: function(){
      //     console.warn('clicou na notificação');
      //   }
      // });
    });

    we.events.on('sails:updated:notification', function updateCount(message) {
      // id is array ...
      if (
       message.data &&
       message.data instanceof Array
      ) {
        message.data.forEach(function (notification) {
          self.updateCount(notification.read);
        })
      } else {
        self.updateCount(message.data.read);
      }
    });
    // Let's check if the browser supports notifications
    if (!('Notification' in window)) {
      console.info('This browser does not support desktop notification');
      return;
    }

    // store default page title
    this.set('defaultTitle', $('title').text() );
    // and set new title
    $('title').text(self.formatTitle());

    var permission = this.hasPermissions();
    if( permission ) {
      if( permission === 'granted') {
        // can notify
      } else {
        this.requestPermission();
      }
    }

    if (Audio) {
      this.set('newMessageAudio', new Audio(this.get('notificationAudioUrl')));
    }

    we.events.on('sails:created:message', function updateCount(message) {
      if ( message.data.fromId != App.get('currentUser.id') ) {
        self.playNotificationSound();
      }
    });

    self.setPageChangeMecanism();

  },

  /**
   * Function to get unread notification count from server
   *
   * return {object}  jquery Ajax object
   */
  loadNotificationCount: function() {
    var self = this;

    if( !App.get('currentUser.id') ) {
      return;
    }

    return $.ajax({
      url: '/api/v1/current-user/notification-count',
      data: {
        read: false
      }
    }).then(function(result){
      if (result.count) {
        self.set('notificationCount', result.count);
      }
      return result;
    });
  },

  /**
   * Function to get read notification count from server
   *
   * return {object}  jquery Ajax object
   */
  loadReadNotificationCount: function() {
    var self = this;

    if( !App.get('auth.isAuthenticated') ) {
      return;
    }

    return $.ajax({
      url: this.get('notificationHost') + '/api/v1/current-user/notification-count',
      data: {
        read: true
      }
    }).then(function(result){
      if (result.count) {
        self.set('readNotificationCount', result.count);
      }
      return result;
    });
  },

  updateCount: function(read, count) {
    if( !count ) {
      count = 1
    }
    if (read) {
      this.decrementProperty('notificationCount', count);
      this.incrementProperty('readNotificationCount', count);
    } else {
      this.incrementProperty('notificationCount', count);
      this.decrementProperty('readNotificationCount', count);
    }

  },

  createNotification: function(title, configs) {
    if (this.hasPermissions()) {
      var notification = new Notification(title,configs);
      return notification;
    }
  },

  requestPermission: function(){
    // request the permission
    Notification.requestPermission(function (permission) {
      // Whatever the user answers, we make sure we store the information
      if (!('permission' in Notification)) {
        Notification.permission = permission;
      }
    });
  },

  hasPermissions: function hasPermissions() {
    // Let's check if the user is okay to get some notification
    if (window.Notification.permission === 'granted') {
      // If it's okay let's create a notification
      return 'granted';
    } else if(window.Notification.permission !== 'denied'){
      // need to ask the user for permission
      return window.Notification.permission;
    }
    // permission denited by user
    return false;
  },

  markModelNotificationAsRead: function(store, modelName, modelId) {
    if( !App.get('auth.isAuthenticated') ) {
      return;
    }

    return $.ajax({
      type: 'POST',
      url: this.get('notificationHost') + '/api/v1/notify/' + modelName + '/' + modelId + '/mark-all-as-read'
    });
  },
  setPageChangeMecanism: function() {
    var self = this;
    // Set the name of the hidden property and the change event for visibility
    var hidden, visibilityChange;
    if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support
      hidden = 'hidden';
      visibilityChange = 'visibilitychange';
    } else if (typeof document.mozHidden !== 'undefined') {
      hidden = 'mozHidden';
      visibilityChange = 'mozvisibilitychange';
    } else if (typeof document.msHidden !== 'undefined') {
      hidden = 'msHidden';
      visibilityChange = 'msvisibilitychange';
    } else if (typeof document.webkitHidden !== 'undefined') {
      hidden = 'webkitHidden';
      visibilityChange = 'webkitvisibilitychange';
    }

    // If the page is hidden, pause the video;
    // if the page is shown, play the video
    function handleVisibilityChange() {
      if (document[hidden]) {
        self.set('isActiveTab', false);
      } else {
        self.set('isActiveTab', true);
      }
    }

    // Warn if the browser doesn't support addEventListener or the Page Visibility API
    if (typeof document.addEventListener === 'undefined' ||
      typeof document[hidden] === 'undefined') {
      // TODO change to one jquery event
      window.onfocus = function () {
        self.set('isActiveTab', true);
      };
      window.onblur = function () {
        self.set('isActiveTab', false);
      };
    } else {
      // Handle page visibility change
      document.addEventListener(visibilityChange, handleVisibilityChange, false);
    }
  }
});
<commit_msg>add configurable request permission<commit_after>/**
 * We.js notification object for controll notifications
 *
 *
 */
window.WeNotification = Ember.Object.extend({
  notificationCount: 0,

  readNotificationCount: 0,

  notificationHost: '',

  defaultTitle: '',
  // flag to check if user is on page
  isActiveTab: true,

  newMessageAudio: null,
  notificationAudioUrl: '/core/sounds/new-message.mp3',
  playNotificationSound: function() {
    if (this.get('newMessageAudio') && !this.get('isActiveTab')) {
      this.get('newMessageAudio').play();
    }
  },

  titleNotificator: function() {
    $('title').text(this.formatTitle());
  }.observes('notificationCount'),

  formatTitle: function() {
    if (!this.get('notificationCount')) {
      return this.get('defaultTitle')
    }
    return '('+this.get('notificationCount')+') | ' + this.get('defaultTitle')
  },

  hasBrowserNotificationsPermissions: false,

  authenticatedUser: function(){
    return App.get('currentUser');
  }.property('App.currentUser'),

  init: function() {
    var self = this;
    we.events.on('sails:created:notification', function (){
      self.incrementProperty('notificationCount');

      // TODO add suport to browser notifications
      // var title = 'Novo conteúdo';
      // var icon = '/core/images/we-logo-branco-small.png';

      // if ( message.data.model == 'post' ) {
      //   if( message.data.action == 'created' ) {
      //     title = 'Novo conteúdo';
      //     icon = '/core/images/we-logo-branco-small.png';
      //   }
      // }

      // if ( message.data.model == 'post' ) {
      //   if( message.data.action == 'created' ) {
      //     title = 'Novo conteúdo';
      //     icon = '/core/images/we-logo-branco-small.png';
      //   }
      // }

      // self.createNotification(title, {
      //   icon: icon,
      //   body: message.data.textClean,
      //   onclick: function(){
      //     console.warn('clicou na notificação');
      //   }
      // });
    });

    we.events.on('sails:updated:notification', function updateCount(message) {
      // id is array ...
      if (
       message.data &&
       message.data instanceof Array
      ) {
        message.data.forEach(function (notification) {
          self.updateCount(notification.read);
        })
      } else {
        self.updateCount(message.data.read);
      }
    });
    // Let's check if the browser supports notifications
    if (!('Notification' in window)) {
      console.info('This browser does not support desktop notification');
      return;
    }

    // store default page title
    this.set('defaultTitle', $('title').text() );
    // and set new title
    $('title').text(self.formatTitle());

    var permission = this.hasPermissions();
    if( permission ) {
      if( permission === 'granted') {
        // can notify
      } else if( we.configs.client.publicVars.allowNotifications ) {
        this.requestPermission();
      }
    }

    if (Audio) {
      this.set('newMessageAudio', new Audio(this.get('notificationAudioUrl')));
    }

    we.events.on('sails:created:message', function updateCount(message) {
      if ( message.data.fromId != App.get('currentUser.id') ) {
        self.playNotificationSound();
      }
    });

    self.setPageChangeMecanism();

  },

  /**
   * Function to get unread notification count from server
   *
   * return {object}  jquery Ajax object
   */
  loadNotificationCount: function() {
    var self = this;

    if( !App.get('currentUser.id') ) {
      return;
    }

    return $.ajax({
      url: '/api/v1/current-user/notification-count',
      data: {
        read: false
      }
    }).then(function(result){
      if (result.count) {
        self.set('notificationCount', result.count);
      }
      return result;
    });
  },

  /**
   * Function to get read notification count from server
   *
   * return {object}  jquery Ajax object
   */
  loadReadNotificationCount: function() {
    var self = this;

    if( !App.get('auth.isAuthenticated') ) {
      return;
    }

    return $.ajax({
      url: this.get('notificationHost') + '/api/v1/current-user/notification-count',
      data: {
        read: true
      }
    }).then(function(result){
      if (result.count) {
        self.set('readNotificationCount', result.count);
      }
      return result;
    });
  },

  updateCount: function(read, count) {
    if( !count ) {
      count = 1
    }
    if (read) {
      this.decrementProperty('notificationCount', count);
      this.incrementProperty('readNotificationCount', count);
    } else {
      this.incrementProperty('notificationCount', count);
      this.decrementProperty('readNotificationCount', count);
    }

  },

  createNotification: function(title, configs) {
    if (this.hasPermissions()) {
      var notification = new Notification(title,configs);
      return notification;
    }
  },

  requestPermission: function(){
    // request the permission
    Notification.requestPermission(function (permission) {
      // Whatever the user answers, we make sure we store the information
      if (!('permission' in Notification)) {
        Notification.permission = permission;
      }
    });
  },

  hasPermissions: function hasPermissions() {
    // Let's check if the user is okay to get some notification
    if (window.Notification.permission === 'granted') {
      // If it's okay let's create a notification
      return 'granted';
    } else if(window.Notification.permission !== 'denied'){
      // need to ask the user for permission
      return window.Notification.permission;
    }
    // permission denited by user
    return false;
  },

  markModelNotificationAsRead: function(store, modelName, modelId) {
    if( !App.get('auth.isAuthenticated') ) {
      return;
    }

    return $.ajax({
      type: 'POST',
      url: this.get('notificationHost') + '/api/v1/notify/' + modelName + '/' + modelId + '/mark-all-as-read'
    });
  },
  setPageChangeMecanism: function() {
    var self = this;
    // Set the name of the hidden property and the change event for visibility
    var hidden, visibilityChange;
    if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support
      hidden = 'hidden';
      visibilityChange = 'visibilitychange';
    } else if (typeof document.mozHidden !== 'undefined') {
      hidden = 'mozHidden';
      visibilityChange = 'mozvisibilitychange';
    } else if (typeof document.msHidden !== 'undefined') {
      hidden = 'msHidden';
      visibilityChange = 'msvisibilitychange';
    } else if (typeof document.webkitHidden !== 'undefined') {
      hidden = 'webkitHidden';
      visibilityChange = 'webkitvisibilitychange';
    }

    // If the page is hidden, pause the video;
    // if the page is shown, play the video
    function handleVisibilityChange() {
      if (document[hidden]) {
        self.set('isActiveTab', false);
      } else {
        self.set('isActiveTab', true);
      }
    }

    // Warn if the browser doesn't support addEventListener or the Page Visibility API
    if (typeof document.addEventListener === 'undefined' ||
      typeof document[hidden] === 'undefined') {
      // TODO change to one jquery event
      window.onfocus = function () {
        self.set('isActiveTab', true);
      };
      window.onblur = function () {
        self.set('isActiveTab', false);
      };
    } else {
      // Handle page visibility change
      document.addEventListener(visibilityChange, handleVisibilityChange, false);
    }
  }
});
<|endoftext|>


<commit_before>var async = require('async');
var moment = require('moment');
var twitter = require('ntwitter');

var models = require('./models');
var settings = require('./settings');

// Rate limit is 180 requests per 15 minutes
// TODO: Use limiter for proper limiting of all Tweeter requests
var LOAD_INTERVAL = 15 * 60 * 1000 / 180;
var MAX_ID_REGEXP = /max_id=(\d+)/;

var twit = new twitter({
    'consumer_key': settings.TWITTER_CONSUMER_KEY,
    'consumer_secret': settings.TWITTER_CONSUMER_SECRET,
    'access_token_key': settings.TWITTER_ACCESS_TOKEN_KEY,
    'access_token_secret': settings.TWITTER_ACCESS_TOKEN_SECRET
});

var maxId = process.argv.length > 2 ? process.argv[2] : null;
var count = 0;
var date = null;
var errorCount = 0;

function next() {
    if (!date) {
        date = moment();
    }
    date.subtract('days', 1);
    maxId = null;
    if (moment() - date > 14 * 24 * 60 * 60 * 1000) { // 14 days
        process.exit(0);
    }
    else {
        setTimeout(loadtweets, LOAD_INTERVAL);
    }
}

function loadtweets() {
    var params = {'include_entities': true, 'count': 100, 'max_id': maxId, 'q': settings.TWITTER_QUERY.join(' OR ') + (date ? ' until:' + date.format('YYYY-MM-DD') : '')};
    console.log("Making request, max_id = %s, date = %s", maxId, date);
    twit.get('/search/tweets.json', params, function(err, data) {
        if (err) {
            if (err.statusCode === 500 && errorCount < 3) {
                console.error("Twitter fetch error, retrying", err);
                errorCount++;
                setTimeout(loadtweets, LOAD_INTERVAL);
            }
            else {
                console.error("Twitter fetch error", err);
                process.exit(1);
            }
            return;
        }

        errorCount = 0;

        if (data.statuses.length === 0) {
            console.log("%s new tweets fetched overall", count);
            next();
            return;
        }

        async.forEach(data.statuses, function (tweet, cb) {
            models.Post.storeTweet(tweet, 'search', function (err, tweet) {
                if (err) {
                    console.error(err);
                    return;
                }

                if (tweet) {
                    count++;
                }
            });

            // We handle error independently
            cb(null);
        }, function (err) {
            console.log("%s new tweets fetched overall", count);

            var max_id_match = MAX_ID_REGEXP.exec(data.search_metadata.next_results);
            if (!max_id_match) {
                next();
                return;
            }

            maxId = max_id_match[1];

            setTimeout(loadtweets, LOAD_INTERVAL);
        });
    });
}

loadtweets();
<commit_msg>Ignore more errors.<commit_after>var async = require('async');
var moment = require('moment');
var twitter = require('ntwitter');

var models = require('./models');
var settings = require('./settings');

// Rate limit is 180 requests per 15 minutes
// TODO: Use limiter for proper limiting of all Tweeter requests
var LOAD_INTERVAL = 15 * 60 * 1000 / 180;
var MAX_ID_REGEXP = /max_id=(\d+)/;

var twit = new twitter({
    'consumer_key': settings.TWITTER_CONSUMER_KEY,
    'consumer_secret': settings.TWITTER_CONSUMER_SECRET,
    'access_token_key': settings.TWITTER_ACCESS_TOKEN_KEY,
    'access_token_secret': settings.TWITTER_ACCESS_TOKEN_SECRET
});

var maxId = process.argv.length > 2 ? process.argv[2] : null;
var count = 0;
var date = null;
var errorCount = 0;

function next() {
    if (!date) {
        date = moment();
    }
    date.subtract('days', 1);
    maxId = null;
    if (moment() - date > 14 * 24 * 60 * 60 * 1000) { // 14 days
        process.exit(0);
    }
    else {
        setTimeout(loadtweets, LOAD_INTERVAL);
    }
}

function loadtweets() {
    var params = {'include_entities': true, 'count': 100, 'max_id': maxId, 'q': settings.TWITTER_QUERY.join(' OR ') + (date ? ' until:' + date.format('YYYY-MM-DD') : '')};
    console.log("Making request, max_id = %s, date = %s", maxId, date);
    twit.get('/search/tweets.json', params, function(err, data) {
        if (err) {
            if ((err.statusCode === 500 || err.statusCode === 503) && errorCount < 3) {
                console.error("Twitter fetch error, retrying", err);
                errorCount++;
                setTimeout(loadtweets, LOAD_INTERVAL);
            }
            else {
                console.error("Twitter fetch error", err);
                process.exit(1);
            }
            return;
        }

        errorCount = 0;

        if (data.statuses.length === 0) {
            console.log("%s new tweets fetched overall", count);
            next();
            return;
        }

        async.forEach(data.statuses, function (tweet, cb) {
            models.Post.storeTweet(tweet, 'search', function (err, tweet) {
                if (err) {
                    console.error(err);
                    return;
                }

                if (tweet) {
                    count++;
                }
            });

            // We handle error independently
            cb(null);
        }, function (err) {
            console.log("%s new tweets fetched overall", count);

            var max_id_match = MAX_ID_REGEXP.exec(data.search_metadata.next_results);
            if (!max_id_match) {
                next();
                return;
            }

            maxId = max_id_match[1];

            setTimeout(loadtweets, LOAD_INTERVAL);
        });
    });
}

loadtweets();
<|endoftext|>


<commit_before>// @flow
import React from 'react'
import {View, StyleSheet} from 'react-native'

const styles = StyleSheet.create({
  barContainer: {
    paddingRight: 5,
    width: 45,
    flexDirection: 'column',
    alignItems: 'center',
  },
  bar: {
    flex: 1,
    width: 5,
  },
  dot: {
    height: 15,
    width: 15,
    marginVertical: -10,
    borderRadius: 20,
    zIndex: 1,
  },
  skippingStop: {
    backgroundColor: 'transparent',
    borderColor: 'transparent',
  },
  passedStop: {
    height: 12,
    width: 12,
  },
  beforeStop: {
    borderWidth: 3,
    backgroundColor: 'white',
    height: 18,
    width: 18,
  },
  atStop: {
    height: 20,
    width: 20,
    borderColor: 'white',
    borderWidth: 3,
    backgroundColor: 'white',
  },
})

export const ProgressChunk = ({
  afterStop,
  atStop,
  barColor,
  beforeStop,
  currentStopColor,
  skippingStop,
  isFirstChunk,
  isLastChunk,
}: {
  afterStop: boolean,
  atStop: boolean,
  barColor: string,
  beforeStop: boolean,
  currentStopColor: string,
  skippingStop: boolean,
  isFirstChunk: boolean,
  isLastChunk: boolean,
}) => {
  // To draw the bar, we draw a chunk of the bar, then we draw the dot, then
  // we draw the last chunk of the bar.
  return (
    <View style={styles.barContainer}>
      <View style={[styles.bar, {backgroundColor: barColor}]} />
      <View style={[
        styles.dot,
        afterStop && [styles.passedStop, {borderColor: barColor, backgroundColor: barColor}],
        beforeStop && [styles.beforeStop, {borderColor: barColor}],
        atStop && [styles.atStop, {borderColor: currentStopColor}],
        skippingStop && styles.skippingStop,
      ]} />
      <View style={[styles.bar, {backgroundColor: barColor}]} />
    </View>
  )
}
<commit_msg>hide the extreme ProgressChunk bar if the row is first/last<commit_after>// @flow
import React from 'react'
import {View, StyleSheet, Platform} from 'react-native'
const isAndroid = Platform.OS === 'android'

const styles = StyleSheet.create({
  barContainer: {
    paddingRight: 5,
    width: 45,
    flexDirection: 'column',
    alignItems: 'center',
  },
  bar: {
    flex: 1,
    width: 5,
  },
  dot: {
    height: 15,
    width: 15,
    marginVertical: -10,
    borderRadius: 20,
    zIndex: 1,
  },
  skippingStop: {
    backgroundColor: 'transparent',
    borderColor: 'transparent',
  },
  passedStop: {
    height: 12,
    width: 12,
  },
  beforeStop: {
    borderWidth: 3,
    backgroundColor: 'white',
    height: 18,
    width: 18,
  },
  atStop: {
    height: 20,
    width: 20,
    borderColor: 'white',
    borderWidth: 3,
    backgroundColor: 'white',
  },
})

export const ProgressChunk = ({
  afterStop,
  atStop,
  barColor,
  beforeStop,
  currentStopColor,
  skippingStop,
  isFirstChunk,
  isLastChunk,
}: {
  afterStop: boolean,
  atStop: boolean,
  barColor: string,
  beforeStop: boolean,
  currentStopColor: string,
  skippingStop: boolean,
  isFirstChunk: boolean,
  isLastChunk: boolean,
}) => {
  // To draw the bar, we draw a chunk of the bar, then we draw the dot, then
  // we draw the last chunk of the bar.
  const startBarColor = isAndroid && isFirstChunk ? 'transparent' : barColor
  const endBarColor = isAndroid && isLastChunk ? 'transparent' : barColor

  return (
    <View style={styles.barContainer}>
      <View style={[styles.bar, {backgroundColor: startBarColor}]} />
      <View style={[
        styles.dot,
        afterStop && [styles.passedStop, {borderColor: barColor, backgroundColor: barColor}],
        beforeStop && [styles.beforeStop, {borderColor: barColor}],
        atStop && [styles.atStop, {borderColor: currentStopColor}],
        skippingStop && styles.skippingStop,
      ]} />
      <View style={[styles.bar, {backgroundColor: endBarColor}]} />
    </View>
  )
}
<|endoftext|>