<commit_before>// Override necessary parts of website/static/src/js/website.seo.js to enable
// META robots management via promote panel.
//
// We need to override all needed function. We don't can use the super function
// here.

(function () {
    'use strict';

    var website = openerp.website;
    website.add_template_file('/website_seo/static/src/xml/website_seo_robots.xml');

    website.seo.HtmlPage.include({
        robots: function() {
            var $robots = $('meta[name=robots]');
            return ($robots.length > 0) && ($robots.attr('content') && $robots.attr('content').trim());
        },
        changeRobots: function(robots) {
            $('meta[name=robots]').attr('content', robots);
            this.trigger('robots-changed', robots);
        },
        seo_url: function () {
            var $seo_url = $('meta[name=seo_url]');
            return ($seo_url.length > 0) && ($seo_url.attr('content') && $seo_url.attr('content').trim());
        },
        changeSeoUrl: function (seo_url) {
            $('meta[name=seo_url]').attr('content', seo_url);
            this.trigger('seo_url-changed', seo_url);
        },
    });

    website.seo.Configurator.include({
        events: {
            'keyup input[name=seo_page_keywords]': 'confirmKeyword',
            'keyup input[name=seo_page_title]': 'titleChanged',
            'keyup textarea[name=seo_page_description]': 'descriptionChanged',
            'change select[name=seo_page_robots]': 'robotsChanged',
            'keyup input[name=seo_url]': 'seoUrlChanged',
            'click button[data-action=add]': 'addKeyword',
            'click button[data-action=update]': 'update',
            'hidden.bs.modal': 'destroy'
        },
        canEditRobots: false,
        canEditSeoUrl: false,
        start: function() {
            var self = this;
            var $modal = self.$el;
            var htmlPage = this.htmlPage = new website.seo.HtmlPage();
            $modal.find('.js_seo_page_url').text(htmlPage.url());
            $modal.find('input[name=seo_page_title]').val(htmlPage.title());
            $modal.find('textarea[name=seo_page_description]').val(htmlPage.description());
            $modal.find('select[name=seo_page_robots]').val(htmlPage.robots());
            $modal.find('input[name=seo_url]').val(htmlPage.seo_url());

		var path = window.location.href.replace('#', '').slice(-1);
            if (path === '/'){
                $('input[name=seo_url]').css('visibility','hidden');
                $('label[for=seo_url]').css('visibility','hidden');
            }

            self.keywordList = new website.seo.KeywordList(self, { page: htmlPage });
            self.keywordList.on('list-full', self, function() {
                $modal.find('input[name=seo_page_keywords]')
                    .attr('readonly', "readonly")
                    .attr('placeholder', "Remove a keyword first");
                $modal.find('button[data-action=add]')
                    .prop('disabled', true).addClass('disabled');
            });
            self.keywordList.on('list-not-full', self, function() {
                $modal.find('input[name=seo_page_keywords]')
                    .removeAttr('readonly').attr('placeholder', "");
                $modal.find('button[data-action=add]')
                    .prop('disabled', false).removeClass('disabled');
            });
            self.keywordList.on('selected', self, function(word) {
                self.keywordList.add(word);
            });
            self.keywordList.appendTo($modal.find('.js_seo_keywords_list'));
            self.disableUnsavableFields();
            self.renderPreview();
            $modal.modal();
        },
        disableUnsavableFields: function () {
            var self = this;
            var $modal = self.$el;
            self.loadMetaData().then(function(data) {
                self.canEditTitle = data && ('website_meta_title' in data);
                self.canEditDescription = data && ('website_meta_description' in data);
                self.canEditKeywords = data && ('website_meta_keywords' in data);
                // Allow editing the meta robots only for pages that have
                self.canEditRobots = data && ('website_meta_robots' in data);
                self.canEditSeoUrl = data && ('seo_url' in data);
                if (!self.canEditTitle) {
                    $modal.find('input[name=seo_page_title]').attr('disabled', true);
                }
                if (!self.canEditDescription) {
                    $modal.find('textarea[name=seo_page_description]').attr('disabled', true);
                }
                if (!self.canEditTitle && !self.canEditDescription && !self.canEditKeywords) {
                    $modal.find('button[data-action=update]').attr('disabled', true);
                }
                if (!self.canEditRobots) {
                    $modal.find('select[name=seo_page_robots]').attr('disabled', true);
                }
                if (!self.canEditSeoUrl) {
                    $modal.find('input[name=seo_url]').attr('disabled', true);
                }
            });
        },
        suggestField: function (field) {
            var tip = self.$('.js_seo_' + field + '_tips');
            if (tip.children().length === 0) {
                var model = website.session.model('website.seo.metadata');
                model.call('get_information_from', [field, website.get_context()]).then(function(data) {
                    if (data.length){
                        new website.seo.Tip(self, {
                            message: data,
                            type: 'info'
                        }).appendTo(tip);
                    }
                });
            }
            else {
                tip.children()[0].remove();
            }
        },
        update: function () {
            var self = this;
            var data = {};
            if (self.canEditTitle) {
                data.website_meta_title = self.htmlPage.title();
            }
            if (self.canEditDescription) {
                data.website_meta_description = self.htmlPage.description();
            }
            if (self.canEditKeywords) {
                data.website_meta_keywords = self.keywordList.keywords().join(", ");
            }
            if (self.canEditRobots) {
                data.website_meta_robots = self.htmlPage.robots();
            }
            if (self.canEditSeoUrl) {
                data.seo_url = self.htmlPage.seo_url();
            }

            self.saveMetaData(data).then(function() {
                self.$el.modal('hide');
                location.replace(data.seo_url, 301);
            });
        },
        loadMetaData: function () {
            var self = this;
            var obj = this.getMainObject();
            var def = $.Deferred();
            if (!obj) {
                def.resolve(null);
            } else {
                var fields = ['website_meta_title', 'website_meta_description', 'website_meta_keywords', 'website_meta_robots', 'seo_url'];
                var model = website.session.model(obj.model);
                model.call('read', [[obj.id], fields, website.get_context()]).then(function(data) {
                    if (data.length) {
                        var meta = data[0];
                        meta.model = obj.model;
                        def.resolve(meta);
                    } else {
                        def.resolve(null);
                    }
                }).fail(function() {
                        def.reject();
                });
            }
            return def;
        },
        robotsChanged: function () {
            var self = this;
            setTimeout(function () {
                var robots = self.$('select[name=seo_page_robots]').val();
                self.htmlPage.changeRobots(robots);
                self.renderPreview();
            }, 0);
        },
        seoUrlChanged: function () {
            var self = this;
            setTimeout(function () {
                var seo_url = self.$('input[name=seo_url]').val();
                self.htmlPage.changeSeoUrl(seo_url);
                self.renderPreview();
            }, 0);
        },
    });

    website.ready().done(function() {
        $(document.body).on('click', '#title_tip', function() {
            new website.seo.Configurator(this).suggestField('website_meta_title');
        });
        $(document.body).on('click', '#description_tip', function() {
            new website.seo.Configurator(this).suggestField('website_meta_description');
        });
    });

})();<commit_msg>[IMP] adding updates from v9<commit_after>// Override necessary parts of website/static/src/js/website.seo.js to enable
// META robots management via promote panel.
//
// We need to override all needed function. We don't can use the super function
// here.

(function () {
    'use strict';

    var website = openerp.website;
    website.add_template_file('/website_seo/static/src/xml/website_seo_robots.xml');

    website.seo.HtmlPage.include({
        robots: function() {
            var $robots = $('meta[name=robots]');
            return ($robots.length > 0) && ($robots.attr('content') && $robots.attr('content').trim());
        },
        changeRobots: function(robots) {
            $('meta[name=robots]').attr('content', robots);
            this.trigger('robots-changed', robots);
        },
        seo_url: function () {
            var $seo_url = $('meta[name=seo_url]');
            return ($seo_url.length > 0) && ($seo_url.attr('content') && $seo_url.attr('content').trim());
        },
        changeSeoUrl: function (seo_url) {
            $('meta[name=seo_url]').attr('content', seo_url);
            this.trigger('seo_url-changed', seo_url);
        },
    });

    website.seo.Configurator.include({
        events: {
            'keyup input[name=seo_page_keywords]': 'confirmKeyword',
            'keyup input[name=seo_page_title]': 'titleChanged',
            'keyup textarea[name=seo_page_description]': 'descriptionChanged',
            'change select[name=seo_page_robots]': 'robotsChanged',
            'keyup input[name=seo_url]': 'seoUrlChanged',
            'click button[data-action=add]': 'addKeyword',
            'click button[data-action=update]': 'update',
            'hidden.bs.modal': 'destroy'
        },
        canEditRobots: false,
        canEditSeoUrl: false,
        start: function() {
            var self = this;
            var $modal = self.$el;
            var htmlPage = this.htmlPage = new website.seo.HtmlPage();
            $modal.find('.js_seo_page_url').text(htmlPage.url());
            $modal.find('input[name=seo_page_title]').val(htmlPage.title());
            $modal.find('textarea[name=seo_page_description]').val(htmlPage.description());
            $modal.find('select[name=seo_page_robots]').val(htmlPage.robots());
            $modal.find('input[name=seo_url]').val(htmlPage.seo_url());

		    var path = window.location.href.replace('#', '').slice(-1);
            if (path === '/'){
                $('input[name=seo_url]').css('visibility','hidden');
                $('label[for=seo_url]').css('visibility','hidden');
            }

            self.keywordList = new website.seo.KeywordList(self, { page: htmlPage });
            self.keywordList.on('list-full', self, function() {
                $modal.find('input[name=seo_page_keywords]')
                    .attr('readonly', "readonly")
                    .attr('placeholder', "Remove a keyword first");
                $modal.find('button[data-action=add]')
                    .prop('disabled', true).addClass('disabled');
            });
            self.keywordList.on('list-not-full', self, function() {
                $modal.find('input[name=seo_page_keywords]')
                    .removeAttr('readonly').attr('placeholder', "");
                $modal.find('button[data-action=add]')
                    .prop('disabled', false).removeClass('disabled');
            });
            self.keywordList.on('selected', self, function(word) {
                self.keywordList.add(word);
            });
            self.keywordList.appendTo($modal.find('.js_seo_keywords_list'));
            self.disableUnsavableFields();
            self.renderPreview();
            $modal.modal();
        },
        disableUnsavableFields: function () {
            var self = this;
            var $modal = self.$el;
            self.loadMetaData().then(function(data) {
                self.canEditTitle = data && ('website_meta_title' in data);
                self.canEditDescription = data && ('website_meta_description' in data);
                self.canEditKeywords = data && ('website_meta_keywords' in data);
                // Allow editing the meta robots only for pages that have
                self.canEditRobots = data && ('website_meta_robots' in data);
                self.canEditSeoUrl = data && ('seo_url' in data);
                if (!self.canEditTitle) {
                    $modal.find('input[name=seo_page_title]').attr('disabled', true);
                }
                if (!self.canEditDescription) {
                    $modal.find('textarea[name=seo_page_description]').attr('disabled', true);
                }
                if (!self.canEditTitle && !self.canEditDescription && !self.canEditKeywords) {
                    $modal.find('button[data-action=update]').attr('disabled', true);
                }
                if (!self.canEditRobots) {
                    $modal.find('select[name=seo_page_robots]').attr('disabled', true);
                }
                if (!self.canEditSeoUrl) {
                    $modal.find('input[name=seo_url]').attr('disabled', true);
                }
            });
        },
        suggestField: function (field) {
            var tip = self.$('.js_seo_' + field + '_tips');
            if (tip.children().length === 0) {
                var model = website.session.model('website.seo.metadata');
                model.call('get_information_from', [field, website.get_context()]).then(function(data) {
                    if (data.length){
                        new website.seo.Tip(self, {
                            message: data,
                            type: 'info'
                        }).appendTo(tip);
                    }
                });
            }
            else {
                tip.children()[0].remove();
            }
        },
        update: function () {
            var self = this;
            var data = {};
            if (self.canEditTitle) {
                data.website_meta_title = self.htmlPage.title();
            }
            if (self.canEditDescription) {
                data.website_meta_description = self.htmlPage.description();
            }
            if (self.canEditKeywords) {
                data.website_meta_keywords = self.keywordList.keywords().join(", ");
            }
            if (self.canEditRobots) {
                data.website_meta_robots = self.htmlPage.robots();
            }
            if (self.canEditSeoUrl) {
                data.seo_url = self.htmlPage.seo_url();
            }

            self.saveMetaData(data).then(function() {
                self.$el.modal('hide');
                location.replace(data.seo_url, 301);
            });
        },
        loadMetaData: function () {
            var self = this;
            var obj = this.getMainObject();
            var def = $.Deferred();
            if (!obj) {
                def.resolve(null);
            } else {
                var fields = ['website_meta_title', 'website_meta_description', 'website_meta_keywords', 'website_meta_robots', 'seo_url'];
                var model = website.session.model(obj.model);
                model.call('read', [[obj.id], fields, website.get_context()]).then(function(data) {
                    if (data.length) {
                        var meta = data[0];
                        meta.model = obj.model;
                        def.resolve(meta);
                    } else {
                        def.resolve(null);
                    }
                }).fail(function() {
                        def.reject();
                });
            }
            return def;
        },
        robotsChanged: function () {
            var self = this;
            setTimeout(function () {
                var robots = self.$('select[name=seo_page_robots]').val();
                self.htmlPage.changeRobots(robots);
                self.renderPreview();
            }, 0);
        },
        seoUrlChanged: function () {
            var self = this;
            setTimeout(function () {
                var seo_url = self.$('input[name=seo_url]').val();
                self.htmlPage.changeSeoUrl(seo_url);
                self.renderPreview();
            }, 0);
        },
    });

    website.ready().done(function() {
        $(document.body).on('click', '#title_tip', function() {
            new website.seo.Configurator(this).suggestField('website_meta_title');
        });
        $(document.body).on('click', '#description_tip', function() {
            new website.seo.Configurator(this).suggestField('website_meta_description');
        });
    });

})();<|endoftext|>


