<commit_before>/**
 * Created by tdiprima.
 */
log('Hello from mugshots.js');

mugshots = function () {
    log('location: ' + location);
    var url = '';
    var hash = '';
    if (location.hash.length > 1) {
        hash = location.hash.slice(1);

        mugshots.n = getQueryVariable('n', hash);
        mugshots.m = getQueryVariable('m', hash);

        url = buildQueryString(hash);

    }
    else {
        // Default data url
        var rand = Math.random();

        var _static = config.quot + 'provenance.analysis.execution_id' + config.quot + ':' + config.quot + config.analysis_execution_id + config.quot;
        url = mugshots.findApi + "?collection=objects&limit=100&find={" + _static + ',' + config.quot + "randval" + config.quot + ":{" + config.quot + "$gte" + config.quot + ":" + rand + "}}";
        log('*** Random nuclei were selected for you. ***');

    }

    log('url: ' + url);

    mugshots.loadData(url);
};

function buildQueryString(q) {

    var caseid = getQueryVariable('caseid', q);
    var fx = getQueryVariable('fx', q);
    var xmin = getQueryVariable('xmin', q);
    var xmax = getQueryVariable('xmax', q);
    var fy = getQueryVariable('fy', q);
    var ymin = getQueryVariable('ymin', q);
    var ymax = getQueryVariable('ymax', q);

    // Remember it stops at '='
    // https://falcon.bmi.stonybrook.edu:4500/?limit
    var base = getQueryVariable('url', q);
    base = base + '=500';

    // "find1: {"randval":{"$gte":0.399},"provenance.analysis.execution_id":"luad:20160215","provenance.image.case_id":"TCGA-05-4244-01Z-00-DX1"}"
    var find = getQueryVariable('find', q);
    // remove the last '}'
    find = find.substring(0, find.length - 1);

    // Build our "find"

    var range_a = config.quot + '$and' + config.quot + ':[{'
        + config.quot + 'properties.scalar_features' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'nv' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'name' + config.quot + ':' + config.quot + fx + config.quot + ','
        + config.quot + 'value' + config.quot + ':{'
        + config.quot + '$gte' + config.quot + ':' + xmin +
        '}}}}}},{'
        + config.quot + 'properties.scalar_features' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'nv' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'name' + config.quot + ':' + config.quot + fx + config.quot + ','
        + config.quot + 'value' + config.quot + ':{'
        + config.quot + '$lte' + config.quot + ':' + xmax +
        '}}}}}}]';

    var range_b = config.quot + '$and' + config.quot + ':[{'
        + config.quot + 'properties.scalar_features' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'nv' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'name' + config.quot + ':' + config.quot + fy + config.quot + ','
        + config.quot + 'value' + config.quot + ':{'
        + config.quot + '$gte' + config.quot + ':' + ymin +
        '}}}}}},{'
        + config.quot + 'properties.scalar_features' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'nv' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'name' + config.quot + ':' + config.quot + fy + config.quot + ','
        + config.quot + 'value' + config.quot + ':{'
        + config.quot + '$lte' + config.quot + ':' + ymax +
        '}}}}}}]';

    var myUrl = base + '&find=' + find + ',' + config.quot + '$and' + config.quot + ':[{' + range_a + '},{' + range_b + '}]}';
    if (config.mongoUrl) {
        myUrl = myUrl + '&mongoUrl=' + config.mongoUrl;

    }

    return myUrl;

}

function getQueryVariable(variable, queryString) {
    var vars = queryString.split('&');
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        if (decodeURIComponent(pair[0]) == variable) {
            return decodeURIComponent(pair[1]);
        }
    }
}

mugshots.loadData = function (url) {
    /*
     $.getJSON(url)
     .done(function (data) {
     log("Got JSON Data");
     //document.write(JSON.stringify(data));
     mugshots.draw('mugshotDiv', data);

     })
     .error(function (jqXHR, textStatus, error) {
     log('jqXHR.responseText: ' + jqXHR.responseText);
     var err = textStatus + ", " + error;
     log("Request Failed: " + err);
     });
     // .fail in jQuery 1.8
     */
    $.ajax({
        url: url,
        async: true,
        dataType: 'json',
        success: function (json) {
            mugshots.draw('mugshotDiv', json);
        }
    });
};

function getRandomSubarrayPartialShuffle(arr, size) {
    var shuffled = arr.slice(0),
        i = arr.length,
        min = i - size,
        temp,
        index;
    while (i-- > min) {
        index = Math.floor((i + 1) * Math.random());
        temp = shuffled[index];
        shuffled[index] = shuffled[i];
        shuffled[i] = temp;
    }
    return shuffled.slice(min);
}

mugshots.fun = function (data, size) {
    var newData = [];

    var randomMembers = getRandomSubarrayPartialShuffle(data, size);
    log(randomMembers);

    var sameCaseId = true;
    var prevCaseId = '';
    randomMembers.forEach(function (doc) {
        if (prevCaseId != '' && prevCaseId != doc.provenance.image.case_id) {
            sameCaseId = false;
        }
        prevCaseId = doc.provenance.image.case_id;
    });

    var identifier = '';
    var slideWidth = 0;
    var slideHeight = 0;

    if (sameCaseId) {
        var url = mugshots.findApi + '?collection=' + config.imgcoll + '&limit=1&find={' + config.quot + 'caseid' + config.quot + ':' + config.quot + prevCaseId + config.quot + '}';
        $.ajax({
            url: url,
            async: false,
            dataType: 'json',
            success: function (json) {
                identifier = json[0].filename;
                slideWidth = json[0].width;
                slideHeight = json[0].height;
            }
        });

    }

    randomMembers.forEach(function (doc) {
        var url = mugshots.findApi + '?collection=' + config.imgcoll + '&limit=1&find={' + config.quot + 'caseid' + config.quot + ':' + config.quot + doc.provenance.image.case_id + config.quot + '}';

        if (!sameCaseId) {
            $.ajax({
                url: url,
                async: false,
                dataType: 'json',
                success: function (json) {
                    identifier = json[0].filename;
                    slideWidth = json[0].width;
                    slideHeight = json[0].height;
                }
            });

        }

        newData.push({
            markup: doc.bbox,
            normalized: doc.normalized,
            caseid: doc.provenance.image.case_id,
            identifier: identifier,
            slideWidth: slideWidth,
            slideHeight: slideHeight
        })
    });

    return newData;

};

mugshots.draw = function (targetDiv, data, layout) {

    if (!layout) {
        layout = {
            title: 'Nuclei Mugshots',
            rows: 3,
            columns: 4
        };
    }

    //m rows and n columns
    if (!mugshots.m) {
        mugshots.m = layout.rows;
    }
    if (!mugshots.n) {
        mugshots.n = layout.columns;
    }
    size = mugshots.m * mugshots.n;

    if (!document.getElementById(targetDiv)) {
        $('

').appendTo(document.body);
    }

    if (!data) {
        document.getElementById(targetDiv).innerHTML = 'Alright now... you need to give me some data in order to get some nuclei!';
        return false;
    }
    else {
        data = mugshots.fun(data, size);
    }

    var div = document.getElementById(targetDiv);

    var k = 0, tableRows = mugshots.m,
        tds = mugshots.n,
        fragment = document.createDocumentFragment();

    var tbl = document.createElement('table');
    fragment.appendChild(tbl);

    var ind = 0;
    for (var i = 0; i < tableRows; i++) {
        //str += '
';
        var row = document.createElement('tr');
        tbl.appendChild(row);

        for (var j = 0; j < tds; j++) {
            //log(ind + ': ' + JSON.stringify(data[ind]));

            var obj = {
                x: data[ind].markup[0],
                y: data[ind].markup[1],
                w: (data[ind].markup[2] - data[ind].markup[0]),
                h: (data[ind].markup[3] - data[ind].markup[1])
            };

            var normalized = data[ind].normalized;
            if (normalized === 'true') {
                obj.x = obj.x * data[ind].slideWidth;
                obj.y = obj.y * data[ind].slideHeight;
                obj.w = obj.w * data[ind].slideWidth;
                obj.h = obj.h * data[ind].slideHeight;
            }

            // IIIF wants whole numbers.
            obj.x = Math.round(obj.x);
            obj.y = Math.round(obj.y);
            obj.w = Math.round(obj.w);
            obj.h = Math.round(obj.h);

            // IIIF Image Request URI Syntax
            var scheme = 'http',
                server = 'quip.bmi.stonybrook.edu',
                prefix = 'fastcgi-bin/iipsrv.fcgi?iiif=',
                region = '',
                size = 'full',
                rotation = '0',
                quality = 'default',
                format = 'jpg';

            var quipUrl = config.quipUrl + '?tissueId=';

            var canvas = document.createElement('canvas');
            canvas.width = 150;
            canvas.height = 150;

            // Expand bounding box, with nucleus in center
            var w = (canvas.width / 2),
                h = (canvas.height / 2);

            var new_x = ((obj.x + (obj.w / 2)) - w),
                new_y = ((obj.y + (obj.h / 2)) - h);

            region = new_x + "," + new_y + "," + canvas.width + "," + canvas.height;

            var uri = scheme + "://" + server + "/" + prefix + data[ind].identifier + "/" + region + "/" + size + "/" + rotation + "/" + quality + "." + format;

            var link = document.createElement('a');
            link.setAttribute("href", quipUrl + data[ind].caseid + "&x=" + obj.x + "&y=" + obj.y);
            link.setAttribute("target", "_blank");
            var col = document.createElement('td');

            canvas.setAttribute('id', 'canvas' + j);
            link.appendChild(canvas);
            col.appendChild(link);
            var context = canvas.getContext("2d");

            var imgSrc = uri;

            context.clearRect(0, 0, canvas.width, canvas.height);
            drawBackground(canvas, context, imgSrc, obj);
            row.appendChild(col);

            ind = ind + 1;
        }
    }

    // Write the table to the html div.
    div.appendChild(fragment);

    // Clean hash.
    location.hash = '';

};

function drawBackground(canvas, context, imgSrc, obj) {

    var imagePaper = new Image();

    imagePaper.onload = function () {
        context.drawImage(imagePaper, 0, 0);
        drawLines(canvas, context, obj);
    };
    imagePaper.src = imgSrc;
}

function drawLines(canvas, context, obj) {
    var x = (canvas.width / 2),
        y = (canvas.height / 2);

    var new_x = (x - (obj.w / 2)),
        new_y = (y - (obj.h / 2));

    // yellow rectangle
    context.beginPath();
    context.lineWidth = "2";
    context.strokeStyle = "yellow";
    context.rect(new_x, new_y, obj.w, obj.h);
    context.stroke();
}

// ini
$(document).ready(function () {
    mugshots.findApi = config.findAPI + ':' + config.port + '/';
    mugshots();
});
<commit_msg>Update main.js<commit_after>/**
 * Created by tdiprima.
 */
log('Hello from mugshots.js');

mugshots = function () {
    log('location: ' + location);
    var url = '';
    var hash = '';
    if (location.hash.length > 1) {
        hash = location.hash.slice(1);

        mugshots.n = getQueryVariable('n', hash);
        mugshots.m = getQueryVariable('m', hash);

        url = buildQueryString(hash);

    }
    else {
        // Default data url
        var rand = Math.random();

        var _static = config.quot + 'provenance.analysis.execution_id' + config.quot + ':' + config.quot + config.analysis_execution_id + config.quot;
        url = mugshots.findApi + "?collection=objects&limit=12&find={" + _static + ',' + config.quot + "randval" + config.quot + ":{" + config.quot + "$gte" + config.quot + ":" + rand + "}}";
        log('*** Random nuclei were selected for you. ***');

    }

    log('url: ' + url);

    mugshots.loadData(url);
};

function buildQueryString(q) {

    var caseid = getQueryVariable('caseid', q);
    var fx = getQueryVariable('fx', q);
    var xmin = getQueryVariable('xmin', q);
    var xmax = getQueryVariable('xmax', q);
    var fy = getQueryVariable('fy', q);
    var ymin = getQueryVariable('ymin', q);
    var ymax = getQueryVariable('ymax', q);

    // Remember it stops at '='
    // https://falcon.bmi.stonybrook.edu:4500/?limit
    var base = getQueryVariable('url', q);
    base = base + '=500';

    // "find1: {"randval":{"$gte":0.399},"provenance.analysis.execution_id":"luad:20160215","provenance.image.case_id":"TCGA-05-4244-01Z-00-DX1"}"
    var find = getQueryVariable('find', q);
    // remove the last '}'
    find = find.substring(0, find.length - 1);

    // Build our "find"

    var range_a = config.quot + '$and' + config.quot + ':[{'
        + config.quot + 'properties.scalar_features' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'nv' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'name' + config.quot + ':' + config.quot + fx + config.quot + ','
        + config.quot + 'value' + config.quot + ':{'
        + config.quot + '$gte' + config.quot + ':' + xmin +
        '}}}}}},{'
        + config.quot + 'properties.scalar_features' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'nv' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'name' + config.quot + ':' + config.quot + fx + config.quot + ','
        + config.quot + 'value' + config.quot + ':{'
        + config.quot + '$lte' + config.quot + ':' + xmax +
        '}}}}}}]';

    var range_b = config.quot + '$and' + config.quot + ':[{'
        + config.quot + 'properties.scalar_features' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'nv' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'name' + config.quot + ':' + config.quot + fy + config.quot + ','
        + config.quot + 'value' + config.quot + ':{'
        + config.quot + '$gte' + config.quot + ':' + ymin +
        '}}}}}},{'
        + config.quot + 'properties.scalar_features' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'nv' + config.quot + ':{'
        + config.quot + '$elemMatch' + config.quot + ':{'
        + config.quot + 'name' + config.quot + ':' + config.quot + fy + config.quot + ','
        + config.quot + 'value' + config.quot + ':{'
        + config.quot + '$lte' + config.quot + ':' + ymax +
        '}}}}}}]';

    var myUrl = base + '&find=' + find + ',' + config.quot + '$and' + config.quot + ':[{' + range_a + '},{' + range_b + '}]}';
    if (config.mongoUrl) {
        myUrl = myUrl + '&mongoUrl=' + config.mongoUrl;

    }

    return myUrl;

}

function getQueryVariable(variable, queryString) {
    var vars = queryString.split('&');
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        if (decodeURIComponent(pair[0]) == variable) {
            return decodeURIComponent(pair[1]);
        }
    }
}

