<commit_before>/*---------------------------------------------------------
 * OpenERP web_linkedin (module)
 *---------------------------------------------------------*/

openerp.web_linkedin = function(instance) {
    var QWeb = instance.web.qweb;
    var _t = instance.web._t;

    instance.web_linkedin.LinkedinTester = instance.web.Class.extend({
        init: function() {
            this.linkedin_added = false;
            this.linkedin_def = $.Deferred();
            this.auth_def = $.Deferred();
        },
        test_linkedin: function() {
            var self = this;
            return this.test_api_key().pipe(function() {
                if (self.linkedin_added)
                    return self.linkedin_def.promise();
                var tag = document.createElement('script');
                tag.type = 'text/javascript';
                tag.src = "http://platform.linkedin.com/in.js";
                tag.innerHTML = 'api_key : ' + self.api_key + '\nauthorize : true';
                document.getElementsByTagName('head')[0].appendChild(tag);
                self.linkedin_added = true;
                $(tag).load(function() {
                    IN.Event.on(IN, "auth", function() {
                        self.auth_def.resolve();
                    });
                    self.linkedin_def.resolve();
                });
                return self.linkedin_def.promise();
            });
        },
        test_api_key: function() {
            var self = this;
            if (this.api_key) {
                return $.when();
            }
            return new instance.web.Model("ir.config_parameter").call("set_param", ["web.linkedin.apikey", ""]).pipe(function() {
            return new instance.web.Model("ir.config_parameter").call("get_param", ["web.linkedin.apikey"]).pipe(function(a) {
                if (!!a) {
                    self.api_key = a;
                    return true;
                } else {
                    return $.Deferred().reject();
                }
            });
            });
        },
        test_authentication: function() {
            return this.auth_def.promise();
        },
    });

    instance.web_linkedin.tester = new instance.web_linkedin.LinkedinTester();

    instance.web_linkedin.Linkedin = instance.web.form.FieldChar.extend({
        init: function() {
            this._super.apply(this, arguments);
            this.display_dm = new instance.web.DropMisordered(true);
        },
        initialize_content: function() {
            var $ht = $(QWeb.render("FieldChar.linkedin"));
            var $in = this.$("input");
            $in.replaceWith($ht);
            this.$(".oe_linkedin_input").append($in);
            this.$(".oe_linkedin_img").click(_.bind(this.search_linkedin, this));
            this._super();

        },
        search_linkedin: function() {
            var self = this;
            this.display_dm.add(instance.web_linkedin.tester.test_linkedin()).then(function() {
                var pop = new instance.web_linkedin.LinkedinPopup(self, self.get("value"));
                pop.open();
                pop.on("selected", this, function(entity) {
                    self.selected_entity(entity);
                });
            }, _.bind(this.linkedin_disabled, this));
        },
        linkedin_disabled: function() {
            if (instance.connection.uid !== 1) {
                instance.web.dialog($(QWeb.render("LinkedIn.DisabledWarning")), {
                    title: _t("LinkedIn is not enabled"),
                    buttons: [
                        {text: _t("Ok"), click: function() { $(this).dialog("close"); }}
                    ]
                });
            } else {
                new instance.web_linkedin.KeyWizard(this).open();
            }
        },
        selected_entity: function(entity) {
            var self = this;
            this.create_on_change(entity).then(function(to_change) {
                self.view.on_processed_onchange({value:to_change});
            });
        },
        create_on_change: function(entity) {
            var self = this;
            var to_change = {};
            var defs = [];
            if (entity.__type === "company") {
                to_change.is_company = true;
                to_change.name = entity.name;
                to_change.photo = false;
                if (entity.logoUrl) {
                    defs.push(self.rpc('/web_linkedin/binary/url2binary',
                                       {'url': entity.logoUrl}).pipe(function(data){
                        to_change.photo = data;
                    }));
                }
                to_change.website = entity.websiteUrl;
                to_change.phone = false;
                _.each(entity.locations.values || [], function(el) {
                    to_change.phone = el.contactInfo.phone1;
                });
                var children_def = $.Deferred();
                IN.API.PeopleSearch().fields(commonPeopleFields).params({
                        "company-name" : entity.name,
                        "current-company": true,
                        "count": 25,
                    }).result(function(result) {
                        children_def.resolve(result);
                    });
                defs.push(children_def.pipe(function(result) {
                    var defs = _.map(result.people.values || [], function(el) {
                        el.__type = "people";
                        return self.create_on_change(el);
                    });
                    return $.when.apply($, defs).pipe(function() {
                        var p_to_change = _.toArray(arguments);
                        to_change.child_ids = p_to_change;
                    });
                }));
                /* TODO
                to_change.linkedinUrl = _.str.sprintf("http://www.linkedin.com/company/%d", entity.id);
                */
            } else { // people
                to_change.is_company = false;
                to_change.name = entity.formattedName;
                to_change.photo = false;
                if (entity.pictureUrl) {
                    defs.push(self.rpc('/web_linkedin/binary/url2binary',
                                       {'url': entity.pictureUrl}).pipe(function(data){
                        to_change.photo = data;
                    }));
                }
                to_change.mobile = false;
                to_change.phone = false;
                _.each(entity.phoneNumbers.values || [], function(el) {
                    if (el.phoneType === "mobile") {
                        to_change.mobile = el.phoneNumber;
                    } else {
                        to_change.phone = el.phoneNumber;
                    }
                });
                to_change.function = entity.headline;
                /* TODO
                to_change.linkedinUrl = entity.publicProfileUrl;
                */
            }
            return $.when.apply($, defs).pipe(function() {
                return to_change;
            });
        },
    });

    instance.web.form.widgets.add('linkedin', 'instance.web_linkedin.Linkedin');

    var commonPeopleFields = ["id", "picture-url", "public-profile-url",
                            "formatted-name", "location", "phone-numbers", "im-accounts",
                            "main-address", "headline"];

    instance.web_linkedin.LinkedinPopup = instance.web.Dialog.extend({
        template: "Linkedin.popup",
        init: function(parent, text) {
            this._super(parent, {title:_t("LinkedIn search")});
            this.text = text;
            this.limit = 15;
        },
        start: function() {
            this._super();
            var self = this;
            this.on("authentified", this, this.authentified);
            instance.web_linkedin.tester.test_authentication().then(function() {
                self.trigger("authentified");
            });
        },
        authentified: function() {
            var self = this;
            cdef = $.Deferred();
            pdef = $.Deferred();
            IN.API.Raw(_.str.sprintf(
                    "company-search:(companies:" +
                    "(id,name,logo-url,description,industry,website-url,locations))?keywords=%s&count=%d",
                    encodeURI(this.text), this.limit)).result(function (result) {
                cdef.resolve(result);
            });
            IN.API.PeopleSearch().fields(commonPeopleFields).
                params({"keywords": this.text, "count": this.limit}).result(function(result) {
                pdef.resolve(result);
            });
            return $.when(cdef, pdef).then(function(companies, people) {
                var lst = companies.companies.values || [];
                var plst = people.people.values || [];
                lst = _.initial(lst, _.min([self.limit / 2, plst.length]));
                _.map(lst, function(el) {
                    el.__type = "company";
                    return el;
                });
                plst = _.first(plst, self.limit - lst.length)
                _.map(plst, function(el) {
                    el.__type = "people";
                    return el;
                });
                lst = plst.concat(lst);
                console.log("Linkedin search found:", lst.length, lst);
                self.result = lst;
                self.display_result();
            });
        },
        display_result: function() {
            var self = this;
            var i = 0;
            var $row;
            _.each(self.result, function(el) {
                var pc = new instance.web_linkedin.EntityWidget(self, el);
                if (i % 5 === 0) {
                    $row = $("<div style='display: table-row;width:100%'/>");
                    $row.appendTo(self.$(">div"));
                }
                pc.appendTo($row);
                pc.$element.css("display", "table-cell");
                pc.$element.css("width", "20%");
                pc.on("selected", self, function(data) {
                    self.trigger("selected", data);
                    self.destroy();
                });
                i++;
            });
            if (self.result.length === 0) {
                self.$(">div").text(_t("No results found"));
            }
        },
    });

    instance.web_linkedin.EntityWidget = instance.web.Widget.extend({
        template: "Linkedin.EntityWidget",
        init: function(parent, data) {
            this._super(parent);
            this.data = data;
        },
        start: function() {
            var self = this;
            this.$element.click(function() {
                self.trigger("selected", self.data);
            });
            if (this.data.__type === "company") {
                this.$("h3").text(this.data.name);
                self.$("img").attr("src", this.data.logoUrl);
            } else { // people
                this.$("h3").text(this.data.formattedName);
                self.$("img").attr("src", this.data.pictureUrl);
            }
        },
    });

    instance.web_linkedin.KeyWizard = instance.web.Dialog.extend({
        template: "LinkedIn.KeyWizard",
        init: function(parent, text) {
            this._super(parent, {title:_t("LinkedIn API Key")});
        },
        start: function() {
            this._super();
            var self = this;
            this.$("button").click(function() {
                var value = self.$("input").val();
                return new instance.web.Model("ir.config_parameter").call("set_param", ["web.linkedin.apikey", value]).pipe(function() {
                    self.destroy();
                });
            });
        },
    });
};
// vim:et fdc=0 fdl=0:
<commit_msg>To force fucking runbot to reload<commit_after>/*---------------------------------------------------------
 * OpenERP web_linkedin (module)
 *---------------------------------------------------------*/