<commit_before>'use strict';

var Transitionable = require('famous-transitions').Transitionable;
var CoreSize = require('famous-core').Size;

/**
 * Size component used for managing the size of the underlying RenderContext.
 * Supports absolute and relative (proportional and differential) sizing.
 *
 * @class Size
 * @constructor
 * @component
 *
 * @param {LocalDispatch} node LocalDispatch to be retrieved from
 *                                 corresponding RenderNode of the Size
 *                                 component
 */
function Size(node) {
    this._node = node;
    this._id = node.addComponent(this);
    this._requestingUpdate = false;
    this._proportional = {
        x: new Transitionable(1),
        y: new Transitionable(1),
        z: new Transitionable(1)
    };
    this._differential = {
        x: new Transitionable(0),
        y: new Transitionable(0),
        z: new Transitionable(0)
    };
    this._absolute = {
        x: new Transitionable(0),
        y: new Transitionable(0),
        z: new Transitionable(0)
    };
}

Size.RELATIVE = CoreSize.RELATIVE;
Size.ABSOLUTE = CoreSize.ABSOLUTE;
Size.RENDER = CoreSize.RENDER;
Size.DEFAULT = CoreSize.DEFAULT;

Size.prototype.setMode = function setMode(x, y, z) {
    this._node.setSizeMode(x, y, z);
    return this;
};

/**
* Stringifies Size.
*
* @method toString
*
* @return {String} `Size`
*/
Size.toString = function toString() {
    return 'Size';
};

/**
 * @typedef absoluteSizeValue
 * @type {Object}
 * @property {String} type current type of sizing being applied ('absolute')
 * @property {String} component component name ('Size')
 * @property {number} x
 * @property {number} y
 * @property {number} z
 */

/**
 * @typedef relativeSizeValue
 * @type {Object}
 * @property {String} type current type of sizing being applied ('relative')
 * @property {String} component component name ('Size')
 * @property {Object} differential
 * @property {number} differential.x
 * @property {number} differential.y
 * @property {number} differential.z
 * @property {Object} proportional
 * @property {number} proportional.x
 * @property {number} proportional.y
 * @property {number} proportional.z
 */

/**
* Returns serialized state of the component.
*
* @method getValue
*
* @return {absoluteSizeValue|relativeSizeValue}
*/
Size.prototype.getValue = function getValue() {
    return {
        sizeMode: this._node.value.sizeMode,
        absolute: {
            x: this._absolute.x.get(),
            y: this._absolute.y.get(),
            z: this._absolute.z.get()
        },
        differential: {
            x: this._differential.x.get(),
            y: this._differential.y.get(),
            z: this._differential.z.get()
        },
        proportional: {
            x: this._proportional.x.get(),
            y: this._proportional.y.get(),
            z: this._proportional.z.get()
        }
    };
};

/**
* Updates state of component.
*
* @method setValue
*
* @param {absoluteSizeValue|relativeSizeValue} state state encoded in same
*                                                    format as state retrieved
*                                                    through `getValue`
* @return {Boolean}                                  boolean indicating
*                                                    whether the new state has
*                                                    been applied
*/
Size.prototype.setValue = function setValue(state) {
    if (state.component === this.constructor.toString()) {
        this.setMode.apply(this, state.sizeMode);
        if (state.absolute) {
            this.setAbsolute(state.absolute.x, state.absolute.y, state.absolute.z);
        }
        if (state.differential) {
            this.setAbsolute(state.differential.x, state.differential.y, state.differential.z);
        }
        if (state.proportional) {
            this.setAbsolute(state.proportional.x, state.proportional.y, state.proportional.z);
        }
    }
    return false;
};

Size.prototype._isActive = function _isActive(type) {
    return type.x.isActive() || type.y.isActive() || type.z.isActive();
};

Size.prototype.isActive = function isActive(){
    return (
        this._isActive(this._absolute) ||
        this._isActive(this._proportional) ||
        this._isActive(this._differential)
    );
};

Size.prototype.onUpdate = function onUpdate() {
    var abs = this._absolute;
    this._node.setAbsoluteSize(
        abs.x.get(),
        abs.y.get(),
        abs.z.get()
    );
    var prop = this._proportional;
    var diff = this._differential;
    this._node.setProportionalSize(
        prop.x.get(),
        prop.y.get(),
        prop.z.get()
    );
    this._node.setDifferentialSize(
        diff.x.get(),
        diff.y.get(),
        diff.z.get()
    );

    if (this.isActive()) this._node.requestUpdateOnNextTick(this._id);
    else this._requestingUpdate = false;
};

/**
* Applies absolute size.
*
* @method setAbsolute
* @chainable
*
* @param {Number} x used to set absolute size in x-direction (width)
* @param {Number} y used to set absolute size in y-direction (height)
* @param {Number} z used to set absolute size in z-direction (depth)
* @param {Object} options options hash
* @param {Function} callback callback function to be executed after the
*                            transitions have been completed
* @return {Size} this
*/
Size.prototype.setAbsolute = function setAbsolute(x, y, z, options, callback) {
    if (!this._requestingUpdate) {
        this._node.requestUpdate(this._id);
        this._requestingUpdate = true;
    }
    var abs = this._absolute;
    if (x != null) {
        abs.x.set(x, options, callback);
    }
    if (y != null) {
        abs.y.set(y, options, callback);
    }
    if (z != null) {
        abs.z.set(z, options, callback);
    }
};

/**
* Applies proportional size.
*
* @method setProportional
* @chainable
*
* @param {Number} x used to set proportional size in x-direction (width)
* @param {Number} y used to set proportional size in y-direction (height)
* @param {Number} z used to set proportional size in z-direction (depth)
* @param {Object} options options hash
* @param {Function} callback callback function to be executed after the
*                            transitions have been completed
* @return {Size} this
*/
Size.prototype.setProportional = function setProportional(x, y, z, options, callback) {
    if (!this._requestingUpdate) {
        this._node.requestUpdate(this._id);
        this._requestingUpdate = true;
    }
    var prop = this._proportional;
    if (x != null) {
        prop.x.set(x, options, callback);
    }
    if (y != null) {
        prop.y.set(y, options, callback);
    }
    if (z != null) {
        prop.z.set(z, options, callback);
    }
    return this;
};

/**
* Applies differential size to Size component.
*
* @method setDifferential
* @chainable
*
* @param {Number} x used to set differential size in x-direction (width)
* @param {Number} y used to set differential size in y-direction (height)
* @param {Number} z used to set differential size in z-direction (depth)
* @param {Object} options options hash
* @param {Function} callback callback function to be executed after the
*                            transitions have been completed
*/
Size.prototype.setDifferential = function setDifferential(x, y, z, options, callback) {
    if (!this._requestingUpdate) {
        this._node.requestUpdate(this._id);
        this._requestingUpdate = true;
    }
    var diff = this._differential;
    if (x != null) {
        diff.x.set(x, options, callback);
    }
    if (y != null) {
        diff.y.set(y, options, callback);
    }
    if (z != null) {
        diff.z.set(z, options, callback);
    }
    return this;
};

/**
* Retrieves the computed size applied to the underlying RenderContext.
*
* @method get
*
* @return {Number[]} size three dimensional computed size
*/
Size.prototype.get = function get () {
    return this._node.getSize();
};

/**
 * Halts all currently active size transitions.
 *
 * @method halt
 * @chainable
 *
 * @return {Size} this
 */