mugshots.loadData = function (url) {
    /*
     $.getJSON(url)
     .done(function (data) {
     log("Got JSON Data");
     //document.write(JSON.stringify(data));
     mugshots.draw('mugshotDiv', data);

     })
     .error(function (jqXHR, textStatus, error) {
     log('jqXHR.responseText: ' + jqXHR.responseText);
     var err = textStatus + ", " + error;
     log("Request Failed: " + err);
     });
     // .fail in jQuery 1.8
     */
    $.ajax({
        url: url,
        async: true,
        dataType: 'json',
        success: function (json) {
            mugshots.draw('mugshotDiv', json);
        }
    });
};

function getRandomSubarrayPartialShuffle(arr, size) {
    var shuffled = arr.slice(0),
        i = arr.length,
        min = i - size,
        temp,
        index;
    while (i-- > min) {
        index = Math.floor((i + 1) * Math.random());
        temp = shuffled[index];
        shuffled[index] = shuffled[i];
        shuffled[i] = temp;
    }
    return shuffled.slice(min);
}

mugshots.fun = function (data, size) {
    var newData = [];

    var randomMembers = getRandomSubarrayPartialShuffle(data, size);
    log(randomMembers);

    var sameCaseId = true;
    var prevCaseId = '';
    randomMembers.forEach(function (doc) {
        if (prevCaseId != '' && prevCaseId != doc.provenance.image.case_id) {
            sameCaseId = false;
        }
        prevCaseId = doc.provenance.image.case_id;
    });

    var identifier = '';
    var slideWidth = 0;
    var slideHeight = 0;

    if (sameCaseId) {
        var url = mugshots.findApi + '?collection=' + config.imgcoll + '&limit=1&find={' + config.quot + 'caseid' + config.quot + ':' + config.quot + prevCaseId + config.quot + '}';
        $.ajax({
            url: url,
            async: false,
            dataType: 'json',
            success: function (json) {
                identifier = json[0].filename;
                slideWidth = json[0].width;
                slideHeight = json[0].height;
            }
        });

    }

    randomMembers.forEach(function (doc) {
        var url = mugshots.findApi + '?collection=' + config.imgcoll + '&limit=1&find={' + config.quot + 'caseid' + config.quot + ':' + config.quot + doc.provenance.image.case_id + config.quot + '}';

        if (!sameCaseId) {
            $.ajax({
                url: url,
                async: false,
                dataType: 'json',
                success: function (json) {
                    identifier = json[0].filename;
                    slideWidth = json[0].width;
                    slideHeight = json[0].height;
                }
            });

        }

        newData.push({
            markup: doc.bbox,
            normalized: doc.normalized,
            caseid: doc.provenance.image.case_id,
            identifier: identifier,
            slideWidth: slideWidth,
            slideHeight: slideHeight
        })
    });

    return newData;

};

