<commit_before>const EXPORT = ["IconEmbedder"];

const HB_NS = "http://b.hatena.ne.jp/";

function IconEmbedder(doc) {
    this.doc = doc;
    this.site = SiteInfoSet.Paragraphs.get(doc);
    if (this.site && !this.site.data.disabled)
        this.ready();
}

IconEmbedder.STYLE = <![CDATA[
    .hBookmark-embedded-counter,
    .hBookmark-embedded-add-button {
        text-decoration: none;
        margin: 0 3px;
    }
    .hBookmark-embedded-counter img,
    .hBookmark-embedded-add-button img {
        border: none;
        vertical-align: text-bottom;
        -moz-force-broken-image-icon: 1;
    }
]]>.toString().replace(/\s+/g, " ");

extend(IconEmbedder.prototype, {
    strings: new Strings("chrome://hatenabookmark/locale/browser.properties"),

    ready: function IE_ready() {
        this.embedStyles();
        this.embed();
        this.doc.addEventListener("HB.PageInserted", this, false);
        this.doc.defaultView.addEventListener("GM_AutoPagerizeLoaded", this, false, true);
    },

    embedStyles: function IE_embedStyles() {
        let style = this.doc.createElementNS(XHTML_NS, "style");
        style.setAttribute("type", "text/css");
        style.textContent = IconEmbedder.STYLE;
        let head = this.doc.getElementsByTagName("head")[0];
        if (!head) return;
        head.appendChild(style);
    },

    embed: function IE_embed() {
        this.site.queryAll("paragraph").forEach(function (paragraph) {
            if (paragraph.hasAttributeNS(HB_NS, "counter")) return;
            paragraph.setAttributeNS(HB_NS, "hb:counter", "true");

            let link = this.site.query("link", paragraph) || paragraph;
            if (!link.href) return;
            let annotation = this.site.query("annotation", paragraph) || link;
            let container = annotation.parentNode;
            let anchor = annotation.nextSibling;
            switch (this.site.data.annotationPosition) {
            case "before":
                anchor = annotation;
                break;

            case "first":
                container = annotation;
                anchor = annotation.firstChild;
                break;

            case "last":
                container = annotation;
                anchor = null;
                break;

            case "after":
            default:
                break;
            }
            let icons = this.createIcons(link, paragraph);
            container.insertBefore(icons, anchor);
        }, this);
    },

    createIcons: function IE_createIcons(link, paragraph) {
        let icons = this.doc.createDocumentFragment();
        let space = this.doc.createTextNode(" ");
        if (Prefs.bookmark.get("embed.counter")) {
            let counter = xml2dom(

                    <img src={ B_HTTP + 'entry/image/' + link.href }
                         alt={ "[" + this.strings.get("embed.showEntryLabel") + "] " }
                         width="1" height="13"
                         onload="if (this.naturalWidth === 1)
                                     this.parentNode.parentNode.removeChild(this.parentNode);
                                 else
                                     this.width = this.naturalWidth;"
                         onerror="this.parentNode.parentNode.removeChild(this.parentNode);"/>

            );
            icons.appendChild(counter);
        }
        if (Prefs.bookmark.get("embed.addButton")) {
            let addButton = xml2dom(

            );
            icons.appendChild(addButton)
        }
        if (icons.firstChild) {
            icons.insertBefore(space.cloneNode(false), icons.firstChild);
            icons.appendChild(space.cloneNode(false));
        }
        return icons;
    },

    handleEvent: function IE_handleEvent(event) {
        switch (event.type) {
        case "DOMNodeInserted":
            if ("isPage" in this.site.data &&
                !this.site.query("isPage", event.target, Boolean))
                break;
            // fall through
        case "HB.PageInserted":
            this.embed();
            break;

        case "GM_AutoPagerizeLoaded":
            this.doc.addEventListener("DOMNodeInserted", this, false);
            break;
        }
    }
});

function tryToEmbedIcons(event) {
    if (Prefs.bookmark.get("embed.enabled") &&
        event.target instanceof HTMLDocument)
        new IconEmbedder(event.target);
}

window.addEventListener("load", function IconEmbedder_BEGIN() {
    gBrowser.addEventListener("DOMContentLoaded", tryToEmbedIcons, false);
}, false);
<commit_msg>検索結果でのウィジェット表示: Prefsのlink.openInNewTabが真なら新しいタブで開くように。<commit_after>const EXPORT = ["IconEmbedder"];

const HB_NS = "http://b.hatena.ne.jp/";

function IconEmbedder(doc) {
    this.doc = doc;
    this.site = SiteInfoSet.Paragraphs.get(doc);
    if (this.site && !this.site.data.disabled)
        this.ready();
}

IconEmbedder.STYLE = <![CDATA[
    .hBookmark-embedded-counter,
    .hBookmark-embedded-add-button {
        text-decoration: none;
        margin: 0 3px;
    }
    .hBookmark-embedded-counter img,
    .hBookmark-embedded-add-button img {
        border: none;
        vertical-align: text-bottom;
        -moz-force-broken-image-icon: 1;
    }
]]>.toString().replace(/\s+/g, " ");

extend(IconEmbedder.prototype, {
    strings: new Strings("chrome://hatenabookmark/locale/browser.properties"),

    ready: function IE_ready() {
        this.embedStyles();
        this.embed();
        this.doc.addEventListener("HB.PageInserted", this, false);
        this.doc.defaultView.addEventListener("GM_AutoPagerizeLoaded", this, false, true);
    },

    embedStyles: function IE_embedStyles() {
        let style = this.doc.createElementNS(XHTML_NS, "style");
        style.setAttribute("type", "text/css");
        style.textContent = IconEmbedder.STYLE;
        let head = this.doc.getElementsByTagName("head")[0];
        if (!head) return;
        head.appendChild(style);
    },

    embed: function IE_embed() {
        this.site.queryAll("paragraph").forEach(function (paragraph) {
            if (paragraph.hasAttributeNS(HB_NS, "counter")) return;
            paragraph.setAttributeNS(HB_NS, "hb:counter", "true");

            let link = this.site.query("link", paragraph) || paragraph;
            if (!link.href) return;
            let annotation = this.site.query("annotation", paragraph) || link;
            let container = annotation.parentNode;
            let anchor = annotation.nextSibling;
            switch (this.site.data.annotationPosition) {
            case "before":
                anchor = annotation;
                break;

            case "first":
                container = annotation;
                anchor = annotation.firstChild;
                break;

            case "last":
                container = annotation;
                anchor = null;
                break;

            case "after":
            default:
                break;
            }
            let icons = this.createIcons(link, paragraph);
            container.insertBefore(icons, anchor);
        }, this);
    },

    createIcons: function IE_createIcons(link, paragraph) {
        let icons = this.doc.createDocumentFragment();
        let space = this.doc.createTextNode(" ");
        let inNewTab = Prefs.bookmark.get("link.openInNewTab");
        if (Prefs.bookmark.get("embed.counter")) {
            let counter =

                    <img src={ B_HTTP + 'entry/image/' + link.href }
                         alt={ "[" + this.strings.get("embed.showEntryLabel") + "] " }
                         width="1" height="13"
                         onload="if (this.naturalWidth === 1)
                                     this.parentNode.parentNode.removeChild(this.parentNode);
                                 else
                                     this.width = this.naturalWidth;"
                         onerror="this.parentNode.parentNode.removeChild(this.parentNode);"/>
                ;
            if (inNewTab)
                counter.@target = "_blank";
            icons.appendChild(xml2dom(counter));
        }
        if (Prefs.bookmark.get("embed.addButton")) {
            let addButton =

                ;
            if (inNewTab)
                addButton.@target = "_blank";
            icons.appendChild(xml2dom(addButton));
        }
        if (icons.firstChild) {
            icons.insertBefore(space.cloneNode(false), icons.firstChild);
            icons.appendChild(space.cloneNode(false));
        }
        return icons;
    },

    handleEvent: function IE_handleEvent(event) {
        switch (event.type) {
        case "DOMNodeInserted":
            if ("isPage" in this.site.data &&
                !this.site.query("isPage", event.target, Boolean))
                break;
            // fall through
        case "HB.PageInserted":
            this.embed();
            break;

        case "GM_AutoPagerizeLoaded":
            this.doc.addEventListener("DOMNodeInserted", this, false);
            break;
        }
    }
});

function tryToEmbedIcons(event) {
    if (Prefs.bookmark.get("embed.enabled") &&
        event.target instanceof HTMLDocument)
        new IconEmbedder(event.target);
}

window.addEventListener("load", function IconEmbedder_BEGIN() {
    gBrowser.addEventListener("DOMContentLoaded", tryToEmbedIcons, false);
}, false);
<|endoftext|>