Size.prototype.halt = function halt () {
    this._proportional.x.halt();
    this._proportional.y.halt();
    this._proportional.z.halt();
    this._differential.x.halt();
    this._differential.y.halt();
    this._differential.z.halt();
    this._absolute.x.halt();
    this._absolute.y.halt();
    this._absolute.z.halt();
    return this;
};

module.exports = Size;
<commit_msg>fix: Use initial size in Size component<commit_after>'use strict';

var Transitionable = require('famous-transitions').Transitionable;
var CoreSize = require('famous-core').Size;

/**
 * Size component used for managing the size of the underlying RenderContext.
 * Supports absolute and relative (proportional and differential) sizing.
 *
 * @class Size
 * @constructor
 * @component
 *
 * @param {LocalDispatch} node LocalDispatch to be retrieved from
 *                                 corresponding RenderNode of the Size
 *                                 component
 */
function Size(node) {
    this._node = node;
    this._id = node.addComponent(this);
    this._requestingUpdate = false;

    var initialProportionalSize = node.getProportionalSize();
    var initialDifferentialSize = node.getDifferentialSize();
    var initialAbsoluteSize = node.getAbsoluteSize();

    this._proportional = {
        x: new Transitionable(initialProportionalSize[0]),
        y: new Transitionable(initialProportionalSize[1]),
        z: new Transitionable(initialProportionalSize[2])
    };
    this._differential = {
        x: new Transitionable(initialDifferentialSize[0]),
        y: new Transitionable(initialDifferentialSize[1]),
        z: new Transitionable(initialDifferentialSize[2])
    };
    this._absolute = {
        x: new Transitionable(initialAbsoluteSize[0]),
        y: new Transitionable(initialAbsoluteSize[1]),
        z: new Transitionable(initialAbsoluteSize[2])
    };
}

Size.RELATIVE = CoreSize.RELATIVE;
Size.ABSOLUTE = CoreSize.ABSOLUTE;
Size.RENDER = CoreSize.RENDER;
Size.DEFAULT = CoreSize.DEFAULT;

Size.prototype.setMode = function setMode(x, y, z) {
    this._node.setSizeMode(x, y, z);
    return this;
};

/**
* Stringifies Size.
*
* @method toString
*
* @return {String} `Size`
*/
Size.toString = function toString() {
    return 'Size';
};

/**
 * @typedef absoluteSizeValue
 * @type {Object}
 * @property {String} type current type of sizing being applied ('absolute')
 * @property {String} component component name ('Size')
 * @property {number} x
 * @property {number} y
 * @property {number} z
 */

/**
 * @typedef relativeSizeValue
 * @type {Object}
 * @property {String} type current type of sizing being applied ('relative')
 * @property {String} component component name ('Size')
 * @property {Object} differential
 * @property {number} differential.x
 * @property {number} differential.y
 * @property {number} differential.z
 * @property {Object} proportional
 * @property {number} proportional.x
 * @property {number} proportional.y
 * @property {number} proportional.z
 */

/**
* Returns serialized state of the component.
*
* @method getValue
*
* @return {absoluteSizeValue|relativeSizeValue}
*/
Size.prototype.getValue = function getValue() {
    return {
        sizeMode: this._node.value.sizeMode,
        absolute: {
            x: this._absolute.x.get(),
            y: this._absolute.y.get(),
            z: this._absolute.z.get()
        },
        differential: {
            x: this._differential.x.get(),
            y: this._differential.y.get(),
            z: this._differential.z.get()
        },
        proportional: {
            x: this._proportional.x.get(),
            y: this._proportional.y.get(),
            z: this._proportional.z.get()
        }
    };
};

/**
* Updates state of component.
*
* @method setValue
*
* @param {absoluteSizeValue|relativeSizeValue} state state encoded in same
*                                                    format as state retrieved
*                                                    through `getValue`
* @return {Boolean}                                  boolean indicating
*                                                    whether the new state has
*                                                    been applied
*/
Size.prototype.setValue = function setValue(state) {
    if (state.component === this.constructor.toString()) {
        this.setMode.apply(this, state.sizeMode);
        if (state.absolute) {
            this.setAbsolute(state.absolute.x, state.absolute.y, state.absolute.z);
        }
        if (state.differential) {
            this.setAbsolute(state.differential.x, state.differential.y, state.differential.z);
        }
        if (state.proportional) {
            this.setAbsolute(state.proportional.x, state.proportional.y, state.proportional.z);
        }
    }
    return false;
};

Size.prototype._isActive = function _isActive(type) {
    return type.x.isActive() || type.y.isActive() || type.z.isActive();
};

Size.prototype.isActive = function isActive(){
    return (
        this._isActive(this._absolute) ||
        this._isActive(this._proportional) ||
        this._isActive(this._differential)
    );
};

Size.prototype.onUpdate = function onUpdate() {
    var abs = this._absolute;
    this._node.setAbsoluteSize(
        abs.x.get(),
        abs.y.get(),
        abs.z.get()
    );
    var prop = this._proportional;
    var diff = this._differential;
    this._node.setProportionalSize(
        prop.x.get(),
        prop.y.get(),
        prop.z.get()
    );
    this._node.setDifferentialSize(
        diff.x.get(),
        diff.y.get(),
        diff.z.get()
    );

    if (this.isActive()) this._node.requestUpdateOnNextTick(this._id);
    else this._requestingUpdate = false;
};

/**
* Applies absolute size.
*
* @method setAbsolute
* @chainable
*
* @param {Number} x used to set absolute size in x-direction (width)
* @param {Number} y used to set absolute size in y-direction (height)
* @param {Number} z used to set absolute size in z-direction (depth)
* @param {Object} options options hash
* @param {Function} callback callback function to be executed after the
*                            transitions have been completed
* @return {Size} this
*/
Size.prototype.setAbsolute = function setAbsolute(x, y, z, options, callback) {
    if (!this._requestingUpdate) {
        this._node.requestUpdate(this._id);
        this._requestingUpdate = true;
    }
    var abs = this._absolute;
    if (x != null) {
        abs.x.set(x, options, callback);
    }
    if (y != null) {
        abs.y.set(y, options, callback);
    }
    if (z != null) {
        abs.z.set(z, options, callback);
    }
};

/**
* Applies proportional size.
*
* @method setProportional
* @chainable
*
* @param {Number} x used to set proportional size in x-direction (width)
* @param {Number} y used to set proportional size in y-direction (height)
* @param {Number} z used to set proportional size in z-direction (depth)
* @param {Object} options options hash
* @param {Function} callback callback function to be executed after the
*                            transitions have been completed
* @return {Size} this
*/
Size.prototype.setProportional = function setProportional(x, y, z, options, callback) {
    if (!this._requestingUpdate) {
        this._node.requestUpdate(this._id);
        this._requestingUpdate = true;
    }
    var prop = this._proportional;
    if (x != null) {
        prop.x.set(x, options, callback);
    }
    if (y != null) {
        prop.y.set(y, options, callback);
    }
    if (z != null) {
        prop.z.set(z, options, callback);
    }
    return this;
};

/**
* Applies differential size to Size component.
*
* @method setDifferential
* @chainable
*
* @param {Number} x used to set differential size in x-direction (width)
* @param {Number} y used to set differential size in y-direction (height)
* @param {Number} z used to set differential size in z-direction (depth)
* @param {Object} options options hash
* @param {Function} callback callback function to be executed after the
*                            transitions have been completed
*/
Size.prototype.setDifferential = function setDifferential(x, y, z, options, callback) {
    if (!this._requestingUpdate) {
        this._node.requestUpdate(this._id);
        this._requestingUpdate = true;
    }
    var diff = this._differential;
    if (x != null) {
        diff.x.set(x, options, callback);
    }
    if (y != null) {
        diff.y.set(y, options, callback);
    }
    if (z != null) {
        diff.z.set(z, options, callback);
    }
    return this;
};

/**
* Retrieves the computed size applied to the underlying RenderContext.
*
* @method get
*
* @return {Number[]} size three dimensional computed size
*/
Size.prototype.get = function get () {
    return this._node.getSize();
};

/**
 * Halts all currently active size transitions.
 *
 * @method halt
 * @chainable
 *
 * @return {Size} this
 */
Size.prototype.halt = function halt () {
    this._proportional.x.halt();
    this._proportional.y.halt();
    this._proportional.z.halt();
    this._differential.x.halt();
    this._differential.y.halt();
    this._differential.z.halt();
    this._absolute.x.halt();
    this._absolute.y.halt();
    this._absolute.z.halt();
    return this;
};

module.exports = Size;
<|endoftext|>


<commit_before>
var net = require('net');
var binding = require('bindings')('abstract_socket.node');

var socket  = binding.socket;
var bind    = binding.bind;
var connect = binding.connect;
var close   = binding.close;

function errnoException(errorno, syscall) {
  var e = new Error(syscall + ' ' + errorno);
  e.errno = e.code = errorno;
  e.syscall = syscall;
  return e;
}

exports.startListening = function(path, connectionListener, listeningListener) {
    var err = socket();
    if (err < 0)
        throw errnoException(err, 'socket');

    var handle = {fd: err};

    err = bind(err, path);
    if (err < 0) {
        close(handle.fd);
        throw errnoException(err, 'bind');
    }

    var server = net.createServer(connectionListener);
    server.listen(handle, listeningListener);
    return server;
};

exports.connect = function(path, connectListener) {
    var err = socket();
    if (err < 0)
        throw errnoException(err, 'socket');

    var options = {fd: err, readable: true, writable: true};

    // yes, connect is synchronous, so sue me
    err = connect(err, path);
    if (err < 0) {
        close(options.fd);
        throw errnoException(err, 'connect');
    }

    return new net.Socket(options);
};

<commit_msg>Add TODO note<commit_after>
var net = require('net');
var binding = require('bindings')('abstract_socket.node');

var socket  = binding.socket;
var bind    = binding.bind;
var connect = binding.connect;
var close   = binding.close;

function errnoException(errorno, syscall) {
    // TODO: having the errno message here would be nice
    var e = new Error(syscall + ' ' + errorno);
    e.errno = e.code = errorno;
    e.syscall = syscall;
    return e;
}

exports.startListening = function(path, connectionListener, listeningListener) {
    var err = socket();
    if (err < 0)
        throw errnoException(err, 'socket');

    var handle = {fd: err};

    err = bind(err, path);
    if (err < 0) {
        close(handle.fd);
        throw errnoException(err, 'bind');
    }

    var server = net.createServer(connectionListener);
    server.listen(handle, listeningListener);
    return server;
};

exports.connect = function(path, connectListener) {
    var err = socket();
    if (err < 0)
        throw errnoException(err, 'socket');

    var options = {fd: err, readable: true, writable: true};

    // yes, connect is synchronous, so sue me
    err = connect(err, path);
    if (err < 0) {
        close(options.fd);
        throw errnoException(err, 'connect');
    }

    return new net.Socket(options);
};

