<commit_before>/*
Copyright (c) 2014, EDINA.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
   list of conditions and the following disclaimer in the documentation and/or
   other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software must
   display the following acknowledgement: This product includes software
   developed by the EDINA.
4. Neither the name of the EDINA nor the names of its contributors may be used to
   endorse or promote products derived from this software without specific prior
   written permission.

THIS SOFTWARE IS PROVIDED BY EDINA ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL EDINA BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*/

"use strict";

/* global FileUploadOptions */

/**
 * Module deals with uploading records to Personal Cloud.
 */
define(['records', 'map', 'utils', './pcapi', './login'],
       function(records, map, utils, pcapi, login){// jshint ignore:line

    /**
     * Create remote record.
     * @param record Record object to create remotely.
     * @param callback
     */
    var createRemoteRecord = function(id, record, callback) {
        var userId = login.getUser().id;
        var cloudProviderUrl = pcapi.getCloudProviderUrl();

        // clone record for remote copy
        var dropboxRecord = jQuery.extend(true, {}, record);

        // create record URL
        var recordDir = cloudProviderUrl + '/records/'+pcapi.getProvider()+'/' +
            userId + '/' + record.name;

        if(dropboxRecord.point !== undefined){
            // convert remote record coords to WGS84
            dropboxRecord.point = map.pointToExternal(dropboxRecord.point);

            // convert asset URLs to simple filename
            $.each(dropboxRecord.fields, function(i, field){
                if(field.val && records.isAsset(field)){
                    field.val = field.val.substr(field.val.lastIndexOf('/') + 1);
                }
            });

            var assetCount = 0;
            var finished = function(success){
                --assetCount;
                if(assetCount < 1){
                    var delay = 0;
                    if(!success){
                        delay = 3000;
                        utils.inform('An error has occurred syncing');
                    }

                    setTimeout(function(){
                        callback(success);
                    }, delay);
                }
            };

            console.debug("Post: " + recordDir);

            // post record
            $.ajax({
                url: recordDir,
                type: "POST",
                cache: false,
                data: JSON.stringify(dropboxRecord, undefined, 2),
                success: function(data){
                    // If the response is not a json or contains an error finish
                    if(typeof(data) !== 'object' || data.error !== 0){
                        console.error(data);
                        finished(false);
                        return;
                    }

                    // check if new record name
                    var s = data.path.indexOf('/', 1) + 1;
                    var name = data.path.substr(s, data.path.lastIndexOf('/') - s);
                    if(record.name !== name){
                        // name has been changed by api
                        console.debug(record.name + " renamed to " + name);
                        utils.inform(record.name + " renamed to " + name);
                        record.name = name;
                        $('#' + id + ' h3').text(name);

                        // update URL
                        recordDir = cloudProviderUrl + '/records/'+pcapi.getProvider()+'/' +
                            userId + '/' + record.name;
                    }

                    // create any asserts associated with record
                    $.each(record.fields, function(i, field){
                        var type = records.typeFromId(field.id);
                        if(records.isAsset(field, type)){
                            ++assetCount;
                            var options = new FileUploadOptions();
                            //options.chunkedMode = false;  // ?

                            if(type === 'audio'){
                                options.mimeType = "audio/3gpp";
                            }
                            else if(type === 'track'){
                                options.mimeType = "text/xml";
                            }

                            var fileName = field.val.substr(field.val.lastIndexOf('/') + 1);
                            var assetUrl = recordDir + '/' + fileName;
                            options.fileName = fileName;

                            setTimeout(function(){
                                var ft = new FileTransfer();
                                ft.upload(
                                    field.val,
                                    encodeURI(assetUrl),
                                    function(result){
                                        utils.printObj(result);
                                        var success;
                                        try{
                                            var res = JSON.parse(result.response);
                                            if(res.error === 0){
                                                success = true;
                                            }else{
                                                success = false;
                                                console.error(res.msg);
                                            }
                                        }catch(e){
                                            console.debug('Non json response');
                                            success = false;
                                        }finally{
                                            finished(success);
                                        }
                                    },
                                    function(error){
                                        utils.printObj(error);
                                        console.error("Problem uploading asset: " +
                                                      assetUrl + ", error = " + error.code);
                                        finished(false);
                                    },
                                    options
                                );
                            }, 1000);
                        }
                    });

                    if(assetCount === 0){
                        finished();
                    }
                },
                error: function(jqXHR, status, error){
                    console.error("Problem creating remote directory " + recordDir +
                                  " : " + status + " : " + error);
                    finished(false);
                }
            });
        }
        else{
            console.error("record has no location delete it: " + record.name);

            // executing callback synchronously causes problems for the calling function
            setTimeout(function(){
                callback(false);
            }, 500);
        }
    };

var _this = {

    /**
     * Upload unsynced records.
     * @param complete Function executed when upload is complete.
     */
    uploadRecords: function(complete) {
        // do upload sync
        var annotations = records.getSavedRecords();
        var uploadCount = 0;
        $.each(annotations, function(id, annotation){
            if(!annotation.isSynced){
                $('#' + id + ' .ui-block-a').removeClass(
                    'saved-records-list-synced-false');
                $('#' + id + ' .ui-block-a').addClass(
                    'saved-records-list-syncing');

                ++uploadCount;
                createRemoteRecord(id, annotation.record, function(success){
                    --uploadCount;
                    $('#' + id + ' .ui-block-a').removeClass(
                        'saved-records-list-syncing');
                    if(success){
                        $('#' + id + ' .ui-block-a').addClass(
                            'saved-records-list-synced-true');

                        annotation.isSynced = true;
                        records.saveAnnotation(id, annotation);
                    }
                    else{
                        $('#' + id + ' .ui-block-a').addClass(
                            'saved-records-list-synced-false');
                    }

                    if(uploadCount === 0){
                        complete();
                    }
                });
            }
        });

        if(uploadCount === 0){
            complete();
            utils.inform('Nothing to upload');
        }
    },
};

return _this;

});
<commit_msg>Show specific error message for dropbox errors<commit_after>/*
Copyright (c) 2014, EDINA.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
   list of conditions and the following disclaimer in the documentation and/or
   other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software must
   display the following acknowledgement: This product includes software
   developed by the EDINA.
4. Neither the name of the EDINA nor the names of its contributors may be used to
   endorse or promote products derived from this software without specific prior
   written permission.

THIS SOFTWARE IS PROVIDED BY EDINA ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL EDINA BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*/

"use strict";

/* global FileUploadOptions */

/**
 * Module deals with uploading records to Personal Cloud.
 */
define(['records', 'map', 'utils', './pcapi', './login'],
       function(records, map, utils, pcapi, login){// jshint ignore:line

    /**
     * Create remote record.
     * @param record Record object to create remotely.
     * @param callback
     */
    var createRemoteRecord = function(id, record, callback) {
        var userId = login.getUser().id;
        var cloudProviderUrl = pcapi.getCloudProviderUrl();

        // clone record for remote copy
        var dropboxRecord = jQuery.extend(true, {}, record);

        // create record URL
        var recordDir = cloudProviderUrl + '/records/'+pcapi.getProvider()+'/' +
            userId + '/' + record.name;

        if(dropboxRecord.point !== undefined){
            // convert remote record coords to WGS84
            dropboxRecord.point = map.pointToExternal(dropboxRecord.point);

            // convert asset URLs to simple filename
            $.each(dropboxRecord.fields, function(i, field){
                if(field.val && records.isAsset(field)){
                    field.val = field.val.substr(field.val.lastIndexOf('/') + 1);
                }
            });

            var assetCount = 0;
            var finished = function(success, msg){
                --assetCount;
                if(assetCount < 1){
                    var delay = 0;
                    if(!success){
                        msg = msg || 'An error has occurred syncing';
                        delay = 3000;
                        utils.inform(msg);
                    }

                    setTimeout(function(){
                        callback(success);
                    }, delay);
                }
            };

            console.debug("Post: " + recordDir);

            // post record
            $.ajax({
                url: recordDir,
                type: "POST",
                cache: false,
                data: JSON.stringify(dropboxRecord, undefined, 2),
                success: function(data){
                    // If the response is not a json or contains an error finish
                    if(typeof(data) !== 'object'){
                        finished(false);
                        return;
                    }

                    if(data.error !== 0){
                        console.error(data);
                        finished(false, data.msg);
                        return;
                    }

                    // check if new record name
                    var s = data.path.indexOf('/', 1) + 1;
                    var name = data.path.substr(s, data.path.lastIndexOf('/') - s);
                    if(record.name !== name){
                        // name has been changed by api
                        console.debug(record.name + " renamed to " + name);
                        utils.inform(record.name + " renamed to " + name);
                        record.name = name;
                        $('#' + id + ' h3').text(name);

                        // update URL
                        recordDir = cloudProviderUrl + '/records/'+pcapi.getProvider()+'/' +
                            userId + '/' + record.name;
                    }

                    // create any asserts associated with record
                    $.each(record.fields, function(i, field){
                        var type = records.typeFromId(field.id);
                        if(records.isAsset(field, type)){
                            ++assetCount;
                            var options = new FileUploadOptions();
                            //options.chunkedMode = false;  // ?

                            if(type === 'audio'){
                                options.mimeType = "audio/3gpp";
                            }
                            else if(type === 'track'){
                                options.mimeType = "text/xml";
                            }

                            var fileName = field.val.substr(field.val.lastIndexOf('/') + 1);
                            var assetUrl = recordDir + '/' + fileName;
                            options.fileName = fileName;

                            setTimeout(function(){
                                var ft = new FileTransfer();
                                ft.upload(
                                    field.val,
                                    encodeURI(assetUrl),
                                    function(result){
                                        utils.printObj(result);
                                        var success;
                                        try{
                                            var res = JSON.parse(result.response);
                                            if(res.error === 0){
                                                success = true;
                                            }else{
                                                success = false;
                                                console.error(res.msg);
                                            }
                                        }catch(e){
                                            console.debug('Non json response');
                                            success = false;
                                        }finally{
                                            finished(success);
                                        }
                                    },
                                    function(error){
                                        utils.printObj(error);
                                        console.error("Problem uploading asset: " +
                                                      assetUrl + ", error = " + error.code);
                                        finished(false);
                                    },
                                    options
                                );
                            }, 1000);
                        }
                    });

                    if(assetCount === 0){
                        finished();
                    }
                },
                error: function(jqXHR, status, error){
                    console.error("Problem creating remote directory " + recordDir +
                                  " : " + status + " : " + error);
                    finished(false);
                }
            });
        }
        else{
            console.error("record has no location delete it: " + record.name);

            // executing callback synchronously causes problems for the calling function
            setTimeout(function(){
                callback(false);
            }, 500);
        }
    };

var _this = {

    /**
     * Upload unsynced records.
     * @param complete Function executed when upload is complete.
     */
    uploadRecords: function(complete) {
        // do upload sync
        var annotations = records.getSavedRecords();
        var uploadCount = 0;
        $.each(annotations, function(id, annotation){
            if(!annotation.isSynced){
                $('#' + id + ' .ui-block-a').removeClass(
                    'saved-records-list-synced-false');
                $('#' + id + ' .ui-block-a').addClass(
                    'saved-records-list-syncing');

                ++uploadCount;
                createRemoteRecord(id, annotation.record, function(success){
                    --uploadCount;
                    $('#' + id + ' .ui-block-a').removeClass(
                        'saved-records-list-syncing');
                    if(success){
                        $('#' + id + ' .ui-block-a').addClass(
                            'saved-records-list-synced-true');

                        annotation.isSynced = true;
                        records.saveAnnotation(id, annotation);
                    }
                    else{
                        $('#' + id + ' .ui-block-a').addClass(
                            'saved-records-list-synced-false');
                    }

                    if(uploadCount === 0){
                        complete();
                    }
                });
            }
        });

        if(uploadCount === 0){
            complete();
            utils.inform('Nothing to upload');
        }
    },
};

return _this;

});
<|endoftext|>