<commit_before>var compose = (function () {

var exports = {};
var is_composing_message = false;
var faded_to;

function show(tabname, focus_area) {
    if (tabname === "stream") {
        $('#private-message').hide();
        $('#stream-message').show();
        $("#stream_toggle").addClass("active");
        $("#private_message_toggle").removeClass("active");
    } else {
        $('#private-message').show();
        $('#stream-message').hide();
        $("#stream_toggle").removeClass("active");
        $("#private_message_toggle").addClass("active");
    }
    $("#send-status").removeClass(status_classes).hide();
    $('#compose').css({visibility: "visible"});
    $("#new_message_content").trigger("autosize");
    $('.message_comp').slideDown(100, function () {
        // If the compose box is obscuring the currently selected message,
        // scroll up until the message is no longer occluded.
        if (current_msg_list.selected_id() === -1) {
            // If there's no selected message, there's no need to
            // scroll the compose box to avoid it.
            return;
        }
        var selected_row = current_msg_list.selected_row();
        var cover = selected_row.offset().top + selected_row.height()
            - $("#compose").offset().top;
        if (cover > 0) {
            disable_pointer_movement = true;
            // We use $('html, body') because you can't animate window.scrollTop
            // on Chrome (http://bugs.jquery.com/ticket/10419).
            $('html, body').animate({
                scrollTop: viewport.scrollTop() + cover + 5
            }, {
                complete: function () {
                    // The complete callback is actually called before the
                    // scrolling has completed, so we try to let scrolling
                    // finish before allowing pointer movements again or the
                    // pointer may still move.
                    setTimeout(function () {
                        disable_pointer_movement = false;
                    }, 50);
                }
            });
        }
    });
    focus_area.focus();
    focus_area.select();
    // Disable the notifications bar if it overlaps with the composebox
    notifications_bar.maybe_disable();
}

// In an attempt to decrease mixing, make the composebox's
// stream bar look like what you're replying to.
// (In particular, if there's a color associated with it,
//  have that color be reflected here too.)
exports.decorate_stream_bar = function (stream_name) {
    var color = subs.get_color(stream_name);
    $("#stream-message .message_header_stream")
        .css('background-color', color)
        .removeClass(subs.color_classes)
        .addClass(subs.get_color_class(color));
};

function messages_with_different_recipients(target_message) {
    var all_elts = rows.get_table(current_msg_list.table_name).find(".recipient_row, .messagebox");
    var i, elts_to_fade = [];
    var different_recipient = false;
    // Note: The below algorithm relies on the fact that all_elts is
    // sorted as it would be displayed in the message view
    for (i = 0; i < all_elts.length; i++) {
        var elt = $(all_elts[i]);
        if (elt.hasClass("recipient_row")) {
            if (!util.same_recipient(target_message, current_msg_list.get(rows.id(elt)))) {
                elts_to_fade.push(elt);
                different_recipient = true;
            } else {
                different_recipient = false;
            }
        } else if (different_recipient) {
            elts_to_fade.push(elt);
        }
    }
    return elts_to_fade;
}

function fade_around(reply_message) {
    var i, fade_class = narrow.active() ? "message_reply_fade_narrowed" : "message_reply_fade";
    var elts_to_fade = messages_with_different_recipients(reply_message);

    faded_to = reply_message;
    for (i = 0; i < elts_to_fade.length; i++) {
        $(elts_to_fade[i]).addClass(fade_class);
    }
    ui.disable_floating_recipient_bar();
}

exports.unfade_messages = function (clear_state) {
    if (faded_to === undefined) {
        return;
    }

    var fade_class = narrow.active() ? "message_reply_fade_narrowed" : "message_reply_fade";
    rows.get_table(current_msg_list.table_name).find(".recipient_row, .messagebox").removeClass(fade_class);
    if (clear_state === true) {
        faded_to = undefined;
    }
    ui.enable_floating_recipient_bar();
};

exports.update_faded_messages = function () {
    if (faded_to === undefined) {
        return;
    }

    fade_around(faded_to);
};

exports.update_recipient_on_narrow = function() {
    if (!compose.composing()) {
        return;
    }
    if (compose.message_content() !== "") {
        return;
    }
    var compose_opts = {};
    narrow.set_compose_defaults(compose_opts);
    if (compose_opts.stream) {
        compose.start("stream");
    } else {
        compose.start("private");
    }
};

exports.start = function (msg_type, opts) {
    if (reload.is_in_progress()) {
        return;
    }

    var default_opts = {
        message_type:     msg_type,
        stream:           '',
        subject:          '',
        private_message_recipient: ''
    };

    // Set default parameters based on the current narrowed view.
    narrow.set_compose_defaults(default_opts);

    opts = $.extend(default_opts, opts);

    if (!(compose.composing() === msg_type &&
          ((msg_type === "stream" &&
            opts.stream === compose.stream() &&
            opts.subject === compose.subject()) ||
           (msg_type === "private" &&
            opts.private_message_recipient === compose.recipient())))) {
        // Clear the compose box if the existing message is to a different recipient
        compose.clear();
    }

    compose.stream_name(opts.stream);
    compose.subject(opts.subject);
    compose.recipient(opts.private_message_recipient);
    // If the user opens the compose box, types some text, and then clicks on a
    // different stream/subject, we want to keep the text in the compose box
    if (opts.message !== undefined) {
        compose.message_content(opts.message);
    }

    ui.change_tab_to("#home");

    var focus_area;
    if (opts.stream && ! opts.subject) {
        focus_area = 'subject';
    } else if (opts.stream || opts.private_message_recipient) {
        focus_area = 'new_message_content';
    }

    if (msg_type === 'stream') {
        show('stream', $("#" + (focus_area || 'stream')));
    } else {
        show('private', $("#" + (focus_area || 'private_message_recipient')));
    }

    if (opts.replying_to_message !== undefined) {
        if (exports.composing() && (faded_to !== opts.replying_to_message)) {
            // Already faded to another message. First unfade everything.
            exports.unfade_messages(true);
        }
        fade_around(opts.replying_to_message);
    }

    is_composing_message = msg_type;
    exports.decorate_stream_bar(opts.stream);
    $(document).trigger($.Event('compose_started.zephyr', opts));
};

exports.cancel = function () {
    compose.hide();
    is_composing_message = false;
    $(document).trigger($.Event('compose_canceled.zephyr'));
};

function compose_error(error_text, bad_input) {
    $('#send-status').removeClass(status_classes)
               .addClass('alert-error')
               .stop(true).fadeTo(0, 1);
    $('#error-msg').html(error_text);
    $("#compose-send-button").removeAttr('disabled');
    $("#sending-indicator").hide();
    bad_input.focus().select();
}

var send_options;

function send_message() {
    var send_status = $('#send-status');

    // TODO: this should be collapsed with the code in composebox_typeahead.js
    var recipients = compose.recipient().split(/\s*[,;]\s*/);

    var request = {client: 'website',
                   type:        compose.composing(),
                   subject:     compose.subject(),
                   content:     compose.message_content()};
    if (request.type === "private") {
        request.to = JSON.stringify(recipients);
    } else {
        request.to = JSON.stringify([compose.stream_name()]);
    }

    if (tutorial.is_running()) {
        // We make a new copy of the request object for the tutorial so that we
        // don't mess up the request we're actually sending to the server
        var tutorial_copy_of_message = $.extend({}, request, {to: compose.stream_name()});
        if (request.type === "private") {
            $.extend(tutorial_copy_of_message, {to: recipients});
        }
        tutorial.message_was_sent(tutorial_copy_of_message);
    }

    $.ajax({
        dataType: 'json', // This seems to be ignored. We still get back an xhr.
        url: '/json/send_message',
        type: 'POST',
        data: request,
        success: function (resp, statusText, xhr) {
            compose.clear();
            send_status.hide();
            is_composing_message = false;
            compose.hide();
            $("#compose-send-button").removeAttr('disabled');
            $("#sending-indicator").hide();
        },
        error: function (xhr, error_type) {
            if (error_type !== 'timeout' && reload.is_pending()) {
                // The error might be due to the server changing
                reload.initiate({immediate: true, send_after_reload: true});
                return;
            }
            var response = "Error sending message";
            if (xhr.status.toString().charAt(0) === "4") {
                // Only display the error response for 4XX, where we've crafted
                // a nice response.
                response += ": " + $.parseJSON(xhr.responseText).msg;
            }
            compose_error(response, $('#new_message_content'));
        }
    });

    send_status.hide();
}

exports.finish = function () {
    if (! compose.validate()) {
        return false;
    }
    send_message();
    // TODO: Do we want to fire the event even if the send failed due
    // to a server-side error?
    $(document).trigger($.Event('compose_finished.zephyr'));
    return true;
};

$(function () {
    $("#compose form").on("submit", function (e) {
       e.preventDefault();
       compose.finish();
    });
});

exports.hide = function () {
    $('.message_comp').find('input, textarea, button').blur();
    $('.message_comp').slideUp(100,
                              function() { $('#compose').css({visibility: "hidden"});});
    notifications_bar.enable();
    exports.unfade_messages(true);
};

exports.clear = function () {
    $("#compose").find('input[type=text], textarea').val('');
};

// Set the mode of a compose already in progress.
// Does not clear the input fields.
exports.set_mode = function (mode) {
    ui.change_tab_to('#home');
    if (!is_composing_message) {
        exports.start(mode);
    }
    if (mode === 'private') {
        show('private', $("#private_message_recipient"));
        is_composing_message = "private";
    } else {
        show('stream', $("#stream"));
        is_composing_message = "stream";
    }
};

exports.composing = function () {
    return is_composing_message;
};

function get_or_set(fieldname, keep_outside_whitespace) {
    // We can't hoist the assignment of 'elem' out of this lambda,
    // because the DOM element might not exist yet when get_or_set
    // is called.
    return function (newval) {
        var elem = $('#'+fieldname);
        var oldval = elem.val();
        if (newval !== undefined) {
            elem.val(newval);
        }
        return keep_outside_whitespace ? oldval : $.trim(oldval);
    };
}

exports.stream_name     = get_or_set('stream');
exports.subject         = get_or_set('subject');
exports.message_content = get_or_set('new_message_content', true);
exports.recipient       = get_or_set('private_message_recipient');

// *Synchronously* check if a stream exists.
exports.check_stream_existence = function (stream_name) {
    var result = "error";
    $.ajax({
        type: "POST",
        url: "/json/subscriptions/exists",
        data: {'stream': stream_name},
        async: false,
        success: function (data) {
            if (!data.exists) {
                result = "does-not-exist";
            } else if (data.subscribed) {
                result = "subscribed";
            } else {
                result = "not-subscribed";
            }
        },
        error: function (xhr) {
            result = "error";
        }
    });
    return result;
};

// Checks if a stream exists. If not, displays an error and returns
// false.
function check_stream_for_send(stream_name) {
    var result = exports.check_stream_existence(stream_name);

    if (result === "error") {
        compose_error("Error checking subscription", $("#stream"));
        $("#compose-send-button").removeAttr('disabled');
        $("#sending-indicator").hide();
    }

    return result;
}

function validate_stream_message() {
    var stream_name = exports.stream_name();
    if (stream_name === "") {
        compose_error("Please specify a stream", $("#stream"));
        return false;
    }

    if (exports.subject() === "") {
        compose_error("Please specify a subject", $("#subject"));
        return false;
    }

    var response;

    if (!subs.have(stream_name)) {
        switch(check_stream_for_send(stream_name)) {
        case "does-not-exist":
            response = "
The stream " +
                Handlebars.Utils.escapeExpression(stream_name) + " does not exist.
" +
                "
Manage your subscriptions on your Streams page.
";
            compose_error(response, $('#stream'));
            return false;
        case "error":
            return false;
        case "subscribed":
            // You're actually subscribed to the stream, but this
            // browser window doesn't know it.
            return true;
        case "not-subscribed":
            response = "
You're not subscribed to the stream " +
                Handlebars.Utils.escapeExpression(stream_name) + ".
" +
                "
Manage your subscriptions on your Streams page.
";
            compose_error(response, $('#stream'));
            return false;
        }
    }

    return true;
}

function validate_private_message() {
    if (exports.recipient() === "") {
        compose_error("Please specify at least one recipient", $("#private_message_recipient"));
        return false;
    }

    return true;
}

exports.validate = function () {
    $("#compose-send-button").attr('disabled', 'disabled').blur();
    $("#sending-indicator").show();

    if (exports.message_content() === "") {
        compose_error("You have nothing to send!", $("#new_message_content"));
        return false;
    }

    if (exports.composing() === 'private') {
        return validate_private_message();
    } else {
        return validate_stream_message();
    }
};

$(function () {
    $("#new_message_content").autosize();
});

return exports;

}());
<commit_msg>compose: Move unfade_messages() call inside fade_around.<commit_after>var compose = (function () {

var exports = {};
var is_composing_message = false;
var faded_to;

function show(tabname, focus_area) {
    if (tabname === "stream") {
        $('#private-message').hide();
        $('#stream-message').show();
        $("#stream_toggle").addClass("active");
        $("#private_message_toggle").removeClass("active");
    } else {
        $('#private-message').show();
        $('#stream-message').hide();
        $("#stream_toggle").removeClass("active");
        $("#private_message_toggle").addClass("active");
    }
    $("#send-status").removeClass(status_classes).hide();
    $('#compose').css({visibility: "visible"});
    $("#new_message_content").trigger("autosize");
    $('.message_comp').slideDown(100, function () {
        // If the compose box is obscuring the currently selected message,
        // scroll up until the message is no longer occluded.
        if (current_msg_list.selected_id() === -1) {
            // If there's no selected message, there's no need to
            // scroll the compose box to avoid it.
            return;
        }
        var selected_row = current_msg_list.selected_row();
        var cover = selected_row.offset().top + selected_row.height()
            - $("#compose").offset().top;
        if (cover > 0) {
            disable_pointer_movement = true;
            // We use $('html, body') because you can't animate window.scrollTop
            // on Chrome (http://bugs.jquery.com/ticket/10419).
            $('html, body').animate({
                scrollTop: viewport.scrollTop() + cover + 5
            }, {
                complete: function () {
                    // The complete callback is actually called before the
                    // scrolling has completed, so we try to let scrolling
                    // finish before allowing pointer movements again or the
                    // pointer may still move.
                    setTimeout(function () {
                        disable_pointer_movement = false;
                    }, 50);
                }
            });
        }
    });
    focus_area.focus();
    focus_area.select();
    // Disable the notifications bar if it overlaps with the composebox
    notifications_bar.maybe_disable();
}

// In an attempt to decrease mixing, make the composebox's
// stream bar look like what you're replying to.
// (In particular, if there's a color associated with it,
//  have that color be reflected here too.)
exports.decorate_stream_bar = function (stream_name) {
    var color = subs.get_color(stream_name);
    $("#stream-message .message_header_stream")
        .css('background-color', color)
        .removeClass(subs.color_classes)
        .addClass(subs.get_color_class(color));
};

function messages_with_different_recipients(target_message) {
    var all_elts = rows.get_table(current_msg_list.table_name).find(".recipient_row, .messagebox");
    var i, elts_to_fade = [];
    var different_recipient = false;
    // Note: The below algorithm relies on the fact that all_elts is
    // sorted as it would be displayed in the message view
    for (i = 0; i < all_elts.length; i++) {
        var elt = $(all_elts[i]);
        if (elt.hasClass("recipient_row")) {
            if (!util.same_recipient(target_message, current_msg_list.get(rows.id(elt)))) {
                elts_to_fade.push(elt);
                different_recipient = true;
            } else {
                different_recipient = false;
            }
        } else if (different_recipient) {
            elts_to_fade.push(elt);
        }
    }
    return elts_to_fade;
}

function fade_around(reply_message) {
    compose.unfade_messages(true);
    faded_to = reply_message;
    var i, fade_class = narrow.active() ? "message_reply_fade_narrowed" : "message_reply_fade";
    var elts_to_fade = messages_with_different_recipients(reply_message);

    for (i = 0; i < elts_to_fade.length; i++) {
        $(elts_to_fade[i]).addClass(fade_class);
    }
    ui.disable_floating_recipient_bar();
}

exports.unfade_messages = function (clear_state) {
    if (faded_to === undefined) {
        return;
    }

    var fade_class = narrow.active() ? "message_reply_fade_narrowed" : "message_reply_fade";
    rows.get_table(current_msg_list.table_name).find(".recipient_row, .messagebox").removeClass(fade_class);
    if (clear_state === true) {
        faded_to = undefined;
    }
    ui.enable_floating_recipient_bar();
};

exports.update_faded_messages = function () {
    if (faded_to === undefined) {
        return;
    }

    fade_around(faded_to);
};

exports.update_recipient_on_narrow = function() {
    if (!compose.composing()) {
        return;
    }
    if (compose.message_content() !== "") {
        return;
    }
    var compose_opts = {};
    narrow.set_compose_defaults(compose_opts);
    if (compose_opts.stream) {
        compose.start("stream");
    } else {
        compose.start("private");
    }
};

exports.start = function (msg_type, opts) {
    if (reload.is_in_progress()) {
        return;
    }

    var default_opts = {
        message_type:     msg_type,
        stream:           '',
        subject:          '',
        private_message_recipient: ''
    };

    // Set default parameters based on the current narrowed view.
    narrow.set_compose_defaults(default_opts);

    opts = $.extend(default_opts, opts);

    if (!(compose.composing() === msg_type &&
          ((msg_type === "stream" &&
            opts.stream === compose.stream() &&
            opts.subject === compose.subject()) ||
           (msg_type === "private" &&
            opts.private_message_recipient === compose.recipient())))) {
        // Clear the compose box if the existing message is to a different recipient
        compose.clear();
    }

    compose.stream_name(opts.stream);
    compose.subject(opts.subject);
    compose.recipient(opts.private_message_recipient);
    // If the user opens the compose box, types some text, and then clicks on a
    // different stream/subject, we want to keep the text in the compose box
    if (opts.message !== undefined) {
        compose.message_content(opts.message);
    }

    ui.change_tab_to("#home");

    var focus_area;
    if (opts.stream && ! opts.subject) {
        focus_area = 'subject';
    } else if (opts.stream || opts.private_message_recipient) {
        focus_area = 'new_message_content';
    }

    if (msg_type === 'stream') {
        show('stream', $("#" + (focus_area || 'stream')));
    } else {
        show('private', $("#" + (focus_area || 'private_message_recipient')));
    }

    if (opts.replying_to_message !== undefined) {
        fade_around(opts.replying_to_message);
    }

    is_composing_message = msg_type;
    exports.decorate_stream_bar(opts.stream);
    $(document).trigger($.Event('compose_started.zephyr', opts));
};

exports.cancel = function () {
    compose.hide();
    is_composing_message = false;
    $(document).trigger($.Event('compose_canceled.zephyr'));
};

function compose_error(error_text, bad_input) {
    $('#send-status').removeClass(status_classes)
               .addClass('alert-error')
               .stop(true).fadeTo(0, 1);
    $('#error-msg').html(error_text);
    $("#compose-send-button").removeAttr('disabled');
    $("#sending-indicator").hide();
    bad_input.focus().select();
}

var send_options;

function send_message() {
    var send_status = $('#send-status');

    // TODO: this should be collapsed with the code in composebox_typeahead.js
    var recipients = compose.recipient().split(/\s*[,;]\s*/);

    var request = {client: 'website',
                   type:        compose.composing(),
                   subject:     compose.subject(),
                   content:     compose.message_content()};
    if (request.type === "private") {
        request.to = JSON.stringify(recipients);
    } else {
        request.to = JSON.stringify([compose.stream_name()]);
    }

    if (tutorial.is_running()) {
        // We make a new copy of the request object for the tutorial so that we
        // don't mess up the request we're actually sending to the server
        var tutorial_copy_of_message = $.extend({}, request, {to: compose.stream_name()});
        if (request.type === "private") {
            $.extend(tutorial_copy_of_message, {to: recipients});
        }
        tutorial.message_was_sent(tutorial_copy_of_message);
    }

    $.ajax({
        dataType: 'json', // This seems to be ignored. We still get back an xhr.
        url: '/json/send_message',
        type: 'POST',
        data: request,
        success: function (resp, statusText, xhr) {
            compose.clear();
            send_status.hide();
            is_composing_message = false;
            compose.hide();
            $("#compose-send-button").removeAttr('disabled');
            $("#sending-indicator").hide();
        },
        error: function (xhr, error_type) {
            if (error_type !== 'timeout' && reload.is_pending()) {
                // The error might be due to the server changing
                reload.initiate({immediate: true, send_after_reload: true});
                return;
            }
            var response = "Error sending message";
            if (xhr.status.toString().charAt(0) === "4") {
                // Only display the error response for 4XX, where we've crafted
                // a nice response.
                response += ": " + $.parseJSON(xhr.responseText).msg;
            }
            compose_error(response, $('#new_message_content'));
        }
    });

    send_status.hide();
}

exports.finish = function () {
    if (! compose.validate()) {
        return false;
    }
    send_message();
    // TODO: Do we want to fire the event even if the send failed due
    // to a server-side error?
    $(document).trigger($.Event('compose_finished.zephyr'));
    return true;
};

$(function () {
    $("#compose form").on("submit", function (e) {
       e.preventDefault();
       compose.finish();
    });
});

exports.hide = function () {
    $('.message_comp').find('input, textarea, button').blur();
    $('.message_comp').slideUp(100,
                              function() { $('#compose').css({visibility: "hidden"});});
    notifications_bar.enable();
    exports.unfade_messages(true);
};

exports.clear = function () {
    $("#compose").find('input[type=text], textarea').val('');
};

// Set the mode of a compose already in progress.
// Does not clear the input fields.
exports.set_mode = function (mode) {
    ui.change_tab_to('#home');
    if (!is_composing_message) {
        exports.start(mode);
    }
    if (mode === 'private') {
        show('private', $("#private_message_recipient"));
        is_composing_message = "private";
    } else {
        show('stream', $("#stream"));
        is_composing_message = "stream";
    }
};

exports.composing = function () {
    return is_composing_message;
};

function get_or_set(fieldname, keep_outside_whitespace) {
    // We can't hoist the assignment of 'elem' out of this lambda,
    // because the DOM element might not exist yet when get_or_set
    // is called.
    return function (newval) {
        var elem = $('#'+fieldname);
        var oldval = elem.val();
        if (newval !== undefined) {
            elem.val(newval);
        }
        return keep_outside_whitespace ? oldval : $.trim(oldval);
    };
}

exports.stream_name     = get_or_set('stream');
exports.subject         = get_or_set('subject');
exports.message_content = get_or_set('new_message_content', true);
exports.recipient       = get_or_set('private_message_recipient');

// *Synchronously* check if a stream exists.
exports.check_stream_existence = function (stream_name) {
    var result = "error";
    $.ajax({
        type: "POST",
        url: "/json/subscriptions/exists",
        data: {'stream': stream_name},
        async: false,
        success: function (data) {
            if (!data.exists) {
                result = "does-not-exist";
            } else if (data.subscribed) {
                result = "subscribed";
            } else {
                result = "not-subscribed";
            }
        },
        error: function (xhr) {
            result = "error";
        }
    });
    return result;
};

// Checks if a stream exists. If not, displays an error and returns
// false.
function check_stream_for_send(stream_name) {
    var result = exports.check_stream_existence(stream_name);

    if (result === "error") {
        compose_error("Error checking subscription", $("#stream"));
        $("#compose-send-button").removeAttr('disabled');
        $("#sending-indicator").hide();
    }

    return result;
}

function validate_stream_message() {
    var stream_name = exports.stream_name();
    if (stream_name === "") {
        compose_error("Please specify a stream", $("#stream"));
        return false;
    }

    if (exports.subject() === "") {
        compose_error("Please specify a subject", $("#subject"));
        return false;
    }

    var response;

    if (!subs.have(stream_name)) {
        switch(check_stream_for_send(stream_name)) {
        case "does-not-exist":
            response = "
The stream " +
                Handlebars.Utils.escapeExpression(stream_name) + " does not exist.
" +
                "
Manage your subscriptions on your Streams page.
";
            compose_error(response, $('#stream'));
            return false;
        case "error":
            return false;
        case "subscribed":
            // You're actually subscribed to the stream, but this
            // browser window doesn't know it.
            return true;
        case "not-subscribed":
            response = "
You're not subscribed to the stream " +
                Handlebars.Utils.escapeExpression(stream_name) + ".
" +
                "
Manage your subscriptions on your Streams page.
";
            compose_error(response, $('#stream'));
            return false;
        }
    }

    return true;
}

function validate_private_message() {
    if (exports.recipient() === "") {
        compose_error("Please specify at least one recipient", $("#private_message_recipient"));
        return false;
    }

    return true;
}

exports.validate = function () {
    $("#compose-send-button").attr('disabled', 'disabled').blur();
    $("#sending-indicator").show();

    if (exports.message_content() === "") {
        compose_error("You have nothing to send!", $("#new_message_content"));
        return false;
    }

    if (exports.composing() === 'private') {
        return validate_private_message();
    } else {
        return validate_stream_message();
    }
};

$(function () {
    $("#new_message_content").autosize();
});

return exports;

}());
<|endoftext|>


