<commit_before>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2013, Olivier BIOT
 * http://www.melonjs.org
 *
 */

(function($) {

	/**
	 * GUI Object

	 * A very basic object to manage GUI elements

	 * The object simply register on the "mousedown"

	 * or "touchstart" event and call the onClicked function"
	 * @class
	 * @extends me.SpriteObject
	 * @memberOf me
	 * @constructor
	 * @param {Number} x the x coordinate of the GUI Object
	 * @param {Number} y the y coordinate of the GUI Object
	 * @param {me.ObjectSettings} settings Object settings
	 * @example
	 *
	 * // create a basic GUI Object
	 * var myButton = me.GUI_Object.extend(
	 * {
	 *    init:function(x, y)
	 *    {
	 *       settings = {}
	 *       settings.image = "button";
	 *       settings.spritewidth = 100;
	 *       settings.spriteheight = 50;
	 *       // parent constructor
	 *       this.parent(x, y, settings);
	 *    },
	 *
	 *    // output something in the console
	 *    // when the object is clicked
	 *    onClick:function()
	 *    {
	 *       console.log("clicked!");
	 *       // don't propagate the event
	 *       return true;
	 *    }
	 * });
	 *
	 * // add the object at pos (10,10), z index 4
	 * me.game.add((new myButton(10,10)),4);
	 *
	 */
	me.GUI_Object = me.SpriteObject.extend({
	/** @scope me.GUI_Object.prototype */

		/**
		 * object can be clicked or not
		 * @public
		 * @type boolean
		 * @name me.GUI_Object#isClickable
		 */
		isClickable : true,

		// object has been updated (clicked,etc..)
		updated : false,

		/**
		 * @ignore
		 */
		 init : function(x, y, settings) {
			this.parent(x, y,
						((typeof settings.image == "string") ? me.loader.getImage(settings.image) : settings.image),
						settings.spritewidth,
						settings.spriteheight);

			// GUI items use screen coordinates
			this.floating = true;

			// register on mouse event
			me.input.registerPointerEvent('mousedown', this, this.clicked.bind(this));

		},

		/**
		 * return true if the object has been clicked
		 * @ignore
		 */
		update : function() {
			if (this.updated) {
				// clear the flag
				this.updated = false;
				return true;
			}
			return false;
		},

		/**
		 * function callback for the mousedown event
		 * @ignore
		 */
		clicked : function() {
			if (this.isClickable) {
				this.updated = true;
				return this.onClick();
			}
		},

		/**
		 * function called when the object is clicked

		 * to be extended

		 * return true if we need to stop propagating the event
		 * @name onClick
		 * @memberOf me.GUI_Object
		 * @public
		 * @function
		 */
		onClick : function() {

			return true;
		},

		/**
		 * OnDestroy notification function

		 * Called by engine before deleting the object

		 * be sure to call the parent function if overwritten
		 * @name onDestroyEvent
		 * @memberOf me.GUI_Object
		 * @public
		 * @function
		 */
		onDestroyEvent : function() {
			me.input.releasePointerEvent('mousedown', this);
		}

	});

	/*---------------------------------------------------------*/
	// END END END
	/*---------------------------------------------------------*/
})(window);
<commit_msg>fix GUI_Object docs<commit_after>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2013, Olivier BIOT
 * http://www.melonjs.org
 *
 */

(function($) {

	/**
	 * GUI Object

	 * A very basic object to manage GUI elements

	 * The object simply register on the "mousedown"

	 * or "touchstart" event and call the onClick function"
	 * @class
	 * @extends me.SpriteObject
	 * @memberOf me
	 * @constructor
	 * @param {Number} x the x coordinate of the GUI Object
	 * @param {Number} y the y coordinate of the GUI Object
	 * @param {me.ObjectSettings} settings Object settings
	 * @example
	 *
	 * // create a basic GUI Object
	 * var myButton = me.GUI_Object.extend(
	 * {
	 *    init:function(x, y)
	 *    {
	 *       settings = {}
	 *       settings.image = "button";
	 *       settings.spritewidth = 100;
	 *       settings.spriteheight = 50;
	 *       // parent constructor
	 *       this.parent(x, y, settings);
	 *    },
	 *
	 *    // output something in the console
	 *    // when the object is clicked
	 *    onClick:function()
	 *    {
	 *       console.log("clicked!");
	 *       // don't propagate the event
	 *       return false;
	 *    }
	 * });
	 *
	 * // add the object at pos (10,10), z index 4
	 * me.game.add((new myButton(10,10)),4);
	 *
	 */
	me.GUI_Object = me.SpriteObject.extend({
	/** @scope me.GUI_Object.prototype */

		/**
		 * object can be clicked or not
		 * @public
		 * @type boolean
		 * @name me.GUI_Object#isClickable
		 */
		isClickable : true,

		// object has been updated (clicked,etc..)
		updated : false,

		/**
		 * @ignore
		 */
		 init : function(x, y, settings) {
			this.parent(x, y,
						((typeof settings.image == "string") ? me.loader.getImage(settings.image) : settings.image),
						settings.spritewidth,
						settings.spriteheight);

			// GUI items use screen coordinates
			this.floating = true;

			// register on mouse event
			me.input.registerPointerEvent('mousedown', this, this.clicked.bind(this));

		},

		/**
		 * return true if the object has been clicked
		 * @ignore
		 */
		update : function() {
			if (this.updated) {
				// clear the flag
				this.updated = false;
				return true;
			}
			return false;
		},

		/**
		 * function callback for the mousedown event
		 * @ignore
		 */
		clicked : function() {
			if (this.isClickable) {
				this.updated = true;
				return this.onClick();
			}
		},

		/**
		 * function called when the object is clicked

		 * to be extended

		 * return false if we need to stop propagating the event
		 * @name onClick
		 * @memberOf me.GUI_Object
		 * @public
		 * @function
		 */
		onClick : function() {

			return true;
		},

		/**
		 * OnDestroy notification function

		 * Called by engine before deleting the object

		 * be sure to call the parent function if overwritten
		 * @name onDestroyEvent
		 * @memberOf me.GUI_Object
		 * @public
		 * @function
		 */
		onDestroyEvent : function() {
			me.input.releasePointerEvent('mousedown', this);
		}

	});

	/*---------------------------------------------------------*/
	// END END END
	/*---------------------------------------------------------*/
})(window);
<|endoftext|>


<commit_before>const constants = require('./js/constants');

