<commit_before>var message_fetch = (function () {

var exports = {};

var consts = {
    backfill_idle_time: 10 * 1000,
    error_retry_time: 5000,
    backfill_batch_size: 1000,
    narrow_before: 50,
    narrow_after: 50,
    num_before_pointer: 200,
    num_after_pointer: 200,
    backward_batch_size: 100,
    forward_batch_size: 100,
    catch_up_batch_size: 1000,
};

function process_result(data, opts) {
    var messages = data.messages;

    if (!$('#connection-error').hasClass('get-events-error')) {
        ui_report.hide_error($("#connection-error"));
    }

    if (messages.length === 0 && current_msg_list === message_list.narrowed &&
        message_list.narrowed.empty()) {
        // Even after trying to load more messages, we have no
        // messages to display in this narrow.
        narrow.show_empty_narrow_message();
    }

    _.each(messages, message_store.set_message_booleans);
    messages = _.map(messages, message_store.add_message_metadata);

    // In case any of the newly fetched messages are new, add them to
    // our unread data structures.  It's important that this run even
    // when fetching in a narrow, since we might return unread
    // messages that aren't in the home view data set (e.g. on a muted
    // stream).
    message_util.do_unread_count_updates(messages);

    // If we're loading more messages into the home view, save them to
    // the message_list.all as well, as the home_msg_list is reconstructed
    // from message_list.all.
    if (opts.msg_list === home_msg_list) {
        message_util.add_old_messages(messages, message_list.all);
    }

    if (messages.length !== 0) {
        message_util.add_old_messages(messages, opts.msg_list);
    }

    activity.process_loaded_messages(messages);
    stream_list.update_streams_sidebar();
    pm_list.update_private_messages();
    stream_list.maybe_scroll_narrow_into_view();

    if (opts.cont !== undefined) {
        opts.cont(data);
    }
}

function get_messages_success(data, opts) {
    if (opts.num_before > 0) {
        opts.msg_list.fetch_status.finish_older_batch({
            found_oldest: data.found_oldest,
            history_limited: data.history_limited,
        });
        if (opts.msg_list === home_msg_list) {
            message_list.all.fetch_status.finish_older_batch({
                found_oldest: data.found_oldest,
                history_limited: data.history_limited,
            });
        }
        notifications.hide_or_show_history_limit_message(opts.msg_list);
    }

    if (opts.num_after > 0) {
        opts.msg_list.fetch_status.finish_newer_batch({
            found_newest: data.found_newest,
        });
        if (opts.msg_list === home_msg_list) {
            message_list.all.fetch_status.finish_newer_batch({
                found_newest: data.found_newest,
            });
        }
    }

    if (opts.msg_list.narrowed && opts.msg_list !== current_msg_list) {
        // We unnarrowed before receiving new messages so
        // don't bother processing the newly arrived messages.
        return;
    }
    if (!data) {
        // The server occasionally returns no data during a
        // restart.  Ignore those responses and try again
        setTimeout(function () {
            exports.load_messages(opts);
        }, 0);
        return;
    }

    process_result(data, opts);
    resize.resize_bottom_whitespace();
}

// This function modifies the data.narrow filters to use user IDs
// instead of emails string if it is supported. We currently don't set
// or convert the emails string to user IDs directly into the Filter code
// because doing so breaks the app in various modules that expect emails string.
function handle_user_ids_supported_operators(data) {
    var user_ids_supported_operators = ['pm-with'];

    if (data.narrow === undefined) {
        return data;
    }

    data.narrow = JSON.parse(data.narrow);
    data.narrow = _.map(data.narrow, function (filter) {
        if (user_ids_supported_operators.indexOf(filter.operator) !== -1) {
            filter.operand = people.emails_strings_to_user_ids_array(filter.operand);
        }

        return filter;
    });

    data.narrow = JSON.stringify(data.narrow);
    return data;
}

exports.load_messages = function (opts) {
    var data = {anchor: opts.anchor,
                num_before: opts.num_before,
                num_after: opts.num_after};

    if (opts.msg_list.narrowed && narrow_state.active()) {
        var operators = narrow_state.public_operators();
        if (page_params.narrow !== undefined) {
            operators = operators.concat(page_params.narrow);
        }
        data.narrow = JSON.stringify(operators);
    }
    if (opts.msg_list === home_msg_list && page_params.narrow_stream !== undefined) {
        data.narrow = JSON.stringify(page_params.narrow);
    }
    if (opts.use_first_unread_anchor) {
        data.use_first_unread_anchor = true;
    }

    if (opts.num_before > 0) {
        opts.msg_list.fetch_status.start_older_batch();
        if (opts.msg_list === home_msg_list) {
            message_list.all.fetch_status.start_older_batch();
        }
    }

    if (opts.num_after > 0) {
        opts.msg_list.fetch_status.start_newer_batch();
        if (opts.msg_list === home_msg_list) {
            message_list.all.fetch_status.start_newer_batch();
        }
    }

    data.client_gravatar = true;
    data = handle_user_ids_supported_operators(data);

    channel.get({
        url: '/json/messages',
        data: data,
        idempotent: true,
        success: function (data) {
            get_messages_success(data, opts);
        },
        error: function (xhr) {
            if (opts.msg_list.narrowed && opts.msg_list !== current_msg_list) {
                // We unnarrowed before getting an error so don't
                // bother trying again or doing further processing.
                return;
            }
            if (xhr.status === 400) {
                // Bad request: We probably specified a narrow operator
                // for a nonexistent stream or something.  We shouldn't
                // retry or display a connection error.
                //
                // FIXME: Warn the user when this has happened?
                var data = {
                    messages: [],
                };
                process_result(data, opts);
                return;
            }

            // We might want to be more clever here
            $('#connection-error').addClass("show");
            setTimeout(function () {
                exports.load_messages(opts);
            }, consts.error_retry_time);
        },
    });
};

exports.load_messages_for_narrow = function (opts) {
    var msg_list = message_list.narrowed;

    message_fetch.load_messages({
        anchor: opts.then_select_id.toFixed(),
        num_before: consts.narrow_before,
        num_after: consts.narrow_after,
        msg_list: msg_list,
        use_first_unread_anchor: opts.use_first_unread_anchor,
        cont: function () {
            message_scroll.hide_indicators();
            opts.cont();
        },
    });
};

exports.get_backfill_anchor = function (msg_list) {
    var oldest_message_id;

    if (msg_list === home_msg_list) {
        msg_list = message_list.all;
    }

    if (msg_list.first() === undefined) {
        oldest_message_id = page_params.pointer;
    } else {
        oldest_message_id = msg_list.first().id;
    }
    return oldest_message_id;
};

exports.get_frontfill_anchor = function (msg_list) {
    if (msg_list === home_msg_list) {
        msg_list = message_list.all;
    }

    var last_msg = msg_list.last();

    if (last_msg) {
        return last_msg.id;
    }

    return page_params.pointer;
};

exports.maybe_load_older_messages = function (opts) {
    // This function gets called when you scroll to the top
    // of your window, and you want to get messages older
    // than what the browers originally fetched.
    var msg_list = opts.msg_list;
    if (!msg_list.fetch_status.can_load_older_messages()) {
        // We may already be loading old messages or already
        // got the oldest one.
        return;
    }

    opts.show_loading();
    exports.do_backfill({
        msg_list: msg_list,
        num_before: consts.backward_batch_size,
        cont: function () {
            opts.hide_loading();
        },
    });
};

exports.do_backfill = function (opts) {
    var msg_list = opts.msg_list;
    var anchor = exports.get_backfill_anchor(msg_list).toFixed();

    exports.load_messages({
        anchor: anchor,
        num_before: opts.num_before,
        num_after: 0,
        msg_list: msg_list,
        cont: function () {
            if (opts.cont) {
                opts.cont();
            }
        },
    });
};

exports.maybe_load_newer_messages = function (opts) {
    // This function gets called when you scroll to the top
    // of your window, and you want to get messages newer
    // than what the browers originally fetched.
    var msg_list = opts.msg_list;

    if (!msg_list.fetch_status.can_load_newer_messages()) {
        // We may already be loading new messages or already
        // got the newest one.
        return;
    }

    var anchor = exports.get_frontfill_anchor(msg_list).toFixed();

    exports.load_messages({
        anchor: anchor,
        num_before: 0,
        num_after: consts.forward_batch_size,
        msg_list: msg_list,
    });
};

exports.start_backfilling_messages = function () {
    // backfill more messages after the user is idle
    $(document).idle({idle: consts.backfill_idle_time,
                      onIdle: function () {
                          exports.do_backfill({
                              num_before: consts.backfill_batch_size,
                              msg_list: home_msg_list,
                          });
                      }});
};

exports.initialize = function () {
    // get the initial message list
    function load_more(data) {
        // If we received the initially selected message, select it on the client side,
        // but not if the user has already selected another one during load.
        //
        // We fall back to the closest selected id, as the user may have removed
        // a stream from the home before already
        if (home_msg_list.selected_id() === -1 && !home_msg_list.empty()) {
            home_msg_list.select_id(page_params.pointer,
                                    {then_scroll: true, use_closest: true,
                                     target_scroll_offset: page_params.initial_offset});
        }

        if (data.found_newest) {
            server_events.home_view_loaded();
            exports.start_backfilling_messages();
            return;
        }

        // If we fall through here, we need to keep fetching more data, and
        // we'll call back to the function we're in.
        var messages = data.messages;
        var latest_id = messages[messages.length - 1].id;

        exports.load_messages({
            anchor: latest_id.toFixed(),
            num_before: 0,
            num_after: consts.catch_up_batch_size,
            msg_list: home_msg_list,
            cont: load_more,
        });

    }

    if (page_params.have_initial_messages) {
        exports.load_messages({
            anchor: page_params.pointer,
            num_before: consts.num_before_pointer,
            num_after: consts.num_after_pointer,
            msg_list: home_msg_list,
            cont: load_more,
        });
    } else {
        server_events.home_view_loaded();
    }
};

return exports;

}());
if (typeof module !== 'undefined') {
    module.exports = message_fetch;
}
window.message_fetch = message_fetch;
<commit_msg>message_fetch: Use user ID for sender and group-pm-with operator.<commit_after>var message_fetch = (function () {

var exports = {};

var consts = {
    backfill_idle_time: 10 * 1000,
    error_retry_time: 5000,
    backfill_batch_size: 1000,
    narrow_before: 50,
    narrow_after: 50,
    num_before_pointer: 200,
    num_after_pointer: 200,
    backward_batch_size: 100,
    forward_batch_size: 100,
    catch_up_batch_size: 1000,
};

function process_result(data, opts) {
    var messages = data.messages;

    if (!$('#connection-error').hasClass('get-events-error')) {
        ui_report.hide_error($("#connection-error"));
    }

    if (messages.length === 0 && current_msg_list === message_list.narrowed &&
        message_list.narrowed.empty()) {
        // Even after trying to load more messages, we have no
        // messages to display in this narrow.
        narrow.show_empty_narrow_message();
    }

    _.each(messages, message_store.set_message_booleans);
    messages = _.map(messages, message_store.add_message_metadata);

    // In case any of the newly fetched messages are new, add them to
    // our unread data structures.  It's important that this run even
    // when fetching in a narrow, since we might return unread
    // messages that aren't in the home view data set (e.g. on a muted
    // stream).
    message_util.do_unread_count_updates(messages);

    // If we're loading more messages into the home view, save them to
    // the message_list.all as well, as the home_msg_list is reconstructed
    // from message_list.all.
    if (opts.msg_list === home_msg_list) {
        message_util.add_old_messages(messages, message_list.all);
    }

    if (messages.length !== 0) {
        message_util.add_old_messages(messages, opts.msg_list);
    }

    activity.process_loaded_messages(messages);
    stream_list.update_streams_sidebar();
    pm_list.update_private_messages();
    stream_list.maybe_scroll_narrow_into_view();

    if (opts.cont !== undefined) {
        opts.cont(data);
    }
}

function get_messages_success(data, opts) {
    if (opts.num_before > 0) {
        opts.msg_list.fetch_status.finish_older_batch({
            found_oldest: data.found_oldest,
            history_limited: data.history_limited,
        });
        if (opts.msg_list === home_msg_list) {
            message_list.all.fetch_status.finish_older_batch({
                found_oldest: data.found_oldest,
                history_limited: data.history_limited,
            });
        }
        notifications.hide_or_show_history_limit_message(opts.msg_list);
    }

    if (opts.num_after > 0) {
        opts.msg_list.fetch_status.finish_newer_batch({
            found_newest: data.found_newest,
        });
        if (opts.msg_list === home_msg_list) {
            message_list.all.fetch_status.finish_newer_batch({
                found_newest: data.found_newest,
            });
        }
    }

    if (opts.msg_list.narrowed && opts.msg_list !== current_msg_list) {
        // We unnarrowed before receiving new messages so
        // don't bother processing the newly arrived messages.
        return;
    }
    if (!data) {
        // The server occasionally returns no data during a
        // restart.  Ignore those responses and try again
        setTimeout(function () {
            exports.load_messages(opts);
        }, 0);
        return;
    }

    process_result(data, opts);
    resize.resize_bottom_whitespace();
}

// This function modifies the data.narrow filters to use user IDs
// instead of emails string if it is supported. We currently don't set
// or convert the emails string to user IDs directly into the Filter code
// because doing so breaks the app in various modules that expect emails string.
function handle_user_ids_supported_operators(data) {
    var user_ids_supported_operators = ['pm-with'];
    var user_id_supported_operators = ['sender', 'group-pm-with'];

    if (data.narrow === undefined) {
        return data;
    }

    data.narrow = JSON.parse(data.narrow);
    data.narrow = _.map(data.narrow, function (filter) {
        if (user_ids_supported_operators.indexOf(filter.operator) !== -1) {
            filter.operand = people.emails_strings_to_user_ids_array(filter.operand);
        }

        if (user_id_supported_operators.indexOf(filter.operator) !== -1) {
            var person = people.get_by_email(filter.operand);
            if (person !== undefined) {
                filter.operand = person.user_id;
            }
        }

        return filter;
    });

    data.narrow = JSON.stringify(data.narrow);
    return data;
}

exports.load_messages = function (opts) {
    var data = {anchor: opts.anchor,
                num_before: opts.num_before,
                num_after: opts.num_after};

    if (opts.msg_list.narrowed && narrow_state.active()) {
        var operators = narrow_state.public_operators();
        if (page_params.narrow !== undefined) {
            operators = operators.concat(page_params.narrow);
        }
        data.narrow = JSON.stringify(operators);
    }
    if (opts.msg_list === home_msg_list && page_params.narrow_stream !== undefined) {
        data.narrow = JSON.stringify(page_params.narrow);
    }
    if (opts.use_first_unread_anchor) {
        data.use_first_unread_anchor = true;
    }

    if (opts.num_before > 0) {
        opts.msg_list.fetch_status.start_older_batch();
        if (opts.msg_list === home_msg_list) {
            message_list.all.fetch_status.start_older_batch();
        }
    }

    if (opts.num_after > 0) {
        opts.msg_list.fetch_status.start_newer_batch();
        if (opts.msg_list === home_msg_list) {
            message_list.all.fetch_status.start_newer_batch();
        }
    }

    data.client_gravatar = true;
    data = handle_user_ids_supported_operators(data);

    channel.get({
        url: '/json/messages',
        data: data,
        idempotent: true,
        success: function (data) {
            get_messages_success(data, opts);
        },
        error: function (xhr) {
            if (opts.msg_list.narrowed && opts.msg_list !== current_msg_list) {
                // We unnarrowed before getting an error so don't
                // bother trying again or doing further processing.
                return;
            }
            if (xhr.status === 400) {
                // Bad request: We probably specified a narrow operator
                // for a nonexistent stream or something.  We shouldn't
                // retry or display a connection error.
                //
                // FIXME: Warn the user when this has happened?
                var data = {
                    messages: [],
                };
                process_result(data, opts);
                return;
            }

            // We might want to be more clever here
            $('#connection-error').addClass("show");
            setTimeout(function () {
                exports.load_messages(opts);
            }, consts.error_retry_time);
        },
    });
};

exports.load_messages_for_narrow = function (opts) {
    var msg_list = message_list.narrowed;

    message_fetch.load_messages({
        anchor: opts.then_select_id.toFixed(),
        num_before: consts.narrow_before,
        num_after: consts.narrow_after,
        msg_list: msg_list,
        use_first_unread_anchor: opts.use_first_unread_anchor,
        cont: function () {
            message_scroll.hide_indicators();
            opts.cont();
        },
    });
};

exports.get_backfill_anchor = function (msg_list) {
    var oldest_message_id;

    if (msg_list === home_msg_list) {
        msg_list = message_list.all;
    }

    if (msg_list.first() === undefined) {
        oldest_message_id = page_params.pointer;
    } else {
        oldest_message_id = msg_list.first().id;
    }
    return oldest_message_id;
};

exports.get_frontfill_anchor = function (msg_list) {
    if (msg_list === home_msg_list) {
        msg_list = message_list.all;
    }

    var last_msg = msg_list.last();

    if (last_msg) {
        return last_msg.id;
    }

    return page_params.pointer;
};

exports.maybe_load_older_messages = function (opts) {
    // This function gets called when you scroll to the top
    // of your window, and you want to get messages older
    // than what the browers originally fetched.
    var msg_list = opts.msg_list;
    if (!msg_list.fetch_status.can_load_older_messages()) {
        // We may already be loading old messages or already
        // got the oldest one.
        return;
    }

    opts.show_loading();
    exports.do_backfill({
        msg_list: msg_list,
        num_before: consts.backward_batch_size,
        cont: function () {
            opts.hide_loading();
        },
    });
};

exports.do_backfill = function (opts) {
    var msg_list = opts.msg_list;
    var anchor = exports.get_backfill_anchor(msg_list).toFixed();

    exports.load_messages({
        anchor: anchor,
        num_before: opts.num_before,
        num_after: 0,
        msg_list: msg_list,
        cont: function () {
            if (opts.cont) {
                opts.cont();
            }
        },
    });
};

exports.maybe_load_newer_messages = function (opts) {
    // This function gets called when you scroll to the top
    // of your window, and you want to get messages newer
    // than what the browers originally fetched.
    var msg_list = opts.msg_list;

    if (!msg_list.fetch_status.can_load_newer_messages()) {
        // We may already be loading new messages or already
        // got the newest one.
        return;
    }

    var anchor = exports.get_frontfill_anchor(msg_list).toFixed();

    exports.load_messages({
        anchor: anchor,
        num_before: 0,
        num_after: consts.forward_batch_size,
        msg_list: msg_list,
    });
};

exports.start_backfilling_messages = function () {
    // backfill more messages after the user is idle
    $(document).idle({idle: consts.backfill_idle_time,
                      onIdle: function () {
                          exports.do_backfill({
                              num_before: consts.backfill_batch_size,
                              msg_list: home_msg_list,
                          });
                      }});
};

exports.initialize = function () {
    // get the initial message list
    function load_more(data) {
        // If we received the initially selected message, select it on the client side,
        // but not if the user has already selected another one during load.
        //
        // We fall back to the closest selected id, as the user may have removed
        // a stream from the home before already
        if (home_msg_list.selected_id() === -1 && !home_msg_list.empty()) {
            home_msg_list.select_id(page_params.pointer,
                                    {then_scroll: true, use_closest: true,
                                     target_scroll_offset: page_params.initial_offset});
        }

        if (data.found_newest) {
            server_events.home_view_loaded();
            exports.start_backfilling_messages();
            return;
        }

        // If we fall through here, we need to keep fetching more data, and
        // we'll call back to the function we're in.
        var messages = data.messages;
        var latest_id = messages[messages.length - 1].id;

        exports.load_messages({
            anchor: latest_id.toFixed(),
            num_before: 0,
            num_after: consts.catch_up_batch_size,
            msg_list: home_msg_list,
            cont: load_more,
        });

    }

    if (page_params.have_initial_messages) {
        exports.load_messages({
            anchor: page_params.pointer,
            num_before: consts.num_before_pointer,
            num_after: consts.num_after_pointer,
            msg_list: home_msg_list,
            cont: load_more,
        });
    } else {
        server_events.home_view_loaded();
    }
};

return exports;

}());
if (typeof module !== 'undefined') {
    module.exports = message_fetch;
}
window.message_fetch = message_fetch;
<|endoftext|>