mugshots.draw = function (targetDiv, data, layout) {

    if (!layout) {
        layout = {
            title: 'Nuclei Mugshots',
            rows: 3,
            columns: 4
        };
    }

    //m rows and n columns
    if (!mugshots.m) {
        mugshots.m = layout.rows;
    }
    if (!mugshots.n) {
        mugshots.n = layout.columns;
    }
    size = mugshots.m * mugshots.n;

    if (!document.getElementById(targetDiv)) {
        $('

').appendTo(document.body);
    }

    if (!data) {
        document.getElementById(targetDiv).innerHTML = 'Alright now... you need to give me some data in order to get some nuclei!';
        return false;
    }
    else {
        data = mugshots.fun(data, size);
    }

    var div = document.getElementById(targetDiv);

    var k = 0, tableRows = mugshots.m,
        tds = mugshots.n,
        fragment = document.createDocumentFragment();

    var tbl = document.createElement('table');
    fragment.appendChild(tbl);

    var ind = 0;
    for (var i = 0; i < tableRows; i++) {
        //str += '
';
        var row = document.createElement('tr');
        tbl.appendChild(row);

        for (var j = 0; j < tds; j++) {
            //log(ind + ': ' + JSON.stringify(data[ind]));

            var obj = {
                x: data[ind].markup[0],
                y: data[ind].markup[1],
                w: (data[ind].markup[2] - data[ind].markup[0]),
                h: (data[ind].markup[3] - data[ind].markup[1])
            };

            var normalized = data[ind].normalized;
            if (normalized === 'true') {
                obj.x = obj.x * data[ind].slideWidth;
                obj.y = obj.y * data[ind].slideHeight;
                obj.w = obj.w * data[ind].slideWidth;
                obj.h = obj.h * data[ind].slideHeight;
            }

            // IIIF wants whole numbers.
            obj.x = Math.round(obj.x);
            obj.y = Math.round(obj.y);
            obj.w = Math.round(obj.w);
            obj.h = Math.round(obj.h);

            // IIIF Image Request URI Syntax
            var scheme = 'http',
                server = 'quip.bmi.stonybrook.edu',
                prefix = 'fastcgi-bin/iipsrv.fcgi?iiif=',
                region = '',
                size = 'full',
                rotation = '0',
                quality = 'default',
                format = 'jpg';

            var quipUrl = config.quipUrl + '?tissueId=';

            var canvas = document.createElement('canvas');
            canvas.width = 150;
            canvas.height = 150;

            // Expand bounding box, with nucleus in center
            var w = (canvas.width / 2),
                h = (canvas.height / 2);

            var new_x = ((obj.x + (obj.w / 2)) - w),
                new_y = ((obj.y + (obj.h / 2)) - h);

            region = new_x + "," + new_y + "," + canvas.width + "," + canvas.height;

            var uri = scheme + "://" + server + "/" + prefix + data[ind].identifier + "/" + region + "/" + size + "/" + rotation + "/" + quality + "." + format;

            var link = document.createElement('a');
            link.setAttribute("href", quipUrl + data[ind].caseid + "&x=" + obj.x + "&y=" + obj.y);
            link.setAttribute("target", "_blank");
            var col = document.createElement('td');

            canvas.setAttribute('id', 'canvas' + j);
            link.appendChild(canvas);
            col.appendChild(link);
            var context = canvas.getContext("2d");

            var imgSrc = uri;

            context.clearRect(0, 0, canvas.width, canvas.height);
            drawBackground(canvas, context, imgSrc, obj);
            row.appendChild(col);

            ind = ind + 1;
        }
    }

    // Write the table to the html div.
    div.appendChild(fragment);

    // Clean hash.
    location.hash = '';

};

function drawBackground(canvas, context, imgSrc, obj) {

    var imagePaper = new Image();

    imagePaper.onload = function () {
        context.drawImage(imagePaper, 0, 0);
        drawLines(canvas, context, obj);
    };
    imagePaper.src = imgSrc;
}

function drawLines(canvas, context, obj) {
    var x = (canvas.width / 2),
        y = (canvas.height / 2);

    var new_x = (x - (obj.w / 2)),
        new_y = (y - (obj.h / 2));

    // yellow rectangle
    context.beginPath();
    context.lineWidth = "2";
    context.strokeStyle = "yellow";
    context.rect(new_x, new_y, obj.w, obj.h);
    context.stroke();
}

// ini
$(document).ready(function () {
    mugshots.findApi = config.findAPI + ':' + config.port + '/';
    mugshots();
});
<|endoftext|>


<commit_before>(function (){
"use strict";
/*jslint browser: true*/
/*global $, L*/

L.Control.Permalink.include({
    initialize_legend: function() {
        /* Methods starting with initialize_ are automatically called
         * when the Permalink control is initialized
         */
        this.on('update', this._set_legend, this);
        this.on('add', this._onadd_legend, this);
    },

    _onadd_legend: function() {
        this._map.on('layeradd', this._update_legend, this);
        this._map.on('layerremove', this._update_legend, this);
        this._map.on('legendupdate', this._update_legend, this);
        this._update_legend();
    },

    _update_legend: function() {
        if (!this.options.layers) return;
        var legends = this.options.layers.legendNames();
        if (legends && legends !== '') {
            this._update({legends: legends});
        }
    },

    _set_legend: function(e) {
        //console.info("Set legend", e);
        var p = e.params;
        if (!this.options.layers || !p.overlays) return;
        if (!p.legends) return;
        this.options.layers.chooseLegends(p.overlays, p.legends);
    }
});

L.Control.CategorizedLayers.include({
    /*jshint unused: true*/
    chooseLegends: function(overlaynames_str, legends) {
    /*jshint unused: false*/
        var layer, obj, i, j,
            layerGroup,
            values,
            enabled;
        //var overlaynames = decodeURIComponent(overlaynames_str).split(',');
        var legendoverlays = decodeURIComponent(legends).split(';');
        var legendhash = {};
        for (i in legendoverlays) {
            var tmp = legendoverlays[i].split(',');
            for (j in tmp) {
                var tmp2 = tmp[j].split('(');
                //var tmp2 = tmp[j].split('.');
                var layerComponent = tmp2[0].split('.');
                values = tmp2[1].replace(')', '').split('_');
                enabled = values[2];
                values = values.slice(0, 2);
                layerGroup = layerComponent[0];
                layer = layerComponent[1];
                var param = layerComponent[2];

                // For some browsers, `attr` is undefined; for others,
                // `attr` is false.  Check for both.
                var attr = $(legendhash).attr(layerGroup);
                if (typeof attr === typeof undefined || attr === false) {
                    legendhash[layerGroup] = {};
                }
                attr = $(legendhash[layerGroup]).attr(layer);
                if (typeof attr === typeof undefined || attr === false) {
                    legendhash[layerGroup][layer] = {};
                }
                legendhash[layerGroup][layer][param] = {};
                legendhash[layerGroup][layer][param].values = values;
                legendhash[layerGroup][layer][param].enabled = enabled;
            }
        }
        //var idx=0;
        for (i in this._overlays) {
            if (!this._overlays.hasOwnProperty(i))
                    continue;
                layerGroup = this._overlays[i];
                for (j in layerGroup) {
                    if (!layerGroup.hasOwnProperty(j))
                        continue;
                    obj = layerGroup[j];
                    if (obj._overlay) {
                        // visible if specified
                        //var name = obj._category_en + '.' + obj._name_en;
                        //var visible = (overlaynames[idx] == name);
                        if (legendhash.hasOwnProperty(obj._category_en)) {
                            if (legendhash[obj._category_en].hasOwnProperty(obj._name_en)) {
                                var mysettings = legendhash[obj._category_en][obj._name_en];
                                for (var k in mysettings) {
                                    enabled = (mysettings[k].enabled === "true");
                                    values =  $.map(mysettings[k].values, parseFloat);
                                    var mylegends = obj._legendControl._legendContainer;
                                    for (var ii in mylegends) {
                                        if (mylegends[ii].options.layer === obj) {
                                            for (var iii in mylegends[ii]._parameterContainer) {
                                                var myparam = mylegends[ii]._parameterContainer[iii];
                                                if (myparam.options.shortname == k) {
                                                     myparam.options.enabled = enabled;
                                                     myparam.options.sliderOptions.values = values;
                                                }
                                            }
                                        }
                                    }
                                    obj._legendControl._redrawLegend();
                                }
                            }
                        }
                    }
                }
        }
        this._update();
    },

    legendNames: function() {
        var names = '';
        for (var i in this._overlays) {
            if (!this._overlays.hasOwnProperty(i))
                continue;
            var layerGroup = this._overlays[i];
            for (var j in layerGroup) {
                if (!layerGroup.hasOwnProperty(j))
                    continue;
                var obj = layerGroup[j];
                if (!obj._overlay) continue;
                if (obj._overlay) {
                    if (this._map.hasLayer(obj)) {
                        if (obj._legendControl) {
                            var legendControl = obj._legendControl;
                            if (legendControl._legendType == 'impact') {
                                var legendLayer = obj._legendControl.
                                    _legendContainer[obj._legendId];
                                var settings = legendLayer.getUrlSettings();
                                for (var k in settings) {
                                    settings[k] = obj._category_en + '.' + settings[k];
                                }
                                if (names.length > 0) {
                                    names += '%3B';
                                }
                                names += settings.join('%2C');
                            }
                        }
                    }
                }
            }
        }
        return names;
    }
});
})();
<commit_msg>fixed layer not present bug<commit_after>(function (){
"use strict";
/*jslint browser: true*/
/*global $, L*/

L.Control.Permalink.include({
    initialize_legend: function() {
        /* Methods starting with initialize_ are automatically called
         * when the Permalink control is initialized
         */
        this.on('update', this._set_legend, this);
        this.on('add', this._onadd_legend, this);
    },

    _onadd_legend: function() {
        this._map.on('layeradd', this._update_legend, this);
        this._map.on('layerremove', this._update_legend, this);
        this._map.on('legendupdate', this._update_legend, this);
        this._update_legend();
    },

    _update_legend: function() {
        if (!this.options.layers) return;
        var legends = this.options.layers.legendNames();
        if (legends && legends !== '') {
            this._update({legends: legends});
        }
    },

    _set_legend: function(e) {
        //console.info("Set legend", e);
        var p = e.params;
        if (!this.options.layers || !p.overlays) return;
        if (!p.legends) return;
        this.options.layers.chooseLegends(p.overlays, p.legends);
    }
});

L.Control.CategorizedLayers.include({
    /*jshint unused: true*/
    chooseLegends: function(overlaynames_str, legends) {
    /*jshint unused: false*/
        var layer, obj, i, j,
            layerGroup,
            values,
            enabled;
        //var overlaynames = decodeURIComponent(overlaynames_str).split(',');
        var legendoverlays = decodeURIComponent(legends).split(';');
        var legendhash = {};
        for (i in legendoverlays) {
            var tmp = legendoverlays[i].split(',');
            for (j in tmp) {
                var tmp2 = tmp[j].split('(');
                //var tmp2 = tmp[j].split('.');
                var layerComponent = tmp2[0].split('.');
                values = tmp2[1].replace(')', '').split('_');
                enabled = values[2];
                values = values.slice(0, 2);
                layerGroup = layerComponent[0];
                layer = layerComponent[1];
                var param = layerComponent[2];

                // For some browsers, `attr` is undefined; for others,
                // `attr` is false.  Check for both.
                var attr = $(legendhash).attr(layerGroup);
                if (typeof attr === typeof undefined || attr === false) {
                    legendhash[layerGroup] = {};
                }
                attr = $(legendhash[layerGroup]).attr(layer);
                if (typeof attr === typeof undefined || attr === false) {
                    legendhash[layerGroup][layer] = {};
                }
                legendhash[layerGroup][layer][param] = {};
                legendhash[layerGroup][layer][param].values = values;
                legendhash[layerGroup][layer][param].enabled = enabled;
            }
        }
        //var idx=0;
        for (i in this._overlays) {
            if (!this._overlays.hasOwnProperty(i))
                    continue;
                layerGroup = this._overlays[i];
                for (j in layerGroup) {
                    if (!layerGroup.hasOwnProperty(j))
                        continue;
                    obj = layerGroup[j];
                    if (obj._overlay) {
                        // visible if specified
                        //var name = obj._category_en + '.' + obj._name_en;
                        //var visible = (overlaynames[idx] == name);
                        if (legendhash.hasOwnProperty(obj._category_en)) {
                            if (legendhash[obj._category_en].hasOwnProperty(obj._name_en)) {
                                var mysettings = legendhash[obj._category_en][obj._name_en];
                                for (var k in mysettings) {
                                    enabled = (mysettings[k].enabled === "true");
                                    values =  $.map(mysettings[k].values, parseFloat);
                                    // Check if layer has been put on map; otherwise put it on
                                    if (obj._map === null) {
                                        this._map.addLayer(obj);
                                    }
                                    var mylegends = obj._legendControl._legendContainer;
                                    for (var ii in mylegends) {
                                        if (mylegends[ii].options.layer === obj) {
                                            for (var iii in mylegends[ii]._parameterContainer) {
                                                var myparam = mylegends[ii]._parameterContainer[iii];
                                                if (myparam.options.shortname == k) {
                                                     myparam.options.enabled = enabled;
                                                     myparam.options.sliderOptions.values = values;
                                                }
                                            }
                                        }
                                    }
                                    obj._legendControl._redrawLegend();
                                }
                            }
                        }
                    }
                }
        }
        this._update();
    },

    legendNames: function() {
        var names = '';
        for (var i in this._overlays) {
            if (!this._overlays.hasOwnProperty(i))
                continue;
            var layerGroup = this._overlays[i];
            for (var j in layerGroup) {
                if (!layerGroup.hasOwnProperty(j))
                    continue;
                var obj = layerGroup[j];
                if (!obj._overlay) continue;
                if (obj._overlay) {
                    if (this._map.hasLayer(obj)) {
                        if (obj._legendControl) {
                            var legendControl = obj._legendControl;
                            if (legendControl._legendType == 'impact') {
                                var legendLayer = obj._legendControl.
                                    _legendContainer[obj._legendId];
                                var settings = legendLayer.getUrlSettings();
                                for (var k in settings) {
                                    settings[k] = obj._category_en + '.' + settings[k];
                                }
                                if (names.length > 0) {
                                    names += '%3B';
                                }
                                names += settings.join('%2C');
                            }
                        }
                    }
                }
            }
        }
        return names;
    }
});
})();
<|endoftext|>


<commit_before>/**
 * @file LinearProgress component
 * @author chao(chao.zhang@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Theme from '../Theme';
import Percent from '../_Percent';

class LinearProgress extends Component {

    static WordStyle = {
        FRONT: 'linear-progress-one',
        MIDDLE: 'linear-progress-two',
        FOLLOW: 'linear-progress-three'
    };
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.getProgressWidth = ::this.getProgressWidth;

    }

    getProgressWidth() {
        if (this.refs.progress) {
            return parseInt(this.refs.progress.offsetWidth) / 2;
        }
    }

    render() {

        const {className, highlightWidth, style, word, wordStyle, theme, animation} = this.props,

            progressClassName = classNames('linear-progress', {
                [wordStyle]: wordStyle,
                [`theme-${theme}`]: theme,
                [className]: className
            }),

            highlightClassName = classNames('linear-progress-highlight', {
                'linear-progress-animate': animation
            }),
            highlightStyle = {
                width: highlightWidth
            },
            percentStyle = {
                marginLeft: this.getProgressWidth()
            };

        return (

                {
                    word ?
                        (
                            wordStyle === LinearProgress.WordStyle.FOLLOW ?
                                <Percent endNum={parseInt(highlightWidth)}
                                         move={true}/>
                                :
                                <Percent endNum={parseInt(highlightWidth)}/>
                        )
                        :
                        null
                }

                        {
                            wordStyle === LinearProgress.WordStyle.MIDDLE ?
                                <Percent className="linear-progress-word"
                                         style={percentStyle}
                                         endNum={parseInt(highlightWidth)}/>
                                :
                                null
                        }

        );
    }
};

LinearProgress.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The progress theme.Can be primary,highlight,success,warning,error.
     */
    theme: PropTypes.oneOf(Object.keys(Theme).map(key => Theme[key])),

    /**
     * The highlight width of linearProgress.
     */
    highlightWidth: PropTypes.string,

    /**
     * If true,there will have a text description.
     */
    word: PropTypes.bool,

    /**
     * The percent text location.Desirable values include front,middle,follow.
     */
    wordStyle: PropTypes.oneOf(Object.keys(LinearProgress.WordStyle).map((key) => LinearProgress.WordStyle[key])),

    /**
     * If true, the linearProgress will have animation.
     */
    animation: PropTypes.bool

};

LinearProgress.defaultProps = {

    className: '',
    style: {
        width: '200px',
        height: '2px'
    },

    highlightWidth: '50%',
    word: false,
    wordStyle: LinearProgress.WordStyle.FRONT,
    animation: false

};

