<commit_before>	/**
     * Url
     *
     * @constructor
     * @param {String} url
     */
    Uri = function () {
        var args = arguments, args_callee = args.callee, args_length = args.length,
            parsed_uri, scheme, host, port, path, query, anchor,
            parser = /^([^:\/?#]+?:\/\/)*([^\/:?#]*)?(:[^\/?#]*)*([^?#]*)(\?[^#]*)?(#(.*))*/
            Uri = this;

        if (!(this instanceof args_callee)) {
            return new args_callee(args);
        }

        Uri.scheme = '';
        Uri.host = '';
        Uri.port = '';
        Uri.path = '';
        Uri.query = new QueryString();
        Uri.anchor = '';

        if (args_length > 0 && args[0] !== NULL) {
            parsed_uri = args[0].match(parser);

            scheme = parsed_uri[1];
            host = parsed_uri[2];
            port = parsed_uri[3];
            path = parsed_uri[4];
            query = parsed_uri[5];
            anchor = parsed_uri[6];

            scheme = (scheme !== UNDEFINED) ? scheme.replace('://', '').toLowerCase() : 'http';
            port = (port ? port.replace(':', '') : (scheme === 'https' ? '443' : '80'));
            // correct the scheme based on port number
            scheme = (scheme == 'http' && port === '443' ? 'https' : scheme);
            query = query ? query.replace('?', '') : '';
            anchor = anchor ? anchor.replace('#', '') : '';

            // Fix the host name to include port if non-standard ports were given
            if ((scheme === 'https' && port !== '443') || (scheme === 'http' && port !== '80')) {
                host = host + ':' + port;
            }

            Uri.scheme = scheme;
            Uri.host = host;
            Uri.port = port;
            Uri.path = (path !== UNDEFINED) ? path : '/';
            Uri.query.setQueryParams(query);
            Uri.anchor = (anchor !== UNDEFINED) ? anchor : '';
        }
        /**
         * Returns the url string
         *
         * @memberOf Uri
         * @return {String}
         */
        Uri.toString = function () {
            var query = this.query.asString();
            return this.scheme + '://' + this.host + this.path +
                (query != '' ? '?' + query : '') +
                (this.anchor !== '' ? '#' + this.anchor : '');
        };
    };

    /**
     * Create and manage a query string
     *
     * @param {Object} obj
     */
    QueryString = function(obj){
        var args = arguments, args_callee = args.callee, args_length = args.length,
            i, querystring = this;

        if (!(this instanceof args_callee)) {
            return new args_callee(obj);
        }

        for(i in obj) {
            if (obj.hasOwnProperty(i)) {
                querystring[i] = obj[i];
            }
        }

        return querystring;
    };
    // QueryString is a type of collection So inherit
    QueryString.prototype = new Collection();

    QueryString.prototype.asString = function () {
        var i, self = this, q_arr = [], ret = '',
        val = EMPTY_STRING, encode = QueryString.urlEncode;
        self.ksort(); // lexicographical byte value ordering of the keys

        for (i in self) {
            if (self.hasOwnProperty(i)) {
                val = (encode(i) + '=' + encode(self[i]));
                q_arr.push(val);
            }
        }

        if (q_arr.length > 0) {
            ret = q_arr.join('&');
        }

        return ret;
    };

    /**
     *
     * @param {Object} query
     */
    QueryString.prototype.setQueryParams = function (query) {
        var args = arguments, args_length = args.length, i, query_array,
            query_array_length, querystring = this, key_value;

        if (args_length == 1) {
            if (typeof query === TYPEOF_OBJECT) {
                // iterate
                for (i in query) {
                    if (query.hasOwnProperty(i)) {
                        querystring[i] = query[i];
                    }
                }
            } else if (typeof query === TYPEOF_STRING) {
                // split string on '&'
                query_array = query.split('&');
                // iterate over each of the array items
                for (i = 0, query_array_length = query_array.length; i < query_array_length; i++) {
                    // split on '=' to get key, value
                    key_value = query_array[i].split('=');
                    querystring[key_value[0]] = key_value[1];
                }
            }
        } else {
            for (i = 0; i < arg_length; i += 2) {
                // treat each arg as key, then value
                querystring[args[i]] = args[i+1];
            }
        }
    };

    /**
     * rfc3986 compatable encode of a string
     *
     * @param {String} string
     */
    QueryString.urlEncode = function (string){
        var reserved_chars = /( |\!|\*|\"|\'|\(|\)|\;|\:|\@|\&|\=|\+|\$|\,|\/|\?|\%|\#|\[|\]|\<|\>|\{|\}|\||\\|`|\^)/,
            str_len = string.length, i, string_arr = string.split('');

        for (i = 0; i < str_len; i++) {
            if (string_arr[i].match(reserved_chars)) {
                string_arr[i] = '%' + (string_arr[i].charCodeAt(0)).toString(16).toUpperCase();
            }
        }

        return string_arr.join('');
    };

    // So we can access it outside, but needs to be related to Uris
    Uri.QueryString = QueryString;

    /** closure compiler "export" method, use quoted syntax */
    if (window['Uri'] === UNDEFINED) {
        // Only give to the world if they want it
        window['Uri'] = Uri
    }
<commit_msg>protection against undefined<commit_after>	/**
     * Url
     *
     * @constructor
     * @param {String} url
     */
    Uri = function () {
        var args = arguments, args_callee = args.callee, args_length = args.length,
            parsed_uri, scheme, host, port, path, query, anchor,
            parser = /^([^:\/?#]+?:\/\/)*([^\/:?#]*)?(:[^\/?#]*)*([^?#]*)(\?[^#]*)?(#(.*))*/
            Uri = this;

        if (!(this instanceof args_callee)) {
            return new args_callee(args);
        }

        Uri.scheme = '';
        Uri.host = '';
        Uri.port = '';
        Uri.path = '';
        Uri.query = new QueryString();
        Uri.anchor = '';

        if (args_length > 0 && args[0] !== NULL) {
            parsed_uri = args[0].match(parser);

            scheme = parsed_uri[1];
            host = parsed_uri[2];
            port = parsed_uri[3];
            path = parsed_uri[4];
            query = parsed_uri[5];
            anchor = parsed_uri[6];

            scheme = (scheme !== UNDEFINED) ? scheme.replace('://', '').toLowerCase() : 'http';
            port = (port ? port.replace(':', '') : (scheme === 'https' ? '443' : '80'));
            // correct the scheme based on port number
            scheme = (scheme == 'http' && port === '443' ? 'https' : scheme);
            query = query ? query.replace('?', '') : '';
            anchor = anchor ? anchor.replace('#', '') : '';

            // Fix the host name to include port if non-standard ports were given
            if ((scheme === 'https' && port !== '443') || (scheme === 'http' && port !== '80')) {
                host = host + ':' + port;
            }

            Uri.scheme = scheme;
            Uri.host = host;
            Uri.port = port;
            Uri.path = (path !== UNDEFINED) ? path : '/';
            Uri.query.setQueryParams(query);
            Uri.anchor = (anchor !== UNDEFINED) ? anchor : '';
        }
        /**
         * Returns the url string
         *
         * @memberOf Uri
         * @return {String}
         */
        Uri.toString = function () {
            var query = this.query.asString();
            return this.scheme + '://' + this.host + this.path +
                (query != '' ? '?' + query : '') +
                (this.anchor !== '' ? '#' + this.anchor : '');
        };
    };

    /**
     * Create and manage a query string
     *
     * @param {Object} obj
     */
    QueryString = function(obj){
        var args = arguments, args_callee = args.callee, args_length = args.length,
            i, querystring = this;

        if (!(this instanceof args_callee)) {
            return new args_callee(obj);
        }

        if (obj != UNDEFINED) {
            for (i in obj) {
                if (obj.hasOwnProperty(i)) {
                    querystring[i] = obj[i];
                }
            }
        }

        return querystring;
    };
    // QueryString is a type of collection So inherit
    QueryString.prototype = new Collection();

    QueryString.prototype.asString = function () {
        var i, self = this, q_arr = [], ret = '',
        val = EMPTY_STRING, encode = QueryString.urlEncode;
        self.ksort(); // lexicographical byte value ordering of the keys

        for (i in self) {
            if (self.hasOwnProperty(i)) {
                if (i != UNDEFINED && self[i] != UNDEFINED) {
                    val = (encode(i) + '=' + encode(self[i]));
                }
                q_arr.push(val);
            }
        }

        if (q_arr.length > 0) {
            ret = q_arr.join('&');
        }

        return ret;
    };

    /**
     *
     * @param {Object} query
     */
    QueryString.prototype.setQueryParams = function (query) {
        var args = arguments, args_length = args.length, i, query_array,
            query_array_length, querystring = this, key_value;

        if (args_length == 1) {
            if (typeof query === TYPEOF_OBJECT) {
                // iterate
                for (i in query) {
                    if (query.hasOwnProperty(i)) {
                        querystring[i] = query[i];
                    }
                }
            } else if (typeof query === TYPEOF_STRING) {
                // split string on '&'
                query_array = query.split('&');
                // iterate over each of the array items
                for (i = 0, query_array_length = query_array.length; i < query_array_length; i++) {
                    // split on '=' to get key, value
                    key_value = query_array[i].split('=');
                    querystring[key_value[0]] = key_value[1];
                }
            }
        } else {
            for (i = 0; i < arg_length; i += 2) {
                // treat each arg as key, then value
                querystring[args[i]] = args[i+1];
            }
        }
    };

    /**
     * rfc3986 compatable encode of a string
     *
     * @param {String} string
     */
    QueryString.urlEncode = function (string){
        var reserved_chars = /( |\!|\*|\"|\'|\(|\)|\;|\:|\@|\&|\=|\+|\$|\,|\/|\?|\%|\#|\[|\]|\<|\>|\{|\}|\||\\|`|\^)/,
            str_len = string.length, i, string_arr = string.split('');

        for (i = 0; i < str_len; i++) {
            if (string_arr[i].match(reserved_chars)) {
                string_arr[i] = '%' + (string_arr[i].charCodeAt(0)).toString(16).toUpperCase();
            }
        }

        return string_arr.join('');
    };

    // So we can access it outside, but needs to be related to Uris
    Uri.QueryString = QueryString;

    /** closure compiler "export" method, use quoted syntax */
    if (window['Uri'] === UNDEFINED) {
        // Only give to the world if they want it
        window['Uri'] = Uri
    }
<|endoftext|>


<commit_before>/*!
 * Copyright (c) 2015-2016 Jessica Tallon & Matt Molyneaux
 * Licensed under AGPLv3 (https://github.com/Inboxen/Inboxen/blob/master/LICENSE)
 */

(function($){
    'use strict';

    var pinned_label = 'Pinned';

    function TogglePinned($row) {
        if ($row.find("span.label-warning").length === 0) {
           $row.find("div.inbox-flags").append(pinned_label);
        } else {
            $row.find("span.label-warning").remove();
        }
    }

    $(".inbox-options button[type=submit]").click(function(event) {
        event.preventDefault();

        var $this = $(this);
        if ($this.data("clicked") === "yes") {
            return false;
        }

        $this.data("clicked", "yes");
        $this.addClass("disabled");
        $this.children("span.fa").addClass("fa-spinner fa-spin");

        var button = {"name": $this.attr("name"), "value": $this.attr("value")};
        var $form = $this.parent("form");
        var form_data = $form.serializeArray();
        form_data.push(button);

        $.ajax({
            type: "POST",
            url: $this.parent("form").data("url"),
            data: form_data,
            complete: function(xhr, statusText) {
                if (xhr.status === 204) {
                    var $row = $("#" + $form.data("inbox-selector"));
                    if (button.name === "pin-inbox") {
                        TogglePinned($row);
                    } else {
                        // don't know what was pressed
                        return
                    }
                } else {
                    var $messageBlock = $("#alertmessages");
                    var message = '
Something went wrong!<button type="button" class="close" data-dismiss="alert">Close</button>
';
                    $messageBlock.append(message);
                }

                // finally, re-enable button
                $this.data("clicked", "no");
                $this.removeClass("disabled");
                $this.children("span.fa").removeClass("fa-spinner fa-spin");
            }
        });
    });
})(jQuery);

(function($){
    'use strict';

    function initForm($form, completeCallback) {
        $form.submit(function(event) {
            event.preventDefault();
            var $this;

            $this = $(this);
            $this.$form = $form;

            if ($this.data("clicked") === "yes") {
                return false;
            }

            $this.data("clicked", "yes");
            $this.find("button").prop("disabled", true).addClass("disabled");
            $this.children("button span.fa").addClass("fa-spinner fa-spin");
            $this.find("a.btn").addClass("disabled");

            $.ajax({
                type: "POST",
                url: $this.attr('action'),
                data: $this.serializeArray(),
                complete: completeCallback.bind($this)
            });
        });
    }

    function homeFormComplete(xhr, statusText) {
        var description, inboxSelector, is_disabled, is_pinned, $row;

        inboxSelector = this.$form.data("inbox-selector");
        $row = $("#" + inboxSelector + " + .row");
        description = this.find("#id_description").val();
        is_disabled = this.find("#id_disable_inbox").prop("checked");
        is_pinned = this.find("#id_pinned").prop("checked");

        if (xhr.status === 204) {
            var $inbox_row = $("#" + inboxSelector);
            var $description_cell = $inbox_row.find(".inbox-description");

            $description_cell.text(description);

            if (is_disabled && !$inbox_row.hasClass("inbox-disabled")) {
                $inbox_row.addClass("inbox-disabled");
                $inbox_row.find(".inbox-flags").empty();
                $inbox_row.find(".inbox-flags").append("
Disabled
");
            } else if (!is_disabled && $inbox_row.hasClass("inbox-disabled")) {
                $inbox_row.removeClass("inbox-disabled");
                $inbox_row.find(".inbox-flags").empty();
            } else if (is_pinned && !is_disabled && $inbox_row.find("span.label-warning").length === 0) {
               $inbox_row.find(".inbox-flags").append('
Pinned
');
            } else if (!is_pinned && !is_disabled) {
                $inbox_row.find("span.label-warning").remove();
            }

            $row.remove();
        } else if (xhr.status === 200) {
            this.$form.html(xhr.responseText);
            initForm(this.$form, homeFormComplete);
            $row.find("a").click(function() {
                $row.remove();
            });
        } else {
            this.$form.html("
Sorry, something went wrong.
");
            console.log("Form for " + inboxSelector + " failed to POST (" + xhr.status + ")");
        }
    }

    function inboxFormComplete(xhr, statusText) {
        if (xhr.status === 204) {
            this.$form.parents(".inbox-edit-form-row").remove();
        } else {
            if (xhr.status === 200) {
                this.$form.html(xhr.responseText);
                initForm(this.$form, inboxFormComplete);
                this.$form.parents(".inbox-edit-form-row").find("a").click(function() {
                    this.$form.parents(".inbox-edit-form-row").remove();
                }.bind(this));
            } else {
                this.$form.html("
Sorry, something went wrong.
");
                console.log("Form failed to POST (" + xhr.status + ")");
            }
        }
    }

    function addInboxComplete(xhr, statusText) {
        if (xhr.status === 204) {
            // TODO: add an alert message
            $("#inbox-add-form").remove();

            // hacky, but this will have to do for now
            document.location.reload(true);
        } else {
            if (xhr.status === 200) {
                this.$form.html(xhr.responseText);
                initForm(this.$form, addInboxComplete);
                $("#inbox-add-form").find("a").click(function() {
                    $("#inbox-add-form").remove();
                });
            } else {
                this.$form.html("
Sorry, something went wrong.
");
                console.log("Form failed to POST (" + xhr.status + ")");
            }
        }
    }

    // adds event listeners for inline forms to be popped in
    $("#inbox-list .inbox-options a").click(function() {
        // option buttons on inbox list
        var $this = $(this);
        var $row = $this.parents("div.row:has(.inbox-name)");
        var formURL = "/forms/inbox/edit/" + $row.attr("id") + "/";

        if (!$row.next().hasClass("inbox-edit-form-row")) {
            if ($this.data("clicked") === "yes") {
                return false;
            }

            $this.data("clicked", "yes");
            $this.addClass("disabled");
            $this.children("span.fa").addClass("fa-spinner fa-spin");

            $.get(formURL, function(data) {
                // double check
                if (!$row.next().hasClass("inbox-edit-form-row")) {
                    $row.after("

" + data + "

");
                    initForm($row.next().find("form"), homeFormComplete);
                    $row.next().find("a").click(function() {
                        $row.next().remove();
                    });
                }

                // finally, re-enable button
                $this.data("clicked", "no");
                $this.removeClass("disabled");
                $this.children("span.fa").removeClass("fa-spinner fa-spin");
            });
        } else if ($row.next().hasClass("inbox-edit-form-row")) {
            $row.next().remove();
        }
        return false;
    });

    $("#email-list .inbox-edit").click(function() {
        // option button on inbox page
        var $this = $(this);
        var $table = $(".honeydew");
        var formURL = "/forms/inbox/edit/" + $this.data("inbox-id") + "/";

        if (!$table.children(":first").hasClass("inbox-edit-form-row")) {
            if ($this.data("clicked") === "yes") {
                return false;
            }

            $this.data("clicked", "yes");
            $this.addClass("disabled");
            $this.children("span.fa").addClass("fa-spinner fa-spin");

            $.get(formURL, function(data) {
                // double check
                if (!$table.children(":first").hasClass("inbox-edit-form-row")) {
                    $table.prepend("

" + data + "

");
                    initForm($table.children(":first").find("form"), inboxFormComplete);
                    $table.children(":first").find("a").click(function() {
                        $table.children(":first").remove();
                    });
                }

                // finally, re-enable button
                $this.data("clicked", "no");
                $this.removeClass("disabled");
                $this.children("span.fa").removeClass("fa-spinner fa-spin");
            });
        } else if ($table.children(":first").hasClass("inbox-edit-form-row")) {
            $table.children(":first").remove();
        }
        return false;
    });

    $("#add-inbox").click(function() {
        var $this = $(this);
        var $nav = $("#navbar-container");

        if ($this.data("clicked") === "yes") {
            return false;
        }

        $this.data("clicked", "yes");

        $.get($this.data("form-url"), function(data) {
            var $addForm;
            // double check
            if ($("#inbox-add-form").length === 0) {
                $addForm = $("

" + data + "

");
                $nav.after($addForm);
                initForm($addForm.find("form"), addInboxComplete);
                $addForm.find("a").click(function() {
                    $addForm.remove();
                });
            }
        });
        return false;
    });
})(jQuery);
<commit_msg>Don't remove add inbox form on submit<commit_after>/*!
 * Copyright (c) 2015-2016 Jessica Tallon & Matt Molyneaux
 * Licensed under AGPLv3 (https://github.com/Inboxen/Inboxen/blob/master/LICENSE)
 */

(function($){
    'use strict';

    var pinned_label = 'Pinned';

    function TogglePinned($row) {
        if ($row.find("span.label-warning").length === 0) {
           $row.find("div.inbox-flags").append(pinned_label);
        } else {
            $row.find("span.label-warning").remove();
        }
    }

    $(".inbox-options button[type=submit]").click(function(event) {
        event.preventDefault();

        var $this = $(this);
        if ($this.data("clicked") === "yes") {
            return false;
        }

        $this.data("clicked", "yes");
        $this.addClass("disabled");
        $this.children("span.fa").addClass("fa-spinner fa-spin");

        var button = {"name": $this.attr("name"), "value": $this.attr("value")};
        var $form = $this.parent("form");
        var form_data = $form.serializeArray();
        form_data.push(button);

        $.ajax({
            type: "POST",
            url: $this.parent("form").data("url"),
            data: form_data,
            complete: function(xhr, statusText) {
                if (xhr.status === 204) {
                    var $row = $("#" + $form.data("inbox-selector"));
                    if (button.name === "pin-inbox") {
                        TogglePinned($row);
                    } else {
                        // don't know what was pressed
                        return
                    }
                } else {
                    var $messageBlock = $("#alertmessages");
                    var message = '
Something went wrong!<button type="button" class="close" data-dismiss="alert">Close</button>
';
                    $messageBlock.append(message);
                }

                // finally, re-enable button
                $this.data("clicked", "no");
                $this.removeClass("disabled");
                $this.children("span.fa").removeClass("fa-spinner fa-spin");
            }
        });
    });
})(jQuery);

(function($){
    'use strict';

    function initForm($form, completeCallback) {
        $form.submit(function(event) {
            event.preventDefault();
            var $this;

            $this = $(this);
            $this.$form = $form;

            if ($this.data("clicked") === "yes") {
                return false;
            }

            $this.data("clicked", "yes");
            $this.find("button").prop("disabled", true).addClass("disabled");
            $this.children("button span.fa").addClass("fa-spinner fa-spin");
            $this.find("a.btn").addClass("disabled");

            $.ajax({
                type: "POST",
                url: $this.attr('action'),
                data: $this.serializeArray(),
                complete: completeCallback.bind($this)
            });
        });
    }

    function homeFormComplete(xhr, statusText) {
        var description, inboxSelector, is_disabled, is_pinned, $row;

        inboxSelector = this.$form.data("inbox-selector");
        $row = $("#" + inboxSelector + " + .row");
        description = this.find("#id_description").val();
        is_disabled = this.find("#id_disable_inbox").prop("checked");
        is_pinned = this.find("#id_pinned").prop("checked");

        if (xhr.status === 204) {
            var $inbox_row = $("#" + inboxSelector);
            var $description_cell = $inbox_row.find(".inbox-description");

            $description_cell.text(description);

            if (is_disabled && !$inbox_row.hasClass("inbox-disabled")) {
                $inbox_row.addClass("inbox-disabled");
                $inbox_row.find(".inbox-flags").empty();
                $inbox_row.find(".inbox-flags").append("
Disabled
");
            } else if (!is_disabled && $inbox_row.hasClass("inbox-disabled")) {
                $inbox_row.removeClass("inbox-disabled");
                $inbox_row.find(".inbox-flags").empty();
            } else if (is_pinned && !is_disabled && $inbox_row.find("span.label-warning").length === 0) {
               $inbox_row.find(".inbox-flags").append('
Pinned
');
            } else if (!is_pinned && !is_disabled) {
                $inbox_row.find("span.label-warning").remove();
            }

            $row.remove();
        } else if (xhr.status === 200) {
            this.$form.html(xhr.responseText);
            initForm(this.$form, homeFormComplete);
            $row.find("a").click(function() {
                $row.remove();
            });
        } else {
            this.$form.html("
Sorry, something went wrong.
");
            console.log("Form for " + inboxSelector + " failed to POST (" + xhr.status + ")");
        }
    }

    function inboxFormComplete(xhr, statusText) {
        if (xhr.status === 204) {
            this.$form.parents(".inbox-edit-form-row").remove();
        } else {
            if (xhr.status === 200) {
                this.$form.html(xhr.responseText);
                initForm(this.$form, inboxFormComplete);
                this.$form.parents(".inbox-edit-form-row").find("a").click(function() {
                    this.$form.parents(".inbox-edit-form-row").remove();
                }.bind(this));
            } else {
                this.$form.html("
Sorry, something went wrong.
");
                console.log("Form failed to POST (" + xhr.status + ")");
            }
        }
    }

    function addInboxComplete(xhr, statusText) {
        if (xhr.status === 204) {
            // hacky, but this will have to do for now
            // in fact very hacky as it will lock up the window!
            document.location.reload(true);
        } else {
            if (xhr.status === 200) {
                this.$form.html(xhr.responseText);
                initForm(this.$form, addInboxComplete);
                $("#inbox-add-form").find("a").click(function() {
                    $("#inbox-add-form").remove();
                });
            } else {
                this.$form.html("
Sorry, something went wrong.
");
                console.log("Form failed to POST (" + xhr.status + ")");
            }
        }
    }

    // adds event listeners for inline forms to be popped in
    $("#inbox-list .inbox-options a").click(function() {
        // option buttons on inbox list
        var $this = $(this);
        var $row = $this.parents("div.row:has(.inbox-name)");
        var formURL = "/forms/inbox/edit/" + $row.attr("id") + "/";

        if (!$row.next().hasClass("inbox-edit-form-row")) {
            if ($this.data("clicked") === "yes") {
                return false;
            }

            $this.data("clicked", "yes");
            $this.addClass("disabled");
            $this.children("span.fa").addClass("fa-spinner fa-spin");

            $.get(formURL, function(data) {
                // double check
                if (!$row.next().hasClass("inbox-edit-form-row")) {
                    $row.after("

" + data + "

");
                    initForm($row.next().find("form"), homeFormComplete);
                    $row.next().find("a").click(function() {
                        $row.next().remove();
                    });
                }

                // finally, re-enable button
                $this.data("clicked", "no");
                $this.removeClass("disabled");
                $this.children("span.fa").removeClass("fa-spinner fa-spin");
            });
        } else if ($row.next().hasClass("inbox-edit-form-row")) {
            $row.next().remove();
        }
        return false;
    });

    $("#email-list .inbox-edit").click(function() {
        // option button on inbox page
        var $this = $(this);
        var $table = $(".honeydew");
        var formURL = "/forms/inbox/edit/" + $this.data("inbox-id") + "/";

        if (!$table.children(":first").hasClass("inbox-edit-form-row")) {
            if ($this.data("clicked") === "yes") {
                return false;
            }

            $this.data("clicked", "yes");
            $this.addClass("disabled");
            $this.children("span.fa").addClass("fa-spinner fa-spin");

            $.get(formURL, function(data) {
                // double check
                if (!$table.children(":first").hasClass("inbox-edit-form-row")) {
                    $table.prepend("

" + data + "

");
                    initForm($table.children(":first").find("form"), inboxFormComplete);
                    $table.children(":first").find("a").click(function() {
                        $table.children(":first").remove();
                    });
                }

                // finally, re-enable button
                $this.data("clicked", "no");
                $this.removeClass("disabled");
                $this.children("span.fa").removeClass("fa-spinner fa-spin");
            });
        } else if ($table.children(":first").hasClass("inbox-edit-form-row")) {
            $table.children(":first").remove();
        }
        return false;
    });

    $("#add-inbox").click(function() {
        var $this = $(this);
        var $nav = $("#navbar-container");

        if ($this.data("clicked") === "yes") {
            return false;
        }

        $this.data("clicked", "yes");

        $.get($this.data("form-url"), function(data) {
            var $addForm;
            // double check
            if ($("#inbox-add-form").length === 0) {
                $addForm = $("

" + data + "

");
                $nav.after($addForm);
                initForm($addForm.find("form"), addInboxComplete);
                $addForm.find("a").click(function() {
                    $addForm.remove();
                });
            }
        });
        return false;
    });
})(jQuery);
<|endoftext|>


<commit_before>(function(context, MM) {

    easey.TouchHandler = function() {
      var handler = {};

      handler.add = function(map) {
            var prevT = 0,
                acceleration = 25.0,
                speed = null,
                maxTapTime = 250,
                maxTapDistance = 30,
                maxDoubleTapDelay = 350,
                drag = 0.10,
                locations = {},
                taps = [],
                wasPinching = false,
                nowPoint = null,
                oldPoint = null,
                lastMove = null,
                lastPinchCenter = null;

            function animate(t) {
                var dir = { x: 0, y: 0 };
                var dt = Math.max(0.001,(t - prevT) / 1000.0);
                if (nowPoint && oldPoint &&
                    (lastMove > (+new Date() - 50))) {
                    dir.x = nowPoint.x - oldPoint.x;
                    dir.y = nowPoint.y - oldPoint.y;
                    speed.x = dir.x;
                    speed.y = dir.y;
                } else {
                    speed.x -= speed.x * drag;
                    speed.y -= speed.y * drag;
                    if (Math.abs(speed.x) < 0.001) {
                        speed.x = 0;
                    }
                    if (Math.abs(speed.y) < 0.001) {
                        speed.y = 0;
                    }
                }
                if (speed.x || speed.y) {
                    map.panBy(speed.x, speed.y);
                }
                prevT = t;
                // tick every frame for time-based anim accuracy
                MM.getFrame(animate);
            }

            // Test whether touches are from the same source -
            // whether this is the same touchmove event.
            function sameTouch (event, touch) {
                return (event && event.touch) &&
                    (touch.identifier == event.touch.identifier);
            }

            function updateTouches (e) {
                for (var i = 0; i < e.touches.length; i += 1) {
                    var t = e.touches[i];
                    if (t.identifier in locations) {
                        var l = locations[t.identifier];
                        l.x = t.screenX;
                        l.y = t.screenY;
                        l.scale = e.scale;
                    }
                    else {
                        locations[t.identifier] = {
                            scale: e.scale,
                            startPos: { x: t.screenX, y: t.screenY },
                            x: t.screenX,
                            y: t.screenY,
                            time: new Date().getTime()
                        };
                    }
                }
            }

            function touchStartMachine(e) {
                updateTouches(e);
                return MM.cancelEvent(e);
            }

            function touchMoveMachine(e) {
                switch (e.touches.length) {
                    case 1:
                        onPanning(e.touches[0]);
                        break;
                    case 2:
                        onPinching(e);
                        break;
                }
                updateTouches(e);
                return MM.cancelEvent(e);
            }

            // Fail early if this isn't a touch device.
            // TODO: move to add fn
            if (!isTouchable()) return false;

            MM.addEvent(map.parent, 'touchstart',
                touchStartMachine);
            MM.addEvent(map.parent, 'touchmove',
                touchMoveMachine);
            MM.addEvent(map.parent, 'touchend',
                touchEndMachine);

            prevT = new Date().getTime();
            speed = { x: 0, y: 0 };
            MM.getFrame(animate);

            // Handle a tap event - mainly watch for a doubleTap
            function onTap(tap) {
                if (taps.length &&
                    (tap.time - taps[0].time) < maxDoubleTapDelay) {
                    onDoubleTap(tap);
                    taps = [];
                    return;
                }
                taps = [tap];
            }

            // Handle a double tap by zooming in a single zoom level to a
            // round zoom.
            function onDoubleTap(tap) {
                // zoom in to a round number
                easey.slow(map, {
                    zoom: Math.round(map.getZoom()) + 1,
                    about: new MM.Point(tap.x, tap.y),
                    time: 100
                });
            }

            function isTouchable () {
                 var el = document.createElement('div');
                 el.setAttribute('ongesturestart', 'return;');
                 return (typeof el.ongesturestart === 'function');
            }

            function remove() {
                // Fail early if this isn't a touch device.
                if (!isTouchable()) return false;

                MM.removeEvent(map.parent, 'touchstart',
                    touchStartMachine);
                MM.removeEvent(map.parent, 'touchmove',
                    touchMoveMachine);
                MM.removeEvent(map.parent, 'touchend',
                    touchEndMachine);
            }

            // Re-transform the actual map parent's CSS transformation
            function onPanning(touch) {
                lastMove = +new Date();
                oldPoint = nowPoint;
                nowPoint = { x: touch.screenX, y: touch.screenY };
                // oldPoint = locations[touch.identifier];
            }

            function onPinching(e) {
                // use the first two touches and their previous positions
                var t0 = e.touches[0],
                    t1 = e.touches[1],
                    p0 = new MM.Point(t0.screenX, t0.screenY),
                    p1 = new MM.Point(t1.screenX, t1.screenY),
                    l0 = locations[t0.identifier],
                    l1 = locations[t1.identifier];

                // mark these touches so they aren't used as taps/holds
                l0.wasPinch = true;
                l1.wasPinch = true;

                // scale about the center of these touches
                var center = MM.Point.interpolate(p0, p1, 0.5);

                map.zoomByAbout(
                    Math.log(e.scale) / Math.LN2 -
                    Math.log(l0.scale) / Math.LN2,
                    center);

                // pan from the previous center of these touches
                var prevCenter = MM.Point.interpolate(l0, l1, 0.5);

                map.panBy(center.x - prevCenter.x,
                               center.y - prevCenter.y);
                wasPinching = true;
                lastPinchCenter = center;
            }

            // When a pinch event ends, round the zoom of the map.
            function onPinched(p) {
                // TODO: easing
                if (true) {
                    var z = map.getZoom(), // current zoom
                        tz = Math.round(z);     // target zoom
                    map.zoomByAbout(tz - z, p);
                }
                wasPinching = false;
            }

            function touchEndMachine(e) {
                var now = new Date().getTime();
                // round zoom if we're done pinching
                if (e.touches.length === 0 && wasPinching) {
                    onPinched(lastPinchCenter);
                }

                oldPoint = nowPoint = null;

                // Look at each changed touch in turn.
                for (var i = 0; i < e.changedTouches.length; i += 1) {
                    var t = e.changedTouches[i],
                        loc = locations[t.identifier];
                    // if we didn't see this one (bug?)
                    // or if it was consumed by pinching already
                    // just skip to the next one
                    if (!loc || loc.wasPinch) {
                        continue;
                    }

                    // we now know we have an event object and a
                    // matching touch that's just ended. Let's see
                    // what kind of event it is based on how long it
                    // lasted and how far it moved.
                    var pos = { x: t.screenX, y: t.screenY },
                        time = now - loc.time,
                        travel = MM.Point.distance(pos, loc.startPos);
                    if (travel > maxTapDistance) {
                        // we will to assume that the drag has been handled separately
                    } else if (time > maxTapTime) {
                        // close in space, but not in time: a hold
                        pos.end = now;
                        pos.duration = time;
                        onHold(pos);
                    } else {
                        // close in both time and space: a tap
                        pos.time = now;
                        onTap(pos);
                    }
                }

                // Weird, sometimes an end event doesn't get thrown
                // for a touch that nevertheless has disappeared.
                // Still, this will eventually catch those ids:

                var validTouchIds = {};
                for (var j = 0; j < e.touches.length; j++) {
                    validTouchIds[e.touches[j].identifier] = true;
                }
                for (var id in locations) {
                    if (!(id in validTouchIds)) {
                        delete validTouchIds[id];
                    }
                }

                return MM.cancelEvent(e);
            }
        }
    };

    easey.DoubleClickHandler = function() {
        var handler = {},
            map;

        function doubleClick(e) {
            // Ensure that this handler is attached once.
            // Get the point on the map that was double-clicked
            var point = MM.getMousePoint(e, map);
            z = map.getZoom() + (e.shiftKey ? -1 : 1);
            // use shift-double-click to zoom out
            easey().map(map)
                .to(map.pointCoordinate(MM.getMousePoint(e, map)).zoomTo(z))
                .path('about').run(100);
            return MM.cancelEvent(e);
        }

        handler.add = function(x) {
            map = x;
            MM.addEvent(map.parent, 'dblclick', doubleClick);
            return handler;
        };

        handler.remove = function() {
            MM.removeEvent(map.parent, 'dblclick', doubleClick);
        };

        return handler;
    };

    easey.MouseWheelHandler = function() {
        var handler = {},
            map,
            _zoomDiv,
            ea = easey(),
            prevTime,
            precise = false;

        function mouseWheel(e) {
            var delta = 0;
            prevTime = prevTime || new Date().getTime();

            try {
                _zoomDiv.scrollTop = 1000;
                _zoomDiv.dispatchEvent(e);
                delta = 1000 - _zoomDiv.scrollTop;
            } catch (error) {
                delta = e.wheelDelta || (-e.detail * 5);
            }

            // limit mousewheeling to once every 200ms
            var timeSince = new Date().getTime() - prevTime;
            var point = MM.getMousePoint(e, map);

            if (Math.abs(delta) > 0 && (timeSince > 200) && !precise) {
                map.zoomByAbout(delta > 0 ? 1 : -1, point);
                prevTime = new Date().getTime();
            } else if (precise) {
                map.zoomByAbout(delta * 0.001, point);
            }
            if (!ea.running()) {
              var point = MM.getMousePoint(e, map),
                  z = map.getZoom();
              ea.map(map)
                .to(map.pointCoordinate(MM.getMousePoint(e, map)).zoomTo(z + (delta > 0 ? 1 : -1)))
                .path('about').run(200);
            } else {
                ea.zoom(ea.to().zoom + (delta > 0 ? 1 : -1));
            }

            // Cancel the event so that the page doesn't scroll
            return MM.cancelEvent(e);
        }

        handler.add = function(x) {
            map = x;
            _zoomDiv = document.body.appendChild(document.createElement('div'));
            _zoomDiv.style.cssText = 'visibility:hidden;top:0;height:0;width:0;overflow-y:scroll';
            var innerDiv = _zoomDiv.appendChild(document.createElement('div'));
            innerDiv.style.height = '2000px';
            MM.addEvent(map.parent, 'mousewheel', mouseWheel);
            return handler;
        };

        handler.precise = function(x) {
            if (!arguments.length) return precise;
            precise = x;
            return handler;
        };

        handler.remove = function() {
            MM.removeEvent(map.parent, 'mousewheel', mouseWheel);
            _zoomDiv.parentNode.removeChild(_zoomDiv);
        };

        return handler;
    };

    easey.DragHandler = function() {
        var handler = {},
            map;

        handler.add = function(map) {
            var prevT = 0,
                speed = null,
                drag = 0.15,
                mouseDownPoint = null,
                mouseDownTime = 0,
                mousePoint = null,
                prevMousePoint = null,
                moveTime = null,
                prevMoveTime = null,
                animatedLastPoint = true;

            function mouseDown(e) {
                if (e.shiftKey) return;
                mousePoint = prevMousePoint = MM.getMousePoint(e, map);
                moveTime = prevMoveTime = +new Date();
                map.parent.style.cursor = 'move';
                return MM.cancelEvent(e);
            }

            function mouseMove(e) {
                if (mousePoint) {
                    if (animatedLastPoint) {
                        prevMousePoint = mousePoint;
                        prevMoveTime = moveTime;
                        animatedLastPoint = false;
                    }
                    mousePoint = MM.getMousePoint(e, map);
                    moveTime = +new Date();
                    return MM.cancelEvent(e);
                }
            }

            function mouseUp(e) {
                if (+new Date() - prevMoveTime < 50) {
                    dt = Math.max(1, moveTime - prevMoveTime);
                    var dir = { x: 0, y: 0 };
                    dir.x = mousePoint.x - prevMousePoint.x;
                    dir.y = mousePoint.y - prevMousePoint.y;
                    speed.x = dir.x / dt;
                    speed.y = dir.y / dt;
                } else {
                    speed.x = 0;
                    speed.y = 0;
                }
                mousePoint = prevMousePoint = null;
                moveTime = lastMoveTime = null;
                map.parent.style.cursor = '';
                return MM.cancelEvent(e);
            }

            function animate(t) {
                var dir = { x: 0, y: 0 };
                var dt = Math.max(1, t - prevT);
                if (mousePoint && prevMousePoint) {
                    if (!animatedLastPoint) {
                        dir.x = mousePoint.x - prevMousePoint.x;
                        dir.y = mousePoint.y - prevMousePoint.y;
                        map.panBy(dir.x, dir.y);
                        animatedLastPoint = true;
                    }
                } else {
                    // Rough time based animation accuracy
                    // using a linear approximation approach
                    speed.x *= Math.pow(1 - drag, dt * 60 / 1000);
                    speed.y *= Math.pow(1 - drag, dt * 60 / 1000);
                    if (Math.abs(speed.x) < 0.001) {
                        speed.x = 0;
                    }
                    if (Math.abs(speed.y) < 0.001) {
                        speed.y = 0;
                    }
                    if (speed.x || speed.y) {
                        map.panBy(speed.x * dt, speed.y * dt);
                    }
                }
                prevT = t;
                MM.getFrame(animate);
            }

            MM.addEvent(map.parent, 'click', function(e) {
                map.parent.focus();
            });
            MM.addEvent(map.parent, 'mousedown', mouseDown);
            MM.addEvent(map.parent, 'mousemove', mouseMove);
            MM.addEvent(map.parent, 'mouseup', mouseUp);
            prevT = new Date().getTime();
            speed = { x: 0, y: 0 };
            MM.getFrame(animate);
        };

        return handler;
    };

})(this, MM);
<commit_msg>Don't activate on right click<commit_after>(function(context, MM) {

    easey.TouchHandler = function() {
      var handler = {};

      handler.add = function(map) {
            var prevT = 0,
                acceleration = 25.0,
                speed = null,
                maxTapTime = 250,
                maxTapDistance = 30,
                maxDoubleTapDelay = 350,
                drag = 0.10,
                locations = {},
                taps = [],
                wasPinching = false,
                nowPoint = null,
                oldPoint = null,
                lastMove = null,
                lastPinchCenter = null;

            function animate(t) {
                var dir = { x: 0, y: 0 };
                var dt = Math.max(0.001,(t - prevT) / 1000.0);
                if (nowPoint && oldPoint &&
                    (lastMove > (+new Date() - 50))) {
                    dir.x = nowPoint.x - oldPoint.x;
                    dir.y = nowPoint.y - oldPoint.y;
                    speed.x = dir.x;
                    speed.y = dir.y;
                } else {
                    speed.x -= speed.x * drag;
                    speed.y -= speed.y * drag;
                    if (Math.abs(speed.x) < 0.001) {
                        speed.x = 0;
                    }
                    if (Math.abs(speed.y) < 0.001) {
                        speed.y = 0;
                    }
                }
                if (speed.x || speed.y) {
                    map.panBy(speed.x, speed.y);
                }
                prevT = t;
                // tick every frame for time-based anim accuracy
                MM.getFrame(animate);
            }

            // Test whether touches are from the same source -
            // whether this is the same touchmove event.
            function sameTouch (event, touch) {
                return (event && event.touch) &&
                    (touch.identifier == event.touch.identifier);
            }

            function updateTouches (e) {
                for (var i = 0; i < e.touches.length; i += 1) {
                    var t = e.touches[i];
                    if (t.identifier in locations) {
                        var l = locations[t.identifier];
                        l.x = t.screenX;
                        l.y = t.screenY;
                        l.scale = e.scale;
                    }
                    else {
                        locations[t.identifier] = {
                            scale: e.scale,
                            startPos: { x: t.screenX, y: t.screenY },
                            x: t.screenX,
                            y: t.screenY,
                            time: new Date().getTime()
                        };
                    }
                }
            }

            function touchStartMachine(e) {
                updateTouches(e);
                return MM.cancelEvent(e);
            }

            function touchMoveMachine(e) {
                switch (e.touches.length) {
                    case 1:
                        onPanning(e.touches[0]);
                        break;
                    case 2:
                        onPinching(e);
                        break;
                }
                updateTouches(e);
                return MM.cancelEvent(e);
            }

            // Fail early if this isn't a touch device.
            // TODO: move to add fn
            if (!isTouchable()) return false;

            MM.addEvent(map.parent, 'touchstart',
                touchStartMachine);
            MM.addEvent(map.parent, 'touchmove',
                touchMoveMachine);
            MM.addEvent(map.parent, 'touchend',
                touchEndMachine);

            prevT = new Date().getTime();
            speed = { x: 0, y: 0 };
            MM.getFrame(animate);

            // Handle a tap event - mainly watch for a doubleTap
            function onTap(tap) {
                if (taps.length &&
                    (tap.time - taps[0].time) < maxDoubleTapDelay) {
                    onDoubleTap(tap);
                    taps = [];
                    return;
                }
                taps = [tap];
            }

            // Handle a double tap by zooming in a single zoom level to a
            // round zoom.
            function onDoubleTap(tap) {
                // zoom in to a round number
                easey.slow(map, {
                    zoom: Math.round(map.getZoom()) + 1,
                    about: new MM.Point(tap.x, tap.y),
                    time: 100
                });
            }

            function isTouchable () {
                 var el = document.createElement('div');
                 el.setAttribute('ongesturestart', 'return;');
                 return (typeof el.ongesturestart === 'function');
            }

            function remove() {
                // Fail early if this isn't a touch device.
                if (!isTouchable()) return false;

                MM.removeEvent(map.parent, 'touchstart',
                    touchStartMachine);
                MM.removeEvent(map.parent, 'touchmove',
                    touchMoveMachine);
                MM.removeEvent(map.parent, 'touchend',
                    touchEndMachine);
            }

            // Re-transform the actual map parent's CSS transformation
            function onPanning(touch) {
                lastMove = +new Date();
                oldPoint = nowPoint;
                nowPoint = { x: touch.screenX, y: touch.screenY };
                // oldPoint = locations[touch.identifier];
            }

            function onPinching(e) {
                // use the first two touches and their previous positions
                var t0 = e.touches[0],
                    t1 = e.touches[1],
                    p0 = new MM.Point(t0.screenX, t0.screenY),
                    p1 = new MM.Point(t1.screenX, t1.screenY),
                    l0 = locations[t0.identifier],
                    l1 = locations[t1.identifier];

                // mark these touches so they aren't used as taps/holds
                l0.wasPinch = true;
                l1.wasPinch = true;

                // scale about the center of these touches
                var center = MM.Point.interpolate(p0, p1, 0.5);

                map.zoomByAbout(
                    Math.log(e.scale) / Math.LN2 -
                    Math.log(l0.scale) / Math.LN2,
                    center);

                // pan from the previous center of these touches
                var prevCenter = MM.Point.interpolate(l0, l1, 0.5);

                map.panBy(center.x - prevCenter.x,
                               center.y - prevCenter.y);
                wasPinching = true;
                lastPinchCenter = center;
            }

            // When a pinch event ends, round the zoom of the map.
            function onPinched(p) {
                // TODO: easing
                if (true) {
                    var z = map.getZoom(), // current zoom
                        tz = Math.round(z);     // target zoom
                    map.zoomByAbout(tz - z, p);
                }
                wasPinching = false;
            }

            function touchEndMachine(e) {
                var now = new Date().getTime();
                // round zoom if we're done pinching
                if (e.touches.length === 0 && wasPinching) {
                    onPinched(lastPinchCenter);
                }

                oldPoint = nowPoint = null;

                // Look at each changed touch in turn.
                for (var i = 0; i < e.changedTouches.length; i += 1) {
                    var t = e.changedTouches[i],
                        loc = locations[t.identifier];
                    // if we didn't see this one (bug?)
                    // or if it was consumed by pinching already
                    // just skip to the next one
                    if (!loc || loc.wasPinch) {
                        continue;
                    }

                    // we now know we have an event object and a
                    // matching touch that's just ended. Let's see
                    // what kind of event it is based on how long it
                    // lasted and how far it moved.
                    var pos = { x: t.screenX, y: t.screenY },
                        time = now - loc.time,
                        travel = MM.Point.distance(pos, loc.startPos);
                    if (travel > maxTapDistance) {
                        // we will to assume that the drag has been handled separately
                    } else if (time > maxTapTime) {
                        // close in space, but not in time: a hold
                        pos.end = now;
                        pos.duration = time;
                        onHold(pos);
                    } else {
                        // close in both time and space: a tap
                        pos.time = now;
                        onTap(pos);
                    }
                }

                // Weird, sometimes an end event doesn't get thrown
                // for a touch that nevertheless has disappeared.
                // Still, this will eventually catch those ids:

                var validTouchIds = {};
                for (var j = 0; j < e.touches.length; j++) {
                    validTouchIds[e.touches[j].identifier] = true;
                }
                for (var id in locations) {
                    if (!(id in validTouchIds)) {
                        delete validTouchIds[id];
                    }
                }

                return MM.cancelEvent(e);
            }
        }
    };

    easey.DoubleClickHandler = function() {
        var handler = {},
            map;

        function doubleClick(e) {
            // Ensure that this handler is attached once.
            // Get the point on the map that was double-clicked
            var point = MM.getMousePoint(e, map);
            z = map.getZoom() + (e.shiftKey ? -1 : 1);
            // use shift-double-click to zoom out
            easey().map(map)
                .to(map.pointCoordinate(MM.getMousePoint(e, map)).zoomTo(z))
                .path('about').run(100);
            return MM.cancelEvent(e);
        }

        handler.add = function(x) {
            map = x;
            MM.addEvent(map.parent, 'dblclick', doubleClick);
            return handler;
        };

        handler.remove = function() {
            MM.removeEvent(map.parent, 'dblclick', doubleClick);
        };

        return handler;
    };

    easey.MouseWheelHandler = function() {
        var handler = {},
            map,
            _zoomDiv,
            ea = easey(),
            prevTime,
            precise = false;

        function mouseWheel(e) {
            var delta = 0;
            prevTime = prevTime || new Date().getTime();

            try {
                _zoomDiv.scrollTop = 1000;
                _zoomDiv.dispatchEvent(e);
                delta = 1000 - _zoomDiv.scrollTop;
            } catch (error) {
                delta = e.wheelDelta || (-e.detail * 5);
            }

            // limit mousewheeling to once every 200ms
            var timeSince = new Date().getTime() - prevTime;
            var point = MM.getMousePoint(e, map);

            if (Math.abs(delta) > 0 && (timeSince > 200) && !precise) {
                map.zoomByAbout(delta > 0 ? 1 : -1, point);
                prevTime = new Date().getTime();
            } else if (precise) {
                map.zoomByAbout(delta * 0.001, point);
            }
            if (!ea.running()) {
              var point = MM.getMousePoint(e, map),
                  z = map.getZoom();
              ea.map(map)
                .to(map.pointCoordinate(MM.getMousePoint(e, map)).zoomTo(z + (delta > 0 ? 1 : -1)))
                .path('about').run(200);
            } else {
                ea.zoom(ea.to().zoom + (delta > 0 ? 1 : -1));
            }

            // Cancel the event so that the page doesn't scroll
            return MM.cancelEvent(e);
        }

        handler.add = function(x) {
            map = x;
            _zoomDiv = document.body.appendChild(document.createElement('div'));
            _zoomDiv.style.cssText = 'visibility:hidden;top:0;height:0;width:0;overflow-y:scroll';
            var innerDiv = _zoomDiv.appendChild(document.createElement('div'));
            innerDiv.style.height = '2000px';
            MM.addEvent(map.parent, 'mousewheel', mouseWheel);
            return handler;
        };

        handler.precise = function(x) {
            if (!arguments.length) return precise;
            precise = x;
            return handler;
        };

        handler.remove = function() {
            MM.removeEvent(map.parent, 'mousewheel', mouseWheel);
            _zoomDiv.parentNode.removeChild(_zoomDiv);
        };

        return handler;
    };

    easey.DragHandler = function() {
        var handler = {},
            map;

        handler.add = function(map) {
            var prevT = 0,
                speed = null,
                drag = 0.15,
                mouseDownPoint = null,
                mouseDownTime = 0,
                mousePoint = null,
                prevMousePoint = null,
                moveTime = null,
                prevMoveTime = null,
                animatedLastPoint = true;

            function mouseDown(e) {
                if (e.shiftKey || e.button == 2) return;
                mousePoint = prevMousePoint = MM.getMousePoint(e, map);
                moveTime = prevMoveTime = +new Date();
                map.parent.style.cursor = 'move';
                return MM.cancelEvent(e);
            }

            function mouseMove(e) {
                if (mousePoint) {
                    if (animatedLastPoint) {
                        prevMousePoint = mousePoint;
                        prevMoveTime = moveTime;
                        animatedLastPoint = false;
                    }
                    mousePoint = MM.getMousePoint(e, map);
                    moveTime = +new Date();
                    return MM.cancelEvent(e);
                }
            }

            function mouseUp(e) {
                if (+new Date() - prevMoveTime < 50) {
                    dt = Math.max(1, moveTime - prevMoveTime);
                    var dir = { x: 0, y: 0 };
                    dir.x = mousePoint.x - prevMousePoint.x;
                    dir.y = mousePoint.y - prevMousePoint.y;
                    speed.x = dir.x / dt;
                    speed.y = dir.y / dt;
                } else {
                    speed.x = 0;
                    speed.y = 0;
                }
                mousePoint = prevMousePoint = null;
                moveTime = lastMoveTime = null;
                map.parent.style.cursor = '';
                return MM.cancelEvent(e);
            }

            function animate(t) {
                var dir = { x: 0, y: 0 };
                var dt = Math.max(1, t - prevT);
                if (mousePoint && prevMousePoint) {
                    if (!animatedLastPoint) {
                        dir.x = mousePoint.x - prevMousePoint.x;
                        dir.y = mousePoint.y - prevMousePoint.y;
                        map.panBy(dir.x, dir.y);
                        animatedLastPoint = true;
                    }
                } else {
                    // Rough time based animation accuracy
                    // using a linear approximation approach
                    speed.x *= Math.pow(1 - drag, dt * 60 / 1000);
                    speed.y *= Math.pow(1 - drag, dt * 60 / 1000);
                    if (Math.abs(speed.x) < 0.001) {
                        speed.x = 0;
                    }
                    if (Math.abs(speed.y) < 0.001) {
                        speed.y = 0;
                    }
                    if (speed.x || speed.y) {
                        map.panBy(speed.x * dt, speed.y * dt);
                    }
                }
                prevT = t;
                MM.getFrame(animate);
            }

            MM.addEvent(map.parent, 'click', function(e) {
                map.parent.focus();
            });
            MM.addEvent(map.parent, 'mousedown', mouseDown);
            MM.addEvent(map.parent, 'mousemove', mouseMove);
            MM.addEvent(map.parent, 'mouseup', mouseUp);
            prevT = new Date().getTime();
            speed = { x: 0, y: 0 };
            MM.getFrame(animate);
        };

        return handler;
    };

})(this, MM);
<|endoftext|>


<commit_before>/**
 * Appends the objects necessary for a new class to extend a base class.
 */
Function.prototype.extends = function(base){
  if(base.constructor == Function){
    // normal inheritance
    this.prototype = Object.create(base.prototype);
    this.prototype.constructor = this;
    this.prototype.base = base.prototype;
  }
  else {
    // virtual inheritance
    this.prototype = Object.create(base.prototype);
    this.prototype.constructor = this;
    this.prototype.base = base;
  }
  return this;
}

var svg = {
  ns: "http://www.w3.org/2000/svg",
}

/*******************************************************************************
 * A node is the root base class for all classes in the svg namespace. It
 * provides methods for working with attributes and children.
 */
svg.node = function(){
  this.root = null;
  this.element = null;
}

/**
 * This function sets the value of an attribute on an element.
 *
 * @param key   - the name of the attribute
 * @param value - the value the attribute should be set to
 *
 * @return a reference to this object
 */
svg.node.prototype.attr = function(key, value){
  this.element.setAttributeNS(null, key, value);
  return this;
}

/**
 * This function sets the values of one or more attributes on an element.
 *
 * @param attrs - an object literal containg the attributes to modify
 *
 * @return a reference to this object
 */
svg.node.prototype.attrs = function(attrs){
  for(var key in attrs){
    this.element.setAttributeNS(null, key, attrs[key]);
  }
  return this;
}

/**
 * Returns the value of the specified attribute.
 *
 * @param key - the name of the attribute to return.
 *
 * @return the value of the attribute
 */
svg.node.prototype.get = function(key){
  return this.element.getAttributeNS(null, key);
}

/**
 * Adds an SVG as a child of this element.
 *
 * @param child - the element to add.
 *
 * @return a reference to this object
 */
svg.node.prototype.add = function(child){
  this.element.appendChild(child.element);
  return this;
}

/**
 * Returns a list of the children contained in this SVG element.
 *
 * @return a NodeList of children.
 */
svg.node.prototype.children = function(){
  return this.element.childNodes;
}

/*******************************************************************************
 * The definition class represents a <defs> element in the SVG.
 *
 * If the provided <svg> element does not contain any <defs> elements, a new one
 * is created. Otherwise, the first <defs> element is associated with this
 * object.
 *
 * @param root - an <svg> element.
 */
svg.definition = function(root){
  svg.node.call(this);

  this.root = root;

  var defs = root.element.getElementsByTagName("defs");
  if(defs.length > 0){
    this.element = defs[0];
  } else {
    this.element = document.createElementNS(svg.ns, "defs");
    this.root.element.appendChild(this.element);
  }
}

svg.definition.extends(svg.node);

/**
 * Returns a new instance of the definition.
 *
 * @param x - the x attribute of the new element.
 * @param y - the y attribute of the new element.
 *
 * @return the new instance of the definition.
 */
svg.definition.prototype.create = function(id, x, y){
  var obj = document.createElementNS(svg.ns, "use");
  obj.setAttributeNS(null, "x", x);
  obj.setAttributeNS(null, "y", y);
  obj.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", id);
  return new svg.element(null, obj);
}

/*******************************************************************************
 * The element class defines an interface that is common to all of the SVG
 * classes.
 */
svg.element = function(root, element){
  this.root = root || null;
  this.element = element;

  var self = this;

  Object.defineProperty(self, "classes", {
    /**
     * Exposes the class attribute of the underlying element as a list.
     */
    get: function(){
      var classes = self.element.getAttributeNS(null, "class");
      if(classes !== null){
        return classes.split(" ");
      }
      return [];
    }
  });
}

svg.element.extends(svg.node);

/**
 * Appends class type to the classes property
 *
 * The class type will be append to the list of classes in the SVG elements
 * 'class' attribute if it not already in the list.
 *
 * @param cls - the name of the class type to append.
 */
svg.element.prototype.add_class = function(cls){
  // If this is the first class, just set the attribute
  if(this.classes.length == 0){
    this.element.setAttributeNS(null, "class", cls);
    return;
  }

  // Ensure the class is not already in the list
  if(-1 != this.classes.indexOf(cls)){
    return;
  }

  // Append the new class
  this.element.setAttributeNS(null, "class",
      this.element.getAttributeNS(null, "class") + " " + cls);
}

/**
 * Sets the 'click' callback
 *
 * @param cb - a callback function
 */
svg.element.prototype.onclick = function(cb){
  this.element.onclick = cb;
}

/**
 * Sets the 'mouse over' callback
 *
 * @param cb - a callback function
 */
svg.element.prototype.onmouseover = function(cb){
  this.element.onmouseover = cb;
}

/**
 * Translates this element.
 *
 * @param dx - the amount to move in the x co-ordinate
 * @param dy - the amount to move in the y co-ordinate
 */
svg.element.prototype.translate = function(dx, dy){
  var transform = this.root.translate(dx, dy);
  this.element.transform.baseVal.insertItemBefore(transform, 0);
}

/**
 * Rotate this element about a point.
 *
 * @param angle - the amount to rotate the element by (degrees)
 * @param x     - the x co-ordinate to rotate about
 * @param y     - the y co-ordinate to rotate about
 */
svg.element.prototype.rotate = function(angle, x, y){
  var transform = this.root.rotation(angle, x, y);
  this.element.transform.baseVal.insertItemBefore(transform, 0);
}

/**
 * Scale this element.
 *
 * @param factor - the scaling factor
 */
svg.element.prototype.scale = function(factor){
  var transform = this.root.scale(factor);
  this.element.transform.baseVal.insertItemBefore(transform,0);
}

/*******************************************************************************
 * This class is used to wrap an existing SVG element, rather than creating
 * one.
 */
svg.proxy = function(element){
  svg.node.call(this);

  this.element = element;
  if(element.ownerSVGElement !== null){
    this.root = new svg.root(element.ownerSVGElement);
  }
}

svg.proxy.extends(svg.node);

/*******************************************************************************
 * This class is specifically for elements that represent root nodes. It
 * exposes functionality that can only be obtained from the root note. In
 * particular, it is necessary to provide consist access to transformation
 * objects.
 */
svg.root = function(element){
  if(!(element instanceof SVGSVGElement))
    throw "A root element must be of type SVGSVGElement";

  svg.proxy.call(this, element);
}

svg.root.extends(svg.proxy);

/**
 * Create an SVGTransform object. This is intended for use (internally) by the
 * other SVG elements (path, rect, or group).
 */
svg.root.prototype.transform = function(){
  return this.element.createSVGTransform();
}

/**
 * Create a translation transform.
 *
 * @param dx - the amount to move in the x co-ordinate
 * @param dy - the amount to move in the y co-ordinate
 *
 * @return a translation transform
 */
svg.root.prototype.translate = function(dx, dy){
  var transform = this.transform();
  transform.setTranslate(dx, dy);
  return transform;
}

/**
 * Create a rotation transform.
 *
 * @param angle - the amount to rotate the element by (degrees)
 * @param x     - the x co-ordinate to rotate about
 * @param y     - the y co-ordinate to rotate about
 *
 * @return a rotation transform
 */
svg.root.prototype.rotation = function(angle, x, y){
  var transform = this.transform();
  transform.setRotate(angle, x, y);
  return transform;
}

/**
 * Create a scale transform.
 *
 * @param factor - the scaling factor
 *
 * @return a scale transform
 */
svg.root.prototype.scale = function(factor){
  var transform = this.transform();
  transform.setScale(factor, factor);
  return transform;
}

/*******************************************************************************
 * This class provides the interface to the 'group' element. The group element
 * is a composite of other elements (even other group elements). It is useful
 * for applying a transformation to a set of related elements.
 */
svg.group = function(root){
  svg.element.call(this, root, document.createElementNS(svg.ns, "g"));
}

svg.group.extends(svg.element);

/*******************************************************************************
 * This class provides the interface to the 'rect' element.
 */
svg.rect = function(root, x, y, w, h){
  svg.element.call(this, root, document.createElementNS(svg.ns, "rect"));
  this.attrs({x: x, y: y, width: w, height: h});
}

svg.rect.extends(svg.element);

/*******************************************************************************
 * This class provides the interface to the 'path' element.
 */
svg.path = function(root, path){
  svg.element.call(this, root, document.createElementNS(svg.ns, "path"));
  this.attr('d', path || '');
}

svg.path.extends(svg.element);

/**
 * Append text to the path attribute.
 *
 * @param text - the text that is appended
 */
svg.path.prototype.append_to_path = function(text){
  var current = this.get('d');
  if(current == ""){
    this.attr('d', text);
  } else {
    this.attr('d', current + ' ' + text);
  }
}

/**
 * Appends a move instruction to the path.
 *
 * @param x - the x absolute position to move to
 * @param y - the y absolute position to move to
 */
svg.path.prototype.move_to = function(x, y){
  this.append_to_path('M ' + x.toString() + ' ' + y.toString());
}

/**
 * Append a line instruction to the path.
 *
 * @param x - the x absolute position to draw to
 * @param y - the y absolute position to draw to
 */
svg.path.prototype.line_to = function(x, y){
  this.append_to_path('L ' + x.toString() + ' ' + y.toString());
}

/**
 * Close the path.
 *
 */
svg.path.prototype.close = function(){
  this.append_to_path('z');
}
<commit_msg>svg: fixed bug in classes property<commit_after>/**
 * Appends the objects necessary for a new class to extend a base class.
 */
Function.prototype.extends = function(base){
  if(base.constructor == Function){
    // normal inheritance
    this.prototype = Object.create(base.prototype);
    this.prototype.constructor = this;
    this.prototype.base = base.prototype;
  }
  else {
    // virtual inheritance
    this.prototype = Object.create(base.prototype);
    this.prototype.constructor = this;
    this.prototype.base = base;
  }
  return this;
}

var svg = {
  ns: "http://www.w3.org/2000/svg",
}

/*******************************************************************************
 * A node is the root base class for all classes in the svg namespace. It
 * provides methods for working with attributes and children.
 */
svg.node = function(){
  this.root = null;
  this.element = null;
}

/**
 * This function sets the value of an attribute on an element.
 *
 * @param key   - the name of the attribute
 * @param value - the value the attribute should be set to
 *
 * @return a reference to this object
 */
svg.node.prototype.attr = function(key, value){
  this.element.setAttributeNS(null, key, value);
  return this;
}

/**
 * This function sets the values of one or more attributes on an element.
 *
 * @param attrs - an object literal containg the attributes to modify
 *
 * @return a reference to this object
 */
svg.node.prototype.attrs = function(attrs){
  for(var key in attrs){
    this.element.setAttributeNS(null, key, attrs[key]);
  }
  return this;
}

/**
 * Returns the value of the specified attribute.
 *
 * @param key - the name of the attribute to return.
 *
 * @return the value of the attribute
 */
svg.node.prototype.get = function(key){
  return this.element.getAttributeNS(null, key);
}

/**
 * Adds an SVG as a child of this element.
 *
 * @param child - the element to add.
 *
 * @return a reference to this object
 */
svg.node.prototype.add = function(child){
  this.element.appendChild(child.element);
  return this;
}

/**
 * Returns a list of the children contained in this SVG element.
 *
 * @return a NodeList of children.
 */
svg.node.prototype.children = function(){
  return this.element.childNodes;
}

/*******************************************************************************
 * The definition class represents a <defs> element in the SVG.
 *
 * If the provided <svg> element does not contain any <defs> elements, a new one
 * is created. Otherwise, the first <defs> element is associated with this
 * object.
 *
 * @param root - an <svg> element.
 */
svg.definition = function(root){
  svg.node.call(this);

  this.root = root;

  var defs = root.element.getElementsByTagName("defs");
  if(defs.length > 0){
    this.element = defs[0];
  } else {
    this.element = document.createElementNS(svg.ns, "defs");
    this.root.element.appendChild(this.element);
  }
}

svg.definition.extends(svg.node);

/**
 * Returns a new instance of the definition.
 *
 * @param x - the x attribute of the new element.
 * @param y - the y attribute of the new element.
 *
 * @return the new instance of the definition.
 */
svg.definition.prototype.create = function(id, x, y){
  var obj = document.createElementNS(svg.ns, "use");
  obj.setAttributeNS(null, "x", x);
  obj.setAttributeNS(null, "y", y);
  obj.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", id);
  return new svg.element(null, obj);
}

/*******************************************************************************
 * The element class defines an interface that is common to all of the SVG
 * classes.
 */
svg.element = function(root, element){
  this.root = root || null;
  this.element = element;

  var self = this;

  Object.defineProperty(self, "classes", {
    /**
     * Exposes the class attribute of the underlying element as a list.
     */
    get: function(){
      var classes = self.element.getAttributeNS(null, "class");
      if(classes !== null && classes != ""){
        return classes.split(" ");
      }
      return [];
    }
  });
}

svg.element.extends(svg.node);

/**
 * Appends class type to the classes property
 *
 * The class type will be append to the list of classes in the SVG elements
 * 'class' attribute if it not already in the list.
 *
 * @param cls - the name of the class type to append.
 */
svg.element.prototype.add_class = function(cls){
  // If this is the first class, just set the attribute
  if(this.classes.length == 0){
    this.element.setAttributeNS(null, "class", cls);
    return;
  }

  // Ensure the class is not already in the list
  if(-1 != this.classes.indexOf(cls)){
    return;
  }

  // Append the new class
  this.element.setAttributeNS(null, "class",
      this.element.getAttributeNS(null, "class") + " " + cls);
}

/**
 * Sets the 'click' callback
 *
 * @param cb - a callback function
 */
svg.element.prototype.onclick = function(cb){
  this.element.onclick = cb;
}

/**
 * Sets the 'mouse over' callback
 *
 * @param cb - a callback function
 */
svg.element.prototype.onmouseover = function(cb){
  this.element.onmouseover = cb;
}

/**
 * Translates this element.
 *
 * @param dx - the amount to move in the x co-ordinate
 * @param dy - the amount to move in the y co-ordinate
 */
svg.element.prototype.translate = function(dx, dy){
  var transform = this.root.translate(dx, dy);
  this.element.transform.baseVal.insertItemBefore(transform, 0);
}

/**
 * Rotate this element about a point.
 *
 * @param angle - the amount to rotate the element by (degrees)
 * @param x     - the x co-ordinate to rotate about
 * @param y     - the y co-ordinate to rotate about
 */
svg.element.prototype.rotate = function(angle, x, y){
  var transform = this.root.rotation(angle, x, y);
  this.element.transform.baseVal.insertItemBefore(transform, 0);
}

/**
 * Scale this element.
 *
 * @param factor - the scaling factor
 */
svg.element.prototype.scale = function(factor){
  var transform = this.root.scale(factor);
  this.element.transform.baseVal.insertItemBefore(transform,0);
}

/*******************************************************************************
 * This class is used to wrap an existing SVG element, rather than creating
 * one.
 */
svg.proxy = function(element){
  svg.node.call(this);

  this.element = element;
  if(element.ownerSVGElement !== null){
    this.root = new svg.root(element.ownerSVGElement);
  }
}

svg.proxy.extends(svg.node);

/*******************************************************************************
 * This class is specifically for elements that represent root nodes. It
 * exposes functionality that can only be obtained from the root note. In
 * particular, it is necessary to provide consist access to transformation
 * objects.
 */
svg.root = function(element){
  if(!(element instanceof SVGSVGElement))
    throw "A root element must be of type SVGSVGElement";

  svg.proxy.call(this, element);
}

svg.root.extends(svg.proxy);

/**
 * Create an SVGTransform object. This is intended for use (internally) by the
 * other SVG elements (path, rect, or group).
 */
svg.root.prototype.transform = function(){
  return this.element.createSVGTransform();
}

/**
 * Create a translation transform.
 *
 * @param dx - the amount to move in the x co-ordinate
 * @param dy - the amount to move in the y co-ordinate
 *
 * @return a translation transform
 */
svg.root.prototype.translate = function(dx, dy){
  var transform = this.transform();
  transform.setTranslate(dx, dy);
  return transform;
}

/**
 * Create a rotation transform.
 *
 * @param angle - the amount to rotate the element by (degrees)
 * @param x     - the x co-ordinate to rotate about
 * @param y     - the y co-ordinate to rotate about
 *
 * @return a rotation transform
 */
svg.root.prototype.rotation = function(angle, x, y){
  var transform = this.transform();
  transform.setRotate(angle, x, y);
  return transform;
}

/**
 * Create a scale transform.
 *
 * @param factor - the scaling factor
 *
 * @return a scale transform
 */
svg.root.prototype.scale = function(factor){
  var transform = this.transform();
  transform.setScale(factor, factor);
  return transform;
}

/*******************************************************************************
 * This class provides the interface to the 'group' element. The group element
 * is a composite of other elements (even other group elements). It is useful
 * for applying a transformation to a set of related elements.
 */
svg.group = function(root){
  svg.element.call(this, root, document.createElementNS(svg.ns, "g"));
}

svg.group.extends(svg.element);

/*******************************************************************************
 * This class provides the interface to the 'rect' element.
 */
svg.rect = function(root, x, y, w, h){
  svg.element.call(this, root, document.createElementNS(svg.ns, "rect"));
  this.attrs({x: x, y: y, width: w, height: h});
}

svg.rect.extends(svg.element);

/*******************************************************************************
 * This class provides the interface to the 'path' element.
 */
svg.path = function(root, path){
  svg.element.call(this, root, document.createElementNS(svg.ns, "path"));
  this.attr('d', path || '');
}

svg.path.extends(svg.element);

/**
 * Append text to the path attribute.
 *
 * @param text - the text that is appended
 */
svg.path.prototype.append_to_path = function(text){
  var current = this.get('d');
  if(current == ""){
    this.attr('d', text);
  } else {
    this.attr('d', current + ' ' + text);
  }
}

/**
 * Appends a move instruction to the path.
 *
 * @param x - the x absolute position to move to
 * @param y - the y absolute position to move to
 */
svg.path.prototype.move_to = function(x, y){
  this.append_to_path('M ' + x.toString() + ' ' + y.toString());
}

/**
 * Append a line instruction to the path.
 *
 * @param x - the x absolute position to draw to
 * @param y - the y absolute position to draw to
 */
svg.path.prototype.line_to = function(x, y){
  this.append_to_path('L ' + x.toString() + ' ' + y.toString());
}

/**
 * Close the path.
 *
 */
svg.path.prototype.close = function(){
  this.append_to_path('z');
}
<|endoftext|>


<commit_before>/**
 * タブプラグイン
 *
 * @since: ver1.0.0
 * @オプション
 *   activeTabClass: アクティブなタブに付与されるクラス名
 *   onChange: タブ表示が切り替わった際に呼び出されるコールバック関数
 *   triggerTabNum: 初期表示にしたいタブパネル番号を指定
 */
(function($l){
    $l.fn.tab = function(settings) {
        var defaults = {
            activeTabClass: "active",
            onChange: $l.empty,
            triggerTabNum: 0
        };

        return this.each(function(){
            var self = $l(this), tabs = self.find("li"), panels,
                o = $l.extend({}, defaults, settings || {});

            tabs.each(function(){
                var i = $l($l("a", this).attr("href"), self);
                if(panels)
                    panels = panels.add(i);
                else
                    panels = i;
            }).find("a[href*=#]").bind("click", function(ev){
                tabs.removeClass(o.activeTabClass).find("a[href="+ev.target.hash+"]").parent().addClass(o.activeTabClass);
                var p = panels.hide().parent().find(ev.target.hash);
                p.show();

                if($l.isFunction(o.onChange))
                    o.onChange.call(this, this, p);

                ev.preventDefault();
            });

            if(tabs.size() < o.triggerTabNum)
                o.triggerTabNum = 0;

            $l("a", tabs.get(o.triggerTabNum)).trigger("click");
        });
    };
})(laquu);
<commit_msg>a要素の中に別の要素が入った場合に正常動作しないバグを修正<commit_after>/**
 * タブプラグイン
 *
 * @since: ver1.0.0
 * @オプション
 *   activeTabClass: アクティブなタブに付与されるクラス名
 *   onChange: タブ表示が切り替わった際に呼び出されるコールバック関数
 *   triggerTabNum: 初期表示にしたいタブパネル番号を指定
 */
(function($l){
    $l.fn.tab = function(settings) {
        var defaults = {
            activeTabClass: "active",
            onChange: $l.empty,
            triggerTabNum: 0
        };

        return this.each(function(){
            var self = $l(this), tabs = self.find("li"), panels,
                o = $l.extend({}, defaults, settings || {});

            tabs.each(function(){
                var i = $l($l("a", this).attr("href"), self);
                if(panels)
                    panels = panels.add(i);
                else
                    panels = i;
            }).find("a[href*=#]").bind("click", function(ev){
                panels.hide();
                tabs.removeClass(o.activeTabClass);
                $l(this).parent().addClass(o.activeTabClass);
                var p = $l($l(this).attr("href")).show();

                if($l.isFunction(o.onChange))
                    o.onChange.call(this, this, p);

                ev.preventDefault();
            });

            if(tabs.size() < o.triggerTabNum)
                o.triggerTabNum = 0;

            $l("a", tabs.get(o.triggerTabNum)).trigger("click");
        });
    };
})(laquu);
<|endoftext|>


<commit_before>const net = require('net')

const request = require('request')

const massey = 'http://seat-skomobo.massey.ac.nz'
// massey url
// send json post request to massey server
// send back received packet to client / whatever HTTP response says ok

var app = net.createServer((socket)=>{
    // console.log("Connected")

    socket.on("data", (data)=>{

        // console.log("got data")
        let received = data.toString("UTF8")

        if(received.slice(0,4) == "POST"){
            let window = JSON.parse(received.slice(received.indexOf('{')))
            send_window(window)
            socket.write('200 OK')
        }
        else{
            console.log(received)
            // to_massey(received)
            // is arduino data
        }
    })
})

function send_window(data){
    // request.post(massey + '/window_moved', data, ()=>{
    let fake = "http://localhost:80"
    request.post(fake + '/window_moved', {json:data}, (err)=>{
        console.log("Forwarded data: ", data)

        if(err !== null){
            console.error(err)
        }
    })
}

/**
 * This function passes the data to massey for storage
 *
 * @param {string} data
 */
function to_massey(data){

    // let options = {
    //     host: "seat-skomobo.massey.ac.nz",
    //     port: 80,
    //     path: 'dynamic',
    //     method: 'GET'
    // }

    // convert the routes the HTTP ones
    let route = ''
    if(data[0] == '0'){
        route = '/' + data.slice(2)
    }else if(data[0] == '1'){
        route = '/raspi_' + data.slice(2)
    }

    request(massey + route, function (error, response, body) {
        // console.log('error:', error); // Print the error if one occurred
        // console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
        // console.log('body:', body); // Print the HTML for the Google homepage.
    });
    // remove first routing values
    // options.path = route + data.slice(2)

    // send a HTTP get request to massey
    // console.log(options.path)
    // http.get(options, (response)=>{
    //     console.log(String(response.statusCode) + response.statusMessage)
    //     // console.log(options.path)
    // })
}

// aws exposes port 80 using ip tables to forward to 8000
const port = 8000
app.listen(port, ()=>{
    console.log("Server listening on: %s:%s", require("ip").address(), port);
})
<commit_msg>Need to fix response sometime<commit_after>const net = require('net')

const request = require('request')

const massey = 'http://seat-skomobo.massey.ac.nz'
// massey url
// send json post request to massey server
// send back received packet to client / whatever HTTP response says ok

var app = net.createServer((socket)=>{
    // console.log("Connected")

    socket.on("data", (data)=>{

        // console.log("got data")
        let received = data.toString("UTF8")

        if(received.slice(0,4) == "POST"){
            let window = JSON.parse(received.slice(received.indexOf('{')))
            send_window(window)

            let cannedResponse = new Buffer(
                "HTTP1.1 200 OK\r\n" +
                "Content-Length: 12\r\n" +
                "Connection: Keep-Alive\r\n" +
                "\r\n" +
                "Data received\n"
              );
            socket.write(cannedResponse)
        }
        else{
            console.log(received)
            // to_massey(received)
            // is arduino data
        }
    })
})

function send_window(data, ca){
    // request.post(massey + '/window_moved', data, ()=>{
    let fake = "http://localhost:80"
    request.post(fake + '/window_moved', {json:data}, (err)=>{
        console.log("Forwarded data: ", data)

        if(err !== null){
            console.error(err)
        }
    })
}

/**
 * This function passes the data to massey for storage
 *
 * @param {string} data
 */
function to_massey(data){

    // let options = {
    //     host: "seat-skomobo.massey.ac.nz",
    //     port: 80,
    //     path: 'dynamic',
    //     method: 'GET'
    // }

    // convert the routes the HTTP ones
    let route = ''
    if(data[0] == '0'){
        route = '/' + data.slice(2)
    }else if(data[0] == '1'){
        route = '/raspi_' + data.slice(2)
    }

    request(massey + route, function (error, response, body) {
        // console.log('error:', error); // Print the error if one occurred
        // console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
        // console.log('body:', body); // Print the HTML for the Google homepage.
    });
    // remove first routing values
    // options.path = route + data.slice(2)

    // send a HTTP get request to massey
    // console.log(options.path)
    // http.get(options, (response)=>{
    //     console.log(String(response.statusCode) + response.statusMessage)
    //     // console.log(options.path)
    // })
}

// aws exposes port 80 using ip tables to forward to 8000
const port = 8000
app.listen(port, ()=>{
    console.log("Server listening on: %s:%s", require("ip").address(), port);
})
<|endoftext|>