<commit_before>import { handleActions } from 'redux-actions'
import { createHashHistory } from 'history'
import polyline from 'polyline'

var history = createHashHistory({ queryKey: false })

const initialState = {
  filters: [
    'buildings' // todo: make constants for this?
  ],
  region: null
}

export default handleActions({
  'enable filter' (state, action) {
    var newState
    if (state.filters.indexOf(action.payload) === -1) {
      newState = {
        filters: state.filters.concat(action.payload),
        region: state.region
      }
    } else {
      newState = state
    }
    updateURL(newState)
    return newState
  },
  'disable filter' (state, action) {
    var newState = {
      filters: state.filters.filter(filter => filter !== action.payload),
      region: state.region
    }
    updateURL(newState)
    return newState
  },
  'set filters from url' (state, action) {
    if (action.payload !== undefined){
      return {
        filters: action.payload !== 'none'
          ? action.payload.split(',')
          : [],
        region: state.region
      }
    }
    return state
  },

  'set region' (state, action) {
    var newState = {
      filters: state.filters,
      region: action.payload
    }
    updateURL(newState)
    return newState
  },
  'set region from url' (state, action) {
    return {
      filters: state.filters,
      region: parseRegionFromUrl(action.payload)
    }
  }
}, initialState)

function updateURL(state) {
  var region = state.region
  var filterPart = state.filters.length > 0
    ? state.filters.sort().join(',')
    : 'none'
  if (region !== null) {
    switch (region.type) {
    case 'bbox':
      history.replace('/show'
        +'/bbox:'
        +region.coords.map(x => x.toFixed(5)).join(',')
        +'/'+filterPart
      )
    break
    case 'polygon':
      history.replace('/show'
        +'/polygon:'
        +encodeURIComponent(
          polyline.encode(
            region.coords
          )
        )
        +'/'+filterPart
      )
    break
    case 'hot':
      history.replace('/show'
        +'/hot:'
        +region.id
        +'/'+filterPart
      )
    break
    default:
      throw new Error('unknown region type', region)
    }
  }
}

