<commit_before>/*!
 * Start Bootstrap - Grayscale Bootstrap Theme (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

// jQuery to collapse the navbar on scroll
$(window).scroll(function() {
    if ($(".navbar").offset().top > 50) {
        $(".navbar-fixed-top").addClass("top-nav-collapse");
    } else {
        $(".navbar-fixed-top").removeClass("top-nav-collapse");
    }
});

// jQuery for page scrolling feature - requires jQuery Easing plugin
$(function() {
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });
});

// Closes the Responsive Menu on Menu Item Click
$('.navbar-collapse ul li a').click(function() {
    $('.navbar-toggle:visible').click();
});

// Google Maps Scripts
// When the window has finished loading create our google map below
google.maps.event.addDomListener(window, 'load', init);

function init() {
    // Basic options for a simple Google Map
    // For more options see: https://developers.google.com/maps/documentation/javascript/reference#MapOptions
    var mapOptions = {
        // How zoomed in you want the map to start at (always required)
        zoom: 16,

        //Type of map
        mapTypeId: google.maps.MapTypeId.HYBRID,

        // The latitude and longitude to center the map (always required)
        center: new google.maps.LatLng(59.852454,17.629119), // Uppsala

        // Disables the default Google Maps UI components
        disableDefaultUI: false, //Changed
        scrollwheel: false,
        draggable: true, //Changed

        // How you would like to style the map.
        // This is where you would paste any style found on Snazzy Maps.
        /* styles: [{
            "featureType": "water",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 17
            }]
        }, {
            "featureType": "landscape",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 20
            }]
        }, {
            "featureType": "road.highway",
            "elementType": "geometry.fill",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 17
            }]
        }, {
            "featureType": "road.highway",
            "elementType": "geometry.stroke",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 29
            }, {
                "weight": 0.2
            }]
        }, {
            "featureType": "road.arterial",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 18
            }]
        }, {
            "featureType": "road.local",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 16
            }]
        }, {
            "featureType": "poi",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 21
            }]
        }, {
            "elementType": "labels.text.stroke",
            "stylers": [{
                "visibility": "on"
            }, {
                "color": "#000000"
            }, {
                "lightness": 16
            }]
        }, {
            "elementType": "labels.text.fill",
            "stylers": [{
                "saturation": 36
            }, {
                "color": "#000000"
            }, {
                "lightness": 40
            }]
        }, {
            "elementType": "labels.icon",
            "stylers": [{
                "visibility": "off"
            }]
        }, {
            "featureType": "transit",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 19
            }]
        }, {
            "featureType": "administrative",
            "elementType": "geometry.fill",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 20
            }]
        }, {
            "featureType": "administrative",
            "elementType": "geometry.stroke",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 17
            }, {
                "weight": 1.2
            }]
        }] */
    };

    // Get the HTML DOM element that will contain your map
    // We are using a div with id="map" seen below in the <body>
    var mapElement = document.getElementById('map');

    // Create the Google Map using out element and options defined above
    var map = new google.maps.Map(mapElement, mapOptions);

    // Custom Map Marker Icon - Customize the map-marker.png file to customize your icon
    //var image = 'img/RedMarker.png';
    var myLatLng = new google.maps.LatLng(59.852454,17.629119);
    var beachMarker = new google.maps.Marker({
        position: myLatLng,
        map: map,
        title: "Place of Woop Woop!"
    });
}
<commit_msg>I can change my mind<commit_after>/*!
 * Start Bootstrap - Grayscale Bootstrap Theme (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

// jQuery to collapse the navbar on scroll
$(window).scroll(function() {
    if ($(".navbar").offset().top > 50) {
        $(".navbar-fixed-top").addClass("top-nav-collapse");
    } else {
        $(".navbar-fixed-top").removeClass("top-nav-collapse");
    }
});

// jQuery for page scrolling feature - requires jQuery Easing plugin
$(function() {
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });
});

// Closes the Responsive Menu on Menu Item Click
$('.navbar-collapse ul li a').click(function() {
    $('.navbar-toggle:visible').click();
});

// Google Maps Scripts
// When the window has finished loading create our google map below
google.maps.event.addDomListener(window, 'load', init);

function init() {
    // Basic options for a simple Google Map
    // For more options see: https://developers.google.com/maps/documentation/javascript/reference#MapOptions
    var mapOptions = {
        // How zoomed in you want the map to start at (always required)
        zoom: 16,

        //Type of map
        mapTypeId: google.maps.MapTypeId.HYBRID,

        // The latitude and longitude to center the map (always required)
        center: new google.maps.LatLng(59.852454,17.629119), // Uppsala

        // Disables the default Google Maps UI components
        disableDefaultUI: false, //Changed
        scrollwheel: false,
        draggable: true, //Changed

        // How you would like to style the map.
        // This is where you would paste any style found on Snazzy Maps.
        /* styles: [{
            "featureType": "water",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 17
            }]
        }, {
            "featureType": "landscape",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 20
            }]
        }, {
            "featureType": "road.highway",
            "elementType": "geometry.fill",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 17
            }]
        }, {
            "featureType": "road.highway",
            "elementType": "geometry.stroke",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 29
            }, {
                "weight": 0.2
            }]
        }, {
            "featureType": "road.arterial",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 18
            }]
        }, {
            "featureType": "road.local",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 16
            }]
        }, {
            "featureType": "poi",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 21
            }]
        }, {
            "elementType": "labels.text.stroke",
            "stylers": [{
                "visibility": "on"
            }, {
                "color": "#000000"
            }, {
                "lightness": 16
            }]
        }, {
            "elementType": "labels.text.fill",
            "stylers": [{
                "saturation": 36
            }, {
                "color": "#000000"
            }, {
                "lightness": 40
            }]
        }, {
            "elementType": "labels.icon",
            "stylers": [{
                "visibility": "off"
            }]
        }, {
            "featureType": "transit",
            "elementType": "geometry",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 19
            }]
        }, {
            "featureType": "administrative",
            "elementType": "geometry.fill",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 20
            }]
        }, {
            "featureType": "administrative",
            "elementType": "geometry.stroke",
            "stylers": [{
                "color": "#000000"
            }, {
                "lightness": 17
            }, {
                "weight": 1.2
            }]
        }] */
    };

    // Get the HTML DOM element that will contain your map
    // We are using a div with id="map" seen below in the <body>
    var mapElement = document.getElementById('map');

    // Create the Google Map using out element and options defined above
    var map = new google.maps.Map(mapElement, mapOptions);

    // Custom Map Marker Icon - Customize the map-marker.png file to customize your icon
    //var image = 'img/RedMarker.png';
    var myLatLng = new google.maps.LatLng(59.852454,17.629119);
    var beachMarker = new google.maps.Marker({
        position: myLatLng,
        map: map,
        title: "Linnéanum, Uppsala. International place of Woop Woop!"
    });
}
<|endoftext|>


<commit_before>/**
 * ****************************************************************************
 *
 *    /\_/\             HTML to JSON
 *  ( ^ v ^ )_______    Author: Nick, Tian Jin, China
 * (~) Version: 2.0 ()  License: MIT
 *
 * ****************************************************************************
 * 2016.07.14           https://github.com/incNick/html2json
 * ****************************************************************************
 */