<|endoftext|>


<commit_before>var Replace = function() { //Constructor

	// Private storage of last entered message per user
	// and channel
	var latestMsgs = [[]];

	// handle is called when a message is sent to a channel by a user
	this.handle = function(from, chan, message) {
		var irc = global.irc,
			matches = message.match(/^s\/(.*?)\/(.*?)(\/(.+))?$/i);

		if (matches) {
			var search = matches[1],
				replace = matches[2],
				user = matches[4] || from;

			if (latestMsgs[user] && latestMsgs[user][chan]) {
				message = latestMsgs[user][chan];
				try {
					var re = new RegExp(search, "ig"),
						msg = message.replace(re, replace);
					irc.client.say(chan, msg);
				} catch(e) {
					console.log('replace error: ' + e)
				}
			}
		}

		// Store in user array. If message was used for replace it is
		// overwritten to make sure we are not replacing on replace strings.
		if(!latestMsgs[from]) latestMsgs[from] = Array();
		latestMsgs[from][chan] = message;
	}
}

module.exports = new Replace();<commit_msg>Fixed indentation of multi-line vars.<commit_after>var Replace = function() { //Constructor

	// Private storage of last entered message per user
	// and channel
	var latestMsgs = [[]];

	// handle is called when a message is sent to a channel by a user
	this.handle = function(from, chan, message) {
		var irc = global.irc,
		matches = message.match(/^s\/(.*?)\/(.*?)(\/(.+))?$/i);

		if (matches) {
			var search = matches[1],
			replace = matches[2],
			user = matches[4] || from;

			if (latestMsgs[user] && latestMsgs[user][chan]) {
				message = latestMsgs[user][chan];
				try {
					var re = new RegExp(search, "ig"),
					msg = message.replace(re, replace);
					irc.client.say(chan, msg);
				} catch(e) {
					console.log('replace error: ' + e)
				}
			}
		}

		// Store in user array. If message was used for replace it is
		// overwritten to make sure we are not replacing on replace strings.
		if(!latestMsgs[from]) latestMsgs[from] = Array();
		latestMsgs[from][chan] = message;
	}
}

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


<commit_before>/*!
 * Riloadr.js 1.0.0 (c) 2012 Tubal Martin - MIT license
 */
 !function(a){typeof define=="function"&&define.amd?define(["jquery"],a):window.Riloadr=a()}(function(){function N(a){function ab(){D==="belowfold"?F?(K||(K=b,H(t,j,Q(function(){U(j)},250))),V(j,f.loadImages),L||(L=b,H(t,k,R(function(){U(k)},250))),V(k,f.loadImages),B&&(M||(M=b,J=t[q],H(t,s,R(function(){t[q]!==J&&(J=t[q],U(s))},250))),V(s,f.loadImages)),f.loadImages()):X(f.loadImages):D===e?X(f.loadImages):f.loadImages()}function bb(a){if(!_||a===b)_=_||[],y("img."+r,Y).each(function(a,b){b&&!b[o]&&_.push(b)})}function cb(a,c){a[o]=b,a[n]=0,a[l]=db,a[m]=eb,a.src=fb(a),_.splice(c,1)}function db(){var b=this;b[l]=b[m]=d,b[p]=b[p].replace(w,"$1$2"),l in a&&a[l].call(b)}function eb(){var c=this;N>0&&c[n]<N&&(c[n]++,c.src=fb(c,b)),m in a&&a[m].call(c)}function fb(a,b){var c=(a.getAttribute("data-base")||C)+(a.getAttribute("data-src")||g);return b&&(c+=(z.test(c)?"&":"?")+"riloadrts="+(new Date).getTime()),c.replace(A,Z)}function gb(a){return u.height()+u.scrollTop()<=y(a).offset().top-I}var f=this,i=a.breakpoints||T('"breakpoints" not defined.'),r=a.name||"responsive",w=new RegExp("(^|\\s)"+r+"(\\s|$)"),C=a.base||g,D=(a.defer+g).toLowerCase()||c,F=D==="belowfold"&&!G,I=+a.foldDistance||100,N=+a[n]||0,Y,Z,_;f.loadImages=function(){var a=arguments;S(function(b,c){bb.apply(d,a);if(_[h]){c=0;while(b=_[c])b&&!b[o]&&(F?gb(b)||(cb(b,c),c--):(cb(b,c),c--)),c++;b=d}})},f.riload=function(){f.loadImages(b)},W(function(){u=y(t),x=v.body,Y=a.root&&y("#"+a.root)||x,E=E||P(),Z=O(i,E),ab()})}function O(a,b){var c=g,d=b,e=0,f,h,i,j,k;while(f=a[e]){h=f.name,i=f.minWidth,j=f.maxWidth,k=f.minDevicePixelRatio;if(b>0){if(i&&j&&b>=i&&b<=j||i&&!j&&b>=i||j&&!i&&b<=j)k?D>=k&&(c=h):c=h}else d<=0?(d=i?i:j?j:d,c=h):(i<d&&(d=i,c=h),j<d&&(d=j,c=h));e++}return c+g}function P(){var a=Math,b=[w.clientWidth,w.offsetWidth,x.clientWidth],c=a.ceil(C/D),d=b[h],e=0,f;for(;e<d;e++)isNaN(b[e])&&(b.splice(e,1),e--);return b[h]&&(f=a.max.apply(a,b),isNaN(c)||(f=a.min(c,f))),f||c||0}function Q(a,e){var f,g,h,i,j,k,l=R(function(){j=i=c},e);return function(){f=this,g=arguments;var c=function(){h=d,j&&a.apply(f,g),l()};return h||(h=setTimeout(c,e)),i?j=b:k=a.apply(f,g),l(),i=b,k}}function R(a,b,c){var e;return function(){var f=this,g=arguments,h=function(){e=d,c||a.apply(f,g)};c&&!e&&a.apply(f,g),clearTimeout(e),e=setTimeout(h,b)}}function S(a){var b=Array.prototype.slice.call(arguments,1);setTimeout(function(){return a.apply(d,b)},1)}function T(a){throw new Error("Riloadr: "+a)}function U(a){var b=F[a],c=0,d;if(b)while(d=b[c])d(),c++}function V(a,b){(F[a]=F[a]||[]).push(b)}function W(a){y(a)}function X(a){if(v.readyState==="complete")a();else{var b=function(){I(t,e,b),a()};H(t,e,b)}}"use strict";var a="on",b=!0,c=!1,d=null,e="load",f="error",g="",h="length",i="jQuery",j="scroll",k="resize",l=a+e,m=a+f,n="retries",o="riloaded",p="className",q="orientation",r="EventListener",s=q+"change",t=window,u,v=t.document,w=v.documentElement,x,y=i in t&&t[i]||T(i+" not found."),z=/\?/,A=/{breakpoint-name}/gi,B=q in t&&a+s in t,C=t.screen.width,D=t.devicePixelRatio||1,E,F={},G=Object.prototype.toString.call(t.operamini)==="[object OperaMini]",H,I,J,K,L,M;return w[p]=w[p].replace(/(^|\s)no-js(\s|$)/,"$1$2"),N.version="1.0.0",!function(){var b="add"+r in v,d=b?"add"+r:"attachEvent",e=b?"remove"+r:"detachEvent",f=b?g:a;H=function(a,b,e){a[d](f+b,e,c)},I=function(a,b,d){a[e](f+b,d,c)}}(),N});<commit_msg>Removed space<commit_after>/*!
 * Riloadr.js 1.0.0 (c) 2012 Tubal Martin - MIT license
 */
!function(a){typeof define=="function"&&define.amd?define(["jquery"],a):window.Riloadr=a()}(function(){function N(a){function ab(){D==="belowfold"?F?(K||(K=b,H(t,j,Q(function(){U(j)},250))),V(j,f.loadImages),L||(L=b,H(t,k,R(function(){U(k)},250))),V(k,f.loadImages),B&&(M||(M=b,J=t[q],H(t,s,R(function(){t[q]!==J&&(J=t[q],U(s))},250))),V(s,f.loadImages)),f.loadImages()):X(f.loadImages):D===e?X(f.loadImages):f.loadImages()}function bb(a){if(!_||a===b)_=_||[],y("img."+r,Y).each(function(a,b){b&&!b[o]&&_.push(b)})}function cb(a,c){a[o]=b,a[n]=0,a[l]=db,a[m]=eb,a.src=fb(a),_.splice(c,1)}function db(){var b=this;b[l]=b[m]=d,b[p]=b[p].replace(w,"$1$2"),l in a&&a[l].call(b)}function eb(){var c=this;N>0&&c[n]<N&&(c[n]++,c.src=fb(c,b)),m in a&&a[m].call(c)}function fb(a,b){var c=(a.getAttribute("data-base")||C)+(a.getAttribute("data-src")||g);return b&&(c+=(z.test(c)?"&":"?")+"riloadrts="+(new Date).getTime()),c.replace(A,Z)}function gb(a){return u.height()+u.scrollTop()<=y(a).offset().top-I}var f=this,i=a.breakpoints||T('"breakpoints" not defined.'),r=a.name||"responsive",w=new RegExp("(^|\\s)"+r+"(\\s|$)"),C=a.base||g,D=(a.defer+g).toLowerCase()||c,F=D==="belowfold"&&!G,I=+a.foldDistance||100,N=+a[n]||0,Y,Z,_;f.loadImages=function(){var a=arguments;S(function(b,c){bb.apply(d,a);if(_[h]){c=0;while(b=_[c])b&&!b[o]&&(F?gb(b)||(cb(b,c),c--):(cb(b,c),c--)),c++;b=d}})},f.riload=function(){f.loadImages(b)},W(function(){u=y(t),x=v.body,Y=a.root&&y("#"+a.root)||x,E=E||P(),Z=O(i,E),ab()})}function O(a,b){var c=g,d=b,e=0,f,h,i,j,k;while(f=a[e]){h=f.name,i=f.minWidth,j=f.maxWidth,k=f.minDevicePixelRatio;if(b>0){if(i&&j&&b>=i&&b<=j||i&&!j&&b>=i||j&&!i&&b<=j)k?D>=k&&(c=h):c=h}else d<=0?(d=i?i:j?j:d,c=h):(i<d&&(d=i,c=h),j<d&&(d=j,c=h));e++}return c+g}function P(){var a=Math,b=[w.clientWidth,w.offsetWidth,x.clientWidth],c=a.ceil(C/D),d=b[h],e=0,f;for(;e<d;e++)isNaN(b[e])&&(b.splice(e,1),e--);return b[h]&&(f=a.max.apply(a,b),isNaN(c)||(f=a.min(c,f))),f||c||0}function Q(a,e){var f,g,h,i,j,k,l=R(function(){j=i=c},e);return function(){f=this,g=arguments;var c=function(){h=d,j&&a.apply(f,g),l()};return h||(h=setTimeout(c,e)),i?j=b:k=a.apply(f,g),l(),i=b,k}}function R(a,b,c){var e;return function(){var f=this,g=arguments,h=function(){e=d,c||a.apply(f,g)};c&&!e&&a.apply(f,g),clearTimeout(e),e=setTimeout(h,b)}}function S(a){var b=Array.prototype.slice.call(arguments,1);setTimeout(function(){return a.apply(d,b)},1)}function T(a){throw new Error("Riloadr: "+a)}function U(a){var b=F[a],c=0,d;if(b)while(d=b[c])d(),c++}function V(a,b){(F[a]=F[a]||[]).push(b)}function W(a){y(a)}function X(a){if(v.readyState==="complete")a();else{var b=function(){I(t,e,b),a()};H(t,e,b)}}"use strict";var a="on",b=!0,c=!1,d=null,e="load",f="error",g="",h="length",i="jQuery",j="scroll",k="resize",l=a+e,m=a+f,n="retries",o="riloaded",p="className",q="orientation",r="EventListener",s=q+"change",t=window,u,v=t.document,w=v.documentElement,x,y=i in t&&t[i]||T(i+" not found."),z=/\?/,A=/{breakpoint-name}/gi,B=q in t&&a+s in t,C=t.screen.width,D=t.devicePixelRatio||1,E,F={},G=Object.prototype.toString.call(t.operamini)==="[object OperaMini]",H,I,J,K,L,M;return w[p]=w[p].replace(/(^|\s)no-js(\s|$)/,"$1$2"),N.version="1.0.0",!function(){var b="add"+r in v,d=b?"add"+r:"attachEvent",e=b?"remove"+r:"detachEvent",f=b?g:a;H=function(a,b,e){a[d](f+b,e,c)},I=function(a,b,d){a[e](f+b,d,c)}}(),N});<|endoftext|>