openerp.web_linkedin = function(instance) {
    var QWeb = instance.web.qweb;
    var _t = instance.web._t;

    instance.web_linkedin.LinkedinTester = instance.web.Class.extend({
        init: function() {
            this.linkedin_added = false;
            this.linkedin_def = $.Deferred();
            this.auth_def = $.Deferred();
        },
        test_linkedin: function() {
            var self = this;
            return this.test_api_key().pipe(function() {
                if (self.linkedin_added)
                    return self.linkedin_def.promise();
                var tag = document.createElement('script');
                tag.type = 'text/javascript';
                tag.src = "http://platform.linkedin.com/in.js";
                tag.innerHTML = 'api_key : ' + self.api_key + '\nauthorize : true';
                document.getElementsByTagName('head')[0].appendChild(tag);
                self.linkedin_added = true;
                $(tag).load(function() {
                    IN.Event.on(IN, "auth", function() {
                        self.auth_def.resolve();
                    });
                    self.linkedin_def.resolve();
                });
                return self.linkedin_def.promise();
            });
        },
        test_api_key: function() {
            var self = this;
            if (this.api_key) {
                return $.when();
            }
            return new instance.web.Model("ir.config_parameter").call("set_param", ["web.linkedin.apikey", ""]).pipe(function() {
            return new instance.web.Model("ir.config_parameter").call("get_param", ["web.linkedin.apikey"]).pipe(function(a) {
                if (!!a) {
                    self.api_key = a;
                    return true;
                } else {
                    return $.Deferred().reject();
                }
            });
            });
        },
        test_authentication: function() {
            return this.auth_def.promise();
        },
    });

    instance.web_linkedin.tester = new instance.web_linkedin.LinkedinTester();

    instance.web_linkedin.Linkedin = instance.web.form.FieldChar.extend({
        init: function() {
            this._super.apply(this, arguments);
            this.display_dm = new instance.web.DropMisordered(true);
        },
        initialize_content: function() {
            var $ht = $(QWeb.render("FieldChar.linkedin"));
            var $in = this.$("input");
            $in.replaceWith($ht);
            this.$(".oe_linkedin_input").append($in);
            this.$(".oe_linkedin_img").click(_.bind(this.search_linkedin, this));
            this._super();

        },
        search_linkedin: function() {
            var self = this;
            this.display_dm.add(instance.web_linkedin.tester.test_linkedin()).then(function() {
                var pop = new instance.web_linkedin.LinkedinPopup(self, self.get("value"));
                pop.open();
                pop.on("selected", this, function(entity) {
                    self.selected_entity(entity);
                });
            }, _.bind(this.linkedin_disabled, this));
        },
        linkedin_disabled: function() {
            if (instance.connection.uid !== 1) {
                instance.web.dialog($(QWeb.render("LinkedIn.DisabledWarning")), {
                    title: _t("LinkedIn is not enabled"),
                    buttons: [
                        {text: _t("Ok"), click: function() { $(this).dialog("close"); }}
                    ]
                });
            } else {
                new instance.web_linkedin.KeyWizard(this).open();
            }
        },
        selected_entity: function(entity) {
            var self = this;
            this.create_on_change(entity).then(function(to_change) {
                self.view.on_processed_onchange({value:to_change});
            });
        },
        create_on_change: function(entity) {
            var self = this;
            var to_change = {};
            var defs = [];
            if (entity.__type === "company") {
                to_change.is_company = true;
                to_change.name = entity.name;
                to_change.photo = false;
                if (entity.logoUrl) {
                    defs.push(self.rpc('/web_linkedin/binary/url2binary',
                                       {'url': entity.logoUrl}).pipe(function(data){
                        to_change.photo = data;
                    }));
                }
                to_change.website = entity.websiteUrl;
                to_change.phone = false;
                _.each(entity.locations.values || [], function(el) {
                    to_change.phone = el.contactInfo.phone1;
                });
                var children_def = $.Deferred();
                IN.API.PeopleSearch().fields(commonPeopleFields).params({
                        "company-name" : entity.name,
                        "current-company": true,
                        "count": 25,
                    }).result(function(result) {
                        children_def.resolve(result);
                    });
                defs.push(children_def.pipe(function(result) {
                    var defs = _.map(result.people.values || [], function(el) {
                        el.__type = "people";
                        return self.create_on_change(el);
                    });
                    return $.when.apply($, defs).pipe(function() {
                        var p_to_change = _.toArray(arguments);
                        to_change.child_ids = p_to_change;
                    });
                }));
                /* TODO
                to_change.linkedinUrl = _.str.sprintf("http://www.linkedin.com/company/%d", entity.id);
                */
            } else { // people
                to_change.is_company = false;
                to_change.name = entity.formattedName;
                to_change.photo = false;
                if (entity.pictureUrl) {
                    defs.push(self.rpc('/web_linkedin/binary/url2binary',
                                       {'url': entity.pictureUrl}).pipe(function(data){
                        to_change.photo = data;
                    }));
                }
                to_change.mobile = false;
                to_change.phone = false;
                _.each(entity.phoneNumbers.values || [], function(el) {
                    if (el.phoneType === "mobile") {
                        to_change.mobile = el.phoneNumber;
                    } else {
                        to_change.phone = el.phoneNumber;
                    }
                });
                to_change.function = entity.headline;
                /* TODO
                to_change.linkedinUrl = entity.publicProfileUrl;
                */
            }
            return $.when.apply($, defs).pipe(function() {
                return to_change;
            });
        },
    });

    instance.web.form.widgets.add('linkedin', 'instance.web_linkedin.Linkedin');

    var commonPeopleFields = ["id", "picture-url", "public-profile-url",
                            "formatted-name", "location", "phone-numbers", "im-accounts",
                            "main-address", "headline"];

    instance.web_linkedin.LinkedinPopup = instance.web.Dialog.extend({
        template: "Linkedin.popup",
        init: function(parent, text) {
            this._super(parent, {title:_t("LinkedIn search")});
            this.text = text;
            this.limit = 15;
        },
        start: function() {
            this._super();
            var self = this;
            this.on("authentified", this, this.authentified);
            instance.web_linkedin.tester.test_authentication().then(function() {
                self.trigger("authentified");
            });
        },
        authentified: function() {
            var self = this;
            cdef = $.Deferred();
            pdef = $.Deferred();
            IN.API.Raw(_.str.sprintf(
                    "company-search:(companies:" +
                    "(id,name,logo-url,description,industry,website-url,locations))?keywords=%s&count=%d",
                    encodeURI(this.text), this.limit)).result(function (result) {
                cdef.resolve(result);
            });
            IN.API.PeopleSearch().fields(commonPeopleFields).
                params({"keywords": this.text, "count": this.limit}).result(function(result) {
                pdef.resolve(result);
            });
            return $.when(cdef, pdef).then(function(companies, people) {
                var lst = companies.companies.values || [];
                var plst = people.people.values || [];
                lst = _.initial(lst, _.min([self.limit / 2, plst.length]));
                _.map(lst, function(el) {
                    el.__type = "company";
                    return el;
                });
                plst = _.first(plst, self.limit - lst.length)
                _.map(plst, function(el) {
                    el.__type = "people";
                    return el;
                });
                lst = plst.concat(lst);
                console.log("Linkedin search found:", lst.length, lst);
                self.result = lst;
                self.display_result();
            });
        },
        display_result: function() {
            var self = this;
            var i = 0;
            var $row;
            _.each(self.result, function(el) {
                var pc = new instance.web_linkedin.EntityWidget(self, el);
                if (i % 5 === 0) {
                    $row = $("<div style='display: table-row;width:100%'/>");
                    $row.appendTo(self.$(">div"));
                }
                pc.appendTo($row);
                pc.$element.css("display", "table-cell");
                pc.$element.css("width", "20%");
                pc.on("selected", self, function(data) {
                    self.trigger("selected", data);
                    self.destroy();
                });
                i++;
            });
            if (self.result.length === 0) {
                self.$(">div").text(_t("No results found"));
            }
        },
    });

    instance.web_linkedin.EntityWidget = instance.web.Widget.extend({
        template: "Linkedin.EntityWidget",
        init: function(parent, data) {
            this._super(parent);
            this.data = data;
        },
        start: function() {
            var self = this;
            this.$element.click(function() {
                self.trigger("selected", self.data);
            });
            if (this.data.__type === "company") {
                this.$("h3").text(this.data.name);
                self.$("img").attr("src", this.data.logoUrl);
            } else { // people
                this.$("h3").text(this.data.formattedName);
                self.$("img").attr("src", this.data.pictureUrl);
            }
        },
    });

    instance.web_linkedin.KeyWizard = instance.web.Dialog.extend({
        template: "LinkedIn.KeyWizard",
        init: function(parent, text) {
            this._super(parent, {title:_t("LinkedIn API Key")});
        },
        start: function() {
            this._super();
            var self = this;
            this.$("button").click(function() {
                var value = self.$("input").val();
                return new instance.web.Model("ir.config_parameter").call("set_param", ["web.linkedin.apikey", value]).pipe(function() {
                    self.destroy();
                });
            });
        },
    });
};
// vim:et fdc=0 fdl=0:
<|endoftext|>


<commit_before>/*
Script: ART.Shape.js

License:
	MIT-style license.
*/

// ART.Shape Class stub.
// Will probably support defining shapes as json at some point.
// Right now, its just functions.

ART.Shape = function(shape){
	return shape;
};

ART.Paint.defineShape = function(name, shape){
	ART.Shape[name.camelCase()] = new ART.Shape(shape);
	return this;
};

ART.Paint.defineShapes = function(shapes){
	for (var shape in shapes) this.defineShape(shape, shapes[shape]);
	return this;
};

ART.Paint.lookupShape = function(name){
	return ART.Shape[name.camelCase()];
};

// connect to ART.Paint

ART.Paint.implement({

	shape: function(shape){
		var args = Array.slice(arguments, 1);
		if (typeof shape == 'string') shape = ART.Paint.lookupShape(shape.camelCase());
		if (!shape) return this;
		this.save();
		shape.apply(this, args);
		return this.restore();
	}

});

// default shapes