<commit_before>$(function() {

	var timeToToggle = 300;

	// display additional options on load
	$(".expandbttn").addClass("advancedoptionsshowing");
	optionsDisplaying = true;

	function displayFileName(ev) {
		var files = ev.target.files || ev.dataTransfer.files;

		for (var i = 0, file; file = files[i]; i++) {
			var label = $("#"+ev.target.id).parent().find("#"+ev.target.id+"bttnlabel");
			label.html(file.name);
			label.css('color', '#00B226');
			$("#usecache"+ev.target.id).attr('disabled', 'disabled');
		}
	}

	function changePreviewHeight() {
		// var optionsHeight = $("#alloptions").height();

		// $("#prepare-wrapper").stop().animate({
		// 	height: optionsHeight
		// }, timeToToggle);

		// $("#preview").stop().animate({
		// 	height: optionsHeight
		// }, timeToToggle);
	}

	// Register the change callback on the file uploads
	$("#swfileselect").change(displayFileName);
	$("#lemfileselect").change(displayFileName);
	$("#consfileselect").change(displayFileName);
	$("#scfileselect").change(displayFileName);

	$(".bttnfilelabels").click( function() {
		var filetype = $(this).attr('id').replace('bttnlabel', '');

		if ($("#usecache"+filetype).attr('disabled') != 'disabled') {
			$(this).css('color', '#FF0000');
			$(this).text($(this).text().replace('(using stored)', ''));
			$("#usecache"+filetype).attr('disabled', 'disabled');
		}
	});

	//-----------------------------------------------------
	// var timeToToggle = 300;
	$("#stopwords").click( function() {
		$("#stopwordinput").slideToggle(timeToToggle, function(){
			changePreviewHeight();
		});
	});
	$("#prettystopwordsupload").click( function() {
		$("#swfileselect").click();
	});
	//-----------------------------------------------------
	$("#lemmas").click( function() {
		$("#lemmainput").slideToggle(timeToToggle, function(){
			changePreviewHeight();
		});
	});
	$("#prettylemmasupload").click( function() {
		$("#lemfileselect").click();
	});
	//-----------------------------------------------------
	$("#consolidations").click( function() {
		$("#consolidationsinput").slideToggle(timeToToggle, function(){
			changePreviewHeight();
		});
	});
	$("#prettyconsolidationsupload").click( function() {
		$("#consfileselect").click();
	});
	//-----------------------------------------------------
	$("#specialchars").click( function() {
		$("#specialcharsinput").slideToggle(timeToToggle, function(){
			changePreviewHeight();
		});
	});
	$("#prettyspecialcharsupload").click( function() {
		$("#scfileselect").click();
	});

	// display/hide additional options here
	$(".expandbttn").click(function(){
		if (optionsDisplaying){
			$(".expandbttn").removeClass("advancedoptionsshowing");
			optionsDisplaying = false;
		} else {
			$(".expandbttn").addClass("advancedoptionsshowing");
			optionsDisplaying = true;
		}

		$(".advancedoptions").animate({
			height: "toggle"
		}, 500);
	});
});

