<commit_before>;(function (window, document) {

    'use strict';

    var defaultWidths, getKeys, isArray, nextTick, addEvent, getNaturalWidth;

    nextTick = window.requestAnimationFrame ||
               window.mozRequestAnimationFrame ||
               window.webkitRequestAnimationFrame ||
               function (callback) {
                   window.setTimeout(callback, 1000 / 60);
               };

    function applyEach (collection, callbackEach) {
        var i = 0,
            length = collection.length,
            new_collection = [];

        for (; i < length; i++) {
            new_collection[i] = callbackEach(collection[i], i);
        }

        return new_collection;
    }

    function returnDirectValue (value) {
      return value;
    }

    getNaturalWidth = (function(){
        if (document.createElement('img').hasOwnProperty('naturalWidth')) {
            return function (image){ return image.naturalWidth;};
        }
        // IE8 and below lacks the naturalWidth property
        return function (source){
            var img = document.createElement('img');
            img.src = source.src;
            return img.width;
        }
    })()

    addEvent = (function(){
        if (document.addEventListener){
            return function addStandardEventListener(el, eventName, fn){
                return el.addEventListener(eventName, fn, false);
            };
        }
        else {
            return function addIEEventListener(el, eventName, fn){
                return el.attachEvent('on'+eventName, fn);
            };
        }
    })();

    defaultWidths = [96, 130, 165, 200, 235, 270, 304, 340, 375, 410, 445, 485, 520, 555, 590, 625, 660, 695, 736];

    getKeys = typeof Object.keys === 'function' ? Object.keys : function (object) {
        var keys = [],
            key;

        for (key in object) {
            keys.push(key);
        }

        return keys;
    };

    /*
        Construct a new Imager instance, passing an optional configuration object.

        Example usage:

            {
                // Available widths for your images
                availableWidths: [Number],

                // Selector to be used to locate your div placeholders
                selector: '',

                // Class name to give your resizable images
                className: '',

                // If set to true, Imager will update the src attribute of the relevant images
                onResize: Boolean,

                // Toggle the lazy load functionality on or off
                lazyload: Boolean,

                // Used alongside the lazyload feature (helps performance by setting a higher delay)
                scrollDelay: Number
            }

        @param {object} configuration settings
        @return {object} instance of Imager
     */
    function Imager (elements, opts) {
        var self = this,
            doc  = document;

        opts = opts || {};

        if (elements !== undefined) {
            // first argument is selector string
            if (typeof elements === 'string') {
                opts.selector = elements;
                elements = undefined;
            }

            // first argument is the `opts` object, `elements` is implicitly the `opts.selector` string
            else if (typeof elements.length === 'undefined') {
                opts = elements;
                elements = undefined;
            }
        }

        this.imagesOffScreen  = [];
        this.viewportHeight   = doc.documentElement.clientHeight;
        this.selector         = opts.selector || '.delayed-image-load';
        this.className        = opts.className || 'image-replace';
        this.gif              = doc.createElement('img');
        this.gif.src          = 'data:image/gif;base64,R0lGODlhEAAJAIAAAP///wAAACH5BAEAAAAALAAAAAAQAAkAAAIKhI+py+0Po5yUFQA7';
        this.gif.className    = this.className;
        this.gif.alt          = '';
        this.scrollDelay      = opts.scrollDelay || 250;
        this.onResize         = opts.hasOwnProperty('onResize') ? opts.onResize : true;
        this.lazyload         = opts.hasOwnProperty('lazyload') ? opts.lazyload : false;
        this.scrolled         = false;
        this.availablePixelRatios = opts.availablePixelRatios || [1, 2];
        this.availableWidths  = opts.availableWidths || defaultWidths;
        this.onImagesReplaced = opts.onImagesReplaced || function () {};
        this.widthsMap        = {};
        this.refreshPixelRatio();
        this.widthInterpolator = opts.widthInterpolator || returnDirectValue;

        // Needed as IE8 adds a default `width`/`height` attribute…
        this.gif.removeAttribute('height');
        this.gif.removeAttribute('width');

        if (typeof this.availableWidths !== 'function'){
          if (typeof this.availableWidths.length === 'number') {
            this.widthsMap = Imager.createWidthsMap(this.availableWidths, this.widthInterpolator);
          }
          else {
            this.widthsMap = this.availableWidths;
            this.availableWidths = getKeys(this.availableWidths);
          }

          this.availableWidths = this.availableWidths.sort(function (a, b) {
            return a - b;
          });
        }

        if (elements) {
            this.divs = applyEach(elements, returnDirectValue);
            this.selector = null;
        }
        else {
            this.divs = applyEach(doc.querySelectorAll(this.selector), returnDirectValue);
        }

        this.changeDivsToEmptyImages();

        nextTick(function(){
            self.init();
        });
    }

    Imager.prototype.scrollCheck = function(){
        if (this.scrolled) {
            if (!this.imagesOffScreen.length) {
                window.clearInterval(this.interval);
            }

            this.divs = this.imagesOffScreen.slice(0); // copy by value, don't copy by reference
            this.imagesOffScreen.length = 0;
            this.changeDivsToEmptyImages();
            this.scrolled = false;
        }
    };

    Imager.prototype.init = function(){
        this.initialized = true;
        this.checkImagesNeedReplacing(this.divs);

        if (this.onResize) {
            this.registerResizeEvent();
        }

        if (this.lazyload) {
            this.registerScrollEvent();
        }
    };

    Imager.prototype.createGif = function (element) {
        // if the element is already a responsive image then we don't replace it again
        if (element.className.match(new RegExp('(^| )' + this.className + '( |$)'))) {
            return element;
        }

        var elementClassName = element.getAttribute('data-class');
        var elementWidth = element.getAttribute('data-width');
        var gif = this.gif.cloneNode(false);

        if (elementWidth) {
          gif.width = elementWidth;
        }
        gif.className = (elementClassName ? elementClassName + ' ' : '') + this.className;
        gif.setAttribute('data-src', element.getAttribute('data-src'));
        gif.setAttribute('alt', element.getAttribute('data-alt') || this.gif.alt);

        element.parentNode.replaceChild(gif, element);

        return gif;
    };

    Imager.prototype.changeDivsToEmptyImages = function(){
        var self = this;

        applyEach(this.divs, function(element, i){
            if (self.lazyload) {
                if (self.isThisElementOnScreen(element)) {
                    self.divs[i] = self.createGif(element);
                } else {
                    self.imagesOffScreen.push(element);
                }
            } else {
                self.divs[i] = self.createGif(element);
            }
        });

        if (this.initialized) {
            this.checkImagesNeedReplacing(this.divs);
        }
    };

    Imager.prototype.isThisElementOnScreen = function (element) {
        // document.body.scrollTop was working in Chrome but didn't work on Firefox, so had to resort to window.pageYOffset
        // but can't fallback to document.body.scrollTop as that doesn't work in IE with a doctype (?) so have to use document.documentElement.scrollTop
        var offset = Imager.getPageOffset();
        var elementOffsetTop = 0;

        if (element.offsetParent) {
            do {
                elementOffsetTop += element.offsetTop;
            }
            while (element = element.offsetParent);
        }

        return (elementOffsetTop < (this.viewportHeight + offset)) ? true : false;
    };

    Imager.prototype.checkImagesNeedReplacing = function (images) {
        var self = this;

        if (!this.isResizing) {
            this.isResizing = true;
            this.refreshPixelRatio();

            applyEach(images, function(image){
                self.replaceImagesBasedOnScreenDimensions(image);
            });

            this.isResizing = false;
            this.onImagesReplaced(images);
        }
    };

    Imager.prototype.replaceImagesBasedOnScreenDimensions = function (image) {
        var computedWidth, src, naturalWidth;

        naturalWidth = getNaturalWidth(image);
        computedWidth = typeof this.availableWidths === 'function' ? this.availableWidths(image)
                                                                   : this.determineAppropriateResolution(image);

        if (image.src !== this.gif.src && computedWidth <= naturalWidth) {
            return;
        }

        src = this.changeImageSrcToUseNewImageDimensions(image.getAttribute('data-src'), computedWidth);

        image.src = src;
    };

    Imager.prototype.determineAppropriateResolution = function (image) {
      return Imager.getClosestValue(image.getAttribute('width') || image.parentNode.clientWidth, this.availableWidths);
    };

    /**
     * Updates the device pixel ratio value used by Imager
     *
     * It is performed before each replacement loop, in case a user zoomed in/out
     * and thus updated the `window.devicePixelRatio` value.
     *
     * @api
     * @since 1.0.1
     */
    Imager.prototype.refreshPixelRatio = function refreshPixelRatio(){
        this.devicePixelRatio = Imager.getClosestValue(Imager.getPixelRatio(), this.availablePixelRatios);
    };

    Imager.prototype.changeImageSrcToUseNewImageDimensions = function (src, selectedWidth) {
        return src
            .replace(/{width}/g, Imager.transforms.width(selectedWidth, this.widthsMap))
            .replace(/{pixel_ratio}/g, Imager.transforms.pixelRatio(this.devicePixelRatio));
    };

    Imager.getPixelRatio = function getPixelRatio(context){
        return (context || window)['devicePixelRatio'] || 1;
    };

    Imager.createWidthsMap = function createWidthsMap (widths, interpolator) {
        var map = {},
            i   = widths.length;

        while (i--) {
            map[widths[i]] = interpolator(widths[i]);
        }

        return map;
    };

    Imager.transforms = {
        pixelRatio: function (value) {
            return value === 1 ? '' : '-' + value + 'x';
        },
        width: function (width, map) {
            return map[width] || width;
        }
    };

    /**
     * Returns the closest upper value.
     *
     * ```js
     * var candidates = [1, 1.5, 2];
     *
     * Imager.getClosestValue(0.8, candidates); // -> 1
     * Imager.getClosestValue(1, candidates); // -> 1
     * Imager.getClosestValue(1.3, candidates); // -> 1.5
     * Imager.getClosestValue(3, candidates); // -> 2
     * ```
     *
     * @api
     * @since 1.0.1
     * @param {Number} baseValue
     * @param {Array.<Number>} candidates
     * @returns {Number}
     */
    Imager.getClosestValue = function getClosestValue(baseValue, candidates){
        var i             = candidates.length,
            selectedWidth = candidates[i - 1];

        baseValue = parseFloat(baseValue, 10);

        while (i--) {
            if (baseValue <= candidates[i]) {
                selectedWidth = candidates[i];
            }
        }

        return selectedWidth;
    };

    Imager.prototype.registerResizeEvent = function(){
        var self = this;

        addEvent(window, 'resize', function(){
            self.checkImagesNeedReplacing(self.divs);
        });
    };

    Imager.prototype.registerScrollEvent = function (){
        var self = this;

        this.scrolled = false;

        this.interval = window.setInterval(function(){
            self.scrollCheck();
        }, self.scrollDelay);

        addEvent(window, 'scroll', function(){
            self.scrolled = true;
        });
    };

    Imager.getPageOffsetGenerator = function getPageVerticalOffset(testCase){
        if(testCase){
            return function(){ return window.pageYOffset; };
        }
        else {
            return function(){ return document.documentElement.scrollTop; };
        }
    };

    // This form is used because it seems impossible to stub `window.pageYOffset`
    Imager.getPageOffset = Imager.getPageOffsetGenerator(Object.prototype.hasOwnProperty.call(window, 'pageYOffset'));

    // Exporting for testing purpose
    Imager.applyEach = applyEach;

    /* global module, exports: true, define */
    if (typeof module === 'object' && typeof module.exports === 'object') {
        // CommonJS, just export
        module.exports = exports = Imager;
    } else if (typeof define === 'function' && define.amd) {
        // AMD support
        define(function () { return Imager; });
    } else if (typeof window === 'object') {
        // If no AMD and we are in the browser, attach to window
        window.Imager = Imager;
    }
    /* global -module, -exports, -define */

}(window, document));
<commit_msg>Fix jshint complaints #77<commit_after>;(function (window, document) {

    'use strict';

    var defaultWidths, getKeys, isArray, nextTick, addEvent, getNaturalWidth;

    nextTick = window.requestAnimationFrame ||
               window.mozRequestAnimationFrame ||
               window.webkitRequestAnimationFrame ||
               function (callback) {
                   window.setTimeout(callback, 1000 / 60);
               };

    function applyEach (collection, callbackEach) {
        var i = 0,
            length = collection.length,
            new_collection = [];

        for (; i < length; i++) {
            new_collection[i] = callbackEach(collection[i], i);
        }

        return new_collection;
    }

    function returnDirectValue (value) {
      return value;
    }

    getNaturalWidth = (function(){
        if (document.createElement('img').hasOwnProperty('naturalWidth')) {
            return function (image){ return image.naturalWidth;};
        }
        // IE8 and below lacks the naturalWidth property
        return function (source){
            var img = document.createElement('img');
            img.src = source.src;
            return img.width;
        };
    })();

    addEvent = (function(){
        if (document.addEventListener){
            return function addStandardEventListener(el, eventName, fn){
                return el.addEventListener(eventName, fn, false);
            };
        }
        else {
            return function addIEEventListener(el, eventName, fn){
                return el.attachEvent('on'+eventName, fn);
            };
        }
    })();

    defaultWidths = [96, 130, 165, 200, 235, 270, 304, 340, 375, 410, 445, 485, 520, 555, 590, 625, 660, 695, 736];

    getKeys = typeof Object.keys === 'function' ? Object.keys : function (object) {
        var keys = [],
            key;

        for (key in object) {
            keys.push(key);
        }

        return keys;
    };

    /*
        Construct a new Imager instance, passing an optional configuration object.

        Example usage:

            {
                // Available widths for your images
                availableWidths: [Number],

                // Selector to be used to locate your div placeholders
                selector: '',

                // Class name to give your resizable images
                className: '',

                // If set to true, Imager will update the src attribute of the relevant images
                onResize: Boolean,

                // Toggle the lazy load functionality on or off
                lazyload: Boolean,

                // Used alongside the lazyload feature (helps performance by setting a higher delay)
                scrollDelay: Number
            }

        @param {object} configuration settings
        @return {object} instance of Imager
     */
    function Imager (elements, opts) {
        var self = this,
            doc  = document;

        opts = opts || {};

        if (elements !== undefined) {
            // first argument is selector string
            if (typeof elements === 'string') {
                opts.selector = elements;
                elements = undefined;
            }

            // first argument is the `opts` object, `elements` is implicitly the `opts.selector` string
            else if (typeof elements.length === 'undefined') {
                opts = elements;
                elements = undefined;
            }
        }

        this.imagesOffScreen  = [];
        this.viewportHeight   = doc.documentElement.clientHeight;
        this.selector         = opts.selector || '.delayed-image-load';
        this.className        = opts.className || 'image-replace';
        this.gif              = doc.createElement('img');
        this.gif.src          = 'data:image/gif;base64,R0lGODlhEAAJAIAAAP///wAAACH5BAEAAAAALAAAAAAQAAkAAAIKhI+py+0Po5yUFQA7';
        this.gif.className    = this.className;
        this.gif.alt          = '';
        this.scrollDelay      = opts.scrollDelay || 250;
        this.onResize         = opts.hasOwnProperty('onResize') ? opts.onResize : true;
        this.lazyload         = opts.hasOwnProperty('lazyload') ? opts.lazyload : false;
        this.scrolled         = false;
        this.availablePixelRatios = opts.availablePixelRatios || [1, 2];
        this.availableWidths  = opts.availableWidths || defaultWidths;
        this.onImagesReplaced = opts.onImagesReplaced || function () {};
        this.widthsMap        = {};
        this.refreshPixelRatio();
        this.widthInterpolator = opts.widthInterpolator || returnDirectValue;

        // Needed as IE8 adds a default `width`/`height` attribute…
        this.gif.removeAttribute('height');
        this.gif.removeAttribute('width');

        if (typeof this.availableWidths !== 'function'){
          if (typeof this.availableWidths.length === 'number') {
            this.widthsMap = Imager.createWidthsMap(this.availableWidths, this.widthInterpolator);
          }
          else {
            this.widthsMap = this.availableWidths;
            this.availableWidths = getKeys(this.availableWidths);
          }

          this.availableWidths = this.availableWidths.sort(function (a, b) {
            return a - b;
          });
        }

        if (elements) {
            this.divs = applyEach(elements, returnDirectValue);
            this.selector = null;
        }
        else {
            this.divs = applyEach(doc.querySelectorAll(this.selector), returnDirectValue);
        }

        this.changeDivsToEmptyImages();

        nextTick(function(){
            self.init();
        });
    }

    Imager.prototype.scrollCheck = function(){
        if (this.scrolled) {
            if (!this.imagesOffScreen.length) {
                window.clearInterval(this.interval);
            }

            this.divs = this.imagesOffScreen.slice(0); // copy by value, don't copy by reference
            this.imagesOffScreen.length = 0;
            this.changeDivsToEmptyImages();
            this.scrolled = false;
        }
    };

    Imager.prototype.init = function(){
        this.initialized = true;
        this.checkImagesNeedReplacing(this.divs);

        if (this.onResize) {
            this.registerResizeEvent();
        }

        if (this.lazyload) {
            this.registerScrollEvent();
        }
    };

    Imager.prototype.createGif = function (element) {
        // if the element is already a responsive image then we don't replace it again
        if (element.className.match(new RegExp('(^| )' + this.className + '( |$)'))) {
            return element;
        }

        var elementClassName = element.getAttribute('data-class');
        var elementWidth = element.getAttribute('data-width');
        var gif = this.gif.cloneNode(false);

        if (elementWidth) {
          gif.width = elementWidth;
        }
        gif.className = (elementClassName ? elementClassName + ' ' : '') + this.className;
        gif.setAttribute('data-src', element.getAttribute('data-src'));
        gif.setAttribute('alt', element.getAttribute('data-alt') || this.gif.alt);

        element.parentNode.replaceChild(gif, element);

        return gif;
    };

    Imager.prototype.changeDivsToEmptyImages = function(){
        var self = this;

        applyEach(this.divs, function(element, i){
            if (self.lazyload) {
                if (self.isThisElementOnScreen(element)) {
                    self.divs[i] = self.createGif(element);
                } else {
                    self.imagesOffScreen.push(element);
                }
            } else {
                self.divs[i] = self.createGif(element);
            }
        });

        if (this.initialized) {
            this.checkImagesNeedReplacing(this.divs);
        }
    };

    Imager.prototype.isThisElementOnScreen = function (element) {
        // document.body.scrollTop was working in Chrome but didn't work on Firefox, so had to resort to window.pageYOffset
        // but can't fallback to document.body.scrollTop as that doesn't work in IE with a doctype (?) so have to use document.documentElement.scrollTop
        var offset = Imager.getPageOffset();
        var elementOffsetTop = 0;

        if (element.offsetParent) {
            do {
                elementOffsetTop += element.offsetTop;
            }
            while (element = element.offsetParent);
        }

        return (elementOffsetTop < (this.viewportHeight + offset)) ? true : false;
    };

    Imager.prototype.checkImagesNeedReplacing = function (images) {
        var self = this;

        if (!this.isResizing) {
            this.isResizing = true;
            this.refreshPixelRatio();

            applyEach(images, function(image){
                self.replaceImagesBasedOnScreenDimensions(image);
            });

            this.isResizing = false;
            this.onImagesReplaced(images);
        }
    };

    Imager.prototype.replaceImagesBasedOnScreenDimensions = function (image) {
        var computedWidth, src, naturalWidth;

        naturalWidth = getNaturalWidth(image);
        computedWidth = typeof this.availableWidths === 'function' ? this.availableWidths(image)
                                                                   : this.determineAppropriateResolution(image);

        if (image.src !== this.gif.src && computedWidth <= naturalWidth) {
            return;
        }

        src = this.changeImageSrcToUseNewImageDimensions(image.getAttribute('data-src'), computedWidth);

        image.src = src;
    };

    Imager.prototype.determineAppropriateResolution = function (image) {
      return Imager.getClosestValue(image.getAttribute('width') || image.parentNode.clientWidth, this.availableWidths);
    };

    /**
     * Updates the device pixel ratio value used by Imager
     *
     * It is performed before each replacement loop, in case a user zoomed in/out
     * and thus updated the `window.devicePixelRatio` value.
     *
     * @api
     * @since 1.0.1
     */
    Imager.prototype.refreshPixelRatio = function refreshPixelRatio(){
        this.devicePixelRatio = Imager.getClosestValue(Imager.getPixelRatio(), this.availablePixelRatios);
    };

    Imager.prototype.changeImageSrcToUseNewImageDimensions = function (src, selectedWidth) {
        return src
            .replace(/{width}/g, Imager.transforms.width(selectedWidth, this.widthsMap))
            .replace(/{pixel_ratio}/g, Imager.transforms.pixelRatio(this.devicePixelRatio));
    };

    Imager.getPixelRatio = function getPixelRatio(context){
        return (context || window)['devicePixelRatio'] || 1;
    };

    Imager.createWidthsMap = function createWidthsMap (widths, interpolator) {
        var map = {},
            i   = widths.length;

        while (i--) {
            map[widths[i]] = interpolator(widths[i]);
        }

        return map;
    };

    Imager.transforms = {
        pixelRatio: function (value) {
            return value === 1 ? '' : '-' + value + 'x';
        },
        width: function (width, map) {
            return map[width] || width;
        }
    };

    /**
     * Returns the closest upper value.
     *
     * ```js
     * var candidates = [1, 1.5, 2];
     *
     * Imager.getClosestValue(0.8, candidates); // -> 1
     * Imager.getClosestValue(1, candidates); // -> 1
     * Imager.getClosestValue(1.3, candidates); // -> 1.5
     * Imager.getClosestValue(3, candidates); // -> 2
     * ```
     *
     * @api
     * @since 1.0.1
     * @param {Number} baseValue
     * @param {Array.<Number>} candidates
     * @returns {Number}
     */
    Imager.getClosestValue = function getClosestValue(baseValue, candidates){
        var i             = candidates.length,
            selectedWidth = candidates[i - 1];

        baseValue = parseFloat(baseValue, 10);

        while (i--) {
            if (baseValue <= candidates[i]) {
                selectedWidth = candidates[i];
            }
        }

        return selectedWidth;
    };

    Imager.prototype.registerResizeEvent = function(){
        var self = this;

        addEvent(window, 'resize', function(){
            self.checkImagesNeedReplacing(self.divs);
        });
    };

    Imager.prototype.registerScrollEvent = function (){
        var self = this;

        this.scrolled = false;

        this.interval = window.setInterval(function(){
            self.scrollCheck();
        }, self.scrollDelay);

        addEvent(window, 'scroll', function(){
            self.scrolled = true;
        });
    };

    Imager.getPageOffsetGenerator = function getPageVerticalOffset(testCase){
        if(testCase){
            return function(){ return window.pageYOffset; };
        }
        else {
            return function(){ return document.documentElement.scrollTop; };
        }
    };

    // This form is used because it seems impossible to stub `window.pageYOffset`
    Imager.getPageOffset = Imager.getPageOffsetGenerator(Object.prototype.hasOwnProperty.call(window, 'pageYOffset'));

    // Exporting for testing purpose
    Imager.applyEach = applyEach;

    /* global module, exports: true, define */
    if (typeof module === 'object' && typeof module.exports === 'object') {
        // CommonJS, just export
        module.exports = exports = Imager;
    } else if (typeof define === 'function' && define.amd) {
        // AMD support
        define(function () { return Imager; });
    } else if (typeof window === 'object') {
        // If no AMD and we are in the browser, attach to window
        window.Imager = Imager;
    }
    /* global -module, -exports, -define */

}(window, document));
<|endoftext|>


