<commit_before>var inputThumbCallback = function() {
    $('#thumb-img').hide();
    $('.thumb-buttons').hide();

    $('#thumb-preview').show();
    $('.crop-buttons').show();
    $('.thumb-crop').show();

    $($('#thumb-crop')).cropper({
        aspectRatio: 350/227,
        preview: '#thumb-preview',
        viewMode: 3
    });
}

var add_caption = function(image) {
    if (image.attr('src').trim() == "http://placehold.it/1600x900/FFFFFF?text=")
        return;
    image.wrap('<figure> </figure>');
    figcaption = $('<figcaption> </figcaption>');
    if (image.attr('data-original-title'))
        figcaption.html(image.attr('data-original-title'));
    figcaption.appendTo(image.parent());

    var image_float = image.css('float'),
        image_width = image.css('width');

    if (image_float == 'left' || image_float == 'right') {
        image
            .css('float', 'none')
            .parent().css('float', image_float);
    }
    image.parent().css('max-width', image_width);
    image.css('width', '100%');
    image.css('height', 'auto');
}

var remove_caption = function(image) {
    if (image.attr('src').trim() == "http://placehold.it/1600x900/FFFFFF?text=")
        return;
    image.siblings('figcaption').remove();
    var figure_width = image.parent().css('max-width');
    image.css('width', figure_width);
    var figure_float = image.parent().css('float');
    if (figure_float == 'left' || figure_float == 'right')
        image.css('float', figure_float);
    image.unwrap();
}

var load_tooltips = function() {
    $('[data-toggle="tooltip"]').each(function() {
        var image_title = $(this).attr('title');
        $(this).attr('title', '');
        $(this).tooltip();
        $(this).attr('title', image_title);
    });
}

$(document).ready(function(){
    select2Config.placeholder = 'Separe as palavras-chave por vírgula';
    $('#subject').select2(select2Config);

    $('#subject').on('select2:select', function(e) {
        var elm = e.params.data.element;
        $elm = $(elm);
        $t = $(this);
        $t.append($elm);
        $t.trigger('change.select2');
    });

    $('#blog-edit').prop('disabled', true);

    $('#text-content-editor').append($('#text_content').val());

    $('#text-content-editor img').each(function() {
        if ($(this).parent().is('figure'))
                remove_caption($(this));
    });

    $('#text-content-editor').summernote(summernoteConfig);

    $('#blog-edit').click(function() {
        var editor = $('#text-content-editor');
        $('#blog-preview').prop('disabled', false);
        $('#blog-edit').prop('disabled', true);
        summernoteConfig['focus'] = true;
        editor.find('img').each(function() {
            if ($(this).parent().is('figure'))
                remove_caption($(this));
        });
        editor.summernote(summernoteConfig);
        load_tooltips();
    });

    $('#blog-preview').click(function() {
        var editor = $('#text-content-editor');
        $('#blog-preview-' + lang_ext).prop('disabled', true);
        $('#blog-edit-' + lang_ext).prop('disabled', false);
        editor.summernote('destroy');
        editor.find('img').each(function() {
            add_caption($(this));
        });
        var aHTML = editor.html();
        $('text_content').val(aHTML);
    });

    cropInput($('#thumb-crop'), $('#thumb-input'), inputThumbCallback)

    $('#thumb-zoomIn').click(function() {
        $('#thumb-crop').cropper('zoom', 0.1);
    });
    $('#thumb-zoomOut').click(function() {
        $('#thumb-crop').cropper('zoom', -0.1);
    });
    $('#thumb-rotateLeft').click(function() {
        $('#thumb-crop').cropper('rotate', 45);
    });
    $('#thumb-rotateRight').click(function() {
        $('#thumb-crop').cropper('rotate', -45);
    });
    $('#thumb-save').click(function() {
        var thumbDataURL = $('#thumb-crop').cropper('getDataURL');
        $('#thumb').val(thumbDataURL);
        $('#thumb-img').attr('src', thumbDataURL);

        $('#thumb-img').show();
        $('.thumb-buttons').show();

        $('#thumb-preview').hide();
        $('.crop-buttons').hide();
        $('.thumb-crop').hide();

        $('#thumb-crop').cropper('destroy');
        $('#thumb-crop').attr('src', '');
    });

    $('#publish-date').datepicker({
        format: "dd/mm/yyyy",
        todayBtn: "linked",
        keyboardNavigation: false,
        forceParse: false,
        calendarWeeks: true,
        autoclose: true
    });

    var text_max = 500;
    $('[name=textarea-feedback]').html(text_max + ' ' + dataviva.dictionary['characters_left']);

    $('#text_call').keyup(function() {
        var text_length = $(this).val().length;
        var text_remaining = text_max - text_length;
        $(this).siblings('[name=textarea-feedback]').html(text_remaining + ' ' + dataviva.dictionary['characters_left']);
    });

    load_tooltips();

    $('#blog-form').submit(function() {
        $('#blog-form > button[type=submit]').prop('disabled', true);
        $('#summernote').hide();

        var submittingForm = dataviva.ui.loading('#blog-form');
        submittingForm.text(dataviva.dictionary['loading'] + "...");

        $('#text-content-editor').summernote('destroy');

        $('#text-content-editor img').each(function() {
            if ($(this).parent().is('figure') == false)
               add_caption($(this));
        });

        var pt_html = $('#text-content-editor').html();
        $('#text_content').val(pt_html);
        if ($('#text-content-editor').summernote('isEmpty')) {
            $('#text_content').val('');
        }

        return true;
    });
});
<commit_msg>Fixes summernote preview button in blog form<commit_after>var inputThumbCallback = function() {
    $('#thumb-img').hide();
    $('.thumb-buttons').hide();

    $('#thumb-preview').show();
    $('.crop-buttons').show();
    $('.thumb-crop').show();

    $($('#thumb-crop')).cropper({
        aspectRatio: 350/227,
        preview: '#thumb-preview',
        viewMode: 3
    });
}

var add_caption = function(image) {
    if (image.attr('src').trim() == "http://placehold.it/1600x900/FFFFFF?text=")
        return;
    image.wrap('<figure> </figure>');
    figcaption = $('<figcaption> </figcaption>');
    if (image.attr('data-original-title'))
        figcaption.html(image.attr('data-original-title'));
    figcaption.appendTo(image.parent());

    var image_float = image.css('float'),
        image_width = image.css('width');

    if (image_float == 'left' || image_float == 'right') {
        image
            .css('float', 'none')
            .parent().css('float', image_float);
    }
    image.parent().css('max-width', image_width);
    image.css('width', '100%');
    image.css('height', 'auto');
}

var remove_caption = function(image) {
    if (image.attr('src').trim() == "http://placehold.it/1600x900/FFFFFF?text=")
        return;
    image.siblings('figcaption').remove();
    var figure_width = image.parent().css('max-width');
    image.css('width', figure_width);
    var figure_float = image.parent().css('float');
    if (figure_float == 'left' || figure_float == 'right')
        image.css('float', figure_float);
    image.unwrap();
}

var load_tooltips = function() {
    $('[data-toggle="tooltip"]').each(function() {
        var image_title = $(this).attr('title');
        $(this).attr('title', '');
        $(this).tooltip();
        $(this).attr('title', image_title);
    });
}

$(document).ready(function(){
    select2Config.placeholder = 'Separe as palavras-chave por vírgula';
    $('#subject').select2(select2Config);

    $('#subject').on('select2:select', function(e) {
        var elm = e.params.data.element;
        $elm = $(elm);
        $t = $(this);
        $t.append($elm);
        $t.trigger('change.select2');
    });

    $('#blog-edit').prop('disabled', true);

    $('#text-content-editor').append($('#text_content').val());

    $('#text-content-editor img').each(function() {
        if ($(this).parent().is('figure'))
                remove_caption($(this));
    });

    $('#text-content-editor').summernote(summernoteConfig);

    $('#blog-edit').click(function() {
        var editor = $('#text-content-editor');
        $('#blog-preview').prop('disabled', false);
        $('#blog-edit').prop('disabled', true);
        summernoteConfig['focus'] = true;
        editor.find('img').each(function() {
            if ($(this).parent().is('figure'))
                remove_caption($(this));
        });
        editor.summernote(summernoteConfig);
        load_tooltips();
    });

    $('#blog-preview').click(function() {
        var editor = $('#text-content-editor');
        $('#blog-preview').prop('disabled', true);
        $('#blog-edit').prop('disabled', false);
        editor.summernote('destroy');
        editor.find('img').each(function() {
            add_caption($(this));
        });
        var aHTML = editor.html();
        $('text_content').val(aHTML);
    });

    cropInput($('#thumb-crop'), $('#thumb-input'), inputThumbCallback)

    $('#thumb-zoomIn').click(function() {
        $('#thumb-crop').cropper('zoom', 0.1);
    });
    $('#thumb-zoomOut').click(function() {
        $('#thumb-crop').cropper('zoom', -0.1);
    });
    $('#thumb-rotateLeft').click(function() {
        $('#thumb-crop').cropper('rotate', 45);
    });
    $('#thumb-rotateRight').click(function() {
        $('#thumb-crop').cropper('rotate', -45);
    });
    $('#thumb-save').click(function() {
        var thumbDataURL = $('#thumb-crop').cropper('getDataURL');
        $('#thumb').val(thumbDataURL);
        $('#thumb-img').attr('src', thumbDataURL);

        $('#thumb-img').show();
        $('.thumb-buttons').show();

        $('#thumb-preview').hide();
        $('.crop-buttons').hide();
        $('.thumb-crop').hide();

        $('#thumb-crop').cropper('destroy');
        $('#thumb-crop').attr('src', '');
    });

    $('#publish-date').datepicker({
        format: "dd/mm/yyyy",
        todayBtn: "linked",
        keyboardNavigation: false,
        forceParse: false,
        calendarWeeks: true,
        autoclose: true
    });

    var text_max = 500;
    $('[name=textarea-feedback]').html(text_max + ' ' + dataviva.dictionary['characters_left']);

    $('#text_call').keyup(function() {
        var text_length = $(this).val().length;
        var text_remaining = text_max - text_length;
        $(this).siblings('[name=textarea-feedback]').html(text_remaining + ' ' + dataviva.dictionary['characters_left']);
    });

    load_tooltips();

    $('#blog-form').submit(function() {
        $('#blog-form > button[type=submit]').prop('disabled', true);
        $('#summernote').hide();

        var submittingForm = dataviva.ui.loading('#blog-form');
        submittingForm.text(dataviva.dictionary['loading'] + "...");

        $('#text-content-editor').summernote('destroy');

        $('#text-content-editor img').each(function() {
            if ($(this).parent().is('figure') == false)
               add_caption($(this));
        });

        var pt_html = $('#text-content-editor').html();
        $('#text_content').val(pt_html);
        if ($('#text-content-editor').summernote('isEmpty')) {
            $('#text_content').val('');
        }

        return true;
    });
});
<|endoftext|>


<commit_before>'use strict';

let Sensor = require('../Sensor');

const DEFAULT_CONDITION = {
  sensorId:  null,
  attribute: null,
  operator:  null,
  value:     null,
};

/**
 * Condition
 *
 * Condition object
 */
class Condition {
  /**
   * Constructor
   *
   * @param {Object} condition Condition
   */
  constructor(condition) {
    this.condition = Object.assign({}, DEFAULT_CONDITION);

    for (let key in condition) {
      this.condition[key] = condition[key];
    }
  }

  /**
   * Get sensor id
   *
   * @return {int} Sensor Id
   */
  get sensorId() {
    return this.condition.sensorId;
  }

  /**
   * Set sensor id
   *
   * @param {string} sensorId Sensor Id
   */
  set sensorId(sensorId) {
    this.condition.sensorId = String(sensorId);
  }

