<commit_before>/**
 * Created by kamalnrf
 */

'use strict';

const msg_me = require('../msg-me');
const connection = require('./handlers/connection');
const newUser = require('./handlers/createUserOperator');
const feedback = require('./handlers/feedback');
const shrImage = require('./handlers/shrImage');

const postback = (bot) => {
    bot.on('postback', (payload, chat) => {
       console.log(payload);

       if (payload.postback.payload === '_stop') {
           const fbID = payload.sender.id;

           msg_me.isConnected(fbID)
               .then(connected => {
                   if (connected === 'true' || connected === true)
                       msg_me.conectedTo(fbID)
                           .then(recieverID => {
                               msg_me.disconnect(fbID, recieverID);

                               chat.say(`Conversation has ended`);
                               bot.say(recieverID, `Conection has been ended.`);
                           });
                   else
                       chat.say(`You have to be in a conversation to stop a conversation`);
               })
       }
    });

    bot.on('postback:REQ_YES', (payload, chat) => {
        console.log(payload);
        const senderID = payload.sender.id;

        msg_me.whatIsOnHold(senderID)
            .then(recieverID => {
                if (recieverID !== '-1') {
                    if (msg_me.connect(senderID, recieverID) === true) {
                        chat.say(`A connection has been established`);
                        bot.say(recieverID, `A connection has been established`);
                    }
                }else {
                    chat.say(`Your request has been, expired.`);
                }
            });
    });

    bot.on('postback:REQ_NO', (payload, chat) => {
        console.log(payload);
        const senderID = payload.sender.id;

        msg_me.whatIsOnHold(senderID)
            .then(recieverID => {
                if (recieverID !== '-1') {
                    if (msg_me.disconnect(senderID, recieverID) === true) {
                        chat.say(`Ok`);
                        bot.say(recieverID, `Your request has been rejected, try connecting with someone else.`);
                        msg_me.removeQueuedUsers(recieverID);
                    }
                }else {
                    chat.say(`OK.`);
                }
            });
    });
    //----------Online/Offline--------//
    bot.on('postback:online/offline', (payload, chat) => {
        console.log(payload);

        const fbID = payload.sender.id;

        msg_me.isOnline(fbID)
            .then(isOnline => {
                console.log(`isOnline ${isOnline}\nType: ${typeof isOnline}`);
                if (isOnline === 'true' || isOnline === true) {
                    msg_me.turnOffline(fbID)
                        .then(result => result ? chat.say("You’re now Offline. Friends will not be able to connect with you. Please turn back to Online if you want to chat anonymously with your friends.") : chat.say("Something went wrong tryagain"));
                }
                else if (isOnline === false || isOnline === "false") {
                    msg_me.turnOnline(fbID)
                        .then(result => result ? chat.say("You’re now Online. Hold on! Any friend of yours maybe contacting you soon.") : chat.say("Something went wrong tryagain"));

                    msg_me.getAllQueuedUsers(fbID)
                        .then(queuedUsers => {
                            console.log(queuedUsers);
                            queuedUsers.map(element => {
                                msg_me.getMyName(fbID)
                                    .then(name => {
                                        console.log(element);
                                        bot.sendTextMessage(element, `${name} is online. Now you can connect with him.`);
                                    });
                            });
                        });

                    msg_me.removeQueuedUsers(fbID);
                }
                else
                    chat.say("You need to create a user name first.")
                        .then(() => {
                            chat.conversation((convo) => {
                                convo.sendTypingIndicator(1000).then(() => newUser.createUser(convo, payload));
                            })
                        });
            }).catch(error => console.log(error));
    });

    //----------Start a conversation----//
    bot.on('postback:start-conversation', (payload, chat) => {
        console.log(payload);

        const fbID = payload.sender.id;

        msg_me.isConnected(fbID)
            .then(connected => {
                if (connected === 'true' || connected === true)
                    chat.say("When you are in a conversation you can't start a new one.");
                else if (connected === 'false' || connected === false)
                    chat.conversation((convo) => {
                        convo.sendTypingIndicator(1000)
                            .then(() => connection.estConnection(convo, payload, bot))
                            .catch(error => console.log(error));
                    });
                else
                    chat.say("You need to create a username first.")
                        .then(() => {
                            chat.conversation((convo) => {
                                convo.sendTypingIndicator(1000).then(() => newUser.createUser(convo, payload));
                            })
                        });

            }).catch(error => console.log(error));
    });

    //----------My User Name-----------//
    bot.on('postback:myName', (payload, chat) => {
        console.log(payload);

        const fbID = payload.sender.id;

        msg_me.getMyName(fbID)
            .then(userName => {
                if (userName !== null) {
                    msg_me.getMyImage(fbID)
                        .then(link => {
                            if (link === null || link === undefined) {
                                console.log(`link is null`);
                                chat.getUserProfile()
                                    .then((user) => {
                                        shrImage.genImage(user.profile_pic, userName)
                                            .then(image => {
                                                shrImage.getLink(image, userName)
                                                    .then(link => {
                                                        console.log(link);
                                                        msg_me.saveImage(fbID, link);
                                                        chat.say({
                                                            attachment: 'image',
                                                            url: link
                                                        });
                                                        chat.say(`Your username is ${userName}. Share it with your friends.`);
                                                    })
                                            });
                                    });
                            }
                            else {
                                chat.say({
                                    attachment: 'image',
                                    url: link
                                }).then(() => chat.say(`Your username is ${userName}. Share it with your friends.`));
                            }
                        });
                }
                else
                    chat.say("You need to create a username first.")
                        .then(() => {
                            chat.conversation((convo) => {
                                convo.sendTypingIndicator(1000).then(() => newUser.createUser(convo, payload));
                            })
                        });
            })
            .catch(error => {
                console.log(error);
                chat.say("You need to create a username first.")
                    .then(() => {
                        chat.conversation((convo) => {
                            convo.sendTypingIndicator(1000).then(() => newUser.createUser(convo, payload));
                        })
                    });
            })
    });

    //----------Feedback----------//
    bot.on('postback:feedback', (payload, chat) => {
       console.log(payload);

       try {

           chat.conversation(convo => {
               convo.sendTypingIndicator(1000).then(() => feedback.sendFeedBack(payload, convo));
           })
       }catch (error){

       }
    });

    console.log(`Initialized the postbacks.`);
};

module.exports = postback;<commit_msg>patches<commit_after>/**
 * Created by kamalnrf
 */

'use strict';

const msg_me = require('../msg-me');
const connection = require('./handlers/connection');
const newUser = require('./handlers/createUserOperator');
const feedback = require('./handlers/feedback');
const shrImage = require('./handlers/shrImage');

const postback = (bot) => {
    bot.on('postback', (payload, chat) => {
       console.log(payload);

       if (payload.postback.payload === '_stop') {
           const fbID = payload.sender.id;

           msg_me.isConnected(fbID)
               .then(connected => {
                   if (connected === 'true' || connected === true)
                       msg_me.conectedTo(fbID)
                           .then(recieverID => {
                               msg_me.disconnect(fbID, recieverID);

                               chat.say(`Conversation has ended`);
                               bot.say(recieverID, `Conection has been ended.`);
                           });
                   else
                       chat.say(`You have to be in a conversation to stop a conversation`);
               })
       }
    });

    bot.on('postback:REQ_YES', (payload, chat) => {
        console.log(payload);
        const senderID = payload.sender.id;

        msg_me.whatIsOnHold(senderID)
            .then(recieverID => {
                if (recieverID !== '-1') {
                    if (msg_me.connect(senderID, recieverID) === true) {
                        chat.say(`A connection has been established`);
                        bot.say(recieverID, `A connection has been established`);
                    }
                }else {
                    chat.say(`Your request has been, expired.`);
                }
            });
    });

    bot.on('postback:REQ_NO', (payload, chat) => {
        console.log(payload);
        const senderID = payload.sender.id;

        msg_me.whatIsOnHold(senderID)
            .then(recieverID => {
                if (recieverID !== '-1') {
                    if (msg_me.disconnect(senderID, recieverID) === true) {
                        chat.say(`Ok`);
                        bot.say(recieverID, `Your request has been rejected, try connecting with someone else.`);
                        msg_me.removeQueuedUsers(recieverID);
                    }
                }else {
                    chat.say(`OK.`);
                }
            });
    });
    //----------Online/Offline--------//
    bot.on('postback:online/offline', (payload, chat) => {
        console.log(payload);

        const fbID = payload.sender.id;

        msg_me.isOnline(fbID)
            .then(isOnline => {
                console.log(`isOnline ${isOnline}\nType: ${typeof isOnline}`);
                if (isOnline === 'true' || isOnline === true) {
                    msg_me.turnOffline(fbID)
                        .then(result => result ? chat.say("You’re now Offline. Friends will not be able to connect with you. Please turn back to Online if you want to chat anonymously with your friends.") : chat.say("Something went wrong tryagain"));
                }
                else if (isOnline === false || isOnline === "false") {
                    msg_me.turnOnline(fbID)
                        .then(result => result ? chat.say("You’re now Online. Hold on! Any friend of yours maybe contacting you soon.") : chat.say("Something went wrong tryagain"));

                    msg_me.getAllQueuedUsers(fbID)
                        .then(queuedUsers => {
                            console.log(queuedUsers);
                            queuedUsers.map(element => {
                                msg_me.getMyName(fbID)
                                    .then(name => {
                                        console.log(element);
                                        bot.sendTextMessage(element, `${name} is online. Now you can connect with him.`);
                                    });
                            });
                        });

                    msg_me.removeQueuedUsers(fbID);
                }
                else
                    chat.say("You need to create a user name first.")
                        .then(() => {
                            chat.conversation((convo) => {
                                convo.sendTypingIndicator(1000).then(() => newUser.createUser(convo, payload));
                            })
                        });
            }).catch(error => console.log(error));
    });

    //----------Start a conversation----//
    bot.on('postback:start-conversation', (payload, chat) => {
        console.log(payload);

        const fbID = payload.sender.id;

        msg_me.isConnected(fbID)
            .then(connected => {
                try {
                    if (connected === 'true' || connected === true)
                        chat.say("When you are in a conversation you can't start a new one.");
                    else if (connected === 'false' || connected === false)
                        chat.conversation((convo) => {
                            convo.sendTypingIndicator(1000)
                                .then(() => connection.estConnection(convo, payload, bot))
                                .catch(error => console.log(error));
                        });
                    else
                        chat.say("You need to create a username first.")
                            .then(() => {
                                chat.conversation((convo) => {
                                    convo.sendTypingIndicator(1000).then(() => newUser.createUser(convo, payload));
                                })
                            });
                }catch (error){
                    chat.say('Seems like something went wrong, try sending a message...');
                }

            }).catch(error => console.log(error));
    });

    //----------My User Name-----------//
    bot.on('postback:myName', (payload, chat) => {
        console.log(payload);

        const fbID = payload.sender.id;

        msg_me.getMyName(fbID)
            .then(userName => {
                if (userName !== null) {
                    msg_me.getMyImage(fbID)
                        .then(link => {
                            if (link === null || link === undefined) {
                                console.log(`link is null`);
                                chat.getUserProfile()
                                    .then((user) => {
                                        shrImage.genImage(user.profile_pic, userName)
                                            .then(image => {
                                                shrImage.getLink(image, userName)
                                                    .then(link => {
                                                        console.log(link);
                                                        msg_me.saveImage(fbID, link);
                                                        chat.say({
                                                            attachment: 'image',
                                                            url: link
                                                        });
                                                        chat.say(`Your username is ${userName}. Share it with your friends.`);
                                                    })
                                            });
                                    });
                            }
                            else {
                                chat.say({
                                    attachment: 'image',
                                    url: link
                                }).then(() => chat.say(`Your username is ${userName}. Share it with your friends.`));
                            }
                        });
                }
                else
                    chat.say("You need to create a username first.")
                        .then(() => {
                            chat.conversation((convo) => {
                                convo.sendTypingIndicator(1000).then(() => newUser.createUser(convo, payload));
                            })
                        });
            })
            .catch(error => {
                console.log(error);
                chat.say("You need to create a username first.")
                    .then(() => {
                        chat.conversation((convo) => {
                            convo.sendTypingIndicator(1000).then(() => newUser.createUser(convo, payload));
                        })
                    });
            })
    });

    //----------Feedback----------//
    bot.on('postback:feedback', (payload, chat) => {
       console.log(payload);

       try {

           chat.conversation(convo => {
               convo.sendTypingIndicator(1000).then(() => feedback.sendFeedBack(payload, convo));
           })
       }catch (error){

       }
    });

    console.log(`Initialized the postbacks.`);
};