<commit_before>describe('The CamlTag should build a valid XML String', function() {
	var CamlTag;
	beforeEach(module('ngSharepoint'));
	beforeEach(inject(function(_CamlTag_) {
		CamlTag = _CamlTag_;
	}));
	it('builds a valid XML Tag', function() {
		expect(new CamlTag('Test').build()).toEqual('<Test/>');
	});
	it('builds a valid XML Tag with Attributes', function() {
		expect(new CamlTag('Test', {Type: "Test"}).build()).toEqual('<Test Type="Test"/>');
	});
	it('builds a valid XML Hierarchy', function() {
		var tag = new CamlTag('Test');
		tag.push('Child');
		expect(tag.build()).toEqual('<Test><Child/></Test>');
	});
	it('builds a valid XML Tag with a value', function() {
		expect(new CamlTag('Test', {}, 'Value').build()).toEqual('<Test>Value</Test>');
	});
});<commit_msg>More Tests<commit_after>describe('The CamlTag should build a valid XML String', function() {
	var CamlTag;
	beforeEach(module('ngSharepoint'));
	beforeEach(inject(function(_CamlTag_) {
		CamlTag = _CamlTag_;
	}));
	it('builds a valid XML Tag', function() {
		expect(new CamlTag('Test').build()).toEqual('<Test/>');
	});
	it('builds a valid XML Tag with Attributes', function() {
		expect(new CamlTag('Test', {Type: "Test"}).build()).toEqual('<Test Type="Test"/>');
	});
	it('builds a valid XML Hierarchy', function() {
		var tag = new CamlTag('Test');
		tag.push('Child');
		expect(tag.build()).toEqual('<Test><Child/></Test>');
	});
	it('builds a valid XML Tag with a value', function() {
		expect(new CamlTag('Test', {}, 'Value').build()).toEqual('<Test>Value</Test>');
	});
	it('builds a valid XML Tag with a value and attributes', function() {
		expect(new CamlTag('Test', {Attr: 'attr'}, 'Value').build()).toEqual('<Test Attr="attr">Value</Test>');
	})
});<|endoftext|>


<commit_before>var casper = require('casper').create();
var mouse = require("mouse").create(casper);

// navigate straight to relevant asp page

casper.start('https://www.questnet.sg/Maincontent.asp', function() {
    this.echo("loaded");
});

// select form and input login details

casper.then(function() {
    casper.waitForSelector("form input[name='txtUserID']", function() {
	this.fillSelectors('form', {
            'input[name = txtUserID ]' : 'username',
            'input[name = txtPassword ]' : 'password'
	}, true);
	this.echo("ive filled in the fields");
    });
});

// click login button

casper.then(function() {
    this.mouse.click("form input[value=LOGIN]");
    this.echo("clicked");

});

// remove maintenance popup

casper.then(function() {
    this.mouse.click(100, 500);
    this.echo("removed overlay");
/*
      if (this.exists("td.searchLink1")) {
	this.echo("am i in the right frame?");
    } else {
	this.echo("no i'm not, good")
    }
*/
});

// switch to child frame. frame focus only lasts in scope

casper.withFrame("main", function() {
    if (this.exists("td.searchLink1")) {
	this.echo("im in the right frame");
    }
    this.clickLabel("search");
});

// input search term

casper.withFrame("main", function() {
    this.sendKeys("input[class = uiCompanyName]", "apple"); // this should be changed to UEN soon because we don't to retrieve all string matches and pay for each retrieval
    if (this.exists("td#BrowseButton")) {
	this.echo("i can see the search button");
    } else {
	this.echo('dead');
    }
    this.sendKeys("input[class = uiCompanyName]", casper.page.event.key.Enter);
    this.echo("i have clicked");
    // can't access the frame, have to wait the dumb way
    this.wait(2000, function() {
	this.mouse.click(496, 251);
	this.page.sendEvent("keypress", casper.page.event.key.Enter);
	this.echo("done");
    });
    this.wait(2000, function() {
	this.mouse.click(303, 495);
	this.mouse.click(750, 560); // this is for mastercard; after submitting request to finance channel should be able to click on the prepay option
    });
});

// nets payment (not currently working atm)

/*
casper.wait(3000, function() {
    if (this.exists("table:nth-child(2)")) {
	this.echo("hi");
    };
    if (this.exists("input[name=name]")) {
    	this.echo("here");
    };
});
*/

// sometimes search has been made in the last 5 days; questnet will redirect to currently existing order to avoid repayment

/*
casper.withFrame("main", function() {
    this.echo(this.getCurrentUrl());
    this.mouse.click(152, 318);
});

casper.wait(2000, function() {
    this.capture("search.png");
});
*/

// assuming prepay, we redirect to collect orders page

casper.withFrame("top", function() {
    this.clickLabel("COLLECT ORDERS");
    this.waitForSelector("td[class=dptxtblue2bold]", function() {
	this.echo("here");;
    });
});

casper.withFrame("listFrame", function() {
    this.mouse.click("td[class=CF]"); // this should usually work as clicking on the most recent search
    // this.clickLabel("44751373"); // an example of order number contained in that selector
});

casper.withFrame("contentFrame", function() {
    this.waitForSelector("td[class=titleFont1]", function() {
	this.echo("loaded");
    });
});

// scrape desired content

casper.withFrame("contentFrame", function() {
    var info = this.evaluate(function() {
	var nodes = document.querySelectorAll("td[class=DtaFld]");
    });
    require('fs').write("results.json", JSON.stringify(info), "w"); // this is messy, will deal with it on the node side
});

casper.run();
<commit_msg>some cleanup<commit_after>var casper = require('casper').create();
var mouse = require("mouse").create(casper);

// navigate straight to relevant asp page

casper.start('https://www.questnet.sg/Maincontent.asp', function() {
    this.echo("loaded");
});

// select form and input login details

casper.then(function() {
    casper.waitForSelector("form input[name='txtUserID']", function() {
	this.fillSelectors('form', {
            'input[name = txtUserID ]' : casper.cli.args[0],
            'input[name = txtPassword ]' : casper.cli.args[1]
	}, true);
	this.echo("ive filled in the fields");
    });
});

// click login button

casper.then(function() {
    this.mouse.click("form input[value=LOGIN]");
    this.echo("clicked");

});

// remove maintenance popup

casper.then(function() {
    this.mouse.click(100, 500);
    this.echo("removed overlay");
});

// switch to child frame. frame focus only lasts in scope

casper.withFrame("main", function() {
    if (this.exists("td.searchLink1")) {
	this.echo("im in the right frame");
    }
    this.clickLabel("search");
});

// input search term

casper.withFrame("main", function() {
    this.sendKeys("input[class = uiCompanyRegno]", casper.cli.args[2]); // this should be changed to UEN soon because we don't to retrieve all string matches and pay for each retrieval
    this.mouse.click(250, 425);
    this.echo("i have clicked");
    // can't access the frame, have to wait the dumb way
    this.wait(1000, function() {
	this.mouse.click(496, 251);
	this.page.sendEvent("keypress", casper.page.event.key.Enter);
	this.echo("done");
    });
    this.wait(1000, function() {
	this.mouse.click(303, 495);
	this.mouse.click(750, 560); // this is for mastercard; after submitting request to finance channel should be able to click on the prepay option
 });
});

// nets payment is unfeasible because of 2FA, but included here for completeness.

casper.then(function() {
    this.sendKeys('input[name=name]', 'name');
    this.sendKeys('input[name=cardNo]', 'card number');
    this.sendKeys('input[name=cvv]', 'cvv');
    this.evaluate(function() {
        document.querySelector('select[name=expiryMonth]').selectedIndex = 1; // numerical value of the month of expiry
    });
    this.sendKeys('input[name=expiryYear]', 'year of expiry');
    this.click('input[name=agree]');
    // this sends for payment, so commented out
    // this.click('input#submit');
});

casper.then(function() {
    this.capture('results.png');
    this.echo('ive just spent five dollars');
});

// sometimes search has been made in the last 5 days; questnet will redirect to currently existing order to avoid repayment

/*
casper.withFrame("main", function() {
    this.echo(this.getCurrentUrl());
    this.mouse.click(152, 318);
});

casper.wait(2000, function() {
    this.capture("search.png");
});
*/

// assuming prepay, we redirect to collect orders page

casper.withFrame("top", function() {
    this.clickLabel("COLLECT ORDERS");
    this.waitForSelector("td[class=dptxtblue2bold]", function() {
 	this.echo("here");;
    });
});

casper.withFrame("listFrame", function() {
    this.mouse.click("td[class=CF]"); // this should usually work as clicking on the most recent search
    // this.clickLabel("44751373"); // an example of order number contained in that selector
});

casper.withFrame("contentFrame", function() {
    this.waitForSelector("td[class=titleFont1]", function() {
 	this.echo("loaded");
    });
});

// scrape desired content

casper.withFrame("contentFrame", function() {
    var info = this.evaluate(function() {
 	var nodes = document.querySelectorAll("td[class=DtaFld]");
    });
    require('fs').write("results.json", JSON.stringify(info), "w"); // this is messy, will deal with it on the node side
});

casper.run();
<|endoftext|>


<commit_before>define(['js/core/Component', 'srv/core/Handler', 'srv/handler/ExceptionHandler'], function (Component, Handler, ExceptionHandler) {
    return Component.inherit('srv.core.Handlers', {

        getRequestHandler: function(context) {
            var ret;

            for (var i = 0; i < this.$elements.length; i++) {
                var handler = this.$elements[i];
                if (handler instanceof Handler) {
                    try {
                        if (handler.isResponsibleForRequest(context)) {
                            ret = handler.getHandlerInstance();

                            if (!ret) {
                                return this.getHandlerForException(new Error("No handler instance returned for '" + context.request.url + " '." ))
                            }
                        }
                    } catch (e) {
                        return this.getHandlerForException(e);
                    }
                }
            }

            return this.getHandlerForException(new Error("No handler responsible for '" + context.request.url + " '."))
        },

        getHandlerForException: function(e) {
            if (!(e instanceof Error)) {
                e = new Error(e);
            }

            return this.createComponent(ExceptionHandler, {
                exception: e
            });
        }
    })
});<commit_msg>return handler<commit_after>define(['js/core/Component', 'srv/core/Handler', 'srv/handler/ExceptionHandler'], function (Component, Handler, ExceptionHandler) {
    return Component.inherit('srv.core.Handlers', {

        getRequestHandler: function(context) {
            var ret;

            for (var i = 0; i < this.$elements.length; i++) {
                var handler = this.$elements[i];
                if (handler instanceof Handler) {
                    try {
                        if (handler.isResponsibleForRequest(context)) {
                            ret = handler.getHandlerInstance();

                            return ret || this.getHandlerForException(
                                    new Error("No handler instance returned for '" + context.request.url + " '."));

                        }
                    } catch (e) {
                        return this.getHandlerForException(e);
                    }
                }
            }

            return this.getHandlerForException(new Error("No handler responsible for '" + context.request.url + " '."))
        },

        getHandlerForException: function(e) {
            if (!(e instanceof Error)) {
                e = new Error(e);
            }

            return this.createComponent(ExceptionHandler, {
                exception: e
            });
        }
    })
});<|endoftext|>