  /**
   * Get attribute
   *
   * @return {string} Attribute
   */
  get attribute() {
    return this.condition.attribute;
  }

  /**
   * Set attribute
   *
   * @param {string} attribute Attribute
   */
  set attribute(attribute) {
    this.condition.attribute = String(attribute);
  }

  /**
   * Get operator
   *
   * @return {string} Operator
   */
  get operator() {
    return this.condition.operator;
  }

  /**
   * Set operator
   *
   * @param {string} operator Operator
   */
  set operator(operator) {
    this.condition.operator = String(operator);
  }

  /**
   * Get value
   *
   * @return {mixed} Value
   */
  get value() {
    return this.condition.value;
  }

  /**
   * Set value
   *
   * @param {mixed} value Value
   */
  set value(value) {
    this.condition.value = value;
  }

  /**
   * When (field changes)
   *
   * @param {string} attribute State attribute
   *
   * @return {Condition} This object
   */
  when(attribute) {
    this.attribute = String(attribute);

    return this;
  }

  /**
   * Greater than value
   *
   * @param {string} value Value
   */
  greaterThan(value) {
    this.operator = 'greaterThan';
    this.value    = value;
  }

  /**
   * Less than value
   *
   * @param {string} value Value
   */
  lessThan(value) {
    this.operator = 'lessThan';
    this.value    = value;
  }

  /**
   * Equals value
   *
   * @param {string} value Value
   */
  equals(value) {
    this.operator = 'equals';
    this.value    = value;
  }

  /**
   * Changes (value changes)
   */
  changes() {
    this.operator = 'changes';
    this.value    = null;
  }
}

module.exports = Condition;
<commit_msg>GitHub #15 - Don't need to import sensor<commit_after>'use strict';

const DEFAULT_CONDITION = {
  sensorId:  null,
  attribute: null,
  operator:  null,
  value:     null,
};

/**
 * Condition
 *
 * Condition object
 */
class Condition {
  /**
   * Constructor
   *
   * @param {Object} condition Condition
   */
  constructor(condition) {
    this.condition = Object.assign({}, DEFAULT_CONDITION);

    for (let key in condition) {
      this.condition[key] = condition[key];
    }
  }

  /**
   * Get sensor id
   *
   * @return {int} Sensor Id
   */
  get sensorId() {
    return this.condition.sensorId;
  }

  /**
   * Set sensor id
   *
   * @param {string} sensorId Sensor Id
   */
  set sensorId(sensorId) {
    this.condition.sensorId = String(sensorId);
  }

  /**
   * Get attribute
   *
   * @return {string} Attribute
   */
  get attribute() {
    return this.condition.attribute;
  }

  /**
   * Set attribute
   *
   * @param {string} attribute Attribute
   */
  set attribute(attribute) {
    this.condition.attribute = String(attribute);
  }

  /**
   * Get operator
   *
   * @return {string} Operator
   */
  get operator() {
    return this.condition.operator;
  }

  /**
   * Set operator
   *
   * @param {string} operator Operator
   */
  set operator(operator) {
    this.condition.operator = String(operator);
  }

  /**
   * Get value
   *
   * @return {mixed} Value
   */
  get value() {
    return this.condition.value;
  }

  /**
   * Set value
   *
   * @param {mixed} value Value
   */
  set value(value) {
    this.condition.value = value;
  }

  /**
   * When (field changes)
   *
   * @param {string} attribute State attribute
   *
   * @return {Condition} This object
   */
  when(attribute) {
    this.attribute = String(attribute);

    return this;
  }

  /**
   * Greater than value
   *
   * @param {string} value Value
   */
  greaterThan(value) {
    this.operator = 'greaterThan';
    this.value    = value;
  }

  /**
   * Less than value
   *
   * @param {string} value Value
   */
  lessThan(value) {
    this.operator = 'lessThan';
    this.value    = value;
  }

  /**
   * Equals value
   *
   * @param {string} value Value
   */
  equals(value) {
    this.operator = 'equals';
    this.value    = value;
  }

  /**
   * Changes (value changes)
   */
  changes() {
    this.operator = 'changes';
    this.value    = null;
  }
}

module.exports = Condition;
<|endoftext|>


<commit_before>/* ============================================================================

 >4SESz.,     _,     ,gSEE2zx.,_        .azx                    ,w.
@Sh. "QEE3.  JEE3.  &ss  `*4EEEEE2x.,_  "EEV  ,aS5^;dEEEE2x.,   VEEF  _
\E2`_,gF4EEEx.?jF   EE5L       `*4EEEEE2zpn..ZEEF ;sz.  `*EEESzw.w* '|EE.
  ,dEEF   `"?j]  _,_   ,_  _,     _,.     L.EEEF  !EEF  _,,  `"``    EE7   ,,_
 :EEE7 ,ws,`|EEL`JEEL`JEE)`JEEL zE5` E3. / [EE3  ,w.  zE2` Ek .zE5^JZE3.,6EF [3
 {EEE. VEE7.EE2  AE3. EEV  ZEEL{EEL ws. ;  [EE1  EEEt{E3. JEELEE3. JE5LJEEF ,w,
  \EEk,,>^ JEEL,@EEF ZE5L,ZE5^ "Q3. V2`.    \EEk,,J' "Q[ yE2^ VE[_zEE[,"QEL V5F
          ,ss  :EE7 ;EEF               L,szzw..            ,.,            ``
          \E5.,E5F  EE1.              /; ``*4EEEZhw._      EEEL
            ````     ``              JEEE.     `"45EEEhw.,,,]

From 2010 till ∞
typecode-js v 0.1
*/

// This module uses jQuery Hashchange (http://benalman.com/projects/jquery-hashchange-plugin/)
// as a fallback to emulate pushstate behavior on browsers that don't support pushstate.
// The hashchange plugin subsequently requires jQuery Migrate (https://github.com/jquery/jquery-migrate)
// if being used with jQuery version 1.9 +

define(['jquery', 'NICookies', 'NIseed'], function($, Cookies) {

    var window = this,
    NI = window.NI;

    function PushstateHelper(options) {

        var self = this, o, internal, fn, handlers;

        o = $.extend({
            app: null,
            use_hash: false
        }, options);

        internal = {
            name: 'mod.PushstateHelper',
            initial_state: false,
            previous_path: o.use_hash ?
                window.location.hash.replace('#', '') : window.location.pathname
        };
        internal.initial_state = internal.previous_path;

        fn = {
            init: function() {
                $(document).on('click', '.js-use-pushstate, .js-simulate-pushstate, .js-do-popstate', handlers.doc_click);

                $(window)
                    .on('popstate', handlers.popstate)
                    .on('pushstate', handlers.pushstate)
                    .on('simulate-pushstate', handlers.simulate_pushstate);

                if (o.use_hash) {
                    require(['jquery_migrate', 'hashchange'], function() {
                        $(window).on('hashchange', handlers.hashchange);
                        fn.statechange(window.location.pathname);
                    });
                } else {
                    fn.statechange(window.location.pathname);
                }
            },
            statechange: function(pathname, data){
                var path_components, _event_data, cookies;

                if (o.use_hash) {
                    pathname = pathname.replace('#', '');
                }

                path_components = PushstateHelper.get_path_components(pathname);

                _event_data = {
                    path: pathname,
                    components: path_components,
                    data: data ? data : {}
                };

                if (data && data['extraPrev']) {
                    cookies = new Cookies();
                    cookies.set_cookie('return-to-path', data['extraPrev']);
                }

                _event_data.data.previous_path = internal.previous_path;

                o.app.events.trigger('navigationEvent:Pushstate', _event_data);

                internal.previous_path = _event_data.path;
            },

            get_path_components: function(){
                return internal.components;
            }
        };

        handlers = {
            doc_click: function(e, d) {
                var $t, _href, _data;
                $t = $(this);
                if (!$t.hasClass('js-ignore-prevent-default')){
                    e.preventDefault();
                }
                _href = $t.attr('HREF');
                _data = $t.data();
                if($t.hasClass('js-use-pushstate')){
                    e.stopImmediatePropagation();
                    if(o.use_hash){
                        window.location.hash = _href;
                    } else {
                        history.pushState(null, null, _href);
                    }
                    fn.statechange(_href, _data);
                } else if($t.hasClass('js-simulate-pushstate')) {
                    e.stopImmediatePropagation();
                    fn.statechange(_href, _data);
                } else if($t.hasClass('js-do-popstate')) {
                    e.stopImmediatePropagation();
                    history.back();
                }
            },
            popstate: function(e, d) {
                var pathname, cur;
                if(o.use_hash){
                    pathname = window.location.hash;
                    cur = pathname.replace('#', '');
                } else {
                    cur = pathname = window.location.pathname;
                }
                if (internal.previous_path == cur && internal.initial_state == cur) {
                    internal.initial_state = false;
                    return;
                }
                fn.statechange(pathname, d);
            },
            pushstate: function(e, d) {
                if(o.use_hash){
                    if(window.location.hash != d.pathname){
                        window.location.hash = d.pathname;
                    }
                } else {
                    if(window.location.pathname != d.pathname){
                        history.pushState(null, null, d.pathname);
                    }
                }
                if(!d || !d.prevent_propagation){
                    fn.statechange(d.pathname, d);
                }
            },
            simulate_pushstate: function(e, d) {
                if(!d || !d.prevent_propagation){
                    fn.statechange(d.pathname, d);
                }
            },
            hashchange: function(e, d) {
                if (!d || !d.prevent_propagation) {
                    fn.statechange(window.location.hash);
                }
            }
        };

        this.get_path_components = fn.get_path_components;

        fn.init();
        console.log(internal);
    }

    PushstateHelper.get_path_components = function(path){
        var components, position;
        if(path){
            components = path.split('/');
            position = components.length;
            while(position--){
                if(!components[position].length){
                    components.splice(position,1);
                }
            }
            return components;
        }
    };

    PushstateHelper.get_get_params = function() {
        var d, get_str, get_components;
        d = {};
        get_str = window.location.search;
        if (!get_str || !get_str.length) {
            return d;
        }
        // first character is always '?'
        get_str = get_str.substring(1);
        get_components = get_str.split('&');
        $.each(get_components, function(i, component) {
            var pair;
            pair = component.split('=');
            if (pair.length) {
                d[pair[0]] = pair[1] ? pair[1] : null;
            }
        });
        return d;
    };

    NI.PushstateHelper = PushstateHelper;

    return PushstateHelper;

});
<commit_msg>DEV-701 workaround for issue with safari, skip initial popstate<commit_after>/* ============================================================================

 >4SESz.,     _,     ,gSEE2zx.,_        .azx                    ,w.
@Sh. "QEE3.  JEE3.  &ss  `*4EEEEE2x.,_  "EEV  ,aS5^;dEEEE2x.,   VEEF  _
\E2`_,gF4EEEx.?jF   EE5L       `*4EEEEE2zpn..ZEEF ;sz.  `*EEESzw.w* '|EE.
  ,dEEF   `"?j]  _,_   ,_  _,     _,.     L.EEEF  !EEF  _,,  `"``    EE7   ,,_
 :EEE7 ,ws,`|EEL`JEEL`JEE)`JEEL zE5` E3. / [EE3  ,w.  zE2` Ek .zE5^JZE3.,6EF [3
 {EEE. VEE7.EE2  AE3. EEV  ZEEL{EEL ws. ;  [EE1  EEEt{E3. JEELEE3. JE5LJEEF ,w,
  \EEk,,>^ JEEL,@EEF ZE5L,ZE5^ "Q3. V2`.    \EEk,,J' "Q[ yE2^ VE[_zEE[,"QEL V5F
          ,ss  :EE7 ;EEF               L,szzw..            ,.,            ``
          \E5.,E5F  EE1.              /; ``*4EEEZhw._      EEEL
            ````     ``              JEEE.     `"45EEEhw.,,,]

From 2010 till ∞
typecode-js v 0.1
*/