export default
{
    "home": {
        "image": "software.jpg",
        "title": "Welcome To UBC Subbots",
        "blurb": "UBC Subbots is an engineering student design team dedicated to \
            making an autonomous underwater vehicle (AUV) for the RoboSub competition \
            in San Diego, California each year. This competition challenges us to make \
            a robot that can navigate and interact with underwater obstacles without any\
            human intervention whatsoever. The team was founded in 2017 and is made up of \
            engineering and computer science students from multiple disciplines who have full\
            control over the design, manufacturing and testing of the robot. Since becoming\
            a team, we have learned a lot about designing for the underwater environment and \
            are continuously improving upon our existing designs. ",
        "pitch":{
            "image": "mechanical.jpg",
            "header": "Why Subbots?",
            "body": " Subbots provides the chance for students to work on unique design\
                problems that can’t be found anywhere else at UBC. The team originated from \
                two existing designs teams: UBC SUBC who focuses on the design of human powered\
                submarines, and UBC Snowbots who designs autonomous land robots for various \
                applications. Combining these two together brings a variety of challenges such \
                as autonomous underwater navigation, hydrodynamics and buoyancy, electronics \
                waterproofing, actuation of mechanical systems and many more. Since Subbots is a \
                relatively new design team, there is plenty of opportunity to improve upon existing\
                designs and be a part of building the team. "
        },
        "goal":{
            "image": "electrical.jpg",
            "header": "Our Goal",
            "body": "As a UBC engineering design team we look to create an interesting and \
                engaging environment for all of our members. The team believes our project is a\
                way for students to take what they have learned in the classroom and apply it to\
                real world problems. We do our best to inspire interest in subsea and robotic\
                design while maintaining a fun atmosphere that promotes learning and team bonding. \
                Each year we hope to grow as a team by recruiting motivated and hard working students \
                who share a passion for our project. \n\n On the technical side, our teams goal is to\
                build a robot that is capable of competing in the RoboSub competition each year. To \
                do this our members must learn how to work within a team and multidisciplinary \
                environment to tackle unique design challenges. The teams goal is to facilitate \
                learning in all aspects of AUV design and encourage good engineering practices that \
                can be passed onto future generations of team members. "
        } ,
        "projects":{
            "header": "The Robots",
            "body": "Since becoming a team in 2017, Subbots has had the chance to work on two robots.\
                Our first robot for the 2017-2018 year was a huge learning curve for the team, but it \
                successfully competed at RoboSub which taught the team a lot about what goes into making \
                an AUV. We are currently on a two year design cycle for our second robot but we are \
                building off of our original design and on track to compete in the 2020 RoboSub competition. \
                More information about the robots can be found below!",
            "carousels": {
                 "first": {
                    "images": ["first_1.jpg", "first_2.jpg", "first_3.jpg", "first_4.jpg"],
                    "caption": "2017-2018"
                },
                "second": {
                     "images": ["second_1.jpg", "second_2.jpg", "second_3.jpg", "second_4.jpg", "second_5.jpg", "second_6.jpg"],
                     "caption": "2018-2019"
                }
            }
        }
    },
    "teams": {
        "image": "electrical.jpg",
        "title": "See What Our Members Do",
        "blurb": "  Whether you’re interested in software, electrical, or mechanical\
            design, Subbots offers many unique design challenges that forces our members \
            to come up with creative solutions for building autonomous underwater robots",
        "software": {
            "blurb":" Create and refine subaquatic artificial intelligence",
            "body": " (Software Body) The Software will run on the embedded computer that \
                the robot carries in its chassis. It defines every movement and decision that\
                the robot makes. Without the software, the robot is a potato.",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Machine Learning", "Computer Vision", "Linux Development"],
                    "learn": ["ROS", "Python", "C++"]
                },
                "descriptions": {
                    "do": ["Use libraries such as Tensorflow for object detection", "Process raw camera signals into meaningful information", "Develop in the open-source wonder that is Linux"],
                    "learn": ["Work on a widely used platform that combines modularity and efficiency", "Learn one of the most widely used languages in the world today", "Wow your friends with your new C++ skills"]
                }
            }
        },
        "electrical": {
            "blurb": "Design the interface between the computer and the sea",
            "body": " The electrical team develops the electrical systems that \
                allow the robot to read and respond to the world. The team designs \
                circuits to control thrusters, process hydrophone signal, read sensor\
                information, and protect valuable electrical components from unexpected\
                power surges. Robust and reliable electrical systems are critical for \
                allowing a robot to react well to a dynamic environment.",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Signal Processing", "Circuit Design", "Comm Systems"],
                    "learn": ["Verification", "Design", "Fabrication"]
                },
                "descriptions": {
                    "do": [" Transformation and interpretation of sensor data", "Robust and accurate electronic hardware", "Facilitating communication between different systems"],
                    "learn": ["Ensuring design and implementation meet specifications", "How to make a system of electronic components safe and robust", "Implementing ideas into the real world"]
                }
            }
        },
        "mechanical": {
            "blurb":"Push the physical limits of underwater mechanics",
            "body": "The mechanical team is responsible for making the body of the robot\
                that the electrical and software systems control. We handle buoyancy and static \
                stability, hydrodynamics, frame and enclosure design, actuation, electronics \
                integration, waterproofing and the overall esthetic of the robot. Designing mechanical \
                systems for underwater applications brings many design challenges and is critical in \
                allowing robots to exist underwater. ",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Structure", "Accuation", "Hydrodynamics"],
                    "learn": ["Design", "Fabrication", "Testing"]
                },
                "descriptions": {
                    "do": ["Robot body and electronics integration", "Interaction with the underwater environment ", "Physical stability and control through the water"],
                    "learn": ["How to design parts for a multidisciplinary project ", "Hands on skills needed to make designs into reality", "How designs perform in practical application"]
                }
            }
        },
    },

    "join": {
        "image": "software.jpg",
        "title": "Become Part Of The Team",
        "blurb": " We are always looking for new members to fill the many challenges\
            that come with designing underwater robots. Whether you’re new to engineering \
            or have previous design experience we encourage everyone who is interested in \
            the project to apply. Our team is built around mentoring new students so that \
            they can eventually take over as team leaders, so students of all skill levels \
            are welcome. Recruitment is primarily done at the start of the school year in \
            September but we continuously recruit throughout the year to fill roles as needed.\
            Our recruitment process consists of an application form that is reviewed by our \
            senior members and a potential interview if we feel you’d be a good fit for the \
            team. If you have a passion for subsea and robotic design feel free to fill out \
            the application below! ",
    },

    "sponsors": {
        "image": "electrical.jpg",
        "title": "See Who Makes Us Possible",
        "blurb": " To make our designs a reality Subbots relies on the support\
            of our many sponsors. Through in-kind and monetary contributions\
            our members are able to develop the skills necessary to become\
            engineering professionals. They also gain experience working\
            with our sponsor’s wonderful products, allowing them to more\
            effectively design with similar components in the future. We are\
             always open to new partners, and if you would like to sponsor our\
            team please reach out to us for our sponsorship package.",
        "sponsor_list": [
            {
                "image": "ubc_walter_gage.png",
                "link": "http://waltergagebook.engineering.ubc.ca/walter-gage-memorial-bursary-in-engineering/"
            },
            {
                "image": "subc.png",
                "link": "https://subc.ca/"
            },
            {
                "image": "ubc-applied-sciences-footer-logo.png",
                "link": "https://apsc.ubc.ca/"
            },
            {
                "image": "4imprint.png",
                "link": "https://www.4imprint.ca/"
            },
            {
                "image": "ECE.jpg",
                "link": "https://www.ece.ubc.ca/"
            },
            {
                "image": "IEEE_logo.png",
                "link": "http://www.ubcieee.org/"
            },
            {
                "image": "MATLAB-Logo.png",
                "link": "https://www.mathworks.com/products/matlab.html"
            },
            {
                "image": "mech.png",
                "link": "https://mech.ubc.ca/"
            },
            {
                "image": "phidgets_logo.png",
                "link": "https://www.phidgets.com/?"
            },
            {
                "image": "Shell-logo.png",
                "link": "https://www.shell.ca/"
            },
            {
                "image": "SNAME.png",
                "link": "https://www.sname.org/home"
            },
            {
                "image": "snowbots.png",
                "link": "http://snowbots.ca/"
            },
            {
                "image": "solidworks-logo.png",
                "link": "https://www.solidworks.com/"
            },
            {
                "image": "spaenaur_logo.jpg",
                "link": "https://spaenaur.com/"
            },
            {
                "image": "ubc_forestry.png",
                "link": "https://forestry.ubc.ca/"
            },
            {
                "image": "venom_logo.png",
                "link": "https://www.venompower.com/"
            },
            {
                "image": "vp.jpg",
                "link": "https://apsc.ubc.ca/"
            },
        ]
    },
    "emails": {
        "Subbots": "info.subbots@gmail.com",
        "Electrical": "info.subbots@gmail.com",
        "Mechanical": "logan.fillo@gmail.com",
        "Software": ""
    }
}<commit_msg>fixed shell logo<commit_after>const constants = require('./js/constants');