ART.Paint.defineShapes({

	rectangle: function(end){
		this.lineBy({x: end.x, y: 0}).lineBy({x: 0, y: end.y}).lineBy({x: -end.x, y: 0}).lineBy({x: 0, y: -end.y});
	},

	ellipse: function(end){
		var radius = {x: end.x / 2, y: end.y / 2};
		this.moveBy({x: 0, y: radius.y});
		this.roundCapLeftBy({x: radius.x, y: -radius.y}).roundCapRightBy({x: radius.x, y: radius.y});
		this.roundCapLeftBy({x: -radius.x, y: radius.y}).roundCapRightBy({x: -radius.x, y: -radius.y});
		this.moveBy({x: end.x, y: - radius.y + end.y});
	},

	roundedRectangle: function(end, radius){
		if (radius == null) radius = [5, 5, 5, 5];
		if (typeof radius == 'number') radius = [radius, radius, radius, radius];

		var tl = radius[0], tr = radius[1], br = radius[2], bl = radius[3];

		this.moveBy({x: 0, y: tl});

		if (end.x < 0) this.moveBy({x: end.x, y: 0});
		if (end.y < 0) this.moveBy({x: 0, y: end.y});

		if (tl > 0) this.roundCapLeftBy({x: tl, y: -tl});
		this.lineBy({x: Math.abs(end.x) - (tr + tl), y: 0});

		if (tr > 0) this.roundCapRightBy({x: tr, y: tr});
		this.lineBy({x: 0, y: Math.abs(end.y) - (tr + br)});

		if (br > 0) this.roundCapLeftBy({x: -br, y: br});
		this.lineBy({x: - Math.abs(end.x) + (br + bl), y: 0});

		if (bl > 0) this.roundCapRightBy({x: -bl, y: -bl});
		this.lineBy({x: 0, y: - Math.abs(end.y) + (bl + tl)});

		this.moveBy({x: end.x, y: -tl + end.y});
	},

	triangle: function(size, direction){
		var x = size.x,
			y = size.y,
			z;
		switch(direction) {
			case 'left':
				this.shift({x: 0, y: y/2})
					.lineBy({x: x, y: -y/2})
					.lineBy({x: 0, y: y})
					.lineBy({x: -x, y: -y/2});
				break;
			case 'up':
				this.shift({x: x/2, y: 0});
				this.lineBy({x: x/2, y: y})
					.lineBy({x: -x, y: 0})
					.lineBy({x: x/2, y: -y});
				break;
			case 'down':
				this.lineBy({x: x, y: 0})
					.lineBy({x: -x/2, y: y})
					.lineBy({x: -x/2, y: -y});
				break;
			default: //right
				this.lineBy({x: x, y: y/2})
					.lineBy({x: -x, y: y/2})
					.lineBy({x: 0, y: y});
				break;
		}
	}

});

// And some extra glyphs

ART.Paint.defineShape('horizontal-pill', function(size){
	var r = (size.y / 2);
	this.shape('rounded-rectangle', {x: size.x, y: size.y}, r);
});

ART.Paint.defineShape('vertical-pill', function(size){
	var r = (size.x / 2);
	this.shape('rounded-rectangle', {x: size.x, y: size.y}, r);
});

ART.Paint.defineShape('plus-icon', function(size){
	this.moveBy({x: 0, y: (size.y / 2)});
	this.lineBy({x: size.x, y: 0});
	this.moveBy({x: -(size.x / 2), y: -(size.y / 2)});
	this.lineBy({x: 0, y: size.y});
});

ART.Paint.defineShape('resize-icon', function(size){
	this.moveBy({x: size.x, y: 0});
	this.lineBy({x: -size.x, y: size.y});
});

ART.Paint.defineShape('minus-icon', function(size){
	this.moveBy({x: 0, y: (size.y / 2)});
	this.lineBy({x: size.x, y: 0});
});

ART.Paint.defineShape('search-icon', function(size){
	ratio = 0.8;
	var max = ratio, min = 1 - ratio;
	this.shape('ellipse', {x: size.x * max, y: size.y * max});
	var lift = {x: -(size.x * min) / 2, y: -(size.y * min) / 2};
	this.moveBy(lift);
	this.lineBy({x: (size.x * min) - lift.x, y: (size.y * min) - lift.y});
});

ART.Paint.defineShape('close-icon', function(size){
	this.moveBy({x: size.x, y: 0});
	this.lineBy({x: -size.x, y: size.y});
	this.moveBy({x: 0, y: -size.y});
	this.lineBy({x: size.x, y: size.y});
});
<commit_msg>adding shortcut for size arguments; can now be numbers adding refresh icon<commit_after>/*
Script: ART.Shape.js

License:
	MIT-style license.
*/

// ART.Shape Class stub.
// Will probably support defining shapes as json at some point.
// Right now, its just functions.

ART.Shape = function(shape){
	return shape;
};

ART.Paint.defineShape = function(name, shape){
	ART.Shape[name.camelCase()] = new ART.Shape(shape);
	return this;
};

ART.Paint.defineShapes = function(shapes){
	for (var shape in shapes) this.defineShape(shape, shapes[shape]);
	return this;
};

ART.Paint.lookupShape = function(name){
	return ART.Shape[name.camelCase()];
};

// connect to ART.Paint

ART.Paint.implement({

	getXY: function(size) {
		return $type(size) == "number" ? { x: size, y: size } : size;
	},

	shape: function(shape){
		var args = Array.slice(arguments, 1);
		if (typeof shape == 'string') shape = ART.Paint.lookupShape(shape.camelCase());
		if (!shape) return this;
		this.save();
		shape.apply(this, args);
		return this.restore();
	}

});

// default shapes

ART.Paint.defineShapes({

	rectangle: function(end){
		end = this.getXY(end);
		this.lineBy({x: end.x, y: 0}).lineBy({x: 0, y: end.y}).lineBy({x: -end.x, y: 0}).lineBy({x: 0, y: -end.y});
	},

	ellipse: function(end){
		end = this.getXY(end);
		var radius = {x: end.x / 2, y: end.y / 2};
		this.moveBy({x: 0, y: radius.y});
		this.roundCapLeftBy({x: radius.x, y: -radius.y}).roundCapRightBy({x: radius.x, y: radius.y});
		this.roundCapLeftBy({x: -radius.x, y: radius.y}).roundCapRightBy({x: -radius.x, y: -radius.y});
		this.moveBy({x: end.x, y: - radius.y + end.y});
	},

	roundedRectangle: function(end, radius){
		end = this.getXY(end);
		if (radius == null) radius = [5, 5, 5, 5];
		if (typeof radius == 'number') radius = [radius, radius, radius, radius];

		var tl = radius[0], tr = radius[1], br = radius[2], bl = radius[3];

		this.moveBy({x: 0, y: tl});

		if (end.x < 0) this.moveBy({x: end.x, y: 0});
		if (end.y < 0) this.moveBy({x: 0, y: end.y});

		if (tl > 0) this.roundCapLeftBy({x: tl, y: -tl});
		this.lineBy({x: Math.abs(end.x) - (tr + tl), y: 0});

		if (tr > 0) this.roundCapRightBy({x: tr, y: tr});
		this.lineBy({x: 0, y: Math.abs(end.y) - (tr + br)});

		if (br > 0) this.roundCapLeftBy({x: -br, y: br});
		this.lineBy({x: - Math.abs(end.x) + (br + bl), y: 0});

		if (bl > 0) this.roundCapRightBy({x: -bl, y: -bl});
		this.lineBy({x: 0, y: - Math.abs(end.y) + (bl + tl)});

		this.moveBy({x: end.x, y: -tl + end.y});
	},

	triangle: function(size, direction){
		size = this.getXY(size);
		var x = size.x,
			y = size.y;
		switch(direction) {
			case 'left':
				this.shift({x: 0, y: y/2})
					.lineBy({x: x, y: -y/2})
					.lineBy({x: 0, y: y})
					.lineBy({x: -x, y: -y/2});
				break;
			case 'up':
				this.shift({x: x/2, y: 0});
				this.lineBy({x: x/2, y: y})
					.lineBy({x: -x, y: 0})
					.lineBy({x: x/2, y: -y});
				break;
			case 'down':
				this.lineBy({x: x, y: 0})
					.lineBy({x: -x/2, y: y})
					.lineBy({x: -x/2, y: -y});
				break;
			default: //right
				this.lineBy({x: x, y: y/2})
					.lineBy({x: -x, y: y/2})
					.lineBy({x: 0, y: -y});
				break;
		}
	}

});

// And some extra glyphs

ART.Paint.defineShape('horizontal-pill', function(size){
	size = this.getXY(size);
	var r = (size.y / 2);
	this.shape('rounded-rectangle', {x: size.x, y: size.y}, r);
});

ART.Paint.defineShape('vertical-pill', function(size){
	size = this.getXY(size);
	var r = (size.x / 2);
	this.shape('rounded-rectangle', {x: size.x, y: size.y}, r);
});

ART.Paint.defineShape('plus-icon', function(size){
	size = this.getXY(size);
	this.moveBy({x: 0, y: (size.y / 2)});
	this.lineBy({x: size.x, y: 0});
	this.moveBy({x: -(size.x / 2), y: -(size.y / 2)});
	this.lineBy({x: 0, y: size.y});
});

ART.Paint.defineShape('resize-icon', function(size){
	size = this.getXY(size);
	this.moveBy({x: size.x, y: 0});
	this.lineBy({x: -size.x, y: size.y});
});

ART.Paint.defineShape('minus-icon', function(size){
	size = this.getXY(size);
	this.moveBy({x: 0, y: (size.y / 2)});
	this.lineBy({x: size.x, y: 0});
});

ART.Paint.defineShape('search-icon', function(size){
	size = this.getXY(size);
	ratio = 0.8;
	var max = ratio, min = 1 - ratio;
	this.shape('ellipse', {x: size.x * max, y: size.y * max});
	var lift = {x: -(size.x * min) / 2, y: -(size.y * min) / 2};
	this.moveBy(lift);
	this.lineBy({x: (size.x * min) - lift.x, y: (size.y * min) - lift.y});
});

ART.Paint.defineShape('close-icon', function(size){
	size = this.getXY(size);
	this.moveBy({x: size.x, y: 0});
	this.lineBy({x: -size.x, y: size.y});
	this.moveBy({x: 0, y: -size.y});
	this.lineBy({x: size.x, y: size.y});
});