// This module uses jQuery Hashchange (http://benalman.com/projects/jquery-hashchange-plugin/)
// as a fallback to emulate pushstate behavior on browsers that don't support pushstate.
// The hashchange plugin subsequently requires jQuery Migrate (https://github.com/jquery/jquery-migrate)
// if being used with jQuery version 1.9 +

define(['jquery', 'NICookies', 'NIseed'], function($, Cookies) {

    var window = this,
    NI = window.NI;

    function PushstateHelper(options) {

        var self = this, o, internal, fn, handlers;

        o = $.extend({
            app: null,
            use_hash: false
        }, options);

        internal = {
            name: 'mod.PushstateHelper',
            initial_state: false,
            previous_path: o.use_hash ?
                window.location.hash.replace('#', '') : window.location.pathname
        };
        internal.initial_state = internal.previous_path;

        fn = {
            init: function() {
                $(document).on('click', '.js-use-pushstate, .js-simulate-pushstate, .js-do-popstate', handlers.doc_click);

                $(window).load(function () {
                    setTimeout(function () {
                        $(window).on('popstate', handlers.popstate);
                    }, 0);
                });

                $(window)
                    .on('pushstate', handlers.pushstate)
                    .on('simulate-pushstate', handlers.simulate_pushstate);

                if (o.use_hash) {
                    require(['jquery_migrate', 'hashchange'], function() {
                        $(window).on('hashchange', handlers.hashchange);
                        fn.statechange(window.location.pathname);
                    });
                } else {
                    fn.statechange(window.location.pathname);
                }
            },
            statechange: function(pathname, data){
                var path_components, _event_data, cookies;

                if (o.use_hash) {
                    pathname = pathname.replace('#', '');
                }

                path_components = PushstateHelper.get_path_components(pathname);

                _event_data = {
                    path: pathname,
                    components: path_components,
                    data: data ? data : {}
                };

                if (data && data['extraPrev']) {
                    cookies = new Cookies();
                    cookies.set_cookie('return-to-path', data['extraPrev']);
                }

                _event_data.data.previous_path = internal.previous_path;

                o.app.events.trigger('navigationEvent:Pushstate', _event_data);

                internal.previous_path = _event_data.path;
            },

            get_path_components: function(){
                return internal.components;
            }
        };

        handlers = {
            doc_click: function(e, d) {
                var $t, _href, _data;
                $t = $(this);
                if (!$t.hasClass('js-ignore-prevent-default')){
                    e.preventDefault();
                }
                _href = $t.attr('HREF');
                _data = $t.data();
                if($t.hasClass('js-use-pushstate')){
                    e.stopImmediatePropagation();
                    if(o.use_hash){
                        window.location.hash = _href;
                    } else {
                        history.pushState(null, null, _href);
                    }
                    fn.statechange(_href, _data);
                } else if($t.hasClass('js-simulate-pushstate')) {
                    e.stopImmediatePropagation();
                    fn.statechange(_href, _data);
                } else if($t.hasClass('js-do-popstate')) {
                    e.stopImmediatePropagation();
                    history.back();
                }
            },
            popstate: function(e, d) {
                var pathname, cur;
                if(o.use_hash){
                    pathname = window.location.hash;
                    cur = pathname.replace('#', '');
                } else {
                    cur = pathname = window.location.pathname;
                }
                if (internal.previous_path == cur && internal.initial_state == cur) {
                    internal.initial_state = false;
                    return;
                }
                fn.statechange(pathname, d);
            },
            pushstate: function(e, d) {
                if(o.use_hash){
                    if(window.location.hash != d.pathname){
                        window.location.hash = d.pathname;
                    }
                } else {
                    if(window.location.pathname != d.pathname){
                        history.pushState(null, null, d.pathname);
                    }
                }
                if(!d || !d.prevent_propagation){
                    fn.statechange(d.pathname, d);
                }
            },
            simulate_pushstate: function(e, d) {
                if(!d || !d.prevent_propagation){
                    fn.statechange(d.pathname, d);
                }
            },
            hashchange: function(e, d) {
                if (!d || !d.prevent_propagation) {
                    fn.statechange(window.location.hash);
                }
            }
        };

        this.get_path_components = fn.get_path_components;

        fn.init();
        console.log(internal);
    }

    PushstateHelper.get_path_components = function(path){
        var components, position;
        if(path){
            components = path.split('/');
            position = components.length;
            while(position--){
                if(!components[position].length){
                    components.splice(position,1);
                }
            }
            return components;
        }
    };

    PushstateHelper.get_get_params = function() {
        var d, get_str, get_components;
        d = {};
        get_str = window.location.search;
        if (!get_str || !get_str.length) {
            return d;
        }
        // first character is always '?'
        get_str = get_str.substring(1);
        get_components = get_str.split('&');
        $.each(get_components, function(i, component) {
            var pair;
            pair = component.split('=');
            if (pair.length) {
                d[pair[0]] = pair[1] ? pair[1] : null;
            }
        });
        return d;
    };

    NI.PushstateHelper = PushstateHelper;

    return PushstateHelper;

});
<|endoftext|>