function parseRegionFromUrl(regionString) {
  if (!regionString) {
    return null
  }
  const [ regionType, regionContent ] = regionString.split(':')
  switch (regionType) {
    case 'bbox':
      return {
        type: 'bbox',
        coords: regionContent.split(',').map(Number)
      }
    break
    case 'polygon':
      return {
        type: 'polygon',
        coords: [polyline.decode(decodeURIComponent(regionContent))]
      }
    break
    case 'hot':
      return {
        type: 'hot',
        id: +regionContent
      }
    break
    default:
      throw new Error('unknown region type when parsing from URL', regionString)
  }
}
<commit_msg>fix polyline decoding of custom areas<commit_after>import { handleActions } from 'redux-actions'
import { createHashHistory } from 'history'
import polyline from 'polyline'

var history = createHashHistory({ queryKey: false })

const initialState = {
  filters: [
    'buildings' // todo: make constants for this?
  ],
  region: null
}

export default handleActions({
  'enable filter' (state, action) {
    var newState
    if (state.filters.indexOf(action.payload) === -1) {
      newState = {
        filters: state.filters.concat(action.payload),
        region: state.region
      }
    } else {
      newState = state
    }
    updateURL(newState)
    return newState
  },
  'disable filter' (state, action) {
    var newState = {
      filters: state.filters.filter(filter => filter !== action.payload),
      region: state.region
    }
    updateURL(newState)
    return newState
  },
  'set filters from url' (state, action) {
    if (action.payload !== undefined){
      return {
        filters: action.payload !== 'none'
          ? action.payload.split(',')
          : [],
        region: state.region
      }
    }
    return state
  },

  'set region' (state, action) {
    var newState = {
      filters: state.filters,
      region: action.payload
    }
    updateURL(newState)
    return newState
  },
  'set region from url' (state, action) {
    return {
      filters: state.filters,
      region: parseRegionFromUrl(action.payload)
    }
  }
}, initialState)