export default LinearProgress;<commit_msg>update LinearProgress<commit_after>/**
 * @file LinearProgress component
 * @author chao(chao.zhang@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Theme from '../Theme';
import Percent from '../_Percent';

import Util from '../_vendors/Util';

class LinearProgress extends Component {

    static WordStyle = {
        FRONT: 'linear-progress-one',
        MIDDLE: 'linear-progress-two',
        FOLLOW: 'linear-progress-three'
    };
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.getProgressWidth = ::this.getProgressWidth;

    }

    getProgressWidth() {
        if (this.refs.progress) {
            return parseInt(this.refs.progress.offsetWidth) / 2;
        }
    }

    render() {

        const {className, highlightWidth, style, word, wordStyle, theme, animation} = this.props,

            progressClassName = classNames('linear-progress', {
                [wordStyle]: wordStyle,
                [`theme-${theme}`]: theme,
                [className]: className
            }),

            highlightClassName = classNames('linear-progress-highlight', {
                'linear-progress-animate': animation
            }),
            highlightStyle = {
                width: highlightWidth
            },
            percentStyle = {
                marginLeft: this.getProgressWidth()
            };

        return (

                {
                    word ?
                        (
                            wordStyle === LinearProgress.WordStyle.FOLLOW ?
                                <Percent endNum={parseInt(highlightWidth)}
                                         move={true}/>
                                :
                                <Percent endNum={parseInt(highlightWidth)}/>
                        )
                        :
                        null
                }

                        {
                            wordStyle === LinearProgress.WordStyle.MIDDLE ?
                                <Percent className="linear-progress-word"
                                         style={percentStyle}
                                         endNum={parseInt(highlightWidth)}/>
                                :
                                null
                        }

        );
    }
};

LinearProgress.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * The progress theme.Can be primary,highlight,success,warning,error.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The highlight width of linearProgress.
     */
    highlightWidth: PropTypes.string,

    /**
     * If true,there will have a text description.
     */
    word: PropTypes.bool,

    /**
     * The percent text location.Desirable values include front,middle,follow.
     */
    wordStyle: PropTypes.oneOf(Object.keys(LinearProgress.WordStyle).map(key => LinearProgress.WordStyle[key])),

    /**
     * If true, the linearProgress will have animation.
     */
    animation: PropTypes.bool

};

LinearProgress.defaultProps = {

    className: '',
    style: {
        width: '200px',
        height: '2px'
    },

    highlightWidth: '50%',
    word: false,
    wordStyle: LinearProgress.WordStyle.FRONT,
    animation: false

};

export default LinearProgress;<|endoftext|>


<commit_before>import arrayContentsMatch from 'utils/arrayContentsMatch';
import isEqual from 'utils/isEqual';

export default function Ractive$updateModel ( keypath, cascade ) {
	var values;

	if ( typeof keypath !== 'string' ) {
		keypath = '';
		cascade = true;
	}

	consolidateChangedValues( this, keypath, values = {}, cascade );
	return this.set( values );
}

function consolidateChangedValues ( ractive, keypath, values, cascade ) {
	var bindings, childDeps, i, binding, oldValue, newValue, checkboxGroups = [];

	bindings = ractive._twowayBindings[ keypath ];

	if ( bindings && ( i = bindings.length ) ) {
		while ( i-- ) {
			binding = bindings[i];

			// special case - radio name bindings
			if ( binding.radioName && !binding.element.node.checked ) {
				continue;
			}

			// special case - checkbox name bindings come in groups, so
			// we want to get the value once at most
			if ( binding.checkboxName ) {
				if ( !checkboxGroups[ binding.keypath ] && !binding.changed() ) {
					checkboxGroups.push( binding.keypath );
					checkboxGroups[ binding.keypath ] = binding;
				}

				continue;
			}

			oldValue = binding.attribute.value;
			newValue = binding.getValue();

			if ( arrayContentsMatch( oldValue, newValue ) ) {
				continue;
			}

			if ( !isEqual( oldValue, newValue ) ) {
				values[ keypath ] = newValue;
			}
		}
	}

	// Handle groups of `<input type='checkbox' name='{{foo}}' ...>`
	if ( checkboxGroups.length ) {
		checkboxGroups.forEach( keypath => {
			var binding, oldValue, newValue;

			binding = checkboxGroups[ keypath ]; // one to represent the entire group
			oldValue = binding.attribute.value;
			newValue = binding.getValue();

			if ( !arrayContentsMatch( oldValue, newValue ) ) {
				values[ keypath ] = newValue;
			}
		});
	}

	if ( !cascade ) {
		return;
	}

	// cascade
	childDeps = ractive.viewmodel.depsMap[ 'default' ][ keypath ];

	if ( childDeps ) {
		i = childDeps.length;
		while ( i-- ) {
			consolidateChangedValues( ractive, childDeps[i], values, cascade );
		}
	}
}
<commit_msg>fix two-way binding across component boundaries<commit_after>import arrayContentsMatch from 'utils/arrayContentsMatch';
import startsWith from 'virtualdom/items/shared/utils/startsWith'; // TODO move this helper
import isEqual from 'utils/isEqual';

export default function Ractive$updateModel ( keypath, cascade ) {
	var values, key, bindings;

	if ( typeof keypath === 'string' && !cascade ) {
		bindings = this._twowayBindings[ keypath ];
	} else {
		bindings = [];

		for ( key in this._twowayBindings ) {
			if ( !keypath || startsWith( key, keypath ) ) {
				bindings.push.apply( bindings, this._twowayBindings[ key ]);
			}
		}
	}

	values = consolidate( this, bindings );
	return this.set( values );
}

function consolidate ( ractive, bindings ) {
	var values = {}, checkboxGroups = [];

	bindings.forEach( b => {
		var oldValue, newValue;

		// special case - radio name bindings
		if ( b.radioName && !b.element.node.checked ) {
			return;
		}

		// special case - checkbox name bindings come in groups, so
		// we want to get the value once at most
		if ( b.checkboxName ) {
			if ( !checkboxGroups[ b.keypath ] && !b.changed() ) {
				checkboxGroups.push( b.keypath );
				checkboxGroups[ b.keypath ] = b;
			}

			return;
		}

		oldValue = b.attribute.value;
		newValue = b.getValue();

		if ( arrayContentsMatch( oldValue, newValue ) ) {
			return;
		}

		if ( !isEqual( oldValue, newValue ) ) {
			values[ b.keypath ] = newValue;
		}
	});

	// Handle groups of `<input type='checkbox' name='{{foo}}' ...>`
	if ( checkboxGroups.length ) {
		checkboxGroups.forEach( keypath => {
			var binding, oldValue, newValue;

			binding = checkboxGroups[ keypath ]; // one to represent the entire group
			oldValue = binding.attribute.value;
			newValue = binding.getValue();

			if ( !arrayContentsMatch( oldValue, newValue ) ) {
				values[ keypath ] = newValue;
			}
		});
	}

	return values;
}
<|endoftext|>


<commit_before>var RcmLoginBoxJs = function(loginMgr, sessionId) {

    var me = this;

    me.loginMgr = loginMgr;
    me.sessionId = sessionId;

    me.init = function() {

        me.loginMgr.setSuccessCallback(me.rcmLoginBoxSuccessFunction);
        me.loginMgr.setMissingCallback(me.rcmLoginBoxMissingItemsCallback);
        me.loginMgr.setInvalidCallback(me.rcmLoginBoxInvalidLoginCallback);
        me.loginMgr.setSystemFailureCallback(me.rcmLoginBoxSystemFailureCallback);
        me.loginMgr.setNoAuthFailureCallback(me.rcmLoginBoxSystemFailureCallback);

        $(function(){
            $("#rcmLoginBoxLoginForm").submit(function(event){
                me.submitBind();
                event.preventDefault();
            });

            $("#rcmLoginBoxLoginSubmit").click(function(event){
                me.submitBind();
                event.preventDefault();
            });

            if (typeof(rcm) === 'object') {
                var urlParms = rcm.getUrlParams();

                if (urlParms.rcmLoginError) {
                    me.loginMgr.processError(urlParms.rcmLoginError);
                }
            }
        });
    };

    me.submitBind = function() {
        me.hideSubmitButton();
        me.loginMgr.doLogin($("#rcmLoginBoxUserName").val(), $("#rcmLoginBoxPassword").val());
    };

    me.hideSubmitButton = function() {
        $("#rcmLoginBoxLoginSubmit").hide();
        $("#rcmLoginBoxProcessingMsgContainer").show();
    };

    me.showSubmitButton = function() {
        $("#rcmLoginBoxLoginSubmit").show();
        $("#rcmLoginBoxProcessingMsgContainer").hide();
    }

    me.rcmLoginBoxSuccessFunction = function(data) {

        var redirectUrl = '';

        if (typeof(rcm) === 'object') {
            var urlParms = rcm.getUrlParams();

            if (urlParms.redirect) {
                redirectUrl = urlParms.redirect
            }
        }

        if (redirectUrl == '') {
            redirectUrl ='https://portal.local.reliv.com';
        }

        var redirectWithSession = rcm.updateURLParameter(redirectUrl,'sess_id', me.sessionId);

        window.location.replace(redirectWithSession);
    };

    me.rcmLoginBoxInvalidLoginCallback = function(data) {
        $("#rcmLoginBoxInvalidError").show();
        me.showSubmitButton();
    };

    me.rcmLoginBoxMissingItemsCallback = function(data) {
        $("#rcmLoginBoxMissingError").show();
        me.showSubmitButton();
    };

    me.rcmLoginBoxSystemFailureCallback = function(data) {
        $("#rcmLoginBoxSystemError").show();
        me.showSubmitButton();
    };

    me.rcmLoginBoxNotAuthCallback = function(data) {
        $("#rcmLoginBoxSystemError").show();
        me.showSubmitButton();
    };
};

<commit_msg>Fixed duplicate errors showing on login page.<commit_after>var RcmLoginBoxJs = function(loginMgr, sessionId) {

    var me = this;

    me.loginMgr = loginMgr;
    me.sessionId = sessionId;

    me.init = function() {

        me.loginMgr.setSuccessCallback(me.rcmLoginBoxSuccessFunction);
        me.loginMgr.setMissingCallback(me.rcmLoginBoxMissingItemsCallback);
        me.loginMgr.setInvalidCallback(me.rcmLoginBoxInvalidLoginCallback);
        me.loginMgr.setSystemFailureCallback(me.rcmLoginBoxSystemFailureCallback);
        me.loginMgr.setNoAuthFailureCallback(me.rcmLoginBoxSystemFailureCallback);

        $(function(){
            $("#rcmLoginBoxLoginForm").submit(function(event){
                me.submitBind();
                event.preventDefault();
            });

            $("#rcmLoginBoxLoginSubmit").click(function(event){
                me.submitBind();
                event.preventDefault();
            });

            if (typeof(rcm) === 'object') {
                var urlParms = rcm.getUrlParams();

                if (urlParms.rcmLoginError) {
                    me.loginMgr.processError(urlParms.rcmLoginError);
                }
            }
        });
    };

    me.submitBind = function() {
        me.hideSubmitButton();
        me.loginMgr.doLogin($("#rcmLoginBoxUserName").val(), $("#rcmLoginBoxPassword").val());
    };

    me.hideSubmitButton = function() {
        $("#rcmLoginBoxLoginSubmit").hide();
        $("#rcmLoginBoxProcessingMsgContainer").show();
    };

    me.showSubmitButton = function() {
        $("#rcmLoginBoxLoginSubmit").show();
        $("#rcmLoginBoxProcessingMsgContainer").hide();
    };

    me.hideErrors = function() {
        $("#rcmLoginBoxInvalidError").hide();
        $("#rcmLoginBoxMissingError").hide();
        $("#rcmLoginBoxSystemError").hide();
        $("#rcmLoginBoxSystemError").hide();
    };

    me.rcmLoginBoxSuccessFunction = function(data) {

        var redirectUrl = '';

        if (typeof(rcm) === 'object') {
            var urlParms = rcm.getUrlParams();

            if (urlParms.redirect) {
                redirectUrl = urlParms.redirect
            }
        }

        if (redirectUrl == '') {
            redirectUrl ='https://portal.local.reliv.com';
        }

        var redirectWithSession = rcm.updateURLParameter(redirectUrl,'sess_id', me.sessionId);

        window.location.replace(redirectWithSession);
    };

    me.rcmLoginBoxInvalidLoginCallback = function(data) {
        me.hideErrors();
        $("#rcmLoginBoxInvalidError").show();
        me.showSubmitButton();
    };

    me.rcmLoginBoxMissingItemsCallback = function(data) {
        me.hideErrors();
        $("#rcmLoginBoxMissingError").show();
        me.showSubmitButton();
    };

    me.rcmLoginBoxSystemFailureCallback = function(data) {
        me.hideErrors();
        $("#rcmLoginBoxSystemError").show();
        me.showSubmitButton();
    };

    me.rcmLoginBoxNotAuthCallback = function(data) {
        me.hideErrors();
        $("#rcmLoginBoxSystemError").show();
        me.showSubmitButton();
    };
};