export default
{
    "home": {
        "image": "software.jpg",
        "title": "Welcome To UBC Subbots",
        "blurb": "UBC Subbots is an engineering student design team dedicated to \
            making an autonomous underwater vehicle (AUV) for the RoboSub competition \
            in San Diego, California each year. This competition challenges us to make \
            a robot that can navigate and interact with underwater obstacles without any\
            human intervention whatsoever. The team was founded in 2017 and is made up of \
            engineering and computer science students from multiple disciplines who have full\
            control over the design, manufacturing and testing of the robot. Since becoming\
            a team, we have learned a lot about designing for the underwater environment and \
            are continuously improving upon our existing designs. ",
        "pitch":{
            "image": "mechanical.jpg",
            "header": "Why Subbots?",
            "body": " Subbots provides the chance for students to work on unique design\
                problems that can’t be found anywhere else at UBC. The team originated from \
                two existing designs teams: UBC SUBC who focuses on the design of human powered\
                submarines, and UBC Snowbots who designs autonomous land robots for various \
                applications. Combining these two together brings a variety of challenges such \
                as autonomous underwater navigation, hydrodynamics and buoyancy, electronics \
                waterproofing, actuation of mechanical systems and many more. Since Subbots is a \
                relatively new design team, there is plenty of opportunity to improve upon existing\
                designs and be a part of building the team. "
        },
        "goal":{
            "image": "electrical.jpg",
            "header": "Our Goal",
            "body": "As a UBC engineering design team we look to create an interesting and \
                engaging environment for all of our members. The team believes our project is a\
                way for students to take what they have learned in the classroom and apply it to\
                real world problems. We do our best to inspire interest in subsea and robotic\
                design while maintaining a fun atmosphere that promotes learning and team bonding. \
                Each year we hope to grow as a team by recruiting motivated and hard working students \
                who share a passion for our project. \n\n On the technical side, our teams goal is to\
                build a robot that is capable of competing in the RoboSub competition each year. To \
                do this our members must learn how to work within a team and multidisciplinary \
                environment to tackle unique design challenges. The teams goal is to facilitate \
                learning in all aspects of AUV design and encourage good engineering practices that \
                can be passed onto future generations of team members. "
        } ,
        "projects":{
            "header": "The Robots",
            "body": "Since becoming a team in 2017, Subbots has had the chance to work on two robots.\
                Our first robot for the 2017-2018 year was a huge learning curve for the team, but it \
                successfully competed at RoboSub which taught the team a lot about what goes into making \
                an AUV. We are currently on a two year design cycle for our second robot but we are \
                building off of our original design and on track to compete in the 2020 RoboSub competition. \
                More information about the robots can be found below!",
            "carousels": {
                 "first": {
                    "images": ["first_1.jpg", "first_2.jpg", "first_3.jpg", "first_4.jpg"],
                    "caption": "2017-2018"
                },
                "second": {
                     "images": ["second_1.jpg", "second_2.jpg", "second_3.jpg", "second_4.jpg", "second_5.jpg", "second_6.jpg"],
                     "caption": "2018-2019"
                }
            }
        }
    },
    "teams": {
        "image": "electrical.jpg",
        "title": "See What Our Members Do",
        "blurb": "  Whether you’re interested in software, electrical, or mechanical\
            design, Subbots offers many unique design challenges that forces our members \
            to come up with creative solutions for building autonomous underwater robots",
        "software": {
            "blurb":" Create and refine subaquatic artificial intelligence",
            "body": " (Software Body) The Software will run on the embedded computer that \
                the robot carries in its chassis. It defines every movement and decision that\
                the robot makes. Without the software, the robot is a potato.",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Machine Learning", "Computer Vision", "Linux Development"],
                    "learn": ["ROS", "Python", "C++"]
                },
                "descriptions": {
                    "do": ["Use libraries such as Tensorflow for object detection", "Process raw camera signals into meaningful information", "Develop in the open-source wonder that is Linux"],
                    "learn": ["Work on a widely used platform that combines modularity and efficiency", "Learn one of the most widely used languages in the world today", "Wow your friends with your new C++ skills"]
                }
            }
        },
        "electrical": {
            "blurb": "Design the interface between the computer and the sea",
            "body": " The electrical team develops the electrical systems that \
                allow the robot to read and respond to the world. The team designs \
                circuits to control thrusters, process hydrophone signal, read sensor\
                information, and protect valuable electrical components from unexpected\
                power surges. Robust and reliable electrical systems are critical for \
                allowing a robot to react well to a dynamic environment.",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Signal Processing", "Circuit Design", "Comm Systems"],
                    "learn": ["Verification", "Design", "Fabrication"]
                },
                "descriptions": {
                    "do": [" Transformation and interpretation of sensor data", "Robust and accurate electronic hardware", "Facilitating communication between different systems"],
                    "learn": ["Ensuring design and implementation meet specifications", "How to make a system of electronic components safe and robust", "Implementing ideas into the real world"]
                }
            }
        },
        "mechanical": {
            "blurb":"Push the physical limits of underwater mechanics",
            "body": "The mechanical team is responsible for making the body of the robot\
                that the electrical and software systems control. We handle buoyancy and static \
                stability, hydrodynamics, frame and enclosure design, actuation, electronics \
                integration, waterproofing and the overall esthetic of the robot. Designing mechanical \
                systems for underwater applications brings many design challenges and is critical in \
                allowing robots to exist underwater. ",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Structure", "Accuation", "Hydrodynamics"],
                    "learn": ["Design", "Fabrication", "Testing"]
                },
                "descriptions": {
                    "do": ["Robot body and electronics integration", "Interaction with the underwater environment ", "Physical stability and control through the water"],
                    "learn": ["How to design parts for a multidisciplinary project ", "Hands on skills needed to make designs into reality", "How designs perform in practical application"]
                }
            }
        },
    },

    "join": {
        "image": "software.jpg",
        "title": "Become Part Of The Team",
        "blurb": " We are always looking for new members to fill the many challenges\
            that come with designing underwater robots. Whether you’re new to engineering \
            or have previous design experience we encourage everyone who is interested in \
            the project to apply. Our team is built around mentoring new students so that \
            they can eventually take over as team leaders, so students of all skill levels \
            are welcome. Recruitment is primarily done at the start of the school year in \
            September but we continuously recruit throughout the year to fill roles as needed.\
            Our recruitment process consists of an application form that is reviewed by our \
            senior members and a potential interview if we feel you’d be a good fit for the \
            team. If you have a passion for subsea and robotic design feel free to fill out \
            the application below! ",
    },

    "sponsors": {
        "image": "electrical.jpg",
        "title": "See Who Makes Us Possible",
        "blurb": " To make our designs a reality Subbots relies on the support\
            of our many sponsors. Through in-kind and monetary contributions\
            our members are able to develop the skills necessary to become\
            engineering professionals. They also gain experience working\
            with our sponsor’s wonderful products, allowing them to more\
            effectively design with similar components in the future. We are\
             always open to new partners, and if you would like to sponsor our\
            team please reach out to us for our sponsorship package.",
        "sponsor_list": [
            {
                "image": "ubc_walter_gage.png",
                "link": "http://waltergagebook.engineering.ubc.ca/walter-gage-memorial-bursary-in-engineering/"
            },
            {
                "image": "subc.png",
                "link": "https://subc.ca/"
            },
            {
                "image": "ubc-applied-sciences-footer-logo.png",
                "link": "https://apsc.ubc.ca/"
            },
            {
                "image": "4imprint.png",
                "link": "https://www.4imprint.ca/"
            },
            {
                "image": "ECE.jpg",
                "link": "https://www.ece.ubc.ca/"
            },
            {
                "image": "IEEE_logo.png",
                "link": "http://www.ubcieee.org/"
            },
            {
                "image": "MATLAB-Logo.png",
                "link": "https://www.mathworks.com/products/matlab.html"
            },
            {
                "image": "mech.png",
                "link": "https://mech.ubc.ca/"
            },
            {
                "image": "phidgets_logo.png",
                "link": "https://www.phidgets.com/?"
            },
            {
                "image": "Shell-Logo.png",
                "link": "https://www.shell.ca/"
            },
            {
                "image": "SNAME.png",
                "link": "https://www.sname.org/home"
            },
            {
                "image": "snowbots.png",
                "link": "http://snowbots.ca/"
            },
            {
                "image": "solidworks-logo.png",
                "link": "https://www.solidworks.com/"
            },
            {
                "image": "spaenaur_logo.jpg",
                "link": "https://spaenaur.com/"
            },
            {
                "image": "ubc_forestry.png",
                "link": "https://forestry.ubc.ca/"
            },
            {
                "image": "venom_logo.png",
                "link": "https://www.venompower.com/"
            },
            {
                "image": "vp.jpg",
                "link": "https://apsc.ubc.ca/"
            },
        ]
    },
    "emails": {
        "Subbots": "info.subbots@gmail.com",
        "Electrical": "info.subbots@gmail.com",
        "Mechanical": "logan.fillo@gmail.com",
        "Software": ""
    }
}<|endoftext|>


<commit_before>(function($){
  'use strict';

  var $thumb = $('');
  $thumb.appendTo('body');

  $('#menu').on('mouseenter', '[name="product"]', _.debounce(function(){
    var vittle = new Vittle(this);
    console.log(vittle.tokens());
    vittle.getImageUrl(function(url){
      console.log(url);
      if (url){
        $thumb.attr('src', url);
      }
    });
  }, 800));
})(Zepto);
<commit_msg>hide the preview after leaving the
<commit_after>(function($){
  'use strict';

  var $thumb = $('');
  $thumb.appendTo('body');

  var $menu = $('#menu');

  $menu.on('mouseenter', '[name="product"]', _.debounce(function(){
    var vittle = new Vittle(this);
    console.log(vittle.tokens());

    vittle.getImageUrl(function(url){
      console.log(url);
      if (url){
        $thumb.attr('src', url);
        $thumb.show();
      }
    });
  }, 800));

  $menu.on('mouseleave', 'li', function(){
    $thumb.hide();
  });
})(Zepto);
<|endoftext|>


<commit_before>const constants = require('./js/constants');