(function($) {
    var html2json = {
        /**
         * Update html group settings
         *
         * @param Object        source      The json html template
         * @param Array|Object  jsonSection
         * @param Array|string  path        Not required, Example: 'uniqueKey'
         * @param string        action      if null then update
         * @return void
         */
        updateJsonTemplate: function (source, jsonSection, path, action) {
            var actions = ['update', 'prepend', 'append', 'after', 'before', 'remove'], format = _format = false, target = latest = '';
            if (! action || ! $.inArray(action.toLowerCase(), actions)) action = 'update';
            action = action.toLowerCase();
            if (path && (jsonSection._init_ && $.isArray(jsonSection._init_) && jsonSection._init_.length || action === 'remove')) {
                format = jsonSection._init_ || {};
                delete jsonSection._init_;
            }
            $.extend(source, jsonSection);
            if (! format) return;

            if (! $.isArray(path)) path = path.split('/');
            _format = source._init_;
            for (var i = 0, l = path.length; i < l; i++) {
                if (latest !== '') target += '[' + latest + ']._child_';
                var key = path[i];
                if (isNaN(key)) {
                    for (var n = 0, x = _format.length; n < x; n ++) {
                        if (_format[n]._ref_ === key) {
                            latest = n;
                            break;
                        }
                    }
                } else {
                    latest = key;
                }
                _format = _format[latest]._child_;
            }
            switch(action) {
                case 'update':
                    eval('source._init_' + target + '[' + latest + ']._child_ = format');
                    break;
                case 'prepend':
                    eval('source._init_' + target + '[' + latest + ']._child_.unshift(format)');
                    break;
                case 'append':
                    eval('source._init_' + target + '[' + latest + ']._child_.push(format)');
                    break;
                case 'before':
                    eval('source._init_' + target + '.splice(' + latest + ', 0, format)');
                    break;
                case 'after':
                    eval('source._init_' + target + '.splice(' + (latest + 1) + ', 0, format)');
                    break;
                case 'remove':
                    eval('source._init_' + target + '.splice(' + latest + ', 1)');
                    break;
            }
        },
        /**
         * Parse json template to html source
         *
         * @param Object    jsonTemplate
         * @param Boolean   returnObject    If true then return jQuery Html Elements, else return HTML string
         * @return jQueryHtmlElements|string
         */
        parseJsonTemplate: function (jsonTemplate, returnObject) {
            var template = $.extend(true, {}, jsonTemplate);
            var format = template._init_, element = $('

');
            delete template._init_;
            jQueryElement(format, template, element);
            if (returnObject) return element.children();
            return element.html();

            /**
             * Group element
             *
             * @param Array|Object      node
             * @param Array|Object      jsonTemplate referece: jsonTemplate._init_
             * @param jQueryObject      parentNode
             * @return void
             */
            function jQueryElement(node, jsonTemplate, parentNode) {
                if ($.isArray(node)) {
                    for (var i = 0, l = node.length; i < l; i ++) {
                        jQueryElement(node[i], jsonTemplate, parentNode);
                    }
                } else {
                    if (node._ref_ === '_text_') {
                        element = formatText(node._value_);
                    } else if (node._ref === '_html_') {
                        element = $(node._value_);
                    } else {
                        var element = $(optionsToHtml(node._ref_, jsonTemplate[node._ref_], node));
                        if (node._child_)    {
                            jQueryElement(node._child_, jsonTemplate, element);
                        }
                    }
                    parentNode.append(element);
                }
            }

            /**
             * Format text
             * @param string str
             * @return string
             */
            function formatText(str) {
                var div = document.createElement("div");
                div.innerHTML = str;
                return div.innerText;
            }

            /**
             * Translate json node to html source
             *
             * @param Array|Object      jsonTemplate
             * @return string
             */
            function optionsToHtml(tagKey, jsonTemplate, settings) {
                var html = '';
                for (var tag in jsonTemplate) {
                    var innerContent = '';
                    var attributes = ['_juid_="' + tagKey + '"'];
                    var options = {};
                    $.extend(options, jsonTemplate[tag], settings);
                    for (var attribute in options) {
                        if (attribute === '_text_') {
                            innerContent += formatText(options[attribute]);
                            continue;
                        }
                        if (attribute === '_html_') {
                            innerContent += options[attribute];
                            continue;
                        }
                        if ((/^_.+_$/).test(attribute)) continue;
                        if (options[attribute] === false) continue;
                        if (options[attribute] === true) {
                            attributes.push(attribute + '="' + attribute + '"');
                        } else {
                            attributes.push(attribute + '="' + options[attribute] + '"');
                        }
                    }
                    attributes = attributes.join(' ');
                    if (attributes.length > 0)  attributes = ' ' + attributes;
                    html = '<' + tag + attributes;
                    if ($.inArray(tag, ['input', 'img', 'br', 'hr', 'area']) > -1) {
                        html += ' />';
                    } else {
                        html += '>';
                        if (innerContent !== '') html += innerContent;
                        html += '</' + tag + '>';
                    }
                }
                return html;
            }
        },
        /**
         * Translate current elements to JSON
         *
         * @param Array     elements    Html element(s)
         * @return Object
         */
        toJsonTemplate: function (elements) {
            var totalTags = {}, jsonTemplate = {}, elements = $(elements);
            var format = parseJQueryElement(elements.toArray(), totalTags, jsonTemplate);
            jsonTemplate._init_ = format;
            return jsonTemplate;

            /**
             * Parse jQuery object
             *
             * @param jQueryElements    elements
             * @param Object            totalTags       Use for build unique node key
             * @param Object            jsonTemplate
             * @return Array|Object
             */
            function parseJQueryElement(elements, totalTags, jsonTemplate) {
                if ($.isArray(elements)) {
                    var format = [];
                    for (var i = 0, l = elements.length; i < l; i ++) {
                        format.push(parseJQueryElement(elements[i], totalTags, jsonTemplate));
                    }
                } else {
                    var format = {}, element = $(elements), key = false;
                    if (element[0].nodeName === '#text') {
                        format = {_ref_: '_text_', _value_: element[0].nodeValue};
                    } else {
                        var tagName = element[0].tagName.toLowerCase();
                        if (element.attr('_juid_')) {
                            key = element.attr('_juid_');
                        } else {
                            if (! totalTags[tagName]) totalTags[tagName] = 0;
                            totalTags[tagName] ++;
                            key = tagName + totalTags[tagName].toString();
                        }
                        var attributes = element[0].attributes;
                        jsonTemplate[key] = {};
                        jsonTemplate[key][tagName] = {};
                        for (var i = 0, l = attributes.length; i < l; i ++) {
                            if (attributes[i].nodeName == '_juid_') continue;
                            jsonTemplate[key][tagName][attributes[i].nodeName] = attributes[i].nodeValue;
                        }
                        format._ref_ = key;
                        var childs = element.contents().toArray();
                        if (childs.length) {
                            format._child_ = parseJQueryElement(childs, totalTags, jsonTemplate);
                        }
                    }
                }
                return format;
            }
        }
    };
    $.extend({
        html2json: html2json
    });
})(jQuery);
<commit_msg>Fix bug<commit_after>/**
 * ****************************************************************************
 *
 *    /\_/\             HTML to JSON
 *  ( ^ v ^ )_______    Author: Nick, Tian Jin, China
 * (~) Version: 2.0 ()  License: MIT
 *
 * ****************************************************************************
 * 2016.07.14           https://github.com/incNick/html2json
 * ****************************************************************************
 */
(function($) {
    var html2json = {
        /**
         * Update html group settings
         *
         * @param Object        source      The json html template
         * @param Array|Object  jsonSection
         * @param Array|string  path        Not required, Example: 'uniqueKey'
         * @param string        action      if null then update
         * @return void
         */
        updateJsonTemplate: function (source, jsonSection, path, action) {
            var actions = ['update', 'prepend', 'append', 'after', 'before', 'remove'], format = _format = false, target = latest = '';
            if (! action || ! $.inArray(action.toLowerCase(), actions)) action = 'update';
            action = action.toLowerCase();
            if (path && (jsonSection._init_ && $.isArray(jsonSection._init_) && jsonSection._init_.length || action === 'remove')) {
                format = jsonSection._init_ || {};
                delete jsonSection._init_;
            }
            $.extend(source, jsonSection);
            if (! format) return;

            if (! $.isArray(path)) path = path.split('/');
            _format = source._init_;
            for (var i = 0, l = path.length; i < l; i++) {
                if (latest !== '') target += '[' + latest + ']._child_';
                var key = path[i];
                if (isNaN(key)) {
                    for (var n = 0, x = _format.length; n < x; n ++) {
                        if (_format[n]._ref_ === key) {
                            latest = n;
                            break;
                        }
                    }
                } else {
                    latest = key;
                }
                _format = _format[latest]._child_;
            }
            switch(action) {
                case 'update':
                    eval('source._init_' + target + '[' + latest + ']._child_ = format');
                    break;
                case 'prepend':
                    eval('source._init_' + target + '[' + latest + ']._child_.unshift(format)');
                    break;
                case 'append':
                    eval('source._init_' + target + '[' + latest + ']._child_.push(format)');
                    break;
                case 'before':
                    eval('source._init_' + target + '.splice(' + latest + ', 0, format)');
                    break;
                case 'after':
                    eval('source._init_' + target + '.splice(' + (latest + 1) + ', 0, format)');
                    break;
                case 'remove':
                    eval('source._init_' + target + '.splice(' + latest + ', 1)');
                    break;
            }
        },
        /**
         * Parse json template to html source
         *
         * @param Object    jsonTemplate
         * @param Boolean   returnObject    If true then return jQuery Html Elements, else return HTML string
         * @return jQueryHtmlElements|string
         */
        parseJsonTemplate: function (jsonTemplate, returnObject) {
            var template = $.extend(true, {}, jsonTemplate);
            var format = template._init_, element = $('

');
            delete template._init_;
            jQueryElement(format, template, element);
            if (returnObject) return element.children();
            return element.html();

            /**
             * Group element
             *
             * @param Array|Object      node
             * @param Array|Object      jsonTemplate referece: jsonTemplate._init_
             * @param jQueryObject      parentNode
             * @return void
             */
            function jQueryElement(node, jsonTemplate, parentNode) {
                if ($.isArray(node)) {
                    for (var i = 0, l = node.length; i < l; i ++) {
                        jQueryElement(node[i], jsonTemplate, parentNode);
                    }
                } else {
                    if (node._ref_ === '_text_') {
                        element = formatText(node._value_);
                    } else if (node._ref === '_html_') {
                        element = $(node._value_);
                    } else {
                        var element = $(optionsToHtml(node._ref_, jsonTemplate[node._ref_], node));
                        if (node._child_)    {
                            jQueryElement(node._child_, jsonTemplate, element);
                        }
                    }
                    parentNode.append(element);
                }
            }

            /**
             * Format text
             * @param string str
             * @return string
             */
            function formatText(str) {
                var div = document.createElement("div");
                div.innerHTML = str;
                return div.innerText;
            }

            /**
             * Translate json node to html source
             *
             * @param Array|Object      jsonTemplate
             * @return string
             */
            function optionsToHtml(tagKey, jsonTemplate, settings) {
                var html = '';
                for (var tag in jsonTemplate) {
                    var innerContent = '';
                    var attributes = ['_juid_="' + tagKey + '"'];
                    var options = {};
                    $.extend(options, jsonTemplate[tag], settings);
                    for (var attribute in options) {
                        if (attribute === '_text_') {
                            innerContent += formatText(options[attribute]);
                            continue;
                        }
                        if (attribute === '_html_') {
                            innerContent += options[attribute];
                            continue;
                        }
                        if ((/^_.+_$/).test(attribute)) continue;
                        if (options[attribute] === false) continue;
                        if (options[attribute] === true) {
                            attributes.push(attribute + '="' + attribute + '"');
                        } else {
                            attributes.push(attribute + '="' + options[attribute] + '"');
                        }
                    }
                    attributes = attributes.join(' ');
                    if (attributes.length > 0)  attributes = ' ' + attributes;
                    html = '<' + tag + attributes;
                    if ($.inArray(tag, ['input', 'img', 'br', 'hr', 'area']) > -1) {
                        html += ' />';
                    } else {
                        html += '>';
                        if (innerContent !== '') html += innerContent;
                        html += '</' + tag + '>';
                    }
                }
                return html;
            }
        },
        /**
         * Translate current elements to JSON
         *
         * @param Array     elements    Html element(s)
         * @return Object
         */
        toJsonTemplate: function (elements) {
            var totalTags = {}, jsonTemplate = {}, elements = $(elements);
            var format = parseJQueryElement(elements.toArray(), totalTags, jsonTemplate);
            jsonTemplate._init_ = format;
            return jsonTemplate;

            /**
             * Parse jQuery object
             *
             * @param jQueryElements    elements
             * @param Object            totalTags       Use for build unique node key
             * @param Object            jsonTemplate
             * @return Array|Object
             */
            function parseJQueryElement(elements, totalTags, jsonTemplate) {
                if ($.isArray(elements)) {
                    var format = [];
                    for (var i = 0, l = elements.length; i < l; i ++) {
                        var _subFormat = parseJQueryElement(elements[i], totalTags, jsonTemplate);
                        if (_subFormat !== false) format.push(_subFormat);
                    }
                } else {
                    var format = {}, element = elements, key = false;
                    if (element.nodeName === '#text') {
                        element.nodeValue = element.nodeValue.replace(/^( |\t)+|( |\t)+$/g, '');
                        if (element.nodeValue.length < 1) return false;
                        return {_ref_: '_text_', _value_: element.nodeValue};
                    } else {
                        var tagName = element.tagName.toLowerCase();
                        element = $(element);
                        if (element.attr('_juid_')) {
                            key = element.attr('_juid_');
                        } else {
                            if (! totalTags[tagName]) totalTags[tagName] = 0;
                            totalTags[tagName] ++;
                            key = tagName + totalTags[tagName].toString();
                        }
                        var attributes = element[0].attributes;
                        jsonTemplate[key] = {};
                        jsonTemplate[key][tagName] = {};
                        for (var i = 0, l = attributes.length; i < l; i ++) {
                            if (attributes[i].nodeName == '_juid_') continue;
                            jsonTemplate[key][tagName][attributes[i].nodeName] = attributes[i].nodeValue;
                        }
                        format._ref_ = key;
                        var childs = element.contents().toArray();
                        if (childs.length) {
                            format._child_ = parseJQueryElement(childs, totalTags, jsonTemplate);
                        }
                    }
                }
                return format;
            }
        }
    };
    $.extend({
        html2json: html2json
    });
})(jQuery);
<|endoftext|>


<commit_before>window.hxManager = (function( Object , Error , $ , Promise ) {

    var PROTOTYPE = 'prototype';
    var PROMISE = 'promise';

    function hxManager( j ) {

        if (instOf( j , hxManager )) {
            return j;
        }

        var that = this;

        j.each(function( i ) {
            that[i] = hxManager.DomNodeFactory( j[i] );
        });

        Object.defineProperty( that , 'length' , {
            get: function() {
                return length( j );
            }
        });
    }

    var hxManager_prototype = (hxManager[PROTOTYPE] = Object.create( $[PROTOTYPE] ));

    hxManager_prototype.animate = function( bundle ) {

        var that = this;

        that.eachNode(function( $hx , node , i ) {

            var pod = PodFactory( node , 'animation' );

            ensureArray( bundle ).forEach(function( seed ) {

                if (isFunc( seed )) {
                    pod.addCallback(
                        bind( that , seed )
                    );
                }
                else {
                    var bean = Bean( seed , node , i );
                    pod.addBean( bean );
                }
            });

            $hx.addPod( pod );
        });

        return that;
    };

    hxManager_prototype.iterate = function( bundle ) {

        var that = this;

        that.eachNode(function( $hx , node , i ) {

            var pod = PodFactory( node , 'precision' );

            ensureArray( bundle ).forEach(function( seed ) {

                if (isFunc( seed )) {
                    pod.addCallback(
                        bind( that , seed )
                    );
                }
                else {
                    var bean = Bean( seed , node , i );
                    var iterator = new hxManager.IteratorMOJO( node , bean );
                    pod.addBean( iterator );
                }
            });

            $hx.addPod( pod );
        });

        return that;
    };

    hxManager_prototype.promise = function( func , method ) {

        method = method || 'all';

        var that = this;
        var micro = [];
        var pods = [];

        that.eachNode(function( $hx , node ) {

            // create a promisePod for each dom node
            var pod = PodFactory( node , PROMISE );

            // when the pod reaches its turn in the queue, resolve its promise
            pod.when( 'promiseMade' , function() {
                pod.resolvePromise();
            });

            // create a microPromise for each pod
            var microPromise = new Promise(function( resolve ) {
                // when the pod is resolved, resolve the microPromise
                pod.when( 'promiseResolved' , resolve );
            });

            // add the promise to the dom node queue
            $hx.addPod( pod );

            pods.push( pod );
            micro.push( microPromise );
        });

        // when the appropriate microPromises have been resolved, create the macroPromise
        Promise[ method ]( micro ).then(function() {

            var macroPromise = new Promise(
                bind( that , func )
            );

            // if the macroPromise is resolved, resolve the pods
            macroPromise.then(function() {
                pods.forEach(function( pod ) {
                    pod.resolvePod();
                });
            });

            // otherwise, clear the queue so we can start again
            macroPromise.catch(function( err ) {
                that.clear();
                if (instOf( err , Error )) {
                    $.hx.error( err );
                }
            });
        });

        return that;
    };

    hxManager_prototype.eachNode = function( callback ) {
        var that = this;
        toArray( that ).forEach(function( node , i ) {
            callback( node.$hx , node , i );
        });
        return that;
    };

    hxManager_prototype.pause = function() {
        return this._precisionPodAction( 'pause' );
    };

    hxManager_prototype.resume = function() {
        return this._precisionPodAction( 'resume' );
    };

    hxManager_prototype._precisionPodAction = function( method , attempts ) {

        attempts = attempts || 0;

        var that = this;

        var pods = toArray( that )
            .map(function( node ) {
                return node.$hx.getCurrentPod();
            })
            .filter(function( pod ) {
                return pod.type === 'precision';
            });

        if (length( pods ) !== length( that ) && attempts < 10) {
            var unsubscribe = subscribe(function() {
                attempts++;
                unsubscribe();
                that._precisionPodAction( method , attempts );
            });
        }
        else {
            pods.forEach(function( pod ) {
                pod[ method ]();
            });
        }

        return that;
    };

    hxManager_prototype.paint = function( type ) {

        var that = this;

        that.eachNode(function( $hx ) {
            $hx.paint( type );
        });

        return that;
    };

    hxManager_prototype.reset = function( type ) {

        var that = this;

        that.eachNode(function( $hx ) {
            $hx.resetComponents( type );
        });

        return that;
    };

    hxManager_prototype.then = function( func ) {
        return this.promise( func );
    };

    hxManager_prototype.race = function( func ) {
        return this.promise( func , 'race' );
    };

    hxManager_prototype.defer = function( time ) {
        return this.promise(function( resolve ) {
            if (time) {
                var unsubscribe = subscribe(function( elapsed ) {
                    if (elapsed >= time) {
                        unsubscribe();
                        resolve();
                    }
                });
            }
        });
    };

    hxManager_prototype.update = function( bundle ) {

        // update a node's components without applying the transition

        var that = this;

        ensureArray( bundle ).forEach(function( seed ) {

            that.eachNode(function( $hx , node , i ) {

                var bean = Bean( seed , node , i );
                $hx.updateComponent( bean );
            });
        });

        return that;
    };

    hxManager_prototype.resolve = function( all ) {

        var that = this;

        // all controls whether all pod types or only promise pods will be resolved
        all = (!isUndef( all ) ? all : false);

        // force resolve the current pod in each queue
        that.eachNode(function( $hx ) {

            var pod = $hx.getCurrentPod();

            if (pod && (all || (!all && pod.type === PROMISE))) {
                pod.resolvePod();
            }
        });

        return that;
    };

    hxManager_prototype.clear = function() {

        var that = this;

        // clear all pods in each queue
        that.eachNode(function( $hx ) {
            $hx.clearQueue();
        });

        return that;
    };

    hxManager_prototype.break = function() {

        var that = this;

        // clear all but the current pod in each queue
        that.eachNode(function( $hx ) {
            $hx.clearQueue( false );
        });

        // resolve any remaining promise pods
        return that.resolve();
    };

    hxManager_prototype.zero = function( hxArgs ) {

        var that = this;

        // update the stored components
        that.update( hxArgs );

        // remove any stored transitions
        that.eachNode(function( $hx ) {
            $hx.resetTransition();
            $hx.applyTransition();
        });

        // run paint
        return that.paint();
    };

    // !!! done does not return the hxManager instance
    hxManager_prototype.done = function( func ) {

        var that = this;

        that.promise(function( resolve ) {
            (func || function() {}).call( that );
            resolve();
        });
    };

    // !!! get does not return the hxManager instance
    hxManager_prototype.get = function( find , pretty ) {
        return toArray( this ).map(function( node ) {
            return node.$hx.getComponents( find , pretty );
        });
    };

    // !!! clean does not return the hxManager instance
    hxManager_prototype.cleanup = function() {

        this.eachNode(function( $hx ) {
            $hx.cleanup();
        });
    };

    function Bean( seed , node , i ) {
        return new hxManager.Bean( seed , node , i );
    }

    function PodFactory( node , type ) {
        return hxManager.PodFactory( node , type );
    }

    function subscribe( callback ) {
        return $.hx.subscribe( callback );
    }

    function bind( hxm , func ) {
        return func.bind( hxm );
    }

    function toArray( hxm ) {
        return hxm.toArray();
    }

    function Helper() {
        return hxManager.Helper;
    }

    function ensureArray( bundle ) {
        return Helper().ensureArray( bundle );
    }

    function instOf( subject , constructor ) {
        return Helper().instOf( subject , constructor );
    }

    function isFunc( subject ) {
        return Helper().isFunc( subject );
    }

    function isUndef( subject ) {
        return Helper().isUndef( subject );
    }

    function length( subject ) {
        return Helper().length( subject );
    }

    return hxManager;

}( Object , Error , jQuery , Promise ));

<commit_msg>adding detach method<commit_after>window.hxManager = (function( Object , Error , $ , Promise ) {

    var PROTOTYPE = 'prototype';
    var PROMISE = 'promise';

    function hxManager( j ) {

        if (instOf( j , hxManager )) {
            return j;
        }

        var that = this;

        j.each(function( i ) {
            that[i] = hxManager.DomNodeFactory( j[i] );
        });

        Object.defineProperty( that , 'length' , {
            get: function() {
                return length( j );
            }
        });
    }

    var hxManager_prototype = (hxManager[PROTOTYPE] = Object.create( $[PROTOTYPE] ));

    hxManager_prototype.animate = function( bundle ) {

        var that = this;

        that.eachNode(function( $hx , node , i ) {

            var pod = PodFactory( node , 'animation' );

            ensureArray( bundle ).forEach(function( seed ) {

                if (isFunc( seed )) {
                    pod.addCallback(
                        bind( that , seed )
                    );
                }
                else {
                    var bean = Bean( seed , node , i );
                    pod.addBean( bean );
                }
            });

            $hx.addPod( pod );
        });

        return that;
    };

    hxManager_prototype.iterate = function( bundle ) {

        var that = this;

        that.eachNode(function( $hx , node , i ) {

            var pod = PodFactory( node , 'precision' );

            ensureArray( bundle ).forEach(function( seed ) {

                if (isFunc( seed )) {
                    pod.addCallback(
                        bind( that , seed )
                    );
                }
                else {
                    var bean = Bean( seed , node , i );
                    var iterator = new hxManager.IteratorMOJO( node , bean );
                    pod.addBean( iterator );
                }
            });

            $hx.addPod( pod );
        });

        return that;
    };

    hxManager_prototype.promise = function( func , method ) {

        method = method || 'all';

        var that = this;
        var micro = [];
        var pods = [];

        that.eachNode(function( $hx , node ) {

            // create a promisePod for each dom node
            var pod = PodFactory( node , PROMISE );

            // when the pod reaches its turn in the queue, resolve its promise
            pod.when( 'promiseMade' , function() {
                pod.resolvePromise();
            });

            // create a microPromise for each pod
            var microPromise = new Promise(function( resolve ) {
                // when the pod is resolved, resolve the microPromise
                pod.when( 'promiseResolved' , resolve );
            });

            // add the promise to the dom node queue
            $hx.addPod( pod );

            pods.push( pod );
            micro.push( microPromise );
        });

        // when the appropriate microPromises have been resolved, create the macroPromise
        Promise[ method ]( micro ).then(function() {

            var macroPromise = new Promise(
                bind( that , func )
            );

            // if the macroPromise is resolved, resolve the pods
            macroPromise.then(function() {
                pods.forEach(function( pod ) {
                    pod.resolvePod();
                });
            });

            // otherwise, clear the queue so we can start again
            macroPromise.catch(function( err ) {
                that.clear();
                if (instOf( err , Error )) {
                    $.hx.error( err );
                }
            });
        });

        return that;
    };

    hxManager_prototype.eachNode = function( callback ) {
        var that = this;
        toArray( that ).forEach(function( node , i ) {
            callback( node.$hx , node , i );
        });
        return that;
    };

    hxManager_prototype.pause = function() {
        return this._precisionPodAction( 'pause' );
    };

    hxManager_prototype.resume = function() {
        return this._precisionPodAction( 'resume' );
    };

    hxManager_prototype._precisionPodAction = function( method , attempts ) {

        attempts = attempts || 0;

        var that = this;

        var pods = toArray( that )
            .map(function( node ) {
                return node.$hx.getCurrentPod();
            })
            .filter(function( pod ) {
                return pod.type === 'precision';
            });

        if (length( pods ) !== length( that ) && attempts < 10) {
            var unsubscribe = subscribe(function() {
                attempts++;
                unsubscribe();
                that._precisionPodAction( method , attempts );
            });
        }
        else {
            pods.forEach(function( pod ) {
                pod[ method ]();
            });
        }

        return that;
    };

    hxManager_prototype.paint = function( type ) {

        var that = this;

        that.eachNode(function( $hx ) {
            $hx.paint( type );
        });

        return that;
    };

    hxManager_prototype.reset = function( type ) {

        var that = this;

        that.eachNode(function( $hx ) {
            $hx.resetComponents( type );
        });

        return that;
    };

    hxManager_prototype.then = function( func ) {
        return this.promise( func );
    };

    hxManager_prototype.race = function( func ) {
        return this.promise( func , 'race' );
    };

    hxManager_prototype.defer = function( time ) {
        return this.promise(function( resolve ) {
            if (time) {
                var unsubscribe = subscribe(function( elapsed ) {
                    if (elapsed >= time) {
                        unsubscribe();
                        resolve();
                    }
                });
            }
        });
    };

    hxManager_prototype.update = function( bundle ) {

        // update a node's components without applying the transition

        var that = this;

        ensureArray( bundle ).forEach(function( seed ) {

            that.eachNode(function( $hx , node , i ) {

                var bean = Bean( seed , node , i );
                $hx.updateComponent( bean );
            });
        });

        return that;
    };

    hxManager_prototype.resolve = function( all ) {

        var that = this;

        // all controls whether all pod types or only promise pods will be resolved
        all = (!isUndef( all ) ? all : false);

        // force resolve the current pod in each queue
        that.eachNode(function( $hx ) {

            var pod = $hx.getCurrentPod();

            if (pod && (all || (!all && pod.type === PROMISE))) {
                pod.resolvePod();
            }
        });

        return that;
    };

    hxManager_prototype.detach = function() {

        // detach callbacks from the subscriber module,
        // but still allow the pod to continue running

        var that = this;

        that.eachNode(function( $hx ) {
            $hx.getCurrentPod().detach();
        });

        return that;
    };

    hxManager_prototype.clear = function() {

        // clear all pods in each queue

        var that = this;

        that.eachNode(function( $hx ) {
            $hx.clearQueue();
        });

        return that;
    };

    hxManager_prototype.break = function() {

        var that = this;

        // clear all but the current pod in each queue
        that.eachNode(function( $hx ) {
            $hx.clearQueue( false );
        });

        // resolve any remaining promise pods
        return that.resolve();
    };

    hxManager_prototype.zero = function( hxArgs ) {

        var that = this;

        // update the stored components
        that.update( hxArgs );

        // remove any stored transitions
        that.eachNode(function( $hx ) {
            $hx.resetTransition();
            $hx.applyTransition();
        });

        // run paint
        return that.paint();
    };

    // !!! done does not return the hxManager instance
    hxManager_prototype.done = function( func ) {

        var that = this;

        that.promise(function( resolve ) {
            (func || function() {}).call( that );
            resolve();
        });
    };

    // !!! get does not return the hxManager instance
    hxManager_prototype.get = function( find , pretty ) {
        return toArray( this ).map(function( node ) {
            return node.$hx.getComponents( find , pretty );
        });
    };

    // !!! clean does not return the hxManager instance
    hxManager_prototype.cleanup = function() {

        this.eachNode(function( $hx ) {
            $hx.cleanup();
        });
    };

    function Bean( seed , node , i ) {
        return new hxManager.Bean( seed , node , i );
    }

    function PodFactory( node , type ) {
        return hxManager.PodFactory( node , type );
    }

    function subscribe( callback ) {
        return $.hx.subscribe( callback );
    }

    function bind( hxm , func ) {
        return func.bind( hxm );
    }

    function toArray( hxm ) {
        return hxm.toArray();
    }

    function Helper() {
        return hxManager.Helper;
    }

    function ensureArray( bundle ) {
        return Helper().ensureArray( bundle );
    }

    function instOf( subject , constructor ) {
        return Helper().instOf( subject , constructor );
    }

    function isFunc( subject ) {
        return Helper().isFunc( subject );
    }

    function isUndef( subject ) {
        return Helper().isUndef( subject );
    }

    function length( subject ) {
        return Helper().length( subject );
    }

    return hxManager;

}( Object , Error , jQuery , Promise ));

<|endoftext|>


<commit_before>//Draw the karyotype
jviz.modules.ideogram.prototype.karyotypeDraw = function()
{
  //Show loading
  this.loading(true);

  //Get the canvas draw zone
  var draw = this._karyotype.draw;

  //Calculate the margin
  this._karyotype.margin = (draw.width - this._genome.length * this._karyotype.chromosome.width) / (this._genome.length - 1);

  //Get the middle layer
  var canvas = this._canvas.el.layer(this._karyotype.draw.layer);

  //Clear the karyotype zone
  this.karyotypeClear(this._karyotype.draw.layer);

  //Reset the karyotypes positions
  this._karyotype.positions = [];

  //Draw all the karyotypes
  for(var i = 0; i < this._genome.chromosomes.length; i++)
  {
    //Get the chromosome
    var chr = this._genome.chromosomes[i];

    //Get the mark for this chromosome
    //var marks = this.GetMarks(ch.id).length;
    var marks = 0;

    //Get the chromosome width
    var chr_width = this._karyotype.chromosome.width;

    //Get the chromosome height
    var chr_height = draw.height * (chr.length / this._karyotype.max);

    //Get the chromosome position x
    var chr_x = draw.margin.left + (i + 0) * this._karyotype.margin + i * this._karyotype.chromosome.width;

    //Get the chromosome position y
    var chr_y = draw.margin.top + draw.height - chr_height;

    //Get the chromosome radius
    var chr_radius = this._karyotype.chromosome.radius;

    //Draw the chromosome
    canvas.Rect({ x: chr_x, y: chr_y, width: chr_width, height: chr_height, radius: chr_radius });

    //Set the chromsome fill color
    canvas.Fill({ color: this._fill.chromosome.color, opacity: this._fill.chromosome.opacity });

    //Save the position
    this._karyotype.positions.push({ x: chr_x, y: chr_y, width: chr_width, height: chr_height });

    //Check for draw the centromere
    if(typeof chr.centromere !== 'undefined')
    {
      //Centromere width
      var cent_width = this._karyotype.chromosome.width;

      //Centromere start
      var cent_start = draw.height * (chr.centromere[0] / this._karyotype.max);

      //Centromere end
      var cent_end = draw.height * (chr.centromere[1] / this._karyotype.max);

      //Centromere height
      var cent_height = Math.abs(cent_end - cent_start);

      //Centromere position x
      var cent_x = chr_x;

      //Centromere position y
      var cent_y = draw.margin.top + draw.height - chr_height + cent_start;

      //Clear the centromere region
      canvas.Clear({ x: cent_x, y: cent_y, width: cent_width, height: cent_height });

      //Centromere points
      var cent = [];

      //Add the top point
      cent.push([cent_x, cent_y]);

      //Add the middle point
      cent.push([cent_x + cent_width / 2, cent_y + cent_height / 2]);

      //Add the end point
      cent.push([cent_x, cent_y + cent_height]);

      //Add the end right
      cent.push([cent_x + cent_width, cent_y + cent_height]);

      //Add the middle right
      cent.push([cent_x + cent_width / 2, cent_y + cent_height / 2]);

      //Add the top right
      cent.push([cent_x + cent_width, cent_y]);

      //Draw the lines
      canvas.Line(cent);

      //Add the fill color
      canvas.Fill({ color: this._fill.centromere.color, opacity: this._fill.centromere.opacity });
    }

    //Get the chromosome name
    var text_txt = chr.name;

    //Get the text position x
    var text_x = chr_x + this._karyotype.chromosome.width / 2;

    //Get the text position y
    var text_y = draw.margin.top + draw.height + this._karyotype.text.margin;

    //Get the text color
    var text_color = this._karyotype.text.color;

    //Get the text size
    var text_size = this._karyotype.text.size;

    //Get the text font
    var text_font = this._karyotype.text.font;

    //Get the text align
    var text_align = this._karyotype.text.align;

    //Draw the chromosome title
    canvas.Text({ x: text_x, y: text_y, text: text_txt, color: text_color, size: text_size, font: text_font, align: text_align });

    //Get the regions for this chromosome
    var regions = (typeof this._regions.list[chr.name] === 'undefined') ? [] : this._regions.list[chr.name];

    //Read all the regions
    for(var j = 0; j < regions.length; j++)
    {
      //Get the region
      var re = regions[j];

      //Region start
      var re_start = draw.height * (re.start / this._karyotype.max);

      //Region end
      var re_end = draw.height * (re.end / this._karyotype.max);

      //Region width
      var re_width = this._karyotype.chromosome.width;

      //Region height
      var re_height = Math.max(Math.abs(re_end - re_start), 1);

      //Region position x
      var re_x = chr_x;

      //Region position y
      var re_y = draw.margin.top + draw.height - chr_height + re_start;

      //Draw the region
      canvas.Rect({ x: re_x, y: re_y, width: re_width, height: re_height });

      //Region fill
      canvas.Fill({ color: this._chromosome.regions.fill, opacity: this._chromosome.regions.opacity });
    }

    //Check the number of marks
    if(marks === 0){ continue; }

    //Get the mark rectangle position x
    var mark_x = chr_x + this._karyotype.width / 2 - this._marks.karyotypes.width / 2;

    //Get the mark rectange position y
    var mark_y = chr_y - this._marks.karyotypes.margin;

    //Get the mark rectange radius
    var mark_radius = this._marks.karyotypes.radius;

    //Get the mark width
    var mark_width = this._marks.karyotypes.width;

    //Get the mark rectangle height
    var mark_height = this._marks.karyotypes.height;

    //Draw the rectangle
    canvas.Rect({ x: mark_x, y: mark_y, width: mark_width, height: mark_height, radius: mark_radius });

    //Set the rectangle color
    canvas.Fill({ color: this._marks.fill });

    //Update the text position x
    this._marks.text.x = posx + this._karyotype.chromosome.width / 2;

    //Update the text position y
    this._marks.text.y = mark_y + this._marks.karyotypes.text;

    //Update the text
    this._marks.text.text = marks.toString();

    //Draw the text
    canvas.Text(this._marks.text);

    //Update the mark position x
    mark_x = posx + this._karyotype.width / 2;

    //Update the mark position y
    mark_y = mark_y + this._marks.karyotypes.height - this._marks.karyotypes.triangle;

    //Initialize the triangle array
    var tri = [];

    //Add the first point
    tri.push([ mark_x - this._marks.triangle, mark_y ]);

    //Add the middle point
    tri.push([ mark_x, mark_y + this._marks.triangle ]);

    //Add the first point
    tri.push([ mark_x + this._marks.triangle, mark_y ]);

    //Add the line
    canvas.Line(tri);

    //Add the fill color
    canvas.Fill(this._marks.fill);
  }

  //Reset the karyotypes hover
  this._karyotype.hover.index = -1;

  //Set loading as false
  this.loading(false);

  //Add the foot info
  //this.foot(this._foot.default);
};

//Get the chromosome
jviz.modules.ideogram.prototype.karyotypeOver = function(x, y)
{
  //Get the actual draw
  var draw = this._karyotype.draw;

  //Check for click on the margin left
  if(x < draw.margin.left + 0 * this._karyotype.margin){ return -1; }

  //Check for click on the margin right
  if(draw.margin.left + draw.width - 0 * this._karyotype.margin < x){return -1; }

  //Check for click on the margin top
  if(y < draw.margin.top){ return -1; }

  //Check for click on the margin bottom
  if(draw.margin.top + draw.height < y){ return -1; }

  //Read all the chromosomes positions
  for(var i = 0; i < this._karyotype.positions.length; i++)
  {
    //Get the position
    var pos = this._karyotype.positions[i];

    //Check the left position x
    if(x < pos.x){ return -1; }

    //Check the right position x
    if(pos.x + pos.width < x){ continue; }

    //Return the chromosome index
    return i;
  }

  //Default, return -1
  return -1;
};

//Clicked down on a chromosome
jviz.modules.ideogram.prototype.karyotypeDown = function(x, y)
{
  //Get the chromosome index
  var index = this.karyotypeOver(x, y);

  //Check for undefined chromosome
  if(index === -1){ return; }

  //Get the chromosome info
  var chr = this._genome.chromosomes[index];

  //Emit the event
  var result = this._events.emit('click:chromosome', chr.name, index);

  //Check for undefined result
  if(result === false){ return; }

  //Open this chromosome
  this.chromosome(index);
};

//Draw the karyotypes hover
jviz.modules.ideogram.prototype.karyotypeMove = function(x, y)
{
  //Get the hover chromosome
  var index = this.karyotypeOver(x, y);

  //Check the index
  if(index === this._karyotype.hover.index){ return; }

  //Update the index
  this._karyotype.hover.index = index;

  //Get the canvas
  var canvas = this._canvas.el.layer(this._karyotype.hover.layer);

  //Clear the layer
  this.karyotypeClear(this._karyotype.hover.layer);

  //Check for no chromosome
  if(index === -1)
  {
    //Reset the foot content
    //this.foot(this._foot.default);

    //Remove the pointer cursor
    jviz.cursor.remove('pointer');

    //Exit
    return;
  }

  //Get the chromosome position
  var chr = this._karyotype.positions[index];

  //Calculate the hover position x
  var rect_x = chr.x - this._karyotype.hover.margin.left;

  //Calculate the hover position y
  var rect_y = chr.y - this._karyotype.hover.margin.top;

  //Calculate the hover width
  var rect_width = chr.width + this._karyotype.hover.margin.left + this._karyotype.hover.margin.right;

  //Calculate the hover height
  var rect_height = chr.height + this._karyotype.hover.margin.top + this._karyotype.hover.margin.bottom;

  //Get the hover radius
  var rect_radius = this._karyotype.hover.radius;

  //Draw
  canvas.Rect({ x: rect_x, y: rect_y, width: rect_width, height: rect_height, radius: rect_radius });

  //Set the fill color
  canvas.Fill({ color: this._karyotype.hover.color, opacity: this._karyotype.hover.opacity });

  //Get the chromosome name
  var chr_name = this._genome.chromosomes[index].name;

  //Get the regions on chromosome
  var chr_regions = (typeof this._regions.list[chr_name] !== 'undefined') ? this._regions.list[chr_name].length : 0;

  //Update the foot content
  //this.foot(this._foot.chromosome.replace('{chromosome}', chr_name).replace('{regions}', chr_regions));

  //Add the pointer cursor
  jviz.cursor.set('pointer');
};

//Preview mouse leave
jviz.modules.ideogram.prototype.karyotypeLeave = function()
{
  //Update the index
  this._karyotype.hover.index = -1;

  //Clear the hover layer
  this.karyotypeClear(this._karyotype.hover.layer);
};

//Draw an empty karyotype
jviz.modules.ideogram.prototype.karyotypeEmpty = function()
{
  //Clear the karyotype view
  this.karyotypeClear(this._karyotype.draw.layer);

  //Exit
  return this;
};

//Clear the karyotype
jviz.modules.ideogram.prototype.karyotypeClear = function(id)
{
  //Get the draw zone
  var draw = this._karyotype.draw;

  //Get the layer
  var canvas = this._canvas.el.layer(id);

  //Clear a rectangle
  canvas.Clear({ x: 0, y: draw.top, width: draw.real_width, height: draw.real_height });

  //Continue
  return this;
};
<commit_msg>js/karyotype.js: clear the hover layer<commit_after>//Draw the karyotype
jviz.modules.ideogram.prototype.karyotypeDraw = function()
{
  //Show loading
  this.loading(true);

  //Clear the chromosomes zone
  this.karyotypeClear(this._karyotype.chromosome.layer);

  //Clear the hover regions
  this.karyotypeClear(this._karyotype.hover.layer);

  //Get the canvas draw zone
  var draw = this._karyotype.draw;

  //Calculate the margin
  this._karyotype.margin = (draw.width - this._genome.length * this._karyotype.chromosome.width) / (this._genome.length - 1);

  //Get the middle layer
  var canvas = this._canvas.el.layer(this._karyotype.chromosome.layer);

  //Reset the karyotypes positions
  this._karyotype.positions = [];

  //Draw all the karyotypes
  for(var i = 0; i < this._genome.chromosomes.length; i++)
  {
    //Get the chromosome
    var chr = this._genome.chromosomes[i];

    //Get the mark for this chromosome
    //var marks = this.GetMarks(ch.id).length;
    var marks = 0;

    //Get the chromosome width
    var chr_width = this._karyotype.chromosome.width;

    //Get the chromosome height
    var chr_height = draw.height * (chr.length / this._karyotype.max);

    //Get the chromosome position x
    var chr_x = draw.margin.left + (i + 0) * this._karyotype.margin + i * this._karyotype.chromosome.width;

    //Get the chromosome position y
    var chr_y = draw.margin.top + draw.height - chr_height;

    //Get the chromosome radius
    var chr_radius = this._karyotype.chromosome.radius;

    //Draw the chromosome
    canvas.Rect({ x: chr_x, y: chr_y, width: chr_width, height: chr_height, radius: chr_radius });

    //Set the chromsome fill color
    canvas.Fill({ color: this._fill.chromosome.color, opacity: this._fill.chromosome.opacity });

    //Save the position
    this._karyotype.positions.push({ x: chr_x, y: chr_y, width: chr_width, height: chr_height });

    //Check for draw the centromere
    if(typeof chr.centromere !== 'undefined')
    {
      //Centromere width
      var cent_width = this._karyotype.chromosome.width;

      //Centromere start
      var cent_start = draw.height * (chr.centromere[0] / this._karyotype.max);

      //Centromere end
      var cent_end = draw.height * (chr.centromere[1] / this._karyotype.max);

      //Centromere height
      var cent_height = Math.abs(cent_end - cent_start);

      //Centromere position x
      var cent_x = chr_x;

      //Centromere position y
      var cent_y = draw.margin.top + draw.height - chr_height + cent_start;

      //Clear the centromere region
      canvas.Clear({ x: cent_x, y: cent_y, width: cent_width, height: cent_height });

      //Centromere points
      var cent = [];

      //Add the top point
      cent.push([cent_x, cent_y]);

      //Add the middle point
      cent.push([cent_x + cent_width / 2, cent_y + cent_height / 2]);

      //Add the end point
      cent.push([cent_x, cent_y + cent_height]);

      //Add the end right
      cent.push([cent_x + cent_width, cent_y + cent_height]);

      //Add the middle right
      cent.push([cent_x + cent_width / 2, cent_y + cent_height / 2]);

      //Add the top right
      cent.push([cent_x + cent_width, cent_y]);

      //Draw the lines
      canvas.Line(cent);

      //Add the fill color
      canvas.Fill({ color: this._fill.centromere.color, opacity: this._fill.centromere.opacity });
    }

    //Get the chromosome name
    var text_txt = chr.name;

    //Get the text position x
    var text_x = chr_x + this._karyotype.chromosome.width / 2;

    //Get the text position y
    var text_y = draw.margin.top + draw.height + this._karyotype.text.margin;

    //Get the text color
    var text_color = this._karyotype.text.color;

    //Get the text size
    var text_size = this._karyotype.text.size;

    //Get the text font
    var text_font = this._karyotype.text.font;

    //Get the text align
    var text_align = this._karyotype.text.align;

    //Draw the chromosome title
    canvas.Text({ x: text_x, y: text_y, text: text_txt, color: text_color, size: text_size, font: text_font, align: text_align });

    //Get the regions for this chromosome
    var regions = (typeof this._regions.list[chr.name] === 'undefined') ? [] : this._regions.list[chr.name];

    //Read all the regions
    for(var j = 0; j < regions.length; j++)
    {
      //Get the region
      var re = regions[j];

      //Region start
      var re_start = draw.height * (re.start / this._karyotype.max);

      //Region end
      var re_end = draw.height * (re.end / this._karyotype.max);

      //Region width
      var re_width = this._karyotype.chromosome.width;

      //Region height
      var re_height = Math.max(Math.abs(re_end - re_start), 1);

      //Region position x
      var re_x = chr_x;

      //Region position y
      var re_y = draw.margin.top + draw.height - chr_height + re_start;

      //Draw the region
      canvas.Rect({ x: re_x, y: re_y, width: re_width, height: re_height });

      //Region fill
      canvas.Fill({ color: this._chromosome.regions.fill, opacity: this._chromosome.regions.opacity });
    }

    //Check the number of marks
    if(marks === 0){ continue; }

    //Get the mark rectangle position x
    var mark_x = chr_x + this._karyotype.width / 2 - this._marks.karyotypes.width / 2;

    //Get the mark rectange position y
    var mark_y = chr_y - this._marks.karyotypes.margin;

    //Get the mark rectange radius
    var mark_radius = this._marks.karyotypes.radius;

    //Get the mark width
    var mark_width = this._marks.karyotypes.width;

    //Get the mark rectangle height
    var mark_height = this._marks.karyotypes.height;

    //Draw the rectangle
    canvas.Rect({ x: mark_x, y: mark_y, width: mark_width, height: mark_height, radius: mark_radius });

    //Set the rectangle color
    canvas.Fill({ color: this._marks.fill });

    //Update the text position x
    this._marks.text.x = posx + this._karyotype.chromosome.width / 2;

    //Update the text position y
    this._marks.text.y = mark_y + this._marks.karyotypes.text;

    //Update the text
    this._marks.text.text = marks.toString();

    //Draw the text
    canvas.Text(this._marks.text);

    //Update the mark position x
    mark_x = posx + this._karyotype.width / 2;

    //Update the mark position y
    mark_y = mark_y + this._marks.karyotypes.height - this._marks.karyotypes.triangle;

    //Initialize the triangle array
    var tri = [];

    //Add the first point
    tri.push([ mark_x - this._marks.triangle, mark_y ]);

    //Add the middle point
    tri.push([ mark_x, mark_y + this._marks.triangle ]);

    //Add the first point
    tri.push([ mark_x + this._marks.triangle, mark_y ]);

    //Add the line
    canvas.Line(tri);

    //Add the fill color
    canvas.Fill(this._marks.fill);
  }

  //Reset the karyotypes hover
  this._karyotype.hover.index = -1;

  //Set loading as false
  this.loading(false);

  //Add the foot info
  //this.foot(this._foot.default);
};

//Get the chromosome
jviz.modules.ideogram.prototype.karyotypeOver = function(x, y)
{
  //Get the actual draw
  var draw = this._karyotype.draw;

  //Check for click on the margin left
  if(x < draw.margin.left + 0 * this._karyotype.margin){ return -1; }

  //Check for click on the margin right
  if(draw.margin.left + draw.width - 0 * this._karyotype.margin < x){return -1; }

  //Check for click on the margin top
  if(y < draw.margin.top){ return -1; }

  //Check for click on the margin bottom
  if(draw.margin.top + draw.height < y){ return -1; }

  //Read all the chromosomes positions
  for(var i = 0; i < this._karyotype.positions.length; i++)
  {
    //Get the position
    var pos = this._karyotype.positions[i];

    //Check the left position x
    if(x < pos.x){ return -1; }

    //Check the right position x
    if(pos.x + pos.width < x){ continue; }

    //Return the chromosome index
    return i;
  }

  //Default, return -1
  return -1;
};

//Clicked down on a chromosome
jviz.modules.ideogram.prototype.karyotypeDown = function(x, y)
{
  //Get the chromosome index
  var index = this.karyotypeOver(x, y);

  //Check for undefined chromosome
  if(index === -1){ return; }

  //Get the chromosome info
  var chr = this._genome.chromosomes[index];

  //Emit the event
  var result = this._events.emit('click:chromosome', chr.name, index);

  //Check for undefined result
  if(result === false){ return; }

  //Open this chromosome
  this.chromosome(index);
};

//Draw the karyotypes hover
jviz.modules.ideogram.prototype.karyotypeMove = function(x, y)
{
  //Get the hover chromosome
  var index = this.karyotypeOver(x, y);

  //Check the index
  if(index === this._karyotype.hover.index){ return; }

  //Update the index
  this._karyotype.hover.index = index;

  //Get the canvas
  var canvas = this._canvas.el.layer(this._karyotype.hover.layer);

  //Clear the layer
  this.karyotypeClear(this._karyotype.hover.layer);

  //Check for no chromosome
  if(index === -1)
  {
    //Reset the foot content
    //this.foot(this._foot.default);

    //Remove the pointer cursor
    jviz.cursor.remove('pointer');

    //Exit
    return;
  }

  //Get the chromosome position
  var chr = this._karyotype.positions[index];

  //Calculate the hover position x
  var rect_x = chr.x - this._karyotype.hover.margin.left;

  //Calculate the hover position y
  var rect_y = chr.y - this._karyotype.hover.margin.top;

  //Calculate the hover width
  var rect_width = chr.width + this._karyotype.hover.margin.left + this._karyotype.hover.margin.right;

  //Calculate the hover height
  var rect_height = chr.height + this._karyotype.hover.margin.top + this._karyotype.hover.margin.bottom;

  //Get the hover radius
  var rect_radius = this._karyotype.hover.radius;

  //Draw
  canvas.Rect({ x: rect_x, y: rect_y, width: rect_width, height: rect_height, radius: rect_radius });

  //Set the fill color
  canvas.Fill({ color: this._karyotype.hover.color, opacity: this._karyotype.hover.opacity });

  //Get the chromosome name
  var chr_name = this._genome.chromosomes[index].name;

  //Get the regions on chromosome
  var chr_regions = (typeof this._regions.list[chr_name] !== 'undefined') ? this._regions.list[chr_name].length : 0;

  //Update the foot content
  //this.foot(this._foot.chromosome.replace('{chromosome}', chr_name).replace('{regions}', chr_regions));

  //Add the pointer cursor
  jviz.cursor.set('pointer');
};

//Preview mouse leave
jviz.modules.ideogram.prototype.karyotypeLeave = function()
{
  //Update the index
  this._karyotype.hover.index = -1;

  //Clear the hover layer
  this.karyotypeClear(this._karyotype.hover.layer);
};

//Draw an empty karyotype
jviz.modules.ideogram.prototype.karyotypeEmpty = function()
{
  //Clear the karyotype view
  this.karyotypeClear(this._karyotype.chromosome.layer);

  //Exit
  return this;
};

//Clear the karyotype
jviz.modules.ideogram.prototype.karyotypeClear = function(id)
{
  //Get the draw zone
  var draw = this._karyotype.draw;

  //Get the layer
  var canvas = this._canvas.el.layer(id);

  //Clear a rectangle
  canvas.Clear({ x: 0, y: draw.top, width: draw.real_width, height: draw.real_height });

  //Continue
  return this;
};
<|endoftext|>


<commit_before>var LargeLots = LargeLots || {};
var LargeLots = {

  map: null,
  map_centroid: [41.8781136, -87.66677856445312],
  defaultZoom: 11,
  lastClickedLayer: null,
  geojson: null,
  marker: null,
  locationScope: 'Chicago',
  boundaryCartocss: '#large_lot_boundary{polygon-fill: #ffffbf;polygon-opacity: 0.1;line-color: #FFF;line-width: 3;line-opacity: 1;}',
  parcelsCartocss: $('#chicago-lots-styles').html().trim(),
  boundingBox: {
    'bottom': 42.023134979999995,
    'top': 41.644286009999995,
    'right': -87.52366115999999,
    'left': -87.94010087999999
  },

  initialize: function() {

      if (!LargeLots.map) {
        LargeLots.map = L.map('map', {
          center: LargeLots.map_centroid,
          zoom: LargeLots.defaultZoom,
          scrollWheelZoom: false
        });
      }
      // render a map!
      L.Icon.Default.imagePath = '/images/'

      LargeLots.streets = L.tileLayer('https://{s}.tiles.mapbox.com/v3/datamade.hn83a654/{z}/{x}/{y}.png', {
        attribution: 'Terms & Feedback',
        detectRetina: true
      });

      LargeLots.satellite = L.tileLayer('https://{s}.tiles.mapbox.com/v3/datamade.k92mcmc8/{z}/{x}/{y}.png', {
        attribution: 'Terms & Feedback',
        detectRetina: true
      });

      LargeLots.buildings = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap contributors',
        detectRetina: true
      });

      LargeLots.baseMaps = {"Streets": LargeLots.streets, "Building addresses": LargeLots.buildings, "Satellite": LargeLots.satellite};
      LargeLots.streets.addTo(LargeLots.map);

      LargeLots.info = L.control({position: 'bottomright'});

      LargeLots.info.onAdd = function (map) {
          this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
          this.update();
          return this._div;
      };

      // method that we will use to update the control based on feature properties passed
      LargeLots.info.update = function (props) {
        var date_formatted = '';
        if (props) {
          var info = "
" + LargeLots.formatAddress(props) + "
";
          info += "
PIN: " + props.pin14 + "
";
          info += "Zoned: " + props.zoning_classification + "
";
          info += "Sq Ft: " + props.sq_ft + "
";

          this._div.innerHTML  = info;
        }
      };

      LargeLots.info.clear = function(){
          this._div.innerHTML = '';
      }

      LargeLots.info.addTo(LargeLots.map);

      var fields = "pin14,zoning_classification,ward,street_name,dir,street_number,type,sq_ft"
      var cartocss = $('#chicago-lots-styles').html().trim();
      var layerOpts = {
          user_name: 'datamade',
          type: 'cartodb',
          sublayers: [{
                  sql: "SELECT * FROM chicago_land_inventory",
                  cartocss: LargeLots.parcelsCartocss,
                  interactivity: fields
              },
              {
                  sql: 'select * from chicago_city_boundary',
                  cartocss: LargeLots.boundaryCartocss
              }]
      }
      cartodb.createLayer(LargeLots.map, layerOpts)
        .addTo(LargeLots.map)
        .done(function(layer) {

            // after layer is loaded, add the layer toggle control
            L.control.layers(LargeLots.baseMaps, {"City-owned parcels": layer}, { collapsed: false, autoZIndex: true }).addTo(LargeLots.map);

            var sublayer = layer.getSubLayer(0)
            sublayer.setInteraction(true);
            sublayer.on('featureOver', function(e, latlng, pos, data, subLayerIndex) {
              $('#map div').css('cursor','pointer');
              LargeLots.info.update(data);
            });
            sublayer.on('featureOut', function(e, latlng, pos, data, subLayerIndex) {
              $('#map div').css('cursor','inherit');
              LargeLots.info.clear();
            });
            sublayer.on('featureClick', function(e, pos, latlng, data){
                LargeLots.getOneParcel(data['pin14']);
            });
            window.setTimeout(function(){
                if($.address.parameter('pin')){
                    LargeLots.getOneParcel($.address.parameter('pin'))
                }
            }, 1000)
        }).error(function(e) {
        //console.log('ERROR')
        //console.log(e)
      });

      var legend = L.control({position: 'bottomleft'});
      legend.onAdd = function (map) {

           var div = L.DomUtil.create('div', 'info legend')

           div.innerHTML = '\

Zoning
\
            Residential
\
            Commercial
\
            Industrial
\
            Other';
           return div;
       };

       legend.addTo(LargeLots.map);

      $("#search_address").val(LargeLots.convertToPlainString($.address.parameter('address')));
      LargeLots.addressSearch();
  },

  checkZone: function (ZONING_CLA, value) {
    if (ZONING_CLA.indexOf(value) != -1)
      return true;
    else
      return false;
  },

  formatAddress: function (prop) {
    return prop.street_number + " " + prop.dir + " " + prop.street_name + " " + prop.type;
  },

  getOneParcel: function(pin14){
      if (LargeLots.lastClickedLayer){
        LargeLots.map.removeLayer(LargeLots.lastClickedLayer);
      }
      var sql = new cartodb.SQL({user: 'datamade', format: 'geojson'});
      sql.execute('select * from chicago_land_inventory where pin14 = {{pin14}}', {pin14:pin14})
        .done(function(data){
            var shape = data.features[0];
            LargeLots.lastClickedLayer = L.geoJson(shape);
            LargeLots.lastClickedLayer.addTo(LargeLots.map);
            LargeLots.lastClickedLayer.setStyle({weight: 2, fillOpacity: 0, color: '#000'});
            LargeLots.map.setView(LargeLots.lastClickedLayer.getBounds().getCenter(), 17);
            LargeLots.selectParcel(shape.properties);
        });
  },

  selectParcel: function (props){
      var address = LargeLots.formatAddress(props);
      var zoning = LargeLots.simplifyZoning(props.zoning_classification);
      var info = "
Selected lot:
\

\

Address	" + address + "
\

PIN	" + props.pin14 + "
\

 	Tax and deed history »
\

Zoned	" + zoning + "
\

Sq ft	" + LargeLots.addCommas(props.sq_ft) + "
\

";
      $.address.parameter('pin', props.pin14)
      $('#lot-info').html(info);
  },

  simplifyZoning: function(zone_class){
    if (zone_class.substring(0, 'PMD'.length) === 'PMD') {
      return "PMD";
    }

    if (zone_class.substring(0, 'PD'.length) === 'PD') {
      return "PD";
    }

    return zone_class;
  },

  addressSearch: function (e) {
    if (e) e.preventDefault();
    var searchRadius = $("#search_address").val();
    if (searchRadius != '') {

      var raw_address = $("#search_address").val().toLowerCase();
      raw_address = raw_address.replace(" n ", " north ");
      raw_address = raw_address.replace(" s ", " south ");
      raw_address = raw_address.replace(" e ", " east ");
      raw_address = raw_address.replace(" w ", " west ");

      if(LargeLots.locationScope && LargeLots.locationScope.length){
        var checkaddress = raw_address.toLowerCase();
        var checkcity = LargeLots.locationScope.split(",")[0].toLowerCase();
        if(checkaddress.indexOf(checkcity) == -1){
          raw_address += ", " + LargeLots.locationScope;
        }
      }

      $.address.parameter('address', encodeURIComponent(raw_address));

      var s = document.createElement("script");
      s.type = "text/javascript";
      s.src = "http://nominatim.openstreetmap.org/search/" + encodeURIComponent(raw_address) + "?format=json&bounded=1&viewbox=" + LargeLots.boundingBox['left'] + "," + LargeLots.boundingBox['top'] + "," + LargeLots.boundingBox['right'] + "," + LargeLots.boundingBox['bottom'] + "&json_callback=LargeLots.returnAddress";
      document.body.appendChild(s);
      //&bounded=1&viewbox=" + LargeLots.boundingBox['left'] + "," + LargeLots.boundingBox['top'] + "," + LargeLots.boundingBox['right'] + "," + LargeLots.boundingBox['bottom'] + "
    }
  },

  returnAddress: function (response){

    if(!response.length){
      $('#modalGeocode').modal('show');
      return;
    }

    var first = response[0];

    LargeLots.map.setView([first.lat, first.lon], 17);

    if (LargeLots.marker)
      LargeLots.map.removeLayer( LargeLots.marker );

    var defaultIcon = L.icon({
        iconUrl: 'images/marker-icon.png',
        shadowUrl: 'images/marker-shadow.png',
        shadowAnchor: [0, 0]
      });
    LargeLots.marker = L.marker([first.lat, first.lon]).addTo(LargeLots.map);
  },

  addCommas: function(nStr) {
      nStr += '';
      x = nStr.split('.');
      x1 = x[0];
      x2 = x.length > 1 ? '.' + x[1] : '';
      var rgx = /(\d+)(\d{3})/;
      while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
      }
      return x1 + x2;
    },

  //converts a slug or query string in to readable text
  convertToPlainString: function (text) {
    if (text == undefined) return '';
    return decodeURIComponent(text);
  }

}
<commit_msg>pulling city boundary from unified chicago_community_areas cartodb table<commit_after>var LargeLots = LargeLots || {};
var LargeLots = {

  map: null,
  map_centroid: [41.8781136, -87.66677856445312],
  defaultZoom: 11,
  lastClickedLayer: null,
  geojson: null,
  marker: null,
  locationScope: 'Chicago',
  boundaryCartocss: '#large_lot_boundary{polygon-fill: #ffffbf;polygon-opacity: 0.1;line-color: #FFF;line-width: 3;line-opacity: 1;}',
  parcelsCartocss: $('#chicago-lots-styles').html().trim(),
  boundingBox: {
    'bottom': 42.023134979999995,
    'top': 41.644286009999995,
    'right': -87.52366115999999,
    'left': -87.94010087999999
  },

  initialize: function() {

      if (!LargeLots.map) {
        LargeLots.map = L.map('map', {
          center: LargeLots.map_centroid,
          zoom: LargeLots.defaultZoom,
          scrollWheelZoom: false
        });
      }
      // render a map!
      L.Icon.Default.imagePath = '/images/'

      LargeLots.streets = L.tileLayer('https://{s}.tiles.mapbox.com/v3/datamade.hn83a654/{z}/{x}/{y}.png', {
        attribution: 'Terms & Feedback',
        detectRetina: true
      });

      LargeLots.satellite = L.tileLayer('https://{s}.tiles.mapbox.com/v3/datamade.k92mcmc8/{z}/{x}/{y}.png', {
        attribution: 'Terms & Feedback',
        detectRetina: true
      });

      LargeLots.buildings = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap contributors',
        detectRetina: true
      });

      LargeLots.baseMaps = {"Streets": LargeLots.streets, "Building addresses": LargeLots.buildings, "Satellite": LargeLots.satellite};
      LargeLots.streets.addTo(LargeLots.map);

      LargeLots.info = L.control({position: 'bottomright'});

      LargeLots.info.onAdd = function (map) {
          this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
          this.update();
          return this._div;
      };

      // method that we will use to update the control based on feature properties passed
      LargeLots.info.update = function (props) {
        var date_formatted = '';
        if (props) {
          var info = "
" + LargeLots.formatAddress(props) + "
";
          info += "
PIN: " + props.pin14 + "
";
          info += "Zoned: " + props.zoning_classification + "
";
          info += "Sq Ft: " + props.sq_ft + "
";

          this._div.innerHTML  = info;
        }
      };

      LargeLots.info.clear = function(){
          this._div.innerHTML = '';
      }

      LargeLots.info.addTo(LargeLots.map);

      var fields = "pin14,zoning_classification,ward,street_name,dir,street_number,type,sq_ft"
      var cartocss = $('#chicago-lots-styles').html().trim();
      var layerOpts = {
          user_name: 'datamade',
          type: 'cartodb',
          sublayers: [{
                  sql: "SELECT * FROM chicago_land_inventory",
                  cartocss: LargeLots.parcelsCartocss,
                  interactivity: fields
              },
              {
                  sql: "select * from chicago_community_areas WHERE community = 'CHICAGO'",
                  cartocss: LargeLots.boundaryCartocss
              }]
      }
      cartodb.createLayer(LargeLots.map, layerOpts)
        .addTo(LargeLots.map)
        .done(function(layer) {

            // after layer is loaded, add the layer toggle control
            L.control.layers(LargeLots.baseMaps, {"City-owned parcels": layer}, { collapsed: false, autoZIndex: true }).addTo(LargeLots.map);

            var sublayer = layer.getSubLayer(0)
            sublayer.setInteraction(true);
            sublayer.on('featureOver', function(e, latlng, pos, data, subLayerIndex) {
              $('#map div').css('cursor','pointer');
              LargeLots.info.update(data);
            });
            sublayer.on('featureOut', function(e, latlng, pos, data, subLayerIndex) {
              $('#map div').css('cursor','inherit');
              LargeLots.info.clear();
            });
            sublayer.on('featureClick', function(e, pos, latlng, data){
                LargeLots.getOneParcel(data['pin14']);
            });
            window.setTimeout(function(){
                if($.address.parameter('pin')){
                    LargeLots.getOneParcel($.address.parameter('pin'))
                }
            }, 1000)
        }).error(function(e) {
        //console.log('ERROR')
        //console.log(e)
      });

      var legend = L.control({position: 'bottomleft'});
      legend.onAdd = function (map) {

           var div = L.DomUtil.create('div', 'info legend')

           div.innerHTML = '\

Zoning
\
            Residential
\
            Commercial
\
            Industrial
\
            Other';
           return div;
       };

       legend.addTo(LargeLots.map);

      $("#search_address").val(LargeLots.convertToPlainString($.address.parameter('address')));
      LargeLots.addressSearch();
  },

  checkZone: function (ZONING_CLA, value) {
    if (ZONING_CLA.indexOf(value) != -1)
      return true;
    else
      return false;
  },

  formatAddress: function (prop) {
    return prop.street_number + " " + prop.dir + " " + prop.street_name + " " + prop.type;
  },

  getOneParcel: function(pin14){
      if (LargeLots.lastClickedLayer){
        LargeLots.map.removeLayer(LargeLots.lastClickedLayer);
      }
      var sql = new cartodb.SQL({user: 'datamade', format: 'geojson'});
      sql.execute('select * from chicago_land_inventory where pin14 = {{pin14}}', {pin14:pin14})
        .done(function(data){
            var shape = data.features[0];
            LargeLots.lastClickedLayer = L.geoJson(shape);
            LargeLots.lastClickedLayer.addTo(LargeLots.map);
            LargeLots.lastClickedLayer.setStyle({weight: 2, fillOpacity: 0, color: '#000'});
            LargeLots.map.setView(LargeLots.lastClickedLayer.getBounds().getCenter(), 17);
            LargeLots.selectParcel(shape.properties);
        });
  },

  selectParcel: function (props){
      var address = LargeLots.formatAddress(props);
      var zoning = LargeLots.simplifyZoning(props.zoning_classification);
      var info = "
Selected lot:
\

\

Address	" + address + "
\

PIN	" + props.pin14 + "
\

 	Tax and deed history »
\

Zoned	" + zoning + "
\

Sq ft	" + LargeLots.addCommas(props.sq_ft) + "
\

";
      $.address.parameter('pin', props.pin14)
      $('#lot-info').html(info);
  },

  simplifyZoning: function(zone_class){
    if (zone_class.substring(0, 'PMD'.length) === 'PMD') {
      return "PMD";
    }

    if (zone_class.substring(0, 'PD'.length) === 'PD') {
      return "PD";
    }

    return zone_class;
  },

  addressSearch: function (e) {
    if (e) e.preventDefault();
    var searchRadius = $("#search_address").val();
    if (searchRadius != '') {

      var raw_address = $("#search_address").val().toLowerCase();
      raw_address = raw_address.replace(" n ", " north ");
      raw_address = raw_address.replace(" s ", " south ");
      raw_address = raw_address.replace(" e ", " east ");
      raw_address = raw_address.replace(" w ", " west ");

      if(LargeLots.locationScope && LargeLots.locationScope.length){
        var checkaddress = raw_address.toLowerCase();
        var checkcity = LargeLots.locationScope.split(",")[0].toLowerCase();
        if(checkaddress.indexOf(checkcity) == -1){
          raw_address += ", " + LargeLots.locationScope;
        }
      }

      $.address.parameter('address', encodeURIComponent(raw_address));

      var s = document.createElement("script");
      s.type = "text/javascript";
      s.src = "http://nominatim.openstreetmap.org/search/" + encodeURIComponent(raw_address) + "?format=json&bounded=1&viewbox=" + LargeLots.boundingBox['left'] + "," + LargeLots.boundingBox['top'] + "," + LargeLots.boundingBox['right'] + "," + LargeLots.boundingBox['bottom'] + "&json_callback=LargeLots.returnAddress";
      document.body.appendChild(s);
      //&bounded=1&viewbox=" + LargeLots.boundingBox['left'] + "," + LargeLots.boundingBox['top'] + "," + LargeLots.boundingBox['right'] + "," + LargeLots.boundingBox['bottom'] + "
    }
  },

  returnAddress: function (response){

    if(!response.length){
      $('#modalGeocode').modal('show');
      return;
    }

    var first = response[0];

    LargeLots.map.setView([first.lat, first.lon], 17);

    if (LargeLots.marker)
      LargeLots.map.removeLayer( LargeLots.marker );

    var defaultIcon = L.icon({
        iconUrl: 'images/marker-icon.png',
        shadowUrl: 'images/marker-shadow.png',
        shadowAnchor: [0, 0]
      });
    LargeLots.marker = L.marker([first.lat, first.lon]).addTo(LargeLots.map);
  },

  addCommas: function(nStr) {
      nStr += '';
      x = nStr.split('.');
      x1 = x[0];
      x2 = x.length > 1 ? '.' + x[1] : '';
      var rgx = /(\d+)(\d{3})/;
      while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
      }
      return x1 + x2;
    },

  //converts a slug or query string in to readable text
  convertToPlainString: function (text) {
    if (text == undefined) return '';
    return decodeURIComponent(text);
  }

}
<|endoftext|>