function updateURL(state) {
  var region = state.region
  var filterPart = state.filters.length > 0
    ? state.filters.sort().join(',')
    : 'none'
  if (region !== null) {
    switch (region.type) {
    case 'bbox':
      history.replace('/show'
        +'/bbox:'
        +region.coords.map(x => x.toFixed(5)).join(',')
        +'/'+filterPart
      )
    break
    case 'polygon':
      history.replace('/show'
        +'/polygon:'
        +encodeURIComponent(
          polyline.encode(
            region.coords
          )
        )
        +'/'+filterPart
      )
    break
    case 'hot':
      history.replace('/show'
        +'/hot:'
        +region.id
        +'/'+filterPart
      )
    break
    default:
      throw new Error('unknown region type', region)
    }
  }
}

function parseRegionFromUrl(regionString) {
  if (!regionString) {
    return null
  }
  const [ regionType, regionContent ] = regionString.split(':')
  switch (regionType) {
    case 'bbox':
      return {
        type: 'bbox',
        coords: regionContent.split(',').map(Number)
      }
    break
    case 'polygon':
      return {
        type: 'polygon',
        coords: polyline.decode(decodeURIComponent(regionContent))
      }
    break
    case 'hot':
      return {
        type: 'hot',
        id: +regionContent
      }
    break
    default:
      throw new Error('unknown region type when parsing from URL', regionString)
  }
}
<|endoftext|>


<commit_before>class DesktopNotifications
{
    static requestPermission() {
        if (this._isSupported() && Notification.permission !== 'granted') {
            Notification.requestPermission(function (status) {
                if (Notification.permission !== status) {
                    Notification.permission = status;
                }
            });
        }
    }

    static isAllowed() {
        return this._isSupported() && Notification.permission === "granted";
    }

    static doNotify(title, body, url) {
        if (this.isAllowed()) {
            let notification = new Notification(title, {body: body, tag: url, icon: '/img/favicon.png'});

            notification.onshow = () => setTimeout(() => notification.close(), 5000);
            notification.onclick = function() {
                window.open(url);
            };

            return true;
        }

        return false;
    }

    static _isSupported() {
        return ('Notification' in window && window['Notification'] !== null);
    }
}

module.exports = DesktopNotifications;
<commit_msg>code formatting<commit_after>class DesktopNotifications {
  static requestPermission() {
    if (this._isSupported() && Notification.permission !== 'granted') {
      Notification.requestPermission(function (status) {
        if (Notification.permission !== status) {
          Notification.permission = status;
        }
      });
    }
  }

  static isAllowed() {
    return this._isSupported() && Notification.permission === "granted";
  }

  static doNotify(title, body, url) {
    if (this.isAllowed()) {
      let notification = new Notification(title, {body: body, tag: url, icon: '/img/favicon.png'});

      notification.onshow = () => setTimeout(() => notification.close(), 5000);
      notification.onclick = function () {
        window.open(url);
      };

      return true;
    }

    return false;
  }

  static _isSupported() {
    return ('Notification' in window && window['Notification'] !== null);
  }
}

module.exports = DesktopNotifications;
<|endoftext|>


<commit_before>import m from 'mithril';
import _ from 'underscore';
import h from '../h';
import HeaderMenuSearch from '../c/header-menu-search';
import menuProfile from '../c/menu-profile';
import models from '../models';
import { catarse } from '../api';

import { ExploreLightBox } from '../experiments/c/explore-light-box';

const menu = {
    oninit: function(vnode) {
        const exploreButtonBehavoir = h.RedrawStream((/** @type {Event} */ event) => {
            event.preventDefault();
            m.route.set('/explore?ref=ctrse_header');
        });
        const displayLightBox = h.RedrawStream(false);
        const user = h.getUser();
        const menuCss = () => {
            return `${vnode.attrs.menuTransparency ? 'overlayer' : ''} ${(vnode.attrs.withAlert || vnode.attrs.withFixedAlert) ? 'with-global-alert' : ''}`;
        };
        const homeAttrs = () => {
            if (vnode.attrs.absoluteHome) {
                return {
                    href: h.rootUrl(),
                    oncreate: m.route.link
                };
            }
            return {
                oncreate: m.route.link
            };
        };

        const filters = catarse.filtersVM;
        const categories = h.RedrawStream([]);
        models.category.getPageWithToken(filters({}).order({ name: 'asc' }).parameters()).then(categories);

        window.optimizeObserver.addListener((variantName) => {
            if (variantName === 'Explore Light Box') {
                exploreButtonBehavoir((/** @type {Event} */ event) => {
                    event.preventDefault();
                    displayLightBox(true);
                });
            }
        });

        vnode.state = {
            user,
            menuCss,
            homeAttrs,
            exploreButtonBehavoir,
            displayLightBox,
            categories,
        };
    },
    view: function({state, attrs}) {

        const exploreButtonBehavoir = state.exploreButtonBehavoir;
        const displayLightBox = state.displayLightBox;
        const categories = state.categories;

        return m('header.main-header', {
            class: state.menuCss()
        }, [

            (displayLightBox() ? m(ExploreLightBox, { onClose: () => displayLightBox(false), categories }) : null),

            m('.w-row', [
                m('.w-clearfix.w-col.w-col-8.w-col-small-8.w-col-tiny-8',
                    [
                        m('a.header-logo.w-inline-block[href=\'/?ref=ctrse_header\'][title=\'Catarse\']',
                            state.homeAttrs(),
                            m('img[alt=\'Logo big\'][src=\'/assets/catarse_bootstrap/logo_big.png\']')
                        ),
                        attrs.menuShort ? '' : m('div#menu-components', [
                            m('a.w-hidden-small.w-hidden-tiny.header-link.w-nav-link[href=\'https://crowdfunding.catarse.me/comece\']', 'Comece seu projeto'),
                            m(`a.w-hidden-small.w-hidden-tiny.header-link.w-nav-link[href=\'/${window.I18n.locale}/explore?ref=ctrse_header\']`, { onclick: exploreButtonBehavoir() },
                                'Explore'
                            ),
                            m(HeaderMenuSearch)
                        ])
                    ]
                ),
                m('.text-align-right.w-col.w-col-4.w-col-small-4.w-col-tiny-4', [
                    state.user ? m(menuProfile, { user: state.user }) : m(`a.w-nav-link.header-link.w-nav-link.btn-edit.u-right[href=\'/${window.I18n.locale}/login?ref=ctrse_header\']`, 'Login'),
                ])

            ]),
            attrs.menuShort ? '' : m('.header-controls-mobile.w-hidden-main.w-hidden-medium',
                [
                    m(`a.header-link.w-nav-link[href=\'/${window.I18n.locale}/start?ref=ctrse_header\']`,
                        { onclick: () => m.route.set('/start') },
                        'Comece seu projeto'
                    ),
                    m(`a.header-link.w-nav-link[href=\'/${window.I18n.locale}/explore?ref=ctrse_header\']`,
                        { onclick: exploreButtonBehavoir() },
                        'Explore'
                    )
                ]
            )
        ]);
    }
};