<commit_before>
// Based on https://github.com/gigamonkey/gg

(function () {

  // ===================
  // NODE/BROWSER CONFIG
  // ===================

  var isNode = false;

  // If Node, create a fake DOM with jsdom and require dependencies.
  if (typeof module !== 'undefined' && module.exports) {
    isNode = true;
    document = require('jsdom').jsdom();
    window = document.parentWindow;
    this.d3 = require('d3');
    this._  = require('underscore');
  }

  if (!d3 || !_) { throw 'ggd3 requires D3 and Underscore.'; }

  // =======
  // GRAPHIC
  // =======

  function Graphic(opts, data, el, width, height, renderNow) {
    _.defaults(opts || {}, { facets: {}, layers: [] });
    this.groupsController = new GroupsController();
    this.layersController = new LayersController(this.groupsController);
    this.facetsController = new FacetsController(this.layersController);
    if(opts)      { this.configure(opts); }
    if(data)      { this.data(data); }
    if(el)        { this.build(el, width, height); }
    if(renderNow) { this.render(); }
  }

  Graphic.prototype.configure = function(opts) {
    _.defaults(opts || {}, { graphic: {}, facets: {}, layers: [], groups: [] });
    this.facetsController.configure(opts);
    this.layersController.configure(opts);
    this.groupsController.configure(opts);
  };

  Graphic.prototype.data = function(dataset) {
    if (!_.isArray(dataset)) { return this.dataset || []; }
    this.dataset = dataset;
    this.facetsController.train(dataset);
    this.layersController.train(dataset);
    this.groupsController.train(dataset);
    this.facets = this.facetsController.nest(dataset);
  };

  Graphic.prototype.build = function(el, width, height) {
    if (!_.isString(el)) { return this.el; }
    this.target = d3.select(el);
    this.width  = width  || parseInt(this.target.style('width'));
    this.height = height || parseInt(this.target.style('height'));
    this.el = d3.select(document.createElement('div'));
    this.el.append('svg').attr('width', this.width).attr('height', this.height).attr('class', 'graphic');
    this.facetsController.build(this.facets, this.el, this.width, this.height);
  };

  Graphic.prototype.render = function() { this.target.html(this.el.html()); };

  // ======
  // FACETS
  // ======

  var facetsDefaults = {
    flow: undefined,
    gridX: undefined,
    gridY: undefined
  };

  function Facet(data) {
    this.key = data.key;
    this.layers = data.layers;
    this.opts = data.opts;
    this.index = data.index;
  }

  function FacetsController(layersController) {
    this.scale = { x: d3.scale.ordinal(), y: d3.scale.ordinal(), domain: [] };
    this.layersController = layersController;
  }

  FacetsController.prototype.configure = function(opts) {
    this.opts = _.extend({}, facetsDefaults, opts.graphic, opts.facets);
    if (this.opts.gridX || this.opts.gridY) { _.extend(this, new GridFacetController()); }
    else { _.extend(this, new FlowFacetController()); }
  };

  function FlowFacetController() {

    this.train = function(dataset) {
      var that = this;
      this.scale.domain = d3.set(dataset.map(function(row) { return row[that.opts.flow]; })).values();
    };

    this.nest = function(dataset) {
      var that = this;
      var facets = d3.nest()
        .key(function(row) { return row[that.opts.flow]; })
        .entries(dataset)
        .map(function(facet, index) {
          var facet = { opts: that.opts, values: facet.values, index: index };
          facet.layers = that.layersController.nest(facet);
          return new Facet(facet);
      });
      return facets;
    };

    this.setRangeX = function(width, height, ratio, numFacets, numCols) {
      var that = this;
      var xRange = this.scale.domain.map(function(key, index) {
        if (numFacets < ratio) { return index * (width/numFacets); }
        var colNum = index % ratio;
        return (colNum/numCols) * that.width;
      });
      this.scale.x.range(xRange);
    };

    this.setRangeY = function(width, height, ratio, numFacets, numRows) {
      var yRange = this.scale.domain.map(function(key, index) {
        var rowNum = Math.floor(index/ratio);
        return (rowNum/numRows) * height;
      });
      this.scale.y.range(yRange);
    };

  }

  FacetsController.prototype.build = function(facets, el, width, height) {

    var that = this;

    var numFacets = facets.length;
    var ratio     = width/height >= 1 ? Math.floor(width/height) : 1/Math.floor(height/width);
    var numRows   = ratio >= 1 ? Math.ceil(numFacets/ratio) : Math.ceil(ratio/numFacets);
    var numCols   = Math.ceil(numFacets/numRows);

    this.width  = width/numCols;
    this.height = height/numRows;
    this.setRangeX(width, height, ratio, numFacets, numCols);
    this.setRangeY(width, height, ratio, numFacets, numRows);

    this.el = el.select('svg');
    this.el.selectAll('g.facet')
      .data(facets)
      .enter()
      .append('g')
      .attr('class', 'facet')
      .attr('data-key', function(facet) { return facet.key; })
      .attr('transform', function(facet) {
        return 'translate(' + that.scale.x(facet.key) + ',' + that.scale.y(facet.key) + ')';
      })
      .each(function(facet, index) {
        that.layersController.build(facet, this);
      });

  };

  // ======
  // LAYERS
  // ======

  var layerDefaults = {
    geometry: 'point',
    mapping: {}
  };

  function Layer(data) {
    this.opts = data.opts;
    this.groups = data.groups;
  }

  function LayersController(groupsController) {
    this.groupsController = groupsController;
  }

  LayersController.prototype.configure = function(opts) {
    if (!opts.layers.length > 0) { opts.layers[0] = _.extend({}, layerDefaults, opts.graphic); }
    this.layersOpts = opts.layers.map(function(layerOpts) { return _.extend({}, layerDefaults, opts.graphic, layerOpts); });
  };

  LayersController.prototype.train = function(dataset) {};

  LayersController.prototype.nest = function(facet) {
    var that = this;
    var layers = this.layersOpts.map(function(layerOpts, index) {
      var layer = { opts: layerOpts, values: facet.values, index: index };
      layer.groups = that.groupsController.nest(layer);
      return new Layer(layer);
    });
    return layers;
  };

  LayersController.prototype.build = function(facet, el) {
    var that = this;
    this.el = d3.select(el);
    this.el.selectAll('g.layer')
      .data(facet.layers)
      .enter()
      .append('g')
      .attr('class', 'layer')
      .attr('data-geometry', function(layer) { return layer.geometry; })
      .each(function(layer) {
        that.groupsController.build(layer, this);
      });
  };

  // ======
  // GROUPS
  // ======

  var groupsDefaults = {
    group: undefined
  };

  function GroupsController() {};

  GroupsController.prototype.configure = function(opts) {
    if (!opts.groups.length > 0) { opts.groups = opts.layers.map(function(layer) { return _.extend(layer, groupsDefaults); }); }
    this.groupsOpts = opts.groups.map(function(groupOpts, index) {
      return _.extend({}, groupsDefaults, opts.graphic, opts.facets, opts.layers[index], groupOpts);
    });
  };

  GroupsController.prototype.train = function(dataset) {};

  GroupsController.prototype.nest = function(layer) {
    var that = this;
    var groups = d3.nest()
      .key(function(row) { return row[layer.opts.mapping.group]; })
      .entries(layer.values)
      .map(function(group) {
        group.opts = that.groupsOpts[layer.index];
        console.log(group)
        // To geometries.
      });
    return groups;
  };

  GroupsController.prototype.build = function(layer, el) {
    var that = this;
    this.el = d3.select(el);
    this.el.selectAll('g.group')
      .data(layer.groups)
      .enter()
      .append('g')
      .attr('class', 'group')
      .attr('data-group', function(group) { return group.key; })
      .each(function(group) {

      });
  };

  // ========
  // GEOMETRY
  // ========

  function GeometryController() {}

  // =============
  // EXPORT GLOBAL
  // =============

  // Export as Node module.
  if (isNode) {
    module.exports = Graphic;
  }

  // Export to global context.
  this.Graphic = Graphic;

})();<commit_msg>geometries component<commit_after>
// Based on https://github.com/gigamonkey/gg