<commit_before>

let test = require('zopf')
let contains = require('underscore').contains

let os = require('../../app/util/os')

test('os', t => {
  let mock = t.mock(os)

  t.ok(contains(['win32', 'linux', 'darwin'], os.platform()), 'is known')

  mock.expects('platform').returns('win32')
  t.is('windows', os.itch_platform(), 'itch_platform windows')

  mock.expects('platform').returns('linux')
  t.is('linux', os.itch_platform(), 'itch_platform linux')

  mock.expects('platform').returns('darwin')
  t.is('osx', os.itch_platform(), 'itch_platform osx')

  t.is(os.process_type(), 'browser', 'process_type')
  t.is(os.cli_args(), process.argv, 'cli args')

  t.case('check presence', t => {
    return os.check_presence('npm', ['-v'])
  })

  t.case('check absence', t => {
    return t.rejects(os.check_presence('kalamzoo123'))
  })
})
<commit_msg>:green_heart: Fix os spec<commit_after>
let test = require('zopf')
let contains = require('underscore').contains

let os = require('../../app/util/os')

test('os', t => {
  let mock = t.mock(os)

  t.ok(contains(['win32', 'linux', 'darwin'], os.platform()), 'is known')

  mock.expects('platform').returns('win32')
  t.is('windows', os.itch_platform(), 'itch_platform windows')

  mock.expects('platform').returns('linux')
  t.is('linux', os.itch_platform(), 'itch_platform linux')

  mock.expects('platform').returns('darwin')
  t.is('osx', os.itch_platform(), 'itch_platform osx')

  t.is(os.process_type(), 'browser', 'process_type')
  t.is(os.cli_args(), process.argv, 'cli args')

  t.case('check presence', t => {
    return os.check_presence('node', ['-v'])
  })

  t.case('check absence', t => {
    return t.rejects(os.check_presence('kalamzoo123'))
  })
})
<|endoftext|>


<commit_before>/** @babel */
/* global beforeEach, afterEach, describe, it */

import WelcomePackage from '../lib/welcome-package'
import assert from 'assert'
import {conditionPromise} from './helpers'

describe('Welcome', () => {
  let welcomePackage

  beforeEach(() => {
    welcomePackage = new WelcomePackage()
    atom.config.set('welcome.showOnStartup', true)
  })

  afterEach(() => {
    atom.reset()
  })

  describe("when `core.telemetryConsent` is 'undecided'", () => {
    beforeEach(async () => {
      atom.config.set('core.telemetryConsent', 'undecided')
      await welcomePackage.activate()
    })

    it('opens the telemetry consent pane and the welcome panes', () => {
      const panes = atom.workspace.getPanes()
      assert.equal(panes.length, 2)
      assert.equal(panes[0].getItems()[0].getTitle(), 'Telemetry Consent')
      assert.equal(panes[0].getItems()[1].getTitle(), 'Welcome')
      assert.equal(panes[1].getItems()[0].getTitle(), 'Welcome Guide')
    })
  })

  describe('when `core.telemetryConsent` is not `undecided`', () => {
    beforeEach(async () => {
      atom.config.set('core.telemetryConsent', 'no')
      await welcomePackage.activate()
    })

    describe('when activated for the first time', () =>
      it('shows the welcome panes', () => {
        const panes = atom.workspace.getPanes()
        assert.equal(panes.length, 2)
        assert.equal(panes[0].getItems()[0].getTitle(), 'Welcome')
        assert.equal(panes[1].getItems()[0].getTitle(), 'Welcome Guide')
      })
    )

    describe('the welcome:show command', () => {
      it('shows the welcome buffer', async () => {
        atom.workspace.getPanes().map(pane => pane.destroy())
        assert(!atom.workspace.getActivePaneItem())

        const workspaceElement = atom.views.getView(atom.workspace)
        atom.commands.dispatch(workspaceElement, 'welcome:show')

        await conditionPromise(() => atom.workspace.getActivePaneItem())

        const panes = atom.workspace.getPanes()
        assert.equal(panes.length, 2)
        assert.equal(panes[0].getItems()[0].getTitle(), 'Welcome')
      })
    })

    describe('deserializing the pane items', () => {
      describe('when GuideView is deserialized', () => {
        it('remembers open sections', () => {
          const panes = atom.workspace.getPanes()
          const guideView = panes[1].getItems()[0]

          guideView.element.querySelector('details[data-section="snippets"]').setAttribute('open', 'open')
          guideView.element.querySelector('details[data-section="init-script"]').setAttribute('open', 'open')

          const state = guideView.serialize()

          assert.deepEqual(state.openSections, ['init-script', 'snippets'])

          const newGuideView = welcomePackage.createGuideView(state)
          assert(!newGuideView.element.querySelector('details[data-section="packages"]').hasAttribute('open'))
          assert(newGuideView.element.querySelector('details[data-section="snippets"]').hasAttribute('open'))
          assert(newGuideView.element.querySelector('details[data-section="init-script"]').hasAttribute('open'))
        })
      })
    })

    describe('reporting events', () => {
      let panes, guideView, reportedEvents
      beforeEach(() => {
        panes = atom.workspace.getPanes()
        guideView = panes[1].getItems()[0]
        reportedEvents = []

        welcomePackage.reporterProxy.sendEvent = (...event) => { reportedEvents.push(event) }
      })

      describe('GuideView events', () => {
        it('captures expand and collapse events', () => {
          guideView.element.querySelector('details[data-section="packages"] summary').click()
          assert.deepEqual(reportedEvents, [['expand-packages-section']])

          guideView.element.querySelector('details[data-section="packages"]').setAttribute('open', 'open')
          guideView.element.querySelector('details[data-section="packages"] summary').click()
          assert.deepEqual(reportedEvents, [['expand-packages-section'], ['collapse-packages-section']])
        })

        it('captures button events', () => {
          for (const detailElement of Array.from(guideView.element.querySelector('details'))) {
            reportedEvents.length = 0

            const sectionName = detailElement.dataset.section
            const eventName = `clicked-${sectionName}-cta`
            const primaryButton = detailElement.querySelector('.btn-primary')
            if (primaryButton) {
              primaryButton.click()
              assert.deepEqual(reportedEvents, [[eventName]])
            }
          }
        })
      })
    })

    describe('when the reporter changes', () =>
      it('sends all queued events', () => {
        welcomePackage.reporterProxy.queue.length = 0

        const reporter1 = {sendEvent (...event) { this.reportedEvents.push(event) }, reportedEvents: []}
        const reporter2 = {sendEvent (...event) { this.reportedEvents.push(event) }, reportedEvents: []}

        welcomePackage.reporterProxy.sendEvent('foo', 'bar', 'baz')
        welcomePackage.reporterProxy.sendEvent('foo2', 'bar2', 'baz2')
        welcomePackage.reporterProxy.setReporter(reporter1)

        assert.deepEqual(reporter1.reportedEvents, [
          ['welcome-v1', 'foo', 'bar', 'baz'],
          ['welcome-v1', 'foo2', 'bar2', 'baz2']
        ])

        welcomePackage.consumeReporter(reporter2)

        assert.deepEqual(reporter2.reportedEvents, [])
      })
    )
  })
})
<commit_msg>Update tests to support new WorkspaceCenter API<commit_after>/** @babel */
/* global beforeEach, afterEach, describe, it */

import WelcomePackage from '../lib/welcome-package'
import assert from 'assert'
import {conditionPromise} from './helpers'

describe('Welcome', () => {
  let welcomePackage

  beforeEach(() => {
    welcomePackage = new WelcomePackage()
    atom.config.set('welcome.showOnStartup', true)
  })

  afterEach(() => {
    atom.reset()
  })

  describe("when `core.telemetryConsent` is 'undecided'", () => {
    beforeEach(async () => {
      atom.config.set('core.telemetryConsent', 'undecided')
      await welcomePackage.activate()
    })

    it('opens the telemetry consent pane and the welcome panes', () => {
      const panes = atom.workspace.getCenter().getPanes()
      assert.equal(panes.length, 2)
      assert.equal(panes[0].getItems()[0].getTitle(), 'Telemetry Consent')
      assert.equal(panes[0].getItems()[1].getTitle(), 'Welcome')
      assert.equal(panes[1].getItems()[0].getTitle(), 'Welcome Guide')
    })
  })

  describe('when `core.telemetryConsent` is not `undecided`', () => {
    beforeEach(async () => {
      atom.config.set('core.telemetryConsent', 'no')
      await welcomePackage.activate()
    })

    describe('when activated for the first time', () =>
      it('shows the welcome panes', () => {
        const panes = atom.workspace.getCenter().getPanes()
        assert.equal(panes.length, 2)
        assert.equal(panes[0].getItems()[0].getTitle(), 'Welcome')
        assert.equal(panes[1].getItems()[0].getTitle(), 'Welcome Guide')
      })
    )

    describe('the welcome:show command', () => {
      it('shows the welcome buffer', async () => {
        atom.workspace.getCenter().getPanes().map(pane => pane.destroy())
        assert(!atom.workspace.getActivePaneItem())

        const workspaceElement = atom.views.getView(atom.workspace)
        atom.commands.dispatch(workspaceElement, 'welcome:show')

        await conditionPromise(() => atom.workspace.getActivePaneItem())

        const panes = atom.workspace.getCenter().getPanes()
        assert.equal(panes.length, 2)
        assert.equal(panes[0].getItems()[0].getTitle(), 'Welcome')
      })
    })

    describe('deserializing the pane items', () => {
      describe('when GuideView is deserialized', () => {
        it('remembers open sections', () => {
          const panes = atom.workspace.getCenter().getPanes()
          const guideView = panes[1].getItems()[0]

          guideView.element.querySelector('details[data-section="snippets"]').setAttribute('open', 'open')
          guideView.element.querySelector('details[data-section="init-script"]').setAttribute('open', 'open')

          const state = guideView.serialize()

          assert.deepEqual(state.openSections, ['init-script', 'snippets'])

          const newGuideView = welcomePackage.createGuideView(state)
          assert(!newGuideView.element.querySelector('details[data-section="packages"]').hasAttribute('open'))
          assert(newGuideView.element.querySelector('details[data-section="snippets"]').hasAttribute('open'))
          assert(newGuideView.element.querySelector('details[data-section="init-script"]').hasAttribute('open'))
        })
      })
    })

    describe('reporting events', () => {
      let panes, guideView, reportedEvents
      beforeEach(() => {
        panes = atom.workspace.getCenter().getPanes()
        guideView = panes[1].getItems()[0]
        reportedEvents = []

        welcomePackage.reporterProxy.sendEvent = (...event) => { reportedEvents.push(event) }
      })

      describe('GuideView events', () => {
        it('captures expand and collapse events', () => {
          guideView.element.querySelector('details[data-section="packages"] summary').click()
          assert.deepEqual(reportedEvents, [['expand-packages-section']])

          guideView.element.querySelector('details[data-section="packages"]').setAttribute('open', 'open')
          guideView.element.querySelector('details[data-section="packages"] summary').click()
          assert.deepEqual(reportedEvents, [['expand-packages-section'], ['collapse-packages-section']])
        })

        it('captures button events', () => {
          for (const detailElement of Array.from(guideView.element.querySelector('details'))) {
            reportedEvents.length = 0

            const sectionName = detailElement.dataset.section
            const eventName = `clicked-${sectionName}-cta`
            const primaryButton = detailElement.querySelector('.btn-primary')
            if (primaryButton) {
              primaryButton.click()
              assert.deepEqual(reportedEvents, [[eventName]])
            }
          }
        })
      })
    })

    describe('when the reporter changes', () =>
      it('sends all queued events', () => {
        welcomePackage.reporterProxy.queue.length = 0

        const reporter1 = {sendEvent (...event) { this.reportedEvents.push(event) }, reportedEvents: []}
        const reporter2 = {sendEvent (...event) { this.reportedEvents.push(event) }, reportedEvents: []}

        welcomePackage.reporterProxy.sendEvent('foo', 'bar', 'baz')
        welcomePackage.reporterProxy.sendEvent('foo2', 'bar2', 'baz2')
        welcomePackage.reporterProxy.setReporter(reporter1)

        assert.deepEqual(reporter1.reportedEvents, [
          ['welcome-v1', 'foo', 'bar', 'baz'],
          ['welcome-v1', 'foo2', 'bar2', 'baz2']
        ])

        welcomePackage.consumeReporter(reporter2)

        assert.deepEqual(reporter2.reportedEvents, [])
      })
    )
  })
})
<|endoftext|>