export default menu;
<commit_msg>Projetos populares como default do botão de explore do header<commit_after>import m from 'mithril';
import _ from 'underscore';
import h from '../h';
import HeaderMenuSearch from '../c/header-menu-search';
import menuProfile from '../c/menu-profile';
import models from '../models';
import { catarse } from '../api';

import { ExploreLightBox } from '../experiments/c/explore-light-box';

const menu = {
    oninit: function(vnode) {
        const exploreButtonBehavoir = h.RedrawStream((/** @type {Event} */ event) => {
            event.preventDefault();
            m.route.set('/explore?ref=ctrse_header&filter=all');
        });
        const displayLightBox = h.RedrawStream(false);
        const user = h.getUser();
        const menuCss = () => {
            return `${vnode.attrs.menuTransparency ? 'overlayer' : ''} ${(vnode.attrs.withAlert || vnode.attrs.withFixedAlert) ? 'with-global-alert' : ''}`;
        };
        const homeAttrs = () => {
            if (vnode.attrs.absoluteHome) {
                return {
                    href: h.rootUrl(),
                    oncreate: m.route.link
                };
            }
            return {
                oncreate: m.route.link
            };
        };

        const filters = catarse.filtersVM;
        const categories = h.RedrawStream([]);
        models.category.getPageWithToken(filters({}).order({ name: 'asc' }).parameters()).then(categories);

        window.optimizeObserver.addListener((variantName) => {
            if (variantName === 'Explore Light Box') {
                exploreButtonBehavoir((/** @type {Event} */ event) => {
                    event.preventDefault();
                    displayLightBox(true);
                });
            }
        });

        vnode.state = {
            user,
            menuCss,
            homeAttrs,
            exploreButtonBehavoir,
            displayLightBox,
            categories,
        };
    },
    view: function({state, attrs}) {

        const exploreButtonBehavoir = state.exploreButtonBehavoir;
        const displayLightBox = state.displayLightBox;
        const categories = state.categories;

        return m('header.main-header', {
            class: state.menuCss()
        }, [

            (displayLightBox() ? m(ExploreLightBox, { onClose: () => displayLightBox(false), categories }) : null),

            m('.w-row', [
                m('.w-clearfix.w-col.w-col-8.w-col-small-8.w-col-tiny-8',
                    [
                        m('a.header-logo.w-inline-block[href=\'/?ref=ctrse_header\'][title=\'Catarse\']',
                            state.homeAttrs(),
                            m('img[alt=\'Logo big\'][src=\'/assets/catarse_bootstrap/logo_big.png\']')
                        ),
                        attrs.menuShort ? '' : m('div#menu-components', [
                            m('a.w-hidden-small.w-hidden-tiny.header-link.w-nav-link[href=\'https://crowdfunding.catarse.me/comece\']', 'Comece seu projeto'),
                            m(`a.w-hidden-small.w-hidden-tiny.header-link.w-nav-link[href=\'/${window.I18n.locale}/explore?ref=ctrse_header\']`, { onclick: exploreButtonBehavoir() },
                                'Explore'
                            ),
                            m(HeaderMenuSearch)
                        ])
                    ]
                ),
                m('.text-align-right.w-col.w-col-4.w-col-small-4.w-col-tiny-4', [
                    state.user ? m(menuProfile, { user: state.user }) : m(`a.w-nav-link.header-link.w-nav-link.btn-edit.u-right[href=\'/${window.I18n.locale}/login?ref=ctrse_header\']`, 'Login'),
                ])

            ]),
            attrs.menuShort ? '' : m('.header-controls-mobile.w-hidden-main.w-hidden-medium',
                [
                    m(`a.header-link.w-nav-link[href=\'/${window.I18n.locale}/start?ref=ctrse_header\']`,
                        { onclick: () => m.route.set('/start') },
                        'Comece seu projeto'
                    ),
                    m(`a.header-link.w-nav-link[href=\'/${window.I18n.locale}/explore?ref=ctrse_header\']`,
                        { onclick: exploreButtonBehavoir() },
                        'Explore'
                    )
                ]
            )
        ]);
    }
};

export default menu;
<|endoftext|>


<commit_before>var express = require('express');
var bodyParser = require('body-parser');
var twilio = require('twilio');
var firebase = require('firebase');
var _ = require('lodash');

var config = require('./helpers/config');
var handle_error = require('./helpers/error_handler');
var utils = require('./helpers/utils');

var urls = utils.urls;
var http = require('http');

var ConsistentHashing = require('consistent-hashing');
var cons = new ConsistentHashing(["server_1", "server_2", "server_3"]);
var map_to_num = {};
map_to_num["server_1"] = '+12179190876';
map_to_num["server_2"] = '+12179190876';
map_to_num["server_3"] = '+12179190876';

var get_fwd_number = function(request, response) {
  var sender = request.body['From'];
  var msg = request.body['Body'];
  var key = sender+msg
  var server = cons.getNode(key);
  send_msg(map_to_num[server], sender, msg)
}

var send_msg = function(to, from, msg) {
  var client = twilio(config.TWILIO_ACCOUNT_SID, config.TWILIO_AUTH_TOKEN);
  client.sendMessage({
    to: to,
    from: from,
    body: msg,
  }, function(err, responseData) {
    if (err) {
      console.log('Error sending: ', err);
    }
    console.log(responseData.to);
    console.log(responseData.body);
  });
};

var app = express();
app.use(bodyParser.urlencoded({
  extended: true
}));

app.post('/sms', twilio.webhook(config.TWILIO_AUTH_TOKEN), get_fwd_number);
// var sms = require('./slave1');
// app.post('/sms', twilio.webhook(config.TWILIO_AUTH_TOKEN), sms);

app.get('/', function(req, res) {
  res.send('Hello World!');
});

var server = app.listen(80, function() {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Refuge listening at http://%s:%s', host, port);
});

<commit_msg>numbers for new slaves<commit_after>var express = require('express');
var bodyParser = require('body-parser');
var twilio = require('twilio');
var firebase = require('firebase');
var _ = require('lodash');

var config = require('./helpers/config');
var handle_error = require('./helpers/error_handler');
var utils = require('./helpers/utils');

var urls = utils.urls;
var http = require('http');

var ConsistentHashing = require('consistent-hashing');
var cons = new ConsistentHashing(["server_1", "server_2", "server_3"]);
var map_to_num = {};
map_to_num["server_1"] = '+12179190876';
map_to_num["server_2"] = '+12243243357';
map_to_num["server_3"] = '+18577284183';

var get_fwd_number = function(request, response) {
  var sender = request.body['From'];
  var msg = request.body['Body'];
  var key = sender+msg
  var server = cons.getNode(key);
  send_msg(map_to_num[server], sender, msg)
}

var send_msg = function(to, from, msg) {
  var client = twilio(config.TWILIO_ACCOUNT_SID, config.TWILIO_AUTH_TOKEN);
  client.sendMessage({
    to: to,
    from: from,
    body: msg,
  }, function(err, responseData) {
    if (err) {
      console.log('Error sending: ', err);
    }
    console.log(responseData.to);
    console.log(responseData.body);
  });
};

var app = express();
app.use(bodyParser.urlencoded({
  extended: true
}));

app.post('/sms', twilio.webhook(config.TWILIO_AUTH_TOKEN), get_fwd_number);
// var sms = require('./slave1');
// app.post('/sms', twilio.webhook(config.TWILIO_AUTH_TOKEN), sms);

app.get('/', function(req, res) {
  res.send('Hello World!');
});

var server = app.listen(80, function() {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Refuge listening at http://%s:%s', host, port);
});

<|endoftext|>


<commit_before>//= require ./lib/patterns
//= require ./lib/extensions

// See how that must be resolved without compromising the builder pattern

var
    esPhinx,
    Iterable,
    SearchContext,
    Search;