module.exports = postback;<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016-2017 The Regents of the University of California
 * Author: Jim Robinson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * Created by dat on 4/18/17.
 */

var igv = (function (igv) {

    /**
     * @param $parent              containing jquery selection used to host the table
     * @param browser              reference to the hicBrower object
     * @param browserLoadFunction function that consumes items selected from the table
     * @param dataSource          source of data fed to the table (see for example EncodeDataSource)
     */
    igv.IGVModalTable = function ($parent, browser, browserLoadFunction, dataSource) {

        var self = this;

        this.browser = browser;

        this.dataSource = dataSource;

        this.initialized = false;

        this.$modalTable = $('

');
        $parent.append(this.$modalTable);

        this.$spinner = $('
');
        this.$modalTable.append(this.$spinner);

        this.$spinner.append($(''));

        $('#hicEncodeModal').on('shown.bs.modal', function (e) {

            if (true !== self.initialized) {

                self.initialized = true;
                dataSource.retrieveData(function () {
                    self.createTableWithDataSource(dataSource);
                });

            }

        });

        $('#encodeModalTopCloseButton').on('click', function () {
            $('tr.selected').removeClass('selected');
        });

        $('#encodeModalBottomCloseButton').on('click', function () {
            $('tr.selected').removeClass('selected');
        });

        $('#encodeModalGoButton').on('click', function () {

            var dt,
                $selectedTableRows,
                result;

            $selectedTableRows = self.$dataTables.$('tr.selected');

            if ($selectedTableRows.length > 0) {

                $selectedTableRows.removeClass('selected');

                dt = self.$modalTable.DataTable();
                result = [];
                $selectedTableRows.each(function() {
                    result.push( dataSource.dataAtRowIndex( dt.row(this).index() ) );
                });

                self.browser[ browserLoadFunction ](result);

            }

        });

    };

    igv.IGVModalTable.prototype.genomeID = function () {
        return this.dataSource.config.genomeID;
    };

    igv.IGVModalTable.prototype.unbindAllMouseHandlers = function () {

        this.$modalTable.find('tbody').unbind();

        $('#hicEncodeModal').unbind();

        $('#encodeModalTopCloseButton').unbind();

        $('#encodeModalBottomCloseButton').unbind();

        $('#encodeModalGoButton').unbind();

    };

    /**
     * @param dataSource source of data fed to the table (see for example EncodeDataSource)
     */
    igv.IGVModalTable.prototype.createTableWithDataSource = function (dataSource) {

        this.$spinner.hide();

        this.$dataTables = this.$modalTable.dataTable({
            data: dataSource.tableData(),
            // deferRender: true,
            paging: true, /* must be true if scroller is enable */
            scrollX: false,
            scrollY: 400,
            scrollCollapse: false,
            scroller: true,
            fixedColumns: true,
            columns: dataSource.tableColumns()
        });

        this.$modalTable.find('tbody').on('click', 'tr', function () {

            if ($(this).hasClass('selected')) {
                $(this).removeClass('selected');
            } else {
                $(this).addClass('selected');
            }

        });

    };

    return igv;

})(igv || {});
<commit_msg>IGVModalTable. Handle undefined browser.<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016-2017 The Regents of the University of California
 * Author: Jim Robinson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * Created by dat on 4/18/17.
 */

var igv = (function (igv) {

    /**
     * @param $parent              containing jquery selection used to host the table
     * @param browser              reference to the hicBrower object
     * @param browserLoadFunction function that consumes items selected from the table
     * @param dataSource          source of data fed to the table (see for example EncodeDataSource)
     */
    igv.IGVModalTable = function ($parent, browser, browserLoadFunction, dataSource) {

        var self = this,
        $modal = $('#hicEncodeModal');

        this.browser = browser;

        this.dataSource = dataSource;

        this.initialized = false;

        this.$modalTable = $('

');
        $parent.append(this.$modalTable);

        this.$spinner = $('
');
        this.$modalTable.append(this.$spinner);

        this.$spinner.append($(''));
        this.$spinner.hide();

        $modal.on('show.bs.modal', function (e) {

            if (undefined === self.browser) {
                igv.presentAlert('ERROR: browser undefined');
            }

        });

        $modal.on('shown.bs.modal', function (e) {

            if (undefined === self.browser) {
                $modal.modal('hide');
            } else if (true !== self.initialized) {
                self.initialized = true;
                self.$spinner.show();
                dataSource.retrieveData(function () {
                    self.createTableWithDataSource(dataSource);
                    self.$spinner.hide();
                });
            }

        });

        $('#encodeModalTopCloseButton').on('click', function () {
            $('tr.selected').removeClass('selected');
        });

        $('#encodeModalBottomCloseButton').on('click', function () {
            $('tr.selected').removeClass('selected');
        });

        $('#encodeModalGoButton').on('click', function () {

            var dt,
                $selectedTableRows,
                result;

            $selectedTableRows = self.$dataTables.$('tr.selected');

            if (undefined === self.browser) {
                igv.presentAlert('ERROR: browser undefined');
            } else if ($selectedTableRows.length > 0) {

                $selectedTableRows.removeClass('selected');

                dt = self.$modalTable.DataTable();
                result = [];
                $selectedTableRows.each(function() {
                    result.push( dataSource.dataAtRowIndex( dt.row(this).index() ) );
                });

                self.browser[ browserLoadFunction ](result);
            }

        });

    };

    igv.IGVModalTable.prototype.genomeID = function () {
        return this.dataSource.config.genomeID;
    };

    igv.IGVModalTable.prototype.unbindAllMouseHandlers = function () {

        this.$modalTable.find('tbody').unbind();

        $('#hicEncodeModal').unbind();

        $('#encodeModalTopCloseButton').unbind();

        $('#encodeModalBottomCloseButton').unbind();

        $('#encodeModalGoButton').unbind();

    };

    /**
     * @param dataSource source of data fed to the table (see for example EncodeDataSource)
     */
    igv.IGVModalTable.prototype.createTableWithDataSource = function (dataSource) {

        this.$spinner.hide();

        this.$dataTables = this.$modalTable.dataTable({
            data: dataSource.tableData(),
            // deferRender: true,
            paging: true, /* must be true if scroller is enable */
            scrollX: false,
            scrollY: 400,
            scrollCollapse: false,
            scroller: true,
            fixedColumns: true,
            columns: dataSource.tableColumns()
        });

        this.$modalTable.find('tbody').on('click', 'tr', function () {

            if ($(this).hasClass('selected')) {
                $(this).removeClass('selected');
            } else {
                $(this).addClass('selected');
            }

        });

    };

    return igv;

})(igv || {});
<|endoftext|>


<commit_before>
/*
 * A general abstract class for nodes on the Pedigree graph. Contains information about
 * position on canvas and other neighboring nodes
 *
 * @param x the x coordinate on the canvas
 * @param x the y coordinate on the canvas
 * @param id the id of the node
 */

var AbstractNode = Class.create( {

    initialize: function(x, y, id) {
        !this._type && (this._type = "AbstractNode");
        this._id = id ? id : editor.getGraph().generateID();
        this._graphics = this.generateGraphics(x, y);
    },

    /*
     * Returns the unique ID of this node
     */
    getID: function() {
        return this._id;
    },

    /*
     * Generates and returns an instance of AbstractNodeVisuals
     */
    generateGraphics: function(x, y) {
        return new AbstractNodeVisuals(this, x, y);
    },

    /*
     * Returns the object responsible for managing graphics
     */
    getGraphics: function() {
        return this._graphics;
    },

    /*
     * Returns the X coordinate of the node on the canvas
     */
    getX: function() {
        return this.getGraphics().getX();
    },

    /*
     * Changes the X coordinate of the nodek
     *
     * @param x the x coordinate on the canvas
     * @param animate set to true if you want to animate, callback the transition
     * @param callback the function called at the end of the animation
     */
    setX: function(x, animate, callback) {
        this.getGraphics().setX(x, animate, callback)
    },

    /*
     * Returns the Y coordinate of the node on the canvas
     */
    getY: function() {
        return this.getGraphics().getY();
    },

    /*
     * Changes the Y coordinate of the node
     *
     * @param y the y coordinate on the canvas
     * @param animate set to true if you want to animate the transition
     * @param callback the function called at the end of the animation
     */
    setY: function(y, animate, callback) {
        this.getGraphics().setY(y, animate, callback)
    },

    /*
     * Returns an array containing the x and y coordinates of the node on canvas.
     */
    getPos: function() {
        return [this.getX(), this.getY()];
    },

    /*
     * Changes the position of the node to (X,Y)
     *
     * @param x the x coordinate on the canvas
     * @param y the y coordinate on the canvas
     * @param animate set to true if you want to animate the transition
     * @param callback the function called at the end of the animation
     */
    setPos: function(x,y, animate, callback) {
        this.getGraphics().setPos(x, y, animate, callback);
    },

    /**
     * Returns the type of this node
     *
     * @return a string expressing the type
     */
    getType: function() {
        return this._type;
    },

    /*
     * Returns an array of all adjacent nodes (neighbors).
     */
    getNeighbors: function() {
        return (this.getLowerNeighbors().concat(this.getSideNeighbors())).concat(this.getUpperNeighbors());
    },

    /*
     * Returns an array of all adjacent nodes (neighbors) located below this node.
     */
    getLowerNeighbors: function() {
        return [];
    },

    /*
     * Returns an array of all adjacent nodes (neighbors) located on the sides of this node.
     */
    getSideNeighbors: function() {
        return [];
    },

    /*
     * Returns an array of all adjacent nodes (neighbors) located above this node.
     */
    getUpperNeighbors: function() {
        return [];
    },

    /*
     * Removes all connections with neighboring nodes and (optionally) removes
     * all the graphics of this node.
     *
     * @param removeVisuals set to true if you want to remove the graphics of this
     * node as well.
     */
    remove: function(isRecursive) {
        var me = this;
        var toRemove = [];
        if(isRecursive) {
            toRemove.push(me);
            this.getNeighbors().each(function(neighbor) {
                var result = neighbor.isRelatedTo(editor.getGraph().getProband(), toRemove.clone());
                if(!result[0]) {
                    toRemove = result[1];
                }
            });
            toRemove.each(function(node) {
                node.getGraphics().getHighlightBox && node.getGraphics().highlight();
            });
            var confirmation;
            if(toRemove.length > 1) {
                confirmation = confirm("Removing this person will also remove all the highlighted individuals. Are you sure you want to proceed?");
            }
            else {
                confirmation = confirm("Removing this person will also remove all the related connections. Are you sure you want to proceed?");
            }
            if(confirmation) {
                toRemove.reverse().each(function(node) {
                    node && node.remove(false);
                });
            }
            else {
                toRemove.each(function(node) {
                    node && node.getGraphics().getHighlightBox && node.getGraphics().unHighlight();
                });
            }
        }
    },

    isRelatedTo: function(node, visited) {
        var visitedNodes = (visited) ? visited : [];
        if(visitedNodes.indexOf(this) >= 0) {
            return [false, visitedNodes];
        }
        visitedNodes.push(this);
        if(node == this) {
            return [true, visitedNodes];
        }
        else {
            var found = false;
            var neighbors = this.getNeighbors();
            neighbors = neighbors.without.apply(neighbors, visitedNodes);
            neighbors.each(function(neighbor) {
                var result = neighbor.isRelatedTo(node, visitedNodes);
                visitedNodes = result[1];
                result[0] && (found = true);
            });
            return [found, visitedNodes];
        }
    },

    getInfo: function() {
        return {type: this.getType(), x: this.getX(), y : this.getY(), id: this.getID()}
    },

    loadInfo: function(info) {
        if(info && info.id == this.getID() && info.type == this.getType()) {
            if(this.getX() != info.x)
                this.setX(info.x, false, null);
            if(this.getY() != info.y)
                this.setY(info.y, false, null.y);
            return true;
        }
        return false;
    },

    onWidgetHide: function() {
        this.getGraphics().getHoverBox().onWidgetHide();
    }
});

var ChildlessBehavior = {

    /*
     * Returns null if the node has no childless markers.
     * Returns 'childless' if this node is marked childless
     * Returns 'infertile' if this node is marked infertile
     */
    getChildlessStatus: function() {
        return this._childlessStatus;
    },

    /*
     * Changes the childless status of this node
     *
     * @param status set to null, 'infertile' or 'childless'
     */
    setChildlessStatus: function(status) {
        var nonPlaceHolders = this.getChildren("Person","PersonGroup");
        if((status == 'infertile' || status == 'childless') && nonPlaceHolders.length == 0) {
            this._childlessStatus = status;
            var phChildren = this.getChildren("PlaceHolder");
            phChildren.each(function(child) {
                child.remove(false);
            });
        }
        else {
            this._childlessStatus = null;
            this.restorePlaceholders();
        }
        this.setChildlessReason(null);
        this.getGraphics().updateChildlessShapes();
    },

    /*
     * Returns the reason for this node's status of 'infertile' or 'childless'
     */
    getChildlessReason: function() {
        return this._childlessReason;
    },

    /*
     * Changes the reason for this node's 'childless' or 'infertile' status
     *
     * @param reason a string that explains the condition (eg. "By Choice", "Vasectomy" etc)
     */
    setChildlessReason: function(reason) {
        if(this.getChildlessStatus() != null) {
            this._childlessReason = reason;
            this.getGraphics().updateChildlessStatusLabel();
        }
    }
};<commit_msg>Fixes #337.<commit_after>
/*
 * A general abstract class for nodes on the Pedigree graph. Contains information about
 * position on canvas and other neighboring nodes
 *
 * @param x the x coordinate on the canvas
 * @param x the y coordinate on the canvas
 * @param id the id of the node
 */

var AbstractNode = Class.create( {

    initialize: function(x, y, id) {
        !this._type && (this._type = "AbstractNode");
        this._id = id ? id : editor.getGraph().generateID();
        this._graphics = this.generateGraphics(x, y);
    },

    /*
     * Returns the unique ID of this node
     */
    getID: function() {
        return this._id;
    },

    /*
     * Generates and returns an instance of AbstractNodeVisuals
     */
    generateGraphics: function(x, y) {
        return new AbstractNodeVisuals(this, x, y);
    },

    /*
     * Returns the object responsible for managing graphics
     */
    getGraphics: function() {
        return this._graphics;
    },

    /*
     * Returns the X coordinate of the node on the canvas
     */
    getX: function() {
        return this.getGraphics().getX();
    },

    /*
     * Changes the X coordinate of the nodek
     *
     * @param x the x coordinate on the canvas
     * @param animate set to true if you want to animate, callback the transition
     * @param callback the function called at the end of the animation
     */
    setX: function(x, animate, callback) {
        this.getGraphics().setX(x, animate, callback)
    },

    /*
     * Returns the Y coordinate of the node on the canvas
     */
    getY: function() {
        return this.getGraphics().getY();
    },

    /*
     * Changes the Y coordinate of the node
     *
     * @param y the y coordinate on the canvas
     * @param animate set to true if you want to animate the transition
     * @param callback the function called at the end of the animation
     */
    setY: function(y, animate, callback) {
        this.getGraphics().setY(y, animate, callback)
    },

    /*
     * Returns an array containing the x and y coordinates of the node on canvas.
     */
    getPos: function() {
        return [this.getX(), this.getY()];
    },

    /*
     * Changes the position of the node to (X,Y)
     *
     * @param x the x coordinate on the canvas
     * @param y the y coordinate on the canvas
     * @param animate set to true if you want to animate the transition
     * @param callback the function called at the end of the animation
     */
    setPos: function(x,y, animate, callback) {
        this.getGraphics().setPos(x, y, animate, callback);
    },

    /**
     * Returns the type of this node
     *
     * @return a string expressing the type
     */
    getType: function() {
        return this._type;
    },

    /*
     * Returns an array of all adjacent nodes (neighbors).
     */
    getNeighbors: function() {
        return (this.getLowerNeighbors().concat(this.getSideNeighbors())).concat(this.getUpperNeighbors());
    },

    /*
     * Returns an array of all adjacent nodes (neighbors) located below this node.
     */
    getLowerNeighbors: function() {
        return [];
    },

    /*
     * Returns an array of all adjacent nodes (neighbors) located on the sides of this node.
     */
    getSideNeighbors: function() {
        return [];
    },

    /*
     * Returns an array of all adjacent nodes (neighbors) located above this node.
     */
    getUpperNeighbors: function() {
        return [];
    },

    /*
     * Removes all connections with neighboring nodes and (optionally) removes
     * all the graphics of this node.
     *
     * @param removeVisuals set to true if you want to remove the graphics of this
     * node as well.
     */
    remove: function(isRecursive) {
        var me = this;
        var toRemove = [];
        var affectedNeighbors = [];
        if(isRecursive) {
            toRemove.push(me);
            this.getNeighbors().each(function(neighbor) {
                var result = neighbor.isRelatedTo(editor.getGraph().getProband(), toRemove.clone());
                if(!result[0]) {
                    toRemove = result[1];
                }
                else if(neighbor.getType() == "Partnership") {
                    affectedNeighbors.push(neighbor);
                    neighbor.getPregnancies().each(function(preg) {
                        affectedNeighbors.push(preg);
                        if(preg.isPlaceHolderPregnancy()) {
                            affectedNeighbors = affectedNeighbors.concat(preg.getChildren());
                        }
                    });
                }
                else if(neighbor.getType() == "Pregnancy") {
                    affectedNeighbors.push(neighbor);
                    if(neighbor.isPlaceHolderPregnancy()) {
                        affectedNeighbors = affectedNeighbors.concat(neighbor.getChildren());
                    }
                }
            });
            toRemove.each(function(node) {
                node.getGraphics().getHighlightBox && node.getGraphics().highlight();
            });
            var confirmation;
            if(toRemove.length > 1) {
                confirmation = confirm("Removing this person will also remove all the highlighted individuals. Are you sure you want to proceed?");
            }
            else {
                confirmation = confirm("Removing this person will also remove all the related connections. Are you sure you want to proceed?");
            }
            if(confirmation) {
                var nodes = {
                    PersonNodes : [],
                    PartnershipNodes : [],
                    PregnancyNodes : [],
                    PersonGroupNodes : [],
                    PlaceHolderNodes : []
                };
                toRemove.concat(affectedNeighbors).each(function(node) {
                    nodes[node.getType() + "Nodes"].push(node.getInfo());
                });
                var nodeID = me.getID();
                var placeholders = [];
                toRemove.reverse().each(function(node) {
                    if(node) {
                        if(node.getID() == nodeID) {
                            var ph = node.remove(false);
                            ph && placeholders.push(ph.getInfo());
                        }
                        else
                            node.remove(false);
                    }
                });
                this.removeAction(nodes, placeholders);
            }
            else {
                toRemove.each(function(node) {
                    node && node.getGraphics().getHighlightBox && node.getGraphics().unHighlight();
                });
            }
        }
    },

    removeAction: function(removed, placeholders) {
        var phPartnerships = [],
            phPregnancies = [];
        placeholders.each(function(ph) {
            var node = editor.getGraph().getNodeMap()[ph.id];
            if(node) {
                var parentPreg = node.getParentPregnancy();
                parentPreg && phPregnancies.push(parentPreg.getInfo());
                node.getPartnerships().each(function(p) {
                    phPartnerships.push(p.getInfo());
                    p.getPregnancies().each(function(preg) {
                        phPregnancies.push(preg.getInfo());
                    });
                });
            }
        });
        var undoFunct = function() {
            placeholders.each(function(ph) {
                var node = editor.getGraph().getNodeMap()[ph.id];
                node && node.remove(false);
            });
            removed.PersonNodes.each(function(p) {
                editor.getGraph().addPerson(p.x, p.y, p.gender, p.id).loadInfo(p);
            });

            removed.PlaceHolderNodes.each(function(p) {
                editor.getGraph().addPlaceHolder(p.x, p.y, p.gender, p.id).loadInfo(p);
            });

            removed.PersonGroupNodes.each(function(p) {
                editor.getGraph().addPersonGroup(p.x, p.y, p.id).loadInfo(p);
            });

            removed.PartnershipNodes.each(function(p) {
                var p1 = editor.getGraph().getNodeMap()[p.partner1ID];
                var p2 = editor.getGraph().getNodeMap()[p.partner2ID];
                if(p1 && p2)
                    editor.getGraph().addPartnership(p.x, p.y, p1, p2, p.id).loadInfo(p);
            });

            removed.PregnancyNodes.each(function(p) {
                var partnership = editor.getGraph().getNodeMap()[p.partnershipID];
                if(partnership)
                    editor.getGraph().addPregnancy(p.x, p.y, partnership, p.id).loadInfo(p);
            });
        };

        var redoFunct = function() {
            removed.PregnancyNodes.each(function(p) {
                var node = editor.getGraph().getNodeMap()[p.id];
                node && node.remove(false);
            });

            removed.PartnershipNodes.each(function(p) {
                var node = editor.getGraph().getNodeMap()[p.id];
                node && node.remove(false);
            });

            removed.PersonGroupNodes.each(function(p) {
                var node = editor.getGraph().getNodeMap()[p.id];
                node && node.remove(false);
            });

            removed.PlaceHolderNodes.each(function(p) {
                var node = editor.getGraph().getNodeMap()[p.id];
                node && node.remove(false);
            });

            removed.PersonNodes.each(function(p) {
                var node = editor.getGraph().getNodeMap()[p.id];
                node && node.remove(false);
            });

            placeholders.each(function(p) {
                editor.getGraph().addPlaceHolder(p.x, p.y, p.gender, p.id).loadInfo(p);
            });

            phPartnerships.each(function(p) {
                var p1 = editor.getGraph().getNodeMap()[p.partner1ID];
                var p2 = editor.getGraph().getNodeMap()[p.partner2ID];
                if(p1 && p2) {
                    editor.getGraph().addPartnership(p.x, p.y, p1, p2, p.id).loadInfo(p);
                }
            });

            phPregnancies.each(function(p) {
                var partnership = editor.getGraph().getNodeMap()[p.partnershipID];
                if(partnership) {
                    var preg = editor.getGraph().addPregnancy(p.x, p.y, partnership, p.id).loadInfo(p);
                    p.childrenIDs.each(function(id){
                        var child = editor.getGraph().getNodeMap()[id].loadInfo(p);
                        child && preg.addChild(child);
                    });
                }
            });
        };
        editor.getActionStack().push({undo: undoFunct, redo: redoFunct});
    },

    isRelatedTo: function(node, visited) {
        var visitedNodes = (visited) ? visited : [];
        if(visitedNodes.indexOf(this) >= 0) {
            return [false, visitedNodes];
        }
        visitedNodes.push(this);
        if(node == this) {
            return [true, visitedNodes];
        }
        else {
            var found = false;
            var neighbors = this.getNeighbors();
            neighbors = neighbors.without.apply(neighbors, visitedNodes);
            neighbors.each(function(neighbor) {
                var result = neighbor.isRelatedTo(node, visitedNodes);
                visitedNodes = result[1];
                result[0] && (found = true);
            });
            return [found, visitedNodes];
        }
    },

    getInfo: function() {
        return {type: this.getType(), x: this.getX(), y : this.getY(), id: this.getID()}
    },

    loadInfo: function(info) {
        if(info && info.id == this.getID() && info.type == this.getType()) {
            if(this.getX() != info.x)
                this.setX(info.x, false, null);
            if(this.getY() != info.y)
                this.setY(info.y, false, null.y);
            return true;
        }
        return false;
    },

    onWidgetHide: function() {
        this.getGraphics().getHoverBox().onWidgetHide();
    }
});

var ChildlessBehavior = {

    /*
     * Returns null if the node has no childless markers.
     * Returns 'childless' if this node is marked childless
     * Returns 'infertile' if this node is marked infertile
     */
    getChildlessStatus: function() {
        return this._childlessStatus;
    },

    /*
     * Changes the childless status of this node
     *
     * @param status set to null, 'infertile' or 'childless'
     */
    setChildlessStatus: function(status) {
        var nonPlaceHolders = this.getChildren("Person","PersonGroup");
        if((status == 'infertile' || status == 'childless') && nonPlaceHolders.length == 0) {
            this._childlessStatus = status;
            var phChildren = this.getChildren("PlaceHolder");
            phChildren.each(function(child) {
                child.remove(false);
            });
        }
        else {
            this._childlessStatus = null;
            this.restorePlaceholders();
        }
        this.setChildlessReason(null);
        this.getGraphics().updateChildlessShapes();
    },

    /*
     * Returns the reason for this node's status of 'infertile' or 'childless'
     */
    getChildlessReason: function() {
        return this._childlessReason;
    },

    /*
     * Changes the reason for this node's 'childless' or 'infertile' status
     *
     * @param reason a string that explains the condition (eg. "By Choice", "Vasectomy" etc)
     */
    setChildlessReason: function(reason) {
        if(this.getChildlessStatus() != null) {
            this._childlessReason = reason;
            this.getGraphics().updateChildlessStatusLabel();
        }
    }
};<|endoftext|>


<commit_before>'use strict';

var element = document.getElementById( 'steamdb-extension-protip' );

if( element )
{
	element.setAttribute( 'hidden', true );
}

GetOption( { 'steamdb-highlight': true, 'steamdb-hide-not-interested': false }, function( items )
{
	if( !items[ 'steamdb-highlight' ] )
	{
		return;
	}

	var apps     = document.querySelectorAll( 'tr.app' ),
	    packages = document.querySelectorAll( 'tr.package' );

	if( apps.length > 0 || packages.length > 0 )
	{
		var xhr = new XMLHttpRequest();

		xhr.open( 'GET', 'https://store.steampowered.com/dynamicstore/userdata/', true );
		xhr.responseType = 'json';

		xhr.onreadystatechange = function()
		{
			if( xhr.readyState !== 4 || xhr.status !== 200 )
			{
				return;
			}

			var i, mapAppsToElements = [], mapPackagesToElements = [];

			for( i = 0; i < apps.length; i++ )
			{
				element = apps[ i ];

				mapAppsToElements[ element.dataset.appid ] = element;
			}

			apps = null;

			for( i = 0; i < packages.length; i++ )
			{
				element = packages[ i ];

				mapPackagesToElements[ element.dataset.subid ] = element;
			}

			packages = null;

			var data = xhr.response;

			if( mapAppsToElements.length > 0 )
			{
				// Wished apps
				for( i = 0; i < data.rgWishlist.length; i++ )
				{
					element = mapAppsToElements[ data.rgWishlist[ i ] ];

					if( element )
					{
						element.classList.add( 'wished' );
					}
				}

				// Owned apps
				for( i = 0; i < data.rgOwnedApps.length; i++ )
				{
					element = mapAppsToElements[ data.rgOwnedApps[ i ] ];

					if( element )
					{
						element.classList.add( 'owned' );
					}
				}

				// Apps in cart
				for( i = 0; i < data.rgAppsInCart.length; i++ )
				{
					element = mapAppsToElements[ data.rgAppsInCart[ i ] ];

					if( element )
					{
						element.classList.add( 'cart' );
					}
				}
			}

			if( mapPackagesToElements.length > 0 )
			{
				// Owned packages
				for( i = 0; i < data.rgOwnedPackages.length; i++ )
				{
					element = mapPackagesToElements[ data.rgOwnedPackages[ i ] ];

					if( element )
					{
						element.classList.add( 'owned' );
					}
				}

				// Packages in cart
				for( i = 0; i < data.rgPackagesInCart.length; i++ )
				{
					element = mapPackagesToElements[ data.rgPackagesInCart[ i ] ];

					if( element )
					{
						element.classList.add( 'cart' );
					}
				}
			}

			if( document.querySelector( '.scope-sales' ) )
			{
				if( items[ 'steamdb-hide-not-interested' ] )
				{
					for( i = 0; i < data.rgIgnoredApps.length; i++ )
					{
						element = mapAppsToElements[ data.rgIgnoredApps[ i ] ];

						if( element )
						{
							element.parentNode.removeChild( element );
						}
					}

					for( i = 0; i < data.rgIgnoredPackages.length; i++ )
					{
						element = mapPackagesToElements[ data.rgIgnoredPackages[ i ] ];

						if( element )
						{
							element.parentNode.removeChild( element );
						}
					}
				}

				if( document.querySelector( '#js-hide-owned-games.checked' ) )
				{
					var elements = document.querySelectorAll( '.appimg.owned' );

					for ( var i = 0; i < elements.length; i++ )
					{
						elements[ i ].hidden = true;
					}
				}
			}
		};

		xhr.send();
	}
} );
<commit_msg>Add "you own this package" on package pages<commit_after>'use strict';

var element = document.getElementById( 'steamdb-extension-protip' );

if( element )
{
	element.setAttribute( 'hidden', true );
}

GetOption( { 'steamdb-highlight': true, 'steamdb-hide-not-interested': false }, function( items )
{
	if( !items[ 'steamdb-highlight' ] )
	{
		return;
	}

	var apps     = document.querySelectorAll( 'tr.app' ),
	    packages = document.querySelectorAll( 'tr.package' ),
		packageScope = document.querySelector( '.scope-package' );

	if( apps.length > 0 || packages.length > 0 || packageScope )
	{
		var xhr = new XMLHttpRequest();

		xhr.open( 'GET', 'https://store.steampowered.com/dynamicstore/userdata/', true );
		xhr.responseType = 'json';

		xhr.onreadystatechange = function()
		{
			if( xhr.readyState !== 4 || xhr.status !== 200 )
			{
				return;
			}

			var i, mapAppsToElements = [], mapPackagesToElements = [];

			for( i = 0; i < apps.length; i++ )
			{
				element = apps[ i ];

				mapAppsToElements[ element.dataset.appid ] = element;
			}

			apps = null;

			for( i = 0; i < packages.length; i++ )
			{
				element = packages[ i ];

				mapPackagesToElements[ element.dataset.subid ] = element;
			}

			packages = null;

			var data = xhr.response, id;

			if( mapAppsToElements.length > 0 )
			{
				// Wished apps
				for( i = 0; i < data.rgWishlist.length; i++ )
				{
					element = mapAppsToElements[ data.rgWishlist[ i ] ];

					if( element )
					{
						element.classList.add( 'wished' );
					}
				}

				// Owned apps
				for( i = 0; i < data.rgOwnedApps.length; i++ )
				{
					element = mapAppsToElements[ data.rgOwnedApps[ i ] ];

					if( element )
					{
						element.classList.add( 'owned' );
					}
				}

				// Apps in cart
				for( i = 0; i < data.rgAppsInCart.length; i++ )
				{
					element = mapAppsToElements[ data.rgAppsInCart[ i ] ];

					if( element )
					{
						element.classList.add( 'cart' );
					}
				}
			}

			if( packageScope || mapPackagesToElements.length > 0 )
			{
				var scopeSubID = packageScope && packageScope.dataset.subid;

				// Owned packages
				for( i = 0; i < data.rgOwnedPackages.length; i++ )
				{
					id = data.rgOwnedPackages[ i ];
					element = mapPackagesToElements[ id ];

					if( element )
					{
						element.classList.add( 'owned' );
					}

					if( packageScope && scopeSubID == id )
					{
						packageScope = document.querySelector( '.panel-ownership' );

						if( packageScope )
						{
							packageScope.hidden = false;
						}
					}
				}

				// Packages in cart
				for( i = 0; i < data.rgPackagesInCart.length; i++ )
				{
					element = mapPackagesToElements[ data.rgPackagesInCart[ i ] ];

					if( element )
					{
						element.classList.add( 'cart' );
					}
				}
			}

			if( document.querySelector( '.scope-sales' ) )
			{
				if( items[ 'steamdb-hide-not-interested' ] )
				{
					for( i = 0; i < data.rgIgnoredApps.length; i++ )
					{
						element = mapAppsToElements[ data.rgIgnoredApps[ i ] ];

						if( element )
						{
							element.parentNode.removeChild( element );
						}
					}

					for( i = 0; i < data.rgIgnoredPackages.length; i++ )
					{
						element = mapPackagesToElements[ data.rgIgnoredPackages[ i ] ];

						if( element )
						{
							element.parentNode.removeChild( element );
						}
					}
				}

				if( document.querySelector( '#js-hide-owned-games.checked' ) )
				{
					var elements = document.querySelectorAll( '.appimg.owned' );

					for ( var i = 0; i < elements.length; i++ )
					{
						elements[ i ].hidden = true;
					}
				}
			}
		};

		xhr.send();
	}
} );
<|endoftext|>


<commit_before>var mysql  = require('mysql');
var connectionParams = require('../../config/connectionParams');
var pool  = mysql.createPool(connectionParams);

/*
  Creates a Fossil object from a database row
 */

function Fossil(databaseRow) {
  // From Link_CalibrationFossil and View_Fossils
  this.id = databaseRow['FossilID'];
  this.collection = databaseRow['CollectionAcro'];
  this.collectionNumber = databaseRow['CollectionNumber'];
  this.shortReference = databaseRow['ShortName'];
  this.fullReference = databaseRow['FullReference'];
  this.stratUnit = databaseRow['Stratum'];
  this.maxAge = databaseRow['MaxAge'];
  this.maxAgeType = databaseRow['MaxAgeType'];
  this.maxAgeTypeDetails = databaseRow['MaxAgeTypeOtherDetails'];
  this.minAge = databaseRow['MinAge'];
  this.minAgeType = databaseRow['MinAgeType'];
  this.minAgeTypeDetails = databaseRow['MinAgeTypeOtherDetails'];
  this.locationRelativeToNode= databaseRow['FossilLocationRelativeToNode'];
}

/*
  Creates a TipPair object from a database row
 */

function TipPair(databaseRow) {

}

/*
  Creates a calibration object from a database row
 */
function Calibration(databaseRow) {
  if(!databaseRow) {
    return;
  }
  // Properties to fill
  this.nodeName = databaseRow['NodeName'];
  this.nodeMinAge = databaseRow['MinAge'];
  this.nodeMaxAge = databaseRow['MaxAge'];
  this.calibrationReference = databaseRow['FullReference'];
  this.fossils = [];
  // fossils
  this.tipPairs = [];
  // tip_pairs
    // Tip 1 Name
    // Tip 2 Name
    // “Distance” of root from tip(s)?
}

function Calibrations() {
  var TABLE_NAME = 'View_Calibrations';
  // this callback is err, rows, fields
  function query(queryString, queryParams, callback) {
    return pool.query(queryString, queryParams, callback);
  }

  // Fetches a calibration and populates its fossils
  function getCalibration(calibrationId, callback) {
    fetchCalibration(calibrationId, function(err, calibration) {
      if(err) {
        callback(err);
      } else {
        // attach fossils
        fetchFossils(calibrationId, function (err, fossils) {
          if (err) {
            callback(err);
          } else {
            calibration.fossils = fossils;
            callback(null, calibration);
          }
        });
        // tips
        // images
      }
    });
  }

  // Fetch a single calibration from the database by ID and produce a single object
  function fetchCalibration(calibrationId, callback) {
    var queryString = 'SELECT * FROM ' + TABLE_NAME + ' WHERE CalibrationID = ?';
    query(queryString, [calibrationId], function(err, results) {
      if(err) {
        callback(null,err);
      } else {
        var calibrationResult = new Calibration(results[0]);
        callback(calibrationResult);
      }
    });
  }

  // Fetch Fossils for a calibration from the database and produce a list of fossils
  function fetchFossils(calibrationId, callback) {
    var queryString = 'SELECT F.*, L.* from Link_CalibrationFossil L, View_Fossils F WHERE L.CalibrationId = ? AND L.FossilID = F.FossilID';
    query(queryString, [calibrationId], function(err, results) {
      if(err) {
        callback(null,err);
      } else {
        var fossilResults = results.map(function(result) { return new Fossil(result); });
        callback(fossilResults);
      }
    });
  }

  this.findById = function(calibrationId, callback) {
    getCalibration(calibrationId, function(err, calibration) {
      if (err) {
        callback(null, err);
      } else {
        callback(calibration);
      }
    });
  };

  this.findByFilter = function(params, callback) {
    var queryString = 'SELECT CalibrationID FROM ' + TABLE_NAME + ' WHERE minAge > ? AND maxAge < ?';
    var calibrationResults = [];
    var success = function(result) {
      callback(result);
    };

    var failed = function(err) {
      callback(null, err);
    };

    query(queryString, [params.min, params.max], function(results, err) {
      if(err) {
        failed(err);
        return;
      }
      results.forEach(function(result, index, array) {
      var calibrationId = result['CalibrationID'];
        getCalibration(calibrationId, function(err, calibration) {
          if(err) {
            failed(err);
            return;
          }
          calibrationResults.push(calibration);
          // If this is the last one, finish everything up
          // This is done because mysql results are async
          // Could use the async node module to help a little bit, but this works for now
          if(index == array.length - 1) {
            success(calibrationResults);
            return;
          }
        });
      });
    });
  };

  // Calls callback with something like {'source':'NCBI', 'taxonid': 4}:
  function fetchNCBITaxonId(ncbiTaxonName, callback) {
    var queryString = 'SELECT taxonid, \'NCBI\' AS source FROM NCBI_names WHERE '
      + 'name LIKE ? OR uniquename LIKE ? LIMIT 1';
    query(queryString, [ncbiTaxonName, ncbiTaxonName], function(err, results) {
      if (err) {
        callback(err);
      } else {
        callback(null, results.length > 0 ? results[0] : null);
      }
    });
    // php code will fall back to FCD names
  }

  function fetchMultiTreeNodeId(source, taxonId, callback) {
    var queryString = 'SELECT getMultiTreeNodeID(?,?) AS node_id';
    query(queryString, [source, taxonId], function (err, results) {
      if (err) {
        callback(err);
      } else {
        // Results resemble this:
        // getMultiTreeNodeID('FCD-116',241); -> [{'node_id' : -1}]
        callback(null, results.length > 0 ? results[0].node_id : null);
      }
    });
  }

  function fetchCalibrationIdsInCladeMultiTree(multiTreeNodeId, callback) {
    var queryString = 'SELECT DISTINCT calibration_id FROM calibrations_by_NCBI_clade WHERE clade_root_multitree_id = ?';
    query(queryString, [multiTreeNodeId], function(err, results) {
      if (err) {
        callback(err);
      } else {
        var extractedIds = results.map(function(result) { return result['calibration_id']; });
        callback(null, extractedIds);
      }
    });
  }

  this.findByClade = function(params, callback) {
    // Search by clade.
    // Starts with a clade/taxon name
    var success = function(result) {
      callback(result);
    };

    var failed = function(err) {
      callback(null, err);
    };

    var taxonName = params.clade;
    fetchNCBITaxonId(taxonName, function(err, taxon) {
      // have a taxon id, now get the multi tree from the taxon
      if (err) {
        failed(err);
        return;
      }
      if(!taxon) {
        failed({error:'No node found for ' + taxonName});
        return;
      }
      fetchMultiTreeNodeId(taxon.source, taxon.taxonid, function(err, multiTreeNodeId) {
        if (err) {
          failed(err);
          return;
        }
        // have a multi tree, now see what calibrations are in it.
        var calibrationResults = [];
        fetchCalibrationIdsInCladeMultiTree(multiTreeNodeId, function(err, calibrationIds) {
          calibrationIds.forEach(function(calibrationId, index, array) {
            getCalibration(calibrationId, function(err, calibration) {
              if(err) {
                failed(err);
                return;
              }
              calibrationResults.push(calibration);
              if(index == array.length - 1) {
                success(calibrationResults);
                return;
              }
            });
          });
        });
      });

    });
    // Current algorithm in PHP:
    // calls nameToMultitreeID to get the multi tree ID from a clade name
      // calls nameToSourceNodeInfo with the taxon name
      // returns a multiTreeID. Prefixes this with 'mID:' and saves it in nodeValues
    // calls getAllCalibrationsInClade with the multitree id
    // adds calibrations to a result array

  };
}

module.exports = new Calibrations();<commit_msg>Fix callback orders again<commit_after>var mysql  = require('mysql');
var connectionParams = require('../../config/connectionParams');
var pool  = mysql.createPool(connectionParams);

/*
  Creates a Fossil object from a database row
 */

function Fossil(databaseRow) {
  // From Link_CalibrationFossil and View_Fossils
  this.id = databaseRow['FossilID'];
  this.collection = databaseRow['CollectionAcro'];
  this.collectionNumber = databaseRow['CollectionNumber'];
  this.shortReference = databaseRow['ShortName'];
  this.fullReference = databaseRow['FullReference'];
  this.stratUnit = databaseRow['Stratum'];
  this.maxAge = databaseRow['MaxAge'];
  this.maxAgeType = databaseRow['MaxAgeType'];
  this.maxAgeTypeDetails = databaseRow['MaxAgeTypeOtherDetails'];
  this.minAge = databaseRow['MinAge'];
  this.minAgeType = databaseRow['MinAgeType'];
  this.minAgeTypeDetails = databaseRow['MinAgeTypeOtherDetails'];
  this.locationRelativeToNode= databaseRow['FossilLocationRelativeToNode'];
}

/*
  Creates a TipPair object from a database row
 */

function TipPair(databaseRow) {

}

/*
  Creates a calibration object from a database row
 */
function Calibration(databaseRow) {
  if(!databaseRow) {
    return;
  }
  // Properties to fill
  this.nodeName = databaseRow['NodeName'];
  this.nodeMinAge = databaseRow['MinAge'];
  this.nodeMaxAge = databaseRow['MaxAge'];
  this.calibrationReference = databaseRow['FullReference'];
  this.fossils = [];
  // fossils
  this.tipPairs = [];
  // tip_pairs
    // Tip 1 Name
    // Tip 2 Name
    // “Distance” of root from tip(s)?
}

function Calibrations() {
  var TABLE_NAME = 'View_Calibrations';
  // this callback is err, rows, fields
  function query(queryString, queryParams, callback) {
    return pool.query(queryString, queryParams, callback);
  }

  // Fetches a calibration and populates its fossils
  function getCalibration(calibrationId, callback) {
    fetchCalibration(calibrationId, function(err, calibration) {
      if(err) {
        callback(err);
      } else {
        // attach fossils
        fetchFossils(calibrationId, function (err, fossils) {
          if (err) {
            callback(err);
          } else {
            calibration.fossils = fossils;
            callback(null, calibration);
          }
        });
        // tips
        // images
      }
    });
  }

  // Fetch a single calibration from the database by ID and produce a single object
  function fetchCalibration(calibrationId, callback) {
    var queryString = 'SELECT * FROM ' + TABLE_NAME + ' WHERE CalibrationID = ?';
    query(queryString, [calibrationId], function(err, results) {
      if(err) {
        callback(err);
      } else {
        var calibrationResult = new Calibration(results[0]);
        callback(null, calibrationResult);
      }
    });
  }

  // Fetch Fossils for a calibration from the database and produce a list of fossils
  function fetchFossils(calibrationId, callback) {
    var queryString = 'SELECT F.*, L.* from Link_CalibrationFossil L, View_Fossils F WHERE L.CalibrationId = ? AND L.FossilID = F.FossilID';
    query(queryString, [calibrationId], function(err, results) {
      if(err) {
        callback(err);
      } else {
        var fossilResults = results.map(function(result) { return new Fossil(result); });
        callback(null, fossilResults);
      }
    });
  }

  this.findById = function(calibrationId, callback) {
    getCalibration(calibrationId, function(err, calibration) {
      if (err) {
        callback(err);
      } else {
        callback(null, calibration);
      }
    });
  };

  this.findByFilter = function(params, callback) {
    var queryString = 'SELECT CalibrationID FROM ' + TABLE_NAME + ' WHERE minAge > ? AND maxAge < ?';
    var calibrationResults = [];
    var success = function(result) {
      callback(null, result);
    };

    var failed = function(err) {
      callback(err);
    };

    query(queryString, [params.min, params.max], function(err, results) {
      if(err) {
        failed(err);
        return;
      }
      results.forEach(function(result, index, array) {
      var calibrationId = result['CalibrationID'];
        getCalibration(calibrationId, function(err, calibration) {
          if(err) {
            failed(err);
            return;
          }
          calibrationResults.push(calibration);
          // If this is the last one, finish everything up
          // This is done because mysql results are async
          // Could use the async node module to help a little bit, but this works for now
          if(index == array.length - 1) {
            success(calibrationResults);
            return;
          }
        });
      });
    });
  };

  // Calls callback with something like {'source':'NCBI', 'taxonid': 4}:
  function fetchNCBITaxonId(ncbiTaxonName, callback) {
    var queryString = 'SELECT taxonid, \'NCBI\' AS source FROM NCBI_names WHERE '
      + 'name LIKE ? OR uniquename LIKE ? LIMIT 1';
    query(queryString, [ncbiTaxonName, ncbiTaxonName], function(err, results) {
      if (err) {
        callback(err);
      } else {
        callback(null, results.length > 0 ? results[0] : null);
      }
    });
    // php code will fall back to FCD names
  }

  function fetchMultiTreeNodeId(source, taxonId, callback) {
    var queryString = 'SELECT getMultiTreeNodeID(?,?) AS node_id';
    query(queryString, [source, taxonId], function (err, results) {
      if (err) {
        callback(err);
      } else {
        // Results resemble this:
        // getMultiTreeNodeID('FCD-116',241); -> [{'node_id' : -1}]
        callback(null, results.length > 0 ? results[0].node_id : null);
      }
    });
  }

  function fetchCalibrationIdsInCladeMultiTree(multiTreeNodeId, callback) {
    var queryString = 'SELECT DISTINCT calibration_id FROM calibrations_by_NCBI_clade WHERE clade_root_multitree_id = ?';
    query(queryString, [multiTreeNodeId], function(err, results) {
      if (err) {
        callback(err);
      } else {
        var extractedIds = results.map(function(result) { return result['calibration_id']; });
        callback(null, extractedIds);
      }
    });
  }

  this.findByClade = function(params, callback) {
    // Search by clade.
    // Starts with a clade/taxon name
    var success = function(result) {
      callback(null, result);
    };

    var failed = function(err) {
      callback(err);
    };

    var taxonName = params.clade;
    fetchNCBITaxonId(taxonName, function(err, taxon) {
      // have a taxon id, now get the multi tree from the taxon
      if (err) {
        failed(err);
        return;
      }
      if(!taxon) {
        failed({error:'No node found for ' + taxonName});
        return;
      }
      fetchMultiTreeNodeId(taxon.source, taxon.taxonid, function(err, multiTreeNodeId) {
        if (err) {
          failed(err);
          return;
        }
        // have a multi tree, now see what calibrations are in it.
        var calibrationResults = [];
        fetchCalibrationIdsInCladeMultiTree(multiTreeNodeId, function(err, calibrationIds) {
          calibrationIds.forEach(function(calibrationId, index, array) {
            getCalibration(calibrationId, function(err, calibration) {
              if(err) {
                failed(err);
                return;
              }
              calibrationResults.push(calibration);
              if(index == array.length - 1) {
                success(calibrationResults);
                return;
              }
            });
          });
        });
      });

    });
    // Current algorithm in PHP:
    // calls nameToMultitreeID to get the multi tree ID from a clade name
      // calls nameToSourceNodeInfo with the taxon name
      // returns a multiTreeID. Prefixes this with 'mID:' and saves it in nodeValues
    // calls getAllCalibrationsInClade with the multitree id
    // adds calibrations to a result array

  };
}

module.exports = new Calibrations();<|endoftext|>


<commit_before>var acg = acg || {};
var cc = cc || {};

acg.bootstrap = function (elem, callback) {
    'use strict';
    cc.game.onStart = function () {
        cc.view.adjustViewPort(true);
        if (cc.sys.isMobile) {
            cc.view.setDesignResolutionSize(480, 320, cc.ResolutionPolicy.FIXED_WIDTH);
        } else {
            cc.view.setDesignResolutionSize(480, 320, cc.ResolutionPolicy.SHOW_ALL);
        }
        cc.view.resizeWithBrowserSize(true);
        cc.director.setDisplayStats(true);
        cc.director.runScene(new cc.Scene());
    };
    cc.game.run(elem);
    // Wait until the director is ready, and then call the function
    if (callback) {
        var timer = setInterval(function () {
            if (cc.director && cc.director.getRunningScene()) {
                clearInterval(timer);
                callback();
            }
        }, 300);
    }
};
<commit_msg>Fix aspect ratio and add an option to change it<commit_after>var acg = acg || {};
var cc = cc || {};

acg.bootstrap = function (elem, aspect_ratio, callback) {
    'use strict';
    cc.game.onStart = function () {
        cc.view.adjustViewPort(true);
        cc.view.setDesignResolutionSize(320 * aspect_ratio, 320, cc.ResolutionPolicy.SHOW_ALL);
        cc.view.resizeWithBrowserSize(true);
        cc.director.setDisplayStats(true);
        cc.director.runScene(new cc.Scene());
    };
    cc.game.run(elem);
    // Wait until the director is ready, and then call the function
    if (callback) {
        var timer = setInterval(function () {
            if (cc.director && cc.director.getRunningScene()) {
                clearInterval(timer);
                callback();
            }
        }, 300);
    }
};
<|endoftext|>


<commit_before>'use strict';

var element = document.getElementById( 'steamdb-extension-protip' );

if( element )
{
	element.setAttribute( 'hidden', true );
}

GetOption( { 'steamdb-highlight': true, 'steamdb-hide-not-interested': false }, function( items )
{
	if( !items[ 'steamdb-highlight' ] )
	{
		return;
	}

	var apps     = document.querySelectorAll( 'tr.app' ),
	    packages = document.querySelectorAll( 'tr.package' ),
	    packageScope = document.querySelector( '.scope-package' ),
	    appScope = document.querySelector( '.scope-app' );

	if( apps.length > 0 || packages.length > 0 || appScope || packageScope )
	{
		var xhr = new XMLHttpRequest();

		var cache = localStorage.getItem( 'userdata.cached' );

		xhr.open( 'GET', 'https://store.steampowered.com/dynamicstore/userdata/?_=' + cache, true );
		xhr.responseType = 'json';

		xhr.onerror = function()
		{
			localStorage.setItem( 'userdata.cached', Date.now() );

			var id = document.createElement( 'div' );
			id.className = 'extension-warning';

			var icon = document.createElement( 'span' );
			icon.className = 'mega-octicon octicon-squirrel';

			id.appendChild( icon );
			id.appendChild( document.createTextNode( 'Failed to load game data from Steam store due to a network failure.' ) );

			document.body.appendChild( id );
		};

		xhr.onreadystatechange = function()
		{
			if( xhr.readyState !== 4 || xhr.status !== 200 )
			{
				return;
			}

			var data = xhr.response, id, i, mapAppsToElements = [], mapPackagesToElements = [];

			if( !data.rgOwnedPackages.length )
			{
				localStorage.setItem( 'userdata.cached', Date.now() );

				id = document.createElement( 'a' );
				id.className = 'extension-warning';
				id.href = 'https://store.steampowered.com/login/';

				var icon = document.createElement( 'span' );
				icon.className = 'mega-octicon octicon-hubot';

				id.appendChild( icon );
				id.appendChild( document.createTextNode( 'You are not logged in on Steam Store, highlighting will not work.' ) );

				document.body.appendChild( id );

				return;
			}

			for( i = 0; i < apps.length; i++ )
			{
				element = apps[ i ];

				mapAppsToElements[ element.dataset.appid ] = element;
			}

			apps = null;

			for( i = 0; i < packages.length; i++ )
			{
				element = packages[ i ];

				mapPackagesToElements[ element.dataset.subid ] = element;
			}

			packages = null;

			if( appScope || mapAppsToElements.length > 0 )
			{
				var scopeAppID = appScope && appScope.dataset.appid;

				// Wished apps
				for( i = 0; i < data.rgWishlist.length; i++ )
				{
					element = mapAppsToElements[ data.rgWishlist[ i ] ];

					if( element )
					{
						element.classList.add( 'wished' );
					}
				}

				// Owned apps
				for( i = 0; i < data.rgOwnedApps.length; i++ )
				{
					id = data.rgOwnedApps[ i ];
					element = mapAppsToElements[ id ];

					if( element )
					{
						element.classList.add( 'owned' );
					}

					if( scopeAppID == id )
					{
						appScope = document.querySelector( '.panel-ownership' );

						if( appScope )
						{
							appScope.hidden = false;
						}

						appScope = false;
					}
				}

				// Apps in cart
				for( i = 0; i < data.rgAppsInCart.length; i++ )
				{
					element = mapAppsToElements[ data.rgAppsInCart[ i ] ];

					if( element )
					{
						element.classList.add( 'cart' );
					}
				}
			}

			if( packageScope || mapPackagesToElements.length > 0 )
			{
				var scopeSubID = packageScope && packageScope.dataset.subid;

				// Owned packages
				for( i = 0; i < data.rgOwnedPackages.length; i++ )
				{
					id = data.rgOwnedPackages[ i ];
					element = mapPackagesToElements[ id ];

					if( element )
					{
						element.classList.add( 'owned' );
					}

					if( scopeSubID == id )
					{
						packageScope = document.querySelector( '.panel-ownership' );

						if( packageScope )
						{
							packageScope.hidden = false;
						}
					}
				}

				// Packages in cart
				for( i = 0; i < data.rgPackagesInCart.length; i++ )
				{
					element = mapPackagesToElements[ data.rgPackagesInCart[ i ] ];

					if( element )
					{
						element.classList.add( 'cart' );
					}
				}
			}

			// Show as owned if one of the packages is owned
			if( appScope )
			{
				appScope = document.querySelector( '.panel-ownership' );

				if( appScope && appScope.hidden && document.querySelector( '#subs .package.owned' ) )
				{
					appScope.hidden = false;
				}
			}

			if( document.querySelector( '.scope-sales' ) )
			{
				if( items[ 'steamdb-hide-not-interested' ] )
				{
					for( i = 0; i < data.rgIgnoredApps.length; i++ )
					{
						element = mapAppsToElements[ data.rgIgnoredApps[ i ] ];

						if( element )
						{
							element.parentNode.removeChild( element );
						}
					}

					for( i = 0; i < data.rgIgnoredPackages.length; i++ )
					{
						element = mapPackagesToElements[ data.rgIgnoredPackages[ i ] ];

						if( element )
						{
							element.parentNode.removeChild( element );
						}
					}
				}

				if( document.querySelector( '#js-hide-owned-games.checked' ) )
				{
					var elements = document.querySelectorAll( '.appimg.owned' );

					for( i = 0; i < elements.length; i++ )
					{
						elements[ i ].hidden = true;
					}
				}
			}
		};

		xhr.send();
	}
} );
<commit_msg>Add a close button to hide "not logged in" alert, cache successful requests so that cached data can be used when user is not logged in<commit_after>'use strict';

var element = document.getElementById( 'steamdb-extension-protip' );

if( element )
{
	element.setAttribute( 'hidden', true );
}

GetOption( { 'steamdb-highlight': true, 'steamdb-hide-not-interested': false }, function( items )
{
	if( !items[ 'steamdb-highlight' ] )
	{
		return;
	}

	var apps     = document.querySelectorAll( 'tr.app' ),
	    packages = document.querySelectorAll( 'tr.package' ),
	    packageScope = document.querySelector( '.scope-package' ),
	    appScope = document.querySelector( '.scope-app' );

	if( apps.length > 0 || packages.length > 0 || appScope || packageScope )
	{
		var xhr = new XMLHttpRequest();

		function AddCloseButton( element )
		{
			var x = document.createElement( 'span' );
			x.className = 'octicon octicon-x';

			var link = document.createElement( 'a' );
			link.className = 'pull-right tooltipped tooltipped-nw';
			link.href = '#';
			link.style.color = '#FFF';
			link.setAttribute( 'aria-label', 'Do not show this message again' );
			link.appendChild( x );

			link.addEventListener( 'click', function( e )
			{
				e.preventDefault();

				this.parentNode.parentNode.removeChild( this.parentNode );

				localStorage.setItem( 'userdata.warning.hidden', 'true' );
			} );

			element.appendChild( link );
		};

		var cache = localStorage.getItem( 'userdata.cached' );

		xhr.open( 'GET', 'https://store.steampowered.com/dynamicstore/userdata/?_=' + cache, true );
		xhr.responseType = 'json';

		xhr.onerror = function()
		{
			TryToUseCachedData( );

			localStorage.setItem( 'userdata.cached', Date.now() );

			if( localStorage.getItem( 'userdata.warning.hidden' ) === 'true' )
			{
				return;
			}

			var id = document.createElement( 'div' );
			id.className = 'extension-warning';

			AddCloseButton( id );

			var icon = document.createElement( 'span' );
			icon.className = 'mega-octicon octicon-squirrel';

			id.appendChild( icon );
			id.appendChild( document.createTextNode( 'Failed to load game data from Steam store due to a network failure.' ) );

			document.body.appendChild( id );
		};

		xhr.onreadystatechange = function()
		{
			if( xhr.readyState !== 4 || xhr.status !== 200 )
			{
				return;
			}

			if( !xhr.response.rgOwnedPackages.length )
			{
				TryToUseCachedData( );

				localStorage.setItem( 'userdata.cached', Date.now() );

				if( localStorage.getItem( 'userdata.warning.hidden' ) === 'true' )
				{
					return;
				}

				var id = document.createElement( 'a' );
				id.className = 'extension-warning';
				id.href = 'https://store.steampowered.com/login/';

				AddCloseButton( id );

				var icon = document.createElement( 'span' );
				icon.className = 'mega-octicon octicon-hubot';

				id.appendChild( icon );
				id.appendChild( document.createTextNode( 'You are not logged in on Steam Store, owned game highlighting will not work.' ) );

				document.body.appendChild( id );

				return;
			}

			OnDataLoaded( xhr.response );

			// TODO: This shouldn't be executed if browser cache was hit
			if( typeof chrome !== 'undefined' )
			{
				chrome.storage.local.set( { 'userdata.stored': JSON.stringify( xhr.response ) } );
			}
		};

		function TryToUseCachedData( )
		{
			chrome.storage.local.get( 'userdata.stored', function( data )
			{
				if( data[ 'userdata.stored' ] )
				{
					OnDataLoaded( JSON.parse( data[ 'userdata.stored' ] ) );
				}
			} );
		}

		function OnDataLoaded( data )
		{
			var id, i, mapAppsToElements = [], mapPackagesToElements = [];

			for( i = 0; i < apps.length; i++ )
			{
				element = apps[ i ];

				mapAppsToElements[ element.dataset.appid ] = element;
			}

			apps = null;

			for( i = 0; i < packages.length; i++ )
			{
				element = packages[ i ];

				mapPackagesToElements[ element.dataset.subid ] = element;
			}

			packages = null;

			if( appScope || mapAppsToElements.length > 0 )
			{
				var scopeAppID = appScope && appScope.dataset.appid;

				// Wished apps
				for( i = 0; i < data.rgWishlist.length; i++ )
				{
					element = mapAppsToElements[ data.rgWishlist[ i ] ];

					if( element )
					{
						element.classList.add( 'wished' );
					}
				}

				// Owned apps
				for( i = 0; i < data.rgOwnedApps.length; i++ )
				{
					id = data.rgOwnedApps[ i ];
					element = mapAppsToElements[ id ];

					if( element )
					{
						element.classList.add( 'owned' );
					}

					if( scopeAppID == id )
					{
						appScope = document.querySelector( '.panel-ownership' );

						if( appScope )
						{
							appScope.hidden = false;
						}

						appScope = false;
					}
				}

				// Apps in cart
				for( i = 0; i < data.rgAppsInCart.length; i++ )
				{
					element = mapAppsToElements[ data.rgAppsInCart[ i ] ];

					if( element )
					{
						element.classList.add( 'cart' );
					}
				}
			}

			if( packageScope || mapPackagesToElements.length > 0 )
			{
				var scopeSubID = packageScope && packageScope.dataset.subid;

				// Owned packages
				for( i = 0; i < data.rgOwnedPackages.length; i++ )
				{
					id = data.rgOwnedPackages[ i ];
					element = mapPackagesToElements[ id ];

					if( element )
					{
						element.classList.add( 'owned' );
					}

					if( scopeSubID == id )
					{
						packageScope = document.querySelector( '.panel-ownership' );

						if( packageScope )
						{
							packageScope.hidden = false;
						}
					}
				}

				// Packages in cart
				for( i = 0; i < data.rgPackagesInCart.length; i++ )
				{
					element = mapPackagesToElements[ data.rgPackagesInCart[ i ] ];

					if( element )
					{
						element.classList.add( 'cart' );
					}
				}
			}

			// Show as owned if one of the packages is owned
			if( appScope )
			{
				appScope = document.querySelector( '.panel-ownership' );

				if( appScope && appScope.hidden && document.querySelector( '#subs .package.owned' ) )
				{
					appScope.hidden = false;
				}
			}

			if( document.querySelector( '.scope-sales' ) )
			{
				if( items[ 'steamdb-hide-not-interested' ] )
				{
					for( i = 0; i < data.rgIgnoredApps.length; i++ )
					{
						element = mapAppsToElements[ data.rgIgnoredApps[ i ] ];

						if( element )
						{
							element.parentNode.removeChild( element );
						}
					}

					for( i = 0; i < data.rgIgnoredPackages.length; i++ )
					{
						element = mapPackagesToElements[ data.rgIgnoredPackages[ i ] ];

						if( element )
						{
							element.parentNode.removeChild( element );
						}
					}
				}

				if( document.querySelector( '#js-hide-owned-games.checked' ) )
				{
					var elements = document.querySelectorAll( '.appimg.owned' );

					for( i = 0; i < elements.length; i++ )
					{
						elements[ i ].hidden = true;
					}
				}
			}
		};

		xhr.send();
	}
} );
<|endoftext|>


<commit_before>/*
 * The OnCore Consulting LLC License
 *
 * Copyright 2016 OnCore Consulting LLC, All Rights Reserved.
 *
 * Permission IS NOT GRANTED to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, unless the following conditions are met:
 *
 * Written permission is obtained from
 * OnCore Consulting LLC and the above copyright
 * notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

var ProductHelper = new function ()
{
    /**
     * Gets the photo for a product and sets it on the product image
     */
    this.getPhoto = function (product)
    {
        if (product === undefined || product === null || product.prdImgImage === null
                || product.prdImgImage === undefined || product.prdImgImage.length === 0)
        {
            var src = '../../css/images/unknown_product.jpg';
            return src;
        }
        else
        {
            var file = product.prdImgImage;

            var imageSize = product.prdImgImage.length;
            var imageType = product.prdImgTypeCd.longDesc;

            var reader = new FileReader();

            var data = window.atob(file);
            var arr = new Uint8Array(data.length);
            for (var i = 0; i < data.length; i++) {
                arr[i] = data.charCodeAt(i);
            }

            var blob = new Blob([arr.buffer], {size: imageSize, type: imageType});

            reader.addEventListener("load", function (event) {
                var preview = document.getElementById('productImage' + product.prdUid);

                if ( preview !== null)
                {
                    preview.src = reader.result;
                }
            }, false);

            if (blob) {

                try {
                    reader.readAsDataURL(blob);

                } catch (err)
                {
                    console.log(err);
                }
            }
        }
    };

    this.addProductToCart = function (product)
    {
        var cartProducts;

        // Get cart - if no cart yet then initialize
        if (sessionStorage.cartProducts !== undefined && sessionStorage.cartProducts !== "")
        {
            cartProducts = JSON.parse(sessionStorage.cartProducts);

        } else
        {
            cartProducts = [];
        }

        // If the product already exists in the cart, then just change the quantity
        var result = $.grep(cartProducts, function (item) {
            return item.prdUid === product.prdUid;
        });
        var cartProduct;

        if (result.length === 1)
        {
            cartProduct = result[0];
            cartProduct.quantity += product.quantity();
        } else
        {
            cartProduct = product;
            cartProduct.quantity = product.quantity();
            cartProducts.push(cartProduct);
        }

        console.log("CART CONTENTS:");
        var val;
        for (val in cartProducts)
        {
            console.log("     Prodcut Id: " + cartProducts[val].prdUid + " - Quantity: " + cartProducts[val].quantity);
        }

        // Save cart back into session
        sessionStorage.cartProducts = JSON.stringify(cartProducts);
    }
    ;
};

<commit_msg>[#140101045] Updated the code that added products to the cart in regards to quantity. It was previoulsy changing the 'quantity' field from an observable to a normal int value incorreclty.<commit_after>/*
 * The OnCore Consulting LLC License
 *
 * Copyright 2016 OnCore Consulting LLC, All Rights Reserved.
 *
 * Permission IS NOT GRANTED to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, unless the following conditions are met:
 *
 * Written permission is obtained from
 * OnCore Consulting LLC and the above copyright
 * notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

var ProductHelper = new function ()
{
    /**
     * Gets the photo for a product and sets it on the product image
     */
    this.getPhoto = function (product)
    {
        if (product === undefined || product === null || product.prdImgImage === null
                || product.prdImgImage === undefined || product.prdImgImage.length === 0)
        {
            var src = '../../css/images/unknown_product.jpg';
            return src;
        }
        else
        {
            var file = product.prdImgImage;

            var imageSize = product.prdImgImage.length;
            var imageType = product.prdImgTypeCd.longDesc;

            var reader = new FileReader();

            var data = window.atob(file);
            var arr = new Uint8Array(data.length);
            for (var i = 0; i < data.length; i++) {
                arr[i] = data.charCodeAt(i);
            }

            var blob = new Blob([arr.buffer], {size: imageSize, type: imageType});

            reader.addEventListener("load", function (event) {
                var preview = document.getElementById('productImage' + product.prdUid);

                if ( preview !== null)
                {
                    preview.src = reader.result;
                }
            }, false);

            if (blob) {

                try {
                    reader.readAsDataURL(blob);

                } catch (err)
                {
                    console.log(err);
                }
            }
        }
    };

    this.addProductToCart = function (product)
    {
        var cartProducts;

        // Get cart - if no cart yet then initialize
        if (sessionStorage.cartProducts !== undefined && sessionStorage.cartProducts !== "")
        {
            cartProducts = JSON.parse(sessionStorage.cartProducts);

        } else
        {
            cartProducts = [];
        }

        // If the product already exists in the cart, then just change the quantity
        var result = $.grep(cartProducts, function (item) {
            return item.prdUid === product.prdUid;
        });
        var cartProduct;

        if (result.length === 1)
        {
            cartProduct = result[0];
            cartProduct.quantity += product.quantity();
        } else
        {
            // Deep copy
            cartProduct = jQuery.extend(true, {}, product);
            cartProduct.quantity = product.quantity();
            cartProducts.push(cartProduct);
        }

        console.log("CART CONTENTS:");
        var val;
        for (val in cartProducts)
        {
            console.log("     Prodcut Id: " + cartProducts[val].prdUid + " - Quantity: " + cartProducts[val].quantity);
        }

        // Save cart back into session
        sessionStorage.cartProducts = JSON.stringify(cartProducts);
    }
    ;
};

<|endoftext|>