(function () {

  // ===================
  // NODE/BROWSER CONFIG
  // ===================

  var isNode = false;

  // If Node, create a fake DOM with jsdom and require dependencies.
  if (typeof module !== 'undefined' && module.exports) {
    isNode = true;
    document = require('jsdom').jsdom();
    window = document.parentWindow;
    this.d3 = require('d3');
    this._  = require('underscore');
  }

  if (!d3 || !_) { throw 'ggd3 requires D3 and Underscore.'; }

  // =======
  // GRAPHIC
  // =======

  function Graphic(opts, data, el, width, height, renderNow) {
    _.defaults(opts || {}, { facets: {}, layers: [], groups: [], geometries: [] });
    this.geometriesController = new GeometriesController();
    this.groupsController = new GroupsController(this.geometriesController);
    this.layersController = new LayersController(this.groupsController);
    this.facetsController = new FacetsController(this.layersController);
    if(opts)      { this.configure(opts); }
    if(data)      { this.data(data); }
    if(el)        { this.build(el, width, height); }
    if(renderNow) { this.render(); }
  }

  Graphic.prototype.configure = function(opts) {
    opts = _.defaults(opts || {}, { graphic: {}, facets: {}, layers: [], groups: [] });
    opts.facets = this.facetsController.configure(opts);
    opts.layers = this.layersController.configure(opts);
    opts.groups = this.groupsController.configure(opts);
    opts.geometries = this.geometriesController.configure(opts);
  };

  Graphic.prototype.data = function(dataset) {
    if (!_.isArray(dataset)) { return this.dataset || []; }
    this.dataset = dataset;
    this.facetsController.train(dataset);
    this.layersController.train(dataset);
    this.groupsController.train(dataset);
    this.facets = this.facetsController.nest(dataset);
  };

  Graphic.prototype.build = function(el, width, height) {
    if (!_.isString(el)) { return this.el; }
    this.target = d3.select(el);
    this.width  = width  || parseInt(this.target.style('width'));
    this.height = height || parseInt(this.target.style('height'));
    this.el = d3.select(document.createElement('div'));
    this.el.append('svg').attr('width', this.width).attr('height', this.height).attr('class', 'graphic');
    this.facetsController.build(this.facets, this.el, this.width, this.height);
  };

  Graphic.prototype.render = function() { this.target.html(this.el.html()); };

  // ======
  // FACETS
  // ======

  var facetsDefaults = {
    flow: undefined,
    gridX: undefined,
    gridY: undefined
  };

  function Facet(data) {
    this.key = data.key;
    this.layers = data.layers;
    this.opts = data.opts;
    this.index = data.index;
  }

  function FacetsController(layersController) {
    this.scale = { x: d3.scale.ordinal(), y: d3.scale.ordinal(), domain: [] };
    this.layersController = layersController;
  }

  FacetsController.prototype.configure = function(opts) {
    this.opts = _.extend({}, facetsDefaults, opts.graphic, opts.facets);
    if (this.opts.gridX || this.opts.gridY) { _.extend(this, new GridFacetController()); }
    else { _.extend(this, new FlowFacetController()); }
    return this.opts;
  };

  function FlowFacetController() {

    this.train = function(dataset) {
      var that = this;
      this.scale.domain = d3.set(dataset.map(function(row) { return row[that.opts.flow]; })).values();
    };

    this.nest = function(dataset) {
      var that = this;
      var facets = d3.nest()
        .key(function(row) { return row[that.opts.flow]; })
        .entries(dataset)
        .map(function(facet, index) {
          var facet = { opts: that.opts, values: facet.values, index: index };
          facet.layers = that.layersController.nest(facet);
          return new Facet(facet);
      });
      return facets;
    };

    this.setRangeX = function(width, height, ratio, numFacets, numCols) {
      var that = this;
      var xRange = this.scale.domain.map(function(key, index) {
        if (numFacets < ratio) { return index * (width/numFacets); }
        var colNum = index % ratio;
        return (colNum/numCols) * that.width;
      });
      this.scale.x.range(xRange);
    };

    this.setRangeY = function(width, height, ratio, numFacets, numRows) {
      var yRange = this.scale.domain.map(function(key, index) {
        var rowNum = Math.floor(index/ratio);
        return (rowNum/numRows) * height;
      });
      this.scale.y.range(yRange);
    };

  }

  FacetsController.prototype.build = function(facets, el, width, height) {

    var that = this;

    var numFacets = facets.length;
    var ratio     = width/height >= 1 ? Math.floor(width/height) : 1/Math.floor(height/width);
    var numRows   = ratio >= 1 ? Math.ceil(numFacets/ratio) : Math.ceil(ratio/numFacets);
    var numCols   = Math.ceil(numFacets/numRows);

    this.width  = width/numCols;
    this.height = height/numRows;
    this.setRangeX(width, height, ratio, numFacets, numCols);
    this.setRangeY(width, height, ratio, numFacets, numRows);

    this.el = el.select('svg');
    this.el.selectAll('g.facet')
      .data(facets)
      .enter()
      .append('g')
      .attr('class', 'facet')
      .attr('data-key', function(facet) { return facet.key; })
      .attr('transform', function(facet) {
        return 'translate(' + that.scale.x(facet.key) + ',' + that.scale.y(facet.key) + ')';
      })
      .each(function(facet, index) {
        that.layersController.build(facet, this);
      });

  };

  // ======
  // LAYERS
  // ======

  var layerDefaults = {
    geometry: 'point',
    mapping: {}
  };

  function Layer(data) {
    this.opts = data.opts;
    this.groups = data.groups;
  }

  function LayersController(groupsController) {
    this.groupsController = groupsController;
  }

  LayersController.prototype.configure = function(opts) {
    if (!opts.layers.length > 0) { opts.layers[0] = _.extend({}, layerDefaults, opts.graphic); }
    this.opts = opts.layers.map(function(layerOpts) { return _.extend({}, layerDefaults, opts.graphic, layerOpts); });
    return this.opts;
  };

  LayersController.prototype.train = function(dataset) {};

  LayersController.prototype.nest = function(facet) {
    var that = this;
    var layers = this.opts.map(function(layerOpts, index) {
      var layer = { opts: layerOpts, values: facet.values, index: index };
      layer.groups = that.groupsController.nest(layer);
      return new Layer(layer);
    });
    return layers;
  };

  LayersController.prototype.build = function(facet, el) {
    var that = this;
    this.el = d3.select(el);
    this.el.selectAll('g.layer')
      .data(facet.layers)
      .enter()
      .append('g')
      .attr('class', 'layer')
      .attr('data-geometry', function(layer) { return layer.geometry; })
      .each(function(layer) {
        that.groupsController.build(layer, this);
      });
  };

  // ======
  // GROUPS
  // ======

  var groupsDefaults = {
    group: undefined
  };

  function Geometry(data) {
    console.log('new geo');
  }

  function GroupsController(geometriesController) {
    this.geometriesController = geometriesController;
  }

  GroupsController.prototype.configure = function(opts) {
    if (!opts.groups.length > 0) { opts.groups = opts.layers.map(function(layer) { return _.extend(layer, groupsDefaults); }); }
    this.opts = opts.groups.map(function(groupOpts, index) {
      return _.extend({}, groupsDefaults, opts.graphic, opts.facets, opts.layers[index], groupOpts);
    });
    return this.opts;
  };

  GroupsController.prototype.train = function(dataset) {};

  GroupsController.prototype.nest = function(layer) {
    var that = this;
    var groups = d3.nest()
      .key(function(row) { return row[layer.opts.mapping.group]; })
      .entries(layer.values)
      .map(function(group) {
        group.opts = that.opts[layer.index];
        return that.geometriesController.create(group);
      });
    return groups;
  };

  GroupsController.prototype.build = function(layer, el) {
    var that = this;
    this.el = d3.select(el);
    this.el.selectAll('g.group')
      .data(layer.groups)
      .enter()
      .append('g')
      .attr('class', 'group')
      .attr('data-group', function(group) {
        // ok
      })
      .each(function(group) {

      });
  };

  // ========
  // GEOMETRY
  // ========

  var geometriesDefaults = {};

  function GeometriesController() {}

  GeometriesController.prototype.configure = function(opts) {
    if (!opts.geometries.length > 0) { opts.geometries = opts.groups.map(function(groupOpts) { return _.extend(groupOpts, geometriesDefaults); }); }
    this.opts = opts.geometries.map(function(geometriesOpts, index) {
      return _.extend({}, geometriesDefaults, opts.graphic, opts.facets, opts.layers[index], opts.groups[index], geometriesOpts);
    });
    return this.opts;
  };

  GeometriesController.prototype.create = function(group) {
    console.log(group)
  };

  // =============
  // EXPORT GLOBAL
  // =============

  // Export as Node module.
  if (isNode) {
    module.exports = Graphic;
  }

  // Export to global context.
  this.Graphic = Graphic;

})();<|endoftext|>


<commit_before>// A function to process stripe payments
//

var stripe = require("");
var KEY = '1231423124123';

var onLoad = function() {
	stripe.init(KEY);
};

var processPayment = function(token, userid, done) {
	stripe.charge(token, userid, 499, function() {
		done(true);
	});
};
<commit_msg>Get rid of WIP stuff<commit_after><|endoftext|>


<commit_before>var sillystring = require('./lib/sillystring')
//  , formulae = require('./lib/formulae')
;

console.log(sillystring('Browserify is fun!'));

// console.log(formulae.makeBig(5, 10));
<commit_msg>Don't comment out formulae in 02 example<commit_after>var sillystring = require('./lib/sillystring')
  , formulae = require('./lib/formulae')
;

console.log(sillystring('Browserify is fun!'));

console.log(formulae.makeBig(5, 10));
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

import {
	Matrix4,
	Object3D,
	Vector3
} from "../../../build/three.module.js";

var CSS2DObject = function ( element ) {

	Object3D.call( this );

	this.element = element;
	this.element.style.position = 'absolute';

	this.addEventListener( 'removed', function () {

		this.traverse( function ( object ) {

			if ( object.element instanceof Element && object.element.parentNode !== null ) {

				object.element.parentNode.removeChild( object.element );

			}

		} );

	} );

};

CSS2DObject.prototype = Object.create( Object3D.prototype );
CSS2DObject.prototype.constructor = CSS2DObject;

//