<commit_before>;(function () {

    // Utility functions
    function rtrim (str, charlist) {
      // Removes trailing whitespace
      //
      // version: 1109.2015
      // discuss at: http://phpjs.org/functions/rtrim
      // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
      // +      input by: Erkekjetter
      // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
      // +   bugfixed by: Onno Marsman
      // +   input by: rem
      // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
      // *     example 1: rtrim('    Kevin van Zonneveld    ');
      // *     returns 1: '    Kevin van Zonneveld'
      charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\\$1');
      var re = new RegExp('[' + charlist + ']+$', 'g');
      return (str + '').replace(re, '');
    }

    function getParameterByName(name) {
      name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
      var regexS = "[\\?&]" + name + "=([^&#]*)";
      var regex = new RegExp(regexS);
      var results = regex.exec(window.location.search);
      if(results == null)
        return undefined;
      else
        return decodeURIComponent(results[1].replace(/\+/g, " "));
    }

    // Info
    var scraper = {};
    scraper.base = window.location.protocol + "//" + window.location.hostname + "/";
    scraper.path = document.location.pathname;
    scraper.url = document.location.href;
    scraper.scanned = 0;

    var config = {};
    config.banned = [
        'http://ds.issuemediagroup.com'
    ];
    config.need = 8;

    var formatSrc = function (src) {

        // add protocol to relative urls
        if( src.substring(0, 2) === "//" ) {
            src = document.location.protocol + src;
        }

        // prepend site if missing
        if( ! src.match(/^https?:\/\//g) ) {

            // relative to site root
            if( src.substring(0,1) === "/" ) {
                src = scraper.url + src;
            }
            // no slash, relative to base
            else {
                src = scraper.base + scraper.path + '/' + src;
            }

        }

        return src;

    };

    var calcGCD = function(size) {
        var a = size.x, b = size.y;
        var remander = 0;
        while (b !== 0) {
            remainder = a % b;
            a = b;
            b = remainder;
        }
        return Math.abs(a);
    };

    var calcAspect = function(size) {
        if ( ! size.x || ! size.y ) return 1;
        var gcd = calcGCD(size);
        return (size.x / gcd) / (size.y / gcd);
    };

    // Filter out unwanted images
    var filterImage = function (img) {

        var src, ext, height = $(img).width(), width = $(img).height(), aspect;

        src = $(img).attr('src');
		if (!src) return false;

        ext = src.split('.').pop(); // This could break with query string... kitten.jpg?size=large

        src = formatSrc(src);

        // valid extension?
        if( ! ext.match(/(jpg|jpeg|gif|png)/i) ) { return false; }

        aspect = calcAspect({x: width, y: height});

        if( height < 50 || width < 85 || aspect < 0.4 || aspect > 4 ) { return false; }

        return {
            url: src,
            title: $(img).attr('title'),
            height: height,
            width: width
        };

    };

    // Retrieve & filter images from current page
    var getImages = function () {

        // Old-skool base tag
        var base = $('base');
        if( base.length > 0 ) {
            scraper.base = rtrim($('base').first().attr('href'), '/') + '/';
        }

        // All images
        var images = $('img'), filtered = [], srcs = {};

        // Grab the open graph image
        var ogimage = $('meta[property="og:image"]');
        var ogtmp;
        if( ogimage.length > 0 ) {
            ogtmp = $('<img>').prop({
                'src': $(ogimage).text(),
                'class': 'opengraph',
                'width': 1000, // High priority
                'height': 1000
            });
            images.push(ogtmp);
        }

        // Cycle through all images
        var i = 0, l=images.length, result, img;
        for(; i < l; i++) {

            scraper.scanned += 1;

            img = images[i];

            // Have we seen this image already?
            if( !! srcs[$(img).attr('src')] ) {
                // Yep, skip it
                continue;
            } else {
                // Nope, remember it
                srcs[$(img).attr('src')] = true;
            }

            result = filterImage(img);

            if( result !== false ) {
                filtered.push(result);
            }

        }

        var pow = Math.pow;
        filtered.sort(function (a, b) {
            return pow(pow(b.width, 2) + pow(b.height, 2), 1/2) - pow(pow(a.width, 2) + pow(a.height, 2), 1/2);
        });

        return filtered.slice(0, config.need);

    };

    var getVideoSource = function () {

        var v;

        // Youtube
        if( scraper.base.match(/youtube.com/i) ) {
            v = getParameterByName('v');
            if( v ) {
                return 'http://www.youtube.com/v/' + v + '?autoplay=1';
            }
        }

        // Vimeo
        if( scraper.url.match(/vimeo.com\/(\d+)$/i) ) {
            v = scraper.path.split('/')[1];
            return 'https://secure.vimeo.com/moogaloop.swf?clip_id=' + v + '&autoplay=1';
        }

        // Soundcloud
        if( scraper.base.match(/soundcloud.com/i) ) {
            return 'https://player.soundcloud.com/player.swf?url=' + encodeURIComponent(scraper.url) + '&color=3b5998&auto_play=true&show_artwork=false';
        }

        return false;

    };

    var getDescription = function () {
        var text = $('p').first().text().substring(0, 200);
        return $('meta[property="og:description"]').text() || $('meta[name=description]').prop('content') || (text.length > 0 ? text + '...' : false) || '';
    };

    var getDetails = function () {

        var start = (new Date()).getTime();

        var data = {
            original: scraper.url,
            title: $('meta[property="og:title"]').prop('content') || document.title || $('h1').first().text() || '',
            description: getDescription(),
            images: getImages(),
            source: getVideoSource()
        };

        data.details = {
            process: ((new Date()).getTime() - start) + 'ms',
            scanned: scraper.scanned
        };

        return data;

    };

    // Wait for a request for data
    console.log("buffer-scraper injected");
    xt.port.on("buffer_details_request", function() {
        console.log("buffer-scraper has recieved buffer_details_request");
        xt.port.emit("buffer_details", getDetails());
    });
    // Tell the background page which port to use
    // to get data from the scraper
    xt.port.emit("buffer_register_scraper");
}());<commit_msg>Rm Console.logs<commit_after>;(function () {

    // Utility functions
    function rtrim (str, charlist) {
      // Removes trailing whitespace
      //
      // version: 1109.2015
      // discuss at: http://phpjs.org/functions/rtrim
      // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
      // +      input by: Erkekjetter
      // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
      // +   bugfixed by: Onno Marsman
      // +   input by: rem
      // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
      // *     example 1: rtrim('    Kevin van Zonneveld    ');
      // *     returns 1: '    Kevin van Zonneveld'
      charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\\$1');
      var re = new RegExp('[' + charlist + ']+$', 'g');
      return (str + '').replace(re, '');
    }

    function getParameterByName(name) {
      name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
      var regexS = "[\\?&]" + name + "=([^&#]*)";
      var regex = new RegExp(regexS);
      var results = regex.exec(window.location.search);
      if(results == null)
        return undefined;
      else
        return decodeURIComponent(results[1].replace(/\+/g, " "));
    }

    // Info
    var scraper = {};
    scraper.base = window.location.protocol + "//" + window.location.hostname + "/";
    scraper.path = document.location.pathname;
    scraper.url = document.location.href;
    scraper.scanned = 0;

    var config = {};
    config.banned = [
        'http://ds.issuemediagroup.com'
    ];
    config.need = 8;

    var formatSrc = function (src) {

        // add protocol to relative urls
        if( src.substring(0, 2) === "//" ) {
            src = document.location.protocol + src;
        }

        // prepend site if missing
        if( ! src.match(/^https?:\/\//g) ) {

            // relative to site root
            if( src.substring(0,1) === "/" ) {
                src = scraper.url + src;
            }
            // no slash, relative to base
            else {
                src = scraper.base + scraper.path + '/' + src;
            }

        }

        return src;

    };

    var calcGCD = function(size) {
        var a = size.x, b = size.y;
        var remander = 0;
        while (b !== 0) {
            remainder = a % b;
            a = b;
            b = remainder;
        }
        return Math.abs(a);
    };

    var calcAspect = function(size) {
        if ( ! size.x || ! size.y ) return 1;
        var gcd = calcGCD(size);
        return (size.x / gcd) / (size.y / gcd);
    };

    // Filter out unwanted images
    var filterImage = function (img) {

        var src, ext, height = $(img).width(), width = $(img).height(), aspect;

        src = $(img).attr('src');
		if (!src) return false;

        ext = src.split('.').pop(); // This could break with query string... kitten.jpg?size=large

        src = formatSrc(src);

        // valid extension?
        if( ! ext.match(/(jpg|jpeg|gif|png)/i) ) { return false; }

        aspect = calcAspect({x: width, y: height});

        if( height < 50 || width < 85 || aspect < 0.4 || aspect > 4 ) { return false; }

        return {
            url: src,
            title: $(img).attr('title'),
            height: height,
            width: width
        };

    };

    // Retrieve & filter images from current page
    var getImages = function () {

        // Old-skool base tag
        var base = $('base');
        if( base.length > 0 ) {
            scraper.base = rtrim($('base').first().attr('href'), '/') + '/';
        }

        // All images
        var images = $('img'), filtered = [], srcs = {};

        // Grab the open graph image
        var ogimage = $('meta[property="og:image"]');
        var ogtmp;
        if( ogimage.length > 0 ) {
            ogtmp = $('<img>').prop({
                'src': $(ogimage).text(),
                'class': 'opengraph',
                'width': 1000, // High priority
                'height': 1000
            });
            images.push(ogtmp);
        }

        // Cycle through all images
        var i = 0, l=images.length, result, img;
        for(; i < l; i++) {

            scraper.scanned += 1;

            img = images[i];

            // Have we seen this image already?
            if( !! srcs[$(img).attr('src')] ) {
                // Yep, skip it
                continue;
            } else {
                // Nope, remember it
                srcs[$(img).attr('src')] = true;
            }

            result = filterImage(img);

            if( result !== false ) {
                filtered.push(result);
            }

        }

        var pow = Math.pow;
        filtered.sort(function (a, b) {
            return pow(pow(b.width, 2) + pow(b.height, 2), 1/2) - pow(pow(a.width, 2) + pow(a.height, 2), 1/2);
        });

        return filtered.slice(0, config.need);

    };

    var getVideoSource = function () {

        var v;

        // Youtube
        if( scraper.base.match(/youtube.com/i) ) {
            v = getParameterByName('v');
            if( v ) {
                return 'http://www.youtube.com/v/' + v + '?autoplay=1';
            }
        }

        // Vimeo
        if( scraper.url.match(/vimeo.com\/(\d+)$/i) ) {
            v = scraper.path.split('/')[1];
            return 'https://secure.vimeo.com/moogaloop.swf?clip_id=' + v + '&autoplay=1';
        }

        // Soundcloud
        if( scraper.base.match(/soundcloud.com/i) ) {
            return 'https://player.soundcloud.com/player.swf?url=' + encodeURIComponent(scraper.url) + '&color=3b5998&auto_play=true&show_artwork=false';
        }

        return false;

    };

    var getDescription = function () {
        var text = $('p').first().text().substring(0, 200);
        return $('meta[property="og:description"]').text() || $('meta[name=description]').prop('content') || (text.length > 0 ? text + '...' : false) || '';
    };

    var getDetails = function () {

        var start = (new Date()).getTime();

        var data = {
            original: scraper.url,
            title: $('meta[property="og:title"]').prop('content') || document.title || $('h1').first().text() || '',
            description: getDescription(),
            images: getImages(),
            source: getVideoSource()
        };

        data.details = {
            process: ((new Date()).getTime() - start) + 'ms',
            scanned: scraper.scanned
        };

        return data;

    };

    // Wait for a request for data
    xt.port.on("buffer_details_request", function() {
        xt.port.emit("buffer_details", getDetails());
    });
    // Tell the background page which port to use
    // to get data from the scraper
    xt.port.emit("buffer_register_scraper");
}());<|endoftext|>


<commit_before>// Licensed to Cloudera, Inc. under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  Cloudera, Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

export const AUTOCOMPLETE_API_PREFIX = '/api/editor/autocomplete/';
export const SAMPLE_API_PREFIX = '/notebook/api/sample/';
export const EXECUTE_API_PREFIX = '/api/editor/execute/'; // Dups with api.ts
export const DOCUMENTS_API = '/desktop/api2/doc/';
export const DOCUMENTS_SEARCH_API = '/desktop/api2/docs/';
export const GET_HUE_CONFIG_API = '/desktop/api2/get_hue_config';
export const FETCH_CONFIG_API = '/api/get_config/';
export const HDFS_API_PREFIX = '/filebrowser/view=' + encodeURIComponent('/');
export const ADLS_API_PREFIX = '/filebrowser/view=' + encodeURIComponent('adl:/');
export const ABFS_API_PREFIX = '/filebrowser/view=' + encodeURIComponent('ABFS://');
export const GIT_API_PREFIX = '/desktop/api/vcs/contents/';
export const S3_API_PREFIX = '/filebrowser/view=' + encodeURIComponent('s3a://');
export const IMPALA_INVALIDATE_API = '/impala/api/invalidate';
export const CONFIG_SAVE_API = '/desktop/api/configurations/save/';
export const CONFIG_APPS_API = '/desktop/api/configurations';
export const SOLR_COLLECTIONS_API = '/indexer/api/indexes/list/';
export const SOLR_FIELDS_API = '/indexer/api/index/list/';
export const DASHBOARD_TERMS_API = '/dashboard/get_terms';
export const DASHBOARD_STATS_API = '/dashboard/get_stats';
export const FORMAT_SQL_API = '/notebook/api/format';
export const GIST_API = '/desktop/api2/gist/';
export const GET_SLACK_CHANNELS = '/desktop/slack/api/channels/get';
export const SEND_SLACK_MESSAGE = '/desktop/slack/api/message/send';
export const TOPO_URL = '/desktop/topo/';

export const SEARCH_API = '/desktop/api/search/entities';
export const INTERACTIVE_SEARCH_API = '/desktop/api/search/entities_interactive';

export const CREATE_SESSION_API = '/api/editor/create_session'; // Note: dup by api.ts
export const CLOSE_SESSION_API = '/api/editor/close_session'; // Note: dup by api.ts
export const FETCH_RESULT_SIZE_API = '/notebook/api/fetch_result_size';
export const FETCH_RESULT_DATA_API = '/notebook/api/fetch_result_data';
export const GET_LOGS_API = '/api/editor/get_logs';
export const CANCEL_STATEMENT_API = '/notebook/api/cancel_statement';
export const CLOSE_STATEMENT_API = '/notebook/api/close_statement';
export const CHECK_STATUS_API = '/api/editor/check_status';

export const HBASE_API_PREFIX = '/hbase/api/';
export const SAVE_TO_FILE_API = '/filebrowser/save';

export const NAV_API = {
  ADD_TAGS: '/metadata/api/catalog/add_tags',
  DELETE_TAGS: '/metadata/api/catalog/delete_tags',
  FIND_ENTITY: '/metadata/api/catalog/find_entity',
  LIST_TAGS: '/metadata/api/catalog/list_tags',
  UPDATE_PROPERTIES: '/metadata/api/catalog/update_properties'
};
<commit_msg>[frontend] Change INTERACTIVE_SEARCH_API to public<commit_after>// Licensed to Cloudera, Inc. under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  Cloudera, Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

export const AUTOCOMPLETE_API_PREFIX = '/api/editor/autocomplete/';
export const SAMPLE_API_PREFIX = '/notebook/api/sample/';
export const EXECUTE_API_PREFIX = '/api/editor/execute/'; // Dups with api.ts
export const DOCUMENTS_API = '/desktop/api2/doc/';
export const DOCUMENTS_SEARCH_API = '/desktop/api2/docs/';
export const GET_HUE_CONFIG_API = '/desktop/api2/get_hue_config';
export const FETCH_CONFIG_API = '/api/get_config/';
export const HDFS_API_PREFIX = '/filebrowser/view=' + encodeURIComponent('/');
export const ADLS_API_PREFIX = '/filebrowser/view=' + encodeURIComponent('adl:/');
export const ABFS_API_PREFIX = '/filebrowser/view=' + encodeURIComponent('ABFS://');
export const GIT_API_PREFIX = '/desktop/api/vcs/contents/';
export const S3_API_PREFIX = '/filebrowser/view=' + encodeURIComponent('s3a://');
export const IMPALA_INVALIDATE_API = '/impala/api/invalidate';
export const CONFIG_SAVE_API = '/desktop/api/configurations/save/';
export const CONFIG_APPS_API = '/desktop/api/configurations';
export const SOLR_COLLECTIONS_API = '/indexer/api/indexes/list/';
export const SOLR_FIELDS_API = '/indexer/api/index/list/';
export const DASHBOARD_TERMS_API = '/dashboard/get_terms';
export const DASHBOARD_STATS_API = '/dashboard/get_stats';
export const FORMAT_SQL_API = '/notebook/api/format';
export const GIST_API = '/desktop/api2/gist/';
export const GET_SLACK_CHANNELS = '/desktop/slack/api/channels/get';
export const SEND_SLACK_MESSAGE = '/desktop/slack/api/message/send';
export const TOPO_URL = '/desktop/topo/';

export const SEARCH_API = '/desktop/api/search/entities';
export const INTERACTIVE_SEARCH_API = '/api/metadata/search/entities_interactive';

export const CREATE_SESSION_API = '/api/editor/create_session'; // Note: dup by api.ts
export const CLOSE_SESSION_API = '/api/editor/close_session'; // Note: dup by api.ts
export const FETCH_RESULT_SIZE_API = '/notebook/api/fetch_result_size';
export const FETCH_RESULT_DATA_API = '/notebook/api/fetch_result_data';
export const GET_LOGS_API = '/api/editor/get_logs';
export const CANCEL_STATEMENT_API = '/notebook/api/cancel_statement';
export const CLOSE_STATEMENT_API = '/notebook/api/close_statement';
export const CHECK_STATUS_API = '/api/editor/check_status';

export const HBASE_API_PREFIX = '/hbase/api/';
export const SAVE_TO_FILE_API = '/filebrowser/save';

export const NAV_API = {
  ADD_TAGS: '/metadata/api/catalog/add_tags',
  DELETE_TAGS: '/metadata/api/catalog/delete_tags',
  FIND_ENTITY: '/metadata/api/catalog/find_entity',
  LIST_TAGS: '/metadata/api/catalog/list_tags',
  UPDATE_PROPERTIES: '/metadata/api/catalog/update_properties'
};
<|endoftext|>


<commit_before>var fs = require('fs');

var routes = function(api, next){

  api.routes = {};
  api.routes.routes = {};
  api.routes.routesFile = api.projectRoot + '/routes.js'; //deprecated, see github issue #450

  api.routes.verbs = ['get', 'post', 'put', 'patch', 'delete'];

  ////////////////////////////////////////////////////////////////////////////
  // route processing for web clients
  api.routes.processRoute = function(connection, pathParts){
    if(connection.params.action === undefined || api.actions.actions[connection.params.action] === undefined){
      var method = connection.rawConnection.method.toLowerCase();
      if(method === 'head'){ method = 'get'; }
      for(var i in api.routes.routes[method]){
        var route = api.routes.routes[method][i];
        var match = api.routes.matchURL(pathParts, route.path);
        if(match.match === true){
          for(var param in match.params){
            try{
              var decodedName = decodeURIComponent(param.replace(/\+/g, ' '));
              var decodedValue = decodeURIComponent(match.params[param].replace(/\+/g, ' '));
              connection.params[decodedName] = decodedValue;
            }catch(e){
              // malformed URL
            }
          }
          connection.params.action = route.action;
          break;
        }
      }
    }
  }

  api.routes.matchURL = function(pathParts, match){
    var response = {match: false, params: {} }
    var matchParts = match.split('/');
    var regexp = '';
    var variable = '';

    if(matchParts[0] === ''){ matchParts.splice(0, 1) }
    if(matchParts[(matchParts.length - 1)] === ''){ matchParts.pop() }

    if(matchParts.length !== pathParts.length){
      return response;
    }

    for(var i in matchParts){
      var part = matchParts[i];
      if(!pathParts[i]){
        return response;
      } else if(part[0] === ':' && part.indexOf('(') < 0){
        variable = part.replace(':', '');
        response.params[variable] = pathParts[i];
      } else if(part[0] === ':' && part.indexOf('(') >= 0){
        variable = part.replace(':', '').split('(')[0];
        regexp = part.split('(')[1];
        var matches = pathParts[i].match(new RegExp(regexp.substring(0, regexp.length - 1), 'g'));
        if(matches){
          response.params[variable] = pathParts[i];
        } else {
          return response;
        }
      } else {
        if(pathParts[i] === null || pathParts[i] === undefined || pathParts[i].toLowerCase() !== matchParts[i].toLowerCase()){
          return response;
        }
      }
    }

    response.match = true;
    return response;
  }

  // load in the routes file
  api.routes.loadRoutes = function(rawRoutes){
    var counter = 0;
    api.routes.routes = { 'get': [], 'post': [], 'put': [], 'patch' : [], 'delete': [] };

    if(!rawRoutes){
      //depricated, see github issue #450
      if(fs.existsSync(api.routes.routesFile)){
        api.log('Using the routes.js in your project root is depricated.', 'warning')
        delete require.cache[require.resolve(api.routes.routesFile)];
        rawRoutes = require(api.routes.routesFile).routes;
      }
    }

    var v, verb;
    for(var i in rawRoutes){
      var method = i.toLowerCase();
      for(var j in rawRoutes[i]){
        var route = rawRoutes[i][j];
        if(method === 'all'){
          for(v in api.routes.verbs){
            verb = api.routes.verbs[v];
            api.routes.routes[verb].push({ path: route.path, action: route.action });
          }
        } else {
          api.routes.routes[method].push({ path: route.path, action: route.action });
        }
        counter++;
      }
    }

    api.params.postVariables = api.utils.arrayUniqueify(api.params.postVariables)
    api.log(counter + ' routes loaded from ' + api.routes.routesFile, 'debug');

    if(api.config.servers.web && api.config.servers.web.simpleRouting === true){
      var simplePaths = [];
      for(var action in api.actions.actions){
        simplePaths.push('/' + action);
        // api.routes.verbs.forEach(function(verb){
        for(v in api.routes.verbs){
          verb = api.routes.verbs[v];
          api.routes.routes[verb].push({ path: '/' + action, action: action });
        }
      }
      api.log(simplePaths.length + ' simple routes loaded from action names', 'debug');

      api.log('routes:', 'debug', api.routes.routes);
    }
  };

  //depricated, see github issue #450
  if(fs.existsSync(api.routes.routesFile)){
    api.routes.loadRoutes();
    api.watchFileAndAct(api.routes.routesFile, function(){
      api.routes.loadRoutes();
    });
  }else{
    api.routes.loadRoutes(api.config.routes);
  }

  next();
}

/////////////////////////////////////////////////////////////////////
// exports
exports.routes = routes;
<commit_msg>Fixes #504<commit_after>var fs = require('fs');

var routes = function(api, next){

  api.routes = {};
  api.routes.routes = {};

  api.routes.verbs = ['get', 'post', 'put', 'patch', 'delete'];

  ////////////////////////////////////////////////////////////////////////////
  // route processing for web clients
  api.routes.processRoute = function(connection, pathParts){
    if(connection.params.action === undefined || api.actions.actions[connection.params.action] === undefined){
      var method = connection.rawConnection.method.toLowerCase();
      if(method === 'head'){ method = 'get'; }
      for(var i in api.routes.routes[method]){
        var route = api.routes.routes[method][i];
        var match = api.routes.matchURL(pathParts, route.path);
        if(match.match === true){
          for(var param in match.params){
            try{
              var decodedName = decodeURIComponent(param.replace(/\+/g, ' '));
              var decodedValue = decodeURIComponent(match.params[param].replace(/\+/g, ' '));
              connection.params[decodedName] = decodedValue;
            }catch(e){
              // malformed URL
            }
          }
          connection.params.action = route.action;
          break;
        }
      }
    }
  }

  api.routes.matchURL = function(pathParts, match){
    var response = {match: false, params: {} }
    var matchParts = match.split('/');
    var regexp = '';
    var variable = '';

    if(matchParts[0] === ''){ matchParts.splice(0, 1) }
    if(matchParts[(matchParts.length - 1)] === ''){ matchParts.pop() }

    if(matchParts.length !== pathParts.length){
      return response;
    }

    for(var i in matchParts){
      var part = matchParts[i];
      if(!pathParts[i]){
        return response;
      } else if(part[0] === ':' && part.indexOf('(') < 0){
        variable = part.replace(':', '');
        response.params[variable] = pathParts[i];
      } else if(part[0] === ':' && part.indexOf('(') >= 0){
        variable = part.replace(':', '').split('(')[0];
        regexp = part.split('(')[1];
        var matches = pathParts[i].match(new RegExp(regexp.substring(0, regexp.length - 1), 'g'));
        if(matches){
          response.params[variable] = pathParts[i];
        } else {
          return response;
        }
      } else {
        if(pathParts[i] === null || pathParts[i] === undefined || pathParts[i].toLowerCase() !== matchParts[i].toLowerCase()){
          return response;
        }
      }
    }

    response.match = true;
    return response;
  }

  // load in the routes file
  api.routes.loadRoutes = function(rawRoutes){
    var counter = 0;
    api.routes.routes = { 'get': [], 'post': [], 'put': [], 'patch' : [], 'delete': [] };

    if(!rawRoutes){
      if(api.config.routes){
        rawRoutes = api.config.routes;
      }
    }

    var v, verb;
    for(var i in rawRoutes){
      var method = i.toLowerCase();
      for(var j in rawRoutes[i]){
        var route = rawRoutes[i][j];
        if(method === 'all'){
          for(v in api.routes.verbs){
            verb = api.routes.verbs[v];
            api.routes.routes[verb].push({ path: route.path, action: route.action });
          }
        } else {
          api.routes.routes[method].push({ path: route.path, action: route.action });
        }
        counter++;
      }
    }

    api.params.postVariables = api.utils.arrayUniqueify(api.params.postVariables)
    api.log(counter + ' routes loaded from ' + api.routes.routesFile, 'debug');

    if(api.config.servers.web && api.config.servers.web.simpleRouting === true){
      var simplePaths = [];
      for(var action in api.actions.actions){
        simplePaths.push('/' + action);
        // api.routes.verbs.forEach(function(verb){
        for(v in api.routes.verbs){
          verb = api.routes.verbs[v];
          api.routes.routes[verb].push({ path: '/' + action, action: action });
        }
      }
      api.log(simplePaths.length + ' simple routes loaded from action names', 'debug');

      api.log('routes:', 'debug', api.routes.routes);
    }
  };

  api.routes.loadRoutes();
  next();
}

/////////////////////////////////////////////////////////////////////
// exports
exports.routes = routes;
<|endoftext|>


<commit_before>module.exports = function( grunt ) {

grunt.registerTask( "default", [ "jshint", "jscs", "test" ] );

};
<commit_msg>Build: Add format task<commit_after>module.exports = function( grunt ) {

grunt.registerTask( "default", [ "jshint", "jscs", "test" ] );

grunt.registerTask( "format", [ "esformatter", "clangformat" ] );

};
<|endoftext|>


<commit_before>import React from 'react';
import Highlight from '../../helpers/highlight.js';
import { filter, filterExample, filterSolution } from './code/filter.js';
import { reduce, reduceExample, reduceSolution} from './code/reduce.js';

export default () => (

    {console.log(filter)}

Level 2 - Filter and Reduce

Lesson 1 - Filter

Objectives:

 Teach what is the predicate function

 Teach the logic behind filter

 Teach that item is pushed to array only if predicate return true

 Teach student to walk step by step thru the function using pseudo code

 Practice creating function on the fly

 Help student to create an example

 Help student to walk thru every iteration of the function using example

Technical:

 Create function filter

 Filter should use each to iterate

 Filter should accept collection and predicate as parameters

 Filter should work on arrays and objects

 Filter should return new array with values that pass predicate test

Boilerplate:

              <Highlight props={filter} />

Example:

              <Highlight props={filterExample} />

Solution:

              <Highlight props={filterSolution} />

Lesson 2 - Reduce

Objectives:

 Teach how to use 'Each' to create Reduce function

 Teach about accumulator and startValue

 Teach that accumulator always takes atleast TWO arguments Memo and Item

 Teach that startValue will get modified(Memo) by accumulator on every iteration

 Teach that startValue is the value that will get returned in the end as the final result

 Teach that startValue is optional

 Teach that if starting value is not provided Reduce will use first item in the collection as the startValue

 Teach that if starting value is not provided Reduce will NOT iterate over the first item because it will become the startValue

Technical:

 Create function reduce

 Reduce should apply accumulator to every item in the collection

 Reduce should pass result of accumulator(MEMO) to every invocation of accumulator

 Reduce should use first item in the collection if start is not provided

 Reduce should NOT invoke accumulator on first item if start in not provided

 Reduce should return a new array

 Reduce should use start value as final result

Boilerplate:

              <Highlight props={reduce} />

Example:

              <Highlight props={reduceExample} />

Solution:

              <Highlight props={reduceSolution} />

);
<commit_msg>fix html layout<commit_after>import React from 'react';
import Highlight from '../../helpers/highlight.js';
import { filter, filterExample, filterSolution } from './code/filter.js';
import { reduce, reduceExample, reduceSolution} from './code/reduce.js';

export default () => (

    {console.log(filter)}

Level 2 - Filter and Reduce

Lesson 1 - Filter

Objectives:

 Teach what is the predicate function

 Teach the logic behind filter

 Teach that item is pushed to array only if predicate return true

 Teach student to walk step by step thru the function using pseudo code

 Practice creating function on the fly

 Help student to create an example

 Help student to walk thru every iteration of the function using example

Technical:

 Create function filter

 Filter should use each to iterate

 Filter should accept collection and predicate as parameters

 Filter should work on arrays and objects

 Filter should return new array with values that pass predicate test

Boilerplate:

              <Highlight props={filter} />

Example:

              <Highlight props={filterExample} />

Solution:

              <Highlight props={filterSolution} />

Lesson 2 - Reduce

Objectives:

 Teach how to use 'Each' to create Reduce function

 Teach about accumulator and startValue

 Teach that accumulator always takes atleast TWO arguments Memo and Item

 Teach that startValue will get modified(Memo) by accumulator on every iteration

 Teach that startValue is the value that will get returned in the end as the final result

 Teach that startValue is optional

 Teach that if starting value is not provided Reduce will use first item in the collection as the startValue

 Teach that if starting value is not provided Reduce will NOT iterate over the first item because it will become the startValue

Technical:

 Create function reduce

 Reduce should apply accumulator to every item in the collection

 Reduce should pass result of accumulator(MEMO) to every invocation of accumulator

 Reduce should use first item in the collection if start is not provided

 Reduce should NOT invoke accumulator on first item if start in not provided

 Reduce should return a new array

 Reduce should use start value as final result

Boilerplate:

              <Highlight props={reduce} />

Example:

              <Highlight props={reduceExample} />

Solution:

              <Highlight props={reduceSolution} />

);
<|endoftext|>


<commit_before>import React from 'react';
import Highlight from '../../helpers/highlight.js';
import { map, mapExample, mapUsingReduce } from './code/map.js';
import { filter, filterExample, filterUsingReduce } from './code/filter.js';

export default () => (

Level 4 - Map And Filter Using Reduce

Lesson 1 - Map usign Reduce

Objectives:

 Teach how to write Map using Reduce

 Teach that an empty array can be a startValue

 Help student to create example

 Help student to walk thru every iteration - STEP by STEP

Technical:

 Create function Map

 Map should accept collection and callback as parameters

 Map should use Reduce

Boilerplate:

              <Highlight props={map} />

Example

              <Highlight props={mapExample} />

Solution:

              <Highlight props={mapUsingReduce} />

Lesson 2 - Filter using Reduce

Objectives:

 Create function each

 Create function each

 Create function each

Technical:

 Create function map

 Map should apply callback to every item in the collection

 Map should accept collection and callback as parameters

 Map should work on arrays and objects

 Map should return a new array

Boilerplate:

              <Highlight props={filter} />

Example

              <Highlight props={filterExample} />

Solution:

              <Highlight props={filterUsingReduce} />

);
<commit_msg>finish level 4<commit_after>import React from 'react';
import Highlight from '../../helpers/highlight.js';
import { map, mapExample, mapUsingReduce } from './code/map.js';
import { filter, filterExample, filterUsingReduce } from './code/filter.js';

export default () => (

Level 4 - Map And Filter Using Reduce

Lesson 1 - Map usign Reduce

Objectives:

 Teach how to write Map using Reduce

 Teach that an empty array can be a startValue

 Teach that an startValue will become result on first iteration

 Teach that result will be updated on every iteration

 Refer to reduce implementation

 Help student to create example

 Help student to walk thru every iteration - STEP by STEP

Technical:

 Create function Map

 Map should accept collection and callback as parameters

 Map should use Reduce

Boilerplate:

              <Highlight props={map} />

Example

              <Highlight props={mapExample} />

Solution:

              <Highlight props={mapUsingReduce} />

Lesson 2 - Filter using Reduce

Objectives:

 Create function filter

 Teach that an empty array can be a startValue

 Teach that an startValue will become result on first iteration

 Teach that result will be updated on every iteration

 Refer to reduce implementation

 Help student to create example

 Help student to walk thru every iteration - STEP by STEP

Technical:

 Create function filer

 Filter should accept collection and predicate

 Filter should use reduce

 Filter should accept empty array as startValue

Boilerplate:

              <Highlight props={filter} />

Example

              <Highlight props={filterExample} />

Solution:

              <Highlight props={filterUsingReduce} />

);
<|endoftext|>


<commit_before>"use strict";

class gsuiSVGDefs {
	constructor() {
		const svg = gsuiSVGDefs.create( "svg" );

		this.rootElement = svg;
		this._defs = new Map();
		this._idPref = `gsuiSVGDefs_${ gsuiSVGDefs._id++ }_`;
		this._elDefs = gsuiSVGDefs.create( "defs" );
		this._optResolution = 0;
		this._w =
		this._h = 0;
		Object.seal( this );

		svg.style.display = "none";
		svg.classList.add( "gsuiSVGDefs" );
		svg.append( this._elDefs );
		document.body.prepend( svg );
	}

	static create( elem ) {
		return document.createElementNS( "http://www.w3.org/2000/svg", elem );
	}

	setDefaultViewbox( w, h ) {
		this._w = w;
		this._h = h;
	}
	empty() {
		this._defs.forEach( def => def.g.remove() );
		this._defs.clear();
	}
	delete( id ) {
		this._defs.get( id ).g.remove();
		this._defs.delete( id );
	}
	add( id, w = 0, h = 0, ...elems ) {
		const g = gsuiSVGDefs.create( "g" );

		g.id = `${ this._idPref }${ id }`;
		g.append( ...elems );
		this._elDefs.append( g );
		this._defs.set( id, { g, w, h } );
	}
	update( id, w, h, ...elems ) {
		const def = this._defs.get( id ),
			g = def.g;

		def.w = w;
		def.h = h;
		while ( g.lastChild ) {
			g.lastChild.remove();
		}
		g.append( ...elems );
	}
	createSVG( id ) {
		const svg = gsuiSVGDefs.create( "svg" ),
			use = gsuiSVGDefs.create( "use" ),
			def = this._defs.get( id ) || {},
			viewBox = `0 0 ${ def.w || this._w } ${ def.h || this._h }`;

		svg.dataset.id = id;
		use.setAttributeNS( "http://www.w3.org/1999/xlink", "href", `#${ this._idPref }${ id }` );
		svg.setAttribute( "viewBox", viewBox );
		svg.setAttribute( "preserveAspectRatio", "none" );
		svg.append( use );
		return svg;
	}
	setSVGViewbox( svg, x, w ) {
		const h = this._defs.get( svg.dataset.id ).h;

		svg.setAttribute( "viewBox", `${ x } 0 ${ w } ${ h }` );
	}
}

gsuiSVGDefs._id = 0;
<commit_msg>gsuiSVGDefs: add an error msg when we try to create an ID already present<commit_after>"use strict";

class gsuiSVGDefs {
	constructor() {
		const svg = gsuiSVGDefs.create( "svg" );

		this.rootElement = svg;
		this._defs = new Map();
		this._idPref = `gsuiSVGDefs_${ gsuiSVGDefs._id++ }_`;
		this._elDefs = gsuiSVGDefs.create( "defs" );
		this._optResolution = 0;
		this._w =
		this._h = 0;
		Object.seal( this );

		svg.style.display = "none";
		svg.classList.add( "gsuiSVGDefs" );
		svg.append( this._elDefs );
		document.body.prepend( svg );
	}

	static create( elem ) {
		return document.createElementNS( "http://www.w3.org/2000/svg", elem );
	}

	setDefaultViewbox( w, h ) {
		this._w = w;
		this._h = h;
	}
	empty() {
		this._defs.forEach( def => def.g.remove() );
		this._defs.clear();
	}
	delete( id ) {
		this._defs.get( id ).g.remove();
		this._defs.delete( id );
	}
	add( id, w = 0, h = 0, ...elems ) {
		if ( this._defs.has( id ) ) {
			console.error( `gsuiSVGDefs: ID already used` );
		} else {
			const g = gsuiSVGDefs.create( "g" );

			g.id = `${ this._idPref }${ id }`;
			g.append( ...elems );
			this._elDefs.append( g );
			this._defs.set( id, { g, w, h } );
		}
	}
	update( id, w, h, ...elems ) {
		const def = this._defs.get( id ),
			g = def.g;

		def.w = w;
		def.h = h;
		while ( g.lastChild ) {
			g.lastChild.remove();
		}
		g.append( ...elems );
	}
	createSVG( id ) {
		const svg = gsuiSVGDefs.create( "svg" ),
			use = gsuiSVGDefs.create( "use" ),
			def = this._defs.get( id ) || {},
			viewBox = `0 0 ${ def.w || this._w } ${ def.h || this._h }`;

		svg.dataset.id = id;
		use.setAttributeNS( "http://www.w3.org/1999/xlink", "href", `#${ this._idPref }${ id }` );
		svg.setAttribute( "viewBox", viewBox );
		svg.setAttribute( "preserveAspectRatio", "none" );
		svg.append( use );
		return svg;
	}
	setSVGViewbox( svg, x, w ) {
		const h = this._defs.get( svg.dataset.id ).h;

		svg.setAttribute( "viewBox", `${ x } 0 ${ w } ${ h }` );
	}
}

gsuiSVGDefs._id = 0;
<|endoftext|>


<commit_before>/*
Wonder how this works?
Storage is the Prototype of both localStorage and sessionStorage.
Got it?
*/

(function() {
  'use strict';

  Storage.prototype.set = function(key, obj) {
    var t = typeof obj;
    if (t==='undefined' || obj===null ) window.removeItem(key);
    window.setItem(key, (t==='object')?JSON.stringify(obj):obj);
  };
  Storage.prototype.get = function(key) {
      var obj = window.getItem(key);
      try {
        var j = JSON.parse(obj);
        if (j && typeof j === "object") return j;
      } catch (e) { }
      return obj;
  };
  Storage.prototype.has = window.hasOwnProperty;
  Storage.prototype.remove = window.removeItem;

  Storage.prototype.keys = function(){
    return Object.keys(window.valueOf());
  };

})();
<commit_msg>partially revert 'this' renaming (should have been done only outside the prototype functions)<commit_after>/*
Wonder how this works?
Storage is the Prototype of both localStorage and sessionStorage.
Got it?
*/

(function() {
  'use strict';

  Storage.prototype.set = function(key, obj) {
    var t = typeof obj;
    if (t==='undefined' || obj===null ) this.removeItem(key);
    this.setItem(key, (t==='object')?JSON.stringify(obj):obj);
  };
  Storage.prototype.get = function(key) {
      var obj = this.getItem(key);
      try {
        var j = JSON.parse(obj);
        if (j && typeof j === "object") return j;
      } catch (e) { }
      return obj;
  };
  Storage.prototype.has = window.hasOwnProperty;
  Storage.prototype.remove = window.removeItem;

  Storage.prototype.keys = function(){
    return Object.keys(this.valueOf());
  };

})();
<|endoftext|>


<commit_before>import { MAX_CHAR_JP, MAX_CHAR_TW } from '../config';
import coroutine                    from 'co';
import fetch                        from 'node-fetch';
import cheerio                      from 'cheerio';
import Character                    from './CharacterClass';

function str2num (str) {
  return parseInt(str.split(',').join(''));
};

function isInteger (num) {
  return typeof num === 'number' && num % 1 === 0;
}

// fetch character data from Japan official website (http://onepiece-treasurecruise.com)
function fetchFromJapan(number) {
  return coroutine(function * () {
    if (!isInteger(number) || number < 1 || number > MAX_CHAR_JP) {
      throw new Error('Invalid parameter: number = ' + number);
    }

    const res = yield fetch('http://onepiece-treasurecruise.com/c-' + number, {
      method: 'GET',
      timeout: 30 * 1000
    });

    const $ = cheerio.load(yield res.text());
    const info0   = $('#left table').eq(0).find('td');
    const info1   = $('#left table').eq(1).find('td');
    const info2   = $('#left table').eq(2).find('td');
    const min     = $('#left table').eq(3).find('tr').eq(1).find('td');
    const max     = $('#left table').eq(3).find('tr').eq(2).find('td');
    const skill   = $('#left table').eq(4).find('td');
    const captain = $('#left table').eq(5).find('td');

    const character = new Character();
    character
      .setNo(number)
      .setName('jp', $('#entry h1').text())
      .setImgUrl(info0.find('img').attr('src'))
      .setType(info1.eq(0).text())
      .addClass(info1.eq(1).text())
      .addClass(info1.eq(2).text())
      .setStar(str2num(info1.eq(3).text()))
      .setCost(str2num(info1.eq(4).text()))
      .setCombo(str2num(info2.eq(1).text()))
      .setMin(
        str2num(min.eq(1).text()),
        str2num(min.eq(2).text()),
        str2num(min.eq(3).text()),
        str2num(min.eq(4).text())
      )
      .setMax(
        str2num(max.eq(1).text()),
        str2num(max.eq(2).text()),
        str2num(max.eq(3).text()),
        str2num(max.eq(4).text())
      )
      .setSpecialAbility(
        'jp',
        skill.eq(1).text(),
        skill.eq(3).text())
      .setCaptainEffect(
        'jp',
        captain.eq(1).text(),
        captain.eq(3).text()
      );

    return character;
  });
};

// fetch character data from Taiwan official website (http://line-optc.com/tw)
function fetchFromTaiwan(number) {
  return coroutine(function * () {
    if (!isInteger(number) || number < 1 || number > MAX_CHAR_TW) {
      throw new Error('Invalid parameter: number = ' + number);
    }

    const res = yield fetch('http://line-optc.com/tw/c-' + number, {
        method: 'GET',
        timeout: 30 * 1000
    });

    const $ = cheerio.load(yield res.text());
    const info0   = $('#left table').eq(0).find('td');
    const info1   = $('#left table').eq(1).find('td');
    const min     = $('#left table').eq(2).find('tr').eq(1).find('td');
    const max     = $('#left table').eq(2).find('tr').eq(2).find('td');
    const skill   = $('#left table').eq(3).find('td');
    const captain = $('#left table').eq(4).find('td');

    const character = new Character();
    character
      .setNo(number)
      .setName('tw', $('#entry h1').text())
      .setImgUrl(info0.find('img').attr('src'))
      .setType(info1.eq(0).text())
      .addClass(info1.eq(1).text())
      .setStar(str2num(info1.eq(2).text()))
      .setCost(str2num(info1.eq(3).text()))
      .setCombo(str2num(info1.eq(4).text()))
      .setMin(
        str2num(min.eq(1).text()),
        str2num(min.eq(2).text()),
        str2num(min.eq(3).text()),
        str2num(min.eq(4).text())
      )
      .setMax(
        str2num(max.eq(1).text()),
        str2num(max.eq(2).text()),
        str2num(max.eq(3).text()),
        str2num(max.eq(4).text())
      )
      .setSpecialAbility(
        'tw',
        skill.eq(1).text(),
        skill.eq(3).text()
      )
      .setCaptainEffect(
        'tw',
        captain.eq(1).text(),
        captain.eq(3).text()
      );

    return character;
  });
};

/*
 * fetchCharacter
 *
 * @number
 */
export default function fetchCharacter(number) {
  return coroutine(function * () {
    let japan = null, taiwan = null;

    try {
      // if fetch japan failed, no need to fetch taiwan
      japan = yield fetchFromJapan(number);
      taiwan = yield fetchFromTaiwan(number);
    } catch (e) {
      console.log(e);
    }

    if (japan === null) {
      throw new Error(`character no.${number} is not found`);
    }

    if (taiwan === null) {
      return japan;
    }

    // merge taiwan into japan
    japan.setName('tw', taiwan.name.tw);
    japan.setSpecialAbility('tw', taiwan.specialAbility.tw.name, taiwan.specialAbility.tw.content);
    japan.setCaptainEffect('tw', taiwan.captainEffect.tw.name, taiwan.captainEffect.tw.content);

    return japan;
  })
};
<commit_msg>[lib] define error code 'CHARACTER_NOT_FOUND' and 'CHARACTER_OUT_OF_RANGE'<commit_after>import { MAX_CHAR_JP, MAX_CHAR_TW } from '../config';
import coroutine                    from 'co';
import fetch                        from 'node-fetch';
import cheerio                      from 'cheerio';
import Character                    from './CharacterClass';

function str2num (str) {
  return parseInt(str.split(',').join(''));
};

function isInteger (num) {
  return typeof num === 'number' && num % 1 === 0;
}

// fetch character data from Japan official website (http://onepiece-treasurecruise.com)
function fetchFromJapan(number) {
  return coroutine(function * () {
    if (!isInteger(number) || number < 1 || number > MAX_CHAR_JP) {
      let err = new Error(`character no.${number} is out of range (1 ~ ${MAX_CHAR_JP}) [JP]`);
      err.code = 'CHARACTER_OUT_OF_RANGE';
      throw err;
    }

    const res = yield fetch('http://onepiece-treasurecruise.com/c-' + number, {
      method: 'GET',
      timeout: 30 * 1000
    });

    const $ = cheerio.load(yield res.text());
    const name = $('#entry h1').text();
    if (name === '？？？') {
      let err = new Error(`character no.${number} is not found from Japan.`);
      err.code = 'CHARACTER_NOT_FOUND';
      throw err;
    }

    const info0   = $('#left table').eq(0).find('td');
    const info1   = $('#left table').eq(1).find('td');
    const info2   = $('#left table').eq(2).find('td');
    const min     = $('#left table').eq(3).find('tr').eq(1).find('td');
    const max     = $('#left table').eq(3).find('tr').eq(2).find('td');
    const skill   = $('#left table').eq(4).find('td');
    const captain = $('#left table').eq(5).find('td');

    const character = new Character();
    character
      .setNo(number)
      .setName('jp', name)
      .setImgUrl(info0.find('img').attr('src'))
      .setType(info1.eq(0).text())
      .addClass(info1.eq(1).text())
      .addClass(info1.eq(2).text())
      .setStar(str2num(info1.eq(3).text()))
      .setCost(str2num(info1.eq(4).text()))
      .setCombo(str2num(info2.eq(1).text()))
      .setMin(
        str2num(min.eq(1).text()),
        str2num(min.eq(2).text()),
        str2num(min.eq(3).text()),
        str2num(min.eq(4).text())
      )
      .setMax(
        str2num(max.eq(1).text()),
        str2num(max.eq(2).text()),
        str2num(max.eq(3).text()),
        str2num(max.eq(4).text())
      )
      .setSpecialAbility(
        'jp',
        skill.eq(1).text(),
        skill.eq(3).text())
      .setCaptainEffect(
        'jp',
        captain.eq(1).text(),
        captain.eq(3).text()
      );

    return character;
  });
};

// fetch character data from Taiwan official website (http://line-optc.com/tw)
function fetchFromTaiwan(number) {
  return coroutine(function * () {
    if (!isInteger(number) || number < 1 || number > MAX_CHAR_TW) {
      let err = new Error(`character no.${number} is out of range (1 ~ ${MAX_CHAR_TW}) [TW]`);
      err.code = 'CHARACTER_OUT_OF_RANGE';
      throw err;
    }

    const res = yield fetch('http://line-optc.com/tw/c-' + number, {
        method: 'GET',
        timeout: 30 * 1000
    });

    const $ = cheerio.load(yield res.text());
    const name = $('#entry h1').text();
    if (name === '') {
      let err = new Error(`character no.${number} is not found from Taiwan.`);
      err.code = 'CHARACTER_NOT_FOUND';
      throw err;
    }

    const info0   = $('#left table').eq(0).find('td');
    const info1   = $('#left table').eq(1).find('td');
    const min     = $('#left table').eq(2).find('tr').eq(1).find('td');
    const max     = $('#left table').eq(2).find('tr').eq(2).find('td');
    const skill   = $('#left table').eq(3).find('td');
    const captain = $('#left table').eq(4).find('td');

    const character = new Character();
    character
      .setNo(number)
      .setName('tw', name)
      .setImgUrl(info0.find('img').attr('src'))
      .setType(info1.eq(0).text())
      .addClass(info1.eq(1).text())
      .setStar(str2num(info1.eq(2).text()))
      .setCost(str2num(info1.eq(3).text()))
      .setCombo(str2num(info1.eq(4).text()))
      .setMin(
        str2num(min.eq(1).text()),
        str2num(min.eq(2).text()),
        str2num(min.eq(3).text()),
        str2num(min.eq(4).text())
      )
      .setMax(
        str2num(max.eq(1).text()),
        str2num(max.eq(2).text()),
        str2num(max.eq(3).text()),
        str2num(max.eq(4).text())
      )
      .setSpecialAbility(
        'tw',
        skill.eq(1).text(),
        skill.eq(3).text()
      )
      .setCaptainEffect(
        'tw',
        captain.eq(1).text(),
        captain.eq(3).text()
      );

    return character;
  });
};

/*
 * fetchCharacter
 *
 * @number
 */
export default function fetchCharacter(number) {
  return coroutine(function * () {
    // if fetch from japan failed, throw error
    let character = yield fetchFromJapan(number);

    try {
      const taiwan = yield fetchFromTaiwan(number);

      // merge taiwan into character
      character.setName('tw', taiwan.name.tw);
      character.setSpecialAbility('tw', taiwan.specialAbility.tw.name, taiwan.specialAbility.tw.content);
      character.setCaptainEffect('tw', taiwan.captainEffect.tw.name, taiwan.captainEffect.tw.content);

    } catch (e) {
      if (e.code !== 'CHARACTER_NOT_FOUND' && e.code !== 'CHARACTER_OUT_OF_RANGE') {
        throw e;
      }
    }

    return character;
  })
};
<|endoftext|>


<commit_before>

/**
 * Основная область имен модуля.
 *
 * @namespace
 */
var pg = {};

/**
 * @const
 * @type {string}
 */
pg.VERSION = '1.0.2';

/**
 * @typedef {Object.<string, (number|string|boolean|null)>}
 */
pg.Row;

/**
 * @typedef {Array.<!pg.Row>}
 */
pg.Table;

/**
 * @param {string} string Исходная строка.
 * @return {string} Экранированная строка.
 */
pg.escapeString = function(string) {};

/**
 * @param {!Array} array Массив строк.
 * @return {string} Массив экранированных строк через запятую.
 */
pg.escapeArray = function(array) {};

/**
 * @param {string} query Запрос.
 * @param {!Object} params Параметры запроса.
 * @return {string} Готовый запрос.
 */
pg.prepareQuery = function(query, params) {};

/**
 * @param {number} size Размер пула.
 * @param {!Object} options Настройки соединения с базой.
 * @param {function(!Error)=} opt_errorHandler Обработчик ошибок подключения.
 */
pg.init = function(size, options, opt_errorHandler) {};

/**
 * @param {string} query Запрос.
 * @param {function(!pg.Table)} complete Обработчик результата.
 * @param {function(string, number=)} cancel Обработчик ошибки.
 */
pg.exec = function(query, complete, cancel) {};

/**
 * @param {string} query Запрос.
 * @param {!Object} params Параметры запроса.
 * @param {function(!pg.Table)} complete Обработчик результата.
 * @param {function(string, number=)} cancel Обработчик ошибки.
 */
pg.execPrepared = function(query, params, complete, cancel) {};

/**
 * Разрушение пула.
 */
pg.destroy = function() {};

<commit_msg>remove externs<commit_after><|endoftext|>


<commit_before>(function() {

  var Surface = function(object) {
    this.object = object;
  };

  Two.Utils.extend(Surface.prototype, {

    limits: function(min, max) {

      var min_exists = typeof min !== 'undefined';
      var max_exists = typeof max !== 'undefined';

      if (!max_exists && !min_exists) {
        return { min: this.min, max: this.max };
      }

      this.min = min_exists ? min : this.min;
      this.max = max_exists ? max : this.max;

      return this;

    },

    apply: function(px, py, s) {
      this.object.translation.set(px, py);
      this.object.scale = s;
      return this;
    }

  });

  var ZUI = Two.ZUI = function(group, domElement) {

    this.limits = {
      scale: ZUI.Limit.clone(),
      x: ZUI.Limit.clone(),
      y: ZUI.Limit.clone()
    };

    this.viewport = domElement || document.body;
    this.viewportOffset = {
      matrix: new Two.Matrix()
    };

    this.surfaceMatrix = new Two.Matrix();

    this.surfaces = [];
    this.reset();
    this.updateSurface();

    this.add(new Surface(group));

  };

  Two.Utils.extend(ZUI, {

    Surface: Surface,

    Clamp: function(v, min, max) {
      return Math.min(Math.max(v, min), max);
    },

    Limit: {
      min: -Infinity,
      max: Infinity,
      clone: function() {
        var result = {};
        for (var k in this) {
          result[k] = this[k];
        }
        return result;
      }
    },

    TranslateMatrix: function(m, x, y) {
      m.elements[2] += x;
      m.elements[5] += y;
      return m;
    },

    PositionToScale: function(pos) {
      return Math.exp(pos);
    },

    ScaleToPosition: function(scale) {
      return Math.log(scale);
    }

  });

  Two.Utils.extend(ZUI.prototype, {

    constructor: ZUI,

    add: function(surface) {
      this.surfaces.push(surface);
      var limits = surface.limits();
      this.addLimits(limits.min, limits.max);
      return this;
    },

    addLimits: function(min, max, type) {

      type = type || 'scale';

      if (typeof min !== 'undefined') {
        if (this.limits[type].min) {
          this.limits[type].min = Math.max(min, this.limits[type].min);
        } else {
          this.limits[type].min = min;
        }
      }

      if (typeof max === 'undefined') {
        return this;
      }

      if (this.limits[type].max) {
        this.limits[type].max = Math.min(max, this.limits[type].max);
      } else {
        this.limits[type].max = max;
      }

      return this;

    },

    /**
     * Conversion Functions
     */

    clientToSurface: function(x, y) {
      this.updateOffset();
      var m = this.surfaceMatrix.inverse();
      var n = this.viewportOffset.matrix.inverse().multiply(x, y, 1);
      return m.multiply.apply(m, [n.x, n.y, n.z]);
    },

    surfaceToClient: function(v) {
      this.updateOffset();
      var vo = this.viewportOffset.matrix.clone();
      var sm = this.surfaceMatrix.multiply.apply(this.surfaceMatrix, [v.x, v.y, v.z]);
      return vo.multiply.apply(vo, [sm.x, sm.y, sm.z]);
    },

    /**
     *
     */

    zoomBy: function(byF, clientX, clientY) {
      var s = ZUI.PositionToScale(this.zoom + byF);
      this.zoomSet(s, clientX, clientY);
      return this;
    },

    zoomSet: function(zoom, clientX, clientY) {

      var newScale = this.fitToLimits(zoom);
      this.zoom = ZUI.ScaleToPosition(newScale);

      if (newScale === this.scale) {
        return this;
      }

      var sf = this.clientToSurface(clientX, clientY);
      var scaleBy = newScale / this.scale;

      this.surfaceMatrix.scale(scaleBy);
      this.scale = newScale;

      var c = this.surfaceToClient(sf);
      var dx = clientX - c.x;
      var dy = clientY - c.y;
      this.translateSurface(dx, dy);

      return this;

    },

    translateSurface: function(x, y) {
      ZUI.TranslateMatrix(this.surfaceMatrix, x, y);
      this.updateSurface();
      return this;
    },

    updateOffset: function() {

      var rect = this.viewport.getBoundingClientRect();
      Two.Utils.extend(this.viewportOffset, rect);

      this.viewportOffset.left -= document.body.scrollLeft;
      this.viewportOffset.top -= document.body.scrollTop;

      this.viewportOffset.matrix
        .identity()
        .translate(this.viewportOffset.left, this.viewportOffset.top);

      return this;

    },

    updateSurface: function() {

      var e = this.surfaceMatrix.elements;
      for (var i = 0; i < this.surfaces.length; i++) {
        this.surfaces[i].apply(e[2], e[5], e[0]);
      }

      return this;

    },

    reset: function() {
      this.zoom = 0;
      this.scale = 1.0;
      this.surfaceMatrix.identity();
      return this;
    },

    fitToLimits: function(s) {
      return ZUI.Clamp(s, this.limits.scale.min, this.limits.scale.max);
    }

  });

})();
<commit_msg>Made JS Version of ZUI ES6 Compliant<commit_after>(function() {

  class Surface {

    constructor(object) {
      this.object = object;
    }

    limits(min, max) {

      const min_exists = typeof min !== 'undefined';
      const max_exists = typeof max !== 'undefined';

      if (!max_exists && !min_exists) {
        return { min: this.min, max: this.max };
      }

      this.min = min_exists ? min : this.min;
      this.max = max_exists ? max : this.max;

      return this;

    }

    apply(px, py, s) {
      this.object.translation.set(px, py);
      this.object.scale = s;
      return this;
    }

  }

  /**
   * @name Two.ZUI
   * @class
   * @param {Two.Group} group - The scene or group to
   * @param {HTMLElement} [domElement=document.body] - The HTML Element to attach event listeners to.
   */
  class ZUI {

    constructor(group, domElement) {

      this.limits = {
        scale: ZUI.Limit.clone(),
        x: ZUI.Limit.clone(),
        y: ZUI.Limit.clone()
      };

      this.viewport = domElement || document.body;
      this.viewportOffset = {
        top: 0,
        left: 0,
        matrix: new Two.Matrix()
      };

      this.surfaceMatrix = new Two.Matrix();

      this.surfaces = [];
      this.reset();
      this.updateSurface();

      this.add(new Surface(group));

    }

    static Surface = Surface;

    static Clamp(v, min, max) {
      return Math.min(Math.max(v, min), max);
    }

    static Limit = {
      min: -Infinity,
      max: Infinity,
      clone: function() {
        const result = {};
        for (let k in this) {
          result[k] = this[k];
        }
        return result;
      }
    }

    static TranslateMatrix(m, x, y) {
      m.elements[2] += x;
      m.elements[5] += y;
      return m;
    }

    static PositionToScale(pos) {
      return Math.exp(pos);
    }

    static ScaleToPosition(scale) {
      return Math.log(scale);
    }

    //

    add(surface) {
      this.surfaces.push(surface);
      const limits = surface.limits();
      this.addLimits(limits.min, limits.max);
      return this;
    }

    addLimits(min, max, type) {

      type = type || 'scale';

      if (typeof min !== 'undefined') {
        if (this.limits[type].min) {
          this.limits[type].min = Math.max(min, this.limits[type].min);
        } else {
          this.limits[type].min = min;
        }
      }

      if (typeof max === 'undefined') {
        return this;
      }

      if (this.limits[type].max) {
        this.limits[type].max = Math.min(max, this.limits[type].max);
      } else {
        this.limits[type].max = max;
      }

      return this;

    }

    clientToSurface(x, y) {
      this.updateOffset();
      const m = this.surfaceMatrix.inverse();
      const n = this.viewportOffset.matrix.inverse().multiply(x, y, 1);
      return m.multiply.apply(m, [n.x, n.y, n.z]);
    }

    surfaceToClient(v) {
      this.updateOffset();
      const vo = this.viewportOffset.matrix.clone();
      const sm = this.surfaceMatrix.multiply.apply(this.surfaceMatrix, [v.x, v.y, v.z]);
      return vo.multiply.apply(vo, [sm.x, sm.y, sm.z]);
    }

    zoomBy(byF, clientX, clientY) {
      const s = ZUI.PositionToScale(this.zoom + byF);
      this.zoomSet(s, clientX, clientY);
      return this;
    }

    zoomSet(zoom, clientX, clientY) {

      const newScale = this.fitToLimits(zoom);
      this.zoom = ZUI.ScaleToPosition(newScale);

      if (newScale === this.scale) {
        return this;
      }

      const sf = this.clientToSurface(clientX, clientY);
      const scaleBy = newScale / this.scale;

      this.surfaceMatrix.scale(scaleBy);
      this.scale = newScale;

      const c = this.surfaceToClient(sf);
      const dx = clientX - c.x;
      const dy = clientY - c.y;
      this.translateSurface(dx, dy);

      return this;

    }

    translateSurface(x, y) {
      ZUI.TranslateMatrix(this.surfaceMatrix, x, y);
      this.updateSurface();
      return this;
    }

    updateOffset() {

      const rect = this.viewport.getBoundingClientRect();

      this.viewportOffset.left = rect.left - document.body.scrollLeft;
      this.viewportOffset.top = rect.top - document.body.scrollTop;

      this.viewportOffset.matrix
        .identity()
        .translate(this.viewportOffset.left, this.viewportOffset.top);

      return this;

    }

    updateSurface() {

      const e = this.surfaceMatrix.elements;
      for (let i = 0; i < this.surfaces.length; i++) {
        this.surfaces[i].apply(e[2], e[5], e[0]);
      }

      return this;

    }

    reset() {
      this.zoom = 0;
      this.scale = 1.0;
      this.surfaceMatrix.identity();
      return this;
    }

    fitToLimits(s) {
      return ZUI.Clamp(s, this.limits.scale.min, this.limits.scale.max);
    }

  }

  Two.ZUI = ZUI;

})();
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var red = require('ansi-red');
var relativePath = require('relative-dest');

module.exports = function linkTo(key, collectionName) {
  var name = collectionName;
  if (typeof name === 'object') {
    name = null;
  }

  name = name || 'pages';

  if (typeof this.app[name] === 'undefined') {
    var msg = 'Invalid collection `' + name + '`';
    console.error(red(msg));
    return '';
  }

  var current = this.context.view;
  var target = this.app.find(key, name);

  if (!target || !Object.keys(target).length) {
    var msg = 'Unable target find `' + key + '` in `' + name + '`';
    console.error(red(msg));
    return '';
  }

  var data = this.app.cache.data;
  var fromDest = current.data.dest;
  var targetDest = target.data.dest;

  return relativePath(fromDest, targetDest);
};
<commit_msg>update "link-to" helper to respect permalinks plugin if available<commit_after>'use strict';

var path = require('path');
var red = require('ansi-red');
var relativePath = require('relative-dest');

module.exports = function linkTo(key, collectionName) {
  var name = collectionName;
  if (typeof name === 'object') {
    name = null;
  }

  name = name || 'pages';

  if (typeof this.app[name] === 'undefined') {
    var msg = 'Invalid collection `' + name + '`';
    console.error(red(msg));
    return '';
  }

  var current = this.context.view;
  var target = this.app.find(key, name);

  if (!target || !Object.keys(target).length) {
    var msg = 'Unable target find `' + key + '` in `' + name + '`';
    console.error(red(msg));
    return '';
  }

  var fromDest = current.data.permalinks ||current.data.dest;
  var targetDest = target.data.permalinks || target.data.dest;

  return relativePath(fromDest, targetDest);
};
<|endoftext|>