ART.Paint.defineShape('refresh', function(size, options){
	size = this.getXY(size);

	options = $merge({
		stroke: {
			x: size.x / 12,
			y: size.y / 12
		}
	}, options);

	var rad = {
		x: size.x / 4,
		y: size.y / 4
	};

	var stroke = this.getXY(options.stroke);

	this.roundCapRightBy({x: -rad.x, y: rad.y});
	this.roundCapLeftBy({x: rad.x, y: rad.x});
	this.roundCapRightBy({x: rad.x, y: -rad.x});
	this.lineBy({x: -stroke.x, y: 0});
	this.roundCapLeftBy({x: -rad.x + stroke.y, y: size.y/4 - stroke.y});
	this.roundCapRightBy({x: -rad.x + stroke.y, y: - size.y/4 + stroke.y});
	this.roundCapLeftBy({x: rad.x - stroke.y, y: - size.y/4 + stroke.y});

	this.moveBy({x: 0, y: (-stroke.y - rad.y) / 2});
	this.shape('triangle', {x: rad.x, y:rad.y}, 'right');
});<|endoftext|>


<commit_before>'use strict';

// Declare app level module which depends on filters, and services
angular.module('myApp.controllers', ['myApp.services']);
angular.module('myApp.directives', ['myApp.filters', 'myApp.services']);
angular.module('myApp.services', ['ngResource']);

angular.module(
        'myApp', ['myApp.filters',
            'myApp.services',
            'myApp.directives',
            'myApp.controllers',
            'ngRoute',
            'ngSanitize',
            'mgcrea.ngStrap'
        ])
    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/', {
            templateUrl: 'partials/evidence.html'
        });
        $routeProvider.otherwise({
            redirectTo: '/'
        });
    }])

// Store config for data and tool access in the rootScope after promise resolution
.run(['$resource', '$location', '$rootScope', function ($resource, $location, $rootScope) {
    // remove /# and everything following to ensure we get host root url (and everything between / and #)
    $rootScope.absUrl = $location.absUrl().replace(/(\/.*#.*)/, '');
    // remove trailing slash
    $rootScope.absUrl = $rootScope.absUrl.replace(/(\/)$/, '');

    var index = $rootScope.absUrl.indexOf('lig');
    if (index == -1) {
        index = $rootScope.absUrl.indexOf('limsi');
    }
    if (index != -1) {
        $rootScope.absUrl = $rootScope.absUrl.substr(0, index - 1);
    }

}]);

function streamTest(){
        var path = document.getElementById("localServerInput").value;
        var html = '<video id="playertest1" src="'+path+'/3-24/0121200000DVBT6x1.mp4" height="80px" style="margin-top:-40px; margin-left:15px;" crossorigin="anonymous"></video>';
        document.getElementById('videoTest1').innerHTML = html;
        document.getElementById('playertest1').currentTime = 12*60+56;
        document.getElementById('playertest1').pause();
        html = '<video id="playertest2" src="'+path+'/DW/DW-news-DE/004435bc-97bf-8935-0d63-fb47561fdfa4.mp4" height="80px" style="margin-top:-40px; margin-left:15px;" crossorigin="anonymous"></video>';
        document.getElementById('videoTest2').innerHTML = html;
        document.getElementById('playertest2').currentTime = 28;
        document.getElementById('playertest2').pause();
        html = '<video id="playertest3" src="'+path+'/INA/snowden/F2_TS/20130607/130607FR20000_B.MPG.mp4" height="80px" style="margin-top:-40px; margin-left:15px;" crossorigin="anonymous"></video>';
        document.getElementById('videoTest3').innerHTML = html;
        document.getElementById('playertest3').currentTime = 70;
        document.getElementById('playertest3').pause();
    }
    function eraseTest(){
        document.getElementById('videoTest1').innerHTML = "";
        document.getElementById('videoTest2').innerHTML = "";
        document.getElementById('videoTest3').innerHTML = "";
    }
    function updateLabel(){
        document.getElementById('label_name').innerHTML = document.getElementById('entry_input').value;
    }<commit_msg>Move updateLabel function to another file<commit_after>'use strict';

// Declare app level module which depends on filters, and services
angular.module('myApp.controllers', ['myApp.services']);
angular.module('myApp.directives', ['myApp.filters', 'myApp.services']);
angular.module('myApp.services', ['ngResource']);

angular.module(
        'myApp', ['myApp.filters',
            'myApp.services',
            'myApp.directives',
            'myApp.controllers',
            'ngRoute',
            'ngSanitize',
            'mgcrea.ngStrap'
        ])
    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/', {
            templateUrl: 'partials/evidence.html'
        });
        $routeProvider.otherwise({
            redirectTo: '/'
        });
    }])