<|endoftext|>


<commit_before>App.view.items_Bar = Ext.Array.push(App.view.items_Bar || [], [
    '-'
    ,{
        iconCls: 'appbar-user-online'
       ,height: 28
       ,tooltip: '', text: ''// filled by controller after auth
       ,menu:{
            xtype: 'menu',
            plain: true,
            items:{
                xtype: 'buttongroup',
                title: l10n.userStatusMenu,
                itemId: 'userstatus',
                columns: 1,
                items:(
    function mk_status_list(){
    var s = new Array(5) ,l = [ 'online', 'away', 'busy', 'offline' ]
        for(var i = 0; i < 4; i++)  s[i] = {
            text: l10n.userStatuses[l[i]]
           ,itemId: l[i]
           ,width: '100%'
           //,icon: 'css/user-' +  l[i] + '.png'
           ,iconCls: 'appbar-user-' + l[i]
           ,handler: onItemClick
        }
        s[i] = { text: l10n.um.users ,scale: 'large' ,iconCls: 'userman'
            ,handler: function open_userman_from_bar(){
                var tb = Ext.getCmp('wm').items.getByKey('Userman')
                if(tb){
                    //debugger
                    //tb.toggle(true)
                    tb.onWMToggle()
                } else {
                    Ext.create('App.view.Userman', { renderTo: Ext.getCmp('desk').getEl() })
                }
                this.up('button').hideMenu()
            }
        }
        return s

        function onItemClick(item){
            item.up('button').setIconCls(item.iconCls).hideMenu()
            Ext.globalEvents.fireEventArgs('userStatus', [ item ])
            //TODO: set state && sync state with backend
        }
    }
                )()// buttongroup.items
            }// menu.items
        }// menu
    }// tbutton
    ,{
        iconCls: 'appbar-shutdown'
       ,height: 28 ,width: 28
       ,tooltip: l10n.shutdown
       ,handler: function(){
            Ext.globalEvents.fireEventArgs('logout')
        }
    }
])
<commit_msg>um.view.items_Bar: fix `view.Userman` launching<commit_after>App.view.items_Bar = Ext.Array.push(App.view.items_Bar || [], [
    '-'
    ,{
        iconCls: 'appbar-user-online'
       ,height: 28
       ,tooltip: '', text: ''// filled by controller after auth
       ,menu:{
            xtype: 'menu',
            plain: true,
            items:{
                xtype: 'buttongroup',
                title: l10n.userStatusMenu,
                itemId: 'userstatus',
                columns: 1,
                items:(
    function mk_status_list(){
    var s = new Array(5) ,l = [ 'online', 'away', 'busy', 'offline' ]
        for(var i = 0; i < 4; i++)  s[i] = {
            text: l10n.userStatuses[l[i]]
           ,itemId: l[i]
           ,width: '100%'
           //,icon: 'css/user-' +  l[i] + '.png'
           ,iconCls: 'appbar-user-' + l[i]
           ,handler: onItemClick
        }
        s[i] = { text: l10n.um.users ,scale: 'large' ,iconCls: 'userman'
           ,handler:
            function open_userman_from_bar(){
            var tb = Ext.getCmp('wm').items.getByKey('Userman')
               ,btn = this.up('button')

                if(tb){
                    tb.toggle(true)
                } else {
                    App.create('view.Userman', btn,{
                        renderTo: Ext.getCmp('desk').getEl()
                    })
                }
                btn.hideMenu()
            }
        }
        return s

        function onItemClick(item){
            item.up('button').setIconCls(item.iconCls).hideMenu()
            Ext.globalEvents.fireEventArgs('userStatus', [ item ])
            //TODO: set state && sync state with backend
        }
    }
                )()// buttongroup.items
            }// menu.items
        }// menu
    }// tbutton
    ,{
        iconCls: 'appbar-shutdown'
       ,height: 28 ,width: 28
       ,tooltip: l10n.shutdown
       ,handler: function(){
            Ext.globalEvents.fireEventArgs('logout')
        }
    }
])
<|endoftext|>


<commit_before>'use strict'
var remixLib = require('remix-lib')
var SourceMappingDecoder = remixLib.SourceMappingDecoder
var AstWalker = remixLib.AstWalker
var EventManager = remixLib.EventManager

/*
  trigger contextChanged(nodes)
*/
class ContextualListener {
  constructor (api, events) {
    this.event = new EventManager()
    this._api = api
    this._index = {
      Declarations: {},
      FlatReferences: {}
    }
    this._activeHighlights = []

    events.compiler.register('compilationFinished', (success, data, source) => {
      this._stopHighlighting()
      this._index = {
        Declarations: {},
        FlatReferences: {}
      }
      if (success) {
        this._buildIndex(data, source)
      }
    })

    events.editor.register('contentChanged', () => { this._stopHighlighting() })

    this.sourceMappingDecoder = new SourceMappingDecoder()
    this.astWalker = new AstWalker()
    setInterval(() => {
      this._highlightItems(api.getCursorPosition(), api.getCompilationResult(), api.getCurrentFile())
    }, 1000)
  }

  getActiveHighlights () {
    return [...this._activeHighlights]
  }

  declarationOf (node) {
    if (node.attributes && node.attributes.referencedDeclaration) {
      return this._index['FlatReferences'][node.attributes.referencedDeclaration]
    }
    return null
  }

  referencesOf (node) {
    return this._index['Declarations'][node.id]
  }

  _highlightItems (cursorPosition, compilationResult, file) {
    if (this.currentPosition === cursorPosition) return
    if (this.currentFile !== file) {
      this.currentFile = file
      this.currentPosition = cursorPosition
      return
    }
    this._stopHighlighting()
    this.currentPosition = cursorPosition
    this.currentFile = file
    if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) {
      var nodes = this.sourceMappingDecoder.nodesAtPosition(null, cursorPosition, compilationResult.data.sources[file])
      this.nodes = nodes
      if (nodes && nodes.length && nodes[nodes.length - 1]) {
        this._highlightExpressions(nodes[nodes.length - 1], compilationResult)
      }
      this.event.trigger('contextChanged', [nodes])
    }
  }

  _buildIndex (compilationResult, source) {
    if (compilationResult && compilationResult.sources) {
      var self = this
      var callback = {}
      callback['*'] = function (node) {
        if (node && node.attributes && node.attributes.referencedDeclaration) {
          if (!self._index['Declarations'][node.attributes.referencedDeclaration]) {
            self._index['Declarations'][node.attributes.referencedDeclaration] = []
          }
          self._index['Declarations'][node.attributes.referencedDeclaration].push(node)
        }
        self._index['FlatReferences'][node.id] = node
        return true
      }
      for (var s in compilationResult.sources) {
        this.astWalker.walk(compilationResult.sources[s].legacyAST, callback)
      }
    }
  }

  _highlight (node, compilationResult) {
    if (!node) return
    var position = this.sourceMappingDecoder.decode(node.src)
    var eventId = this._api.highlight(position, node)
    if (eventId) {
      this._activeHighlights.push({ eventId, position, fileTarget: this._api.getSourceName(position.file), nodeId: node.id })
    }
  }

  _highlightExpressions (node, compilationResult) {
    var self = this
    function highlights (id) {
      if (self._index['Declarations'] && self._index['Declarations'][id]) {
        var refs = self._index['Declarations'][id]
        for (var ref in refs) {
          var node = refs[ref]
          self._highlight(node, compilationResult)
        }
      }
    }
    if (node.attributes && node.attributes.referencedDeclaration) {
      highlights(node.attributes.referencedDeclaration)
      var current = this._index['FlatReferences'][node.attributes.referencedDeclaration]
      this._highlight(current, compilationResult)
    } else {
      highlights(node.id)
      this._highlight(node, compilationResult)
    }
    this.results = compilationResult
  }

  _stopHighlighting () {
    for (var event in this._activeHighlights) {
      this._api.stopHighlighting(this._activeHighlights[event])
    }
    this._activeHighlights = []
  }

  // GET GAS ESTIMATION
  _getGasEstimation (contract) {
    this.contract = this.results.data.contracts[this.results.source.target][contract.attributes.name]
    this.estimationObj = this.contract.evm.gasEstimates
    this.creationCost = this.estimationObj.creation.totalCost
    this.codeDepositCost = this.estimationObj.creation.codeDepositCost
  }

  gasEstimation (node) {
    this._getContract(node)
    var executionCost
    var codeDepositCost
    if (node.name === 'FunctionDefinition') {
      if (!node.attributes.isConstructor) {
        var fnName = node.attributes.name
        var fn = fnName + this._getInputParams(node)
        if (node.attributes.visibility === 'public') {
          executionCost = this.estimationObj.external[fn]
        } else if (node.attributes.visibility === 'internal') {
          executionCost = this.estimationObj.internal[fn]
        }
      } else {
        executionCost = this.creationCost
        codeDepositCost = this.codeDepositCost
      }
    } else {
      executionCost = '-'
    }
    return {executionCost, codeDepositCost}
  }

  _getContract (node) {
    for (var i in this.nodes) {
      if (this.nodes[i].id === node.attributes.scope) {
        var contract = this._getGasEstimation(this.nodes[i])
        break
      }
    }
    return contract
  }

  _getInputParams (node) {
    var params
    var list = []
    for (var i in node.children) {
      if (node.children[i].name === 'ParameterList') {
        list.push(node.children[i])
        break
      }
    }
    debugger
    for (var j in list) {
      if (list[j].children.length) {
        var children = list[j].children
        for (var k in children) {
          if (children[k].name === 'VariableDeclaration') {
            params = children[k].attributes.type
            break
          }
        }
      } else {
        params = ''
      }
    }
    return '(' + params + ')'
  }
}

module.exports = ContextualListener
<commit_msg>Refactor _getInputParams<commit_after>'use strict'
var remixLib = require('remix-lib')
var SourceMappingDecoder = remixLib.SourceMappingDecoder
var AstWalker = remixLib.AstWalker
var EventManager = remixLib.EventManager