<commit_before>var JsonRules = require('../index').JsonRules;
var FnCatalog = require('../index').FnCatalog;
var assert = require("assert");
var _ = require('underscore');

var exampleRule = {
  ifs : [
    { operands: [ '_object.temp', '_object.setTemp'],
      test: '<',
    },
    { operands: [ '_object.relay', {_value: 1}],
      test: '==',
    },
  ],
  then:
    {
      _catalog : {name: 'setTemp',
                  args: ['_object.setTemp']}
    }
};

var ifs = exampleRule.ifs;
var then = exampleRule.then;
var value1= {temp: 60, setTemp: 70, relay: 1};
var value2= {temp: 71, setTemp: 70, relay: 1};

describe("Json Rules Constructor", function(){
  it("return a function", function(done){
    var ruleEngine = new JsonRules();
    assert.ok(ruleEngine);
    done();
  });
});

describe("JsonRules._testIf", function(){
  it("tests an individual if statement,  returns (null,true) if true", function(done){
    var ruleEngine = new JsonRules();
    ruleEngine._testIf(ifs[0], value1, function(err, results){
      assert.equal(err, null);
      done();
    });
  });
  it("tests an individual if statement,  returns (\"error\",null) if false", function(done){
    var ruleEngine = new JsonRules();
    ruleEngine._testIf(ifs[0], value2, function(err, results){
      assert.equal(err, "error");
      done();
    });
  });
});
describe("JsonRules.test", function(){
  it("tests an array of if statements, and callbacks true if they pass", function(done){
    var ruleEngine = new JsonRules();
    ruleEngine.test(ifs, value1, function(result){
      assert.equal(result, true);
      done();
    });
  });
  it("tests an array of if statements, and callbacks false if they fail", function(done){
    var ruleEngine = new JsonRules();
    ruleEngine.test(ifs, value2, function(result){
      assert.equal(result, false);
      done();
    });
  });
});
describe("JsonRules.doRule", function(){
  it("tests a rule, and callbacks with fn if it passes", function(done){
    var exampleThen = function(word){return "example"}
    var catalog = new FnCatalog();
    catalog.addFn(exampleThen, 'setTemp', this);
    var ruleEngine = new JsonRules({catalog: catalog});
    ruleEngine.doRule(exampleRule, value1, function(err, fn){
      if(fn){
      assert.equal(fn(), exampleThen());
      done();
      }else
      done('error');
    });
  });
  it("tests a rule, and callback with no fn if it fails ", function(done){
    var exampleThen = function(word){return "example"}
    var catalog = new FnCatalog();
    catalog.addFn(exampleThen, 'setTemp', this);
    var ruleEngine = new JsonRules({catalog: catalog});
    ruleEngine.doRule(exampleRule, value2, function(err, fn){
      assert.equal(fn, null);
      done();
    });
  });
});

<commit_msg>added 2 test cases for async catalog fns<commit_after>var JsonRules = require('../index').JsonRules;
var FnCatalog = require('../index').FnCatalog;
var assert = require("assert");
var _ = require('underscore');

var exampleRule = {
  ifs : [
    { operands: [ '_object.temp', '_object.setTemp'],
      test: '<',
    },
    { operands: [ '_object.relay', {_value: 1}],
      test: '==',
    },
  ],
  then:
    {
      _catalog : {name: 'setTemp',
                  args: ['_object.setTemp']}
    }
};

var ifs = exampleRule.ifs;
var then = exampleRule.then;
var value1= {temp: 60, setTemp: 70, relay: 1};
var value2= {temp: 71, setTemp: 70, relay: 1};

var catalogOperandRule = {
  ifs : [
    { operands: [ '_object.temp', '_object.setTemp'],
      test: '<',
    },
    { operands: [ '_object.relay', {_catalog: {name: 'getOtherSensorByUserId',
                                               args: [{_value: '1234'}, {_value :1000}]}},
                ],
      test: '=='
    },
  ],
  then:
    {
      _catalog : {name: 'setTemp',
                  args: ['_object.temp']}
    }
};

var shortCircuitRule = {
  ifs : [
    { operands: [ '_object.relay', {_catalog: {name: 'getOtherSensorByUserId',
                                               args: [{_value: '1234'}, {_value :5000}]}},
                ],
      test: '=='
    },
    { operands: [ '_object.relay', {_catalog: {name: 'getOtherSensorByUserId',
                                               args: [{_value: '1233'}, {_value :1000}]}},
                ],
      test: '=='
    },
  ],
  then:
    {
      _catalog : {name: 'setTemp',
                  args: ['_object.temp']}
    }
};

var getOtherSensorByUserId = function(userid, timeout,cb){
  setTimeout(function(){
    if(userid === '1234')
       cb(null, 1);
    else
      cb(null, false);
  }, timeout);
};

describe("Json Rules Constructor", function(){
  it("return a function", function(done){
    var ruleEngine = new JsonRules();
    assert.ok(ruleEngine);
    done();
  });
});

describe("JsonRules._testIf", function(){
  it("tests an individual if statement,  returns (null,true) if true", function(done){
    var ruleEngine = new JsonRules();
    ruleEngine._testIf(ifs[0], value1, function(err, results){
      assert.equal(err, null);
      done();
    });
  });
  it("tests an individual if statement,  returns (\"error\",null) if false", function(done){
    var ruleEngine = new JsonRules();
    ruleEngine._testIf(ifs[0], value2, function(err, results){
      assert.equal(err, "error");
      done();
    });
  });
});
describe("JsonRules.test", function(){
  it("tests an array of if statements, and callbacks true if they pass", function(done){
    var ruleEngine = new JsonRules();
    ruleEngine.test(ifs, value1, function(result){
      assert.equal(result, true);
      done();
    });
  });
  it("tests an array of if statements, and callbacks false if they fail", function(done){
    var ruleEngine = new JsonRules();
    ruleEngine.test(ifs, value2, function(result){
      assert.equal(result, false);
      done();
    });
  });
});
describe("JsonRules.doRule", function(){
  it("tests a rule, and callbacks with fn if it passes", function(done){
    var exampleThen = function(word){return "example"}
    var catalog = new FnCatalog();
    catalog.addFn(exampleThen, 'setTemp', this);
    var ruleEngine = new JsonRules({catalog: catalog});
    ruleEngine.doRule(exampleRule, value1, function(err, fn){
      if(fn){
      assert.equal(fn(), exampleThen());
      done();
      }else
      done('error');
    });
  });
  it("tests a rule, and callback with no fn if it fails ", function(done){
    var exampleThen = function(word){return "example"}
    var catalog = new FnCatalog();
    catalog.addFn(exampleThen, 'setTemp', this);
    var ruleEngine = new JsonRules({catalog: catalog});
    ruleEngine.doRule(exampleRule, value2, function(err, fn){
      assert.equal(fn, null);
      done();
    });
  });
  it("tests a rule with an catalog attribute and returns fn because it passes ", function(done){
    this.timeout(1200);
    var exampleThen = function(word){return "example"}
    var catalog = new FnCatalog();
    catalog.addFn(exampleThen, 'setTemp', this);
    catalog.addFn(getOtherSensorByUserId, 'getOtherSensorByUserId', this);
    var ruleEngine = new JsonRules({catalog: catalog});
    ruleEngine.doRule(catalogOperandRule, value1, function(err, fn){
      if(fn){
        assert.equal(fn(), exampleThen());
        done();
      }else{
        throw("Should have received Then but didn't");
      }
    });
  });
  it("tests a rule with an catalog attribute and returns a null fn after the first false if statement fails", function(done){
    this.timeout(1200);
    var exampleThen = function(word){return "example"}
    var catalog = new FnCatalog();
    catalog.addFn(exampleThen, 'setTemp', this);
    catalog.addFn(getOtherSensorByUserId, 'getOtherSensorByUserId', this);
    var ruleEngine = new JsonRules({catalog: catalog});
    ruleEngine.doRule(shortCircuitRule, value1, function(err, fn){
      if(fn){
        throw("Shouldn't have returned a function");
      }else{
        done();
      }
    });
  });
});

<|endoftext|>


<commit_before>function DotManager() {
	this.lists = {ALLDOTS:[]};
	this.spcLists = {};
	this.count = 0;
}