export default
{
    "home": {
        "image": "software.jpg",
        "title": "Welcome To UBC Subbots",
        "blurb": "UBC Subbots is an engineering student design team dedicated to \
            making an autonomous underwater vehicle (AUV) for the RoboSub competition \
            in San Diego, California each year. This competition challenges us to make \
            a robot that can navigate and interact with underwater obstacles without any\
            human intervention whatsoever. The team was founded in 2017 and is made up of \
            engineering and computer science students from multiple disciplines who have full\
            control over the design, manufacturing and testing of the robot. Since becoming\
            a team, we have learned a lot about designing for the underwater environment and \
            are continuously improving upon our existing designs. ",
        "pitch":{
            "image": "mechanical.jpg",
            "header": "Why Subbots?",
            "body": " Subbots provides the chance for students to work on unique design\
                problems that can’t be found anywhere else at UBC. The team originated from \
                two existing designs teams: UBC SUBC who focuses on the design of human powered\
                submarines, and UBC Snowbots who designs autonomous land robots for various \
                applications. Combining these two together brings a variety of challenges such \
                as autonomous underwater navigation, hydrodynamics and buoyancy, electronics \
                waterproofing, actuation of mechanical systems and many more. Since Subbots is a \
                relatively new design team, there is plenty of opportunity to improve upon existing\
                designs and be a part of building the team. "
        },
        "goal":{
            "image": "electrical.jpg",
            "header": "Our Goal",
            "body": "As a UBC engineering design team we look to create an interesting and \
                engaging environment for all of our members. The team believes our project is a\
                way for students to take what they have learned in the classroom and apply it to\
                real world problems. We do our best to inspire interest in subsea and robotic\
                design while maintaining a fun atmosphere that promotes learning and team bonding. \
                Each year we hope to grow as a team by recruiting motivated and hard working students \
                who share a passion for our project. \n\n On the technical side, our teams goal is to\
                build a robot that is capable of competing in the RoboSub competition each year. To \
                do this our members must learn how to work within a team and multidisciplinary \
                environment to tackle unique design challenges. The teams goal is to facilitate \
                learning in all aspects of AUV design and encourage good engineering practices that \
                can be passed onto future generations of team members. "
        } ,
        "projects":{
            "header": "The Robots",
            "body": "Since becoming a team in 2017, Subbots has had the chance to work on two robots.\
                Our first robot for the 2017-2018 year was a huge learning curve for the team, but it \
                successfully competed at RoboSub which taught the team a lot about what goes into making \
                an AUV. We are currently on a two year design cycle for our second robot but we are \
                building off of our original design and on track to compete in the 2020 RoboSub competition. \
                More information about the robots can be found below!",
            "carousels": {
                 "first": {
                    "images": ["first_1.jpg", "first_2.jpg", "first_3.jpg", "first_4.jpg"],
                    "caption": "2017-2018"
                },
                "second": {
                     "images": ["second_1.jpg", "second_2.jpg", "second_3.jpg", "second_4.jpg", "second_5.jpg", "second_6.jpg"],
                     "caption": "2018-2019"
                }
            }
        }
    },
    "teams": {
        "image": "electrical.jpg",
        "title": "See What Our Members Do",
        "blurb": "  Whether you’re interested in software, electrical, or mechanical\
            design, Subbots offers many unique design challenges that forces our members \
            to come up with creative solutions for building autonomous underwater robots",
        "software": {
            "blurb":" Create and refine subaquatic artificial intelligence",
            "body": " The Software will run on the embedded computer that \
                the robot carries in its chassis. It defines every movement and decision that\
                the robot makes. Without the software, the robot is a potato.",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Machine Learning", "Computer Vision", "Linux Development"],
                    "learn": ["ROS", "Python", "C++"]
                },
                "descriptions": {
                    "do": ["Use libraries such as Tensorflow for object detection", "Process raw camera signals into meaningful information", "Develop in the open-source wonder that is Linux"],
                    "learn": ["Work on a widely used platform that combines modularity and efficiency", "Learn one of the most widely used languages in the world today", "Wow your friends with your new C++ skills"]
                }
            }
        },
        "electrical": {
            "blurb": "Design the interface between the computer and the sea",
            "body": " The electrical team develops the electrical systems that \
                allow the robot to read and respond to the world. The team designs \
                circuits to control thrusters, process hydrophone signal, read sensor\
                information, and protect valuable electrical components from unexpected\
                power surges. Robust and reliable electrical systems are critical for \
                allowing a robot to react well to a dynamic environment.",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Signal Processing", "Circuit Design", "Comm Systems"],
                    "learn": ["Verification", "Design", "Fabrication"]
                },
                "descriptions": {
                    "do": [" Transformation and interpretation of sensor data", "Robust and accurate electronic hardware", "Facilitating communication between different systems"],
                    "learn": ["Ensuring design and implementation meet specifications", "How to make a system of electronic components safe and robust", "Implementing ideas into the real world"]
                }
            }
        },
        "mechanical": {
            "blurb":"Push the physical limits of underwater mechanics",
            "body": "The mechanical team is responsible for making the body of the robot\
                that the electrical and software systems control. We handle buoyancy and static \
                stability, hydrodynamics, frame and enclosure design, actuation, electronics \
                integration, waterproofing and the overall esthetic of the robot. Designing mechanical \
                systems for underwater applications brings many design challenges and is critical in \
                allowing robots to exist underwater. ",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Structure", "Accuation", "Hydrodynamics"],
                    "learn": ["Design", "Fabrication", "Testing"]
                },
                "descriptions": {
                    "do": ["Robot body and electronics integration", "Interaction with the underwater environment ", "Physical stability and control through the water"],
                    "learn": ["How to design parts for a multidisciplinary project ", "Hands on skills needed to make designs into reality", "How designs perform in practical application"]
                }
            }
        },
    },

    "join": {
        "image": "software.jpg",
        "title": "Become Part Of The Team",
        "blurb": " We are always looking for new members to fill the many challenges\
            that come with designing underwater robots. Whether you’re new to engineering \
            or have previous design experience we encourage everyone who is interested in \
            the project to apply. Our team is built around mentoring new students so that \
            they can eventually take over as team leaders, so students of all skill levels \
            are welcome. Recruitment is primarily done at the start of the school year in \
            September but we continuously recruit throughout the year to fill roles as needed.\
            Our recruitment process consists of an application form that is reviewed by our \
            senior members and a potential interview if we feel you’d be a good fit for the \
            team. If you have a passion for subsea and robotic design feel free to fill out \
            the application below! ",
    },

    "sponsors": {
        "image": "electrical.jpg",
        "title": "See Who Makes Us Possible",
        "blurb": " To make our designs a reality Subbots relies on the support\
            of our many sponsors. Through in-kind and monetary contributions\
            our members are able to develop the skills necessary to become\
            engineering professionals. They also gain experience working\
            with our sponsor’s wonderful products, allowing them to more\
            effectively design with similar components in the future. We are\
             always open to new partners, and if you would like to sponsor our\
            team please reach out to us for our sponsorship package.",
        "sponsor_list": [
            {
                "image": "ubc_walter_gage.png",
                "link": "http://waltergagebook.engineering.ubc.ca/walter-gage-memorial-bursary-in-engineering/"
            },
            {
                "image": "subc.png",
                "link": "https://subc.ca/"
            },
            {
                "image": "ubc-applied-sciences-footer-logo.png",
                "link": "https://apsc.ubc.ca/"
            },
            {
                "image": "4imprint.png",
                "link": "https://www.4imprint.ca/"
            },
            {
                "image": "ECE.jpg",
                "link": "https://www.ece.ubc.ca/"
            },
            {
                "image": "IEEE_logo.png",
                "link": "http://www.ubcieee.org/"
            },
            {
                "image": "MATLAB-Logo.png",
                "link": "https://www.mathworks.com/products/matlab.html"
            },
            {
                "image": "mech.png",
                "link": "https://mech.ubc.ca/"
            },
            {
                "image": "phidgets_logo.png",
                "link": "https://www.phidgets.com/?"
            },
            {
                "image": "Shell-Logo.png",
                "link": "https://www.shell.ca/"
            },
            {
                "image": "SNAME.png",
                "link": "https://www.sname.org/home"
            },
            {
                "image": "snowbots.png",
                "link": "http://snowbots.ca/"
            },
            {
                "image": "solidworks-logo.png",
                "link": "https://www.solidworks.com/"
            },
            {
                "image": "spaenaur_logo.jpg",
                "link": "https://spaenaur.com/"
            },
            {
                "image": "ubc_forestry.png",
                "link": "https://forestry.ubc.ca/"
            },
            {
                "image": "venom_logo.png",
                "link": "https://www.venompower.com/"
            },
            {
                "image": "vp.jpg",
                "link": "https://apsc.ubc.ca/"
            },
        ]
    },
    "emails": {
        "Subbots": "ubc.subbots@gmail.com",
        "Electrical": "info.subbots@gmail.com",
        "Mechanical": "info.subbots@gmail.com",
        "Software": "info.subbots@gmail.com"
    }
}<commit_msg>changed emails<commit_after>const constants = require('./js/constants');