/*
  trigger contextChanged(nodes)
*/
class ContextualListener {
  constructor (api, events) {
    this.event = new EventManager()
    this._api = api
    this._index = {
      Declarations: {},
      FlatReferences: {}
    }
    this._activeHighlights = []

    events.compiler.register('compilationFinished', (success, data, source) => {
      this._stopHighlighting()
      this._index = {
        Declarations: {},
        FlatReferences: {}
      }
      if (success) {
        this._buildIndex(data, source)
      }
    })

    events.editor.register('contentChanged', () => { this._stopHighlighting() })

    this.sourceMappingDecoder = new SourceMappingDecoder()
    this.astWalker = new AstWalker()
    setInterval(() => {
      this._highlightItems(api.getCursorPosition(), api.getCompilationResult(), api.getCurrentFile())
    }, 1000)
  }

  getActiveHighlights () {
    return [...this._activeHighlights]
  }

  declarationOf (node) {
    if (node.attributes && node.attributes.referencedDeclaration) {
      return this._index['FlatReferences'][node.attributes.referencedDeclaration]
    }
    return null
  }

  referencesOf (node) {
    return this._index['Declarations'][node.id]
  }

  _highlightItems (cursorPosition, compilationResult, file) {
    if (this.currentPosition === cursorPosition) return
    if (this.currentFile !== file) {
      this.currentFile = file
      this.currentPosition = cursorPosition
      return
    }
    this._stopHighlighting()
    this.currentPosition = cursorPosition
    this.currentFile = file
    if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) {
      var nodes = this.sourceMappingDecoder.nodesAtPosition(null, cursorPosition, compilationResult.data.sources[file])
      this.nodes = nodes
      if (nodes && nodes.length && nodes[nodes.length - 1]) {
        this._highlightExpressions(nodes[nodes.length - 1], compilationResult)
      }
      this.event.trigger('contextChanged', [nodes])
    }
  }

  _buildIndex (compilationResult, source) {
    if (compilationResult && compilationResult.sources) {
      var self = this
      var callback = {}
      callback['*'] = function (node) {
        if (node && node.attributes && node.attributes.referencedDeclaration) {
          if (!self._index['Declarations'][node.attributes.referencedDeclaration]) {
            self._index['Declarations'][node.attributes.referencedDeclaration] = []
          }
          self._index['Declarations'][node.attributes.referencedDeclaration].push(node)
        }
        self._index['FlatReferences'][node.id] = node
        return true
      }
      for (var s in compilationResult.sources) {
        this.astWalker.walk(compilationResult.sources[s].legacyAST, callback)
      }
    }
  }

  _highlight (node, compilationResult) {
    if (!node) return
    var position = this.sourceMappingDecoder.decode(node.src)
    var eventId = this._api.highlight(position, node)
    if (eventId) {
      this._activeHighlights.push({ eventId, position, fileTarget: this._api.getSourceName(position.file), nodeId: node.id })
    }
  }

  _highlightExpressions (node, compilationResult) {
    var self = this
    function highlights (id) {
      if (self._index['Declarations'] && self._index['Declarations'][id]) {
        var refs = self._index['Declarations'][id]
        for (var ref in refs) {
          var node = refs[ref]
          self._highlight(node, compilationResult)
        }
      }
    }
    if (node.attributes && node.attributes.referencedDeclaration) {
      highlights(node.attributes.referencedDeclaration)
      var current = this._index['FlatReferences'][node.attributes.referencedDeclaration]
      this._highlight(current, compilationResult)
    } else {
      highlights(node.id)
      this._highlight(node, compilationResult)
    }
    this.results = compilationResult
  }

  _stopHighlighting () {
    for (var event in this._activeHighlights) {
      this._api.stopHighlighting(this._activeHighlights[event])
    }
    this._activeHighlights = []
  }

  // GET GAS ESTIMATION
  _getGasEstimation (contract) {
    this.contract = this.results.data.contracts[this.results.source.target][contract.attributes.name]
    this.estimationObj = this.contract.evm.gasEstimates
    this.creationCost = this.estimationObj.creation.totalCost
    this.codeDepositCost = this.estimationObj.creation.codeDepositCost
  }

  gasEstimation (node) {
    this._getContract(node)
    var executionCost
    var codeDepositCost
    if (node.name === 'FunctionDefinition') {
      if (!node.attributes.isConstructor) {
        var fnName = node.attributes.name
        var fn = fnName + this._getInputParams(node)
        if (node.attributes.visibility === 'public') {
          executionCost = this.estimationObj.external[fn]
        } else if (node.attributes.visibility === 'internal') {
          executionCost = this.estimationObj.internal[fn]
        }
      } else {
        executionCost = this.creationCost
        codeDepositCost = this.codeDepositCost
      }
    } else {
      executionCost = '-'
    }
    return {executionCost, codeDepositCost}
  }

  _getContract (node) {
    for (var i in this.nodes) {
      if (this.nodes[i].id === node.attributes.scope) {
        var contract = this._getGasEstimation(this.nodes[i])
        break
      }
    }
    return contract
  }

  _getInputParams (node) {
    var params = []
    for (var i in node.children) {
      if (node.children[i].name === 'ParameterList') {
        var target = node.children[i]
        break
      }
    }
    if (target) {
      var children = target.children
      for (var j in children) {
        if (children[j].name === 'VariableDeclaration') {
          params.push(children[j].attributes.type.split(' ')[0])
        }
      }
    }
    return '(' + params.toString() + ')'
  }
}

module.exports = ContextualListener
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   xTuple Postbooks - Business Management System Framework
// Copyright: ©2011 OpenMFG LLC, d/b/a xTuple
// ==========================================================================
/*globals Postbooks sc_assert */

sc_require('views/carousel');

var base03 =   "#002b36";
var base02 =   "#073642";
var base01 =   "#586e75";
var base00 =   "#657b83";
var base0 =    "#839496";
var base1 =    "#93a1a1";
var base2 =    "#eee8d5";
var base3 =    "#fdf6e3";
var yellow =   "#b58900";
var orange =   "#cb4b16";
var red =      "#dc322f";
var magenta =  "#d33682";
var violet =   "#6c71c4";
var blue =     "#268bd2";
var cyan =     "#2aa198";
var green =    "#859900";
var white =    "white";

/**
  This surface lays out its subsurfaces, in order, from left to right. Each
  subsurface is sized so that it's frame is the same size as the Carousel.

  By default, the first subsurface is visible. You can choose another
  subsurface by doing `carousel.makeSurfaceVisible(theSuburface)`.

  @extends SC.CompositeSurface
*/
Postbooks.TileCarousel = Postbooks.Carousel.extend({

  _sc_backgroundColor: 'black',

  updateTrayLayout: function() {
    // console.log('Postbooks.TileCarousel#updateTrayLayout()');
    var tray = this._sc_tray,
        frame = SC.MakeRect(this.get('frame')),
        width = frame.width, height = frame.height,
        tilesPerSlide = 4;

    sc_assert(tray);
    var slides = tray.get('subsurfaces').length || 1; // Make at least one.

    // Need to calculate the number of tiles per slide, then figure out
    // the number of slides.
    if (slides <= 4 || width <= 678 || height <= 704) {
      tilesPerSlide = 4; // This is our minimum.
      tray.__horizontalTiles__ = tray.__verticalTiles__ = 2;
    } else {
      // See if we can fit more tiles per slide.
      var horizontalTiles = Math.floor((width-38)/320),
          verticalTiles = Math.floor((height-55)/320);

      tilesPerSlide = horizontalTiles * verticalTiles;
      tray.__horizontalTiles__ = horizontalTiles;
      tray.__verticalTiles__ = verticalTiles;
    }

    slides = Math.ceil(slides/tilesPerSlide);

    frame[2]/*width*/ = frame[2]/*width*/ * slides;
    tray.set('frame', frame);
    tray.__slides__ = slides;
  },

  initTray: function() {
    var tray;
    tray = this._sc_tray = Postbooks.InternalTileCarouselTray.create();
    this.get('subsurfaces').pushObject(tray);
  }

});

Postbooks.InternalTileCarouselTray = SC.CompositeSurface.extend({

  _sc_backgroundColor: base01,

  mouseDown: function(evt) {
    // console.log('Postbooks.InternalTileCarouselTray#mouseDown()');
    this._clientX = evt.clientX;
    this._startX = this.get('frame').x;
    // this._clientY = evt.clientY;
    this._needDirection = true;
    return true;
  },

  mouseDragged: function(evt) {
    // console.log('Postbooks.InternalTileCarouselTray#mouseDragged()');
    SC.AnimationTransaction.begin({ duration: 0 });
    var frame = this.get('frame');
    if (this._needDirection) {
      // debugger;
      this._needDirection = false;
      var currentSlide = this._nextSlide || 0;
      if (evt.clientX - this._clientX > 0) {
        currentSlide--;
      } else {
        currentSlide++;
      }

      if (currentSlide >= this.__slides__) currentSlide = this.__slides__ - 1;
      if (currentSlide < 0) currentSlide = 0;

      this._nextSlide = currentSlide;
    }
    frame.x = frame.x + evt.clientX - this._clientX;
    // frame.y = frame.y + evt.clientY - this._clientY;
    this._clientX = evt.clientX;
    // this._clientY = evt.clientY;
    SC.AnimationTransaction.end();
    return true;
  },

  mouseUp: function(evt) {
    // console.log('Postbooks.InternalTileCarouselTray#mouseUp()');
    SC.AnimationTransaction.begin({ duration: 300 });
    var frame = this.get('frame');
    // frame.x = frame.x + evt.clientX - this._clientX;
    frame.x = this._nextSlide * -this.getPath('carousel.frame').width;
    // frame.x = this._startX;
    // frame.y = frame.y + evt.clientY - this._clientY;
    this.set('frame', frame);
    delete this._clientX;
    // delete this._clientY;
    SC.AnimationTransaction.end();
    return true;
  },

  carousel: function() {
    return this.get('supersurface');
  }.property(),

  updateLayout: function() {
    // console.log('Postbooks.InternalTileCarouselTray#updateLayout()');
    var subsurfaces = this.get('subsurfaces'),
        frame = SC.MakeRect(this.get('frame')),
        totalWidth = frame.width,
        slides = this.__slides__, // Set by our Carousel.
        width = Math.floor(frame.width / slides),
        height = frame.height,
        horizontalTiles = this.__horizontalTiles__,
        verticalTiles = this.__verticalTiles__,
        tilesPerSlide = horizontalTiles * verticalTiles;

    // Calculate and cache the tile frames for a single slide.
    var columns = [], column, tileFrame;
    var horizontalCenter = Math.floor((width/horizontalTiles)/2);
    var horizontalOffset = Math.floor(width/horizontalTiles);
    var verticalCenter = Math.floor(((height-55)/verticalTiles)/2);
    var verticalOffset = Math.floor((height-55)/verticalTiles);
    for (var idx=0, len=horizontalTiles; idx<len; ++idx) {
      column = columns[idx] = [];
      for (var idx2=0, len2=verticalTiles; idx2<len2; ++idx2) {
        tileFrame = column[idx2] = SC.MakeRect();
        if (Postbooks.USE_320_TILES) {

          tileFrame.width = tileFrame.height = 320;
          tileFrame.x = ((idx*horizontalOffset)+horizontalCenter) - 160;
          tileFrame.y = ((idx2*verticalOffset)+verticalCenter) - 160;
        } else {
          tileFrame.width = horizontalOffset - 12;
          tileFrame.height = verticalOffset - 12;
          tileFrame.x = ((idx*horizontalOffset)+horizontalCenter) - (horizontalOffset/2) + 6;
          tileFrame.y = ((idx2*verticalOffset)+verticalCenter) - (verticalOffset/2) + 6;
        }
      }
    }

    // Loop over the slides and set the tile frames using the cached frames.
    for (var i=0, ilen=slides; i<ilen; ++i) {
      // Loop over the tiles in that slide (not all tiles need to exist);
      for (var j=i*tilesPerSlide, jlen=j+tilesPerSlide; j<jlen; ++j) {
        var tile = subsurfaces[j];
        if (tile) {
          sc_assert(tile.isTile);

          // Look up the cached frame for this tile.
          var slideIndex = j - (i*tilesPerSlide);
          var columnIndex = slideIndex % horizontalTiles;
          var rowIndex = Math.floor(slideIndex/horizontalTiles);

          tileFrame = columns[columnIndex][rowIndex];

          // We need to move the tileFrame to the correct slide.
          var x = tileFrame.x;
          tileFrame.x = x + width*i;
          sc_assert(tileFrame);
          tile.set('frame', tileFrame);
          tileFrame.x = x; // Restore the original.
        }
      }
    }
  }

});
<commit_msg>continuing tile carousel layouts and behavior<commit_after>// ==========================================================================
// Project:   xTuple Postbooks - Business Management System Framework
// Copyright: ©2011 OpenMFG LLC, d/b/a xTuple
// ==========================================================================
/*globals Postbooks sc_assert */