DotManager.prototype = {
//start public funcs
	add: function(dot) {//can send as list or single dot
		if (dot instanceof Array) {
			this.count += dot.length;
		} else {
			this.count ++;
		}
		this.execAllCombos(this.addFunc, dot);
	},
	remove: function(dot) {//can send as list or single dot
		if (dot instanceof Array) {
			this.count -= dot.length;
			for (var dotIdx=0; dotIdx<dot.length;dotIdx++) {
				dot[dotIdx].kill();
			}
		} else {
			this.count --;
			dot.kill();
		}
	},
	removeByAttr: function(attr, val) {
		var dots = this.lists.ALLDOTS;
		for (var i=dots.length-1; i>=0; i--) {
			if (dots[i][attr] == val) dots[i].kill();
		}
	},
	changeDotSpc: function(dots, newSpcName) {//can send as list or single dot
		if (!(dots instanceof Array)) dots = [dots];
		var def = spcs[newSpcName];
		for (var dotIdx=0; dotIdx<dots.length; dotIdx++) {
			var dot = dots[dotIdx];
			var tempF = (dot.hF298 - (def.hF298 * 1000 / N) + dot.cv * (dot.temp() - 298.15)) / (def.cv / N) + 298.15;
			if (tempF > 0) {
				for (var parentListIdx=0; parentListIdx<dot.parentLists.length; parentListIdx++) {
					dot.parentLists[parentListIdx].splice(dot.parentLists[parentListIdx].indexOf(dot), 1);
				}
				dot.parentLists = [];
				dot.m = def.m;
				dot.r = def.r;
				dot.col = def.col;
				dot.spcName = def.spcName;
				dot.hF298 = def.hF298 * 1000 / N;
				dot.hVap298 = def.hVap298 * 1000 / N;
				dot.idNum = def.idNum;
				dot.cvKinetic = 1.5 * R / N;
				dot.cv = def.cv / N;
				dot.cp = dot.cv + R;
				dot.cpLiq = def.cpLiq / N;
				dot.spcVolLiq = def.spcVolLiq / N;
				dot.setTempNoReference(tempF);

				var newLists = this.getRelevantLists(dot);
				for (var newListIdx=0; newListIdx<newLists.length; newListIdx++) {
					dot.parentLists.push(newLists[newListIdx]);
					dot.parentLists[dot.parentLists.length - 1].push(dot);
				}
			}
		}

	},
	addSpcs: function(name) {
		if (!this.lists[name]) {
			this.lists[name] = [];
			this.spcLists[name] = this.lists[name];
		}
		return this.lists[name];
	},
	removeByInfo: function(info) {
		if (info.spcName && info.tag) {
			this.execAllCombos(this.removeByNameAndTagFunc, info);
		} else if (info.spcName){
			this.execAllCombos(this.removeByNameFunc, info);
		} else if (info.tag) {
			this.execAllCombos(this.removeByTagFunc, info);
		} else {
			console.log('No useful info given to removeByInfo func in DotManager');
			console.trace();
		}
	},
	getWithLog: function(info) {
		var gotten = this.get(info);
		if (gotten) {
			return gotten
		} else {
			console.log('Bad species data');
			console.log(info);
		}
	},
	get: function(info) {
		return this.createIfNotExists(info);
		// if (info) {
			// if (info.spcName && info.tag) {
				// return this.lists[info.spcName + '-' + info.tag];
			// } else if (info.spcName) {
				// return this.lists[info.spcName];
			// } else if (info.tag) {
				// return this.lists[info.tag];
			// }
		// } else {
			// return this.lists.ALLDOTS;
		// }
	},
	clearAll: function() {
		for (var list in this.lists) {
			this.lists[list].splice(0, this.lists[list].length);
		}
	},
	createIfNotExists: function(info) {
		if (info) {
			if (info.spcName && info.tag) {
				return this.getByNameAndTag(info);
			} else if (info.spcName) {
				return this.getByName(info.spcName);
			} else if (info.tag) {
				return this.getByTag(info.tag);
			}
		} else {
			return this.lists.ALLDOTS;
		}
	},

//end public funcs
	addFunc: function(list, dot) {
		list.push(dot);
		dot.parentLists.push(list);
	},
	removeFunc: function(list, dot) {
		var idx = list.indexOf(dot);
		if (idx>-1) {
			list.splice(idx, 1);
			dot.parentLists.splice(dot.parentLists.indexOf(list), 1);
		} else {
			console.log('Tried to remove dot from global list of spcName ' + dot.spcName + ' and tag ' + dot.tag + '. Dot not present.');
			console.trace();
		}
	},
	removeByNameAndTagFunc: function(list, info) {
		for (var dotIdx=list.length-1; dotIdx>-1; dotIdx--) {
			if (list[dotIdx].spcName==info.spcName && list[dotIdx].tag==info.tag) {
				list[dotIdx].kill();
			}
		}
	},
	removeByNameFunc: function(list, info) {
		for (var dotIdx=list.length-1; dotIdx>-1; dotIdx--) {
			if (list[dotIdx].spcName==info.spcName) {
				list.splice(dotIdx, 1);
				list[dotIdx].kill();
			}
		}
	},
	removeByNameAndTagFunc: function(list, info) {
		for (var dotIdx=list.length-1; dotIdx>-1; dotIdx--) {
			if (list[dotIdx].tag==info.tag) {
				list.splice(dotIdx, 1);
				list[dotIdx].kill();
			}
		}
	},
	execAllCombos: function(listFunc, dot) {
		if (dot instanceof Array && dot.length) {
			var dots = dot;
			var info = {spcName: dots[0].spcName, tag: dots[0].tag};
		} else {
			var info = dot;
		}
		var lists = this.getRelevantLists(info);
		if (dots) {
			for (var dotIdx=0; dotIdx<dots.length; dotIdx++) {
				this.execFuncOnLists(listFunc, lists, dots[dotIdx]);
			}
		} else if (dot instanceof Dot) {
			this.execFuncOnLists(listFunc, lists, dot);
		}
	},
	execFuncOnLists: function(func, lists, dot) {
		dot.active = true;
		for (var listIdx=0; listIdx<lists.length; listIdx++) {
			func(lists[listIdx], dot);
		}
	},
	getRelevantLists: function(info) {
		var lists = [];
		lists.push(this.lists.ALLDOTS);
		if (info.spcName && info.tag) {
			lists.push(this.getByNameAndTag(info));
		}
		if (info.spcName) {
			lists.push(this.getByName(info.spcName));
		}
		if (info.tag) {
			lists.push(this.getByTag(info.tag));
		}
		return lists;
	},

	getByNameAndTag: function(info) {
		if (this.lists[info.spcName + '-' + info.tag]) {
			return this.lists[info.spcName + '-' + info.tag];
		} else if (spcs[spcName]) {
			this.lists[info.spcName + '-' + info.tag] = [];
			return this.lists[info.spcName + '-' + info.tag];
		} else {
			console.log('Tried to get bad spcName ' + spcName);
			console.trace();
		}
	},
	getByName: function(spcName) {
		if (this.lists[spcName]) {
			return this.lists[spcName];
		} else if (spcs[spcName]) {
			this.lists[spcName] = [];
			return this.lists[spcName];
		} else {
			console.log('Tried to get bad spcName ' + spcName);
			console.trace();
		}
	},
	getByTag: function(tag) {
		if (this.lists[tag]){
			return this.lists[tag];
		} else {
			this.lists[tag] = [];
			return this.lists[tag];
		}
	},

}<commit_msg>little bug fix<commit_after>function DotManager() {
	this.lists = {ALLDOTS:[]};
	this.spcLists = {};
	this.count = 0;
}

DotManager.prototype = {
//start public funcs
	add: function(dot) {//can send as list or single dot
		if (dot instanceof Array) {
			this.count += dot.length;
		} else {
			this.count ++;
		}
		this.execAllCombos(this.addFunc, dot);
	},
	remove: function(dot) {//can send as list or single dot
		if (dot instanceof Array) {
			this.count -= dot.length;
			for (var dotIdx=0; dotIdx<dot.length;dotIdx++) {
				dot[dotIdx].kill();
			}
		} else {
			this.count --;
			dot.kill();
		}
	},
	removeByAttr: function(attr, val) {
		var dots = this.lists.ALLDOTS;
		for (var i=dots.length-1; i>=0; i--) {
			if (dots[i][attr] == val) dots[i].kill();
		}
	},
	changeDotSpc: function(dots, newSpcName) {//can send as list or single dot
		if (!(dots instanceof Array)) dots = [dots];
		var def = spcs[newSpcName];
		for (var dotIdx=0; dotIdx<dots.length; dotIdx++) {
			var dot = dots[dotIdx];
			var tempF = (dot.hF298 - (def.hF298 * 1000 / N) + dot.cv * (dot.temp() - 298.15)) / (def.cv / N) + 298.15;
			if (tempF > 0) {
				for (var parentListIdx=0; parentListIdx<dot.parentLists.length; parentListIdx++) {
					dot.parentLists[parentListIdx].splice(dot.parentLists[parentListIdx].indexOf(dot), 1);
				}
				dot.parentLists = [];
				dot.m = def.m;
				dot.r = def.r;
				dot.col = def.col;
				dot.spcName = def.spcName;
				dot.hF298 = def.hF298 * 1000 / N;
				dot.hVap298 = def.hVap298 * 1000 / N;
				dot.idNum = def.idNum;
				dot.cvKinetic = 1.5 * R / N;
				dot.cv = def.cv / N;
				dot.cp = dot.cv + R;
				dot.cpLiq = def.cpLiq / N;
				dot.spcVolLiq = def.spcVolLiq / N;
				dot.setTempNoReference(tempF);

				var newLists = this.getRelevantLists(dot);
				for (var newListIdx=0; newListIdx<newLists.length; newListIdx++) {
					dot.parentLists.push(newLists[newListIdx]);
					dot.parentLists[dot.parentLists.length - 1].push(dot);
				}
			}
		}

	},
	addSpcs: function(name) {
		if (!this.lists[name]) {
			this.lists[name] = [];
			this.spcLists[name] = this.lists[name];
		}
		return this.lists[name];
	},
	removeByInfo: function(info) {
		if (info.spcName && info.tag) {
			this.execAllCombos(this.removeByNameAndTagFunc, info);
		} else if (info.spcName){
			this.execAllCombos(this.removeByNameFunc, info);
		} else if (info.tag) {
			this.execAllCombos(this.removeByTagFunc, info);
		} else {
			console.log('No useful info given to removeByInfo func in DotManager');
			console.trace();
		}
	},
	getWithLog: function(info) {
		var gotten = this.get(info);
		if (gotten) {
			return gotten
		} else {
			console.log('Bad species data');
			console.log(info);
		}
	},
	get: function(info) {
		return this.createIfNotExists(info);
		// if (info) {
			// if (info.spcName && info.tag) {
				// return this.lists[info.spcName + '-' + info.tag];
			// } else if (info.spcName) {
				// return this.lists[info.spcName];
			// } else if (info.tag) {
				// return this.lists[info.tag];
			// }
		// } else {
			// return this.lists.ALLDOTS;
		// }
	},
	clearAll: function() {
		for (var list in this.lists) {
			this.lists[list].splice(0, this.lists[list].length);
		}
	},
	createIfNotExists: function(info) {
		if (info) {
			if (info.spcName && info.tag) {
				return this.getByNameAndTag(info);
			} else if (info.spcName) {
				return this.getByName(info.spcName);
			} else if (info.tag) {
				return this.getByTag(info.tag);
			}
		} else {
			return this.lists.ALLDOTS;
		}
	},

//end public funcs
	addFunc: function(list, dot) {
		list.push(dot);
		dot.parentLists.push(list);
	},
	removeFunc: function(list, dot) {
		var idx = list.indexOf(dot);
		if (idx>-1) {
			list.splice(idx, 1);
			dot.parentLists.splice(dot.parentLists.indexOf(list), 1);
		} else {
			console.log('Tried to remove dot from global list of spcName ' + dot.spcName + ' and tag ' + dot.tag + '. Dot not present.');
			console.trace();
		}
	},
	removeByNameAndTagFunc: function(list, info) {
		for (var dotIdx=list.length-1; dotIdx>-1; dotIdx--) {
			if (list[dotIdx].spcName==info.spcName && list[dotIdx].tag==info.tag) {
				list[dotIdx].kill();
			}
		}
	},
	removeByNameFunc: function(list, info) {
		for (var dotIdx=list.length-1; dotIdx>-1; dotIdx--) {
			if (list[dotIdx].spcName==info.spcName) {
				list.splice(dotIdx, 1);
				list[dotIdx].kill();
			}
		}
	},
	removeByNameAndTagFunc: function(list, info) {
		for (var dotIdx=list.length-1; dotIdx>-1; dotIdx--) {
			if (list[dotIdx].tag==info.tag) {
				list.splice(dotIdx, 1);
				list[dotIdx].kill();
			}
		}
	},
	execAllCombos: function(listFunc, dot) {
		if (dot instanceof Array && dot.length) {
			var dots = dot;
			var info = {spcName: dots[0].spcName, tag: dots[0].tag};
		} else {
			var info = dot;
		}
		var lists = this.getRelevantLists(info);
		if (dots) {
			for (var dotIdx=0; dotIdx<dots.length; dotIdx++) {
				this.execFuncOnLists(listFunc, lists, dots[dotIdx]);
			}
		} else if (dot instanceof Dot) {
			this.execFuncOnLists(listFunc, lists, dot);
		}
	},
	execFuncOnLists: function(func, lists, dot) {
		dot.active = true;
		for (var listIdx=0; listIdx<lists.length; listIdx++) {
			func(lists[listIdx], dot);
		}
	},
	getRelevantLists: function(info) {
		var lists = [];
		lists.push(this.lists.ALLDOTS);
		if (info.spcName && info.tag) {
			lists.push(this.getByNameAndTag(info));
		}
		if (info.spcName) {
			lists.push(this.getByName(info.spcName));
		}
		if (info.tag) {
			lists.push(this.getByTag(info.tag));
		}
		return lists;
	},

	getByNameAndTag: function(info) {
		if (this.lists[info.spcName + '-' + info.tag]) {
			return this.lists[info.spcName + '-' + info.tag];
		} else if (spcs[info.spcName]) {
			this.lists[info.spcName + '-' + info.tag] = [];
			return this.lists[info.spcName + '-' + info.tag];
		} else {
			console.log('Tried to get bad spcName ' + spcName);
			console.trace();
		}
	},
	getByName: function(spcName) {
		if (this.lists[spcName]) {
			return this.lists[spcName];
		} else if (spcs[spcName]) {
			this.lists[spcName] = [];
			return this.lists[spcName];
		} else {
			console.log('Tried to get bad spcName ' + spcName);
			console.trace();
		}
	},
	getByTag: function(tag) {
		if (this.lists[tag]){
			return this.lists[tag];
		} else {
			this.lists[tag] = [];
			return this.lists[tag];
		}
	},

}<|endoftext|>