export default
{
    "home": {
        "image": "software.jpg",
        "title": "Welcome To UBC Subbots",
        "blurb": "UBC Subbots is an engineering student design team dedicated to \
            making an autonomous underwater vehicle (AUV) for the RoboSub competition \
            in San Diego, California each year. This competition challenges us to make \
            a robot that can navigate and interact with underwater obstacles without any\
            human intervention whatsoever. The team was founded in 2017 and is made up of \
            engineering and computer science students from multiple disciplines who have full\
            control over the design, manufacturing and testing of the robot. Since becoming\
            a team, we have learned a lot about designing for the underwater environment and \
            are continuously improving upon our existing designs. ",
        "pitch":{
            "image": "mechanical.jpg",
            "header": "Why Subbots?",
            "body": " Subbots provides the chance for students to work on unique design\
                problems that can’t be found anywhere else at UBC. The team originated from \
                two existing designs teams: UBC SUBC who focuses on the design of human powered\
                submarines, and UBC Snowbots who designs autonomous land robots for various \
                applications. Combining these two together brings a variety of challenges such \
                as autonomous underwater navigation, hydrodynamics and buoyancy, electronics \
                waterproofing, actuation of mechanical systems and many more. Since Subbots is a \
                relatively new design team, there is plenty of opportunity to improve upon existing\
                designs and be a part of building the team. "
        },
        "goal":{
            "image": "electrical.jpg",
            "header": "Our Goal",
            "body": "As a UBC engineering design team we look to create an interesting and \
                engaging environment for all of our members. The team believes our project is a\
                way for students to take what they have learned in the classroom and apply it to\
                real world problems. We do our best to inspire interest in subsea and robotic\
                design while maintaining a fun atmosphere that promotes learning and team bonding. \
                Each year we hope to grow as a team by recruiting motivated and hard working students \
                who share a passion for our project. \n\n On the technical side, our teams goal is to\
                build a robot that is capable of competing in the RoboSub competition each year. To \
                do this our members must learn how to work within a team and multidisciplinary \
                environment to tackle unique design challenges. The teams goal is to facilitate \
                learning in all aspects of AUV design and encourage good engineering practices that \
                can be passed onto future generations of team members. "
        } ,
        "projects":{
            "header": "The Robots",
            "body": "Since becoming a team in 2017, Subbots has had the chance to work on two robots.\
                Our first robot for the 2017-2018 year was a huge learning curve for the team, but it \
                successfully competed at RoboSub which taught the team a lot about what goes into making \
                an AUV. We are currently on a two year design cycle for our second robot but we are \
                building off of our original design and on track to compete in the 2020 RoboSub competition. \
                More information about the robots can be found below!",
            "carousels": {
                 "first": {
                    "images": ["first_1.jpg", "first_2.jpg", "first_3.jpg", "first_4.jpg"],
                    "caption": "2017-2018"
                },
                "second": {
                     "images": ["second_1.jpg", "second_2.jpg", "second_3.jpg", "second_4.jpg", "second_5.jpg", "second_6.jpg"],
                     "caption": "2018-2019"
                }
            }
        }
    },
    "teams": {
        "image": "electrical.jpg",
        "title": "See What Our Members Do",
        "blurb": "  Whether you’re interested in software, electrical, or mechanical\
            design, Subbots offers many unique design challenges that forces our members \
            to come up with creative solutions for building autonomous underwater robots",
        "software": {
            "blurb":" Create and refine subaquatic artificial intelligence",
            "body": " The Software will run on the embedded computer that \
                the robot carries in its chassis. It defines every movement and decision that\
                the robot makes. Without the software, the robot is a potato.",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Machine Learning", "Computer Vision", "Linux Development"],
                    "learn": ["ROS", "Python", "C++"]
                },
                "descriptions": {
                    "do": ["Use libraries such as Tensorflow for object detection", "Process raw camera signals into meaningful information", "Develop in the open-source wonder that is Linux"],
                    "learn": ["Work on a widely used platform that combines modularity and efficiency", "Learn one of the most widely used languages in the world today", "Wow your friends with your new C++ skills"]
                }
            }
        },
        "electrical": {
            "blurb": "Design the interface between the computer and the sea",
            "body": " The electrical team develops the electrical systems that \
                allow the robot to read and respond to the world. The team designs \
                circuits to control thrusters, process hydrophone signal, read sensor\
                information, and protect valuable electrical components from unexpected\
                power surges. Robust and reliable electrical systems are critical for \
                allowing a robot to react well to a dynamic environment.",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Signal Processing", "Circuit Design", "Comm Systems"],
                    "learn": ["Verification", "Design", "Fabrication"]
                },
                "descriptions": {
                    "do": [" Transformation and interpretation of sensor data", "Robust and accurate electronic hardware", "Facilitating communication between different systems"],
                    "learn": ["Ensuring design and implementation meet specifications", "How to make a system of electronic components safe and robust", "Implementing ideas into the real world"]
                }
            }
        },
        "mechanical": {
            "blurb":"Push the physical limits of underwater mechanics",
            "body": "The mechanical team is responsible for making the body of the robot\
                that the electrical and software systems control. We handle buoyancy and static \
                stability, hydrodynamics, frame and enclosure design, actuation, electronics \
                integration, waterproofing and the overall esthetic of the robot. Designing mechanical \
                systems for underwater applications brings many design challenges and is critical in \
                allowing robots to exist underwater. ",
            "items": {
                "images": {
                    "do": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                    "learn": ["crosshair.jpg", "crosshair.jpg", "crosshair.jpg"],
                },
                "names": {
                    "do": ["Structure", "Accuation", "Hydrodynamics"],
                    "learn": ["Design", "Fabrication", "Testing"]
                },
                "descriptions": {
                    "do": ["Robot body and electronics integration", "Interaction with the underwater environment ", "Physical stability and control through the water"],
                    "learn": ["How to design parts for a multidisciplinary project ", "Hands on skills needed to make designs into reality", "How designs perform in practical application"]
                }
            }
        },
    },

    "join": {
        "image": "software.jpg",
        "title": "Become Part Of The Team",
        "blurb": " We are always looking for new members to fill the many challenges\
            that come with designing underwater robots. Whether you’re new to engineering \
            or have previous design experience we encourage everyone who is interested in \
            the project to apply. Our team is built around mentoring new students so that \
            they can eventually take over as team leaders, so students of all skill levels \
            are welcome. Recruitment is primarily done at the start of the school year in \
            September but we continuously recruit throughout the year to fill roles as needed.\
            Our recruitment process consists of an application form that is reviewed by our \
            senior members and a potential interview if we feel you’d be a good fit for the \
            team. If you have a passion for subsea and robotic design feel free to fill out \
            the application below! ",
    },

    "sponsors": {
        "image": "electrical.jpg",
        "title": "See Who Makes Us Possible",
        "blurb": " To make our designs a reality Subbots relies on the support\
            of our many sponsors. Through in-kind and monetary contributions\
            our members are able to develop the skills necessary to become\
            engineering professionals. They also gain experience working\
            with our sponsor’s wonderful products, allowing them to more\
            effectively design with similar components in the future. We are\
             always open to new partners, and if you would like to sponsor our\
            team please reach out to us for our sponsorship package.",
        "sponsor_list": [
            {
                "image": "ubc_walter_gage.png",
                "link": "http://waltergagebook.engineering.ubc.ca/walter-gage-memorial-bursary-in-engineering/"
            },
            {
                "image": "subc.png",
                "link": "https://subc.ca/"
            },
            {
                "image": "ubc-applied-sciences-footer-logo.png",
                "link": "https://apsc.ubc.ca/"
            },
            {
                "image": "4imprint.png",
                "link": "https://www.4imprint.ca/"
            },
            {
                "image": "ECE.jpg",
                "link": "https://www.ece.ubc.ca/"
            },
            {
                "image": "IEEE_logo.png",
                "link": "http://www.ubcieee.org/"
            },
            {
                "image": "MATLAB-Logo.png",
                "link": "https://www.mathworks.com/products/matlab.html"
            },
            {
                "image": "mech.png",
                "link": "https://mech.ubc.ca/"
            },
            {
                "image": "phidgets_logo.png",
                "link": "https://www.phidgets.com/?"
            },
            {
                "image": "Shell-Logo.png",
                "link": "https://www.shell.ca/"
            },
            {
                "image": "SNAME.png",
                "link": "https://www.sname.org/home"
            },
            {
                "image": "snowbots.png",
                "link": "http://snowbots.ca/"
            },
            {
                "image": "solidworks-logo.png",
                "link": "https://www.solidworks.com/"
            },
            {
                "image": "spaenaur_logo.jpg",
                "link": "https://spaenaur.com/"
            },
            {
                "image": "ubc_forestry.png",
                "link": "https://forestry.ubc.ca/"
            },
            {
                "image": "venom_logo.png",
                "link": "https://www.venompower.com/"
            },
            {
                "image": "vp.jpg",
                "link": "https://apsc.ubc.ca/"
            },
        ]
    },
    "emails": {
        "Subbots": "ubc.subbots@gmail.com",
        "Electrical": "ubc.subbots@gmail.com",
        "Mechanical": "ubc.subbots@gmail.com",
        "Software": "ubc.subbots@gmail.com"
    }
}<|endoftext|>