var CSS2DRenderer = function () {

	var _this = this;

	var _width, _height;
	var _widthHalf, _heightHalf;

	var vector = new Vector3();
	var viewMatrix = new Matrix4();
	var viewProjectionMatrix = new Matrix4();

	var cache = {
		objects: new WeakMap()
	};

	var domElement = document.createElement( 'div' );
	domElement.style.overflow = 'hidden';

	this.domElement = domElement;

	this.getSize = function () {

		return {
			width: _width,
			height: _height
		};

	};

	this.setSize = function ( width, height ) {

		_width = width;
		_height = height;

		_widthHalf = _width / 2;
		_heightHalf = _height / 2;

		domElement.style.width = width + 'px';
		domElement.style.height = height + 'px';

	};

	var renderObject = function ( object, scene, camera ) {

		if ( object instanceof CSS2DObject ) {

			object.onBeforeRender( _this, scene, camera );

			vector.setFromMatrixPosition( object.matrixWorld );
			vector.applyMatrix4( viewProjectionMatrix );

			var element = object.element;
			var style = 'translate(-50%,-50%) translate(' + ( vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - vector.y * _heightHalf + _heightHalf ) + 'px)';

			element.style.WebkitTransform = style;
			element.style.MozTransform = style;
			element.style.oTransform = style;
			element.style.transform = style;

			element.style.display = ( object.visible && vector.z >= - 1 && vector.z <= 1 ) ? '' : 'none';

			var objectData = {
				distanceToCameraSquared: getDistanceToSquared( camera, object )
			};

			cache.objects.set( object, objectData );

			if ( element.parentNode !== domElement ) {

				domElement.appendChild( element );

			}

			object.onAfterRender( _this, scene, camera );

		}

		for ( var i = 0, l = object.children.length; i < l; i ++ ) {

			renderObject( object.children[ i ], camera );

		}

	};

	var getDistanceToSquared = function () {

		var a = new Vector3();
		var b = new Vector3();

		return function ( object1, object2 ) {

			a.setFromMatrixPosition( object1.matrixWorld );
			b.setFromMatrixPosition( object2.matrixWorld );

			return a.distanceToSquared( b );

		};

	}();

	var filterAndFlatten = function ( scene ) {

		var result = [];

		scene.traverse( function ( object ) {

			if ( object instanceof CSS2DObject ) result.push( object );

		} );

		return result;

	};

	var zOrder = function ( scene ) {

		var sorted = filterAndFlatten( scene ).sort( function ( a, b ) {

			var distanceA = cache.objects.get( a ).distanceToCameraSquared;
			var distanceB = cache.objects.get( b ).distanceToCameraSquared;

			return distanceA - distanceB;

		} );

		var zMax = sorted.length;

		for ( var i = 0, l = sorted.length; i < l; i ++ ) {

			sorted[ i ].element.style.zIndex = zMax - i;

		}

	};

	this.render = function ( scene, camera ) {

		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
		if ( camera.parent === null ) camera.updateMatrixWorld();

		viewMatrix.copy( camera.matrixWorldInverse );
		viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );

		renderObject( scene, scene, camera );
		zOrder( scene );

	};

};

export { CSS2DObject, CSS2DRenderer };
<commit_msg>Updated modules.<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 */

import {
	Matrix4,
	Object3D,
	Vector3
} from "../../../build/three.module.js";

var CSS2DObject = function ( element ) {

	Object3D.call( this );

	this.element = element;
	this.element.style.position = 'absolute';

	this.addEventListener( 'removed', function () {

		this.traverse( function ( object ) {

			if ( object.element instanceof Element && object.element.parentNode !== null ) {

				object.element.parentNode.removeChild( object.element );

			}

		} );

	} );

};

CSS2DObject.prototype = Object.create( Object3D.prototype );
CSS2DObject.prototype.constructor = CSS2DObject;

//

var CSS2DRenderer = function () {

	var _this = this;

	var _width, _height;
	var _widthHalf, _heightHalf;

	var vector = new Vector3();
	var viewMatrix = new Matrix4();
	var viewProjectionMatrix = new Matrix4();

	var cache = {
		objects: new WeakMap()
	};

	var domElement = document.createElement( 'div' );
	domElement.style.overflow = 'hidden';

	this.domElement = domElement;

	this.getSize = function () {

		return {
			width: _width,
			height: _height
		};

	};

	this.setSize = function ( width, height ) {

		_width = width;
		_height = height;

		_widthHalf = _width / 2;
		_heightHalf = _height / 2;

		domElement.style.width = width + 'px';
		domElement.style.height = height + 'px';

	};

	var renderObject = function ( object, scene, camera ) {

		if ( object instanceof CSS2DObject ) {

			object.onBeforeRender( _this, scene, camera );

			vector.setFromMatrixPosition( object.matrixWorld );
			vector.applyMatrix4( viewProjectionMatrix );

			var element = object.element;
			var style = 'translate(-50%,-50%) translate(' + ( vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - vector.y * _heightHalf + _heightHalf ) + 'px)';

			element.style.WebkitTransform = style;
			element.style.MozTransform = style;
			element.style.oTransform = style;
			element.style.transform = style;

			element.style.display = ( object.visible && vector.z >= - 1 && vector.z <= 1 ) ? '' : 'none';

			var objectData = {
				distanceToCameraSquared: getDistanceToSquared( camera, object )
			};

			cache.objects.set( object, objectData );

			if ( element.parentNode !== domElement ) {

				domElement.appendChild( element );

			}

			object.onAfterRender( _this, scene, camera );

		}

		for ( var i = 0, l = object.children.length; i < l; i ++ ) {

			renderObject( object.children[ i ], scene, camera );

		}

	};

	var getDistanceToSquared = function () {

		var a = new Vector3();
		var b = new Vector3();

		return function ( object1, object2 ) {

			a.setFromMatrixPosition( object1.matrixWorld );
			b.setFromMatrixPosition( object2.matrixWorld );

			return a.distanceToSquared( b );

		};

	}();

	var filterAndFlatten = function ( scene ) {

		var result = [];

		scene.traverse( function ( object ) {

			if ( object instanceof CSS2DObject ) result.push( object );

		} );

		return result;

	};

	var zOrder = function ( scene ) {

		var sorted = filterAndFlatten( scene ).sort( function ( a, b ) {

			var distanceA = cache.objects.get( a ).distanceToCameraSquared;
			var distanceB = cache.objects.get( b ).distanceToCameraSquared;

			return distanceA - distanceB;

		} );

		var zMax = sorted.length;

		for ( var i = 0, l = sorted.length; i < l; i ++ ) {

			sorted[ i ].element.style.zIndex = zMax - i;

		}

	};

	this.render = function ( scene, camera ) {

		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
		if ( camera.parent === null ) camera.updateMatrixWorld();

		viewMatrix.copy( camera.matrixWorldInverse );
		viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );

		renderObject( scene, scene, camera );
		zOrder( scene );

	};

};

export { CSS2DObject, CSS2DRenderer };
<|endoftext|>


<commit_before>var fs = require("fs");
var http = require("http");
var express = require("express");
// var connect = require("connect");
// gzip/deflate outgoing responses
var compression = require("compression");
var bodyParser = require("body-parser");
var favicon = require("serve-favicon");
// logger
var morgan = require("morgan");
var serveIndex = require("serve-index");
var serveStatic = require("serve-static");
var auth = require('http-auth');

var config = require("./config");
var media = require("./media");

var basic = auth.basic({
    realm: "thoughtcatchers",
    file: __dirname + "/../data/users.htpasswd"
});

var app = express();
var router = express.Router();
var cors = require('cors');

app.use(auth.connect(basic));
// app.use(favicon(www + "favicon.ico"));

/*
app.use("/", serveIndex(config.www, {
    "icons": true
}));
*/

app.use(compression());

app.use(cors());

// parse urlencoded request bodies into req.body
app.use(bodyParser.urlencoded());

// logger
var accessLogStream = fs.createWriteStream(config.accessLog, {
    flags: "a"
});

/*
app.use(morgan("combined", {
    stream: accessLogStream
}));
*/

app.use(serveStatic(config.www));

app.use("/", router);

router.get("/uploads", function (req, res, next) {
    // console.log("uploads");
    media.listFiles(res);
    next();
});

/*
"index": ["/index.html"],
"about": ["/about.html"],
"contact": ["/contact.html"]
*/

/*
app.use("/", router);

router.get("/", function (req, res) {
    res.sendFile(path + "index.html");
});
*/

/*
router.get("/about", function (req, res) {
    res.sendFile(path + "about.html");
});

router.get("/contact", function (req, res) {
    res.sendFile(path + "contact.html");
});
*/

/* catch all
app.use("*",function(req,res){
  res.sendFile(path + "404.html");
});
*/
/*
router.use(function (req, res, next) {
    // console.log("/" + req.method);
    next();
});
*/

console.log("serving on port " + config.port);
//create node.js http server and listen on port
http.createServer(app).listen(config.port);
<commit_msg>added cors<commit_after>var fs = require("fs");
var http = require("http");
var express = require("express");
// var connect = require("connect");
// gzip/deflate outgoing responses
var compression = require("compression");
var bodyParser = require("body-parser");
var favicon = require("serve-favicon");
// logger
var morgan = require("morgan");
var serveIndex = require("serve-index");
var serveStatic = require("serve-static");
var auth = require('http-auth');
var cors = require('cors');

var config = require("./config");
var media = require("./media");

var basic = auth.basic({
    realm: "thoughtcatchers",
    file: __dirname + "/../data/users.htpasswd"
});

var app = express();

app.use(cors());
var router = express.Router();

app.use(auth.connect(basic));
// app.use(favicon(www + "favicon.ico"));

/*
app.use("/", serveIndex(config.www, {
    "icons": true
}));
*/

app.use(compression());

// parse urlencoded request bodies into req.body
app.use(bodyParser.urlencoded());

// logger
var accessLogStream = fs.createWriteStream(config.accessLog, {
    flags: "a"
});

/*
app.use(morgan("combined", {
    stream: accessLogStream
}));
*/

app.use(serveStatic(config.www));

app.use("/", router);

router.get("/uploads", function (req, res, next) {
    // console.log("uploads");
    media.listFiles(res);
    next();
});

/*
"index": ["/index.html"],
"about": ["/about.html"],
"contact": ["/contact.html"]
*/

/*
app.use("/", router);

router.get("/", function (req, res) {
    res.sendFile(path + "index.html");
});
*/

/*
router.get("/about", function (req, res) {
    res.sendFile(path + "about.html");
});

router.get("/contact", function (req, res) {
    res.sendFile(path + "contact.html");
});
*/

/* catch all
app.use("*",function(req,res){
  res.sendFile(path + "404.html");
});
*/
/*
router.use(function (req, res, next) {
    // console.log("/" + req.method);
    next();
});
*/

console.log("serving on port " + config.port);
//create node.js http server and listen on port
http.createServer(app).listen(config.port);
<|endoftext|>


<commit_before>'use strict';
const promise = require('request-promise');
const Anesidora = require("anesidora");
const Fuse = require('fuse.js');

let settings = {};

try {
  settings = require('../../settings.json');
} catch (e) {}

function getPandoraMetadata(id, title, auth) {
  return `<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
        xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">
        <item id="OOOX${id}" parentID="0" restricted="true"><dc:title>${title}</dc:title><upnp:class>object.item.audioItem.audioBroadcast</upnp:class>
        <desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON3_${auth}</desc></item></DIDL-Lite>`;
}

function getPandoraUri(id, title, albumart) {
  if (albumart == undefined) {
    return `pndrradio:${id}?sn=2`;
  } else {
    return `pndrradio:${id}?sn=2,"title":"${title}","albumArtUri":"${albumart}"`;
  }
}