<commit_before>import CESModule from './core/CESModule';
import dom from '../utils/dom';

export default class HideProfileCSS extends CESModule {
  constructor () {
    super();
    this.conditions = {
      isPage: ['profile']
    };
  }

  go () {
    this.style = dom.get('style');
    this.head = dom.get('head');
    this.addWindowListeners();
  }

  addWindowListeners () {
    dom.window.on('disable-css', this.removeStyle.bind(this));
    dom.window.on('enable-css', this.appendStyle.bind(this));
  }

  removeStyle () {
    this.style.remove();
  }

  appendStyle () {
    this.head.append(this.style);
  }

}
<commit_msg>Refactor profile css module with new storage/messenger utilities<commit_after>import CESModule from './core/CESModule';
import dom from '../utils/dom';
import messenger from '../utils/messenger';
import storage from '../utils/storage';
import initData from '../utils/initData';

export default class HideProfileCSS extends CESModule {
  constructor () {
    super();
    this.conditions = {
      isPage: ['profile']
    };
  }

  go () {
    storage.get('disabledProfiles')
    .then(profiles => {
      return new Set(profiles);
    }, () => {
      return new Set();
    }).then((profiles) => {
      this.initWithProfiles(profiles);
    });
  }

  initWithProfiles (profiles) {
    this.disabledProfiles = profiles;
    this.profile = initData.__profiled.username;
    this.style = dom.get('style');
    this.head = dom.get('head');
    this.addRuntimeListeners();
  }

  addRuntimeListeners () {
    messenger.on('disable-profile-css', (isDisabled) => {
      if (isDisabled) {
        this.removeStyle();
        this.addToDisabledProfiles();
      } else {
        this.appendStyle();
        this.removeFromDisabledProfiles();
      }
    });
  }

  removeFromDisabledProfiles () {
    const { profile, disabledProfiles } = this;
    disabledProfiles.delete(profile);
    this.saveProfilesToStorage(disabledProfiles);
  }

  addToDisabledProfiles () {
    const { profile, disabledProfiles } = this;
    disabledProfiles.add(profile);
    this.saveProfilesToStorage(disabledProfiles);
  }

  saveProfilesToStorage () {
    const { disabledProfiles } = this;
    storage.set('disabledProfiles', [...disabledProfiles]);
  }

  removeStyle () {
    this.style.remove();
  }

  appendStyle () {
    this.head.append(this.style);
  }

}
<|endoftext|>


<commit_before>$.ajax($('#juicer-summary-item')
	.data('juicer-summary-item-url'))
	.done(function (data) {
		$('#juicer-summary-item')
			.removeClass('icon-spinner')
			.addClass('icon-site')
			.append(data);
	});
<commit_msg>Fix indentation.<commit_after>$.ajax($('#juicer-summary-item').data('juicer-summary-item-url'))
	.done(function (data) {
		$('#juicer-summary-item')
			.removeClass('icon-spinner')
			.addClass('icon-site')
			.append(data);
	});
<|endoftext|>


<commit_before>const https = require('https');

const axios = require('axios');
const _ = require('lodash');
const parse = require('docker-parse-image');

function nonSecureRequest(url, options) {
  const nonSecureOptions = _.merge(options, {
    httpsAgent: new https.Agent({ rejectUnauthorized: false }),
  });
  return axios.get(url, nonSecureOptions);
}

/**
 * Query registry server for authentication info.
 *
 * @private
 * @param {string} registryUrl URL for the registry to get authentication info.
 * @param {Object} parsedImage Object with the parsed image name
 * @param {Object} options Options for axios to use
 * @returns {Object} Authentication info for the requested registry and image.
 * @throws Will throw an error if authentication info can't be parsed or the realm is unreachable.
 */
async function getAuthenticationInfo(image, options = null) {
  // parse image string to determine registry url
  let registryUrl = '';
  const parsedImage = parse(image);
  if (parsedImage.registry) {
    registryUrl = `https://${parsedImage.registry}/v2/`;
  } else {
    registryUrl = 'https://registry-1.docker.io/v2/';
  }

  // options passed to axios
  const queryOptions = {
    ...options.requestOptions,
    validateStatus: status => status === 401,
  };

  // add authentication info if provided
  if (options.auth) {
    queryOptions.auth = options.auth;
  }

  try {
    // await axios get request, this will be a 401 response and the registry
    // will provide info required to get an authentication token
    const realmResponse = await axios.get(registryUrl, queryOptions);

    // parse auth response for the realm and service params provided by
    // registry
    const authInfo = {};
    if (realmResponse.headers['www-authenticate']) {
      const re = /Bearer realm="(.*)",service="(.*)"/i;
      const found = realmResponse.headers['www-authenticate'].match(re);
      if (found) {
        [, authInfo.realm, authInfo.service] = found;
      }
    } else {
      throw new Error("Can't get authentication info for registry.");
    }

    // use the realm and service info to get an auth token from the registry
    const tokenOptions = {
      ...options.requestOptions,
      params: {
        service: authInfo.service,
        scope: `repository:${parsedImage.namespace ? `${parsedImage.namespace}/` : 'library/'}${parsedImage.repository}:pull`,
      },
    };

    // add authentication info if provided
    if (options.auth) {
      tokenOptions.auth = options.auth;
    }

    // await axios get request, response should contain the auth token
    const tokenResponse = await axios.get(authInfo.realm, tokenOptions);

    if (!tokenResponse.data.token) {
      throw new Error("Can't get authentication token from registry.");
    }

    return {
      ...authInfo,
      token: tokenResponse.data.token,
    };
  } catch (error) {
    console.log('in getAuthenticationInfo: ', error.message);
  }
}

/**
 * Query the registry server for the manifest info on a docker image.
 * @private
 */
function getManifest(options) {
  const authOptions = {};
  authOptions.params = options.token.params;
  if (options.token.auth) {
    authOptions.auth = options.token.auth;
  }

  let authPromise;
  if (options.nonSecure) {
    authPromise = nonSecureRequest(options.token.url, authOptions);
  } else {
    authPromise = axios.get(options.token.url, authOptions);
  }

  return authPromise
    .then((tokenResponse) => {
      const repoOptions = {
        headers: {
          Authorization: `Bearer ${tokenResponse.data.token}`,
        },
      };

      let repoPromise;
      if (options.nonSecure) {
        repoPromise = nonSecureRequest(options.repository.url, repoOptions);
      } else {
        repoPromise = axios.get(options.repository.url, repoOptions);
      }

      return repoPromise
        .then(repoResponse => repoResponse.data)
        .catch((error) => {
        // console.log(error.response.data);
          console.log(error.response.status);
          console.log(error.response.headers);
        });
    });
}

/**
 * Get manifest info for a docker image.
 * @param {string} image The name of the image. Example: "alpine:latest".
 * @param {Object} options Request options passed to axios.
 */
async function getImageManifest(image, options = null) {
  // get an oauth token for the registry
  const authInfo = await getAuthenticationInfo(image, options);
  console.log(authInfo);

  // const manifest = await getManifest(options);

  // return manifest;
}

module.exports.getImageManifest = getImageManifest;
<commit_msg>refactor to use async/await<commit_after>const https = require('https');

const axios = require('axios');
const dockerParseImage = require('docker-parse-image');

/**
 * Determines the URL for a Docker registry based on the image name.
 * @private
 * @param {string} image the name of a Docker image
 * @returns {string} URL for the image's registry
 */
function getRegistryUrl(image) {
  const parsedImage = dockerParseImage(image);
  if (parsedImage.registry) {
    return `https://${parsedImage.registry}/v2/`;
  }
  return 'https://registry-1.docker.io/v2/';
}

/**
 * Query registry server for authentication info.
 * @private
 * @param {string} image the image to get authentication info for (example: "alpine:latest")
 * @param {Object} options options to use for the query
 * @returns {Object} Authentication info for the requested registry and image.
 * @throws Will throw an error if authentication info can't be parsed or the registry is unreachable.
 */