<commit_before>/*jslint forin: true, nomen: true*/
/*global _, observable*/
var content = function (contentAggregate) {
	'use strict';
	var init = function (contentIdea) {
		if (contentIdea.ideas) {
			_.each(contentIdea.ideas, function (value, key) {
				contentIdea.ideas[key] = init(value);
			});
		}
		contentIdea.id = contentIdea.id || (contentAggregate.maxId() + 1);
		contentIdea.containsDirectChild = contentIdea.findChildRankById = function (childIdeaId) {
			return parseFloat(
				_.reduce(
					contentIdea.ideas,
					function (res, value, key) {
						return value.id === childIdeaId ? key : res;
					},
					undefined
				)
			);
		};
		contentIdea.findSubIdeaById = function (childIdeaId) {
			var myChild = _.find(contentIdea.ideas, function (idea) {
				return idea.id === childIdeaId;
			});
			return myChild || _.reduce(contentIdea.ideas, function (result, idea) {
				return result || idea.findSubIdeaById(childIdeaId);
			}, undefined);
		};
		contentIdea.find = function (predicate) {
			var current = predicate(contentIdea) ? [_.pick(contentIdea, 'id', 'title')] : [];
			if (_.size(contentIdea.ideas) === 0) {
				return current;
			}
			return _.reduce(contentIdea.ideas, function (result, idea) {
				return _.union(result, idea.find(predicate));
			}, current);
		};
		contentIdea.getStyle = function (name) {
			if (contentIdea.style && contentIdea.style[name]) {
				return contentIdea.style[name];
			}
			return false;
		};
		return contentIdea;
	},
		maxKey = function (kv_map, sign) {
			sign = sign || 1;
			if (_.size(kv_map) === 0) {
				return 0;
			}
			var current_keys = _.keys(kv_map);
			current_keys.push(0); /* ensure at least 0 is there for negative ranks */
			return _.max(_.map(current_keys, parseFloat), function (x) {
				return x * sign;
			});
		},
		nextChildRank = function (parentIdea) {
			var new_rank, counts, childRankSign = 1;
			if (parentIdea.id === contentAggregate.id) {
				counts = _.countBy(parentIdea.ideas, function (v, k) {
					return k < 0;
				});
				if ((counts['true'] || 0) < counts['false']) {
					childRankSign = -1;
				}
			}
			new_rank = maxKey(parentIdea.ideas, childRankSign) + childRankSign;
			return new_rank;
		},
		appendSubIdea = function (parentIdea, subIdea) {
			parentIdea.ideas = parentIdea.ideas || {};

			parentIdea.ideas[nextChildRank(parentIdea)] = subIdea;
		},
		findIdeaById = function (ideaId) {
			ideaId = parseFloat(ideaId);
			return contentAggregate.id === ideaId ? contentAggregate : contentAggregate.findSubIdeaById(ideaId);
		},
		sameSideSiblingRanks = function (parentIdea, ideaRank) {
			return _(_.map(_.keys(parentIdea.ideas), parseFloat)).reject(function (k) {return k * ideaRank < 0; });
		},
		traverseAndRemoveIdea = function (parentIdea, subIdeaId) {
			var deleted, childRank = parentIdea.findChildRankById(subIdeaId);
			if (childRank) {
				deleted = parentIdea.ideas[childRank];
				delete parentIdea.ideas[childRank];
				return deleted;
			}
			return _.reduce(
				parentIdea.ideas,
				function (result, child) {
					return result || traverseAndRemoveIdea(child, subIdeaId);
				},
				false
			);
		},
		sign = function (number) {
			/* intentionally not returning 0 case, to help with split sorting into 2 groups */
			return number < 0 ? -1 : 1;
		};
	contentAggregate.maxId = function maxId(idea) {
		idea = idea || contentAggregate;
		if (!idea.ideas) {
			return idea.id || 0;
		}
		return _.reduce(
			idea.ideas,
			function (result, subidea) {
				return Math.max(result, maxId(subidea));
			},
			idea.id || 0
		);
	};
	contentAggregate.nextSiblingId = function (subIdeaId) {
		var parentIdea = contentAggregate.findParent(subIdeaId),
			currentRank,
			candidateSiblingRanks,
			siblingsAfter;
		if (!parentIdea) { return false; }
		currentRank = parentIdea.findChildRankById(subIdeaId);
		candidateSiblingRanks = sameSideSiblingRanks(parentIdea, currentRank);
		siblingsAfter = _.reject(candidateSiblingRanks, function (k) { return Math.abs(k) <= Math.abs(currentRank); });
		if (siblingsAfter.length === 0) { return false; }
		return parentIdea.ideas[_.min(siblingsAfter, Math.abs)].id;
	};
	contentAggregate.previousSiblingId = function (subIdeaId) {
		var parentIdea = contentAggregate.findParent(subIdeaId),
			currentRank,
			candidateSiblingRanks,
			siblingsBefore;
		if (!parentIdea) { return false; }
		currentRank = parentIdea.findChildRankById(subIdeaId);
		candidateSiblingRanks = sameSideSiblingRanks(parentIdea, currentRank);
		siblingsBefore = _.reject(candidateSiblingRanks, function (k) { return Math.abs(k) >= Math.abs(currentRank); });
		if (siblingsBefore.length === 0) { return false; }
		return parentIdea.ideas[_.max(siblingsBefore, Math.abs)].id;
	};

	/*** private utility methods ***/
	contentAggregate.findParent = function (subIdeaId, parentIdea) {
		parentIdea = parentIdea || contentAggregate;
		var childRank = parentIdea.findChildRankById(subIdeaId);
		if (childRank) {
			return parentIdea;
		}
		return _.reduce(
			parentIdea.ideas,
			function (result, child) {
				return result || contentAggregate.findParent(subIdeaId, child);
			},
			false
		);
	};

	/**** aggregate command processing methods ****/
	contentAggregate.flip = function (ideaId) {
		var new_rank, max_rank, current_rank = contentAggregate.findChildRankById(ideaId);
		if (!current_rank) {
			return false;
		}
		max_rank = maxKey(contentAggregate.ideas, -1 * sign(current_rank));
		new_rank = max_rank - 10 * sign(current_rank);
		contentAggregate.ideas[new_rank] = contentAggregate.ideas[current_rank];
		delete contentAggregate.ideas[current_rank];
		contentAggregate.dispatchEvent('changed', 'flip', [ideaId]);
		return true;
	};
	contentAggregate.updateTitle = function (ideaId, title) {
		var idea = findIdeaById(ideaId);
		if (!idea) {
			return false;
		}
		idea.title = title;
		contentAggregate.dispatchEvent('changed', 'updateTitle', [ideaId, title]);
		return true;
	};
	contentAggregate.addSubIdea = function (parentId, ideaTitle) {
		var idea, parent = findIdeaById(parentId);
		if (!parent) {
			return false;
		}
		idea = init({
			title: ideaTitle
		});
		appendSubIdea(parent, idea);
		contentAggregate.dispatchEvent('changed', 'addSubIdea', [parentId, ideaTitle, idea.id]);
		return true;
	};
	contentAggregate.removeSubIdea = function (subIdeaId) {
		var result = traverseAndRemoveIdea(contentAggregate, subIdeaId);
		if (result) {
			contentAggregate.dispatchEvent('changed', 'removeSubIdea', [subIdeaId]);
		}
		return result;
	};
	contentAggregate.insertIntermediate = function (inFrontOfIdeaId, title) {
		if (contentAggregate.id === inFrontOfIdeaId) {
			return false;
		}
		var childRank, oldIdea, newIdea, parentIdea = contentAggregate.findParent(inFrontOfIdeaId);
		if (!parentIdea) {
			return false;
		}
		childRank = parentIdea.findChildRankById(inFrontOfIdeaId);
		if (!childRank) {
			return false;
		}
		oldIdea = parentIdea.ideas[childRank];
		newIdea = init({
			title: title
		});
		parentIdea.ideas[childRank] = newIdea;
		newIdea.ideas = {
			1: oldIdea
		};
		contentAggregate.dispatchEvent('changed', 'insertIntermediate', [inFrontOfIdeaId, title, newIdea.id]);
		return true;
	};
	contentAggregate.changeParent = function (ideaId, newParentId) {
		if (ideaId === newParentId) {
			return false;
		}
		var idea, parent = findIdeaById(newParentId);
		if (!parent) {
			return false;
		}
		idea = contentAggregate.findSubIdeaById(ideaId);
		if (!idea) {
			return false;
		}
		if (idea.findSubIdeaById(newParentId)) {
			return false;
		}
		if (parent.containsDirectChild(ideaId)) {
			return false;
		}
		traverseAndRemoveIdea(contentAggregate, ideaId);
		if (!idea) {
			return false;
		}
		appendSubIdea(parent, idea);
		contentAggregate.dispatchEvent('changed', 'changeParent', [ideaId, newParentId]);
		return true;
	};
	contentAggregate.updateStyle = function (ideaId, styleName, styleValue) {
		var idea = findIdeaById(ideaId);
		if (!idea) {
			return false;
		}
		idea.style = idea.style || {};
		if (styleValue) {
			idea.style[styleName] = styleValue;
		} else {
			delete idea.style[styleName];
		}
		if (_.size(idea.style) === 0) {
			delete idea.style;
		}
		contentAggregate.dispatchEvent('changed', 'updateStyle', [ideaId, styleName, styleValue]);
		return true;
	};
	contentAggregate.positionBefore = function (ideaId, positionBeforeIdeaId, parentIdea) {
		parentIdea = parentIdea || contentAggregate;
		var new_rank, after_rank, sibling_ranks, candidate_siblings, before_rank, max_rank, current_rank;
		current_rank = parentIdea.findChildRankById(ideaId);
		if (!current_rank) {
			return _.reduce(
				parentIdea.ideas,
				function (result, idea) {
					return result || contentAggregate.positionBefore(ideaId, positionBeforeIdeaId, idea);
				},
				false
			);
		}
		if (ideaId === positionBeforeIdeaId) {
			return false;
		}
		new_rank = 0;
		if (positionBeforeIdeaId) {
			after_rank = parentIdea.findChildRankById(positionBeforeIdeaId);
			if (!after_rank) {
				return false;
			}
			sibling_ranks = sameSideSiblingRanks(parentIdea, current_rank);
			candidate_siblings = _.reject(_.sortBy(sibling_ranks, Math.abs), function (k) {
				return Math.abs(k) >= Math.abs(after_rank);
			});
			before_rank = candidate_siblings.length > 0 ? _.max(candidate_siblings) : 0;
			if (before_rank === current_rank) {
				return false;
			}
			new_rank = before_rank + (after_rank - before_rank) / 2;
		} else {
			max_rank = maxKey(parentIdea.ideas, current_rank < 0 ? -1 : 1);
			if (max_rank === current_rank) {
				return false;
			}
			new_rank = max_rank + 10 * (current_rank < 0 ? -1 : 1);
		}
		if (new_rank === current_rank) {
			return false;
		}
		parentIdea.ideas[new_rank] = parentIdea.ideas[current_rank];
		delete parentIdea.ideas[current_rank];
		contentAggregate.dispatchEvent('changed', 'positionBefore', [ideaId, positionBeforeIdeaId]);
		return true;
	};
	init(contentAggregate);
	return observable(contentAggregate);
};
<commit_msg>insertBefore for children with negative ranks<commit_after>/*jslint forin: true, nomen: true*/
/*global _, observable*/
var content = function (contentAggregate) {
	'use strict';
	var init = function (contentIdea) {
		if (contentIdea.ideas) {
			_.each(contentIdea.ideas, function (value, key) {
				contentIdea.ideas[key] = init(value);
			});
		}
		contentIdea.id = contentIdea.id || (contentAggregate.maxId() + 1);
		contentIdea.containsDirectChild = contentIdea.findChildRankById = function (childIdeaId) {
			return parseFloat(
				_.reduce(
					contentIdea.ideas,
					function (res, value, key) {
						return value.id === childIdeaId ? key : res;
					},
					undefined
				)
			);
		};
		contentIdea.findSubIdeaById = function (childIdeaId) {
			var myChild = _.find(contentIdea.ideas, function (idea) {
				return idea.id === childIdeaId;
			});
			return myChild || _.reduce(contentIdea.ideas, function (result, idea) {
				return result || idea.findSubIdeaById(childIdeaId);
			}, undefined);
		};
		contentIdea.find = function (predicate) {
			var current = predicate(contentIdea) ? [_.pick(contentIdea, 'id', 'title')] : [];
			if (_.size(contentIdea.ideas) === 0) {
				return current;
			}
			return _.reduce(contentIdea.ideas, function (result, idea) {
				return _.union(result, idea.find(predicate));
			}, current);
		};
		contentIdea.getStyle = function (name) {
			if (contentIdea.style && contentIdea.style[name]) {
				return contentIdea.style[name];
			}
			return false;
		};
		return contentIdea;
	},
		maxKey = function (kv_map, sign) {
			sign = sign || 1;
			if (_.size(kv_map) === 0) {
				return 0;
			}
			var current_keys = _.keys(kv_map);
			current_keys.push(0); /* ensure at least 0 is there for negative ranks */
			return _.max(_.map(current_keys, parseFloat), function (x) {
				return x * sign;
			});
		},
		nextChildRank = function (parentIdea) {
			var new_rank, counts, childRankSign = 1;
			if (parentIdea.id === contentAggregate.id) {
				counts = _.countBy(parentIdea.ideas, function (v, k) {
					return k < 0;
				});
				if ((counts['true'] || 0) < counts['false']) {
					childRankSign = -1;
				}
			}
			new_rank = maxKey(parentIdea.ideas, childRankSign) + childRankSign;
			return new_rank;
		},
		appendSubIdea = function (parentIdea, subIdea) {
			parentIdea.ideas = parentIdea.ideas || {};

			parentIdea.ideas[nextChildRank(parentIdea)] = subIdea;
		},
		findIdeaById = function (ideaId) {
			ideaId = parseFloat(ideaId);
			return contentAggregate.id === ideaId ? contentAggregate : contentAggregate.findSubIdeaById(ideaId);
		},
		sameSideSiblingRanks = function (parentIdea, ideaRank) {
			return _(_.map(_.keys(parentIdea.ideas), parseFloat)).reject(function (k) {return k * ideaRank < 0; });
		},
		traverseAndRemoveIdea = function (parentIdea, subIdeaId) {
			var deleted, childRank = parentIdea.findChildRankById(subIdeaId);
			if (childRank) {
				deleted = parentIdea.ideas[childRank];
				delete parentIdea.ideas[childRank];
				return deleted;
			}
			return _.reduce(
				parentIdea.ideas,
				function (result, child) {
					return result || traverseAndRemoveIdea(child, subIdeaId);
				},
				false
			);
		},
		sign = function (number) {
			/* intentionally not returning 0 case, to help with split sorting into 2 groups */
			return number < 0 ? -1 : 1;
		};
	contentAggregate.maxId = function maxId(idea) {
		idea = idea || contentAggregate;
		if (!idea.ideas) {
			return idea.id || 0;
		}
		return _.reduce(
			idea.ideas,
			function (result, subidea) {
				return Math.max(result, maxId(subidea));
			},
			idea.id || 0
		);
	};
	contentAggregate.nextSiblingId = function (subIdeaId) {
		var parentIdea = contentAggregate.findParent(subIdeaId),
			currentRank,
			candidateSiblingRanks,
			siblingsAfter;
		if (!parentIdea) { return false; }
		currentRank = parentIdea.findChildRankById(subIdeaId);
		candidateSiblingRanks = sameSideSiblingRanks(parentIdea, currentRank);
		siblingsAfter = _.reject(candidateSiblingRanks, function (k) { return Math.abs(k) <= Math.abs(currentRank); });
		if (siblingsAfter.length === 0) { return false; }
		return parentIdea.ideas[_.min(siblingsAfter, Math.abs)].id;
	};
	contentAggregate.previousSiblingId = function (subIdeaId) {
		var parentIdea = contentAggregate.findParent(subIdeaId),
			currentRank,
			candidateSiblingRanks,
			siblingsBefore;
		if (!parentIdea) { return false; }
		currentRank = parentIdea.findChildRankById(subIdeaId);
		candidateSiblingRanks = sameSideSiblingRanks(parentIdea, currentRank);
		siblingsBefore = _.reject(candidateSiblingRanks, function (k) { return Math.abs(k) >= Math.abs(currentRank); });
		if (siblingsBefore.length === 0) { return false; }
		return parentIdea.ideas[_.max(siblingsBefore, Math.abs)].id;
	};

	/*** private utility methods ***/
	contentAggregate.findParent = function (subIdeaId, parentIdea) {
		parentIdea = parentIdea || contentAggregate;
		var childRank = parentIdea.findChildRankById(subIdeaId);
		if (childRank) {
			return parentIdea;
		}
		return _.reduce(
			parentIdea.ideas,
			function (result, child) {
				return result || contentAggregate.findParent(subIdeaId, child);
			},
			false
		);
	};

	/**** aggregate command processing methods ****/
	contentAggregate.flip = function (ideaId) {
		var new_rank, max_rank, current_rank = contentAggregate.findChildRankById(ideaId);
		if (!current_rank) {
			return false;
		}
		max_rank = maxKey(contentAggregate.ideas, -1 * sign(current_rank));
		new_rank = max_rank - 10 * sign(current_rank);
		contentAggregate.ideas[new_rank] = contentAggregate.ideas[current_rank];
		delete contentAggregate.ideas[current_rank];
		contentAggregate.dispatchEvent('changed', 'flip', [ideaId]);
		return true;
	};
	contentAggregate.updateTitle = function (ideaId, title) {
		var idea = findIdeaById(ideaId);
		if (!idea) {
			return false;
		}
		idea.title = title;
		contentAggregate.dispatchEvent('changed', 'updateTitle', [ideaId, title]);
		return true;
	};
	contentAggregate.addSubIdea = function (parentId, ideaTitle) {
		var idea, parent = findIdeaById(parentId);
		if (!parent) {
			return false;
		}
		idea = init({
			title: ideaTitle
		});
		appendSubIdea(parent, idea);
		contentAggregate.dispatchEvent('changed', 'addSubIdea', [parentId, ideaTitle, idea.id]);
		return true;
	};
	contentAggregate.removeSubIdea = function (subIdeaId) {
		var result = traverseAndRemoveIdea(contentAggregate, subIdeaId);
		if (result) {
			contentAggregate.dispatchEvent('changed', 'removeSubIdea', [subIdeaId]);
		}
		return result;
	};
	contentAggregate.insertIntermediate = function (inFrontOfIdeaId, title) {
		if (contentAggregate.id === inFrontOfIdeaId) {
			return false;
		}
		var childRank, oldIdea, newIdea, parentIdea = contentAggregate.findParent(inFrontOfIdeaId);
		if (!parentIdea) {
			return false;
		}
		childRank = parentIdea.findChildRankById(inFrontOfIdeaId);
		if (!childRank) {
			return false;
		}
		oldIdea = parentIdea.ideas[childRank];
		newIdea = init({
			title: title
		});
		parentIdea.ideas[childRank] = newIdea;
		newIdea.ideas = {
			1: oldIdea
		};
		contentAggregate.dispatchEvent('changed', 'insertIntermediate', [inFrontOfIdeaId, title, newIdea.id]);
		return true;
	};
	contentAggregate.changeParent = function (ideaId, newParentId) {
		if (ideaId === newParentId) {
			return false;
		}
		var idea, parent = findIdeaById(newParentId);
		if (!parent) {
			return false;
		}
		idea = contentAggregate.findSubIdeaById(ideaId);
		if (!idea) {
			return false;
		}
		if (idea.findSubIdeaById(newParentId)) {
			return false;
		}
		if (parent.containsDirectChild(ideaId)) {
			return false;
		}
		traverseAndRemoveIdea(contentAggregate, ideaId);
		if (!idea) {
			return false;
		}
		appendSubIdea(parent, idea);
		contentAggregate.dispatchEvent('changed', 'changeParent', [ideaId, newParentId]);
		return true;
	};
	contentAggregate.updateStyle = function (ideaId, styleName, styleValue) {
		var idea = findIdeaById(ideaId);
		if (!idea) {
			return false;
		}
		idea.style = idea.style || {};
		if (styleValue) {
			idea.style[styleName] = styleValue;
		} else {
			delete idea.style[styleName];
		}
		if (_.size(idea.style) === 0) {
			delete idea.style;
		}
		contentAggregate.dispatchEvent('changed', 'updateStyle', [ideaId, styleName, styleValue]);
		return true;
	};
	contentAggregate.positionBefore = function (ideaId, positionBeforeIdeaId, parentIdea) {
		parentIdea = parentIdea || contentAggregate;
		var new_rank, after_rank, sibling_ranks, candidate_siblings, before_rank, max_rank, current_rank;
		current_rank = parentIdea.findChildRankById(ideaId);
		if (!current_rank) {
			return _.reduce(
				parentIdea.ideas,
				function (result, idea) {
					return result || contentAggregate.positionBefore(ideaId, positionBeforeIdeaId, idea);
				},
				false
			);
		}
		if (ideaId === positionBeforeIdeaId) {
			return false;
		}
		new_rank = 0;
		if (positionBeforeIdeaId) {
			after_rank = parentIdea.findChildRankById(positionBeforeIdeaId);
			if (!after_rank) {
				return false;
			}
			sibling_ranks = sameSideSiblingRanks(parentIdea, current_rank);
			candidate_siblings = _.reject(_.sortBy(sibling_ranks, Math.abs), function (k) {
				return Math.abs(k) >= Math.abs(after_rank);
			});
			before_rank = candidate_siblings.length > 0 ? _.max(candidate_siblings, Math.abs) : 0;
			if (before_rank === current_rank) {
				return false;
			}
			new_rank = before_rank + (after_rank - before_rank) / 2;
		} else {
			max_rank = maxKey(parentIdea.ideas, current_rank < 0 ? -1 : 1);
			if (max_rank === current_rank) {
				return false;
			}
			new_rank = max_rank + 10 * (current_rank < 0 ? -1 : 1);
		}
		if (new_rank === current_rank) {
			return false;
		}
		parentIdea.ideas[new_rank] = parentIdea.ideas[current_rank];
		delete parentIdea.ideas[current_rank];
		contentAggregate.dispatchEvent('changed', 'positionBefore', [ideaId, positionBeforeIdeaId]);
		return true;
	};
	init(contentAggregate);
	return observable(contentAggregate);
};
<|endoftext|>