<commit_before>var LaterTabs = {

    tabs: [],

    init: function(){
        if (typeof localStorage.latertabs == 'undefined'){
            localStorage.latertabs = JSON.stringify(LaterTabs.tabs);
        }
        else{
            LaterTabs.tabs = JSON.parse(localStorage.latertabs);
        }
    },

    save: function(item){
        if (LaterTabs.tabs[item.url]){
            return false;
        }
        LaterTabs.tabs[item.url] = item;
        localStorage.latertabs = JSON.stringify(LaterTabs.tabs);
    },

    remove: function(url){
        if (LaterTabs.tabs[url]){
            delete LaterTabs.tabs[url];
            LaterTabs.notify('Tab removed', url);
            return true;
        }
        return false;
    },

    saveCurrent: function(callback){
        chrome.tabs.getSelected(null, function(tab){
            LaterTabs.save({ url: tab.url, title: tab.title });
            LaterTabs.notify('Tab saved', tab.url);
            if (callback){ callback(); }
        });
    },

    saveAll: function(callback){
        chrome.tabs.getAllInWindow(null, function(tabs){
            for (var i=0; i < tabs.length; i++){
                LaterTabs.save({ url: tabs[i].url, title: tabs[i].title });
            }
            LaterTabs.notify('All tabs saved', '');
            if (callback){ callback(); }
        });
    },

    restore: function(url){
        chrome.tabs.create({'url': url}, function(tab) {
            LaterTabs.notify('Tab restored', url);
        });
    },

    getSaved: function(){
        return LaterTabs.tabs;
    },

    notify: function(title, text){
        var notification = webkitNotifications.createNotification(
            '/imgs/clock.png',
            title,
            text
        );
        notification.show();
    }
};