<commit_before>/**
 * Patterns bumper - `bumper' handling for elements
 *
 * Copyright 2013 Florian Friesdorf
 * Copyright 2012 Humberto Sermeno
 * Copyright 2013 Simplon B.V. - Wichert Akkerman
 */
define([
    "jquery",
    "../core/parser",
    "../registry",
    "../utils"
], function($, Parser, registry, utils) {
    var parser = new Parser("bumper");

    parser.add_argument("margin", 0);
    parser.add_argument("selector");
    parser.add_argument("bump-add", "bumped");
    parser.add_argument("bump-remove");
    parser.add_argument("unbump-add");
    parser.add_argument("unbump-remove", "bumped");

    var _ = {
        name: "bumper",
        trigger: ".pat-bumper",

        init: function($el, opts) {
            $el.each(function() {
                var $trigger = $(this),
                    options = parser.parse($trigger, opts);
                $trigger.data("pat-bumper:config", options);
            });

            $(window).on("scroll.bumper", function() {
                _._testBump($el, _._getViewport());
            });

            _._testBump($el, _._getViewport());
            return $el;
        },

        /**
         * Calculates the bounding box for the current viewport
         */
        _getViewport: function() {
            var $win = $(window), view = {
                top: $win.scrollTop(),
                left: $win.scrollLeft()
            };

            view.right = view.left + $win.width();
            view.bottom = view.top + $win.height();
            return view;
        },

        /**
         * Calculates the bounding box for a given element, taking margins
         * into consideration
         *
         * @param $elem The element
         */
        _getElementBox: function($elem) {
            var box = $elem.offset();

            box.top -= parseFloat($elem.css("marginTop").replace(/auto/, 0));
            box.left -= parseFloat($elem.css("marginLeft").replace(/auto/, 0));
            box.right = box.left + $elem.outerWidth(true);
            box.bottom = box.top + $elem.outerHeight(true);

            return box;
        },

        /**
         * Determines whether an element should be bumped
         *
         * @param $el  The element to look for
         * @param box The bounding box in which the element will be bumped
         */
        _testBump: function($el, box) {
            // initialize the elements
            $el.each(function() {
                var $this = $(this),
                    options = $this.data("pat-bumper:config"),
                    $target = options.selector ? $(options.selector) : $this,
                    already_bumped = !!$this.data("pat-bumper:bumped"),
                    must_bump = false,
                    bumped = false,
                    element_box = $this.data("pat-bumper:elementbox");

                // get current ElementBox while not bumped, otherwise used
                // saved state before bumping
                if (!element_box) {
                    element_box = _._getElementBox($this);
                    element_box.threshold = {
                        top:    element_box.top - options.margin,
                        bottom: element_box.bottom + options.margin,
                        left:   element_box.left - options.margin,
                        right:  element_box.right + options.margin
                    };
                    element_box.margin = options.margin;
                    $this.data("pat-bumper:elementbox", element_box);
                }

                if (box.top > element_box.threshold.top) {
                    $target.addClass("bumped-top").removeClass("bumped-bottom");
                    must_bump = true;
                } else if (box.bottom < element_box.threshold.bottom) {
                    $target.addClass("bumped-bottom").removeClass("bumped-top");
                    must_bump = true;
                } else
                    $target.removeClass("bumped-top bumped-bottom");

                if (box.left > element_box.threshold.left) {
                    $target.addClass("bumped-left").removeClass("bumped-right");
                    must_bump = true;
                } else if (box.right < element_box.threshold.right) {
                    $target.addClass("bumped-right").removeClass("bumped-left");
                    must_bump = true;
                } else
                    $target.removeClass("bumped-left bumped-right");

                $this.data("pat-bumper:bumped", must_bump);
                if (!already_bumped && must_bump) {
                    $target.addClass("bumped");
                    if (options.bump.add)
                        $target.addClass(options.bump.add);
                    if (options.bump.remove)
                        utils.removeWildcardClass($target, options.bump.remove);
                } else if (already_bumped && !must_bump) {
                    $target.removeClass("bumped");
                    if (options.unbump.add)
                        $target.addClass(options.unbump.add);
                    if (options.unbump.remove)
                        utils.removeWildcardClass($target, options.unbump.remove);
                }
            });
        }
    };
    registry.register(_);
    return _;
});