sc_require('views/carousel');

var base03 =   "#002b36";
var base02 =   "#073642";
var base01 =   "#586e75";
var base00 =   "#657b83";
var base0 =    "#839496";
var base1 =    "#93a1a1";
var base2 =    "#eee8d5";
var base3 =    "#fdf6e3";
var yellow =   "#b58900";
var orange =   "#cb4b16";
var red =      "#dc322f";
var magenta =  "#d33682";
var violet =   "#6c71c4";
var blue =     "#268bd2";
var cyan =     "#2aa198";
var green =    "#859900";
var white =    "white";

/**
  This surface lays out its subsurfaces, in order, from left to right. Each
  subsurface is sized so that it's frame is the same size as the Carousel.

  By default, the first subsurface is visible. You can choose another
  subsurface by doing `carousel.makeSurfaceVisible(theSuburface)`.

  @extends SC.CompositeSurface
*/
Postbooks.TileCarousel = Postbooks.Carousel.extend({

  _sc_backgroundColor: 'black',

  updateTrayLayout: function() {
    // console.log('Postbooks.TileCarousel#updateTrayLayout()');
    var tray = this._sc_tray,
        frame = SC.MakeRect(this.get('frame')),
        width = frame.width, height = frame.height;

    sc_assert(tray);
    var slides = tray.get('subsurfaces').length || 1;
    // Need to calculate the number of tiles per slide, then figure out
    // the number of slides.
/*
    if (slides <= 4 || width <= 678 || height <= 704) {
      tilesPerSlide = 4; // This is our minimum.
      tray.__horizontalTiles__ = tray.__verticalTiles__ = 2;
    } else {
      // See if we can fit more tiles per slide.
      var horizontalTiles = Math.floor((width-38)/320),
          verticalTiles = Math.floor((height-55)/320);

      tilesPerSlide = horizontalTiles * verticalTiles;
      tray.__horizontalTiles__ = horizontalTiles;
      tray.__verticalTiles__ = verticalTiles;
    }*/

    tilesPerSlide = 2;
    tray.__horizontalTiles__ = 1;
    tray.__verticalTiles__ = 2;
    slides = Math.ceil(slides/2);

    frame[2]/*width*/ = frame[2]/*width*/ * slides;
    tray.set('frame', frame);
    tray.__slides__ = slides;
  },

  initTray: function() {
    var tray;
    tray = this._sc_tray = Postbooks.InternalTileCarouselTray.create();
    this.get('subsurfaces').pushObject(tray);
  }

});

Postbooks.InternalTileCarouselTray = SC.CompositeSurface.extend({

  _sc_backgroundColor: base01,

  mouseDown: function(evt) {
    // console.log('Postbooks.InternalTileCarouselTray#mouseDown()');
    this._clientX = evt.clientX;
    this._startX = this.get('frame').x;
    // this._clientY = evt.clientY;
    this._needDirection = true;
    return true;
  },

  mouseDragged: function(evt) {
    // console.log('Postbooks.InternalTileCarouselTray#mouseDragged()');
    SC.AnimationTransaction.begin({ duration: 0 });
    var frame = this.get('frame');
    if (this._needDirection) {
      // debugger;
      this._needDirection = false;
      var currentSlide = this._nextSlide || 0;
      if (evt.clientX - this._clientX > 0) {
        currentSlide--;
      } else {
        currentSlide++;
      }

      if (currentSlide >= this.__slides__) currentSlide = this.__slides__ - 1;
      if (currentSlide < 0) currentSlide = 0;

      this._nextSlide = currentSlide;
    }
    frame.x = frame.x + evt.clientX - this._clientX;
    // frame.y = frame.y + evt.clientY - this._clientY;
    this._clientX = evt.clientX;
    // this._clientY = evt.clientY;
    SC.AnimationTransaction.end();
    return true;
  },

  mouseUp: function(evt) {
    // console.log('Postbooks.InternalTileCarouselTray#mouseUp()');
    SC.AnimationTransaction.begin({ duration: 300 });
    var frame = this.get('frame');
    // frame.x = frame.x + evt.clientX - this._clientX;
    frame.x = this._nextSlide * -this.getPath('carousel.frame').width;
    // frame.x = this._startX;
    // frame.y = frame.y + evt.clientY - this._clientY;
    this.set('frame', frame);
    delete this._clientX;
    // delete this._clientY;
    SC.AnimationTransaction.end();
    return true;
  },

  carousel: function() {
    return this.get('supersurface');
  }.property(),

  updateLayout: function() {
    // console.log('Postbooks.InternalTileCarouselTray#updateLayout()');
    var subsurfaces = this.get('subsurfaces'),
        frame = SC.MakeRect(this.get('frame')),
        totalWidth = frame.width,
        slides = this.__slides__, // Set by our Carousel.
        width = 500,//Math.floor(frame.width / slides),
        height = frame.height,
        horizontalTiles = this.__horizontalTiles__,
        verticalTiles = this.__verticalTiles__,
        tilesPerSlide = 2;
console.log('frame width: %@'.fmt(frame.width));
console.log('width: %@'.fmt(width));
console.log('height: %@'.fmt(height));
    // Calculate and cache the tile frames for a single slide.
    var columns = [], column, tileFrame;
    var horizontalCenter = 48;
    var horizontalOffset = 96;
    var verticalCenter = 162;
    var verticalOffset = 324;
    for (var idx=0, len=horizontalTiles; idx<len; ++idx) {
      column = columns[idx] = [];
      for (var idx2=0, len2=verticalTiles; idx2<len2; ++idx2) {
        tileFrame = column[idx2] = SC.MakeRect();
        if (Postbooks.USE_320_TILES) {

          tileFrame.width = tileFrame.height = 320;
          tileFrame.x = ((idx*horizontalOffset)+horizontalCenter) - 50;
          tileFrame.y = ((idx2*verticalOffset)+verticalCenter) - 100;
        }/* else {
          tileFrame.width = horizontalOffset - 12;
          tileFrame.height = verticalOffset - 12;
          tileFrame.x = ((idx*horizontalOffset)+horizontalCenter) - (horizontalOffset/2) + 6;
          tileFrame.y = ((idx2*verticalOffset)+verticalCenter) - (verticalOffset/2) + 6;
        }*/
      }
    }

    // Loop over the slides and set the tile frames using the cached frames.
    for (var i=0, ilen=slides; i<ilen; ++i) {
      // Loop over the tiles in that slide (not all tiles need to exist);
      for (var j=i*tilesPerSlide, jlen=j+tilesPerSlide; j<jlen; ++j) {
        var tile = subsurfaces[j];
        if (tile) {
          sc_assert(tile.isTile);

          // Look up the cached frame for this tile.
          var slideIndex = j - (i*tilesPerSlide);
          var columnIndex = slideIndex % horizontalTiles;
          var rowIndex = Math.floor(slideIndex/horizontalTiles);

          tileFrame = columns[columnIndex][rowIndex];

          // We need to move the tileFrame to the correct slide.
          var x = tileFrame.x;
          tileFrame.x = x + width*i;
          sc_assert(tileFrame);
          tile.set('frame', tileFrame);
          tileFrame.x = x; // Restore the original.
        }
      }
    }
  }

});
<|endoftext|>


<commit_before>/**
 * Data store utilities.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';

/**
 * WordPress dependencies
 */
import { createRegistryControl } from '@wordpress/data';

const GET_REGISTRY = 'GET_REGISTRY';

/**
 * Collects and combines multiple objects of similar shape.
 *
 * Used to combine objects like actions, selectors, etc. for a data
 * store while ensuring no keys/action names/selector names are duplicated.
 *
 * Effectively this is an object spread, but throws an error if keys are
 * duplicated.
 *
 * @since 1.5.0
 * @private
 *
 * @param {...Object} items A list of arguments, each one should be an object to combine into one.
 * @return {Object} The combined object.
 */
export const collect = ( ...items ) => {
	const collectedObject = items.reduce( ( acc, item ) => {
		return { ...acc, ...item };
	}, {} );

	const functionNames = items.reduce( ( acc, itemSet ) => {
		return [ ...acc, ...Object.keys( itemSet ) ];
	}, [] );
	const duplicates = findDuplicates( functionNames );

	invariant( duplicates.length === 0, `collect() cannot accept collections with duplicate keys. Your call to collect() contains the following duplicated functions: ${ duplicates.join( ', ' ) }. Check your data stores for duplicates.` );

	return collectedObject;
};

/**
 * Collects all actions.
 *
 * @since 1.5.0
 *
 * @param {...Object} args A list of objects, each containing their own actions.
 * @return {Object} The combined object.
 */
export const collectActions = collect;

/**
 * Collects all controls.
 *
 * @since 1.5.0
 *
 * @param {...Object} args A list of objects, each containing their own controls.
 * @return {Object} The combined object.
 */
export const collectControls = collect;

/**
 * Collects all reducers and (optionally) provides initial state.
 *
 * If the first argument passed is not a function, it will be used as the
 * combined reducer's `INITIAL_STATE`.
 *
 * @since 1.5.0
 *
 * @param {...(Object|Function)} args A list of reducers, each containing their own controls. If the first argument is not a function, it will be used as the combined reducer's `INITIAL_STATE`.
 * @return {Function} A Redux-style reducer.
 */
export const collectReducers = ( ...args ) => {
	const reducers = [ ...args ];
	let initialState;

	if ( typeof reducers[ 0 ] !== 'function' ) {
		initialState = reducers.shift();
	}

	return ( state = initialState, action = {} ) => {
		return reducers.reduce( ( newState, reducer ) => {
			return reducer( newState, action );
		}, state );
	};
};

/**
 * Collects all resolvers.
 *
 * @since 1.5.0
 *
 * @param {...Object} args A list of objects, each containing their own resolvers.
 * @return {Object} The combined object.
 */
export const collectResolvers = collect;