// Store config for data and tool access in the rootScope after promise resolution
.run(['$resource', '$location', '$rootScope', function ($resource, $location, $rootScope) {
    // remove /# and everything following to ensure we get host root url (and everything between / and #)
    $rootScope.absUrl = $location.absUrl().replace(/(\/.*#.*)/, '');
    // remove trailing slash
    $rootScope.absUrl = $rootScope.absUrl.replace(/(\/)$/, '');

    var index = $rootScope.absUrl.indexOf('lig');
    if (index == -1) {
        index = $rootScope.absUrl.indexOf('limsi');
    }
    if (index != -1) {
        $rootScope.absUrl = $rootScope.absUrl.substr(0, index - 1);
    }

}]);

function streamTest(){
        var path = document.getElementById("localServerInput").value;
        var html = '<video id="playertest1" src="'+path+'/3-24/0121200000DVBT6x1.mp4" height="80px" style="margin-top:-40px; margin-left:15px;" crossorigin="anonymous"></video>';
        document.getElementById('videoTest1').innerHTML = html;
        document.getElementById('playertest1').currentTime = 12*60+56;
        document.getElementById('playertest1').pause();
        html = '<video id="playertest2" src="'+path+'/DW/DW-news-DE/004435bc-97bf-8935-0d63-fb47561fdfa4.mp4" height="80px" style="margin-top:-40px; margin-left:15px;" crossorigin="anonymous"></video>';
        document.getElementById('videoTest2').innerHTML = html;
        document.getElementById('playertest2').currentTime = 28;
        document.getElementById('playertest2').pause();
        html = '<video id="playertest3" src="'+path+'/INA/snowden/F2_TS/20130607/130607FR20000_B.MPG.mp4" height="80px" style="margin-top:-40px; margin-left:15px;" crossorigin="anonymous"></video>';
        document.getElementById('videoTest3').innerHTML = html;
        document.getElementById('playertest3').currentTime = 70;
        document.getElementById('playertest3').pause();
    }
function eraseTest(){
        document.getElementById('videoTest1').innerHTML = "";
        document.getElementById('videoTest2').innerHTML = "";
        document.getElementById('videoTest3').innerHTML = "";
}
    <|endoftext|>


<commit_before>var math = require('../math'),
    Texture = require('../textures/Texture'),
    Container = require('../display/Container'),
    utils = require('../utils'),
    CONST = require('../const'),
    tempPoint = new math.Point();

/**
 * The Sprite object is the base for all textured objects that are rendered to the screen
 *
 * A sprite can be created directly from an image like this:
 *
 * ```js
 * var sprite = new PIXI.Sprite.fromImage('assets/image.png');
 * ```
 *
 * @class
 * @extends PIXI.Container
 * @memberof PIXI
 * @param texture {PIXI.Texture} The texture for this sprite
 */
function Sprite(texture)
{
    Container.call(this);

    /**
     * The anchor sets the origin point of the texture.
     * The default is 0,0 this means the texture's origin is the top left
     * Setting the anchor to 0.5,0.5 means the texture's origin is centered
     * Setting the anchor to 1,1 would mean the texture's origin point will be the bottom right corner
     *
     * @member {PIXI.Point}
     */
    this.anchor = new math.Point();

    /**
     * The texture that the sprite is using
     *
     * @member {PIXI.Texture}
     * @private
     */
    this._texture = null;

    /**
     * The width of the sprite (this is initially set by the texture)
     *
     * @member {number}
     * @private
     */
    this._width = 0;

    /**
     * The height of the sprite (this is initially set by the texture)
     *
     * @member {number}
     * @private
     */
    this._height = 0;

    /**
     * The tint applied to the sprite. This is a hex value. A value of 0xFFFFFF will remove any tint effect.
     *
     * @member {number}
     * @default 0xFFFFFF
     */
    this.tint = 0xFFFFFF;

    /**
     * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.
     *
     * @member {number}
     * @default PIXI.BLEND_MODES.NORMAL
     * @see PIXI.BLEND_MODES
     */
    this.blendMode = CONST.BLEND_MODES.NORMAL;

    /**
     * The shader that will be used to render the sprite. Set to null to remove a current shader.
     *
     * @member {PIXI.AbstractFilter|PIXI.Shader}
     */
    this.shader = null;

    /**
     * An internal cached value of the tint.
     *
     * @member {number}
     * @default 0xFFFFFF
     */
    this.cachedTint = 0xFFFFFF;

    // call texture setter
    this.texture = texture || Texture.EMPTY;
    this.textureDirty = true;
    this.vertexData = new Float32Array(8);
}

// constructor
Sprite.prototype = Object.create(Container.prototype);
Sprite.prototype.constructor = Sprite;
module.exports = Sprite;

Object.defineProperties(Sprite.prototype, {
    /**
     * The width of the sprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.Sprite#
     */
    width: {
        get: function ()
        {
            return Math.abs(this.scale.x) * (this.texture.trim || this.texture.orig).width;
        },
        set: function (value)
        {
            var sign = utils.sign(this.scale.x) || 1;
            this.scale.x = sign * value / (this.texture.trim || this.texture.orig).width;
            this._width = value;
        }
    },

    /**
     * The height of the sprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.Sprite#
     */
    height: {
        get: function ()
        {
            return  Math.abs(this.scale.y) * (this.texture.trim || this.texture.orig).height;
        },
        set: function (value)
        {
            var sign = utils.sign(this.scale.y) || 1;
            this.scale.y = sign * value / (this.texture.trim || this.texture.orig).height;
            this._height = value;
        }
    },

    /**
     * The texture that the sprite is using
     *
     * @member {PIXI.Texture}
     * @memberof PIXI.Sprite#
     */
    texture: {
        get: function ()
        {
            return  this._texture;
        },
        set: function (value)
        {
            if (this._texture === value)
            {
                return;
            }

            this._texture = value;
            this.cachedTint = 0xFFFFFF;

            this.textureDirty = true;

            if (value)
            {
                // wait for the texture to load
                if (value.baseTexture.hasLoaded)
                {
                    this._onTextureUpdate();
                }
                else
                {
                    value.once('update', this._onTextureUpdate, this);
                }
            }
        }
    }
});

/**
 * When the texture is updated, this event will fire to update the scale and frame
 *
 * @private
 */
Sprite.prototype._onTextureUpdate = function ()
{
    this.textureDirty = true;

    // so if _width is 0 then width was not set..
    if (this._width)
    {
        this.scale.x = utils.sign(this.scale.x) * this._width / (this.texture.trim || this.texture.orig).width;
    }

    if (this._height)
    {
        this.scale.y = utils.sign(this.scale.y) * this._height / (this.texture.trim || this.texture.orig).height;
    }
};

Sprite.prototype.calculateVertices = function ()
{
    var texture = this._texture,
        wt = this.transform.worldTransform,
        a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
        vertexData = this.vertexData,
        w0, w1, h0, h1,
        trim = texture.trim,
        orig = texture.orig;

    if (trim)
    {
        // if the sprite is trimmed and is not a tilingsprite then we need to add the extra space before transforming the sprite coords..
        w1 = trim.x - this.anchor.x * orig.width;
        w0 = w1 + trim.width;

        h1 = trim.y - this.anchor.y * orig.height;
        h0 = h1 + trim.height;

    }
    else
    {
        w0 = (orig.width ) * (1-this.anchor.x);
        w1 = (orig.width ) * -this.anchor.x;

        h0 = orig.height * (1-this.anchor.y);
        h1 = orig.height * -this.anchor.y;
    }

    // xy
    vertexData[0] = a * w1 + c * h1 + tx;
    vertexData[1] = d * h1 + b * w1 + ty;

    // xy
    vertexData[2] = a * w0 + c * h1 + tx;
    vertexData[3] = d * h1 + b * w0 + ty;

     // xy
    vertexData[4] = a * w0 + c * h0 + tx;
    vertexData[5] = d * h0 + b * w0 + ty;

    // xy
    vertexData[6] = a * w1 + c * h0 + tx;
    vertexData[7] = d * h0 + b * w1 + ty;
};

/**
*
* Renders the object using the WebGL renderer
*
* @param renderer {PIXI.WebGLRenderer}
* @private
*/
Sprite.prototype._renderWebGL = function (renderer)
{
    if(this.transform.updated || this.textureDirty)
    {
        this.textureDirty = false;
        // set the vertex data
        this.calculateVertices();
    }

    renderer.setObjectRenderer(renderer.plugins.sprite);
    renderer.plugins.sprite.render(this);
};

/**
* Renders the object using the Canvas renderer
*
* @param renderer {PIXI.CanvasRenderer} The renderer
* @private
*/
Sprite.prototype._renderCanvas = function (renderer)
{
    renderer.plugins.sprite.render(this);
};

/**
 * Returns the bounds of the Sprite as a rectangle. The bounds calculation takes the worldTransform into account.
 *
 * @return {PIXI.Rectangle} the framing rectangle
 */
Sprite.prototype.getBounds = function ()
{
    //TODO lookinto caching..
    if(!this._currentBounds)
    {
       // if(this.vertexDirty)
        {
            this.vertexDirty = false;

            // set the vertex data
            this.calculateVertices();

        }

        var minX, maxX, minY, maxY,
            w0, w1, h0, h1,
            vertexData = this.vertexData;

        var x1 = vertexData[0];
        var y1 = vertexData[1];

        var x2 = vertexData[2];
        var y2 = vertexData[3];

        var x3 = vertexData[4];
        var y3 = vertexData[5];

        var x4 = vertexData[6];
        var y4 = vertexData[7];

        minX = x1;
        minX = x2 < minX ? x2 : minX;
        minX = x3 < minX ? x3 : minX;
        minX = x4 < minX ? x4 : minX;

        minY = y1;
        minY = y2 < minY ? y2 : minY;
        minY = y3 < minY ? y3 : minY;
        minY = y4 < minY ? y4 : minY;

        maxX = x1;
        maxX = x2 > maxX ? x2 : maxX;
        maxX = x3 > maxX ? x3 : maxX;
        maxX = x4 > maxX ? x4 : maxX;

        maxY = y1;
        maxY = y2 > maxY ? y2 : maxY;
        maxY = y3 > maxY ? y3 : maxY;
        maxY = y4 > maxY ? y4 : maxY;

        // check for children
        if(this.children.length)
        {
            var childBounds = this.containerGetBounds();

            w0 = childBounds.x;
            w1 = childBounds.x + childBounds.width;
            h0 = childBounds.y;
            h1 = childBounds.y + childBounds.height;

            minX = (minX < w0) ? minX : w0;
            minY = (minY < h0) ? minY : h0;

            maxX = (maxX > w1) ? maxX : w1;
            maxY = (maxY > h1) ? maxY : h1;
        }

        var bounds = this._bounds;

        bounds.x = minX;
        bounds.width = maxX - minX;

        bounds.y = minY;
        bounds.height = maxY - minY;

        // store a reference so that if this function gets called again in the render cycle we do not have to recalculate
        this._currentBounds = bounds;
    }

    return this._currentBounds;
};

/**
 * Gets the local bounds of the sprite object.
 *
 */
Sprite.prototype.getLocalBounds = function ()
{
    this._bounds.x = -this._texture.orig.width * this.anchor.x;
    this._bounds.y = -this._texture.orig.height * this.anchor.y;
    this._bounds.width = this._texture.orig.width;
    this._bounds.height = this._texture.orig.height;
    return this._bounds;
};

/**
* Tests if a point is inside this sprite
*
* @param point {PIXI.Point} the point to test
* @return {boolean} the result of the test
*/
Sprite.prototype.containsPoint = function( point )
{
    this.worldTransform.applyInverse(point,  tempPoint);

    var width = this._texture.orig.width;
    var height = this._texture.orig.height;
    var x1 = -width * this.anchor.x;
    var y1;

    if ( tempPoint.x > x1 && tempPoint.x < x1 + width )
    {
        y1 = -height * this.anchor.y;

        if ( tempPoint.y > y1 && tempPoint.y < y1 + height )
        {
            return true;
        }
    }

    return false;
};

/**
 * Destroys this sprite and optionally its texture and children
 *
 * @param [options] {object|boolean} Options parameter. A boolean will act as if all options have been set to that value
 * @param [options.children=false] {boolean} if set to true, all the children will have their destroy
 *      method called as well. 'options' will be passed on to those calls.
 * @param [options.texture=false] {boolean} Should it destroy the current texture of the sprite as well
 * @param [options.baseTexture=false] {boolean} Should it destroy the base texture of the sprite as well
 */
Sprite.prototype.destroy = function (options)
{
    Container.prototype.destroy.call(this, options);

    this.anchor = null;

    var destroyTexture = typeof options === 'boolean' ? options : options && options.texture;
    if (destroyTexture)
    {
        var destroyBaseTexture = typeof options === 'boolean' ? options : options && options.baseTexture;
        this._texture.destroy(!!destroyBaseTexture);
    }

    this._texture = null;
    this.shader = null;
};

// some helper functions..

/**
 * Helper function that creates a new sprite based on the source you provide.
 * The soucre can be - frame id, image url, video url, canvae element, video element, base texture
 *
 * @static
 * @param source {}
 * @return {PIXI.Texture} A Texture
 */
Sprite.from = function (source)
{
    return new Sprite(Texture.from(source));
};

/**
 * Helper function that creates a sprite that will contain a texture from the TextureCache based on the frameId
 * The frame ids are created when a Texture packer file has been loaded
 *
 * @static
 * @param frameId {string} The frame Id of the texture in the cache
 * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the frameId
 */
Sprite.fromFrame = function (frameId)
{
    var texture = utils.TextureCache[frameId];

    if (!texture)
    {
        throw new Error('The frameId "' + frameId + '" does not exist in the texture cache');
    }

    return new Sprite(texture);
};

/**
 * Helper function that creates a sprite that will contain a texture based on an image url
 * If the image is not in the texture cache it will be loaded
 *
 * @static
 * @param imageId {string} The image url of the texture
 * @param [crossorigin=(auto)] {boolean} if you want to specify the cross-origin parameter
 * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} if you want to specify the scale mode, see {@link PIXI.SCALE_MODES} for possible values
 * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the image id
 */
Sprite.fromImage = function (imageId, crossorigin, scaleMode)
{
    return new Sprite(Texture.fromImage(imageId, crossorigin, scaleMode));
};
<commit_msg>sprite fix, again, compatible with v3<commit_after>var math = require('../math'),
    Texture = require('../textures/Texture'),
    Container = require('../display/Container'),
    utils = require('../utils'),
    CONST = require('../const'),
    tempPoint = new math.Point();

/**
 * The Sprite object is the base for all textured objects that are rendered to the screen
 *
 * A sprite can be created directly from an image like this:
 *
 * ```js
 * var sprite = new PIXI.Sprite.fromImage('assets/image.png');
 * ```
 *
 * @class
 * @extends PIXI.Container
 * @memberof PIXI
 * @param texture {PIXI.Texture} The texture for this sprite
 */
function Sprite(texture)
{
    Container.call(this);

    /**
     * The anchor sets the origin point of the texture.
     * The default is 0,0 this means the texture's origin is the top left
     * Setting the anchor to 0.5,0.5 means the texture's origin is centered
     * Setting the anchor to 1,1 would mean the texture's origin point will be the bottom right corner
     *
     * @member {PIXI.Point}
     */
    this.anchor = new math.Point();

    /**
     * The texture that the sprite is using
     *
     * @member {PIXI.Texture}
     * @private
     */
    this._texture = null;

    /**
     * The width of the sprite (this is initially set by the texture)
     *
     * @member {number}
     * @private
     */
    this._width = 0;

    /**
     * The height of the sprite (this is initially set by the texture)
     *
     * @member {number}
     * @private
     */
    this._height = 0;

    /**
     * The tint applied to the sprite. This is a hex value. A value of 0xFFFFFF will remove any tint effect.
     *
     * @member {number}
     * @default 0xFFFFFF
     */
    this.tint = 0xFFFFFF;

    /**
     * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.
     *
     * @member {number}
     * @default PIXI.BLEND_MODES.NORMAL
     * @see PIXI.BLEND_MODES
     */
    this.blendMode = CONST.BLEND_MODES.NORMAL;

    /**
     * The shader that will be used to render the sprite. Set to null to remove a current shader.
     *
     * @member {PIXI.AbstractFilter|PIXI.Shader}
     */
    this.shader = null;

    /**
     * An internal cached value of the tint.
     *
     * @member {number}
     * @default 0xFFFFFF
     */
    this.cachedTint = 0xFFFFFF;

    // call texture setter
    this.texture = texture || Texture.EMPTY;
    this.textureDirty = true;
    this.vertexData = new Float32Array(16);
}

// constructor
Sprite.prototype = Object.create(Container.prototype);
Sprite.prototype.constructor = Sprite;
module.exports = Sprite;

Object.defineProperties(Sprite.prototype, {
    /**
     * The width of the sprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.Sprite#
     */
    width: {
        get: function ()
        {
            return Math.abs(this.scale.x) * this.texture.orig.width;
        },
        set: function (value)
        {
            var sign = utils.sign(this.scale.x) || 1;
            this.scale.x = sign * value / this.texture.orig.width;
            this._width = value;
        }
    },

    /**
     * The height of the sprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.Sprite#
     */
    height: {
        get: function ()
        {
            return  Math.abs(this.scale.y) * this.texture.orig.height;
        },
        set: function (value)
        {
            var sign = utils.sign(this.scale.y) || 1;
            this.scale.y = sign * value / this.texture.orig.height;
            this._height = value;
        }
    },

    /**
     * The texture that the sprite is using
     *
     * @member {PIXI.Texture}
     * @memberof PIXI.Sprite#
     */
    texture: {
        get: function ()
        {
            return  this._texture;
        },
        set: function (value)
        {
            if (this._texture === value)
            {
                return;
            }

            this._texture = value;
            this.cachedTint = 0xFFFFFF;

            this.textureDirty = true;

            if (value)
            {
                // wait for the texture to load
                if (value.baseTexture.hasLoaded)
                {
                    this._onTextureUpdate();
                }
                else
                {
                    value.once('update', this._onTextureUpdate, this);
                }
            }
        }
    }
});

/**
 * When the texture is updated, this event will fire to update the scale and frame
 *
 * @private
 */
Sprite.prototype._onTextureUpdate = function ()
{
    this.textureDirty = true;

    // so if _width is 0 then width was not set..
    if (this._width)
    {
        this.scale.x = utils.sign(this.scale.x) * this._width / this.texture.orig.width;
    }

    if (this._height)
    {
        this.scale.y = utils.sign(this.scale.y) * this._height / this.texture.orig.height;
    }
};

/**
 * calculates worldTransform * vertices, store it in vertexData
 */
Sprite.prototype.calculateVertices = function ()
{
    var texture = this._texture,
        wt = this.transform.worldTransform,
        a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
        vertexData = this.vertexData,
        w0, w1, h0, h1,
        trim = texture.trim,
        orig = texture.orig;

    if (trim)
    {
        // if the sprite is trimmed and is not a tilingsprite then we need to add the extra space before transforming the sprite coords..
        w1 = trim.x - this.anchor.x * orig.width;
        w0 = w1 + trim.width;

        h1 = trim.y - this.anchor.y * orig.height;
        h0 = h1 + trim.height;

    }
    else
    {
        w0 = (orig.width ) * (1-this.anchor.x);
        w1 = (orig.width ) * -this.anchor.x;

        h0 = orig.height * (1-this.anchor.y);
        h1 = orig.height * -this.anchor.y;
    }

    // xy
    vertexData[0] = a * w1 + c * h1 + tx;
    vertexData[1] = d * h1 + b * w1 + ty;

    // xy
    vertexData[2] = a * w0 + c * h1 + tx;
    vertexData[3] = d * h1 + b * w0 + ty;

     // xy
    vertexData[4] = a * w0 + c * h0 + tx;
    vertexData[5] = d * h0 + b * w0 + ty;

    // xy
    vertexData[6] = a * w1 + c * h0 + tx;
    vertexData[7] = d * h0 + b * w1 + ty;
};

/**
 * we need this method to be compatible with pixiv3. v3 does calculate bounds of original texture are, not trimmed one
 */
Sprite.prototype.calculateBoundsVertices = function ()
{
    var texture = this._texture,
        trim = texture.trim,
        vertexData = this.vertexData,
        orig = texture.orig;

    if (!trim || trim.width == orig.width && trim.height == orig.height) {
        vertexData[8] = vertexData[0];
        vertexData[9] = vertexData[1];
        vertexData[10] = vertexData[2];
        vertexData[11] = vertexData[3];
        vertexData[12] = vertexData[4];
        vertexData[13] = vertexData[5];
        vertexData[14] = vertexData[6];
        vertexData[15] = vertexData[7];
        return;
    }

    var wt = this.transform.worldTransform,
        a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
        w0, w1, h0, h1;

    w0 = (orig.width ) * (1-this.anchor.x);
    w1 = (orig.width ) * -this.anchor.x;

    h0 = orig.height * (1-this.anchor.y);
    h1 = orig.height * -this.anchor.y;

    // xy
    vertexData[8] = a * w1 + c * h1 + tx;
    vertexData[9] = d * h1 + b * w1 + ty;

    // xy
    vertexData[10] = a * w0 + c * h1 + tx;
    vertexData[11] = d * h1 + b * w0 + ty;

    // xy
    vertexData[12] = a * w0 + c * h0 + tx;
    vertexData[13] = d * h0 + b * w0 + ty;

    // xy
    vertexData[14] = a * w1 + c * h0 + tx;
    vertexData[15] = d * h0 + b * w1 + ty;
};

/**
*
* Renders the object using the WebGL renderer
*
* @param renderer {PIXI.WebGLRenderer}
* @private
*/
Sprite.prototype._renderWebGL = function (renderer)
{
    if(this.transform.updated || this.textureDirty)
    {
        this.textureDirty = false;
        // set the vertex data
        this.calculateVertices();
    }

    renderer.setObjectRenderer(renderer.plugins.sprite);
    renderer.plugins.sprite.render(this);
};

/**
* Renders the object using the Canvas renderer
*
* @param renderer {PIXI.CanvasRenderer} The renderer
* @private
*/
Sprite.prototype._renderCanvas = function (renderer)
{
    renderer.plugins.sprite.render(this);
};

/**
 * Returns the bounds of the Sprite as a rectangle. The bounds calculation takes the worldTransform into account.
 *
 * @return {PIXI.Rectangle} the framing rectangle
 */
Sprite.prototype.getBounds = function ()
{
    //TODO lookinto caching..
    if(!this._currentBounds)
    {
       // if(this.vertexDirty)
        {
            this.vertexDirty = false;

            // set the vertex data
            this.calculateBoundsVertices();

        }

        var minX, maxX, minY, maxY,
            w0, w1, h0, h1,
            vertexData = this.vertexData;

        var x1 = vertexData[8];
        var y1 = vertexData[9];

        var x2 = vertexData[10];
        var y2 = vertexData[11];

        var x3 = vertexData[12];
        var y3 = vertexData[13];

        var x4 = vertexData[14];
        var y4 = vertexData[15];

        minX = x1;
        minX = x2 < minX ? x2 : minX;
        minX = x3 < minX ? x3 : minX;
        minX = x4 < minX ? x4 : minX;

        minY = y1;
        minY = y2 < minY ? y2 : minY;
        minY = y3 < minY ? y3 : minY;
        minY = y4 < minY ? y4 : minY;

        maxX = x1;
        maxX = x2 > maxX ? x2 : maxX;
        maxX = x3 > maxX ? x3 : maxX;
        maxX = x4 > maxX ? x4 : maxX;

        maxY = y1;
        maxY = y2 > maxY ? y2 : maxY;
        maxY = y3 > maxY ? y3 : maxY;
        maxY = y4 > maxY ? y4 : maxY;

        // check for children
        if(this.children.length)
        {
            var childBounds = this.containerGetBounds();

            w0 = childBounds.x;
            w1 = childBounds.x + childBounds.width;
            h0 = childBounds.y;
            h1 = childBounds.y + childBounds.height;

            minX = (minX < w0) ? minX : w0;
            minY = (minY < h0) ? minY : h0;

            maxX = (maxX > w1) ? maxX : w1;
            maxY = (maxY > h1) ? maxY : h1;
        }

        var bounds = this._bounds;

        bounds.x = minX;
        bounds.width = maxX - minX;

        bounds.y = minY;
        bounds.height = maxY - minY;

        // store a reference so that if this function gets called again in the render cycle we do not have to recalculate
        this._currentBounds = bounds;
    }

    return this._currentBounds;
};

/**
 * Gets the local bounds of the sprite object.
 *
 */
Sprite.prototype.getLocalBounds = function ()
{
    this._bounds.x = -this._texture.orig.width * this.anchor.x;
    this._bounds.y = -this._texture.orig.height * this.anchor.y;
    this._bounds.width = this._texture.orig.width;
    this._bounds.height = this._texture.orig.height;
    return this._bounds;
};

/**
* Tests if a point is inside this sprite
*
* @param point {PIXI.Point} the point to test
* @return {boolean} the result of the test
*/
Sprite.prototype.containsPoint = function( point )
{
    this.worldTransform.applyInverse(point,  tempPoint);

    var width = this._texture.orig.width;
    var height = this._texture.orig.height;
    var x1 = -width * this.anchor.x;
    var y1;

    if ( tempPoint.x > x1 && tempPoint.x < x1 + width )
    {
        y1 = -height * this.anchor.y;

        if ( tempPoint.y > y1 && tempPoint.y < y1 + height )
        {
            return true;
        }
    }

    return false;
};

/**
 * Destroys this sprite and optionally its texture and children
 *
 * @param [options] {object|boolean} Options parameter. A boolean will act as if all options have been set to that value
 * @param [options.children=false] {boolean} if set to true, all the children will have their destroy
 *      method called as well. 'options' will be passed on to those calls.
 * @param [options.texture=false] {boolean} Should it destroy the current texture of the sprite as well
 * @param [options.baseTexture=false] {boolean} Should it destroy the base texture of the sprite as well
 */
Sprite.prototype.destroy = function (options)
{
    Container.prototype.destroy.call(this, options);

    this.anchor = null;

    var destroyTexture = typeof options === 'boolean' ? options : options && options.texture;
    if (destroyTexture)
    {
        var destroyBaseTexture = typeof options === 'boolean' ? options : options && options.baseTexture;
        this._texture.destroy(!!destroyBaseTexture);
    }

    this._texture = null;
    this.shader = null;
};

// some helper functions..

/**
 * Helper function that creates a new sprite based on the source you provide.
 * The soucre can be - frame id, image url, video url, canvae element, video element, base texture
 *
 * @static
 * @param source {}
 * @return {PIXI.Texture} A Texture
 */
Sprite.from = function (source)
{
    return new Sprite(Texture.from(source));
};

/**
 * Helper function that creates a sprite that will contain a texture from the TextureCache based on the frameId
 * The frame ids are created when a Texture packer file has been loaded
 *
 * @static
 * @param frameId {string} The frame Id of the texture in the cache
 * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the frameId
 */
Sprite.fromFrame = function (frameId)
{
    var texture = utils.TextureCache[frameId];

    if (!texture)
    {
        throw new Error('The frameId "' + frameId + '" does not exist in the texture cache');
    }

    return new Sprite(texture);
};

/**
 * Helper function that creates a sprite that will contain a texture based on an image url
 * If the image is not in the texture cache it will be loaded
 *
 * @static
 * @param imageId {string} The image url of the texture
 * @param [crossorigin=(auto)] {boolean} if you want to specify the cross-origin parameter
 * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} if you want to specify the scale mode, see {@link PIXI.SCALE_MODES} for possible values
 * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the image id
 */
Sprite.fromImage = function (imageId, crossorigin, scaleMode)
{
    return new Sprite(Texture.fromImage(imageId, crossorigin, scaleMode));
};
<|endoftext|>


<commit_before>// goods
(function () {
'use strict';
var module = angular.module('fim.base');
module.run(function (plugins, modals, $q, $rootScope, nxt) {

  var plugin = plugins.get('transaction');

  // Add Goods

  plugin.add({
    label: 'Devious Item',
    id: 'dgsListing',
    exclude: true,
    execute: function (senderRS, args) {
      args = args||{};
      return plugin.create(angular.extend(args, {
        title: 'Devious Item',
        message: 'Create a Marketplace item with no length restricted tags',
        senderRS: senderRS,
        requestType: 'dgsListing',
        canHaveRecipient: false,
        createArguments: function (items) {
          return {
            name: items.name,
            description: JSON.stringify({ description: items.description, image: items.image || '', callback: items.callback || '' }),
            tags: items.tags,
            quantity: String(items.quantity),
            priceNQT: nxt.util.convertToNQT(items.priceNXT)
          }
        },
        fields: [{
          label: 'Name',
          name: 'name',
          type: 'text',
          value: args.name||''
        }, {
          label: 'Description',
          name: 'description',
          type: 'textarea',
          value: args.description||''
        }, {
          label: 'ImageURL',
          name: 'image',
          type: 'image',
          value: args.image||''
        }, {
          label: 'Callback',
          name: 'callback',
          type: 'image',
          value: args.callback||''
        }, {
          label: 'Tags',
          name: 'tags',
          type: 'textarea',
          value: args.tags||''
        }, {
          label: 'Price',
          name: 'priceNXT',
          type: 'money',
          value: args.priceNXT||''
        }, {
          label: 'Quantity',
          name: 'quantity',
          type: 'text',
          value: args.quantity||''
        }]
      }));
    }
  });

  // Delete Goods

  plugin.add({
    label: 'Devious Item',
    id: 'dgsDelisting',
    exclude: true,
    execute: function (senderRS, args) {
      args = args||{};
      return plugin.create(angular.extend(args, {
        title: 'Devious Item',
        message: 'Delete a Marketplace item with no length restricted tags',
        // senderRS: senderRS,
        requestType: 'dgsDelisting',
        // canHaveRecipient: false,
        createArguments: function (items) {
          return {
            goods: items.goods
          }
        }
      }));
    }
  });

  // Purchase Goods

  plugin.add({
    label: 'Devious Item',
    id: 'dgsPurchase',
    exclude: true,
    execute: function (senderRS, args) {
      console.log(args);
      args = args||{};
      return plugin.create(angular.extend(args, {
        title: 'Devious Item',
        message: 'Pay to complete Marketplace purchases',
        senderRS: senderRS,
        requestType: 'dgsPurchase',
        canHaveRecipient: false,
        createArguments: function (items) {
          return {
            goods: items.goods,
            priceNQT: items.priceNQT,
            quantity: String(items.quantity),
            deliveryDeadlineTimestamp: items.deliveryDeadlineTimestamp
            // priceNQT: nxt.util.convertToNQT(items.priceNXT)
          }
        },
        fields: [{
          label: 'Name',
          name: 'name',
          type: 'text',
          value: args.name||''
        },
        {
          label: 'Price',
          name: 'price',
          type: 'text',
          value: args.priceNQT||''
        },
        {
          label: 'Quantity',
          name: 'quantity',
          type: 'text',
          value: args.quantity||''
        }]
      }));
    }
  });
});
})();<commit_msg>devious item to purchase item issue fixed<commit_after>// goods
(function () {
'use strict';
var module = angular.module('fim.base');
module.run(function (plugins, modals, $q, $rootScope, nxt) {

  var plugin = plugins.get('transaction');

  // Add Goods

  plugin.add({
    label: 'Devious Item',
    id: 'dgsListing',
    exclude: true,
    execute: function (senderRS, args) {
      args = args||{};
      return plugin.create(angular.extend(args, {
        title: 'Devious Item',
        message: 'Create a Marketplace item with no length restricted tags',
        senderRS: senderRS,
        requestType: 'dgsListing',
        canHaveRecipient: false,
        createArguments: function (items) {
          return {
            name: items.name,
            description: JSON.stringify({ description: items.description, image: items.image || '', callback: items.callback || '' }),
            tags: items.tags,
            quantity: String(items.quantity),
            priceNQT: nxt.util.convertToNQT(items.priceNXT)
          }
        },
        fields: [{
          label: 'Name',
          name: 'name',
          type: 'text',
          value: args.name||''
        }, {
          label: 'Description',
          name: 'description',
          type: 'textarea',
          value: args.description||''
        }, {
          label: 'ImageURL',
          name: 'image',
          type: 'image',
          value: args.image||''
        }, {
          label: 'Callback',
          name: 'callback',
          type: 'image',
          value: args.callback||''
        }, {
          label: 'Tags',
          name: 'tags',
          type: 'textarea',
          value: args.tags||''
        }, {
          label: 'Price',
          name: 'priceNXT',
          type: 'money',
          value: args.priceNXT||''
        }, {
          label: 'Quantity',
          name: 'quantity',
          type: 'text',
          value: args.quantity||''
        }]
      }));
    }
  });

  // Delete Goods

  plugin.add({
    label: 'Devious Item',
    id: 'dgsDelisting',
    exclude: true,
    execute: function (senderRS, args) {
      args = args||{};
      return plugin.create(angular.extend(args, {
        title: 'Devious Item',
        message: 'Delete a Marketplace item with no length restricted tags',
        // senderRS: senderRS,
        requestType: 'dgsDelisting',
        // canHaveRecipient: false,
        createArguments: function (items) {
          return {
            goods: items.goods
          }
        }
      }));
    }
  });

  // Purchase Goods

  plugin.add({
    label: 'Purchase Item',
    id: 'dgsPurchase',
    exclude: true,
    execute: function (senderRS, args) {
      console.log(args);
      args = args||{};
      return plugin.create(angular.extend(args, {
        title: 'Purchase Item',
        message: 'Pay to complete Marketplace purchases',
        senderRS: senderRS,
        requestType: 'dgsPurchase',
        canHaveRecipient: false,
        createArguments: function (items) {
          return {
            goods: items.goods,
            priceNQT: items.priceNQT,
            quantity: String(items.quantity),
            deliveryDeadlineTimestamp: items.deliveryDeadlineTimestamp
            // priceNQT: nxt.util.convertToNQT(items.priceNXT)
          }
        },
        fields: [{
          label: 'Name',
          name: 'name',
          type: 'text',
          value: args.name||''
        },
        {
          label: 'Price',
          name: 'price',
          type: 'text',
          value: args.priceNQT||''
        },
        {
          label: 'Quantity',
          name: 'quantity',
          type: 'text',
          value: args.quantity||''
        }]
      }));
    }
  });
});
})();<|endoftext|>


<commit_before>'use strict'
//var Client = require('muxhttp/client')
var pull = require('pull-stream')
var h = require('hyperscript')
var MuxRpc = require('muxrpc')
var WS = require('pull-ws-server')
var JSONDL = require('pull-serializer')
var o = require('observable')

var ListGrad = require('./views/list-grad')
var Grad = require('./views/grad')
var Edit = require('./views/edit-grad')
var Admin = require('./views/admin')

//switch between states - state + value
//list, view (feed), edit(feed)

var mode = o() //list, view, edit
var current = o() //current grad

var client
var resource = o()
// --- client side dataset ---
// TODO: move into module ...

var merge = require('deep-merge')
//client side data.

var all = [], keys = {}
function add (data) {
  if(!keys[data.key]) {
    keys[data.key] = data
    all.push(data)
  }
  else
    keys[data.key].value = merge(keys[data.key].value, data.value)
}

var backgrounds = [
  {  image: '/assets/bg_01.png'
  },
  {  image: '/assets/bg_02.png'
  },
  {  image: '/assets/bg_03.png'
  },
  {  image: '/assets/bg_04.png'
  },
  {  image: '/assets/bg_05.png'
  },
]

// event handler function
function handler(e) {
  var key = window.event ? e.keyCode : e.which;
  if (key == 27) {
    mode('list')
  }
  //console.log(key, e.shiftKey, e.altKey, e.ctrlKey);
}

// attach handler to the keydown event of the document
if (document.attachEvent) document.attachEvent('onkeydown', handler);
else document.addEventListener('keydown', handler);

// -------

var title = o()
var content = o()

function view () {
  return h('div.view', link(h('img.back', {src:'/assets/back-arrow.svg', alt:'back to home page'}), function () { mode ('list') }), Grad(current().value))
}

function edit (data) {
  data = data || {}
  return Edit(data.value, function (err, value) {
    console.log('edited', err, value)
    if(!value) mode('list')
    var _value = {key: data.key || value.email, value: value}
    client.put(_value, function (err) {
      console.log(err, _value, data)
      if(err) { current(data); alert(err.message) }
      else current(_value)
      mode('view')
    })
  })
}

function link (name, onclick) {
  return h('a', name, {href: '#', onclick: onclick})
}

function editLink (data) {
  return link( data ? 'edit' : h('div.add'), function () {
    current(data)
    mode('edit')
  })
}

function canAccess(obv, set, value) {
  return o.transform(obv, function (val) {
    return ~set.indexOf(val) ? value : null
  })
}

function hasTicketStub(obv, set, value) {
  return o.transform(obv, function (val){
    return val ? value : null
  })
}

function list () {
  return h('ol',
    Object.keys(keys).map(function (key) {
      var value = keys[key].value
      return h('li.grad--card',
        h('div.links',
          canAccess(resource, [key, 'admin'],
            link('edit', function () { current(keys[key]); mode ('edit') })
          )
        ),
        link(ListGrad(value), function () { current(keys[key]); mode ('view') }))
    })
  )
}

function getRandomInt (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
}

mode('list')

mode(function (m) {
  if('view' == m) {
    title(current().value.name)
    content(view(current()))
  }
  else if('edit' == m) {
    title(current() ? 'edit:'+current().value.name: 'enter new grad')
    content(edit(current()))
  }
  else if('admin' == m) {
    title('admin')
    content(Admin(client))
  }
  else {
    title('eda-grads')
    content(list())
  }
})

require('./reconnect')(function (cb) {

// if (document.location.hostname == "localhost"){
//    var ws = WS.connect('ws://localhost:8000/')
//  }
//  else {
//    var ws = WS.connect('ws://124.150.139.107/')
//  }
//

  var ws = WS.connect('/')

  client = window.CLIENT = MuxRpc(require('./manifest.json'), null, JSONDL)()

  pull(ws, client.createStream(), pull.through(null, cb), ws)

  client.whoami(function (err, _resource) {
    resource(window.RESOURCE = _resource)
  })

  pull(
    client.read(),
    pull.drain(add, function (err) {
      content(list())
      if(err) console.log(err)
    })
  )
})

document.body.appendChild(
  h('div.page--wrapper',
    h('header',
      h('div.logo', link( h('img', {src:'/assets/logo.png', alt:'enspiral dev academy'}),
          function () { mode ('list') })
      ),
      h('nav',
        hasTicketStub(resource, [current], editLink()),
        canAccess(resource, ['admin'],
          link( h('img', {src:'/assets/admin-logo.png', alt:'admin portal'}), function () { mode ('admin') })
        )
      )),
    h('section.main',
      h('div.content', content))
    )
)

document.addEventListener("DOMContentLoaded", function(event) {
  var bgNumber = getRandomInt(0, backgrounds.length-1)
  document.body.style.background = 'url(' + backgrounds[bgNumber].image + ')'
  //bug! make it so that a click on the bg will go back to main view
  document.querySelector('.page--wrapper').addEventListener('click', mode('list'), false)
})

<commit_msg>set up deep-merge properly!<commit_after>'use strict'
//var Client = require('muxhttp/client')
var pull = require('pull-stream')
var h = require('hyperscript')
var MuxRpc = require('muxrpc')
var WS = require('pull-ws-server')
var JSONDL = require('pull-serializer')
var o = require('observable')

var ListGrad = require('./views/list-grad')
var Grad = require('./views/grad')
var Edit = require('./views/edit-grad')
var Admin = require('./views/admin')

//switch between states - state + value
//list, view (feed), edit(feed)

var mode = o() //list, view, edit
var current = o() //current grad

var client
var resource = o()
// --- client side dataset ---
// TODO: move into module ...

//set up deep-merge properly!
var merge = require('deep-merge')(function (a, b, k) {
  return b != null ? b : a
})
//client side data.

var all = [], keys = {}
function add (data) {
  if(!keys[data.key]) {
    keys[data.key] = data
    all.push(data)
  }
  else {
    keys[data.key].value = merge(keys[data.key].value, data.value)
  }
}

var backgrounds = [
  {  image: '/assets/bg_01.png'
  },
  {  image: '/assets/bg_02.png'
  },
  {  image: '/assets/bg_03.png'
  },
  {  image: '/assets/bg_04.png'
  },
  {  image: '/assets/bg_05.png'
  },
]

// event handler function
function handler(e) {
  var key = window.event ? e.keyCode : e.which;
  if (key == 27) {
    mode('list')
  }
  //console.log(key, e.shiftKey, e.altKey, e.ctrlKey);
}

// attach handler to the keydown event of the document
if (document.attachEvent) document.attachEvent('onkeydown', handler);
else document.addEventListener('keydown', handler);

// -------

var title = o()
var content = o()

function view () {
  return h('div.view', link(h('img.back', {src:'/assets/back-arrow.svg', alt:'back to home page'}), function () { mode ('list') }), Grad(current().value))
}

function edit (data) {
  data = data || {}
  return Edit(data.value, function (err, value) {
    console.log('edited', err, value)
    if(!value) mode('list')
    var _value = {key: data.key || value.email, value: value}
    client.put(_value, function (err) {
      console.log(err, _value, data)
      if(err) { current(data); alert(err.message) }
      else current(_value)
      mode('view')
    })
  })
}

function link (name, onclick) {
  return h('a', name, {href: '#', onclick: onclick})
}

function editLink (data) {
  return link( data ? 'edit' : h('div.add'), function () {
    current(data)
    mode('edit')
  })
}

function canAccess(obv, set, value) {
  return o.transform(obv, function (val) {
    return ~set.indexOf(val) ? value : null
  })
}

function hasTicketStub(obv, set, value) {
  return o.transform(obv, function (val){
    return val ? value : null
  })
}

function list () {
  return h('ol',
    Object.keys(keys).map(function (key) {
      var value = keys[key].value
      return h('li.grad--card',
        h('div.links',
          canAccess(resource, [key, 'admin'],
            link('edit', function () { current(keys[key]); mode ('edit') })
          )
        ),
        link(ListGrad(value), function () { current(keys[key]); mode ('view') }))
    })
  )
}

function getRandomInt (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
}

mode('list')

mode(function (m) {
  if('view' == m) {
    title(current().value.name)
    content(view(current()))
  }
  else if('edit' == m) {
    title(current() ? 'edit:'+current().value.name: 'enter new grad')
    content(edit(current()))
  }
  else if('admin' == m) {
    title('admin')
    content(Admin(client))
  }
  else {
    title('eda-grads')
    content(list())
  }
})

require('./reconnect')(function (cb) {

// if (document.location.hostname == "localhost"){
//    var ws = WS.connect('ws://localhost:8000/')
//  }
//  else {
//    var ws = WS.connect('ws://124.150.139.107/')
//  }
//

  var ws = WS.connect('/')

  client = window.CLIENT = MuxRpc(require('./manifest.json'), null, JSONDL)()

  pull(ws, client.createStream(), pull.through(null, cb), ws)

  client.whoami(function (err, _resource) {
    resource(window.RESOURCE = _resource)
  })

  pull(
    client.read(),
    pull.drain(add, function (err) {
      content(list())
      if(err) console.log(err)
    })
  )
})

document.body.appendChild(
  h('div.page--wrapper',
    h('header',
      h('div.logo', link( h('img', {src:'/assets/logo.png', alt:'enspiral dev academy'}),
          function () { mode ('list') })
      ),
      h('nav',
        hasTicketStub(resource, [current], editLink()),
        canAccess(resource, ['admin'],
          link( h('img', {src:'/assets/admin-logo.png', alt:'admin portal'}), function () { mode ('admin') })
        )
      )),
    h('section.main',
      h('div.content', content))
    )
)

document.addEventListener("DOMContentLoaded", function(event) {
  var bgNumber = getRandomInt(0, backgrounds.length-1)
  document.body.style.background = 'url(' + backgrounds[bgNumber].image + ')'
  //bug! make it so that a click on the bg will go back to main view
  document.querySelector('.page--wrapper').addEventListener('click', mode('list'), false)
})

<|endoftext|>