// vim: sw=4 expandtab
<commit_msg>Fix bumper jslint error.<commit_after>/**
 * Patterns bumper - `bumper' handling for elements
 *
 * Copyright 2013 Florian Friesdorf
 * Copyright 2012 Humberto Sermeno
 * Copyright 2013 Simplon B.V. - Wichert Akkerman
 */
define([
    "jquery",
    "../core/parser",
    "../registry",
    "../utils"
], function($, Parser, registry, utils) {
    var parser = new Parser("bumper");

    parser.add_argument("margin", 0);
    parser.add_argument("selector");
    parser.add_argument("bump-add", "bumped");
    parser.add_argument("bump-remove");
    parser.add_argument("unbump-add");
    parser.add_argument("unbump-remove", "bumped");

    var _ = {
        name: "bumper",
        trigger: ".pat-bumper",

        init: function($el, opts) {
            $el.each(function() {
                var $trigger = $(this),
                    options = parser.parse($trigger, opts);
                $trigger.data("pat-bumper:config", options);
            });

            $(window).on("scroll.bumper", function() {
                _._testBump($el, _._getViewport());
            });

            _._testBump($el, _._getViewport());
            return $el;
        },

        /**
         * Calculates the bounding box for the current viewport
         */
        _getViewport: function() {
            var $win = $(window), view = {
                top: $win.scrollTop(),
                left: $win.scrollLeft()
            };

            view.right = view.left + $win.width();
            view.bottom = view.top + $win.height();
            return view;
        },

        /**
         * Calculates the bounding box for a given element, taking margins
         * into consideration
         *
         * @param $elem The element
         */
        _getElementBox: function($elem) {
            var box = $elem.offset();

            box.top -= parseFloat($elem.css("marginTop").replace(/auto/, 0));
            box.left -= parseFloat($elem.css("marginLeft").replace(/auto/, 0));
            box.right = box.left + $elem.outerWidth(true);
            box.bottom = box.top + $elem.outerHeight(true);

            return box;
        },

        /**
         * Determines whether an element should be bumped
         *
         * @param $el  The element to look for
         * @param box The bounding box in which the element will be bumped
         */
        _testBump: function($el, box) {
            // initialize the elements
            $el.each(function() {
                var $this = $(this),
                    options = $this.data("pat-bumper:config"),
                    $target = options.selector ? $(options.selector) : $this,
                    already_bumped = !!$this.data("pat-bumper:bumped"),
                    must_bump = false,
                    element_box = $this.data("pat-bumper:elementbox");

                // get current ElementBox while not bumped, otherwise used
                // saved state before bumping
                if (!element_box) {
                    element_box = _._getElementBox($this);
                    element_box.threshold = {
                        top:    element_box.top - options.margin,
                        bottom: element_box.bottom + options.margin,
                        left:   element_box.left - options.margin,
                        right:  element_box.right + options.margin
                    };
                    element_box.margin = options.margin;
                    $this.data("pat-bumper:elementbox", element_box);
                }

                if (box.top > element_box.threshold.top) {
                    $target.addClass("bumped-top").removeClass("bumped-bottom");
                    must_bump = true;
                } else if (box.bottom < element_box.threshold.bottom) {
                    $target.addClass("bumped-bottom").removeClass("bumped-top");
                    must_bump = true;
                } else
                    $target.removeClass("bumped-top bumped-bottom");

                if (box.left > element_box.threshold.left) {
                    $target.addClass("bumped-left").removeClass("bumped-right");
                    must_bump = true;
                } else if (box.right < element_box.threshold.right) {
                    $target.addClass("bumped-right").removeClass("bumped-left");
                    must_bump = true;
                } else
                    $target.removeClass("bumped-left bumped-right");

                $this.data("pat-bumper:bumped", must_bump);
                if (!already_bumped && must_bump) {
                    $target.addClass("bumped");
                    if (options.bump.add)
                        $target.addClass(options.bump.add);
                    if (options.bump.remove)
                        utils.removeWildcardClass($target, options.bump.remove);
                } else if (already_bumped && !must_bump) {
                    $target.removeClass("bumped");
                    if (options.unbump.add)
                        $target.addClass(options.unbump.add);
                    if (options.unbump.remove)
                        utils.removeWildcardClass($target, options.unbump.remove);
                }
            });
        }
    };
    registry.register(_);
    return _;
});