async function getAuthenticationInfo(image, options) {
  const authInfo = {}; // object to store realm and service info

  // options passed to axios
  let queryOptions = {};
  if (options.requestOptions) {
    queryOptions = { ...options.requestOptions };
  }
  queryOptions.validateStatus = status => status === 401;

  // add authentication info if provided
  if (options.auth) {
    queryOptions.auth = options.auth;
  }

  try {
    // await axios get request, this will be a 401 response and the registry
    // will provide info required to get an authentication token
    const realmResponse = await axios.get(getRegistryUrl(image), queryOptions);

    // parse auth response for the realm and service params provided by
    // registry
    if (realmResponse.headers['www-authenticate']) {
      const re = /Bearer realm="(.*)",service="(.*)"/i;
      const found = realmResponse.headers['www-authenticate'].match(re);
      if (found) {
        [, authInfo.realm, authInfo.service] = found;
      }
    } else {
      throw new Error('Failed to parse realm and service info from registry.');
    }
  } catch (error) {
    throw new Error('Failed to get authentication info from registry.');
  }

  // use the realm and service info to get an auth token from the registry
  let tokenResponse = {}; // object to store token info
  try {
    const parsedImage = dockerParseImage(image);

    let tokenOptions = {};
    if (options.requestOptions) {
      tokenOptions = { ...options.requestOptions };
    }
    tokenOptions.params = {
      service: authInfo.service,
      scope: `repository:${parsedImage.namespace ? `${parsedImage.namespace}/` : 'library/'}${parsedImage.repository}:pull`,
    };

    // add authentication info if provided
    if (options.auth) {
      tokenOptions.auth = options.auth;
    }

    // await axios get request, response should contain the auth token
    tokenResponse = await axios.get(authInfo.realm, tokenOptions);

    if (!tokenResponse.data.token) {
      throw new Error("Can't get authentication token from registry.");
    }
  } catch (error) {
    console.log(error);
    throw new Error('Failed to get authentication token from registry.');
  }

  // return token and other auth info
  return {
    ...authInfo,
    token: tokenResponse.data.token,
  };
}

/**
 * Query the registry server for the manifest info on a docker image.
 * @private
 * @param {string} image the image to get manifest info for (example: "alpine:latest")
 * @param {Object} token authentication info for the registry
 * @param {Object} options options to use for the query
 * @returns {Object} manifest data for the requested image
 * @throws Will throw an error if the registry is unreachable.
 */
async function getManifest(image, token, options = {}) {
  // options passed to axios
  let manifestOptions = {};
  if (options.requestOptions) {
    manifestOptions = { ...options.requestOptions };
  }
  manifestOptions.headers = {
    Authorization: `Bearer ${token.token}`,
  };

  const parsedImage = dockerParseImage(image);
  // build url for manifest request - see https://docs.docker.com/registry/spec/api/
  const manifestUrl = `${getRegistryUrl(image)}${parsedImage.namespace ? `${parsedImage.namespace}/` : 'library/'}${parsedImage.repository}/manifests/${parsedImage.tag ? parsedImage.tag : 'latest'}`;

  try {
    const manifest = await axios.get(manifestUrl, manifestOptions);
    return manifest.data;
  } catch (error) {
    // TODO throw errors for: 1. registry unreachable, 2. auth failure
    throw new Error('Unable to get manifest info from registry.');
  }
}

/**
 * Get manifest info for a docker image.
 * @param {string} image the name of the image. Example: "alpine:latest".
 * @param {Object} options options for the request.
 * @returns {Object} manifest info for the image
 */
async function getImageManifest(image, options = {}) {
  // get an oauth token for the registry
  const token = await getAuthenticationInfo(image, options);

  // query registry for an image manifest
  const manifest = await getManifest(image, token, options);

  return manifest;
}

module.exports.getImageManifest = getImageManifest;
<|endoftext|>