/**
 * Collects all selectors.
 *
 * @since 1.5.0
 *
 * @param {...Object} args A list of objects, each containing their own selectors.
 * @return {Object} The combined object.
 */
export const collectSelectors = collect;

/**
 * Collects all state values.
 *
 * @param {...Object} args A list of objects, each containing their own state values.
 *
 * @return {Object} The combined object.
 */
export const collectState = collect;

/**
 * Collects all store names.
 *
 * This function's main purpose is to ensure generated store names for a single store match.
 *
 * @since 1.6.0
 *
 * @param {...string} args A list of store names, all of which must be equal.
 * @return {string} The single store name.
 */
export const collectName = ( ...args ) => {
	const names = [ ...args ];

	const duplicates = findDuplicates( names );
	invariant( duplicates.length === names.length - 1, 'collectName() must not receive different names.' );

	return names.shift();
};

/**
 * An empty reducer.
 *
 * @since 1.8.0
 * @private
 *
 * @param {Object} state A store's state.
 * @return {Object} The same state data as passed in `state`.
 */
const passthroughReducer = ( state ) => {
	return { ...state };
};

/**
 * Combines multiple stores.
 *
 * @since 1.8.0
 *
 * @param {...Object} stores A list of objects, each a store containing one or more of the following keys: INITIAL_STATE, actions, controls, reducer, resolvers, selectors
 * @return {Object} The combined store.
 */
export const combineStores = ( ...stores ) => {
	const combinedInitialState = collectState(
		...stores.map( ( store ) => ( store.INITIAL_STATE || {} ) )
	);

	return {
		INITIAL_STATE: combinedInitialState,
		controls: collectControls(
			...stores.map( ( store ) => ( store.controls || {} ) )
		),
		actions: collectActions(
			...stores.map( ( store ) => ( store.actions || {} ) )
		),
		reducer: collectReducers(
			combinedInitialState,
			...stores.map( ( store ) => ( store.reducer || passthroughReducer ) )
		),
		resolvers: collectResolvers(
			...stores.map( ( store ) => ( store.resolvers || {} ) )
		),
		selectors: collectSelectors(
			...stores.map( ( store ) => ( store.selectors || {} ) )
		),
	};
};

/**
 * An object of common actions most stores will use.
 *
 * @since 1.7.0
 *
 * @return {Object} key/value list of common actions most stores will want.
 */
export const commonActions = {
	/**
	 * Dispatches an action and calls a control to get the current data registry.
	 *
	 * Useful for controls and resolvers that wish to dispatch actions/use selectors
	 * on the current data registry.
	 *
	 * @since 1.7.0
	 *
	 * @return {Object} FSA-compatible action.
	 */
	getRegistry() {
		return {
			payload: {},
			type: GET_REGISTRY,
		};
	},
};

/**
 * An object of common controls most stores will use.
 *
 * @since 1.7.0
 *
 * @return {Object} key/value list of common controls most stores will want.
 */
export const commonControls = {
	/**
	 * Returns the current registry.
	 *
	 * Useful for controls and resolvers that wish to dispatch actions/use selectors
	 * on the current data registry.
	 *
	 * @since 1.7.0
	 *
	 * @return {Object} FSA-compatible action.
	 */
	[ GET_REGISTRY ]: createRegistryControl( ( registry ) => () => registry ),
};

/**
 * An object of common selectors some store will use.
 *
 * @since n.e.x.t
 *
 * @return
 */
export const commonSelectors = {
	/**
	 * Returns the registry key being used for a given store.
	 *
	 * @since n.e.x.t
	 * @private
	 *
	 * @param {Object} state Data store's state.
	 * @return {(number|undefined)} The registryKey for a given store.
	 */
	getRegistryKey( state ) {
		const { registryKey } = state;

		return registryKey;
	},
};

/**
 * Finds all duplicate items in an array and return them.
 *
 * @since 1.5.0
 * @private
 *
 * @param {Array} array Any array.
 * @return {Array} All values in the input array that were duplicated.
 */
const findDuplicates = ( array ) => {
	const duplicates = [];
	const counts = {};

	for ( let i = 0; i < array.length; i++ ) {
		const item = array[ i ];
		counts[ item ] = counts[ item ] >= 1 ? counts[ item ] + 1 : 1;
		if ( counts[ item ] > 1 ) {
			duplicates.push( item );
		}
	}

	return duplicates;
};

/**
 * A store containing the common actions, controls and reducer that all stores will use.
 *
 * @since 1.8.0
 *
 * @return {Object} Object with common actions, controls and reducer.
 */
export const commonStore = {
	actions: commonActions,
	controls: commonControls,
	selectors: commonSelectors,
	reducer: passthroughReducer,
};
<commit_msg>Remove getRegistryKey from common items.<commit_after>/**
 * Data store utilities.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';

/**
 * WordPress dependencies
 */
import { createRegistryControl } from '@wordpress/data';

const GET_REGISTRY = 'GET_REGISTRY';

/**
 * Collects and combines multiple objects of similar shape.
 *
 * Used to combine objects like actions, selectors, etc. for a data
 * store while ensuring no keys/action names/selector names are duplicated.
 *
 * Effectively this is an object spread, but throws an error if keys are
 * duplicated.
 *
 * @since 1.5.0
 * @private
 *
 * @param {...Object} items A list of arguments, each one should be an object to combine into one.
 * @return {Object} The combined object.
 */
export const collect = ( ...items ) => {
	const collectedObject = items.reduce( ( acc, item ) => {
		return { ...acc, ...item };
	}, {} );

	const functionNames = items.reduce( ( acc, itemSet ) => {
		return [ ...acc, ...Object.keys( itemSet ) ];
	}, [] );
	const duplicates = findDuplicates( functionNames );

	invariant( duplicates.length === 0, `collect() cannot accept collections with duplicate keys. Your call to collect() contains the following duplicated functions: ${ duplicates.join( ', ' ) }. Check your data stores for duplicates.` );

	return collectedObject;
};

/**
 * Collects all actions.
 *
 * @since 1.5.0
 *
 * @param {...Object} args A list of objects, each containing their own actions.
 * @return {Object} The combined object.
 */
export const collectActions = collect;

/**
 * Collects all controls.
 *
 * @since 1.5.0
 *
 * @param {...Object} args A list of objects, each containing their own controls.
 * @return {Object} The combined object.
 */
export const collectControls = collect;

/**
 * Collects all reducers and (optionally) provides initial state.
 *
 * If the first argument passed is not a function, it will be used as the
 * combined reducer's `INITIAL_STATE`.
 *
 * @since 1.5.0
 *
 * @param {...(Object|Function)} args A list of reducers, each containing their own controls. If the first argument is not a function, it will be used as the combined reducer's `INITIAL_STATE`.
 * @return {Function} A Redux-style reducer.
 */
export const collectReducers = ( ...args ) => {
	const reducers = [ ...args ];
	let initialState;

	if ( typeof reducers[ 0 ] !== 'function' ) {
		initialState = reducers.shift();
	}

	return ( state = initialState, action = {} ) => {
		return reducers.reduce( ( newState, reducer ) => {
			return reducer( newState, action );
		}, state );
	};
};

/**
 * Collects all resolvers.
 *
 * @since 1.5.0
 *
 * @param {...Object} args A list of objects, each containing their own resolvers.
 * @return {Object} The combined object.
 */
export const collectResolvers = collect;

/**
 * Collects all selectors.
 *
 * @since 1.5.0
 *
 * @param {...Object} args A list of objects, each containing their own selectors.
 * @return {Object} The combined object.
 */
export const collectSelectors = collect;

/**
 * Collects all state values.
 *
 * @param {...Object} args A list of objects, each containing their own state values.
 *
 * @return {Object} The combined object.
 */
export const collectState = collect;

/**
 * Collects all store names.
 *
 * This function's main purpose is to ensure generated store names for a single store match.
 *
 * @since 1.6.0
 *
 * @param {...string} args A list of store names, all of which must be equal.
 * @return {string} The single store name.
 */
export const collectName = ( ...args ) => {
	const names = [ ...args ];

	const duplicates = findDuplicates( names );
	invariant( duplicates.length === names.length - 1, 'collectName() must not receive different names.' );

	return names.shift();
};

/**
 * An empty reducer.
 *
 * @since 1.8.0
 * @private
 *
 * @param {Object} state A store's state.
 * @return {Object} The same state data as passed in `state`.
 */
const passthroughReducer = ( state ) => {
	return { ...state };
};

/**
 * Combines multiple stores.
 *
 * @since 1.8.0
 *
 * @param {...Object} stores A list of objects, each a store containing one or more of the following keys: INITIAL_STATE, actions, controls, reducer, resolvers, selectors
 * @return {Object} The combined store.
 */
export const combineStores = ( ...stores ) => {
	const combinedInitialState = collectState(
		...stores.map( ( store ) => ( store.INITIAL_STATE || {} ) )
	);

	return {
		INITIAL_STATE: combinedInitialState,
		controls: collectControls(
			...stores.map( ( store ) => ( store.controls || {} ) )
		),
		actions: collectActions(
			...stores.map( ( store ) => ( store.actions || {} ) )
		),
		reducer: collectReducers(
			combinedInitialState,
			...stores.map( ( store ) => ( store.reducer || passthroughReducer ) )
		),
		resolvers: collectResolvers(
			...stores.map( ( store ) => ( store.resolvers || {} ) )
		),
		selectors: collectSelectors(
			...stores.map( ( store ) => ( store.selectors || {} ) )
		),
	};
};

/**
 * An object of common actions most stores will use.
 *
 * @since 1.7.0
 *
 * @return {Object} key/value list of common actions most stores will want.
 */
export const commonActions = {
	/**
	 * Dispatches an action and calls a control to get the current data registry.
	 *
	 * Useful for controls and resolvers that wish to dispatch actions/use selectors
	 * on the current data registry.
	 *
	 * @since 1.7.0
	 *
	 * @return {Object} FSA-compatible action.
	 */
	getRegistry() {
		return {
			payload: {},
			type: GET_REGISTRY,
		};
	},
};

/**
 * An object of common controls most stores will use.
 *
 * @since 1.7.0
 *
 * @return {Object} key/value list of common controls most stores will want.
 */
export const commonControls = {
	/**
	 * Returns the current registry.
	 *
	 * Useful for controls and resolvers that wish to dispatch actions/use selectors
	 * on the current data registry.
	 *
	 * @since 1.7.0
	 *
	 * @return {Object} FSA-compatible action.
	 */
	[ GET_REGISTRY ]: createRegistryControl( ( registry ) => () => registry ),
};

/**
 * Finds all duplicate items in an array and return them.
 *
 * @since 1.5.0
 * @private
 *
 * @param {Array} array Any array.
 * @return {Array} All values in the input array that were duplicated.
 */
const findDuplicates = ( array ) => {
	const duplicates = [];
	const counts = {};

	for ( let i = 0; i < array.length; i++ ) {
		const item = array[ i ];
		counts[ item ] = counts[ item ] >= 1 ? counts[ item ] + 1 : 1;
		if ( counts[ item ] > 1 ) {
			duplicates.push( item );
		}
	}

	return duplicates;
};

/**
 * A store containing the common actions, controls and reducer that all stores will use.
 *
 * @since 1.8.0
 *
 * @return {Object} Object with common actions, controls and reducer.
 */
export const commonStore = {
	actions: commonActions,
	controls: commonControls,
	reducer: passthroughReducer,
};
<|endoftext|>


<commit_before><commit_msg>error messages<commit_after><|endoftext|>