// vim: sw=4 expandtab
<|endoftext|>


<commit_before>/*
TK102 GPS server for Node.js

License: COPYLEFT
This code is released under COPYLEFT meaning you can do with it
anything you like except copyrighting it. If possible it would
be nice to include the source URL for future reference:

https://github.com/fvdm/nodejs-tk102
*/

// INIT
var	net = require('net'),
	EventEmitter = require('events').EventEmitter

var tk102 = new EventEmitter()

// defaults
tk102.settings = {
	ip:				'0.0.0.0',	// default listen on all IPs
	port:			0,			// 0 = random, 'listening' event reports port
	connections:	10,			// 10 simultaneous connections
	timeout:		10			// 10 seconds idle timeout
}

// Create server
tk102.createServer = function( vars ) {

	// override settings
	if( typeof vars == 'object' && Object.keys(vars).length >= 1 ) {
		for( var key in vars ) {
			tk102.settings[ key ] = vars[ key ]
		}
	}

	// start server
	tk102.server = net.createServer( function( socket ) {

		// socket idle timeout
		if( tk102.settings.timeout > 0 ) {
			socket.setTimeout( tk102.settings.timeout * 1000, function() {
				tk102.emit( 'timeout', socket )
				socket.end()
			})
		}

	}).listen( tk102.settings.port, tk102.settings.ip, function() {

		// server ready
		tk102.emit( 'listening', tk102.server.address() )

	})

	// maximum number of slots
	tk102.server.maxConnections = tk102.settings.connections

	// inbound connection
	tk102.server.on( 'connection', function( socket ) {

		tk102.emit( 'connection', socket )
		socket.setEncoding( 'utf8' )
		var data = ''

		// receiving data
		socket.on( 'data', function( chunk ) {
			tk102.emit( 'data', chunk )
			data += chunk
		})

		// complete
		socket.on( 'close', function() {

			var gps = {}
			gps = tk102.parse( data )
			if( data != '' ) {
				var gps = tk102.parse( data )
				if( gps ) {
					tk102.emit( 'track', gps )
				} else {
					tk102.emit( 'fail', {
						reason:	'Cannot parse GPS data from device',
						socket:	socket,
						input:	data
					})
				}
			}

		})

	})
}