<commit_before>chrome.runtime.sendMessage({'message': "ping"});

chrome.runtime.sendMessage({method: "getToken"}, function(response) {
    token = response.token;
});

var getApiUrl = function(token, url) {
    return 'https://api.diffbot.com/v3/article?html&token=' + token + '&url=' + encodeURIComponent(url);
};

var recrunId = '_recrun';

var getOverlay = function() {
    return document.getElementById(recrunId);
};

var getRecrunDoc = function() {
    var iframe = document.getElementById(recrunId);
    return iframe.contentWindow.document;
};

var getRecrunElementById = function(id) {
    return getRecrunDoc().getElementById(id);
};

var recrunShow = function(id) {
    $(getRecrunElementById(id)).show();
};

var recrunHide = function(id) {
    $(getRecrunElementById(id)).hide();
};

var overlay = null;
var bPopup = function(callback) {
    overlay = $('#' + recrunId).bPopup({
        zIndex: 2147483647,
        position: ['auto', '0px'],
        positionStyle: 'fixed'
    }, function() {
        var intervalId = setInterval(function() {
            if (getRecrunDoc().readyState === 'complete') {
                clearInterval(intervalId);
                callback();
            }
        }, 100);
    });
};
function receiveMessage(event) {
    if (event.data === 'close'
          && event.origin === (new URL(chrome.extension.getURL(''))).origin
          && overlay) {
        overlay.close();
    }
}
window.addEventListener("message", receiveMessage, false);