(function(){
    LaterTabs.init();
    var tabList = LaterTabs.getSaved();

    createList(tabList);

    var saveButton = document.getElementById('save_current_tab_button');
    var saveAllButton = document.getElementById('save_all_tabs_button');
    var settingsButton = document.getElementById('settings_button');
    var deleteButtons = document.querySelector('.delete_button');

    saveButton.addEventListener('click', function(){
        LaterTabs.saveCurrent(createList);
    });

    saveAllButton.addEventListener('click', function(){
        LaterTabs.saveAll(createList);
    });

    settingsButton.addEventListener('click', function(){
        chrome.tabs.create({ url: "options.html" });
    });

    /*for (var i in deleteButtons){
        deleteButtons[i].addEventListener('click', function(){
            LaterTabs.remove();
        });
    }*/

    function createList(){
        var items = LaterTabs.tabs,
            htmlContent = '';
        for (var i in items){
            htmlContent += '

';
            htmlContent += items[i].title + '
';
            htmlContent += '';
            htmlContent += '' + items[i].url + '
';
        }
        document.getElementById('tab_list').innerHTML = htmlContent; }
})();
<commit_msg>fixed stupid array/object bug.<commit_after>var LaterTabs = {

    tabs: {},

    init: function(){
        if (typeof localStorage.latertabs == 'undefined'){
            localStorage.latertabs = JSON.stringify(LaterTabs.tabs);
        }
        else{
            LaterTabs.tabs = JSON.parse(localStorage.latertabs);
        }
    },

    save: function(item){
        if (LaterTabs.tabs[item.url]){
            return false;
        }
        LaterTabs.tabs[item.url] = item;
        localStorage.latertabs = JSON.stringify(LaterTabs.tabs);
        return true;
    },

    remove: function(url){
        if (LaterTabs.tabs[url]){
            delete LaterTabs.tabs[url];
            LaterTabs.notify('Tab removed', url);
            return true;
        }
        return false;
    },

    saveCurrent: function(callback){
        chrome.tabs.getSelected(null, function(tab){
            LaterTabs.save({ url: tab.url, title: tab.title });
            LaterTabs.notify('Tab saved', tab.url);
            if (callback){ callback(); }
        });
    },

    saveAll: function(callback){
        chrome.tabs.getAllInWindow(null, function(tabs){
            for (var i=0; i < tabs.length; i++){
                LaterTabs.save({ url: tabs[i].url, title: tabs[i].title });
            }
            LaterTabs.notify('All tabs saved', '');
            if (callback){ callback(); }
        });
    },

    restore: function(url){
        chrome.tabs.create({'url': url}, function(tab) {
            LaterTabs.notify('Tab restored', url);
        });
    },

    getSaved: function(){
        return LaterTabs.tabs;
    },

    notify: function(title, text){
        var notification = webkitNotifications.createNotification(
            '/imgs/clock.png',
            title,
            text
        );
        notification.show();
    }
};

(function(){
    LaterTabs.init();
    createList();

    var saveButton = document.getElementById('save_current_tab_button');
    var saveAllButton = document.getElementById('save_all_tabs_button');
    var settingsButton = document.getElementById('settings_button');
    var deleteButtons = document.querySelector('.delete_button');

    saveButton.addEventListener('click', function(){
        LaterTabs.saveCurrent(createList);
    });

    saveAllButton.addEventListener('click', function(){
        LaterTabs.saveAll(createList);
    });

    settingsButton.addEventListener('click', function(){
        chrome.tabs.create({ url: "options.html" });
    });

    /*for (var i in deleteButtons){
        deleteButtons[i].addEventListener('click', function(){
            LaterTabs.remove();
        });
    }*/

    function createList(){
        var items = LaterTabs.tabs,
            htmlContent = '';
        for (var i in items){
            htmlContent += '

';
            htmlContent += items[i].title + '
';
            htmlContent += '';
            htmlContent += '' + items[i].url + '
';
        }
        document.getElementById('tab_list').innerHTML = htmlContent; }
})();
<|endoftext|>