// Parse GPRMC string
tk102.parse = function( raw ) {

	// 1203292316,0031698765432,GPRMC,211657.000,A,5213.0247,N,00516.7757,E,0.00,273.30,290312,,,A*62,F,imei:123456789012345,123
	var raw = raw.replace( /(^[\s\t\r\n]+|[\s\t\r\n]+$)/, '' )
	var str = raw.split(',')
	var data = false

	// only continue with correct input, else the server may quit...
	if( str.length == 18 && str[2] == 'GPRMC' ) {

		// parse
		var datetime = str[0].replace( /([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/, function( match, year, month, day, hour, minute ) {
			return '20'+ year +'-'+ month +'-'+ day +' '+ hour +':'+ minute
		})

		var gpsdate = str[11].replace( /([0-9]{2})([0-9]{2})([0-9]{2})/, function( match, day, month, year ) {
			return '20'+ year +'-'+ month +'-'+ day
		})

		var gpstime = str[3].replace( /([0-9]{2})([0-9]{2})([0-9]{2})\.([0-9]{3})/, function( match, hour, minute, second, ms ) {
			return hour +':'+ minute +':'+ second +'.'+ ms
		})

		data = {
			'raw':		raw,
			'datetime':	datetime,
			'phone':	str[1],
			'gps': {
				'date':			gpsdate,
				'time':			gpstime,
				'signal':		str[15] == 'F' ? 'full' : 'low',
				'fix':			str[4] == 'A' ? 'active' : 'invalid'
			},
			'geo': {
				'latitude':		tk102.fixGeo( str[5], str[6] ),
				'longitude':	tk102.fixGeo( str[7], str[8] ),
				'bearing':		parseInt( str[10] )
			},
			'speed': {
				'knots':		Math.round( str[9] * 1000 ) / 1000,
				'kmh':			Math.round( str[9] * 1.852 * 1000 ) / 1000,
				'mph':			Math.round( str[9] * 1.151 * 1000 ) / 1000
			},
			'imei':		str[16].replace( 'imei:', '' )
		}
	}

	// done
	return data
}

// Clean geo positions, with 6 decimals
tk102.fixGeo = function( one, two ) {
	var minutes = one.substr(-7, 7)
	var degrees = parseInt( one.replace( minutes, '' ) )
	var one = degrees + (minutes / 60)

	var one = parseFloat( (two == 'S' || two == 'W' ? '-' : '') + one )
	return Math.round( one * 1000000 ) / 1000000
}

// ready
module.exports = tk102<commit_msg>Clean input using trim() instead of custom replacer<commit_after>/*
TK102 GPS server for Node.js

License: COPYLEFT
This code is released under COPYLEFT meaning you can do with it
anything you like except copyrighting it. If possible it would
be nice to include the source URL for future reference:

https://github.com/fvdm/nodejs-tk102
*/

// INIT
var	net = require('net'),
	EventEmitter = require('events').EventEmitter

var tk102 = new EventEmitter()

// defaults
tk102.settings = {
	ip:				'0.0.0.0',	// default listen on all IPs
	port:			0,			// 0 = random, 'listening' event reports port
	connections:	10,			// 10 simultaneous connections
	timeout:		10			// 10 seconds idle timeout
}

// Create server
tk102.createServer = function( vars ) {

	// override settings
	if( typeof vars == 'object' && Object.keys(vars).length >= 1 ) {
		for( var key in vars ) {
			tk102.settings[ key ] = vars[ key ]
		}
	}

	// start server
	tk102.server = net.createServer( function( socket ) {

		// socket idle timeout
		if( tk102.settings.timeout > 0 ) {
			socket.setTimeout( tk102.settings.timeout * 1000, function() {
				tk102.emit( 'timeout', socket )
				socket.end()
			})
		}

	}).listen( tk102.settings.port, tk102.settings.ip, function() {

		// server ready
		tk102.emit( 'listening', tk102.server.address() )

	})

	// maximum number of slots
	tk102.server.maxConnections = tk102.settings.connections

	// inbound connection
	tk102.server.on( 'connection', function( socket ) {

		tk102.emit( 'connection', socket )
		socket.setEncoding( 'utf8' )
		var data = ''

		// receiving data
		socket.on( 'data', function( chunk ) {
			tk102.emit( 'data', chunk )
			data += chunk
		})

		// complete
		socket.on( 'close', function() {

			var gps = {}
			gps = tk102.parse( data )
			if( data != '' ) {
				var gps = tk102.parse( data )
				if( gps ) {
					tk102.emit( 'track', gps )
				} else {
					tk102.emit( 'fail', {
						reason:	'Cannot parse GPS data from device',
						socket:	socket,
						input:	data
					})
				}
			}

		})

	})
}

// Parse GPRMC string
tk102.parse = function( raw ) {

	// 1203292316,0031698765432,GPRMC,211657.000,A,5213.0247,N,00516.7757,E,0.00,273.30,290312,,,A*62,F,imei:123456789012345,123
	var raw = raw.trim()
	var str = raw.split(',')
	var data = false

	// only continue with correct input, else the server may quit...
	if( str.length == 18 && str[2] == 'GPRMC' ) {

		// parse
		var datetime = str[0].replace( /([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/, function( match, year, month, day, hour, minute ) {
			return '20'+ year +'-'+ month +'-'+ day +' '+ hour +':'+ minute
		})

		var gpsdate = str[11].replace( /([0-9]{2})([0-9]{2})([0-9]{2})/, function( match, day, month, year ) {
			return '20'+ year +'-'+ month +'-'+ day
		})

		var gpstime = str[3].replace( /([0-9]{2})([0-9]{2})([0-9]{2})\.([0-9]{3})/, function( match, hour, minute, second, ms ) {
			return hour +':'+ minute +':'+ second +'.'+ ms
		})

		data = {
			'raw':		raw,
			'datetime':	datetime,
			'phone':	str[1],
			'gps': {
				'date':			gpsdate,
				'time':			gpstime,
				'signal':		str[15] == 'F' ? 'full' : 'low',
				'fix':			str[4] == 'A' ? 'active' : 'invalid'
			},
			'geo': {
				'latitude':		tk102.fixGeo( str[5], str[6] ),
				'longitude':	tk102.fixGeo( str[7], str[8] ),
				'bearing':		parseInt( str[10] )
			},
			'speed': {
				'knots':		Math.round( str[9] * 1000 ) / 1000,
				'kmh':			Math.round( str[9] * 1.852 * 1000 ) / 1000,
				'mph':			Math.round( str[9] * 1.151 * 1000 ) / 1000
			},
			'imei':		str[16].replace( 'imei:', '' )
		}
	}

	// done
	return data
}

// Clean geo positions, with 6 decimals
tk102.fixGeo = function( one, two ) {
	var minutes = one.substr(-7, 7)
	var degrees = parseInt( one.replace( minutes, '' ) )
	var one = degrees + (minutes / 60)

	var one = parseFloat( (two == 'S' || two == 'W' ? '-' : '') + one )
	return Math.round( one * 1000000 ) / 1000000
}

// ready
module.exports = tk102<|endoftext|>


<commit_before>var proxy = "SOCKS5 127.0.0.1:1080;";
var direct = "DIRECT";

var DirectNetworks = {DirectNetworks};
var DirectSuffixes = {DirectSuffixes};

var hasOwnProperty = Object.hasOwnProperty;

var reIPv4 = /^\d+\.\d+\.\d+\.\d+$/;
function isIPv4(host) {
    return reIPv4.test(host);
}

function isInNets(nets, host) {
    var ip = convert_addr(host);
    for (var i = 24; i >= 8; i--) {
        var key = (ip >> i) + '/' + (32 - i);
        if (hasOwnProperty.call(nets, key))
            return true;
    }
    return false;
}

function isSuffixes(suffixes, host) {
    var parts = host.split('.');
    var level = suffixes;
    for (var i = parts.length - 1; i >= 0; i--) {
        var part = parts[i];
        level = level[part];
        if (level === undefined)
            return false
        if (level === 1)
            return true
    }
    return false;
}

function FindProxyForURL(url, host) {
    if (isIPv4(host)) {
        if (isInNets(DirectNetworks, host))
            return direct;
    } else {
        if (isSuffixes(DirectSuffixes, host))
            return direct;
    }
    return proxy;
}

// DEBUG CODE
// function convert_addr(ipchars) {
//     var bytes = ipchars.split('.');
//     var result = (bytes[0] << 24) |
//     (bytes[1] << 16) |
//     (bytes[2] << 8) |
//     (bytes[3]);
//     return result >>> 0;
// }
// module.exports = FindProxyForURL<commit_msg>Bug fix: javascript bit operation<commit_after>var proxy = "SOCKS5 127.0.0.1:1080;";
var direct = "DIRECT";

var DirectNetworks = {DirectNetworks};
var DirectSuffixes = {DirectSuffixes};

var hasOwnProperty = Object.hasOwnProperty;

var reIPv4 = /^\d+\.\d+\.\d+\.\d+$/;
function isIPv4(host) {
    return reIPv4.test(host);
}

function isInNets(nets, host) {
    var ip = convert_addr(host);
    for (var i = 24; i >= 8; i--) {
        var key = (ip >>> i) + '/' + (32 - i);
        if (hasOwnProperty.call(nets, key))
            return true;
    }
    return false;
}

function isSuffixes(suffixes, host) {
    var parts = host.split('.');
    var level = suffixes;
    for (var i = parts.length - 1; i >= 0; i--) {
        var part = parts[i];
        level = level[part];
        if (level === undefined)
            return false
        if (level === 1)
            return true
    }
    return false;
}

function FindProxyForURL(url, host) {
    if (isIPv4(host)) {
        if (isInNets(DirectNetworks, host))
            return direct;
    } else {
        if (isSuffixes(DirectSuffixes, host))
            return direct;
    }
    return proxy;
}

// DEBUG CODE
// function convert_addr(ipchars) {
//     var bytes = ipchars.split('.');
//     var result = (bytes[0] << 24) |
//     (bytes[1] << 16) |
//     (bytes[2] << 8) |
//     (bytes[3]);
//     return result >>> 0;
// }
// module.exports = FindProxyForURL<|endoftext|>


<commit_before>;(function(window, undefined) {
	"use strict";
	var ess,emptyArray = [],slice = emptyArray.slice,filter = emptyArray.filter,elementTypes = [1, 9, 11],
		WCJ = (function(){
		var WCJ = function( selector ) {
		    return new WCJ.fn.init(selector);
		};
		WCJ.fn = WCJ.prototype = {
			init:function( selector ){
				var dom ;
    			if (!selector)
    				dom = emptyArray,dom.selector = selector || '',dom.__proto__ = WCJ.fn.init.prototype;
    			else {
    				if (WCJ.isArray(selector))
    					dom = selector;
	                else if (elementTypes.indexOf(selector.nodeType) >= 0 || selector === window)
	                	dom = [selector], selector = null;
	                else dom = (function(){
				        var found;
				        return (document && /^#([\w-]+)$/.test(selector))?
				        ((found = document.getElementById(RegExp.$1)) ? [found] : emptyArray ):
					    slice.call(
						    /^\.([\w-]+)$/.test(selector) ? document.getElementsByClassName(RegExp.$1) :
						    /^[\w-]+$/.test(selector) ? document.getElementsByTagName(selector) :
						    document.querySelectorAll(selector)
					    );
					})();
					dom = dom || emptyArray;
					dom.__proto__ = WCJ.fn.init.prototype;
					dom.selector = selector || '';
    			}
    			return dom;
			},
			size:function(){return this.length;}
		}
		WCJ.fn.init.prototype = WCJ.fn;
        WCJ.extend = WCJ.fn.extend = function () {
            var options, name, src, copy,
			target = arguments[0] || {},
			i = 1,
			length = arguments.length,
			deep = false;
            //处理深拷贝的情况
            if (typeof (target) === "boolean") {
                deep = target;
                target = arguments[1] || {};
                i = 2;
            }
            //处理时，目标是一个字符串或（深拷贝可能的情况下）的东西
            if (typeof (target) !== "object" && !WCJ.isFunction(target)) {
                target = {};
            }
            //扩展WCJ的本身，如果只有一个参数传递
            if (length === i) {
                target = this;
                --i;
            }
            for (; i < length; i++) {
                if ((options = arguments[i]) != null) {
                    for (name in options) {
                        src = target[name];
                        copy = options[name];
                        if (target === copy) {
                            continue;
                        }
                        if (copy !== undefined) {
                            target[name] = copy;
                        }
                    }
                }
            }
            return target;
        };
		return WCJ;
	})();

	WCJ.fn.extend({
		forEach: emptyArray.forEach,
		concat: emptyArray.concat,
	    each: function(callback){
	      this.forEach(function(el, idx){ callback.call(el, idx, el) });
	      return this;
	    },
	    map: function(fn){
	    	return WCJ(WCJ.map(this, function(el, i){ return fn.call(el, i, el) }));
	    },
	    get: function(index){
	      return index === undefined ? slice.call(this) : this[index >= 0 ? index : index + this.length];
	    },
	    empty: function(){ return this.each(function(){ this.innerHTML = '' }) },
	    text: function(text){
	      return text === undefined ?
	        (this.length > 0 ? this[0].textContent : null) :
	        this.each(function(){ this.textContent = text });
	    },
        bind: function(type, func) {
			this.each(function(){
				if (this.addEventListener) this.addEventListener(type, func, false);
				else if (this.attachEvent) this.attachEvent("on" + type, func);
				else this["on" + type] = func;
			})
			return this;
		},
		unbind:function(type, func) {
			this.each(function(ele,obj){
				if (this.removeEventListener) this.removeEventListener(type, func, false);
				else if (this[i].detachEvent) this.detachEvent("on" + type, func);
				else this["on" + type] = null;
			})
			return this;
		},
		filter:function(selector){
			return WCJ(filter.call(this, function(element){
        		return WCJ.matches(element, selector)
		    }))
		},
		pluck: function(property){ return WCJ.map(this, function(el){ return el[property] })},
		parent: function(){
			var arr=this.pluck('parentNode');
			return filter.call(arr, function(item, idx){
				return arr.indexOf(item) == idx
			});
		},
		parents: function(selector){
			var ancestors = [], nodes = this
			while (nodes.length > 0)
			nodes = WCJ.map(nodes, function(node){
			  if ((node = node.parentNode) && !WCJ.isDocument(node) && ancestors.indexOf(node) < 0) {
			    ancestors.push(node)
			    return node
			  }
			});
    		return selector == null ? WCJ(ancestors) : WCJ(ancestors).filter(selector);
		}
	});

	WCJ.extend({
		isDocument:function (obj) { return obj = obj ? obj != null && obj.nodeType ? obj.nodeType == obj.DOCUMENT_NODE : false : undefined;},
		isFunction:function (value) { return ({}).toString.call(value) == "[object Function]" },
		isObject:function (value) { return value instanceof Object },
		isArray:function (value) { return value instanceof Array },
		likeArray:function (obj) { return typeof obj.length == 'number' },
        type: function (obj) {
            switch (obj) {
                case null: return "Null";
                case (void 0): return "Undefined";
            }
            var type = typeof (obj);
            switch (type) {
                case 'boolean': return "Boolean";
                case 'number': return "Number";
                case 'string': return "String";
                case 'function': return "Function";
            }
            return "Object";
        },
        error:function(msg) {throw msg;},
        each:function(elements, callback){
			var i, key
			if (this.likeArray(elements)) {
				for (i = 0; i < elements.length; i++)
					if (callback.call(elements[i], i, elements[i]) === false) return elements
				} else {
				for (key in elements)
					if (callback.call(elements[key], key, elements[key]) === false) return elements
			}
			return elements
		},
		map:function(elements, callback){
			var value, values = [], i, key
			if (this.likeArray(elements))
			for (i = 0; i < elements.length; i++) {
				value = callback(elements[i], i)
				if (value != null) values.push(value)
			}
			else
			for (key in elements) {
				value = callback(elements[key], key)
				if (value != null) values.push(value)
			}
			return values.length > 0 ? WCJ.fn.concat.apply([], values) : values;
		},
		matches:function(element, selector){
			if (!selector || !element || element.nodeType !== 1) return false;
		    var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector ||
		                          element.oMatchesSelector || element.msMatchesSelector || element.matchesSelector;
		    if (matchesSelector) return matchesSelector.call(element, selector);
		},
		inArray:function(elem, array, i){
			return emptyArray.indexOf.call(array, elem, i)
		}
	});

	//解决低版本浏览器对filter方法的支持
	if (!Array.prototype.filter){
		Array.prototype.filter = function(fun /*, thisArg */){
			"use strict";
			if (this === void 0 || this === null)
				throw new TypeError();
			var t = Object(this);
			var len = t.length >>> 0;
			if (typeof fun !== "function")
				throw new TypeError();
			var res = [];
			var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
			for (var i = 0; i < len; i++){
				if (i in t){
					var val = t[i];
					if (fun.call(thisArg, val, i, t))
					res.push(val);
				}
			}

			return res;
		};
	}

	//字符串处理
    WCJ.extend(String.prototype,{
        trim: function () {return this.replace(/(^\s*)|(\s*$)/g, "");},
        leftTrim: function () {return this.replace(/(^\s*)/g, "");}
    })
	window.WCJ = window.$$ = WCJ;
})(window);<commit_msg>fix:低版本IE对indexOf方法的支持<commit_after>;(function(window, undefined) {
	"use strict";
	var ess,emptyArray = [],slice = emptyArray.slice,filter = emptyArray.filter,elementTypes = [1, 9, 11],
		WCJ = (function(){
		var WCJ = function( selector ) {
		    return new WCJ.fn.init(selector);
		};
		WCJ.fn = WCJ.prototype = {
			init:function( selector ){
				var dom ;
    			if (!selector)
    				dom = emptyArray,dom.selector = selector || '',dom.__proto__ = WCJ.fn.init.prototype;
    			else {
    				if (WCJ.isArray(selector))
    					dom = selector;
	                else if (elementTypes.indexOf(selector.nodeType) >= 0 || selector === window)
	                	dom = [selector], selector = null;
	                else dom = (function(){
				        var found;
				        return (document && /^#([\w-]+)$/.test(selector))?
				        ((found = document.getElementById(RegExp.$1)) ? [found] : emptyArray ):
					    slice.call(
						    /^\.([\w-]+)$/.test(selector) ? document.getElementsByClassName(RegExp.$1) :
						    /^[\w-]+$/.test(selector) ? document.getElementsByTagName(selector) :
						    document.querySelectorAll(selector)
					    );
					})();
					dom = dom || emptyArray;
					dom.__proto__ = WCJ.fn.init.prototype;
					dom.selector = selector || '';
    			}
    			return dom;
			},
			size:function(){return this.length;}
		}
		WCJ.fn.init.prototype = WCJ.fn;
        WCJ.extend = WCJ.fn.extend = function () {
            var options, name, src, copy,
			target = arguments[0] || {},
			i = 1,
			length = arguments.length,
			deep = false;
            //处理深拷贝的情况
            if (typeof (target) === "boolean") {
                deep = target;
                target = arguments[1] || {};
                i = 2;
            }
            //处理时，目标是一个字符串或（深拷贝可能的情况下）的东西
            if (typeof (target) !== "object" && !WCJ.isFunction(target)) {
                target = {};
            }
            //扩展WCJ的本身，如果只有一个参数传递
            if (length === i) {
                target = this;
                --i;
            }
            for (; i < length; i++) {
                if ((options = arguments[i]) != null) {
                    for (name in options) {
                        src = target[name];
                        copy = options[name];
                        if (target === copy) {
                            continue;
                        }
                        if (copy !== undefined) {
                            target[name] = copy;
                        }
                    }
                }
            }
            return target;
        };
		return WCJ;
	})();

	WCJ.fn.extend({
		forEach: emptyArray.forEach,
		concat: emptyArray.concat,
	    each: function(callback){
	      this.forEach(function(el, idx){ callback.call(el, idx, el) });
	      return this;
	    },
	    map: function(fn){
	    	return WCJ(WCJ.map(this, function(el, i){ return fn.call(el, i, el) }));
	    },
	    get: function(index){
	      return index === undefined ? slice.call(this) : this[index >= 0 ? index : index + this.length];
	    },
	    empty: function(){ return this.each(function(){ this.innerHTML = '' }) },
	    text: function(text){
	      return text === undefined ?
	        (this.length > 0 ? this[0].textContent : null) :
	        this.each(function(){ this.textContent = text });
	    },
        bind: function(type, func) {
			this.each(function(){
				if (this.addEventListener) this.addEventListener(type, func, false);
				else if (this.attachEvent) this.attachEvent("on" + type, func);
				else this["on" + type] = func;
			})
			return this;
		},
		unbind:function(type, func) {
			this.each(function(ele,obj){
				if (this.removeEventListener) this.removeEventListener(type, func, false);
				else if (this[i].detachEvent) this.detachEvent("on" + type, func);
				else this["on" + type] = null;
			})
			return this;
		},
		filter:function(selector){
			return WCJ(filter.call(this, function(element){
        		return WCJ.matches(element, selector)
		    }))
		},
		pluck: function(property){ return WCJ.map(this, function(el){ return el[property] })},
		parent: function(){
			var arr=this.pluck('parentNode');
			return filter.call(arr, function(item, idx){
				return arr.indexOf(item) == idx
			});
		},
		parents: function(selector){
			var ancestors = [], nodes = this
			while (nodes.length > 0)
			nodes = WCJ.map(nodes, function(node){
			  if ((node = node.parentNode) && !WCJ.isDocument(node) && ancestors.indexOf(node) < 0) {
			    ancestors.push(node)
			    return node
			  }
			});
    		return selector == null ? WCJ(ancestors) : WCJ(ancestors).filter(selector);
		}
	});

	WCJ.extend({
		isDocument:function (obj) { return obj = obj ? obj != null && obj.nodeType ? obj.nodeType == obj.DOCUMENT_NODE : false : undefined;},
		isFunction:function (value) { return ({}).toString.call(value) == "[object Function]" },
		isObject:function (value) { return value instanceof Object },
		isArray:function (value) { return value instanceof Array },
		likeArray:function (obj) { return typeof obj.length == 'number' },
        type: function (obj) {
            switch (obj) {
                case null: return "Null";
                case (void 0): return "Undefined";
            }
            var type = typeof (obj);
            switch (type) {
                case 'boolean': return "Boolean";
                case 'number': return "Number";
                case 'string': return "String";
                case 'function': return "Function";
            }
            return "Object";
        },
        error:function(msg) {throw msg;},
        each:function(elements, callback){
			var i, key
			if (this.likeArray(elements)) {
				for (i = 0; i < elements.length; i++)
					if (callback.call(elements[i], i, elements[i]) === false) return elements
				} else {
				for (key in elements)
					if (callback.call(elements[key], key, elements[key]) === false) return elements
			}
			return elements
		},
		map:function(elements, callback){
			var value, values = [], i, key
			if (this.likeArray(elements))
			for (i = 0; i < elements.length; i++) {
				value = callback(elements[i], i)
				if (value != null) values.push(value)
			}
			else
			for (key in elements) {
				value = callback(elements[key], key)
				if (value != null) values.push(value)
			}
			return values.length > 0 ? WCJ.fn.concat.apply([], values) : values;
		},
		matches:function(element, selector){
			if (!selector || !element || element.nodeType !== 1) return false;
		    var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector ||
		                          element.oMatchesSelector || element.msMatchesSelector || element.matchesSelector;
		    if (matchesSelector) return matchesSelector.call(element, selector);
		},
		inArray:function(elem, array, i){
			return emptyArray.indexOf.call(array, elem, i)
		}
	});

	//解决低版本浏览器对filter方法的支持
	if (!Array.prototype.filter){
		Array.prototype.filter = function(fun /*, thisArg */){
			"use strict";
			if (this === void 0 || this === null)
				throw new TypeError();
			var t = Object(this);
			var len = t.length >>> 0;
			if (typeof fun !== "function")
				throw new TypeError();
			var res = [];
			var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
			for (var i = 0; i < len; i++){
				if (i in t){
					var val = t[i];
					if (fun.call(thisArg, val, i, t))
					res.push(val);
				}
			}

			return res;
		};
	}
	//低版本IE对indexOf方法的支持
	if(!Array.indexOf){
	    Array.prototype.indexOf = function(obj){
	        for(var i=0; i<this.length; i++){
	            if(this[i]==obj){
	                return i;
	            }
	        }
	        return -1;
	    }
	}

	//字符串处理
    WCJ.extend(String.prototype,{
        trim: function () {return this.replace(/(^\s*)|(\s*$)/g, "");},
        leftTrim: function () {return this.replace(/(^\s*)/g, "");}
    })
	window.WCJ = window.$$ = WCJ;
})(window);<|endoftext|>


<commit_before>/* Copyright © 2014 Ngine Networks - All Rights Reserved. */
function		find_dealer(table, game)
{
	var			pos = 1;

	if (table.playing_seats.length < 2)
		return 0;
	if (game.d_pos == -1 || game.d_pos > 6 || game.d_pos <= 0) // First game of the table
		{
			while (table.playing_seats.indexOf(pos) == -1)
				pos = Math.floor(Math.random() * 6);
			return pos;
		}
	if (game.sb_pos)
	{
		pos = game.d_pos + 1;
		while (table.playing_seats.indexOf(pos) == -1)
		{
			if (pos >= 7 || pos <= 0)
				pos = 0;
			++pos;
		}
	}
	return pos;
}

function		find_sb(table, game)
{
	var			pos = game.d_pos + 1;

	if (table.playing_seats.length < 2)
		return 0;
	if (pos >= 7 || pos <= 0)
		pos = 1;
	if (table.playing_seats.length == 2) // Heads-up situation
		return game.d_pos;
	pos = game.d_pos + 1;
	while (table.playing_seats.indexOf(pos) == -1)
		{
			if (pos >= 7 || pos <= 0)
				pos = 0;
			++pos;
		}
	return pos;
}

function		find_bb(table, game)
{
	var			pos = game.sb_pos + 1;

	if (table.playing_seats.length < 2)
		return 0;
	while (table.playing_seats.indexOf(pos) == -1 && pos != game.sb_pos && pos != game.d_pos)
	{
		if (pos >= 7 || pos <= 0)
			pos = 0;
		++pos;
	}
	return pos;
}

function	get_next_player(table, game)
{
	var		pos = game.highlights_pos + 1;

	if (table.playing_seats.length < 2)
		return 0;
	while (table.playing_seats.indexOf(pos) == -1)
	{
		if (pos >= 7 || pos <= 0)
			pos = 0;
		++pos;
	}
	console.log("get_next_player() = " + pos);
	return pos;
}

function	get_first_to_talk(table, game)
{
	var		pos = game.bb_pos + 1;

	if (table.playing_seats.length < 2)
		return 0;
	if (table.playing_seats.length == 2)
	{
		game.highlights_pos = game.d_pos;
		return game.d_pos;
	}
	while (table.playing_seats.indexOf(pos) == -1)
	{
		if (pos >= 7 || pos <= 0)
			pos = 0;
		++pos;
	}
	game.highlights_pos = pos;
	return pos;
}

function	preflop_deal(socket, game, table)
{
	var		idx = 1;
	var		curseat;

	while (idx <= 6)
	{
		curseat = get_seat(table.seats, idx);
		if (curseat && curseat.state == "playing")
		{
			io.to(get_private_id(table.private_ids, idx)).emit("first deal", game.deck[idx], game.deck[idx + 1]);
			curseat.player.card1 = game.deck[idx];
			curseat.player.card2 = game.deck[idx + 1];
			game.deck.splice(idx, 2);
		}
		++idx;
	}
}

function	get_first_cards_suit(card1, card2)
{
	return (card1[0] === card2[0]) ? "One Pair" : "High Card";
}

function	preflop_first_cards_suits(socket, game, table)
{
	var		idx = 1;
	var		player;
	var		first_suit;
	var		curseat;

	while (idx <= 6)
	{
		curseat = get_seat(table.seats, idx);
		if (curseat.state == "playing")
		{
			player = curseat.player;
			first_suit = get_first_cards_suit(player.card1, player.card2);
			player.rank_name = first_suit;
			io.to(get_private_id(table.private_ids, idx)).emit("first suit", first_suit);
		}
		++idx;
	}
}

function		send_raise_limits(table, game, seat_nb, token)
{
	var			curseat;
	var			raise_limit1;

	curseat = get_seat(table.seats, seat_nb);
	if (token) {
		raise_limit1 = cfg.conf.big_blind;
		console.log('raise limit1 : '+raise_limit1);
		io.to(get_private_id(table.private_ids, seat_nb)).emit("raise limits", raise_limit1, curseat.player.bankroll);
	}
	else if (curseat.state == "playing" && !token)
	{
		raise_limit1 = game.curbet *2;
		console.log('raise limit1 : '+raise_limit1); /** 2;(game.curbet - curseat.bet) * 2 > 0 ? (game.curbet - curseat.bet) * 1.10 : game.curbet;
		raise_limit1 = raise_limit1 > curseat.player.bankroll ? curseat.player.bankroll : raise_limit1;*/
		io.to(get_private_id(table.private_ids, seat_nb)).emit("raise limits", raise_limit1, curseat.player.bankroll);
	}
}

function		send_option(table, seat_nb, option, choice, amount)
{
	var			player;
	var			curseat = get_seat(table.seats, seat_nb);

	if (curseat && curseat.player.bankroll === "ALL IN" && amount > curseat.player.bankroll)
		amount = curseat.player.bankroll;
	if (curseat.state == "playing")
	{
		if (choice === "fold") // As it's the last option, client should be ready.
		{
			io.to(get_private_id(table.private_ids, seat_nb)).emit("your turn");
		}
		player = get_seat(table.seats, seat_nb).player;
		io.to(get_private_id(table.private_ids, seat_nb)).emit(option, choice, amount);
	}

}

function		send_emplacements(table)
{
	io.to(table.id).emit("place button", "sb", table.game.sb_pos);	// Respect this sending order.
	io.to(table.id).emit("place button", "dealer", table.game.d_pos);
	io.to(table.id).emit("place button", "bb", table.game.bb_pos);
	io.to(table.id).emit("highlights", table.game.highlights_pos, "on");
}

function		blinds_treatment(table, sb, bb)
{
	if (sb.player.bankroll <= 0)
		sb.player.bankroll = +cfg.start_bankroll; // New cave!
	if (bb.player.bankroll <= 0)
		bb.player.bankroll = +cfg.start_bankroll;
	sb.player.bankroll -= cfg.conf.small_blind;
	table.game.pot_amount += +cfg.conf.small_blind;
	bb.player.bankroll -= cfg.conf.big_blind;
	table.game.pot_amount += +cfg.conf.big_blind;
	table.game.curbet = cfg.conf.big_blind;
}

function		send_blinds(table, sb, bb)
{
	io.to(table.id).emit("bankroll modification", table.game.sb_pos, sb.player);
	io.to(table.id).emit("bankroll modification", table.game.bb_pos, bb.player);
	io.to(table.id).emit("pot modification", table.game.pot_amount);
	io.to(table.id).emit("bet", table.game.sb_pos, sb.bet = cfg.conf.small_blind);
	io.to(table.id).emit("bet", table.game.bb_pos, bb.bet = cfg.conf.big_blind);

	console.log('sb : ' + sb.bet, 'bb : ' + bb.bet);
}

function		ask_first_player(socket, player, game)
{
	//starts_timer(table, player.nickname);
	send_option(table, game.highlights_pos, "first choice", "call", /*game.highlights_pos === game.sb_pos ? game.curbet / 2 :*/ game.curbet);
	send_option(table, game.highlights_pos, "second choice", "null", -1/*game.highlights_pos === game.sb_pos ? game.curbet * 2 / 2 : game.curbet */);
	send_option(table, game.highlights_pos, "third choice", "fold");
	/* SEE PLAYER GENERAL SOCKETS FOR THE FOLLOWING */
}

function		players_wait_mode(table)
{
	for (var idx = 1; idx <= 6; ++idx)
		io.to(get_private_id(table.private_ids, idx)).emit("turn wait");
}

function		game_routine(socket, table)
{
	var			sb; // small blind.
	var			bb;	// big blind.

	table.game.d_pos = find_dealer(table, table.game);
	table.game.sb_pos = find_sb(table, table.game);
	table.game.bb_pos = find_bb(table, table.game);
	/*
	console.log("Dealer is at seat " + table.game.d_pos);
	console.log("Small blind is at seat " + table.game.sb_pos);
	console.log("Big blind is at seat " + table.game.bb_pos);
	*/

	get_first_to_talk(table, table.game);
	send_emplacements(table);					   		// Send buttons emplacements.
	sb = get_seat(table.seats, table.game.sb_pos);
	bb = get_seat(table.seats, table.game.bb_pos);
	blinds_treatment(table, sb, bb); 				   // Take blinds (server side).
	send_blinds(table, sb, bb); 					   // Send blinds to clients.
	/* Preflop */
	preflop_deal(socket, table.game, table);
	preflop_first_cards_suits(socket, table.game, table);
	table.game.curbet = cfg.conf.big_blind;
	send_raise_limits(table, table.game, table.game.highlights_pos, 0);
	players_wait_mode(table);
	console.log('ask first player');
	ask_first_player(socket, table, table.game);
}

function		init_obj(table)
{
	var			idx = 1;
	var			seat;

	while (idx <= 6)
	{
		seat = get_seat(table.seats, idx);
		seat.bet = 0;
		++idx;
	}
}

function		stop_high_rollers(table)
{
	var			seat;

	for (var idx = 1; idx <= 6; ++idx)
	{
		seat = get_seat(table.seats, idx)
		if (seat.player.bankroll >= 9999)
			seat.player.bankroll = 9000;
		else if (seat.player.bankroll <= 0)
			seat.player.bankroll = +cfg.start_bankroll;
		io.to(table.id).emit("bankroll modification", idx, seat.player);
		/* send cards to player (should not be here) */
		if ((table.playing_seats.indexOf(idx) != -1))
			io.to(table.id).emit("give cards", idx);
	}
}

function		new_cashgame(socket, table)
{
	init_obj(table);
	table.game.moment = "preflop";
	table.game.round_nb = socket === 42 ? 0 : 1;
	table.game.pot_amount = 0;
	table.game.curbet = 0;
	io.to(table.id).emit("pot modification", table.game.pot_amount);
	fisher_shuffle(table.game.deck);
	stop_high_rollers(table);
	console.log("Round nb: " + table.game.round_nb);
	return game_routine(socket, table);
}
<commit_msg>fix raise limits<commit_after>/* Copyright © 2014 Ngine Networks - All Rights Reserved. */
function		find_dealer(table, game)
{
	var			pos = 1;

	if (table.playing_seats.length < 2)
		return 0;
	if (game.d_pos == -1 || game.d_pos > 6 || game.d_pos <= 0) // First game of the table
		{
			while (table.playing_seats.indexOf(pos) == -1)
				pos = Math.floor(Math.random() * 6);
			return pos;
		}
	if (game.sb_pos)
	{
		pos = game.d_pos + 1;
		while (table.playing_seats.indexOf(pos) == -1)
		{
			if (pos >= 7 || pos <= 0)
				pos = 0;
			++pos;
		}
	}
	return pos;
}

function		find_sb(table, game)
{
	var			pos = game.d_pos + 1;

	if (table.playing_seats.length < 2)
		return 0;
	if (pos >= 7 || pos <= 0)
		pos = 1;
	if (table.playing_seats.length == 2) // Heads-up situation
		return game.d_pos;
	pos = game.d_pos + 1;
	while (table.playing_seats.indexOf(pos) == -1)
		{
			if (pos >= 7 || pos <= 0)
				pos = 0;
			++pos;
		}
	return pos;
}

function		find_bb(table, game)
{
	var			pos = game.sb_pos + 1;

	if (table.playing_seats.length < 2)
		return 0;
	while (table.playing_seats.indexOf(pos) == -1 && pos != game.sb_pos && pos != game.d_pos)
	{
		if (pos >= 7 || pos <= 0)
			pos = 0;
		++pos;
	}
	return pos;
}

function	get_next_player(table, game)
{
	var		pos = game.highlights_pos + 1;

	if (table.playing_seats.length < 2)
		return 0;
	while (table.playing_seats.indexOf(pos) == -1)
	{
		if (pos >= 7 || pos <= 0)
			pos = 0;
		++pos;
	}
	console.log("get_next_player() = " + pos);
	return pos;
}

function	get_first_to_talk(table, game)
{
	var		pos = game.bb_pos + 1;

	if (table.playing_seats.length < 2)
		return 0;
	if (table.playing_seats.length == 2)
	{
		game.highlights_pos = game.d_pos;
		return game.d_pos;
	}
	while (table.playing_seats.indexOf(pos) == -1)
	{
		if (pos >= 7 || pos <= 0)
			pos = 0;
		++pos;
	}
	game.highlights_pos = pos;
	return pos;
}

function	preflop_deal(socket, game, table)
{
	var		idx = 1;
	var		curseat;

	while (idx <= 6)
	{
		curseat = get_seat(table.seats, idx);
		if (curseat && curseat.state == "playing")
		{
			io.to(get_private_id(table.private_ids, idx)).emit("first deal", game.deck[idx], game.deck[idx + 1]);
			curseat.player.card1 = game.deck[idx];
			curseat.player.card2 = game.deck[idx + 1];
			game.deck.splice(idx, 2);
		}
		++idx;
	}
}

function	get_first_cards_suit(card1, card2)
{
	return (card1[0] === card2[0]) ? "One Pair" : "High Card";
}

function	preflop_first_cards_suits(socket, game, table)
{
	var		idx = 1;
	var		player;
	var		first_suit;
	var		curseat;

	while (idx <= 6)
	{
		curseat = get_seat(table.seats, idx);
		if (curseat.state == "playing")
		{
			player = curseat.player;
			first_suit = get_first_cards_suit(player.card1, player.card2);
			player.rank_name = first_suit;
			io.to(get_private_id(table.private_ids, idx)).emit("first suit", first_suit);
		}
		++idx;
	}
}

function		send_raise_limits(table, game, seat_nb, token)
{
	var			curseat;
	var			raise_limit1;

	curseat = get_seat(table.seats, seat_nb);
	if (token) {
		console.log('send raise limits 1');
		raise_limit1 = cfg.conf.big_blind;
		console.log('raise limit1 : '+raise_limit1);
		console.log('curseat player bankroll ' + curseat.player.bankroll);
		io.to(get_private_id(table.private_ids, seat_nb)).emit("raise limits", raise_limit1, curseat.player.bankroll);
	}
	else if (!token)
	{
		console.log('send raise limits 1');
		raise_limit1 = game.curbet *2;
		console.log('raise limit1 : '+raise_limit1); /** 2;(game.curbet - curseat.bet) * 2 > 0 ? (game.curbet - curseat.bet) * 1.10 : game.curbet;
		raise_limit1 = raise_limit1 > curseat.player.bankroll ? curseat.player.bankroll : raise_limit1;*/
		console.log('curseat player bankroll ' + curseat.player.bankroll);
		io.to(get_private_id(table.private_ids, seat_nb)).emit("raise limits", raise_limit1, curseat.player.bankroll);
	}
}

function		send_option(table, seat_nb, option, choice, amount)
{
	var			player;
	var			curseat = get_seat(table.seats, seat_nb);

	if (curseat && curseat.player.bankroll === "ALL IN" && amount > curseat.player.bankroll)
		amount = curseat.player.bankroll;
	if (curseat.state == "playing")
	{
		if (choice === "fold") // As it's the last option, client should be ready.
		{
			io.to(get_private_id(table.private_ids, seat_nb)).emit("your turn");
		}
		player = get_seat(table.seats, seat_nb).player;
		io.to(get_private_id(table.private_ids, seat_nb)).emit(option, choice, amount);
	}

}

function		send_emplacements(table)
{
	io.to(table.id).emit("place button", "sb", table.game.sb_pos);	// Respect this sending order.
	io.to(table.id).emit("place button", "dealer", table.game.d_pos);
	io.to(table.id).emit("place button", "bb", table.game.bb_pos);
	io.to(table.id).emit("highlights", table.game.highlights_pos, "on");
}

function		blinds_treatment(table, sb, bb)
{
	if (sb.player.bankroll <= 0)
		sb.player.bankroll = +cfg.start_bankroll; // New cave!
	if (bb.player.bankroll <= 0)
		bb.player.bankroll = +cfg.start_bankroll;
	sb.player.bankroll -= cfg.conf.small_blind;
	table.game.pot_amount += +cfg.conf.small_blind;
	bb.player.bankroll -= cfg.conf.big_blind;
	table.game.pot_amount += +cfg.conf.big_blind;
	table.game.curbet = cfg.conf.big_blind;
}

function		send_blinds(table, sb, bb)
{
	io.to(table.id).emit("bankroll modification", table.game.sb_pos, sb.player);
	io.to(table.id).emit("bankroll modification", table.game.bb_pos, bb.player);
	io.to(table.id).emit("pot modification", table.game.pot_amount);
	io.to(table.id).emit("bet", table.game.sb_pos, sb.bet = cfg.conf.small_blind);
	io.to(table.id).emit("bet", table.game.bb_pos, bb.bet = cfg.conf.big_blind);

	console.log('sb : ' + sb.bet, 'bb : ' + bb.bet);
}

function		ask_first_player(socket, player, game)
{
	//starts_timer(table, player.nickname);
	send_option(table, game.highlights_pos, "first choice", "call", /*game.highlights_pos === game.sb_pos ? game.curbet / 2 :*/ game.curbet);
	send_option(table, game.highlights_pos, "second choice", "null", -1/*game.highlights_pos === game.sb_pos ? game.curbet * 2 / 2 : game.curbet */);
	send_option(table, game.highlights_pos, "third choice", "fold");
	/* SEE PLAYER GENERAL SOCKETS FOR THE FOLLOWING */
}

function		players_wait_mode(table)
{
	for (var idx = 1; idx <= 6; ++idx)
		io.to(get_private_id(table.private_ids, idx)).emit("turn wait");
}

function		game_routine(socket, table)
{
	var			sb; // small blind.
	var			bb;	// big blind.

	table.game.d_pos = find_dealer(table, table.game);
	table.game.sb_pos = find_sb(table, table.game);
	table.game.bb_pos = find_bb(table, table.game);
	/*
	console.log("Dealer is at seat " + table.game.d_pos);
	console.log("Small blind is at seat " + table.game.sb_pos);
	console.log("Big blind is at seat " + table.game.bb_pos);
	*/

	get_first_to_talk(table, table.game);
	send_emplacements(table);					   		// Send buttons emplacements.
	sb = get_seat(table.seats, table.game.sb_pos);
	bb = get_seat(table.seats, table.game.bb_pos);
	blinds_treatment(table, sb, bb); 				   // Take blinds (server side).
	send_blinds(table, sb, bb); 					   // Send blinds to clients.
	/* Preflop */
	preflop_deal(socket, table.game, table);
	preflop_first_cards_suits(socket, table.game, table);
	table.game.curbet = cfg.conf.big_blind;
	send_raise_limits(table, table.game, table.game.highlights_pos, 0);
	players_wait_mode(table);
	console.log('ask first player');
	ask_first_player(socket, table, table.game);
}

function		init_obj(table)
{
	var			idx = 1;
	var			seat;

	while (idx <= 6)
	{
		seat = get_seat(table.seats, idx);
		seat.bet = 0;
		++idx;
	}
}

function		stop_high_rollers(table)
{
	var			seat;

	for (var idx = 1; idx <= 6; ++idx)
	{
		seat = get_seat(table.seats, idx)
		if (seat.player.bankroll >= 9999)
			seat.player.bankroll = 9000;
		else if (seat.player.bankroll <= 0)
			seat.player.bankroll = +cfg.start_bankroll;
		io.to(table.id).emit("bankroll modification", idx, seat.player);
		/* send cards to player (should not be here) */
		if ((table.playing_seats.indexOf(idx) != -1))
			io.to(table.id).emit("give cards", idx);
	}
}

function		new_cashgame(socket, table)
{
	init_obj(table);
	table.game.moment = "preflop";
	table.game.round_nb = socket === 42 ? 0 : 1;
	table.game.pot_amount = 0;
	table.game.curbet = 0;
	io.to(table.id).emit("pot modification", table.game.pot_amount);
	fisher_shuffle(table.game.deck);
	stop_high_rollers(table);
	console.log("Round nb: " + table.game.round_nb);
	return game_routine(socket, table);
}
<|endoftext|>