// IIFE
(function ($module) {
    "use strict";

    // closure (private static attribute)
    var
        NAME = "esPhinx",

        selectInBreadth = function (iterable, callback) {
            var
                strategy;

            if (iterable instanceof window.Node) {
                strategy = SearchContext.Proxy.new(Search.Graphs.BFS.Element
                                                   .new(iterable));
            } else {
                strategy = SearchContext.Proxy.new(Search.Graphs.BFS.Object
                                                   .new(iterable));
            }

            return strategy.research(callback);
        },

        resolveContext = function (context) {
            if (typeof context == "object") {
                if (context instanceof window.esPhinx ||
                    context instanceof Element) {
                    return context;
                }
            } else if (typeof context == "string") {
                // recursivity
                return window.esPhinx(context);
            }

            return window.document;
        },

        Extender = {
            extend: function (object, final, structure) {
                var
                    context,
                    strategy,
                    verbose = false,
                    propertyDescriptors = {
                        enumerable: true,
                        configurable: false
                    },

                    // create or mount the context. If there is trace and object type is an Object, but it doesn't exists, it will be created, else it will be mounted.
                    mountContext = function (methodName, trace, originalObject) {
                        var
                            context = originalObject,

                            callback = function (v) {
                                if (!context[v]) {
                                    context[v] = {};
                                }

                                context = context[v];
                            },

                            isAnAccessor = function (methodName, trace) {
                                return (methodName == "get" ||
                                        methodName == "set") && trace.length;
                            };

                        if ((trace.length &&
                             !isAnAccessor(methodName, trace)) ||
                            methodName != "get" && methodName != "set") {

                            trace.forEach(callback);
                        }

                        return context;
                    },

                    informeIf = function (verbose) {
                        if (verbose) {
                            console.warn("Property \"" + name +
                                "\" of class \"" +
                                Object.className(context) +
                                "\" can't be redefined because " +
                                "it's configured as read-only.");
                        }
                    },

                    hasAnyAccessor = function (body) {
                        return Object.implementsMethod(body, "get") ||
                         Object.implementsMethod(body, "set");
                    },

                    callback = function (body, name, trace) {

                        if (!Object.belongsToClass(body, Object) ||
                            // otherwise it will arrive there still
                            Object.empty(body) || hasAnyAccessor(body)) {

                            context = mountContext(name, trace, object);

                            // propertyDescriptors = JSON
                            //     .parse(JSON.parse(JSON.stringify("{\"" + name +
                            //     "\":" + JSON.stringify(propertyDescriptors) + "}")));

                            if (Object.belongsToClass(body, Object)){
                                if (hasAnyAccessor(body)) {
                                    delete propertyDescriptors.writable;
                                    delete propertyDescriptors.configurable;
                                    propertyDescriptors.get = body.get ||
                                        function () {};
                                    propertyDescriptors.set = body.set ||
                                        function () {};
                                } else if (Object.empty(body)) {
                                    propertyDescriptors.value = {};
                                }
                            } else {
                                if (typeof body == "function") {
                                    delete propertyDescriptors.enumerable;
                                }

                                propertyDescriptors.value = body;
                            }

                            try {
                                Object.defineProperty(context, name,
                                                      propertyDescriptors);
                            } catch (e) {
                                informeIf(verbose);
                            }

                            // restart propertyDescriptors
                            propertyDescriptors = {
                                enumerable: true,
                                configurable: false,
                                writable: !final
                            };
                        }

                    };

                if (!structure && (typeof final == "object" ||
                    typeof final == "function")) {
                    structure = final;
                }

                if (typeof final != "boolean") {
                    final = false;
                }
                propertyDescriptors.writable = !final;
                propertyDescriptors.configurable = false;

                strategy = SearchContext.Proxy.new(Search.Graphs.BFS.Object
                                                   .new(structure));
                strategy.research(callback);
            }
        };

    if (!$module.esPhinx) {

        Extender.extend($module, {
            esPhinx: function (selector, context) {
                var
                    parsed,
                    self = window.esPhinx,
                    mainReference = this,
                    collection = [],

                    callback = function (node) {
                        collection = collection.concat(Array
                            .from(node
                            .querySelectorAll(selector)))
                        .flatten();
                    },

                    hasElement = function (iterable) {
                        var
                            iterator,
                            response = false,

                            callback = function (object) {
                                if (object instanceof window.Element) {
                                    this.finalize();
                                    response = true;
                                }
                            };

                        iterator = Iterable.Proxy.new(iterable);
                        iterator.each(callback);
                        return response;
                    };

                if (!(mainReference instanceof self)) {
                    return new self(selector, context);
                }

                context = resolveContext(context);

                if (selector) {
                    if (selector instanceof self) {
                        return selector;
                    } else if (typeof selector == "function") {
                        // don't never pass a autoexecutable function as parameter
                        return window.document
                            .addEventListener("DOMContentLoaded",
                                              function (e) {
                            selector.call(self, self, e);
                        });
                    // get children "".match(/(>)(<.(?=(<\/)))/)[0]
                    // add support to XPath
                    } else if (typeof selector == "string") {
                        parsed = (new window.DOMParser())
                            .parseFromString(selector, "text/html");

                        if (parsed.head.childElementCount) {
                            collection = Array.from(parsed.head
                                                    .childNodes);
                        } else {
                            collection = Array.from(parsed.body
                                                    .childNodes);
                        }

                        if (!hasElement(collection)) {
                            collection = [];
                            if (Iterable.isIterable(context)) {
                                Array.from(context)
                                    .forEach(callback);
                            } else {
                                try {
                                    collection = Array.from(context
                                        .querySelectorAll(selector));
                                } catch (e) {}
                            }
                        }
                    } else if (selector instanceof window.Node) {
                        collection = [selector];
                    } else if (selector instanceof Object) {
                        collection = Array.from(selector);

                        if (!Object.belongsToClass(selector,
                            window.HTMLCollection) &&
                            collection.length) {
                            mainReference[0] = selector;

                            if (selector == window) {
                                collection = [];
                            }
                        }
                    }

                    Object.assign(mainReference, collection);
                }

                Extender.extend(mainReference, {
                    splice: Array.prototype.splice,

                    toString: function () {
                        return "[object " + NAME + "]";
                    }
                });

                Iterable.toIterable(mainReference);

                return mainReference;
            },

        });

        Extender.extend(esPhinx, {
            Extender: {}
        });

        Extender.extend(esPhinx.Extender, {
            extend: function (object, final, structure) {
                Extender.extend(object, final, structure);
            }
        });

    }

    esPhinx.Extender.extend(esPhinx, true, {
        extend: function () {
            this.Extender.extend(this, arguments[0], arguments[1]);
        }
    });

    esPhinx.Extender.extend(esPhinx.prototype, true, {
        extend: function () {
            esPhinx.Extender.extend(this, arguments[0], arguments[1]);
        }
    });

    esPhinx.extend(true, {

        selectByText: function (text, context) {
            var
                collection = [],

                callback = function (element) {
                    collection = collection.concat(document.evaluate(
                        "descendant-or-self::*[normalize-space(text())='" +
                        text.trim() + "']", element).elements()).flatten();
                };

            this.select(this(resolveContext(context)), callback);

            return esPhinx(collection);
        },

        isIterable: function (object) {
            return Iterable.isIterable(object);
        },

        selectInBreadth: function (collection, callback) {
            return selectInBreadth(collection, callback);
        },

        each: function (collection, startingIndex, finalIndex, callback) {
            var
                iterator = Iterable.Proxy.new(collection);

            iterator.each(startingIndex, finalIndex, callback);
        },

        reverseEach: function (collection, startingIndex, callback) {
            var
                iterator = Iterable.Proxy.new(collection);

            if (typeof startingIndex == "function") {
                callback = startingIndex;
            }

            iterator.reverseEach(startingIndex, callback);
        },

        select: function (collection, callback) {
            var
                iterator = Iterable.Proxy.new(collection);

            return iterator.select(callback);
        }

    });

})(window);

// recognize a element
// (^( *<)[a-z]+ *)( *((\/)|(>.*<\/[a-z]+))(> *)$)

// recognize attributes and values
// It's not possible capture attributes and their values, because their values can be given any character, which forces them to use ".+".
<commit_msg>Delete main.js<commit_after><|endoftext|>


<commit_before>/**
 * Circle body definition
 * @module bodies/circle
 * @requires geometries/circle
 */
Physics.body('circle', function( parent ){

    var defaults = {

    };

    return {

        /**
         * Initialization
         * @param  {Object} options Configuration options
         * @return {void}
         */
        init: function( options ){

            // call parent init method
            parent.init.call(this, options);

            options = Physics.util.extend({}, defaults, options);

            this.geometry = Physics.geometry('circle', {
                radius: options.radius
            });

            this.recalc();
        },

        /**
         * Recalculate properties. Call when body physical properties are changed.
         * @return {this}
         */
        recalc: function(){
            parent.recalc.call(this);
            // moment of inertia
            this.moi = this.mass * this.geometry.radius * this.geometry.radius / 2;
        }
    };
});
<commit_msg>set default radius for circle<commit_after>/**
 * Circle body definition
 * @module bodies/circle
 * @requires geometries/circle
 */
Physics.body('circle', function( parent ){

    var defaults = {
        radius: 1.0
    };

    return {

        /**
         * Initialization
         * @param  {Object} options Configuration options
         * @return {void}
         */
        init: function( options ){

            // call parent init method
            parent.init.call(this, options);

            options = Physics.util.extend({}, defaults, options);

            this.geometry = Physics.geometry('circle', {
                radius: options.radius
            });

            this.recalc();
        },

        /**
         * Recalculate properties. Call when body physical properties are changed.
         * @return {this}
         */
        recalc: function(){
            parent.recalc.call(this);
            // moment of inertia
            this.moi = this.mass * this.geometry.radius * this.geometry.radius / 2;
        }
    };
});
<|endoftext|>


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

/**
 * External dependencies
 */
import { storiesOf } from '@storybook/react';

/**
 * WordPress dependencies
 */
import { removeAllFilters, addFilter } from '@wordpress/hooks';

/**
 * Internal dependencies
 */
import SetupWrapper from '../assets/js/components/setup/setup-wrapper';
import { SetupMain as AnalyticsSetup } from '../assets/js/modules/analytics/setup/index';
import { fillFilterWithComponent } from '../assets/js/util';
import * as fixtures from '../assets/js/modules/analytics/datastore/__fixtures__';