$(function() {
	var timeToToggle = 100;
	$("#punctbox").click( function() {
		if ($(this).children('input').is(':checked')) {
			$("#aposhyph").fadeIn(timeToToggle);
		}
		else {
			$("#aposhyph").fadeOut(timeToToggle);
		}
	});
});<commit_msg>Fixed the identifiers inside to the new names<commit_after>$(function() {
	var timeToToggle = 300;

	// display additional options on load
	$(".expandbttn").addClass("advancedoptionsshowing");
	optionsDisplaying = true;

	function displayFileName(ev) {
		var files = ev.target.files || ev.dataTransfer.files;

		for (var i = 0, file; file = files[i]; i++) {
			var label = $("#"+ev.target.id).parent().find("#"+ev.target.id+"bttnlabel");
			label.html(file.name);
			label.css('color', '#00B226');
			$("#usecache"+ev.target.id).attr('disabled', 'disabled');
		}
	}

	function changePreviewHeight() {
		var optionsHeight = $("#prepare-options").height();

		$("#prepare-wrapper").stop().animate({
			height: optionsHeight
		}, timeToToggle);

		$("#preview").stop().animate({
			height: optionsHeight
		}, timeToToggle);
	}

	// Register the change callback on the file uploads
	$("#swfileselect").change(displayFileName);
	$("#lemfileselect").change(displayFileName);
	$("#consfileselect").change(displayFileName);
	$("#scfileselect").change(displayFileName);

	$(".bttnfilelabels").click( function() {
		var filetype = $(this).attr('id').replace('bttnlabel', '');

		if ($("#usecache"+filetype).attr('disabled') != 'disabled') {
			$(this).css('color', '#FF0000');
			$(this).text($(this).text().replace('(using stored)', ''));
			$("#usecache"+filetype).attr('disabled', 'disabled');
		}
	});

	//-----------------------------------------------------
	$("#stopwords").click( function() {
		$("#stopwordinput").slideToggle(timeToToggle, function(){
			changePreviewHeight();
		});
	});
	$("#prettystopwordsupload").click( function() {
		$("#swfileselect").click();
	});
	//-----------------------------------------------------
	$("#lemmas").click( function() {
		$("#lemmainput").slideToggle(timeToToggle, function(){
			changePreviewHeight();
		});
	});
	$("#prettylemmasupload").click( function() {
		$("#lemfileselect").click();
	});
	//-----------------------------------------------------
	$("#consolidations").click( function() {
		$("#consolidationsinput").slideToggle(timeToToggle, function(){
			changePreviewHeight();
		});
	});
	$("#prettyconsolidationsupload").click( function() {
		$("#consfileselect").click();
	});
	//-----------------------------------------------------
	$("#specialchars").click( function() {
		$("#specialcharsinput").slideToggle(timeToToggle, function(){
			changePreviewHeight();
		});
	});
	$("#prettyspecialcharsupload").click( function() {
		$("#scfileselect").click();
	});

	// display/hide additional options here
	$(".expandbttn").click(function(){
		if (optionsDisplaying){
			$(".expandbttn").removeClass("advancedoptionsshowing");
			optionsDisplaying = false;
		} else {
			$(".expandbttn").addClass("advancedoptionsshowing");
			optionsDisplaying = true;
		}

		$(".advancedoptions").animate({
			height: "toggle"
		}, 500);
	});
});

$(function() {
	var timeToToggle = 100;
	$("#punctbox").click( function() {
		if ($(this).children('input').is(':checked')) {
			$("#aposhyph").fadeIn(timeToToggle);
		}
		else {
			$("#aposhyph").fadeOut(timeToToggle);
		}
	});
});<|endoftext|>


<commit_before>$("input").keyup(function(event){
    if(event.keyCode == 13){
        $("#search").click();
    }
});

$("#dropdown-wheat").off('click').on('click', function(){
    var html = $("#dropdown-wheat").text() + ' ';
    $("#default-option").html(html);
    $(".div-product").hide();
    $(".div-product.wheat").show();
    $("#n_results").text($(".div-product.wheat").length);
});

$("#dropdown-gluten-free").off('click').on('click', function(){
    var html = $("#dropdown-gluten-free").text() + ' ';
    $("#default-option").html(html);
    $(".div-product").hide();
    $(".div-product.gluten-free").show();
    $("#n_results").text($(".div-product.gluten-free").length);
});

$("#dropdown-all").off('click').on('click', function(){
    var html = $("#dropdown-all").text() + ' ';
    $("#default-option").html(html);
    $(".div-product").show();
    $("#n_results").text($(".div-product").length);
});

function confidenceTxt(n_people) {
    if (n_people < 33) {
        txt_confidence = '¡Cuidado! Sólo han revisado este producto ' + n_people + ' personas.';
    }
    if (n_people > 33 && n_people < 66) {
        txt_confidence = '¡No está nada mal! Al menos ' + n_people + ' personas han revisado el producto.';
    }
    if (n_people > 66) {
        txt_confidence = '¡GENIAL! Más de' + n_people + ' personas han revisado el producto.';
    }
    return txt_confidence;
}