<commit_before>define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/array",
		"./CartesianBase", "./common", "dojox/lang/utils", "dojox/gfx/fx"],
	function(lang, declare, hub, arr, CartesianBase, dc, du, fx){

	/*=====
	dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
		//	summary:
		//		A special keyword arguments object that is specific to a grid "plot".

		//	majorHLine: dojox.gfx.Stroke?
		//		An optional dojox.gfx.Stroke for a major horizontal line. By default major lines use major tick stroke.
		majorHLine,

		//	minorHLine: dojox.gfx.Stroke?
		//		An optional dojox.gfx.Stroke for a minor horizontal line. By default minor lines use minor tick stroke.
		minorHLine,

		//	majorVLine: dojox.gfx.Stroke?
		//		An optional dojox.gfx.Stroke for a major vertical line. By default major lines use major tick stroke.
		majorVLine,

		//	minorVLine: dojox.gfx.Stroke?
		//		An optional dojox.gfx.Stroke for a minor vertical line. By default major lines use major tick stroke.
		minorVLine,

		//	hMajorLines: Boolean?
		//		Whether to show lines at the major ticks along the horizontal axis. Default is true.
		hMajorLines: true,

		//	hMinorLines: Boolean?
		//		Whether to show lines at the minor ticks along the horizontal axis. Default is false.
		hMinorLines: false,

		//	vMajorLines: Boolean?
		//		Whether to show lines at the major ticks along the vertical axis. Default is true.
		vMajorLines: true,

		//	vMinorLines: Boolean?
		//		Whether to show lines at the major ticks along the vertical axis. Default is false.
		vMinorLines: false,

		//	enableCache: Boolean?
		//		Whether the grid lines are cached from one rendering to another. This improves the rendering performance of
		//		successive rendering but penalize the first rendering.  Default false.
		enableCache: false,

		//	renderOnAxis: Boolean?
		//		Whether or not the grid is rendered when drawn at horizontal or vertical axis position. Default is true.
		renderOnAxis: true
	});
	var CartesianBase = dojox.charting.plot2d.CartesianBase;
	=====*/

	return declare("dojox.charting.plot2d.Grid", CartesianBase, {
		//	summary:
		//		A "faux" plot that can be placed behind other plots to represent
		//		a grid against which other plots can be easily measured.
		defaultParams: {
			hAxis: "x",			// use a horizontal axis named "x"
			vAxis: "y",			// use a vertical axis named "y"
			hMajorLines: true,	// draw horizontal major lines
			hMinorLines: false,	// draw horizontal minor lines
			vMajorLines: true,	// draw vertical major lines
			vMinorLines: false,	// draw vertical minor lines
			hStripes: false,	// TBD, stripes are not implemented
			vStripes: false,	// TBD, stripes are not implemented
			animate: null,   // animate bars into place
			enableCache: false,
			renderOnAxis: true
		},

		optionalParams: {
			majorHLine: {},
			minorHLine: {},
			majorVLine: {},
			minorVLine: {}
		},

		constructor: function(chart, kwArgs){
			//	summary:
			//		Create the faux Grid plot.
			//	chart: dojox.charting.Chart
			//		The chart this plot belongs to.
			//	kwArgs: dojox.charting.plot2d.__GridCtorArgs?
			//		An optional keyword arguments object to help define the parameters of the underlying grid.
			this.opt = lang.clone(this.defaultParams);
			du.updateWithObject(this.opt, kwArgs);
			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
			this.animate = this.opt.animate;
			if(this.opt.enableCache){
				this._lineFreePool = [];
				this._lineUsePool = [];
			}
		},
		addSeries: function(run){
			//	summary:
			//		Ignored but included as a dummy method.
			//	returns: dojox.charting.plot2d.Grid
			//		The reference to this plot for functional chaining.
			return this;	//	dojox.charting.plot2d.Grid
		},
		getSeriesStats: function(){
			//	summary:
			//		Returns default stats (irrelevant for this type of plot).
			//	returns: Object
			//		{hmin, hmax, vmin, vmax} min/max in both directions.
			return lang.delegate(dc.defaultStats);
		},
		cleanGroup: function(){
			this.inherited(arguments);
			if(this.opt.enableCache){
				this._lineFreePool = this._lineFreePool.concat(this._lineUsePool);
				this._lineUsePool = [];
			}
		},
		createLine: function(creator, params){
			var line;
			if(this.opt.enableCache && this._lineFreePool.length > 0){
				line = this._lineFreePool.pop();
				line.setShape(params);
				// was cleared, add it back
				creator.add(line);
			}else{
				line = creator.createLine(params);
			}
			if(this.opt.enableCache){
				this._lineUsePool.push(line);
			}
			return line;
		},
		render: function(dim, offsets){
			//	summary:
			//		Render the plot on the chart.
			//	dim: Object
			//		An object of the form { width, height }.
			//	offsets: Object
			//		An object of the form { l, r, t, b }.
			//	returns: dojox.charting.plot2d.Grid
			//		A reference to this plot for functional chaining.
			if(this.zoom){
				return this.performZoom(dim, offsets);
			}
			this.dirty = this.isDirty();
			if(!this.dirty){ return this; }
			this.cleanGroup();
			var s = this.group, ta = this.chart.theme, lineStroke;
			var renderOnAxis = this.opt.renderOnAxis;
			if(this._vAxis){
				var vScaler = this._vAxis.getScaler();
				if(vScaler){
					var vt = vScaler.scaler.getTransformerFromModel(vScaler);
					var ticks;
					// draw horizontal stripes and lines
					ticks = this._vAxis.getTicks();
					if(ticks != null){
						if(this.opt.hMinorLines){
							lineStroke = this.opt.minorHLine || (ta.grid && ta.grid.minorLine) || ta.axis.minorTick;
							arr.forEach(ticks.minor, function(tick){
								if(!renderOnAxis && tick.value == (this._vAxis.opt.leftBottom?vScaler.bounds.from:vScaler.bounds.to)){
									return;
								}
								var y = dim.height - offsets.b - vt(tick.value);
								var hMinorLine = this.createLine(s, {
									x1: offsets.l,
									y1: y,
									x2: dim.width - offsets.r,
									y2: y
								}).setStroke(lineStroke);
								if(this.animate){
									this._animateGrid(hMinorLine, "h", offsets.l, offsets.r + offsets.l - dim.width);
								}
							}, this);
						}
						if(this.opt.hMajorLines){
							lineStroke = this.opt.majorHLine || (ta.grid && ta.grid.majorLine) || ta.axis.majorTick;
							arr.forEach(ticks.major, function(tick){
								if(!renderOnAxis && tick.value == (this._vAxis.opt.leftBottom?vScaler.bounds.from:vScaler.bounds.to)){
									return;
								}
								var y = dim.height - offsets.b - vt(tick.value);
								var hMajorLine = this.createLine(s, {
									x1: offsets.l,
									y1: y,
									x2: dim.width - offsets.r,
									y2: y
								}).setStroke(lineStroke);
								if(this.animate){
									this._animateGrid(hMajorLine, "h", offsets.l, offsets.r + offsets.l - dim.width);
								}
							}, this);
						}
					}
				}
			}
			if(this._hAxis){
				var hScaler = this._hAxis.getScaler();
				if(hScaler){
					var ht = hScaler.scaler.getTransformerFromModel(hScaler);
					// draw vertical stripes and lines
					ticks = this._hAxis.getTicks();
					if(this != null){
						if(ticks && this.opt.vMinorLines){
							lineStroke = this.opt.minorVLine || (ta.grid && ta.grid.minorLine) || ta.axis.minorTick;
							arr.forEach(ticks.minor, function(tick){
								if(!renderOnAxis && tick.value == (this._hAxis.opt.leftBottom?hScaler.bounds.from:hScaler.bounds.to)){
									return;
								}
								var x = offsets.l + ht(tick.value);
								var vMinorLine = this.createLine(s, {
									x1: x,
									y1: offsets.t,
									x2: x,
									y2: dim.height - offsets.b
								}).setStroke(lineStroke);
								if(this.animate){
									this._animateGrid(vMinorLine, "v", dim.height - offsets.b, dim.height - offsets.b - offsets.t);
								}
							}, this);
						}
						if(ticks && this.opt.vMajorLines){
							lineStroke = this.opt.majorVLine || (ta.grid && ta.grid.majorLine) || ta.axis.majorTick;
							arr.forEach(ticks.major, function(tick){
								if(!renderOnAxis && tick.value == (this._hAxis.opt.leftBottom?hScaler.bounds.from:hScaler.bounds.to)){
									return;
								}
								var x = offsets.l + ht(tick.value);
								var vMajorLine = this.createLine(s, {
									x1: x,
									y1: offsets.t,
									x2: x,
									y2: dim.height - offsets.b
								}).setStroke(lineStroke);
								if(this.animate){
									this._animateGrid(vMajorLine, "v", dim.height - offsets.b, dim.height - offsets.b - offsets.t);
								}
							}, this);
						}
					}
				}
			}
			this.dirty = false;
			return this;	//	dojox.charting.plot2d.Grid
		},
		_animateGrid: function(shape, type, offset, size){
			var transStart = type == "h" ? [offset, 0] : [0, offset];
			var scaleStart = type == "h" ? [1/size, 1] : [1, 1/size];
			fx.animateTransform(lang.delegate({
				shape: shape,
				duration: 1200,
				transform: [
					{name: "translate", start: transStart, end: [0, 0]},
					{name: "scale", start: scaleStart, end: [1, 1]},
					{name: "original"}
				]
			}, this.animate)).play();
		}
	});
});
<commit_msg>refs #14583. Fix grid regression introduced by [27862/dojo]. !strict.<commit_after>define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/array",
		"./CartesianBase", "./common", "dojox/lang/utils", "dojox/gfx/fx"],
	function(lang, declare, hub, arr, CartesianBase, dc, du, fx){

	/*=====
	dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
		//	summary:
		//		A special keyword arguments object that is specific to a grid "plot".

		//	majorHLine: dojox.gfx.Stroke?
		//		An optional dojox.gfx.Stroke for a major horizontal line. By default major lines use major tick stroke.
		majorHLine,

		//	minorHLine: dojox.gfx.Stroke?
		//		An optional dojox.gfx.Stroke for a minor horizontal line. By default minor lines use minor tick stroke.
		minorHLine,

		//	majorVLine: dojox.gfx.Stroke?
		//		An optional dojox.gfx.Stroke for a major vertical line. By default major lines use major tick stroke.
		majorVLine,

		//	minorVLine: dojox.gfx.Stroke?
		//		An optional dojox.gfx.Stroke for a minor vertical line. By default major lines use major tick stroke.
		minorVLine,

		//	hMajorLines: Boolean?
		//		Whether to show lines at the major ticks along the horizontal axis. Default is true.
		hMajorLines: true,

		//	hMinorLines: Boolean?
		//		Whether to show lines at the minor ticks along the horizontal axis. Default is false.
		hMinorLines: false,

		//	vMajorLines: Boolean?
		//		Whether to show lines at the major ticks along the vertical axis. Default is true.
		vMajorLines: true,

		//	vMinorLines: Boolean?
		//		Whether to show lines at the major ticks along the vertical axis. Default is false.
		vMinorLines: false,

		//	enableCache: Boolean?
		//		Whether the grid lines are cached from one rendering to another. This improves the rendering performance of
		//		successive rendering but penalize the first rendering.  Default false.
		enableCache: false,

		//	renderOnAxis: Boolean?
		//		Whether or not the grid is rendered when drawn at horizontal or vertical axis position. Default is true.
		renderOnAxis: true
	});
	var CartesianBase = dojox.charting.plot2d.CartesianBase;
	=====*/

	return declare("dojox.charting.plot2d.Grid", CartesianBase, {
		//	summary:
		//		A "faux" plot that can be placed behind other plots to represent
		//		a grid against which other plots can be easily measured.
		defaultParams: {
			hAxis: "x",			// use a horizontal axis named "x"
			vAxis: "y",			// use a vertical axis named "y"
			hMajorLines: true,	// draw horizontal major lines
			hMinorLines: false,	// draw horizontal minor lines
			vMajorLines: true,	// draw vertical major lines
			vMinorLines: false,	// draw vertical minor lines
			hStripes: false,	// TBD, stripes are not implemented
			vStripes: false,	// TBD, stripes are not implemented
			animate: null,   // animate bars into place
			enableCache: false,
			renderOnAxis: true
		},

		optionalParams: {
			majorHLine: {},
			minorHLine: {},
			majorVLine: {},
			minorVLine: {}
		},

		constructor: function(chart, kwArgs){
			//	summary:
			//		Create the faux Grid plot.
			//	chart: dojox.charting.Chart
			//		The chart this plot belongs to.
			//	kwArgs: dojox.charting.plot2d.__GridCtorArgs?
			//		An optional keyword arguments object to help define the parameters of the underlying grid.
			this.opt = lang.clone(this.defaultParams);
			du.updateWithObject(this.opt, kwArgs);
			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
			this.hAxis = this.opt.hAxis;
			this.vAxis = this.opt.vAxis;
			this.animate = this.opt.animate;
			if(this.opt.enableCache){
				this._lineFreePool = [];
				this._lineUsePool = [];
			}
		},
		addSeries: function(run){
			//	summary:
			//		Ignored but included as a dummy method.
			//	returns: dojox.charting.plot2d.Grid
			//		The reference to this plot for functional chaining.
			return this;	//	dojox.charting.plot2d.Grid
		},
		getSeriesStats: function(){
			//	summary:
			//		Returns default stats (irrelevant for this type of plot).
			//	returns: Object
			//		{hmin, hmax, vmin, vmax} min/max in both directions.
			return lang.delegate(dc.defaultStats);
		},
		cleanGroup: function(){
			this.inherited(arguments);
			if(this.opt.enableCache){
				this._lineFreePool = this._lineFreePool.concat(this._lineUsePool);
				this._lineUsePool = [];
			}
		},
		createLine: function(creator, params){
			var line;
			if(this.opt.enableCache && this._lineFreePool.length > 0){
				line = this._lineFreePool.pop();
				line.setShape(params);
				// was cleared, add it back
				creator.add(line);
			}else{
				line = creator.createLine(params);
			}
			if(this.opt.enableCache){
				this._lineUsePool.push(line);
			}
			return line;
		},
		render: function(dim, offsets){
			//	summary:
			//		Render the plot on the chart.
			//	dim: Object
			//		An object of the form { width, height }.
			//	offsets: Object
			//		An object of the form { l, r, t, b }.
			//	returns: dojox.charting.plot2d.Grid
			//		A reference to this plot for functional chaining.
			if(this.zoom){
				return this.performZoom(dim, offsets);
			}
			this.dirty = this.isDirty();
			if(!this.dirty){ return this; }
			this.cleanGroup();
			var s = this.group, ta = this.chart.theme, lineStroke;
			var renderOnAxis = this.opt.renderOnAxis;
			if(this._vAxis){
				var vScaler = this._vAxis.getScaler();
				if(vScaler){
					var vt = vScaler.scaler.getTransformerFromModel(vScaler);
					var ticks;
					// draw horizontal stripes and lines
					ticks = this._vAxis.getTicks();
					if(ticks != null){
						if(this.opt.hMinorLines){
							lineStroke = this.opt.minorHLine || (ta.grid && ta.grid.minorLine) || ta.axis.minorTick;
							arr.forEach(ticks.minor, function(tick){
								if(!renderOnAxis && tick.value == (this._vAxis.opt.leftBottom?vScaler.bounds.from:vScaler.bounds.to)){
									return;
								}
								var y = dim.height - offsets.b - vt(tick.value);
								var hMinorLine = this.createLine(s, {
									x1: offsets.l,
									y1: y,
									x2: dim.width - offsets.r,
									y2: y
								}).setStroke(lineStroke);
								if(this.animate){
									this._animateGrid(hMinorLine, "h", offsets.l, offsets.r + offsets.l - dim.width);
								}
							}, this);
						}
						if(this.opt.hMajorLines){
							lineStroke = this.opt.majorHLine || (ta.grid && ta.grid.majorLine) || ta.axis.majorTick;
							arr.forEach(ticks.major, function(tick){
								if(!renderOnAxis && tick.value == (this._vAxis.opt.leftBottom?vScaler.bounds.from:vScaler.bounds.to)){
									return;
								}
								var y = dim.height - offsets.b - vt(tick.value);
								var hMajorLine = this.createLine(s, {
									x1: offsets.l,
									y1: y,
									x2: dim.width - offsets.r,
									y2: y
								}).setStroke(lineStroke);
								if(this.animate){
									this._animateGrid(hMajorLine, "h", offsets.l, offsets.r + offsets.l - dim.width);
								}
							}, this);
						}
					}
				}
			}
			if(this._hAxis){
				var hScaler = this._hAxis.getScaler();
				if(hScaler){
					var ht = hScaler.scaler.getTransformerFromModel(hScaler);
					// draw vertical stripes and lines
					ticks = this._hAxis.getTicks();
					if(this != null){
						if(ticks && this.opt.vMinorLines){
							lineStroke = this.opt.minorVLine || (ta.grid && ta.grid.minorLine) || ta.axis.minorTick;
							arr.forEach(ticks.minor, function(tick){
								if(!renderOnAxis && tick.value == (this._hAxis.opt.leftBottom?hScaler.bounds.from:hScaler.bounds.to)){
									return;
								}
								var x = offsets.l + ht(tick.value);
								var vMinorLine = this.createLine(s, {
									x1: x,
									y1: offsets.t,
									x2: x,
									y2: dim.height - offsets.b
								}).setStroke(lineStroke);
								if(this.animate){
									this._animateGrid(vMinorLine, "v", dim.height - offsets.b, dim.height - offsets.b - offsets.t);
								}
							}, this);
						}
						if(ticks && this.opt.vMajorLines){
							lineStroke = this.opt.majorVLine || (ta.grid && ta.grid.majorLine) || ta.axis.majorTick;
							arr.forEach(ticks.major, function(tick){
								if(!renderOnAxis && tick.value == (this._hAxis.opt.leftBottom?hScaler.bounds.from:hScaler.bounds.to)){
									return;
								}
								var x = offsets.l + ht(tick.value);
								var vMajorLine = this.createLine(s, {
									x1: x,
									y1: offsets.t,
									x2: x,
									y2: dim.height - offsets.b
								}).setStroke(lineStroke);
								if(this.animate){
									this._animateGrid(vMajorLine, "v", dim.height - offsets.b, dim.height - offsets.b - offsets.t);
								}
							}, this);
						}
					}
				}
			}
			this.dirty = false;
			return this;	//	dojox.charting.plot2d.Grid
		},
		_animateGrid: function(shape, type, offset, size){
			var transStart = type == "h" ? [offset, 0] : [0, offset];
			var scaleStart = type == "h" ? [1/size, 1] : [1, 1/size];
			fx.animateTransform(lang.delegate({
				shape: shape,
				duration: 1200,
				transform: [
					{name: "translate", start: transStart, end: [0, 0]},
					{name: "scale", start: scaleStart, end: [1, 1]},
					{name: "original"}
				]
			}, this.animate)).play();
		}
	});
});
<|endoftext|>