import { STORE_NAME, ACCOUNT_CREATE, PROVISIONING_SCOPE } from '../assets/js/modules/analytics/datastore/constants';
import { STORE_NAME as CORE_SITE } from '../assets/js/googlesitekit/datastore/site/constants';
import { STORE_NAME as CORE_USER } from '../assets/js/googlesitekit/datastore/user/constants';
import { WithTestRegistry } from '../tests/js/utils';

function filterAnalyticsSetup() {
	global.googlesitekit.setup.moduleToSetup = 'analytics';

	removeAllFilters( 'googlesitekit.ModuleSetup-analytics' );
	addFilter(
		'googlesitekit.ModuleSetup-analytics',
		'googlesitekit.AnalyticsModuleSetup',
		fillFilterWithComponent( AnalyticsSetup )
	);
}

function Setup( props ) {
	return (
		<WithTestRegistry { ...props }>
			<SetupWrapper />
		</WithTestRegistry>
	);
}

storiesOf( 'Analytics Module/Setup', module )
	.add( 'Loading', () => {
		filterAnalyticsSetup();

		const setupRegistry = ( registry ) => {
			registry.dispatch( STORE_NAME ).setSettings( {} );
			registry.dispatch( STORE_NAME ).receiveGetExistingTag( null );
			registry.stores[ STORE_NAME ].store.dispatch( { type: 'START_FETCH_ACCOUNTS_PROPERTIES_PROFILES' } );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Start', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).setSettings( {} );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Start (with matched property)', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles, matchedProperty } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).setSettings( {} );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
			dispatch( STORE_NAME ).receiveMatchedProperty( matchedProperty );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Create Account Legacy (no accounts)', () => {
		filterAnalyticsSetup();

		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).setSettings( {} );
			dispatch( STORE_NAME ).receiveGetAccounts( [] );
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Create Account Legacy (new account option)', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).setSettings( {
				accountID: ACCOUNT_CREATE,
			} );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Create Account (scope not granted)', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( CORE_SITE ).receiveSiteInfo( {
				usingProxy: true,
				referenceSiteURL: 'http://example.com',
				timezone: 'America/Detroit',
				siteName: 'My Site Name',
			} );
			dispatch( CORE_USER ).receiveGetAuthentication( {
				authenticated: true,
				requiredScopes: [],
				grantedScopes: [],
			} );
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).setSettings( {
				accountID: ACCOUNT_CREATE,
			} );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Create Account (scope granted)', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( CORE_SITE ).receiveSiteInfo( {
				usingProxy: true,
				referenceSiteURL: 'http://example.com',
				timezone: 'America/Detroit',
				siteName: 'My Site Name',
			} );
			dispatch( CORE_USER ).receiveGetAuthentication( {
				authenticated: true,
				requiredScopes: [],
				grantedScopes: [ PROVISIONING_SCOPE ],
			} );
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).setSettings( {
				accountID: ACCOUNT_CREATE,
			} );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Existing Tag (with access)', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const existingTag = {
			accountID: properties[ 0 ].accountId,
			propertyID: properties[ 0 ].id,
		};

		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).setSettings( {} );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).receiveGetExistingTag( existingTag.propertyID );
			dispatch( STORE_NAME ).receiveGetTagPermission( {
				accountID: existingTag.accountID,
				permission: true,
			}, { propertyID: existingTag.propertyID } );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Existing Tag (no access)', () => {
		filterAnalyticsSetup();

		const existingTag = {
			accountID: '12345678',
			propertyID: 'UA-12345678-1',
		};
		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).setSettings( {} );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).receiveGetExistingTag( existingTag.propertyID );
			dispatch( STORE_NAME ).receiveGetTagPermission( {
				accountID: existingTag.accountID,
				permission: false,
			}, { propertyID: existingTag.propertyID } );
		};

		return <Setup callback={ setupRegistry } />;
	} )
;
<commit_msg>Fix Analytics setup loading state in storybook.<commit_after>/**
 * Analytics Setup stories.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import { storiesOf } from '@storybook/react';

/**
 * WordPress dependencies
 */
import { removeAllFilters, addFilter } from '@wordpress/hooks';

/**
 * Internal dependencies
 */
import SetupWrapper from '../assets/js/components/setup/setup-wrapper';
import { SetupMain as AnalyticsSetup } from '../assets/js/modules/analytics/setup/index';
import { fillFilterWithComponent } from '../assets/js/util';
import * as fixtures from '../assets/js/modules/analytics/datastore/__fixtures__';

import { STORE_NAME, ACCOUNT_CREATE, PROVISIONING_SCOPE } from '../assets/js/modules/analytics/datastore/constants';
import { STORE_NAME as CORE_SITE } from '../assets/js/googlesitekit/datastore/site/constants';
import { STORE_NAME as CORE_USER } from '../assets/js/googlesitekit/datastore/user/constants';
import { WithTestRegistry } from '../tests/js/utils';

function filterAnalyticsSetup() {
	global.googlesitekit.setup.moduleToSetup = 'analytics';

	removeAllFilters( 'googlesitekit.ModuleSetup-analytics' );
	addFilter(
		'googlesitekit.ModuleSetup-analytics',
		'googlesitekit.AnalyticsModuleSetup',
		fillFilterWithComponent( AnalyticsSetup )
	);
}

function Setup( props ) {
	return (
		<WithTestRegistry { ...props }>
			<SetupWrapper />
		</WithTestRegistry>
	);
}

storiesOf( 'Analytics Module/Setup', module )
	.add( 'Loading', () => {
		filterAnalyticsSetup();

		const setupRegistry = ( registry ) => {
			registry.dispatch( STORE_NAME ).setSettings( {} );
			registry.dispatch( STORE_NAME ).receiveGetExistingTag( null );
			registry.stores[ STORE_NAME ].store.dispatch( {
				type: 'START_FETCH_GET_ACCOUNTS_PROPERTIES_PROFILES',
				payload: { params: {} },
			} );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Start', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).setSettings( {} );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Start (with matched property)', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles, matchedProperty } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).setSettings( {} );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
			dispatch( STORE_NAME ).receiveMatchedProperty( matchedProperty );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Create Account Legacy (no accounts)', () => {
		filterAnalyticsSetup();

		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).setSettings( {} );
			dispatch( STORE_NAME ).receiveGetAccounts( [] );
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Create Account Legacy (new account option)', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).setSettings( {
				accountID: ACCOUNT_CREATE,
			} );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Create Account (scope not granted)', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( CORE_SITE ).receiveSiteInfo( {
				usingProxy: true,
				referenceSiteURL: 'http://example.com',
				timezone: 'America/Detroit',
				siteName: 'My Site Name',
			} );
			dispatch( CORE_USER ).receiveGetAuthentication( {
				authenticated: true,
				requiredScopes: [],
				grantedScopes: [],
			} );
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).setSettings( {
				accountID: ACCOUNT_CREATE,
			} );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Create Account (scope granted)', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( CORE_SITE ).receiveSiteInfo( {
				usingProxy: true,
				referenceSiteURL: 'http://example.com',
				timezone: 'America/Detroit',
				siteName: 'My Site Name',
			} );
			dispatch( CORE_USER ).receiveGetAuthentication( {
				authenticated: true,
				requiredScopes: [],
				grantedScopes: [ PROVISIONING_SCOPE ],
			} );
			dispatch( STORE_NAME ).receiveGetExistingTag( null );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).setSettings( {
				accountID: ACCOUNT_CREATE,
			} );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Existing Tag (with access)', () => {
		filterAnalyticsSetup();

		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const existingTag = {
			accountID: properties[ 0 ].accountId,
			propertyID: properties[ 0 ].id,
		};

		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).setSettings( {} );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).receiveGetExistingTag( existingTag.propertyID );
			dispatch( STORE_NAME ).receiveGetTagPermission( {
				accountID: existingTag.accountID,
				permission: true,
			}, { propertyID: existingTag.propertyID } );
		};

		return <Setup callback={ setupRegistry } />;
	} )
	.add( 'Existing Tag (no access)', () => {
		filterAnalyticsSetup();

		const existingTag = {
			accountID: '12345678',
			propertyID: 'UA-12345678-1',
		};
		const { accounts, properties, profiles } = fixtures.accountsPropertiesProfiles;
		const setupRegistry = ( { dispatch } ) => {
			dispatch( STORE_NAME ).setSettings( {} );
			dispatch( STORE_NAME ).receiveGetAccounts( accounts );
			dispatch( STORE_NAME ).receiveGetProperties( properties, { accountID: properties[ 0 ].accountId } );
			dispatch( STORE_NAME ).receiveGetProfiles( profiles, { propertyID: profiles[ 0 ].webPropertyId } );
			dispatch( STORE_NAME ).receiveGetExistingTag( existingTag.propertyID );
			dispatch( STORE_NAME ).receiveGetTagPermission( {
				accountID: existingTag.accountID,
				permission: false,
			}, { propertyID: existingTag.propertyID } );
		};

		return <Setup callback={ setupRegistry } />;
	} )
;
<|endoftext|>