function search(queryData, showBig, back) {
    var regex_non_words = XRegExp("[^\\p{L}\\s\\d]", "g");
    queryData = XRegExp.replace(queryData, regex_non_words, " ");
    var regex_spaces = XRegExp("\\p{Z}+", "g");
    queryData = XRegExp.replace(queryData, regex_spaces, " ");
    queryData = queryData.replace(/^ /gi, "");
    queryData = queryData.replace(/ $/gi, "");
    if ((queryData.match(/ /g) || []).length >= 1) {
        var query = queryData.replace(/ /g, '%26');
    }
    else {
        var query = queryData.replace(/ /g, '');
    }
    $.ajax({
        url: "/api/result?info=name::" + query + "&fulltextsearch=1",
    })
    .done(function( data ) {
        var n_products_added = 0;
        if ( console && console.log ) {
            $(".row.products").html("");
            $(".row.selected").remove();
            $("#search_term").text($("input").val());
            $("#search_term").text(queryData);

            if (data.length > 0) {
                $(".numbers").remove();
                $(".last-product").remove();
                for (i=0; i<data.length;i++) {
                    var col = $("
");
                    col.addClass("col-xs-12 col-sm-6 col-md-4 col-lg-3 div-product");
                    var product = $("
");
                    product.attr("id", "product-" + i);
                    product.addClass("product");
                    var brand = $("
");
                    brand.addClass("brand");
                    var name = $("
");
                    name.addClass("name");
                    var labels = $("
");
                    var oneLabel = false;
                    if (data[i]['info']['labelGlutenFree'] === 'yes') {
                        oneLabel = true;
                        var iconGlutenFree = $("");
                        iconGlutenFree.attr("src", "/static/img/green-gluten.svg");
                        labels.text(" Sin gluten");
                        labels.prepend(iconGlutenFree);
                        labels.addClass("gluten-free");
                        col.addClass("gluten-free ");
                        labels.addClass("classification-label");
                    }

                    if (data[i]['info']['ingredientsWheat'] === 'yes') {
                        oneLabel = true;
                        var iconWheat = $("");
                        iconWheat.attr("src", "/static/img/red-gluten.svg");
                        labels.text(" Trigo o trazas");
                        labels.prepend(iconWheat);
                        labels.addClass("wheat");
                        col.addClass("wheat");
                        labels.addClass("classification-label");
                    }

                    if (!oneLabel) {
                        labels.html("
");
                    }

                    product.append(brand);
                    product.append(name);
                    product.append(labels);

                    var divImg = $("
");
                    divImg.addClass("img-vertical-centered");
                    var productImg = $("");
                    productImg.attr("src", data[i]['info']['productImg']);
                    productImg.addClass("img img-responsive");
                    divImg.append(productImg);

                    name.text(data[i]['info']['name']);
                    product.append(divImg);
                    col.append(product);
                    if (oneLabel) {
                        n_products_added += 1;
                        $(".row.products").append(col);
                        $("#n_results").text(n_products_added);
                    }

                    // SELECTED PRODUCT CREATION
                    var row = $("
");
                    row.addClass("row selected");
                    row.attr("id", "product-" + i + "-big");
                    var colImg = $("
");
                    colImg.addClass("col-xs-12 col-sm-5 col-md-4 col-md-offset-2");
                    var colData = $("
");
                    colData.addClass("col-xs-12 col-sm-7 col-md-5");

                    var square = $("
");
                    square.addClass("square");
                    var productImgBig = $("");
                    productImgBig.attr("src", data[i]['info']['productImg']);
                    productImgBig.addClass("img-responsive img");

                    square.append(productImgBig);
                    colImg.append(square);

                    var aBrand = $("");
                    aBrand.text(data[i]['info']['brand']);
                    aBrand.addClass("brand");
                    aBrand.attr("href", "/results?name=" + data[i]['info']['brand']);
                    colData.append(aBrand);

                    var nameBig = $("
");
                    nameBig.addClass("name");
                    nameBig.text(data[i]['info']['name']);

                    colData.append(nameBig);

                    var classification = $("
");
                    var topDiv = $("
");
                    var bottomDiv = $("
");
                    bottomDiv.addClass("bottom");
                    classification.addClass("classification");
                    var labelsBig = $("
");
                    if (data[i]['info']['labelGlutenFree'] === 'yes') {
                        var iconGlutenFree = $("");
                        iconGlutenFree.attr("src", "/static/img/green-gluten.svg");
                        var txtClassification = " Sin gluten"
                        labelsBig.text(txtClassification);
                        labelsBig.prepend(iconGlutenFree);
                        labelsBig.addClass("gluten-free");
                        classification.addClass("gluten-free");
                        col.addClass("gluten-free");
                        labelsBig.addClass("classification-label");
                    }

                    if (data[i]['info']['ingredientsWheat'] === 'yes') {
                        var iconWheat = $("");
                        iconWheat.attr("src", "/static/img/red-gluten.svg");
                        var txtClassification = " Trigo o trazas"
                        labelsBig.text(txtClassification);
                        labelsBig.prepend(iconWheat);
                        labelsBig.addClass("wheat");
                        classification.addClass("wheat");
                        col.addClass("wheat");
                        labelsBig.addClass("classification-label");
                    }

                    topDiv.append(labelsBig);
                    var leftDiv = $("
");
                    leftDiv.addClass("onefold")
                    var rightDiv = $("
");
                    rightDiv.addClass("twofolds")
                    bottomDiv.append(leftDiv);
                    bottomDiv.append(rightDiv);

                    classification.append(topDiv);
                    classification.append(bottomDiv);

                    var explanation = $("
");
                    var confidence = $("
");
                    var explanation_large = $("
");
                    var txt_summary;
                    var txt_confidence;
                    if (data[i]['info']['labelGlutenFree'] === 'yes') {
                        var n_people = data[i]['info']['labelGlutenFreeSummary']['count'];
                        var n_people_agree = data[i]['info']['labelGlutenFreeSummary']['freq'];
                        var pct = ((n_people_agree * 100)/n_people);
                        //txt_summary =  n_people_agree + " de " + n_people + " personas (el " + pct + "%) han identificado el sello sin gluten en el producto.";
                        txt_summary =  "(" + n_people_agree + " de " + n_people + " usuarios)";
                        txt_confidence = confidenceTxt(n_people);
                    }
                    if (data[i]['info']['ingredientsWheat'] === 'yes') {
                        var n_people = data[i]['info']['ingredientsWheatSummary']['count'];
                        var n_people_agree = data[i]['info']['ingredientsWheatSummary']['freq'];
                        var pct = ((n_people_agree * 100)/n_people);
                        txt_summary =  "(" + n_people_agree + " de " + n_people + " usuarios)";

                        txt_confidence = confidenceTxt(n_people);
                    }
                    var txt = "El producto ha sido clasificado así:";
                    //explanation.text(txt);
                    //confidence.text(txt_confidence);
                    //explanation_large.text(txt_summary);

                    var text = "Clasificado por"

                    leftDiv.html("
Clasificado por

" + n_people + "

usuarios
");
                    rightDiv.html("
Producto clasificado

" + txtClassification + " por el

" + pct + "% " + txt_summary + "

Nivel de confianza
");

                    var legend =$("
");
                    var low =$("
");
                    var mid =$("
");
                    var high=$("
");
                    low.addClass("column");
                    mid.addClass("column");
                    high.addClass("column");
                    legend.append(low);
                    legend.append(mid);
                    legend.append(high);
                    legend.addClass("legend");

                    low.html('<svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"><rect class="low" x="0" y="0" width="30" height="30"/></svg>
<30
');

                    mid.html('<svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"><rect class="mid" x="0" y="0" width="30" height="30"/></svg>
<31 - 70>
');

                    high.html('<svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"><rect class="high" x="0" y="0" width="30" height="30"/></svg>
71
');

                    rightDiv.append(legend);

                    classification.append(explanation);
                    classification.append(confidence);
                    classification.append(explanation_large);

                    colData.append(classification);

                    var link = $("");
                    link.addClass("btn btn-primary");
                    link.attr("href", data[i]['info']['url']);
                    link.text("Ver en Soysuper");
                    var backCol = $("
");
                    backCol.addClass("col-xs-12 col-md-10 col-md-offset-2");
                    var backRow = $("
");
                    backRow.addClass("row row-back");
                    var back2 = $("");
                    back2.addClass("back hidden-md hidden-lg");
                    back2.html(' Atrás');
                    backCol.append(back2);
                    backRow.append(backCol);
                    colData.append(link);
                    colData.append(backRow);
                    row.append(colImg);
                    row.append(colData);
                    $(".selected-product > .container").append(row);

                    $(".back").off('click').on('click', function(){
                        if (back === '') {
                            $(".last-product").remove();
                            $(".row.products").show();
                            $(".found").show();
                            $(".selected-product").hide();
                            var id = $(this).data("close");
                            $("#" + id + "-big").hide();
                            $(".results").show();
                        }
                        else {
                            window.location.href = back;
                        }
                    });

                    $(".product").off('click').on('click', function(event){
                        var id = $(this).attr("id");
                        $(".numbers").hide();
                        $(".results").hide();
                        $(".row.products").hide();
                        $(".found").hide();
                        $(".selected-product").show();
                        $("#" + id + "-big").show();
                        $(".back").data("close", id);
                        window.scrollTo(0,0);
                    });

                }

                if (!showBig) {
                    console.log("NoShoBig");
                    $(".found").show();
                }
                else {
                    console.log("ShowBig");
                    $(".found").hide();
                }

            }
            else {
                var p = $("
");
                p.text("No results");
                $("#searchresults").append(p);
            }

        }

        if (showBig) {
            $("#product-0").click();
        }

    $(".last-product").remove();
    });

}

$("#search").off('click').on('click', function(){
    var data = $("input").val();
    search(data, false, '');
});

var params={};window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi,function(str,key,value){params[key] = value;});
if ('name' in params) {
    console.log(params['name']);
    var data = decodeURIComponent(params['name']);
    if ('showBig' in params) {
        if ('back' in params) {
            search(data, true, decodeURIComponent(params['back']));
        }
        else {
            search(data, true, '');
        }
    }
    else {
        search(data, false, '');
    }
}

<commit_msg>Remove last 3 p.<commit_after>$("input").keyup(function(event){
    if(event.keyCode == 13){
        $("#search").click();
    }
});

$("#dropdown-wheat").off('click').on('click', function(){
    var html = $("#dropdown-wheat").text() + ' ';
    $("#default-option").html(html);
    $(".div-product").hide();
    $(".div-product.wheat").show();
    $("#n_results").text($(".div-product.wheat").length);
});

$("#dropdown-gluten-free").off('click').on('click', function(){
    var html = $("#dropdown-gluten-free").text() + ' ';
    $("#default-option").html(html);
    $(".div-product").hide();
    $(".div-product.gluten-free").show();
    $("#n_results").text($(".div-product.gluten-free").length);
});

$("#dropdown-all").off('click').on('click', function(){
    var html = $("#dropdown-all").text() + ' ';
    $("#default-option").html(html);
    $(".div-product").show();
    $("#n_results").text($(".div-product").length);
});

function confidenceTxt(n_people) {
    if (n_people < 33) {
        txt_confidence = '¡Cuidado! Sólo han revisado este producto ' + n_people + ' personas.';
    }
    if (n_people > 33 && n_people < 66) {
        txt_confidence = '¡No está nada mal! Al menos ' + n_people + ' personas han revisado el producto.';
    }
    if (n_people > 66) {
        txt_confidence = '¡GENIAL! Más de' + n_people + ' personas han revisado el producto.';
    }
    return txt_confidence;
}

function search(queryData, showBig, back) {
    var regex_non_words = XRegExp("[^\\p{L}\\s\\d]", "g");
    queryData = XRegExp.replace(queryData, regex_non_words, " ");
    var regex_spaces = XRegExp("\\p{Z}+", "g");
    queryData = XRegExp.replace(queryData, regex_spaces, " ");
    queryData = queryData.replace(/^ /gi, "");
    queryData = queryData.replace(/ $/gi, "");
    if ((queryData.match(/ /g) || []).length >= 1) {
        var query = queryData.replace(/ /g, '%26');
    }
    else {
        var query = queryData.replace(/ /g, '');
    }
    $.ajax({
        url: "/api/result?info=name::" + query + "&fulltextsearch=1",
    })
    .done(function( data ) {
        var n_products_added = 0;
        if ( console && console.log ) {
            $(".row.products").html("");
            $(".row.selected").remove();
            $("#search_term").text($("input").val());
            $("#search_term").text(queryData);

            if (data.length > 0) {
                $(".numbers").remove();
                $(".last-product").remove();
                for (i=0; i<data.length;i++) {
                    var col = $("
");
                    col.addClass("col-xs-12 col-sm-6 col-md-4 col-lg-3 div-product");
                    var product = $("
");
                    product.attr("id", "product-" + i);
                    product.addClass("product");
                    var brand = $("
");
                    brand.addClass("brand");
                    var name = $("
");
                    name.addClass("name");
                    var labels = $("
");
                    var oneLabel = false;
                    if (data[i]['info']['labelGlutenFree'] === 'yes') {
                        oneLabel = true;
                        var iconGlutenFree = $("");
                        iconGlutenFree.attr("src", "/static/img/green-gluten.svg");
                        labels.text(" Sin gluten");
                        labels.prepend(iconGlutenFree);
                        labels.addClass("gluten-free");
                        col.addClass("gluten-free ");
                        labels.addClass("classification-label");
                    }

                    if (data[i]['info']['ingredientsWheat'] === 'yes') {
                        oneLabel = true;
                        var iconWheat = $("");
                        iconWheat.attr("src", "/static/img/red-gluten.svg");
                        labels.text(" Trigo o trazas");
                        labels.prepend(iconWheat);
                        labels.addClass("wheat");
                        col.addClass("wheat");
                        labels.addClass("classification-label");
                    }

                    if (!oneLabel) {
                        labels.html("
");
                    }

                    product.append(brand);
                    product.append(name);
                    product.append(labels);

                    var divImg = $("
");
                    divImg.addClass("img-vertical-centered");
                    var productImg = $("");
                    productImg.attr("src", data[i]['info']['productImg']);
                    productImg.addClass("img img-responsive");
                    divImg.append(productImg);

                    name.text(data[i]['info']['name']);
                    product.append(divImg);
                    col.append(product);
                    if (oneLabel) {
                        n_products_added += 1;
                        $(".row.products").append(col);
                        $("#n_results").text(n_products_added);
                    }

                    // SELECTED PRODUCT CREATION
                    var row = $("
");
                    row.addClass("row selected");
                    row.attr("id", "product-" + i + "-big");
                    var colImg = $("
");
                    colImg.addClass("col-xs-12 col-sm-5 col-md-4 col-md-offset-2");
                    var colData = $("
");
                    colData.addClass("col-xs-12 col-sm-7 col-md-5");

                    var square = $("
");
                    square.addClass("square");
                    var productImgBig = $("");
                    productImgBig.attr("src", data[i]['info']['productImg']);
                    productImgBig.addClass("img-responsive img");

                    square.append(productImgBig);
                    colImg.append(square);

                    var aBrand = $("");
                    aBrand.text(data[i]['info']['brand']);
                    aBrand.addClass("brand");
                    aBrand.attr("href", "/results?name=" + data[i]['info']['brand']);
                    colData.append(aBrand);

                    var nameBig = $("
");
                    nameBig.addClass("name");
                    nameBig.text(data[i]['info']['name']);

                    colData.append(nameBig);

                    var classification = $("
");
                    var topDiv = $("
");
                    var bottomDiv = $("
");
                    bottomDiv.addClass("bottom");
                    classification.addClass("classification");
                    var labelsBig = $("
");
                    if (data[i]['info']['labelGlutenFree'] === 'yes') {
                        var iconGlutenFree = $("");
                        iconGlutenFree.attr("src", "/static/img/green-gluten.svg");
                        var txtClassification = " Sin gluten"
                        labelsBig.text(txtClassification);
                        labelsBig.prepend(iconGlutenFree);
                        labelsBig.addClass("gluten-free");
                        classification.addClass("gluten-free");
                        col.addClass("gluten-free");
                        labelsBig.addClass("classification-label");
                    }

                    if (data[i]['info']['ingredientsWheat'] === 'yes') {
                        var iconWheat = $("");
                        iconWheat.attr("src", "/static/img/red-gluten.svg");
                        var txtClassification = " Trigo o trazas"
                        labelsBig.text(txtClassification);
                        labelsBig.prepend(iconWheat);
                        labelsBig.addClass("wheat");
                        classification.addClass("wheat");
                        col.addClass("wheat");
                        labelsBig.addClass("classification-label");
                    }

                    topDiv.append(labelsBig);
                    var leftDiv = $("
");
                    leftDiv.addClass("onefold")
                    var rightDiv = $("
");
                    rightDiv.addClass("twofolds")
                    bottomDiv.append(leftDiv);
                    bottomDiv.append(rightDiv);

                    classification.append(topDiv);
                    classification.append(bottomDiv);

                    var explanation = $("
");
                    var confidence = $("
");
                    var explanation_large = $("
");
                    var txt_summary;
                    var txt_confidence;
                    if (data[i]['info']['labelGlutenFree'] === 'yes') {
                        var n_people = data[i]['info']['labelGlutenFreeSummary']['count'];
                        var n_people_agree = data[i]['info']['labelGlutenFreeSummary']['freq'];
                        var pct = ((n_people_agree * 100)/n_people);
                        //txt_summary =  n_people_agree + " de " + n_people + " personas (el " + pct + "%) han identificado el sello sin gluten en el producto.";
                        txt_summary =  "(" + n_people_agree + " de " + n_people + " usuarios)";
                        txt_confidence = confidenceTxt(n_people);
                    }
                    if (data[i]['info']['ingredientsWheat'] === 'yes') {
                        var n_people = data[i]['info']['ingredientsWheatSummary']['count'];
                        var n_people_agree = data[i]['info']['ingredientsWheatSummary']['freq'];
                        var pct = ((n_people_agree * 100)/n_people);
                        txt_summary =  "(" + n_people_agree + " de " + n_people + " usuarios)";

                        txt_confidence = confidenceTxt(n_people);
                    }
                    var txt = "El producto ha sido clasificado así:";
                    //explanation.text(txt);
                    //confidence.text(txt_confidence);
                    //explanation_large.text(txt_summary);

                    var text = "Clasificado por"

                    leftDiv.html("
Clasificado por

" + n_people + "

usuarios
");
                    rightDiv.html("
Producto clasificado

" + txtClassification + " por el

" + pct + "% " + txt_summary + "

Nivel de confianza
");

                    var legend =$("
");
                    var low =$("
");
                    var mid =$("
");
                    var high=$("
");
                    low.addClass("column");
                    mid.addClass("column");
                    high.addClass("column");
                    legend.append(low);
                    legend.append(mid);
                    legend.append(high);
                    legend.addClass("legend");

                    low.html('<svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"><rect class="low" x="0" y="0" width="30" height="30"/></svg>
<30
');

                    mid.html('<svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"><rect class="mid" x="0" y="0" width="30" height="30"/></svg>
<31 - 70>
');

                    high.html('<svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"><rect class="high" x="0" y="0" width="30" height="30"/></svg>
71
');

                    rightDiv.append(legend);

                    // classification.append(explanation);
                    // classification.append(confidence);
                    // classification.append(explanation_large);

                    colData.append(classification);

                    var link = $("");
                    link.addClass("btn btn-primary");
                    link.attr("href", data[i]['info']['url']);
                    link.text("Ver en Soysuper");
                    var backCol = $("
");
                    backCol.addClass("col-xs-12 col-md-10 col-md-offset-2");
                    var backRow = $("
");
                    backRow.addClass("row row-back");
                    var back2 = $("");
                    back2.addClass("back hidden-md hidden-lg");
                    back2.html(' Atrás');
                    backCol.append(back2);
                    backRow.append(backCol);
                    colData.append(link);
                    colData.append(backRow);
                    row.append(colImg);
                    row.append(colData);
                    $(".selected-product > .container").append(row);

                    $(".back").off('click').on('click', function(){
                        if (back === '') {
                            $(".last-product").remove();
                            $(".row.products").show();
                            $(".found").show();
                            $(".selected-product").hide();
                            var id = $(this).data("close");
                            $("#" + id + "-big").hide();
                            $(".results").show();
                        }
                        else {
                            window.location.href = back;
                        }
                    });

                    $(".product").off('click').on('click', function(event){
                        var id = $(this).attr("id");
                        $(".numbers").hide();
                        $(".results").hide();
                        $(".row.products").hide();
                        $(".found").hide();
                        $(".selected-product").show();
                        $("#" + id + "-big").show();
                        $(".back").data("close", id);
                        window.scrollTo(0,0);
                    });

                }

                if (!showBig) {
                    console.log("NoShoBig");
                    $(".found").show();
                }
                else {
                    console.log("ShowBig");
                    $(".found").hide();
                }

            }
            else {
                var p = $("
");
                p.text("No results");
                $("#searchresults").append(p);
            }

        }

        if (showBig) {
            $("#product-0").click();
        }

    $(".last-product").remove();
    });

}

$("#search").off('click').on('click', function(){
    var data = $("input").val();
    search(data, false, '');
});

var params={};window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi,function(str,key,value){params[key] = value;});
if ('name' in params) {
    console.log(params['name']);
    var data = decodeURIComponent(params['name']);
    if ('showBig' in params) {
        if ('back' in params) {
            search(data, true, decodeURIComponent(params['back']));
        }
        else {
            search(data, true, '');
        }
    }
    else {
        search(data, false, '');
    }
}

<|endoftext|>


<commit_before>// tipsy, facebook style tooltips for jquery
// version 1.0.0a
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
// released under the MIT license

(function($) {

    function maybeCall(thing, ctx) {
        return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
    };

    function isElementInDOM(ele) {
      while (ele = ele.parentNode) {
        if (ele == document) return true;
      }
      return false;
    };

    function Tipsy(element, options) {
        this.$element = $(element);
        this.options = options;
        this.enabled = true;
        this.fixTitle();
    };

    Tipsy.prototype = {
        show: function() {
            var title = this.getTitle();
            if (title && this.enabled) {
                var $tip = this.tip();

                $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
                $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
                $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body);

                var pos = $.extend({}, this.$element.offset(), {
                    width: this.$element[0].offsetWidth,
                    height: this.$element[0].offsetHeight
                });

                var actualWidth = $tip[0].offsetWidth,
                    actualHeight = $tip[0].offsetHeight,
                    gravity = maybeCall(this.options.gravity, this.$element[0]);

                var tp;
                switch (gravity.charAt(0)) {
                    case 'n':
                        tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
                        break;
                    case 's':
                        tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
                        break;
                    case 'e':
                        tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
                        break;
                    case 'w':
                        tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
                        break;
                }

                if (gravity.length == 2) {
                    if (gravity.charAt(1) == 'w') {
                        tp.left = pos.left + pos.width / 2 - 15;
                    } else {
                        tp.left = pos.left + pos.width / 2 - actualWidth + 15;
                    }
                }

                $tip.css(tp).addClass('tipsy-' + gravity);
                $tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
                if (this.options.className) {
                    $tip.addClass(maybeCall(this.options.className, this.$element[0]));
                }

                if (this.options.fade) {
                    $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
                } else {
                    $tip.css({visibility: 'visible', opacity: this.options.opacity});
                }
            }
        },

        hide: function() {
            if (this.options.fade) {
                this.tip().stop().fadeOut(function() { $(this).remove(); });
            } else {
                this.tip().remove();
            }
        },

        fixTitle: function() {
            var $e = this.$element;
            if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') {
                $e.attr('original-title', $e.attr('title') || '').removeAttr('title');
            }
        },

        getTitle: function() {
            var title, $e = this.$element, o = this.options;
            this.fixTitle();
            var title, o = this.options;
            if (typeof o.title == 'string') {
                title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
            } else if (typeof o.title == 'function') {
                title = o.title.call($e[0]);
            }
            title = ('' + title).replace(/(^\s*|\s*$)/, "");
            return title || o.fallback;
        },

        tip: function() {
            if (!this.$tip) {
                this.$tip = $('

').html('

');
                this.$tip.data('tipsy-pointee', this.$element[0]);
            }
            return this.$tip;
        },

        validate: function() {
            if (!this.$element[0].parentNode) {
                this.hide();
                this.$element = null;
                this.options = null;
            }
        },

        enable: function() { this.enabled = true; },
        disable: function() { this.enabled = false; },
        toggleEnabled: function() { this.enabled = !this.enabled; }
    };

    $.fn.tipsy = function(options) {

        if (options === true) {
            return this.data('tipsy');
        } else if (typeof options == 'string') {
            var tipsy = this.data('tipsy');
            if (tipsy) tipsy[options]();
            return this;
        }

        options = $.extend({}, $.fn.tipsy.defaults, options);

        function get(ele) {
            var tipsy = $.data(ele, 'tipsy');
            if (!tipsy) {
                tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
                $.data(ele, 'tipsy', tipsy);
            }
            return tipsy;
        }

        function enter() {
            var tipsy = get(this);
            tipsy.hoverState = 'in';
            if (options.delayIn == 0) {
                tipsy.show();
            } else {
                tipsy.fixTitle();
                setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
            }
        };

        function leave() {
            var tipsy = get(this);
            tipsy.hoverState = 'out';
            if (options.delayOut == 0) {
                tipsy.hide();
            } else {
                setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut);
            }
        };

        if (!options.live) this.each(function() { get(this); });

        if (options.trigger != 'manual') {
            var binder   = options.live ? 'live' : 'bind',
                eventIn  = options.trigger == 'hover' ? 'mouseenter' : 'focus',
                eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
            this[binder](eventIn, enter)[binder](eventOut, leave);
        }

        return this;

    };

    $.fn.tipsy.defaults = {
        className: null,
        delayIn: 0,
        delayOut: 0,
        fade: false,
        fallback: '',
        gravity: 'n',
        html: false,
        live: false,
        offset: 0,
        opacity: 0.8,
        title: 'title',
        trigger: 'hover'
    };

    $.fn.tipsy.revalidate = function() {
      $('.tipsy').each(function() {
        var pointee = $.data(this, 'tipsy-pointee');
        if (!pointee || !isElementInDOM(pointee)) {
          $(this).remove();
        }
      });
    };

    // Overwrite this method to provide options on a per-element basis.
    // For example, you could store the gravity in a 'tipsy-gravity' attribute:
    // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
    // (remember - do not modify 'options' in place!)
    $.fn.tipsy.elementOptions = function(ele, options) {
        return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
    };

    $.fn.tipsy.autoNS = function() {
        return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
    };

    $.fn.tipsy.autoWE = function() {
        return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
    };

    /**
     * yields a closure of the supplied parameters, producing a function that takes
     * no arguments and is suitable for use as an autogravity function like so:
     *
     * @param margin (int) - distance from the viewable region edge that an
     *        element should be before setting its tooltip's gravity to be away
     *        from that edge.
     * @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer
     *        if there are no viewable region edges effecting the tooltip's
     *        gravity. It will try to vary from this minimally, for example,
     *        if 'sw' is preferred and an element is near the right viewable
     *        region edge, but not the top edge, it will set the gravity for
     *        that element's tooltip to be 'se', preserving the southern
     *        component.
     */
     $.fn.tipsy.autoBounds = function(margin, prefer) {
		return function() {
			var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)},
			    boundTop = $(document).scrollTop() + margin,
			    boundLeft = $(document).scrollLeft() + margin,
			    $this = $(this);

			if ($this.offset().top < boundTop) dir.ns = 'n';
			if ($this.offset().left < boundLeft) dir.ew = 'w';
			if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e';
			if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's';

			return dir.ns + (dir.ew ? dir.ew : '');
		}
	};

})(jQuery);
<commit_msg>update tipsy with SVG support fork. Fixed #109<commit_after>// tipsy, facebook style tooltips for jquery
// version 1.0.0a
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
// (c) 2013 Devon Meunier <devon@ajah.ca>
// released under the MIT license

(function($) {

    function maybeCall(thing, ctx) {
        return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
    }

    function isElementInDOM(ele) {
      ele = ele.parentNode;
      while (ele) {
        if (ele == document) return true;
        else ele = ele.parentNode;
      }
      return false;
    }

    function Tipsy(element, options) {
        this.$element = $(element);
        this.options = options;
        this.enabled = true;
        this.fixTitle();
    }

    Tipsy.prototype = {
        show: function() {
            var title = this.getTitle();
            if (title && this.enabled) {
                var $tip = this.tip();

                $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
                $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
                $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body);

                var pos;
                try {
                  pos = $.extend({}, this.$element.offset(), {
                    width: this.$element[0].getBBox().width,
                    height: this.$element[0].getBBox().height
                  });
                }
                catch (TypeError) {
                  pos = $.extend({}, this.$element.offset(), {
                      width: this.$element[0].offsetWidth,
                      height: this.$element[0].offsetHeight
                  });
                }

                var actualWidth = $tip[0].offsetWidth,
                    actualHeight = $tip[0].offsetHeight,
                    gravity = maybeCall(this.options.gravity, this.$element[0]);

                var tp;
                switch (gravity.charAt(0)) {
                    case 'n':
                        tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
                        break;
                    case 's':
                        tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
                        break;
                    case 'e':
                        tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
                        break;
                    case 'w':
                        tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
                        break;
                }

                if (gravity.length == 2) {
                    if (gravity.charAt(1) == 'w') {
                        tp.left = pos.left + pos.width / 2 - 15;
                    } else {
                        tp.left = pos.left + pos.width / 2 - actualWidth + 15;
                    }
                }

                $tip.css(tp).addClass('tipsy-' + gravity);
                $tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
                if (this.options.className) {
                    $tip.addClass(maybeCall(this.options.className, this.$element[0]));
                }

                if (this.options.fade) {
                    $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
                } else {
                    $tip.css({visibility: 'visible', opacity: this.options.opacity});
                }
            }
        },

        hide: function() {
            if (this.options.fade) {
                this.tip().stop().fadeOut(function() { $(this).remove(); });
            } else {
                this.tip().remove();
            }
        },

        fixTitle: function() {
            var $e = this.$element;
            if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') {
                $e.attr('original-title', $e.attr('title') || '').removeAttr('title');
            }
        },

        getTitle: function() {
            var title, $e = this.$element, o = this.options;
            this.fixTitle();
            if (typeof o.title == 'string') {
                title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
            } else if (typeof o.title == 'function') {
                title = o.title.call($e[0]);
            }
            title = ('' + title).replace(/(^\s*|\s*$)/, "");
            return title || o.fallback;
        },

        tip: function() {
            if (!this.$tip) {
                this.$tip = $('

').html('

');
                this.$tip.data('tipsy-pointee', this.$element[0]);
            }
            return this.$tip;
        },

        validate: function() {
            if (!this.$element[0].parentNode) {
                this.hide();
                this.$element = null;
                this.options = null;
            }
        },

        enable: function() { this.enabled = true; },
        disable: function() { this.enabled = false; },
        toggleEnabled: function() { this.enabled = !this.enabled; }
    };

    $.fn.tipsy = function(options) {

        if (options === true) {
            return this.data('tipsy');
        } else if (typeof options == 'string') {
            var tipsy = this.data('tipsy');
            if (tipsy) tipsy[options]();
            return this;
        }

        options = $.extend({}, $.fn.tipsy.defaults, options);

        function get(ele) {
            var tipsy = $.data(ele, 'tipsy');
            if (!tipsy) {
                tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
                $.data(ele, 'tipsy', tipsy);
            }
            return tipsy;
        }

        function enter() {
            var tipsy = get(this);
            tipsy.hoverState = 'in';
            if (options.delayIn === 0) {
                tipsy.show();
            } else {
                tipsy.fixTitle();
                setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
            }
        }

        function leave() {
            var tipsy = get(this);
            tipsy.hoverState = 'out';
            if (options.delayOut === 0) {
                tipsy.hide();
            } else {
                setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut);
            }
        }

        if (!options.live) this.each(function() { get(this); });

        if (options.trigger != 'manual') {
            var binder   = options.live ? 'live' : 'bind',
                eventIn  = options.trigger == 'hover' ? 'mouseenter' : 'focus',
                eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
            this[binder](eventIn, enter)[binder](eventOut, leave);
        }

        return this;

    };

    $.fn.tipsy.defaults = {
        className: null,
        delayIn: 0,
        delayOut: 0,
        fade: false,
        fallback: '',
        gravity: 'n',
        html: false,
        live: false,
        offset: 0,
        opacity: 0.8,
        title: 'title',
        trigger: 'hover'
    };

    $.fn.tipsy.revalidate = function() {
      $('.tipsy').each(function() {
        var pointee = $.data(this, 'tipsy-pointee');
        if (!pointee || !isElementInDOM(pointee)) {
          $(this).remove();
        }
      });
    };

    // Overwrite this method to provide options on a per-element basis.
    // For example, you could store the gravity in a 'tipsy-gravity' attribute:
    // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
    // (remember - do not modify 'options' in place!)
    $.fn.tipsy.elementOptions = function(ele, options) {
        return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
    };

    $.fn.tipsy.autoNS = function() {
        return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
    };

    $.fn.tipsy.autoWE = function() {
        return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
    };

    /**
     * yields a closure of the supplied parameters, producing a function that takes
     * no arguments and is suitable for use as an autogravity function like so:
     *
     * @param margin (int) - distance from the viewable region edge that an
     *        element should be before setting its tooltip's gravity to be away
     *        from that edge.
     * @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer
     *        if there are no viewable region edges effecting the tooltip's
     *        gravity. It will try to vary from this minimally, for example,
     *        if 'sw' is preferred and an element is near the right viewable
     *        region edge, but not the top edge, it will set the gravity for
     *        that element's tooltip to be 'se', preserving the southern
     *        component.
     */
     $.fn.tipsy.autoBounds = function(margin, prefer) {
		return function() {
			var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)},
          boundTop = $(document).scrollTop() + margin,
          boundLeft = $(document).scrollLeft() + margin,
          $this = $(this);

			if ($this.offset().top < boundTop) dir.ns = 'n';
			if ($this.offset().left < boundLeft) dir.ew = 'w';
			if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e';
			if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's';

			return dir.ns + (dir.ew ? dir.ew : '');
		};
	};

})(jQuery);
<|endoftext|>


<commit_before>// Copyright (c) 2018, Compiler Explorer Team
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
"use strict";

function definition() {
    return {
        keywords: [
            'module', 'import', 'Start', 'where', 'otherwise',
            'definition', 'implementation', 'from', 'class', 'instance', 'abort'
        ],

        builtintypes: [
            'Int', 'Real', 'String'
        ],

        operators: [
            '=', '==', '>=', '<=', '+', '-', '*', '/', '::', ':==', '->', '=:', '=>', '|', '\\\\'
        ],

        numbers: /-?[0-9.]/,

        tokenizer: {
            root: [
                { include: '@whitespace' },

                [/->/, 'operators'],

                [/\|/, 'operators'],

                [/(\w*)(\s?)(::)/, ['keyword', 'white', 'operators']],

                [/[+\-*/=<>\\]/, 'operators'],

                [/[a-zA-Z_][a-zA-Z0-9_]*/, {
                    cases: {
                        '@builtintypes': 'type',
                        '@keywords': 'keyword',
                        '@default': ''
                    }
                }],

                [/[()[\],:]/, 'delimiter'],

                [/@numbers/, 'number'],

                [/(")(.*)(")/, ['string', 'string', 'string']]
            ],

            comment: [
                [/[^/*]+/, 'comment'],
                [/\*\//, 'comment', '@pop'],
                [/[/*]/, 'comment']
            ],

            whitespace: [
                [/[ \t\r\n]+/, 'white'],
                [/\/\*/, 'comment', '@comment'],
                [/\/\/.*$/, 'comment']
            ],
        }
    };
}

monaco.languages.register({ id: 'clean' });
monaco.languages.setMonarchTokensProvider('clean', definition());
<commit_msg>forgot char type<commit_after>// Copyright (c) 2018, Compiler Explorer Team
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
"use strict";

function definition() {
    return {
        keywords: [
            'module', 'import', 'Start', 'where', 'otherwise',
            'definition', 'implementation', 'from', 'class', 'instance', 'abort'
        ],

        builtintypes: [
            'Int', 'Real', 'String', 'Char'
        ],

        operators: [
            '=', '==', '>=', '<=', '+', '-', '*', '/', '::', ':==', '->', '=:', '=>', '|', '\\\\'
        ],

        numbers: /-?[0-9.]/,

        tokenizer: {
            root: [
                { include: '@whitespace' },

                [/->/, 'operators'],

                [/\|/, 'operators'],

                [/(\w*)(\s?)(::)/, ['keyword', 'white', 'operators']],

                [/[+\-*/=<>\\]/, 'operators'],

                [/[a-zA-Z_][a-zA-Z0-9_]*/, {
                    cases: {
                        '@builtintypes': 'type',
                        '@keywords': 'keyword',
                        '@default': ''
                    }
                }],

                [/[()[\],:]/, 'delimiter'],

                [/@numbers/, 'number'],

                [/(")(.*)(")/, ['string', 'string', 'string']]
            ],

            comment: [
                [/[^/*]+/, 'comment'],
                [/\*\//, 'comment', '@pop'],
                [/[/*]/, 'comment']
            ],

            whitespace: [
                [/[ \t\r\n]+/, 'white'],
                [/\/\*/, 'comment', '@comment'],
                [/\/\/.*$/, 'comment']
            ],
        }
    };
}

monaco.languages.register({ id: 'clean' });
monaco.languages.setMonarchTokensProvider('clean', definition());
<|endoftext|>


<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide("frappe.ui.form.handlers");

frappe.ui.form.get_event_handler_list = function(doctype, fieldname) {
	if(!frappe.ui.form.handlers[doctype]) {
		frappe.ui.form.handlers[doctype] = {};
	}
	if(!frappe.ui.form.handlers[doctype][fieldname]) {
		frappe.ui.form.handlers[doctype][fieldname] = [];
	}
	return frappe.ui.form.handlers[doctype][fieldname];
}

frappe.ui.form.on = frappe.ui.form.on_change = function(doctype, fieldname, handler) {
	var add_handler = function(fieldname, handler) {
		var handler_list = frappe.ui.form.get_event_handler_list(doctype, fieldname);

		let _handler = (...args) => {
			try {
				handler(...args);
			} catch (error) {
				console.error(handler);
				throw error;
			}
		}

		handler_list.push(_handler);

		// add last handler to events so it can be called as
		// frm.events.handler(frm)
		if(cur_frm && cur_frm.doctype===doctype) {
			cur_frm.events[fieldname] = _handler;
		}
	}

	if (!handler && $.isPlainObject(fieldname)) {
		// a dict of handlers {fieldname: handler, ...}
		for (var key in fieldname) {
			var fn = fieldname[key];
			if (typeof fn === "function") {
				add_handler(key, fn);
			}
		}
	} else {
		add_handler(fieldname, handler);
	}
}

// remove standard event handlers
frappe.ui.form.off = function(doctype, fieldname, handler) {
	var handler_list = frappe.ui.form.get_event_handler_list(doctype, fieldname);
	if(handler_list.length) {
		frappe.ui.form.handlers[doctype][fieldname] = [];
	}

	if(cur_frm && cur_frm.doctype===doctype && cur_frm.events[fieldname]) {
		delete cur_frm.events[fieldname];
	}

	if(cur_frm && cur_frm.cscript && cur_frm.cscript[fieldname]) {
		delete cur_frm.cscript[fieldname];
	}
}

frappe.ui.form.trigger = function(doctype, fieldname) {
	cur_frm.script_manager.trigger(fieldname, doctype);
}

frappe.ui.form.ScriptManager = Class.extend({
	init: function(opts) {
		$.extend(this, opts);
	},
	make: function(ControllerClass) {
		this.frm.cscript = $.extend(this.frm.cscript,
			new ControllerClass({frm: this.frm}));
	},
	trigger: function(event_name, doctype, name) {
		// trigger all the form level events that
		// are bound to this event_name
		let me = this;
		doctype = doctype || this.frm.doctype;
		name = name || this.frm.docname;

		let tasks = [];
		let handlers = this.get_handlers(event_name, doctype);

		// helper for child table
		this.frm.selected_doc = frappe.get_doc(doctype, name);

		let runner = (_function, is_old_style) => {
			let _promise = null;
			if(is_old_style) {
				// old style arguments (doc, cdt, cdn)
				_promise = me.frm.cscript[_function](me.frm.doc, doctype, name);
			} else {
				// new style (frm, doctype, name)
				_promise = _function(me.frm, doctype, name);
			}

			// if the trigger returns a promise, return it,
			// or use the default promise frappe.after_ajax
			if (_promise && _promise.then) {
				return _promise;
			} else {
				return frappe.after_server_call();
			}
		};

		// make list of functions to be run serially
		handlers.new_style.forEach((_function) => {
			if(event_name==='setup') {
				// setup must be called immediately
				runner(_function, false);
			} else {
				tasks.push(() => runner(_function, false));
			}
		});

		handlers.old_style.forEach((_function) => {
			if(event_name==='setup') {
				// setup must be called immediately
				runner(_function, true);
			} else {
				tasks.push(() => runner(_function, true));
			}
		});

		// run them serially
		return frappe.run_serially(tasks);
	},
	has_handlers: function(event_name, doctype) {
		let handlers = this.get_handlers(event_name, doctype);
		return handlers && (handlers.old_style.length || handlers.new_style.length);
	},
	get_handlers: function(event_name, doctype) {
		// returns list of all functions to be called (old style and new style)
		let me = this;
		let handlers = {
			old_style: [],
			new_style: []
		};
		if(frappe.ui.form.handlers[doctype] && frappe.ui.form.handlers[doctype][event_name]) {
			$.each(frappe.ui.form.handlers[doctype][event_name], function(i, fn) {
				handlers.new_style.push(fn);
			});
		}
		if(this.frm.cscript[event_name]) {
			handlers.old_style.push(event_name);
		}
		if(this.frm.cscript["custom_" + event_name]) {
			handlers.old_style.push("custom_" + event_name);
		}
		return handlers;
	},
	setup: function() {
		var doctype = this.frm.meta;
		var me = this;

		// js
		var cs = doctype.__js;
		if(cs) {
			var tmp = eval(cs);
		}

		if(doctype.__custom_js) {
			try {
				eval(doctype.__custom_js);
			} catch(e) {
				frappe.msgprint({
					title: __('Error in Custom Script'),
					indicator: 'orange',
					message: '
' + e.stack  + '
'
				});
			}
		}

		function setup_add_fetch(df) {
			if((['Data', 'Read Only', 'Text', 'Small Text', 'Currency',
				'Text Editor', 'Code', 'Link', 'Float', 'Int', 'Date', 'Select'].includes(df.fieldtype) || df.read_only==1)
				&& df.fetch_from && df.fetch_from.indexOf(".")!=-1) {
				var parts = df.fetch_from.split(".");
				me.frm.add_fetch(parts[0], parts[1], df.fieldname);
			}
		}

		// setup add fetch
		$.each(this.frm.fields, function(i, field) {
			setup_add_fetch(field.df);
			if(frappe.model.table_fields.includes(field.df.fieldtype)) {
				$.each(frappe.meta.get_docfields(field.df.options, me.frm.docname), function(i, df) {
					setup_add_fetch(df);
				});
			}
		});

		// css
		doctype.__css && frappe.dom.set_style(doctype.__css);

		this.trigger('setup');
	},
	log_error: function(caller, e) {
		frappe.show_alert("Error in Client Script.");
		console.group && console.group();
		console.log("----- error in client script -----");
		console.log("method: " + caller);
		console.log(e);
		console.log("error message: " + e.message);
		console.trace && console.trace();
		console.log("----- end of error message -----");
		console.group && console.groupEnd();
	},
	copy_from_first_row: function(parentfield, current_row, fieldnames) {
		var data = this.frm.doc[parentfield];
		if(data.length===1 || data[0]===current_row) return;

		if(typeof fieldnames==='string') {
			fieldnames = [fieldnames];
		}

		$.each(fieldnames, function(i, fieldname) {
			frappe.model.set_value(current_row.doctype, current_row.name, fieldname,
				data[0][fieldname]);
		});
	}
});
<commit_msg>fix: return handler in _handler (#11215)<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide("frappe.ui.form.handlers");

frappe.ui.form.get_event_handler_list = function(doctype, fieldname) {
	if(!frappe.ui.form.handlers[doctype]) {
		frappe.ui.form.handlers[doctype] = {};
	}
	if(!frappe.ui.form.handlers[doctype][fieldname]) {
		frappe.ui.form.handlers[doctype][fieldname] = [];
	}
	return frappe.ui.form.handlers[doctype][fieldname];
}

frappe.ui.form.on = frappe.ui.form.on_change = function(doctype, fieldname, handler) {
	var add_handler = function(fieldname, handler) {
		var handler_list = frappe.ui.form.get_event_handler_list(doctype, fieldname);

		let _handler = (...args) => {
			try {
				return handler(...args);
			} catch (error) {
				console.error(handler);
				throw error;
			}
		}

		handler_list.push(_handler);

		// add last handler to events so it can be called as
		// frm.events.handler(frm)
		if(cur_frm && cur_frm.doctype===doctype) {
			cur_frm.events[fieldname] = _handler;
		}
	}

	if (!handler && $.isPlainObject(fieldname)) {
		// a dict of handlers {fieldname: handler, ...}
		for (var key in fieldname) {
			var fn = fieldname[key];
			if (typeof fn === "function") {
				add_handler(key, fn);
			}
		}
	} else {
		add_handler(fieldname, handler);
	}
}

// remove standard event handlers
frappe.ui.form.off = function(doctype, fieldname, handler) {
	var handler_list = frappe.ui.form.get_event_handler_list(doctype, fieldname);
	if(handler_list.length) {
		frappe.ui.form.handlers[doctype][fieldname] = [];
	}

	if(cur_frm && cur_frm.doctype===doctype && cur_frm.events[fieldname]) {
		delete cur_frm.events[fieldname];
	}

	if(cur_frm && cur_frm.cscript && cur_frm.cscript[fieldname]) {
		delete cur_frm.cscript[fieldname];
	}
}

frappe.ui.form.trigger = function(doctype, fieldname) {
	cur_frm.script_manager.trigger(fieldname, doctype);
}

frappe.ui.form.ScriptManager = Class.extend({
	init: function(opts) {
		$.extend(this, opts);
	},
	make: function(ControllerClass) {
		this.frm.cscript = $.extend(this.frm.cscript,
			new ControllerClass({frm: this.frm}));
	},
	trigger: function(event_name, doctype, name) {
		// trigger all the form level events that
		// are bound to this event_name
		let me = this;
		doctype = doctype || this.frm.doctype;
		name = name || this.frm.docname;

		let tasks = [];
		let handlers = this.get_handlers(event_name, doctype);

		// helper for child table
		this.frm.selected_doc = frappe.get_doc(doctype, name);

		let runner = (_function, is_old_style) => {
			let _promise = null;
			if(is_old_style) {
				// old style arguments (doc, cdt, cdn)
				_promise = me.frm.cscript[_function](me.frm.doc, doctype, name);
			} else {
				// new style (frm, doctype, name)
				_promise = _function(me.frm, doctype, name);
			}

			// if the trigger returns a promise, return it,
			// or use the default promise frappe.after_ajax
			if (_promise && _promise.then) {
				return _promise;
			} else {
				return frappe.after_server_call();
			}
		};

		// make list of functions to be run serially
		handlers.new_style.forEach((_function) => {
			if(event_name==='setup') {
				// setup must be called immediately
				runner(_function, false);
			} else {
				tasks.push(() => runner(_function, false));
			}
		});

		handlers.old_style.forEach((_function) => {
			if(event_name==='setup') {
				// setup must be called immediately
				runner(_function, true);
			} else {
				tasks.push(() => runner(_function, true));
			}
		});

		// run them serially
		return frappe.run_serially(tasks);
	},
	has_handlers: function(event_name, doctype) {
		let handlers = this.get_handlers(event_name, doctype);
		return handlers && (handlers.old_style.length || handlers.new_style.length);
	},
	get_handlers: function(event_name, doctype) {
		// returns list of all functions to be called (old style and new style)
		let me = this;
		let handlers = {
			old_style: [],
			new_style: []
		};
		if(frappe.ui.form.handlers[doctype] && frappe.ui.form.handlers[doctype][event_name]) {
			$.each(frappe.ui.form.handlers[doctype][event_name], function(i, fn) {
				handlers.new_style.push(fn);
			});
		}
		if(this.frm.cscript[event_name]) {
			handlers.old_style.push(event_name);
		}
		if(this.frm.cscript["custom_" + event_name]) {
			handlers.old_style.push("custom_" + event_name);
		}
		return handlers;
	},
	setup: function() {
		var doctype = this.frm.meta;
		var me = this;

		// js
		var cs = doctype.__js;
		if(cs) {
			var tmp = eval(cs);
		}

		if(doctype.__custom_js) {
			try {
				eval(doctype.__custom_js);
			} catch(e) {
				frappe.msgprint({
					title: __('Error in Custom Script'),
					indicator: 'orange',
					message: '
' + e.stack  + '
'
				});
			}
		}

		function setup_add_fetch(df) {
			if((['Data', 'Read Only', 'Text', 'Small Text', 'Currency',
				'Text Editor', 'Code', 'Link', 'Float', 'Int', 'Date', 'Select'].includes(df.fieldtype) || df.read_only==1)
				&& df.fetch_from && df.fetch_from.indexOf(".")!=-1) {
				var parts = df.fetch_from.split(".");
				me.frm.add_fetch(parts[0], parts[1], df.fieldname);
			}
		}

		// setup add fetch
		$.each(this.frm.fields, function(i, field) {
			setup_add_fetch(field.df);
			if(frappe.model.table_fields.includes(field.df.fieldtype)) {
				$.each(frappe.meta.get_docfields(field.df.options, me.frm.docname), function(i, df) {
					setup_add_fetch(df);
				});
			}
		});

		// css
		doctype.__css && frappe.dom.set_style(doctype.__css);

		this.trigger('setup');
	},
	log_error: function(caller, e) {
		frappe.show_alert("Error in Client Script.");
		console.group && console.group();
		console.log("----- error in client script -----");
		console.log("method: " + caller);
		console.log(e);
		console.log("error message: " + e.message);
		console.trace && console.trace();
		console.log("----- end of error message -----");
		console.group && console.groupEnd();
	},
	copy_from_first_row: function(parentfield, current_row, fieldnames) {
		var data = this.frm.doc[parentfield];
		if(data.length===1 || data[0]===current_row) return;

		if(typeof fieldnames==='string') {
			fieldnames = [fieldnames];
		}

		$.each(fieldnames, function(i, fieldname) {
			frappe.model.set_value(current_row.doctype, current_row.name, fieldname,
				data[0][fieldname]);
		});
	}
});
<|endoftext|>