<commit_before>(function() {
    "use strict";

    var jQuery = require("jquery");
    var cockpit = require("cockpit");
    require("patterns");

    var _ = cockpit.gettext;

    var MANAGER = "/org/freedesktop/realmd";

    var SERVICE = "org.freedesktop.realmd.Service";
    var PROVIDER = "org.freedesktop.realmd.Provider";
    var KERBEROS = "org.freedesktop.realmd.KerberosMembership";
    var REALM = "org.freedesktop.realmd.Realm";

    function instance(realmd, mode, realm, button) {
        var dialog = jQuery.parseHTML(require("raw!./operation.html"))[0];

        /* Scope the jQuery selector to our dialog */
        var $ = function(selector, context) {
            return new jQuery.fn.init(selector, context || dialog);
        };
        $.fn = $.prototype = jQuery.fn;
        jQuery.extend($, jQuery);

        var operation = null;
        var checking = null;
        var checked = null;
        var kerberos = null;

        /* If in an operation first time cancel is clicked, cancel operation */
        $(".realms-op-cancel").on("click", function() {
            if (!cancel())
                $(dialog).modal('hide');
        });

        /* When we're hidden some other way, cancel any operations */
        $(dialog).on("hide.bs.modal", function() {
            cancel();
        });

        $(".realms-op-apply").on("click", perform);
        $(".realms-op-field")
            .on("keydown", function(ev) {
                if (ev.which == 13)
                    perform();
            });

        $(dialog).on("click", ".realms-op-more-diagnostics", function() {
            $(".realms-op-error").hide();
            $(".realms-op-diagnostics").show();
        });

        var timeout = null;
        $(".realms-op-address").on("keyup change", function() {
            if ($(".realms-op-address").val() != checked) {
                $(".realms-op-address-error").hide();
                window.clearTimeout(timeout);
                timeout = window.setTimeout(check, 1000);
            }
        });

        var auth = null;
        function auth_changed(item) {
            auth = item.attr('data-value');
            $(".realms-op-auth span").text(item.text());
            var parts = (auth || "").split("/");
            var type = parts[0];
            var owner = parts[1];

            $(".realms-op-admin-row").hide();
            $(".realms-op-admin-password-row").hide();
            $(".realms-op-user-row").hide();
            $(".realms-op-user-password-row").hide();
            $(".realms-op-otp-row").hide();

            if (type == "password" && owner == "administrator") {
                $(".realms-op-admin-row").show();
                $(".realms-op-admin-password-row").show();
            } else if (type == "password" && owner == "user") {
                $(".realms-op-user-row").show();
                $(".realms-op-user-password-row").show();
            } else if (type == "secret") {
                $(".realms-op-otp-row").show();
            }
        }

        $(".realms-op-auth").on('click', 'li', function() {
            auth_changed($(this));
        });

        var title, label, text;
        if (mode == 'join') {
            title = _("page-title", _("Join a Domain"));
            label = _("Join");
            $(".realms-op-join-only-row").show();
            $(".realms-op-leave-only-row").hide();
            check("");
        } else {
            title = _("page-title", _("Leave Domain"));
            label = _("Leave");
            text = _("Are you sure you want to leave this domain?");
            if (realm && realm.Name) {
                text = cockpit.format(_("Are you sure you want to leave the '$0' domain?"), realm.Name);
            }

            text = cockpit.format(_("$0 Only users with local credentials will be able to log into this machine. This may also effect other services as DNS resolution settings and the list of trusted CAs may change."), text);

            $(".realms-op-leave-only-row").text(text);
            $(".realms-op-join-only-row").hide();
            $(".realms-op-leave-only-row").show();
        }

        $(".realms-op-title").text(title);
        $(".realms-op-apply").text(label);
        $(".realms-op-field").val("");

        function check(name) {
            var dfd = $.Deferred();

            if (name === undefined)
                name = $(".realms-op-address").val();

            if (name)
                $(".realms-op-address-spinner").show();

            dfd.always(function() {
                if (name)
                    $(".realms-op-address-spinner").hide();
            });

            realmd.call(MANAGER, PROVIDER, "Discover", [ name, { } ])
                .always(function() {

                    if ($(".realms-op-address").val() != name) {
                        dfd.reject();
                        check();
                        return;
                    }

                    var error, result = [], path;
                    if (this.state() == "rejected") {
                        error = arguments[0];
                        $(".realms-op-message")
                            .empty()
                            .text(error.message);
                        dfd.reject(error);
                    }

                    var message;
                    if (arguments[0][1])
                        result = arguments[0][1];
                    path = result[0]; /* the first realm */

                    if (!path) {
                        if (name) {
                            message = cockpit.format(_("Domain $0 could not be contacted"), name);
                            $(".realms-op-address-error").show().attr('title', message);
                        }

                        realm = null;
                        kerberos = null;

                        dfd.reject(new Error(message));
                    } else {
                        kerberos = realmd.proxy(KERBEROS, path);
                        $(kerberos).on("changed", update);

                        realm = realmd.proxy(REALM, path);
                        $(realm).on("changed", update);
                        realm.wait(function() {
                            dfd.resolve(realm);
                        });
                    }

                    update();
                });

            checking = dfd.promise();
            checked = name;
            return checking;
        }

        function ensure() {
            if (mode != 'join') {
                var dfd = $.Deferred();
                dfd.resolve(realm);
                return dfd.promise();
            }

            if ($(".realms-op-address").val() === checked) {
                if (checking)
                    return checking;
            }

            return check();
        }

        /*
         * The realmd dbus interface has an a(ss) Details
         * property. Lookup the right value for the given
         * field key.
         */
        function find_detail(realm, field) {
            var result = null;
            if (realm && realm.Details) {
                realm.Details.forEach(function(value) {
                    if (value[0] === field)
                        result = value[1];
                });
            }
            return result;
        }

        function update() {
            var message;

            $(".realms-op-spinner").toggle(!!operation);
            $(".realms-op-wait-message").toggle(!!operation);
            $(".realms-op-field").prop('disabled', !!operation);
            $(".realms-op-apply").prop('disabled', !!operation);
            $(".realm-active-directory-only").hide();

            var server = find_detail(realm, "server-software");

            if (realm && kerberos && !kerberos.valid) {
                message = cockpit.format(_("Domain $0 is not supported"), realm.Name);
                $(".realms-op-address-spinner").hide();
                $(".realms-op-address-error").show().attr('title', message);
            } else {
                $(".realms-op-address-error").hide();
            }

            if (operation)
                button.attr('disabled', 'disabled');
            else
                button.removeAttr('disabled');

            if (mode != 'join')
                return;

            $(".realm-active-directory-only").toggle(!server || server == "active-directory");

            if (realm && realm.Name && !$(".realms-op-address")[0].placeholder) {
                $(".realms-op-address")[0].placeholder = cockpit.format(_("e.g. \"$0\""), realm.Name);
            }

            var placeholder = "";
            if (kerberos) {
                if (kerberos.SuggestedAdministrator)
                    placeholder = cockpit.format(_("e.g. \"$0\""), kerberos.SuggestedAdministrator);
            }
            $(".realms-op-admin")[0].placeholder = placeholder;

            var list = $(".realms-op-auth .dropdown-menu");
            var supported = (kerberos && kerberos.SupportedJoinCredentials) || [ ];
            supported.push(["password", "administrator"]);

            var first = true;
            var count = 0;

            function add_choice(owner, type, text) {
                var item, choice, i, length = supported.length;
                for (i = 0; i < length; i++) {
                    if ((!owner || owner == supported[i][1]) && type == supported[i][0]) {
                        choice = type + "/" + supported[i][1];
                        item = $("
").attr("data-value", choice).append($("").text(text));
                        list.append(item);
                        if (first) {
                            auth_changed(item);
                            first = false;
                        }
                        count += 1;
                        break;
                    }
                }
            }

            list.empty();
            add_choice('administrator', "password", _("Administrator Password"));
            add_choice('user', "password", _("User Password"));
            add_choice(null, "secret", _("One Time Password"));
            add_choice(null, "automatic", _("Automatic"));
            $(".realms-authentification-row").toggle(count > 1);
            list.prop('disabled', !!operation).val(!first);
        }

        function credentials() {
            var creds, secret;

            var parts = (auth || "").split("/");
            var type = parts[0];
            var owner = parts[1];

            if (owner == "user" && type == "password") {
                creds = [
                    type, owner,
                    cockpit.variant('(ss)', [ $(".realms-op-user").val(), $(".realms-op-user-password").val() ])
                ];
            } else if (owner == "administrator" && type == "password") {
                creds = [
                    type, owner,
                    cockpit.variant('(ss)', [ $(".realms-op-admin").val(), $(".realms-op-admin-password").val() ])
                ];
            } else if (type == "secret") {
                secret = $(".realms-op-ot-password").val();
                creds = [
                    type, owner,
                    cockpit.variant('ay', cockpit.utf8_encoder().encode(secret))
                ];
            } else {
                creds = [
                    "automatic", owner,
                    cockpit.variant('s', "")
                ];
            }

            return creds;
        }

        var unique = 1;

        function perform() {
            var id = "cockpit-" + unique;
            unique += 1;
            busy(id);
            $(".realms-op-error").hide();

            ensure()
                .fail(function() {
                    busy(null);
                })
                .done(function(realm) {
                    var options = { operation: cockpit.variant('s', id) };

                    $(".realms-op-message").empty();
                    $(".realms-op-diagnostics").empty().hide();

                    var diagnostics = "";
                    var sub = realmd.subscribe({ member: "Diagnostics" }, function(path, iface, signal, args) {
                        if (args[1] === id) {
                            diagnostics += args[0];
                        }
                    });

                    var call, computer_ou;
                    if (mode == 'join') {
                        computer_ou = $(".realms-join-computer-ou").val();
                        if (computer_ou)
                            options["computer-ou"] = cockpit.variant('s', computer_ou);
                        if (kerberos.valid) {
                            call = kerberos.call("Join", [ credentials(), options ]);
                        } else {
                            busy(null);
                            $(".realms-op-message").empty().text(_("Joining this domain is not supported"));
                            $(".realms-op-error").show();
                        }
                    } else if (mode == 'leave') {
                        call = realm.Deconfigure(options);
                    }

                    if (!call) {
                        sub.remove();
                        return;
                    }

                    call
                        .fail(function(ex) {
                            busy(null);
                            if (ex.name == "org.freedesktop.realmd.Error.Cancelled") {
                                $(dialog).modal("hide");
                            } else {
                                console.log("Failed to join domain: " + realm.Name + ": " + ex);
                                $(".realms-op-message").empty().text(ex + " ");
                                $(".realms-op-error").show();
                                if (diagnostics) {
                                    $(".realms-op-message")
                                        .append('' + _("More") + '');
                                    $(".realms-op-diagnostics").text(diagnostics);
                                }
                            }
                        })
                        .done(function() {
                            busy(null);
                            $(dialog).modal("hide");
                        })
                        .always(function() {
                            sub.remove();
                        });
                });
        }

        function busy(id) {
            operation = id;
            update();
        }

        function cancel() {
            if (operation) {
                realmd.call(MANAGER, SERVICE, "Cancel", [ operation ]);
                busy(null);
                return true;
            }
            return false;
        }

        update();
        return dialog;
    }

    function setup() {
        var $ = jQuery;

        var element = $("");
        var link = $("");
        element.append(link);

        var realmd = cockpit.dbus("org.freedesktop.realmd");
        realmd.watch(MANAGER);

        var realms = realmd.proxies("org.freedesktop.realmd.Realm");

        /* The realm we are joined to */
        var joined = null;

        var permission = null;

        $(realmd).on("close", function(ev, options) {
            var message;
            if (options.problem == "not-found")
                message = _("Cannot join a domain because realmd is not available on this system");
            else
                message = cockpit.message(options);
            link.addClass("disabled");
            element
                .attr('title', message)
                .tooltip({ container: 'body'})
                .tooltip('fixTitle');
            realmd = null;
        });

        realms.wait(function() {
            if (!realmd)
                return;

            permission = cockpit.permission({ admin: true });

            function update_realm_privileged() {
                $(link).update_privileged(permission,
                        cockpit.format(_("The user $0 is not permitted to modify realms"),
                            permission.user ? permission.user.name : ''), null, element);
            }

            $(permission).on("changed", update_realm_privileged);
        });

        function update_realms() {
            var text, path, realm;
            joined = [];
            for (path in realms) {
                realm = realms[path];
                if (realm.Configured)
                    joined.push(realm);
            }

            if (!joined || !joined.length)
                text = _("Join Domain");
            else
                text = joined.map(function(x) { return x.Name; }).join(", ");
            link.text(text);
        }

        $(realms).on("changed", update_realms);
        update_realms();

        var dialog = null;
        link.on("click", function() {
            if (dialog)
                $(dialog).remove();

            if (joined && joined.length)
                dialog = instance(realmd, 'leave', joined[0], link);
            else
                dialog = instance(realmd, 'join', null, link);

            $(dialog)
                .attr("id", "realms-op")
                .appendTo("body")
                .modal('show');
            cockpit.translate();
        });

        element.close = function close() {
            if (dialog)
                dialog.cancel();
            element.remove();
            if (realmd)
                realmd.close();
            if (permission)
                permission.close();
        };

        return element;
    }

    /* Hook this in when loaded */
    jQuery(function() {
        var placeholder = jQuery("#system-info-domain");
        if (placeholder.length) {
            placeholder.find(".button-location").append(setup());
            placeholder.removeAttr('hidden');
        }
    });

    return module;
}());
<commit_msg>realmd: Consistent variable naming<commit_after>(function() {
    "use strict";

    var jQuery = require("jquery");
    var cockpit = require("cockpit");
    require("patterns");

    var _ = cockpit.gettext;

    var MANAGER = "/org/freedesktop/realmd";

    var SERVICE = "org.freedesktop.realmd.Service";
    var PROVIDER = "org.freedesktop.realmd.Provider";
    var KERBEROS_MEMBERSHIP = "org.freedesktop.realmd.KerberosMembership";
    var REALM = "org.freedesktop.realmd.Realm";

    function instance(realmd, mode, realm, button) {
        var dialog = jQuery.parseHTML(require("raw!./operation.html"))[0];

        /* Scope the jQuery selector to our dialog */
        var $ = function(selector, context) {
            return new jQuery.fn.init(selector, context || dialog);
        };
        $.fn = $.prototype = jQuery.fn;
        jQuery.extend($, jQuery);

        var operation = null;
        var checking = null;
        var checked = null;
        var kerberos_membership = null;

        /* If in an operation first time cancel is clicked, cancel operation */
        $(".realms-op-cancel").on("click", function() {
            if (!cancel())
                $(dialog).modal('hide');
        });

        /* When we're hidden some other way, cancel any operations */
        $(dialog).on("hide.bs.modal", function() {
            cancel();
        });

        $(".realms-op-apply").on("click", perform);
        $(".realms-op-field")
            .on("keydown", function(ev) {
                if (ev.which == 13)
                    perform();
            });

        $(dialog).on("click", ".realms-op-more-diagnostics", function() {
            $(".realms-op-error").hide();
            $(".realms-op-diagnostics").show();
        });

        var timeout = null;
        $(".realms-op-address").on("keyup change", function() {
            if ($(".realms-op-address").val() != checked) {
                $(".realms-op-address-error").hide();
                window.clearTimeout(timeout);
                timeout = window.setTimeout(check, 1000);
            }
        });

        var auth = null;
        function auth_changed(item) {
            auth = item.attr('data-value');
            $(".realms-op-auth span").text(item.text());
            var parts = (auth || "").split("/");
            var type = parts[0];
            var owner = parts[1];

            $(".realms-op-admin-row").hide();
            $(".realms-op-admin-password-row").hide();
            $(".realms-op-user-row").hide();
            $(".realms-op-user-password-row").hide();
            $(".realms-op-otp-row").hide();

            if (type == "password" && owner == "administrator") {
                $(".realms-op-admin-row").show();
                $(".realms-op-admin-password-row").show();
            } else if (type == "password" && owner == "user") {
                $(".realms-op-user-row").show();
                $(".realms-op-user-password-row").show();
            } else if (type == "secret") {
                $(".realms-op-otp-row").show();
            }
        }

        $(".realms-op-auth").on('click', 'li', function() {
            auth_changed($(this));
        });

        var title, label, text;
        if (mode == 'join') {
            title = _("page-title", _("Join a Domain"));
            label = _("Join");
            $(".realms-op-join-only-row").show();
            $(".realms-op-leave-only-row").hide();
            check("");
        } else {
            title = _("page-title", _("Leave Domain"));
            label = _("Leave");
            text = _("Are you sure you want to leave this domain?");
            if (realm && realm.Name) {
                text = cockpit.format(_("Are you sure you want to leave the '$0' domain?"), realm.Name);
            }

            text = cockpit.format(_("$0 Only users with local credentials will be able to log into this machine. This may also effect other services as DNS resolution settings and the list of trusted CAs may change."), text);

            $(".realms-op-leave-only-row").text(text);
            $(".realms-op-join-only-row").hide();
            $(".realms-op-leave-only-row").show();
        }

        $(".realms-op-title").text(title);
        $(".realms-op-apply").text(label);
        $(".realms-op-field").val("");

        function check(name) {
            var dfd = $.Deferred();

            if (name === undefined)
                name = $(".realms-op-address").val();

            if (name)
                $(".realms-op-address-spinner").show();

            dfd.always(function() {
                if (name)
                    $(".realms-op-address-spinner").hide();
            });

            realmd.call(MANAGER, PROVIDER, "Discover", [ name, { } ])
                .always(function() {

                    if ($(".realms-op-address").val() != name) {
                        dfd.reject();
                        check();
                        return;
                    }

                    var error, result = [], path;
                    if (this.state() == "rejected") {
                        error = arguments[0];
                        $(".realms-op-message")
                            .empty()
                            .text(error.message);
                        dfd.reject(error);
                    }

                    var message;
                    if (arguments[0][1])
                        result = arguments[0][1];
                    path = result[0]; /* the first realm */

                    if (!path) {
                        if (name) {
                            message = cockpit.format(_("Domain $0 could not be contacted"), name);
                            $(".realms-op-address-error").show().attr('title', message);
                        }

                        realm = null;
                        kerberos_membership = null;

                        dfd.reject(new Error(message));
                    } else {
                        kerberos_membership = realmd.proxy(KERBEROS_MEMBERSHIP, path);
                        $(kerberos_membership).on("changed", update);

                        realm = realmd.proxy(REALM, path);
                        $(realm).on("changed", update);
                        realm.wait(function() {
                            dfd.resolve(realm);
                        });
                    }

                    update();
                });

            checking = dfd.promise();
            checked = name;
            return checking;
        }

        function ensure() {
            if (mode != 'join') {
                var dfd = $.Deferred();
                dfd.resolve(realm);
                return dfd.promise();
            }

            if ($(".realms-op-address").val() === checked) {
                if (checking)
                    return checking;
            }

            return check();
        }

        /*
         * The realmd dbus interface has an a(ss) Details
         * property. Lookup the right value for the given
         * field key.
         */
        function find_detail(realm, field) {
            var result = null;
            if (realm && realm.Details) {
                realm.Details.forEach(function(value) {
                    if (value[0] === field)
                        result = value[1];
                });
            }
            return result;
        }

        function update() {
            var message;

            $(".realms-op-spinner").toggle(!!operation);
            $(".realms-op-wait-message").toggle(!!operation);
            $(".realms-op-field").prop('disabled', !!operation);
            $(".realms-op-apply").prop('disabled', !!operation);
            $(".realm-active-directory-only").hide();

            var server = find_detail(realm, "server-software");

            if (realm && kerberos_membership && !kerberos_membership.valid) {
                message = cockpit.format(_("Domain $0 is not supported"), realm.Name);
                $(".realms-op-address-spinner").hide();
                $(".realms-op-address-error").show().attr('title', message);
            } else {
                $(".realms-op-address-error").hide();
            }

            if (operation)
                button.attr('disabled', 'disabled');
            else
                button.removeAttr('disabled');

            if (mode != 'join')
                return;

            $(".realm-active-directory-only").toggle(!server || server == "active-directory");

            if (realm && realm.Name && !$(".realms-op-address")[0].placeholder) {
                $(".realms-op-address")[0].placeholder = cockpit.format(_("e.g. \"$0\""), realm.Name);
            }

            var placeholder = "";
            if (kerberos_membership) {
                if (kerberos_membership.SuggestedAdministrator)
                    placeholder = cockpit.format(_("e.g. \"$0\""), kerberos_membership.SuggestedAdministrator);
            }
            $(".realms-op-admin")[0].placeholder = placeholder;

            var list = $(".realms-op-auth .dropdown-menu");
            var supported = (kerberos_membership && kerberos_membership.SupportedJoinCredentials) || [ ];
            supported.push(["password", "administrator"]);

            var first = true;
            var count = 0;

            function add_choice(owner, type, text) {
                var item, choice, i, length = supported.length;
                for (i = 0; i < length; i++) {
                    if ((!owner || owner == supported[i][1]) && type == supported[i][0]) {
                        choice = type + "/" + supported[i][1];
                        item = $("
").attr("data-value", choice).append($("").text(text));
                        list.append(item);
                        if (first) {
                            auth_changed(item);
                            first = false;
                        }
                        count += 1;
                        break;
                    }
                }
            }

            list.empty();
            add_choice('administrator', "password", _("Administrator Password"));
            add_choice('user', "password", _("User Password"));
            add_choice(null, "secret", _("One Time Password"));
            add_choice(null, "automatic", _("Automatic"));
            $(".realms-authentification-row").toggle(count > 1);
            list.prop('disabled', !!operation).val(!first);
        }

        function credentials() {
            var creds, secret;

            var parts = (auth || "").split("/");
            var type = parts[0];
            var owner = parts[1];

            if (owner == "user" && type == "password") {
                creds = [
                    type, owner,
                    cockpit.variant('(ss)', [ $(".realms-op-user").val(), $(".realms-op-user-password").val() ])
                ];
            } else if (owner == "administrator" && type == "password") {
                creds = [
                    type, owner,
                    cockpit.variant('(ss)', [ $(".realms-op-admin").val(), $(".realms-op-admin-password").val() ])
                ];
            } else if (type == "secret") {
                secret = $(".realms-op-ot-password").val();
                creds = [
                    type, owner,
                    cockpit.variant('ay', cockpit.utf8_encoder().encode(secret))
                ];
            } else {
                creds = [
                    "automatic", owner,
                    cockpit.variant('s', "")
                ];
            }

            return creds;
        }

        var unique = 1;

        function perform() {
            var id = "cockpit-" + unique;
            unique += 1;
            busy(id);
            $(".realms-op-error").hide();

            ensure()
                .fail(function() {
                    busy(null);
                })
                .done(function(realm) {
                    var options = { operation: cockpit.variant('s', id) };

                    $(".realms-op-message").empty();
                    $(".realms-op-diagnostics").empty().hide();

                    var diagnostics = "";
                    var sub = realmd.subscribe({ member: "Diagnostics" }, function(path, iface, signal, args) {
                        if (args[1] === id) {
                            diagnostics += args[0];
                        }
                    });

                    var call, computer_ou;
                    if (mode == 'join') {
                        computer_ou = $(".realms-join-computer-ou").val();
                        if (computer_ou)
                            options["computer-ou"] = cockpit.variant('s', computer_ou);
                        if (kerberos_membership.valid) {
                            call = kerberos_membership.call("Join", [ credentials(), options ]);
                        } else {
                            busy(null);
                            $(".realms-op-message").empty().text(_("Joining this domain is not supported"));
                            $(".realms-op-error").show();
                        }
                    } else if (mode == 'leave') {
                        call = realm.Deconfigure(options);
                    }

                    if (!call) {
                        sub.remove();
                        return;
                    }

                    call
                        .fail(function(ex) {
                            busy(null);
                            if (ex.name == "org.freedesktop.realmd.Error.Cancelled") {
                                $(dialog).modal("hide");
                            } else {
                                console.log("Failed to join domain: " + realm.Name + ": " + ex);
                                $(".realms-op-message").empty().text(ex + " ");
                                $(".realms-op-error").show();
                                if (diagnostics) {
                                    $(".realms-op-message")
                                        .append('' + _("More") + '');
                                    $(".realms-op-diagnostics").text(diagnostics);
                                }
                            }
                        })
                        .done(function() {
                            busy(null);
                            $(dialog).modal("hide");
                        })
                        .always(function() {
                            sub.remove();
                        });
                });
        }

        function busy(id) {
            operation = id;
            update();
        }

        function cancel() {
            if (operation) {
                realmd.call(MANAGER, SERVICE, "Cancel", [ operation ]);
                busy(null);
                return true;
            }
            return false;
        }

        update();
        return dialog;
    }

    function setup() {
        var $ = jQuery;

        var element = $("");
        var link = $("");
        element.append(link);

        var realmd = cockpit.dbus("org.freedesktop.realmd");
        realmd.watch(MANAGER);

        var realms = realmd.proxies("org.freedesktop.realmd.Realm");

        /* The realm we are joined to */
        var joined = null;

        var permission = null;

        $(realmd).on("close", function(ev, options) {
            var message;
            if (options.problem == "not-found")
                message = _("Cannot join a domain because realmd is not available on this system");
            else
                message = cockpit.message(options);
            link.addClass("disabled");
            element
                .attr('title', message)
                .tooltip({ container: 'body'})
                .tooltip('fixTitle');
            realmd = null;
        });

        realms.wait(function() {
            if (!realmd)
                return;

            permission = cockpit.permission({ admin: true });

            function update_realm_privileged() {
                $(link).update_privileged(permission,
                        cockpit.format(_("The user $0 is not permitted to modify realms"),
                            permission.user ? permission.user.name : ''), null, element);
            }

            $(permission).on("changed", update_realm_privileged);
        });

        function update_realms() {
            var text, path, realm;
            joined = [];
            for (path in realms) {
                realm = realms[path];
                if (realm.Configured)
                    joined.push(realm);
            }

            if (!joined || !joined.length)
                text = _("Join Domain");
            else
                text = joined.map(function(x) { return x.Name; }).join(", ");
            link.text(text);
        }

        $(realms).on("changed", update_realms);
        update_realms();

        var dialog = null;
        link.on("click", function() {
            if (dialog)
                $(dialog).remove();

            if (joined && joined.length)
                dialog = instance(realmd, 'leave', joined[0], link);
            else
                dialog = instance(realmd, 'join', null, link);

            $(dialog)
                .attr("id", "realms-op")
                .appendTo("body")
                .modal('show');
            cockpit.translate();
        });

        element.close = function close() {
            if (dialog)
                dialog.cancel();
            element.remove();
            if (realmd)
                realmd.close();
            if (permission)
                permission.close();
        };

        return element;
    }

    /* Hook this in when loaded */
    jQuery(function() {
        var placeholder = jQuery("#system-info-domain");
        if (placeholder.length) {
            placeholder.find(".button-location").append(setup());
            placeholder.removeAttr('hidden');
        }
    });

    return module;
}());
<|endoftext|>


<commit_before>'use strict';
var path = require('path');
var ComponentGenerator = require('../componentGenerator');
var Generator = module.exports = ComponentGenerator.extend({

    constructor: function() {
        this.basetype = 'component'; // this will create a property this.componentname
        this.basefolder = 'components'; // this is the folder for the components
        this.hasOwnFolder = true; // to specify if the component files should be in a subfolder
        this.isDasherize = true; // to specify that the file name should be dasherized
        ComponentGenerator.apply(this, arguments);

        this.option('targettype', {
            desc: 'The type of target',
            type: String,
            hide: false
        });
    },

    initializing: function() {
        Generator.__super__.initializing.apply(this, arguments);
        this.mixins.beautifyTs();
    },

    prompting: function() {
        var done = this.async();
        var self = this;
        var extraPrompts = [{
            type: 'list',
            name: 'targettype',
            default: 'web',
            when: function() {
                return !self.options.targettype || self.options.targettype.length <= 0;
            },
            message: 'What type of component do you want to create?',
            choices: ['web', 'fuse', 'multi']
        }];
        Generator.__super__.prompting.call(this, done, extraPrompts);

    },

    configuring: function() {
        Generator.__super__.configuring.apply(this, arguments);
        this.targettype = this.answers.targettype || this.options.targettype;
    },

    writing: function() {
        var destinationPath = Generator.__super__.writing.apply(this, arguments);
        //var componentnameFile = this.componentname; //this.mixins.dasherize(this.componentname); // could be componentname

        switch (this.targettype) {
            case 'web':
                this.fs.copyTpl(
                    this.templatePath('_component.web.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.web.spec.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.spec.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass,
                        modulename: this.modulename
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.web.html'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.html')), {
                        componentname: this.componentname
                    }
                );
                this.fs.copyTpl(
                    this.templatePath('_component.web.scss'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.scss'))
                );
                break;

            case 'ionic2':

                this.fs.copyTpl(
                    this.templatePath('_component.ionic2.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.ionic2.spec.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.spec.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass,
                        modulename: this.modulename
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.ionic2.html'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.html')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.ionic2.scss'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.scss'))
                );

                break;

            case 'fuse':
                this.fs.copyTpl(
                    this.templatePath('_component.fuse.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.fuse.spec.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.spec.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass,
                        modulename: this.modulename
                    }
                );
                this.fs.copyTpl(
                    this.templatePath('_component.ngux'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ngux')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );
                break;

            case 'multi':
                this.fs.copyTpl(
                    this.templatePath('_component.multi.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.web.spec.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.spec.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass,
                        modulename: this.modulename
                    }
                );
                this.fs.copyTpl(
                    this.templatePath('_component.web.html'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.html')), {
                        componentname: this.componentname
                    }
                );
                this.fs.copyTpl(
                    this.templatePath('_component.web.scss'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.scss'))
                );

                this.fs.copyTpl(
                    this.templatePath('_component.ionic2.html'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ionic.html')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.ngux'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ngux')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );
                break;
        }

    }

});
<commit_msg>feat(app): Add ionic2 option for component<commit_after>'use strict';
var path = require('path');
var ComponentGenerator = require('../componentGenerator');
var Generator = module.exports = ComponentGenerator.extend({

    constructor: function() {
        this.basetype = 'component'; // this will create a property this.componentname
        this.basefolder = 'components'; // this is the folder for the components
        this.hasOwnFolder = true; // to specify if the component files should be in a subfolder
        this.isDasherize = true; // to specify that the file name should be dasherized
        ComponentGenerator.apply(this, arguments);

        this.option('targettype', {
            desc: 'The type of target',
            type: String,
            hide: false
        });
    },

    initializing: function() {
        Generator.__super__.initializing.apply(this, arguments);
        this.mixins.beautifyTs();
    },

    prompting: function() {
        var done = this.async();
        var self = this;
        var extraPrompts = [{
            type: 'list',
            name: 'targettype',
            default: 'web',
            when: function() {
                return !self.options.targettype || self.options.targettype.length <= 0;
            },
            message: 'What type of component do you want to create?',
            choices: ['web', 'fuse', 'ionic2', 'multi']
        }];
        Generator.__super__.prompting.call(this, done, extraPrompts);

    },

    configuring: function() {
        Generator.__super__.configuring.apply(this, arguments);
        this.targettype = this.answers.targettype || this.options.targettype;
    },

    writing: function() {
        var destinationPath = Generator.__super__.writing.apply(this, arguments);
        //var componentnameFile = this.componentname; //this.mixins.dasherize(this.componentname); // could be componentname

        switch (this.targettype) {
            case 'web':
                this.fs.copyTpl(
                    this.templatePath('_component.web.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.web.spec.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.spec.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass,
                        modulename: this.modulename
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.web.html'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.html')), {
                        componentname: this.componentname
                    }
                );
                this.fs.copyTpl(
                    this.templatePath('_component.web.scss'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.scss'))
                );
                break;

            case 'ionic2':

                this.fs.copyTpl(
                    this.templatePath('_component.ionic2.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.ionic2.spec.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.spec.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass,
                        modulename: this.modulename
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.ionic2.html'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.html')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.ionic2.scss'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.scss'))
                );

                break;

            case 'fuse':
                this.fs.copyTpl(
                    this.templatePath('_component.fuse.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.fuse.spec.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.spec.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass,
                        modulename: this.modulename
                    }
                );
                this.fs.copyTpl(
                    this.templatePath('_component.ngux'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ngux')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );
                break;

            case 'multi':
                this.fs.copyTpl(
                    this.templatePath('_component.multi.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.web.spec.ts'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.spec.ts')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass,
                        modulename: this.modulename
                    }
                );
                this.fs.copyTpl(
                    this.templatePath('_component.web.html'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.html')), {
                        componentname: this.componentname
                    }
                );
                this.fs.copyTpl(
                    this.templatePath('_component.web.scss'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.scss'))
                );

                this.fs.copyTpl(
                    this.templatePath('_component.ionic2.html'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ionic.html')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );

                this.fs.copyTpl(
                    this.templatePath('_component.ngux'),
                    this.destinationPath(path.join(destinationPath, this.componentnameFile + '.component.ngux')), {
                        componentnameFile: this.componentnameFile,
                        componentname: this.componentname,
                        componentnameClass: this.componentnameClass
                    }
                );
                break;
        }

    }

});
<|endoftext|>


<commit_before>/*jslint browser: true, devel: true, sloppy: true*/
/*global google, $ */

/*---------------------------- Setup ----------------------------*/
// Set up constants
var polygons = []; // Array of polygon shapes drawn from ES requests
var info_windows = []; // Array of InfoWindows (one for each polygon)
var additional_filter_params = null; // Additional filter parameters

var es_url = "http://fatcat-test.jc.rl.ac.uk:9200/badc/eufar/_search";
var wps_url = "http://ceda-wps2.badc.rl.ac.uk:8080/submit/form?proc_id=PlotTimeSeries&FilePath=";
var geocoder = new google.maps.Geocoder();
var map = new google.maps.Map(
    document.getElementById('map'),
    {
        mapTypeId: google.maps.MapTypeId.TERRAIN,
        zoom: 6
    }
);

/*---------------------------- Functions ----------------------------*/

// Checks if a given item is in an array
function is_in(array, item) {
    var i;
    for (i = 0; i < array.length; i += 1) {
        if (i === array[i]) {
            return true;
        }
    }
    return false;
}

// Location search
function location_search() {
    var loc = $("#location").val();
    if (loc === "") {
        alert("Please enter a value into the 'Location' box.");
    } else {
        geocoder.geocode({
            "address": loc
        },
            function (results, status) {
                if (status === "OK") {
                    var new_centre = results[0].geometry.location;
                    // Centre map on new location
                    map.panTo(new_centre);
                } else {
                    alert("Could not find '" + loc + "'");
                }
            });
    }
}

// Clears additional filters from ES request
function clear_filters() {
    additional_filter_params = null;
    $("#ftext").val("");
    $("#start_time").val("");
    $("#end_time").val("");
    redraw_map();
}

// Applies additional filters to ES request
function apply_filters() {
    var ftext_filt, ftq,
        start_time_query, start_time,
        end_time_query, end_time,
        time_queries;

    // Free text search
    additional_filter_params = [];
    ftext_filt = {};
    ftq = $("#ftext").val();
    if (ftq.length > 0) {
        ftext_filt = {
            "term": {
                "_all": ftq
            }
        };
        additional_filter_params.push(ftext_filt);
    }

    // Time range
    start_time_query = {};
    start_time = $("#start_time").val();
    if (start_time.length > 0) {
        start_time_query = {
            "range": {
                "temporal.start_time": {
                    "from": start_time
                }
            }
        };
    }

    end_time_query = {};
    end_time = $("#end_time").val();
    if (end_time.length > 0) {
        end_time_query = {
            "range": {
                "temporal.start_time": {
                    "to": end_time
                }
            }
        };
    }

    // Combine time restrictions into single filter
    time_queries = {};
    if (!$.isEmptyObject(start_time_query)) {
        $.extend(true, time_queries, start_time_query);
    }

    if (!$.isEmptyObject(end_time_query)) {
        $.extend(true, time_queries, end_time_query);
    }

    // Add time filter to list of search criteria
    if (!$.isEmptyObject(time_queries)) {
        additional_filter_params.push(time_queries);
    }
    redraw_map();
}

// Creates an ES geo_shape filter query based on a bounding box
function create_es_request(bbox, offset) {
    var temp_ne, temp_sw, nw, se, request, i;

    temp_ne = bbox.getNorthEast();
    temp_sw = bbox.getSouthWest();

    // Build search extent using NW/SE and lng/lat format
    nw = [temp_sw.lng().toString(),
          temp_ne.lat().toString()];
    se = [temp_ne.lng().toString(),
          temp_sw.lat().toString()];

    // Construct request for ElasticSearch
    request = {
        "_source": {
            "include": [
                "data_format.format",
                "file.filename",
                "file.path",
                "spatial.geometries.bbox",
                "temporal"
            ]
        },
        "filter": {
            "and": {
                "must": [
                    {
                        "geo_shape": {
                            "bbox": {
                                "shape": {
                                    "type": "envelope",
                                    "coordinates": [nw, se]
                                }
                            }
                        }
                    }
                ]
            }
        },
        "size": 50
    };

    // Add any extra user-defined filters
    if (additional_filter_params !== null) {
        for (i = 0; i < additional_filter_params.length; i += 1) {
            request.filter.and.must.unshift(additional_filter_params[i]);
        }
    }
    return request;
}

// Construct a google.maps.Polygon object from a bounding box
function construct_polygon(bbox) {
    var vertices, polygon;

    vertices = [];
    vertices.push(new google.maps.LatLng(bbox[0][1], bbox[0][0]));
    vertices.push(new google.maps.LatLng(bbox[1][1], bbox[1][0]));
    vertices.push(new google.maps.LatLng(bbox[3][1], bbox[3][0]));
    vertices.push(new google.maps.LatLng(bbox[2][1], bbox[2][0]));
    polygon = new google.maps.Polygon({
        paths: vertices,
        geodesic: false,
        strokeColor: "#FF0000",
        strokeWeight: 1,
        strokeOpacity: 1.0,
        fillColor: "#FF0000",
        fillOpacity: 0.1
    });
    return polygon;
}

// Construct an InfoWindow from a search hit, containing useful info
function construct_info_window(hit) {
    var content, info;

    content = "

Filename: " + hit.file.filename + "
";

    if (hit.temporal) {
        content += "
Start Time: " +
                    hit.temporal.start_time + "
" +
                    "
End Time: " +
                    hit.temporal.end_time + "
";
    }

    content += "
Get data
";

    if (hit.data_format.format === "NetCDF") {
        content += "
Plot time-series
";
    }

    content += "
";

    info = new google.maps.InfoWindow({
        content: content
    });

    return info;
}

function draw_polygons(hits) {
    var i, j, polygon, hit, bbox, iw;

    for (i = 0; i < hits.length; i += 1) {
        hit = hits[i]._source;
        bbox = hit.spatial.geometries.bbox.coordinates;

        // Construct and display polygon
        polygon = construct_polygon(bbox);
        polygon.setMap(map);
        polygons.push(polygon);

        // Add info window
        iw = construct_info_window(hits[i]._source);
        info_windows.push(iw);
    }

    // Add a listener function to polygon that opens a new
    // InfoWindow on top of the polygon that was clicked
    // (closes all other InfoWindows first)
    for (i = 0; i < hits.length; i += 1) {
        google.maps.event.addListener(polygons[i], 'click', (function (i, e) {
            return function (e) {
                for (j = 0; j < info_windows.length; j += 1) {
                    info_windows[j].close();
                }
                info_windows[i].open(map, null);
                info_windows[i].setPosition(e.latLng);
            };
        }(i)));
    }
}

// Search ES for data (and display received data asynchronously)
function search_es_bbox(bbox) {
    var xhr, request, response, hits;

    // Create and send request
    xhr = new XMLHttpRequest();
    xhr.open("POST", es_url, true);

    request = create_es_request(bbox);
    xhr.send(JSON.stringify(request));

    // Handle the response
    xhr.onload = function (e) {
        if (xhr.readyState === 4) {
            response = JSON.parse(xhr.responseText);
            if (response.hits) {
                $("#resptime").html(response.took);
                // Update "number of hits" field in sidebar
                $("#numresults").html(response.hits.total);

                // Loop through each hit, drawing as necessary
                hits = response.hits.hits;
                draw_polygons(hits);
            }
        }
    };
}

// Redraw the map (inc. polygons, etc)
function redraw_map() {
    var p, i, bounds;

    // Clean up old polygons and info windows
    for (p = 0; p < polygons.length; p += 1) {
        polygons[p].setMap(null);
    }

    for (i = 0; i < info_windows.length; i += 1) {
        info_windows[i].close();
    }

    polygons = [];
    info_windows = [];

    // Make ES request
    bounds = map.getBounds();
    search_es_bbox(bounds);

    // Update bounding coordinates on sidebar
    $("#ge_northeast").html(
        bounds.getNorthEast().toUrlValue(3).replace(",", ", ")
    );
    $("#ge_southwest").html(
        bounds.getSouthWest().toUrlValue(3).replace(",", ", ")
    );

    // Rate-limit requests to ES to 1 per second
    window.setTimeout(function () {
        add_bounds_changed_listener(map);
    }, 500);
}

// Add a listener to make an ES data request when the map bounds change
function add_bounds_changed_listener(map) {
    google.maps.event.addListenerOnce(map, 'bounds_changed', function () {
        redraw_map();
    });
}

function draw_histogram(response) {
    var i, data, keys, buckets, key;

    data = [];
    keys = [];
    buckets = response.aggregations.times.buckets;

    for (i = 0; i < buckets.length; i += 1) {
        data.push(buckets[i].doc_count);
        key = buckets[i].key_as_string.split("T")[0];
        if (i === 0) {
            keys.push("Unknown Date");
        } else {
            keys.push("Week beginning " + key);
        }
    }

    $("#histogram").highcharts({
        chart: {
            type: "column",
            height: 200
        },
        title: {
            size: "8px",
            text: "Documents by Date"
        },
        xAxis: {
            categories: keys,
            labels: {
                enabled: false
            }
        },
        yAxis: {
            min: 1,
            type: "logarithmic",
            minorTickInterval: 0.5,
            tickInterval: 0.5,
            title: {
                text: "Documents"
            }
        },
        series: [
            {
                showInLegend: false,
                name: "Files",
                data: data
            }
        ],
        plotOptions: {
            column: {
                pointPadding: 0,
                borderWidth: 1,
                groupPadding: 0,
                shadow: false
            }
        }
    });
}

function request_histogram() {
    var xhr, request, response;

    request = {
        "_source": {
            "include": []
        },
        "aggs": {
            "times": {
                "date_histogram": {
                    "field": "start_time",
                    "interval": "week"
                }
            }
        },
        "size": 0
    };

    // Create and send request
    xhr = new XMLHttpRequest();
    xhr.open("POST", es_url, true);
    xhr.send(JSON.stringify(request));

    // Handle the response
    xhr.onload = function (e) {
        if (xhr.readyState === 4) {
            response = JSON.parse(xhr.responseText);
            draw_histogram(response);
        }
    };
}

// Start the main "bounds_changed" listener loop
window.onload = function () {
    // Draw histogram
    var resp = request_histogram();

    // Centre the map on Hungary initially
    geocoder.geocode(
        {
            "address": "Lake Balaton, Hungary"
        },
        function (results, status) {
            if (status === "OK") {
                map.setCenter(results[0].geometry.location);
            }
        }
    );

    // Set up location 'search' button
    $("#location_search").click(
        function () {
            location_search();
        }
    );

    // Clears all input values
    $("#clearfil").click(
        function () {
            clear_filters();
        }
    );

    // Constructs query filters from input values
    $("#applyfil").click(
        function () {
            apply_filters();
        }
    );

    // Override location form submission on 'enter'
    $("#location").keypress(
        function (e) {
            var charcode = e.charCode || e.keyCode || e.which;
            if (charcode === 13) {
                location_search();
                return false;
            }
        }
    );

    add_bounds_changed_listener(map);
};<commit_msg>Add click action to histogram bars<commit_after>/*jslint browser: true, devel: true, sloppy: true*/
/*global google, $ */

/*---------------------------- Setup ----------------------------*/
// Set up constants
var polygons = []; // Array of polygon shapes drawn from ES requests
var info_windows = []; // Array of InfoWindows (one for each polygon)
var additional_filter_params = null; // Additional filter parameters

var es_url = "http://fatcat-test.jc.rl.ac.uk:9200/badc/eufar/_search";
var wps_url = "http://ceda-wps2.badc.rl.ac.uk:8080/submit/form?proc_id=PlotTimeSeries&FilePath=";
var geocoder = new google.maps.Geocoder();
var map = new google.maps.Map(
    document.getElementById('map'),
    {
        mapTypeId: google.maps.MapTypeId.TERRAIN,
        zoom: 6
    }
);

/*---------------------------- Functions ----------------------------*/

// Checks if a given item is in an array
function is_in(array, item) {
    var i;
    for (i = 0; i < array.length; i += 1) {
        if (i === array[i]) {
            return true;
        }
    }
    return false;
}

// Location search
function location_search() {
    var loc = $("#location").val();
    if (loc === "") {
        alert("Please enter a value into the 'Location' box.");
    } else {
        geocoder.geocode({
            "address": loc
        },
            function (results, status) {
                if (status === "OK") {
                    var new_centre = results[0].geometry.location;
                    // Centre map on new location
                    map.panTo(new_centre);
                } else {
                    alert("Could not find '" + loc + "'");
                }
            });
    }
}

// Clears additional filters from ES request
function clear_filters() {
    additional_filter_params = null;
    $("#ftext").val("");
    $("#start_time").val("");
    $("#end_time").val("");
    redraw_map();
}

// Applies additional filters to ES request
function apply_filters() {
    var ftext_filt, ftq,
        start_time_query, start_time,
        end_time_query, end_time,
        time_queries;

    // Free text search
    additional_filter_params = [];
    ftext_filt = {};
    ftq = $("#ftext").val();
    if (ftq.length > 0) {
        ftext_filt = {
            "term": {
                "_all": ftq
            }
        };
        additional_filter_params.push(ftext_filt);
    }

    // Time range
    start_time_query = {};
    start_time = $("#start_time").val();
    if (start_time.length > 0) {
        start_time_query = {
            "range": {
                "temporal.start_time": {
                    "from": start_time
                }
            }
        };
    }

    end_time_query = {};
    end_time = $("#end_time").val();
    if (end_time.length > 0) {
        end_time_query = {
            "range": {
                "temporal.start_time": {
                    "to": end_time
                }
            }
        };
    }

    // Combine time restrictions into single filter
    time_queries = {};
    if (!$.isEmptyObject(start_time_query)) {
        $.extend(true, time_queries, start_time_query);
    }

    if (!$.isEmptyObject(end_time_query)) {
        $.extend(true, time_queries, end_time_query);
    }

    // Add time filter to list of search criteria
    if (!$.isEmptyObject(time_queries)) {
        additional_filter_params.push(time_queries);
    }
    redraw_map();
}

// Creates an ES geo_shape filter query based on a bounding box
function create_es_request(bbox, offset) {
    var temp_ne, temp_sw, nw, se, request, i;

    temp_ne = bbox.getNorthEast();
    temp_sw = bbox.getSouthWest();

    // Build search extent using NW/SE and lng/lat format
    nw = [temp_sw.lng().toString(),
          temp_ne.lat().toString()];
    se = [temp_ne.lng().toString(),
          temp_sw.lat().toString()];

    // Construct request for ElasticSearch
    request = {
        "_source": {
            "include": [
                "data_format.format",
                "file.filename",
                "file.path",
                "spatial.geometries.bbox",
                "temporal"
            ]
        },
        "filter": {
            "and": {
                "must": [
                    {
                        "geo_shape": {
                            "bbox": {
                                "shape": {
                                    "type": "envelope",
                                    "coordinates": [nw, se]
                                }
                            }
                        }
                    }
                ]
            }
        },
        "size": 50
    };

    // Add any extra user-defined filters
    if (additional_filter_params !== null) {
        for (i = 0; i < additional_filter_params.length; i += 1) {
            request.filter.and.must.unshift(additional_filter_params[i]);
        }
    }
    return request;
}

// Construct a google.maps.Polygon object from a bounding box
function construct_polygon(bbox) {
    var vertices, polygon;

    vertices = [];
    vertices.push(new google.maps.LatLng(bbox[0][1], bbox[0][0]));
    vertices.push(new google.maps.LatLng(bbox[1][1], bbox[1][0]));
    vertices.push(new google.maps.LatLng(bbox[3][1], bbox[3][0]));
    vertices.push(new google.maps.LatLng(bbox[2][1], bbox[2][0]));
    polygon = new google.maps.Polygon({
        paths: vertices,
        geodesic: false,
        strokeColor: "#FF0000",
        strokeWeight: 1,
        strokeOpacity: 1.0,
        fillColor: "#FF0000",
        fillOpacity: 0.1
    });
    return polygon;
}

// Construct an InfoWindow from a search hit, containing useful info
function construct_info_window(hit) {
    var content, info;

    content = "

Filename: " + hit.file.filename + "
";

    if (hit.temporal) {
        content += "
Start Time: " +
                    hit.temporal.start_time + "
" +
                    "
End Time: " +
                    hit.temporal.end_time + "
";
    }

    content += "
Get data
";

    if (hit.data_format.format === "NetCDF") {
        content += "
Plot time-series
";
    }

    content += "
";

    info = new google.maps.InfoWindow({
        content: content
    });

    return info;
}

function draw_polygons(hits) {
    var i, j, polygon, hit, bbox, iw;

    for (i = 0; i < hits.length; i += 1) {
        hit = hits[i]._source;
        bbox = hit.spatial.geometries.bbox.coordinates;

        // Construct and display polygon
        polygon = construct_polygon(bbox);
        polygon.setMap(map);
        polygons.push(polygon);

        // Add info window
        iw = construct_info_window(hits[i]._source);
        info_windows.push(iw);
    }

    // Add a listener function to polygon that opens a new
    // InfoWindow on top of the polygon that was clicked
    // (closes all other InfoWindows first)
    for (i = 0; i < hits.length; i += 1) {
        google.maps.event.addListener(polygons[i], 'click', (function (i, e) {
            return function (e) {
                for (j = 0; j < info_windows.length; j += 1) {
                    info_windows[j].close();
                }
                info_windows[i].open(map, null);
                info_windows[i].setPosition(e.latLng);
            };
        }(i)));
    }
}

// Search ES for data (and display received data asynchronously)
function search_es_bbox(bbox) {
    var xhr, request, response, hits;

    // Create and send request
    xhr = new XMLHttpRequest();
    xhr.open("POST", es_url, true);

    request = create_es_request(bbox);
    xhr.send(JSON.stringify(request));

    // Handle the response
    xhr.onload = function (e) {
        if (xhr.readyState === 4) {
            response = JSON.parse(xhr.responseText);
            if (response.hits) {
                $("#resptime").html(response.took);

                // Update "number of hits" field in sidebar
                $("#numresults").html(response.hits.total);

                // Loop through each hit, drawing as necessary
                hits = response.hits.hits;
                draw_polygons(hits);
            }
        }
    };
}

// Redraw the map (inc. polygons, etc)
function redraw_map() {
    var p, i, bounds;

    // Clean up old polygons and info windows
    for (p = 0; p < polygons.length; p += 1) {
        polygons[p].setMap(null);
    }

    for (i = 0; i < info_windows.length; i += 1) {
        info_windows[i].close();
    }

    polygons = [];
    info_windows = [];

    // Make ES request
    bounds = map.getBounds();
    search_es_bbox(bounds);

    // Update bounding coordinates on sidebar
    $("#ge_northeast").html(
        bounds.getNorthEast().toUrlValue(3).replace(",", ", ")
    );
    $("#ge_southwest").html(
        bounds.getSouthWest().toUrlValue(3).replace(",", ", ")
    );

    // Rate-limit requests to ES to 1 per second
    window.setTimeout(function () {
        add_bounds_changed_listener(map);
    }, 500);
}

// Add a listener to make an ES data request when the map bounds change
function add_bounds_changed_listener(map) {
    google.maps.event.addListenerOnce(map, 'bounds_changed', function () {
        redraw_map();
    });
}

function draw_histogram(response) {
    var i, data, keys, buckets, key;

    data = [];
    keys = [];
    buckets = response.aggregations.times.buckets;

    for (i = 0; i < buckets.length; i += 1) {
        data.push(buckets[i].doc_count);
        key = buckets[i].key_as_string.split("T")[0];
        if (i === 0) {
            keys.push("Unknown Date");
        } else {
            keys.push(key);
        }
    }

    $("#histogram").highcharts({
        chart: {
            type: "column",
            height: 200
        },
        title: {
            size: "8px",
            text: "Documents by Date",
            style: {
                fontSize: "10px"
            }
        },
        xAxis: {
            categories: keys,
            labels: {
                enabled: false
            }
        },
        yAxis: {
            min: 1,
            type: "logarithmic",
            minorTickInterval: 0.5,
            tickInterval: 0.5,
            title: {
                text: ""
            }
        },
        series: [
            {
                showInLegend: false,
                name: "Files",
                data: data
            }
        ],
        plotOptions: {
            column: {
                pointPadding: 0,
                borderWidth: 1,
                groupPadding: 0,
                shadow: false,
                point: {
                    events: {
                        click: function () {
                            if (this.category !== "Unknown Date") {
                                $("#start_time").val(this.category);
                            } else {
                                $("#start_time").val("1970-01-01");
                            }
                        }
                    }
                }
            }
        }
    });
}

function request_histogram() {
    var xhr, request, response;

    request = {
        "_source": {
            "include": []
        },
        "aggs": {
            "times": {
                "date_histogram": {
                    "field": "start_time",
                    "interval": "week"
                }
            }
        },
        "size": 0
    };

    // Create and send request
    xhr = new XMLHttpRequest();
    xhr.open("POST", es_url, true);
    xhr.send(JSON.stringify(request));

    // Handle the response
    xhr.onload = function (e) {
        if (xhr.readyState === 4) {
            response = JSON.parse(xhr.responseText);
            draw_histogram(response);
        }
    };
}

// Start the main "bounds_changed" listener loop
window.onload = function () {
    // Draw histogram
    var resp = request_histogram();

    // Centre the map on Hungary initially
    geocoder.geocode(
        {
            "address": "Lake Balaton, Hungary"
        },
        function (results, status) {
            if (status === "OK") {
                map.setCenter(results[0].geometry.location);
            }
        }
    );

    // Set up location 'search' button
    $("#location_search").click(
        function () {
            location_search();
        }
    );

    // Clears all input values
    $("#clearfil").click(
        function () {
            clear_filters();
        }
    );

    // Constructs query filters from input values
    $("#applyfil").click(
        function () {
            apply_filters();
        }
    );

    // Override location form submission on 'enter'
    $("#location").keypress(
        function (e) {
            var charcode = e.charCode || e.keyCode || e.which;
            if (charcode === 13) {
                location_search();
                return false;
            }
        }
    );

    add_bounds_changed_listener(map);
};
<|endoftext|>


<commit_before>import gravity from '../../lib/loaders/gravity';
import delta from '../../lib/loaders/delta';
import { sortBy, first, forEach, clone } from 'lodash';
import blacklist from '../../lib/artist_blacklist';

export const featuredFair = () => {
  return gravity('fairs', { size: 5, active: true, has_full_feature: true }).then((fairs) => {
    if (fairs.length) {
      return first(sortBy(fairs, ({ banner_size }) =>
        ['x-large', 'large', 'medium', 'small', 'x-small'].indexOf(banner_size)
      ));
    }
  });
};

export const featuredAuction = () => {
  return gravity('sales', { live: true, size: 1 }).then((sales) => {
    if (sales.length) {
      return first(sales);
    }
  });
};

export const featuredGene = (accessToken) => {
  return gravity.with(accessToken)('me/follow/genes', { size: 1 }).then((follows) => {
    if (follows.length) {
      return first(follows).gene;
    }
  });
};

export const followedArtist = (accessToken) => {
  return gravity.with(accessToken)('me/follow/artists', { size: 1 }).then((follows) => {
    if (follows.length) {
      return first(follows).artist;
    }
  });
};

export const relatedArtist = (accessToken) => {
  return followedArtist(accessToken).then((followed_artist) => {
    return gravity
      .with(accessToken)('me/suggested/artists', {
        exclude_followed_artists: true,
        exclude_artists_without_artworks: true,
        artist_id: followed_artist._id,
      })
      .then(first);
  });
};

export const iconicArtists = () => {
  return delta('/', {
    method: 'fetch',
    n: 9,
    name: 'artist_search_2t',
  }).then((trending) => {
    const clonedTrending = clone(trending);
    forEach(blacklist, (id) => delete clonedTrending[id]);
    return clonedTrending;
  });
};
<commit_msg>better filter on for sale related artists<commit_after>import gravity from '../../lib/loaders/gravity';
import delta from '../../lib/loaders/delta';
import { sortBy, first, forEach, clone } from 'lodash';
import blacklist from '../../lib/artist_blacklist';

export const featuredFair = () => {
  return gravity('fairs', { size: 5, active: true, has_full_feature: true }).then((fairs) => {
    if (fairs.length) {
      return first(sortBy(fairs, ({ banner_size }) =>
        ['x-large', 'large', 'medium', 'small', 'x-small'].indexOf(banner_size)
      ));
    }
  });
};

export const featuredAuction = () => {
  return gravity('sales', { live: true, size: 1 }).then((sales) => {
    if (sales.length) {
      return first(sales);
    }
  });
};

export const featuredGene = (accessToken) => {
  return gravity.with(accessToken)('me/follow/genes', { size: 1 }).then((follows) => {
    if (follows.length) {
      return first(follows).gene;
    }
  });
};

export const followedArtist = (accessToken) => {
  return gravity.with(accessToken)('me/follow/artists', { size: 1 }).then((follows) => {
    if (follows.length) {
      return first(follows).artist;
    }
  });
};

export const relatedArtist = (accessToken) => {
  return followedArtist(accessToken).then((followed_artist) => {
    return gravity
      .with(accessToken)('me/suggested/artists', {
        exclude_followed_artists: true,
        exclude_artists_without_forsale_artworks: true,
        artist_id: followed_artist._id,
      })
      .then(first);
  });
};

export const iconicArtists = () => {
  return delta('/', {
    method: 'fetch',
    n: 9,
    name: 'artist_search_2t',
  }).then((trending) => {
    const clonedTrending = clone(trending);
    forEach(blacklist, (id) => delete clonedTrending[id]);
    return clonedTrending;
  });
};
<|endoftext|>


<commit_before>var sanitize = require('validator').sanitize;

var at = require('../services/at');
var message = require('../services/message');

var EventProxy = require('eventproxy');

var User = require('../proxy').User;
var Topic = require('../proxy').Topic;
var Reply = require('../proxy').Reply;

/**
 * 添加一级回复
 */
exports.add = function (req, res, next) {
  var content = req.body.r_content;
  var topic_id = req.params.topic_id;

  var str = sanitize(content).trim();
  if (str === '') {
    res.render('notify/notify', {error: '回复内容不能为空！'});
    return;
  }

  var ep = EventProxy.create();
  ep.fail(next);

  Topic.getTopic(topic_id, ep.doneLater(function (topic) {
    if (!topic) {
      ep.unbind();
      // just 404 page
      return next();
    }
    ep.emit('topic');
  }));

  ep.on('topic', function (topic) {
    Reply.newAndSave(content, topic_id, req.session.user._id, ep.done(function (reply) {
      Topic.updateLastReply(topic_id, reply._id, ep.done(function () {
        ep.emit('reply_saved', reply);
        //发送at消息
        at.sendMessageToMentionUsers(content, topic_id, req.session.user._id, reply._id);
      }));
    }));

    User.getUserById(req.session.user._id, ep.done(function (user) {
      user.score += 5;
      user.reply_count += 1;
      user.save();
      req.session.user.score += 5;
      ep.emit('score_saved');
    }));
  });

  ep.on('reply_saved', 'topic', function (reply, topic) {
    if (topic.author_id.toString() !== req.session.user._id.toString()) {
      message.sendReplyMessage(topic.author_id, req.session.user._id, topic._id, reply._id);
    }
    ep.emit('message_saved');
  });

  ep.all('reply_saved', 'message_saved', 'score_saved', function (reply) {
    res.redirect('/topic/' + topic_id + '#' + reply._id);
  });
};

/**
 * 添加二级回复
 */
exports.add_reply2 = function (req, res, next) {
  var topic_id = req.params.topic_id;
  var reply_id = req.body.reply_id;
  var content = req.body.r2_content;

  var str = sanitize(content).trim();
  if (str === '') {
    res.send('');
    return;
  }

  var proxy = new EventProxy();
  proxy.assign('reply_saved', 'message_saved', function (reply) {
    Reply.getReplyById(reply._id, function (err, reply) {
      res.redirect('/topic/' + topic_id + '#' + reply._id);
      // res.partial('reply/reply2', {object: reply, as: 'reply'});
    });
  });

  // 创建一条回复，并保存
  Reply.newAndSave(content, topic_id, req.session.user._id, reply_id, function (err, reply) {
    if (err) {
      return next(err);
    }
    // 更新主题的最后回复信息
    Topic.updateLastReply(topic_id, reply._id, function (err) {
      if (err) {
        return next(err);
      }
      proxy.emit('reply_saved', reply);
      //发送at消息
      at.sendMessageToMentionUsers(content, topic_id, req.session.user._id, reply._id);
    });
  });

  // 将回复信息发送通知到相关人
  Reply.getReply(reply_id, function (err, reply) {
    if (err) {
      return next(err);
    }
    if (reply && reply.author_id.toString() !== req.session.user._id.toString()) {
      message.sendReply2Message(reply.author_id, req.session.user._id, topic_id, reply._id);
    }
    proxy.emit('message_saved');
  });
};

/**
 * 删除回复信息
 */
exports.delete = function (req, res, next) {
  var reply_id = req.body.reply_id;
  Reply.getReplyById(reply_id, function (err, reply) {
    if (err) {
      return next(err);
    }

    if (!reply) {
      res.json({status: 'failed'});
      return;
    }
    if (reply.author_id.toString() === req.session.user._id.toString()) {
      reply.remove();
      res.json({status: 'success'});

      if (!reply.reply_id) {
        reply.author.score -= 5;
        reply.author.reply_count -= 1;
        reply.author.save();
      }
    } else {
      res.json({status: 'failed'});
      return;
    }

    Topic.reduceCount(reply.topic_id, function () {});
  });
};
<commit_msg>emit topic<commit_after>var sanitize = require('validator').sanitize;

var at = require('../services/at');
var message = require('../services/message');

var EventProxy = require('eventproxy');

var User = require('../proxy').User;
var Topic = require('../proxy').Topic;
var Reply = require('../proxy').Reply;

/**
 * 添加一级回复
 */
exports.add = function (req, res, next) {
  var content = req.body.r_content;
  var topic_id = req.params.topic_id;

  var str = sanitize(content).trim();
  if (str === '') {
    res.render('notify/notify', {error: '回复内容不能为空！'});
    return;
  }

  var ep = EventProxy.create();
  ep.fail(next);

  Topic.getTopic(topic_id, ep.doneLater(function (topic) {
    if (!topic) {
      ep.unbind();
      // just 404 page
      return next();
    }
    ep.emit('topic', topic);
  }));

  ep.on('topic', function (topic) {
    Reply.newAndSave(content, topic_id, req.session.user._id, ep.done(function (reply) {
      Topic.updateLastReply(topic_id, reply._id, ep.done(function () {
        ep.emit('reply_saved', reply);
        //发送at消息
        at.sendMessageToMentionUsers(content, topic_id, req.session.user._id, reply._id);
      }));
    }));

    User.getUserById(req.session.user._id, ep.done(function (user) {
      user.score += 5;
      user.reply_count += 1;
      user.save();
      req.session.user.score += 5;
      ep.emit('score_saved');
    }));
  });

  ep.on('reply_saved', 'topic', function (reply, topic) {
    if (topic.author_id.toString() !== req.session.user._id.toString()) {
      message.sendReplyMessage(topic.author_id, req.session.user._id, topic._id, reply._id);
    }
    ep.emit('message_saved');
  });

  ep.all('reply_saved', 'message_saved', 'score_saved', function (reply) {
    res.redirect('/topic/' + topic_id + '#' + reply._id);
  });
};

/**
 * 添加二级回复
 */
exports.add_reply2 = function (req, res, next) {
  var topic_id = req.params.topic_id;
  var reply_id = req.body.reply_id;
  var content = req.body.r2_content;

  var str = sanitize(content).trim();
  if (str === '') {
    res.send('');
    return;
  }

  var proxy = new EventProxy();
  proxy.assign('reply_saved', 'message_saved', function (reply) {
    Reply.getReplyById(reply._id, function (err, reply) {
      res.redirect('/topic/' + topic_id + '#' + reply._id);
      // res.partial('reply/reply2', {object: reply, as: 'reply'});
    });
  });

  // 创建一条回复，并保存
  Reply.newAndSave(content, topic_id, req.session.user._id, reply_id, function (err, reply) {
    if (err) {
      return next(err);
    }
    // 更新主题的最后回复信息
    Topic.updateLastReply(topic_id, reply._id, function (err) {
      if (err) {
        return next(err);
      }
      proxy.emit('reply_saved', reply);
      //发送at消息
      at.sendMessageToMentionUsers(content, topic_id, req.session.user._id, reply._id);
    });
  });

  // 将回复信息发送通知到相关人
  Reply.getReply(reply_id, function (err, reply) {
    if (err) {
      return next(err);
    }
    if (reply && reply.author_id.toString() !== req.session.user._id.toString()) {
      message.sendReply2Message(reply.author_id, req.session.user._id, topic_id, reply._id);
    }
    proxy.emit('message_saved');
  });
};

/**
 * 删除回复信息
 */
exports.delete = function (req, res, next) {
  var reply_id = req.body.reply_id;
  Reply.getReplyById(reply_id, function (err, reply) {
    if (err) {
      return next(err);
    }

    if (!reply) {
      res.json({status: 'failed'});
      return;
    }
    if (reply.author_id.toString() === req.session.user._id.toString()) {
      reply.remove();
      res.json({status: 'success'});

      if (!reply.reply_id) {
        reply.author.score -= 5;
        reply.author.reply_count -= 1;
        reply.author.save();
      }
    } else {
      res.json({status: 'failed'});
      return;
    }

    Topic.reduceCount(reply.topic_id, function () {});
  });
};
<|endoftext|>