function pandora(player, values) {
  const cmd = values[0];

  function userLogin() {
    return new Promise(function(resolve, reject) {
      pAPI.login(function(err) {
        if (!err) {
          resolve();
        } else {
          reject(err);
        }
      });
    });
  }

  function pandoraAPI(command, parameters) {
    return new Promise(function(resolve, reject) {
      pAPI.request(command, parameters, function(err, result) {
        if (!err) {
          resolve(result);
        } else {
          console.log("pandoraAPI " + command + " " + JSON.stringify(parameters));
          console.log("ERROR: " + JSON.stringify(err));
          reject(err);
        }
      });
    });
  }

  function playPandora(player, name) {
    var uri = '';
    var metadata = '';

    return userLogin()
      .then(() => pandoraAPI("user.getStationList", {"includeStationArtUrl" : true}))
      .then((stationList) => {
        return pandoraAPI("music.search", {"searchText": name})
          .then((result) => {
            if (result.artists != undefined) {
              result.artists.map(function(artist) {
                if (artist.score > 90) {
                  stationList.stations.push({"stationId":artist.musicToken,"stationName":artist.artistName,"type":"artist"});
                }
              });
            }
            if (result.songs != undefined) {
              result.songs.map(function(song) {
                if (song.score > 90) {
                  stationList.stations.push({"stationId":song.musicToken,"stationName":song.songName,"type":"song"});
                }
              });
            }
            return pandoraAPI("station.getGenreStations", {});
          })
          .then((result) => {
            result.categories.map(function(category) {
              category.stations.map(function(genreStation) {
                stationList.stations.push({"stationId":genreStation.stationToken,"stationName":genreStation.stationName,"type":"song"});
              });
            });
            var fuzzy = new Fuse(stationList.stations, { keys: ["stationName"] });

            const results = fuzzy.search(name);
            if (results.length > 0) {
              const station = results[0];
              if (station.type == undefined) {
                uri = getPandoraUri(station.stationId, station.stationName, station.artUrl);
                metadata = getPandoraMetadata(station.stationId, station.stationName, settings.pandora.username);
                return Promise.resolve();
              } else {
                return pandoraAPI("station.createStation", {"musicToken":station.stationId, "musicType":station.type})
                  .then((stationInfo) => {
                  	 uri = getPandoraUri(stationInfo.stationId);
                     metadata = getPandoraMetadata(stationInfo.stationId, stationInfo.stationName, settings.pandora.username);
                     return Promise.resolve();
                  });
              }
            } else {
              return Promise.reject("No match was found");
            }
          })
          .then(() => player.coordinator.setAVTransport(uri, metadata))
          .then(() => player.coordinator.play());
      });
  }

  if (settings && settings.pandora) {
    var pAPI = new Anesidora(settings.pandora.username, settings.pandora.password);

    if (cmd == 'play') {
      return playPandora(player, values[1]);
    } if ((cmd == 'thumbsup')||(cmd == 'thumbsdown')) {
      const uri = player.state.currentTrack.uri;

      if (uri.startsWith('pndrradio-http')) {
        const stationToken = uri.substring(uri.search('&x=') + 3);
        const trackToken = uri.substring(uri.search('&m=') + 3,uri.search('&f='));

        return pandoraAPI("station.addFeedback", {"stationToken" : stationToken, "trackToken" : trackToken, "isPositive" : up})
          .then(() => {
            if (cmd == 'thumbsdown') {
              return player.coordinator.nextTrack();
            }
          });
      } else {
        return Promise.reject('The music that is playing is not a Pandora station');
      }
    }
  } else {
    console.log('Missing Pandora settings');
    return Promise.reject('Missing Pandora settings');
  }

}

module.exports = function (api) {
  api.registerAction('pandora', pandora);
}

<commit_msg>Update pandora.js<commit_after>'use strict';
const promise = require('request-promise');
const Anesidora = require("anesidora");
const Fuse = require('fuse.js');

let settings = {};

try {
  settings = require('../../settings.json');
} catch (e) {}

function getPandoraMetadata(id, title, auth) {
  return `<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
        xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/">
        <item id="OOOX${id}" parentID="0" restricted="true"><dc:title>${title}</dc:title><upnp:class>object.item.audioItem.audioBroadcast</upnp:class>
        <desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON3_${auth}</desc></item></DIDL-Lite>`;
}

function getPandoraUri(id, title, albumart) {
  if (albumart == undefined) {
    return `pndrradio:${id}?sn=2`;
  } else {
    return `pndrradio:${id}?sn=2,"title":"${title}","albumArtUri":"${albumart}"`;
  }
}

function pandora(player, values) {
  const cmd = values[0];

  function userLogin() {
    return new Promise(function(resolve, reject) {
      pAPI.login(function(err) {
        if (!err) {
          resolve();
        } else {
          reject(err);
        }
      });
    });
  }

  function pandoraAPI(command, parameters) {
    return new Promise(function(resolve, reject) {
      pAPI.request(command, parameters, function(err, result) {
        if (!err) {
          resolve(result);
        } else {
          console.log("pandoraAPI " + command + " " + JSON.stringify(parameters));
          console.log("ERROR: " + JSON.stringify(err));
          reject(err);
        }
      });
    });
  }

  function playPandora(player, name) {
    var uri = '';
    var metadata = '';

    return userLogin()
      .then(() => pandoraAPI("user.getStationList", {"includeStationArtUrl" : true}))
      .then((stationList) => {
        return pandoraAPI("music.search", {"searchText": name})
          .then((result) => {
            if (result.artists != undefined) {
              result.artists.map(function(artist) {
                if (artist.score > 90) {
                  stationList.stations.push({"stationId":artist.musicToken,"stationName":artist.artistName,"type":"artist"});
                }
              });
            }
            if (result.songs != undefined) {
              result.songs.map(function(song) {
                if (song.score > 90) {
                  stationList.stations.push({"stationId":song.musicToken,"stationName":song.songName,"type":"song"});
                }
              });
            }
            return pandoraAPI("station.getGenreStations", {});
          })
          .then((result) => {
            result.categories.map(function(category) {
              category.stations.map(function(genreStation) {
                stationList.stations.push({"stationId":genreStation.stationToken,"stationName":genreStation.stationName,"type":"song"});
              });
            });
            var fuzzy = new Fuse(stationList.stations, { keys: ["stationName"] });

            const results = fuzzy.search(name);
            if (results.length > 0) {
              const station = results[0];
              if (station.type == undefined) {
                uri = getPandoraUri(station.stationId, station.stationName, station.artUrl);
                metadata = getPandoraMetadata(station.stationId, station.stationName, settings.pandora.username);
                return Promise.resolve();
              } else {
                return pandoraAPI("station.createStation", {"musicToken":station.stationId, "musicType":station.type})
                  .then((stationInfo) => {
                  	 uri = getPandoraUri(stationInfo.stationId);
                     metadata = getPandoraMetadata(stationInfo.stationId, stationInfo.stationName, settings.pandora.username);
                     return Promise.resolve();
                  });
              }
            } else {
              return Promise.reject("No match was found");
            }
          })
          .then(() => player.coordinator.setAVTransport(uri, metadata))
          .then(() => player.coordinator.play());
      });
  }

  if (settings && settings.pandora) {
    var pAPI = new Anesidora(settings.pandora.username, settings.pandora.password);

    if (cmd == 'play') {
      return playPandora(player, values[1]);
    } if ((cmd == 'thumbsup')||(cmd == 'thumbsdown')) {
      const uri = player.state.currentTrack.uri;

      if (uri.startsWith('pndrradio-http')) {
        const stationToken = uri.substring(uri.search('&x=') + 3);
        const trackToken = uri.substring(uri.search('&m=') + 3,uri.search('&f='));
        const up = (cmd == 'thumbsup');

        return pandoraAPI("station.addFeedback", {"stationToken" : stationToken, "trackToken" : trackToken, "isPositive" : up})
          .then(() => {
            if (cmd == 'thumbsdown') {
              return player.coordinator.nextTrack();
            }
          });
      } else {
        return Promise.reject('The music that is playing is not a Pandora station');
      }
    }
  } else {
    console.log('Missing Pandora settings');
    return Promise.reject('Missing Pandora settings');
  }

}

module.exports = function (api) {
  api.registerAction('pandora', pandora);
}

<|endoftext|>


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

var assert = require('assert'),
    vows = require('vows'),
    databank = require('databank'),
    URLMaker = require('../lib/urlmaker').URLMaker,
    modelBatch = require('./lib/model').modelBatch,
    Databank = databank.Databank,
    DatabankObject = databank.DatabankObject;

// Need this to make IDs

URLMaker.hostname = "example.net";

// Dummy databank

DatabankObject.bank = Databank.get('memory', {});

var suite = vows.describe('access token interface');

var testSchema = {
    pkey: 'token',
    fields: ['token_secret',
             'consumer_key',
             'username',
             'created',
             'updated'],
    indices: ['username', 'consumer_key']
};

var testData = {
    'create': {
        consumer_key: "AAAAAAAAAAAAAAAAAAAAAA",
        username: "evan"
    },
    'update': {
        consumer_key: "AAAAAAAAAAAAAAAAAAAAAB"
    }
};

suite.addBatch(modelBatch('accesstoken', 'AccessToken', testSchema, testData));

suite.export(module);
<commit_msg>Check for token_secret<commit_after>// accesstoken-test.js
//
// Test the accesstoken module
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var assert = require('assert'),
    vows = require('vows'),
    databank = require('databank'),
    URLMaker = require('../lib/urlmaker').URLMaker,
    modelBatch = require('./lib/model').modelBatch,
    Databank = databank.Databank,
    DatabankObject = databank.DatabankObject;

// Need this to make IDs

URLMaker.hostname = "example.net";

// Dummy databank

DatabankObject.bank = Databank.get('memory', {});

var suite = vows.describe('access token interface');

var testSchema = {
    pkey: 'token',
    fields: ['token_secret',
             'consumer_key',
             'username',
             'created',
             'updated'],
    indices: ['username', 'consumer_key']
};

var testData = {
    'create': {
        consumer_key: "AAAAAAAAAAAAAAAAAAAAAA",
        username: "evan"
    },
    'update': {
        consumer_key: "AAAAAAAAAAAAAAAAAAAAAB"
    }
};

suite.addBatch(modelBatch('accesstoken', 'AccessToken', testSchema, testData));

suite.addBatch({
    'When we create a new accesstoken': {
        topic: function() {
            var AccessToken = require('../lib/model/accesstoken').AccessToken;
            AccessToken.create({consumer_key: "AAAAAAAA",
                                callback: "http://example.com/callback"},
                          this.callback);
        },
        'token_secret is automatically created': function(err, accessToken) {
            assert.isString(accessToken.token_secret);
        }
    }
});

suite.export(module);
<|endoftext|>