var setPropertyImp = function(element, key, val) {
    // have to use setProperty for setting !important. This doesn't work: span.style.backgroundColor = 'yellow !important';
    element.style.setProperty(key, val, 'important');
};

// gets the overlay or creates it if it doesn't exist
var createOverlay = function() {
    var body = document.body;

    var iframe = document.createElement('iframe');
    var src = 'src/iframe.html';
    var hash = '#' + encodeURIComponent(location.href);
    iframe.src = chrome.extension.getURL(src + hash);
    iframe.setAttribute('id', recrunId);

    iframe.style.display = 'none'; // don't make this !important, or it won't change

    setPropertyImp(iframe, 'padding', '6px');
    setPropertyImp(iframe, 'margin-top', '1%');
    setPropertyImp(iframe, 'margin-bottom', '1%');
    setPropertyImp(iframe, 'width', '800px');
    setPropertyImp(iframe, 'height', '95%');
    setPropertyImp(iframe, 'border-radius', '3px');
    setPropertyImp(iframe, 'background-color', '#f3f2ee');
    setPropertyImp(iframe, 'border', '1px solid #ccc');

    body.appendChild(iframe);
    return iframe;
};

// have to store response here. recalling bpopup relaods the iframe,
// losing its content.
var resp = null;

var token = ''; // have to update token when this script is run and when user updates token.
                // there is no synchronous way that you're aware of to get the token from
                // local storage right before making an API call.

var recrun = function() {
    if (!getOverlay())
        createOverlay();

    var show = function() {
        recrunHide('recrun-loader');
        if (resp) {
            var doc = getRecrunDoc(); // recrun document
            var article = resp[0];
            var fields = ['title', 'author', 'date'];
            for (var i = 0; i < fields.length; i++) {
                var field = fields[i];
                var e = getRecrunElementById('recrun-' + field);
                if (field in article && e && doc) {
                    e.appendChild(doc.createTextNode(article[field]));
                }
            }

            var e = getRecrunElementById('recrun-html');

            if ('images' in article && e) {
                var images = article['images'];
                for (var i = 0; i < images.length; i++) {
                    var image = images[i];
                    if ('primary' in image
                            && image['primary'] === true
                            && 'url' in image
                            && (image['url'].startsWith('http://')
                                    || image['url'].startsWith('https://'))
                            && doc) {
                        var img = doc.createElement('img');
                        img.src = image['url'];
                        e.appendChild(img);
                        break;
                    }
                }
            }

            if ('text' in article && e && doc) {
                var text = article['text'];
                var paragraphs = text.split(/\n/g);
                for (var i = 0; i < paragraphs.length; i++) {
                    var p = doc.createElement('p');
                    p.appendChild(doc.createTextNode(paragraphs[i]));
                    e.appendChild(p);
                }
            }

            recrunShow('recrun-apiresponse');
        } else {
            recrunShow('recrun-error');
        }
    };

    if (resp) {
        bPopup(show);
    } else {
        bPopup(function() {
            recrunHide('recrun-apiresponse');
            recrunHide('recrun-error');
            recrunShow('recrun-loader');
            // missing token will return an error from Diffbot
            var url = document.location.href;
            var xhr = new XMLHttpRequest();
            var apiUrl = getApiUrl(token, url);
            xhr.open("GET", apiUrl, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    var status = xhr.status;
                    if (status === 200) {
                        var _resp = JSON.parse(xhr.responseText);
                        if (!('error' in _resp)
                                && 'objects' in _resp
                                && _resp['objects'].length > 0) {
                            var articles = [];
                            for (var i = 0; i < _resp['objects'].length; i++) {
                                var object = _resp['objects'][i];
                                if ('type' in object && object['type'] === 'article') {
                                    articles.push(object);
                                }
                            }
                            if (articles.length > 0)
                                resp = articles;
                        }
                    }
                    show();
                }
            };
            xhr.send();
        });
    }
};

chrome.runtime.onMessage.addListener(function(request) {
    if (request.method == "recrun") {
        recrun();
    } else if (request.method == "updateToken") {
        token = request.token;
    }
});

<commit_msg>clicking recrun icon when overlay is open causes overlay to close<commit_after>chrome.runtime.sendMessage({'message': "ping"});

chrome.runtime.sendMessage({method: "getToken"}, function(response) {
    token = response.token;
});

var getApiUrl = function(token, url) {
    return 'https://api.diffbot.com/v3/article?html&token=' + token + '&url=' + encodeURIComponent(url);
};

var recrunId = '_recrun';

var getOverlay = function() {
    return document.getElementById(recrunId);
};

var getRecrunDoc = function() {
    var iframe = document.getElementById(recrunId);
    return iframe.contentWindow.document;
};

var getRecrunElementById = function(id) {
    return getRecrunDoc().getElementById(id);
};

var recrunShow = function(id) {
    $(getRecrunElementById(id)).show();
};

var recrunHide = function(id) {
    $(getRecrunElementById(id)).hide();
};

var overlay = null;
var bPopup = function(callback) {
    overlay = $('#' + recrunId).bPopup({
        zIndex: 2147483647,
        position: ['auto', '0px'],
        positionStyle: 'fixed'
    }, function() {
        var intervalId = setInterval(function() {
            if (getRecrunDoc().readyState === 'complete') {
                clearInterval(intervalId);
                callback();
            }
        }, 100);
    });
};
function receiveMessage(event) {
    if (event.data === 'close'
          && event.origin === (new URL(chrome.extension.getURL(''))).origin
          && overlay) {
        overlay.close();
    }
}
window.addEventListener("message", receiveMessage, false);

var setPropertyImp = function(element, key, val) {
    // have to use setProperty for setting !important. This doesn't work: span.style.backgroundColor = 'yellow !important';
    element.style.setProperty(key, val, 'important');
};

// gets the overlay or creates it if it doesn't exist
var createOverlay = function() {
    var body = document.body;

    var iframe = document.createElement('iframe');
    var src = 'src/iframe.html';
    var hash = '#' + encodeURIComponent(location.href);
    iframe.src = chrome.extension.getURL(src + hash);
    iframe.setAttribute('id', recrunId);

    iframe.style.display = 'none'; // don't make this !important, or it won't change

    setPropertyImp(iframe, 'padding', '6px');
    setPropertyImp(iframe, 'margin-top', '1%');
    setPropertyImp(iframe, 'margin-bottom', '1%');
    setPropertyImp(iframe, 'width', '800px');
    setPropertyImp(iframe, 'height', '95%');
    setPropertyImp(iframe, 'border-radius', '3px');
    setPropertyImp(iframe, 'background-color', '#f3f2ee');
    setPropertyImp(iframe, 'border', '1px solid #ccc');

    body.appendChild(iframe);
    return iframe;
};

// have to store response here. recalling bpopup relaods the iframe,
// losing its content.
var resp = null;

var token = ''; // have to update token when this script is run and when user updates token.
                // there is no synchronous way that you're aware of to get the token from
                // local storage right before making an API call.

var overlayOpen = function() {
    return overlay && (document.getElementsByClassName('b-modal').length > 0);
};

var recrun = function() {
    if (overlayOpen()) {
        overlay.close();
        return;
    }

    if (!getOverlay())
        createOverlay();

    var show = function() {
        recrunHide('recrun-loader');
        if (resp) {
            var doc = getRecrunDoc(); // recrun document
            var article = resp[0];
            var fields = ['title', 'author', 'date'];
            for (var i = 0; i < fields.length; i++) {
                var field = fields[i];
                var e = getRecrunElementById('recrun-' + field);
                if (field in article && e && doc) {
                    e.appendChild(doc.createTextNode(article[field]));
                }
            }

            var e = getRecrunElementById('recrun-html');

            if ('images' in article && e) {
                var images = article['images'];
                for (var i = 0; i < images.length; i++) {
                    var image = images[i];
                    if ('primary' in image
                            && image['primary'] === true
                            && 'url' in image
                            && (image['url'].startsWith('http://')
                                    || image['url'].startsWith('https://'))
                            && doc) {
                        var img = doc.createElement('img');
                        img.src = image['url'];
                        e.appendChild(img);
                        break;
                    }
                }
            }

            if ('text' in article && e && doc) {
                var text = article['text'];
                var paragraphs = text.split(/\n/g);
                for (var i = 0; i < paragraphs.length; i++) {
                    var p = doc.createElement('p');
                    p.appendChild(doc.createTextNode(paragraphs[i]));
                    e.appendChild(p);
                }
            }

            recrunShow('recrun-apiresponse');
        } else {
            recrunShow('recrun-error');
        }
    };

    if (resp) {
        bPopup(show);
    } else {
        bPopup(function() {
            recrunHide('recrun-apiresponse');
            recrunHide('recrun-error');
            recrunShow('recrun-loader');
            // missing token will return an error from Diffbot
            var url = document.location.href;
            var xhr = new XMLHttpRequest();
            var apiUrl = getApiUrl(token, url);
            xhr.open("GET", apiUrl, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) {
                    var status = xhr.status;
                    if (status === 200) {
                        var _resp = JSON.parse(xhr.responseText);
                        if (!('error' in _resp)
                                && 'objects' in _resp
                                && _resp['objects'].length > 0) {
                            var articles = [];
                            for (var i = 0; i < _resp['objects'].length; i++) {
                                var object = _resp['objects'][i];
                                if ('type' in object && object['type'] === 'article') {
                                    articles.push(object);
                                }
                            }
                            if (articles.length > 0)
                                resp = articles;
                        }
                    }
                    show();
                }
            };
            xhr.send();
        });
    }
};

chrome.runtime.onMessage.addListener(function(request) {
    if (request.method == "recrun") {
        recrun();
    } else if (request.method == "updateToken") {
        token = request.token;
    }
});

<|endoftext|>