Media management command demonstrates multiple layers of sub-commands being handled by AutoCompleter
10948
def do_library(self, args):
        """"""
        func = getattr(args, 'func', None)
        if func is not None:
            # Call whatever subcommand function was selected
            func(self, args)
        else:
            # No subcommand was provided, so call help
            self.do_help('library')
582481
function contextMenuOpenHandler() {
        var file = MainViewManager.getCurrentlyViewedFile(MainViewManager.ACTIVE_PANE);

        if (file) {
            var targetIndex  = MainViewManager.findInWorkingSet(MainViewManager.ACTIVE_PANE, file.fullPath),
                workingSetListSize = MainViewManager.getWorkingSetSize(MainViewManager.ACTIVE_PANE);

            if (targetIndex === workingSetListSize - 1) { // hide "Close Others Below" if the last file in Working Files is selected
                CommandManager.get(closeBelow).setEnabled(false);
            } else {
                CommandManager.get(closeBelow).setEnabled(true);
            }

            if (workingSetListSize === 1) { // hide "Close Others" if there is only one file in Working Files
                CommandManager.get(closeOthers).setEnabled(false);
            } else {
                CommandManager.get(closeOthers).setEnabled(true);
            }

            if (targetIndex === 0) { // hide "Close Others Above" if the first file in Working Files is selected
                CommandManager.get(closeAbove).setEnabled(false);
            } else {
                CommandManager.get(closeAbove).setEnabled(true);
            }
        }
    }
814246
function fixChromeAutocomplete() {
      const global = formlyConfig.extras.removeChromeAutoComplete === true
      const offInstance = scope.options && scope.options.removeChromeAutoComplete === false
      const onInstance = scope.options && scope.options.removeChromeAutoComplete === true
      if ((global && !offInstance) || onInstance) {
        const input = document.createElement('input')
        input.setAttribute('autocomplete', 'address-level4')
        input.setAttribute('hidden', 'true')
        el[0].appendChild(input)
      }

    }
1312100
function UI() {
		var submitHandler; // Function which is later bound to handle form submits
		var formDataProperty = "smartyForm"; // Indicates whether we've stored the form already
		var autocompleteResponse; // The latest response from the autocomplete server
		var autocplCounter = 0; // A counter so that only the most recent JSONP request is used
		var autocplRequests = []; // The array that holds autocomplete requests in order
		var loaderWidth = 24,
			loaderHeight = 8; // TODO: Update these if the image changes
		var uiCss = "<style>" + ".smarty-dots { display: none; position: absolute; z-index: 999; width: " +
			loaderWidth + "px; height: " + loaderHeight + "px; " +
			"background-image: url(\"data:image/gif;base64,R0lGODlhGAAIAOMAALSytOTi5MTCxPTy9Ly6vPz6/Ozq7MzKzLS2tOTm5PT29Ly+v" +
			"Pz+/MzOzP///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJBgAOACwAAAAAGAAIAAAEUtA5NZi8jNrr2FBScQAAYVyKQC6gZBDkUTRkXUhLDSw" +
			"hojc+XcAx0JEGjoRxCRgWjcjAkqZr5WoIiSJIaohIiATqimglg4KWwrDBDNiczgDpiAAAIfkECQYAFwAsAAAAABgACACEVFZUtLK05OLkxMbE9" +
			"PL0jI6MvL68bG5s7Ors1NbU/Pr8ZGJkvLq8zM7MXFpctLa05ObkzMrM9Pb0nJqcxMLE7O7s/P78////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
			"ABWDgZVWQcp2nJREWmhLSKRWOcySoRAWBEZ8IBi+imAAcxwXhZODxDCfFwxloLI6A7OBCoPKWEG/giqxRuOLKRSA2lpVM6kM2dTZmyBuK0Aw8f" +
			"hcQdQMxIwImLiMSLYkVPyEAIfkECQYAFwAsAAAAABgACACEBAIEpKak1NbU7O7svL68VFZU/Pr8JCIktLK05OLkzMrMDA4M9Pb0vLq87Ors9PL" +
			"0xMLEZGZk/P78tLa05ObkzM7MFBIU////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWLgJVGCcZ2n9DASmq7nUwDAQaAPhCAEgzqNncIQodEWg" +
			"xNht7tdDBMmorIw0gKXh3T3uCSYgV3VitUiwrskZTspGpFKsJMRRVdkNBuKseT5Tg4TUQo+BgkCfygSDCwuIgN/IQAh+QQJBgAXACwAAAAAGAA" +
			"IAIRUVlS0srTk4uR8enz08vTExsRsbmzs6uyMjoz8+vzU1tRkYmS8urzMzsxcWly0trTk5uR8fnz09vTMyszs7uycmpz8/vz///8AAAAAAAAAA" +
			"AAAAAAAAAAAAAAAAAAAAAAFYOBlUVBynad1QBaaEtIpIY5jKOgxAM5w5IxAYJKo8HgLwmnnAAAGsodQ2FgcnYUL5Nh0QLTTqbXryB6cXcBPEBY" +
			"aybEL0wm9SNqFWfOWY0Z+JxBSAXkiFAImLiolLoZxIQAh+QQJBgAQACwAAAAAGAAIAIQEAgS0srTc2tz08vTMyszk5uT8+vw0MjS8ury0trTk4" +
			"uT09vTMzszs6uz8/vw0NjT///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFWiAELYMjno4gmCfkDItoEEG" +
			"ANKfwAMAjnA1EjWBg1I4G14HHO5gMiWOAEZUqIAIm86eQeo/XrBbA/RqlMceS6RxVa4xZLVHI7QCHn6hQRbAWDSwoKoIiLzEQIQAh+QQJBgAXA" +
			"CwAAAAAGAAIAIRUVlS0srTk4uR8enz08vTExsRsbmzs6uyMjoz8+vzU1tRkYmS8urzMzsxcWly0trTk5uR8fnz09vTMyszs7uycmpz8/vz///8" +
			"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFY+B1SYQlntYBmeeVQJSZTEHAHCcUOUCEiwqDw4GQNGrIhGgA4DkGIsIC0ARUHsia4AKpOiGXghewy" +
			"Gq5YwCu4Gw6jlnJ0gu9SKvWRKH2AIt0TQN+F0FNRSISMS0XKSuLCQKKIQAh+QQJBgAXACwAAAAAGAAIAIQEAgSkpqTU1tTs7uy8vrxUVlT8+vw" +
			"kIiS0srTk4uTMyswMDgz09vS8urzs6uz08vTEwsRkZmT8/vy0trTk5uTMzswUEhT///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZOB1MY8kn" +
			"hJpnpchUKahIEjjnAxEE8xJHABA4VGhGQ0ighFBEA0swWBkYgxMEpfHkva4BKLBxRaBHdACCHT3C14U0VbkRWlsXgYLcERGJQxOD3Q8PkBCfyM" +
			"DKygMDIoiDAIJJiEAIfkECQYAFwAsAAAAABgACACEVFZUtLK05OLkxMbE9PL0jI6MvL68bG5s7Ors1NbU/Pr8ZGJkvLq8zM7MXFpctLa05Obkz" +
			"MrM9Pb0nJqcxMLE7O7s/P78////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWPgdUmEJZ4WaZ6XAlWmEgUBg5wSRRvSmRwOR0HSoBkVIoMxYBA" +
			"RFgBHdPJYBgSXijVAuAykUsBii5VsK96oelFc9i5K40MkgYInigHtAcHFH28XP1EFXSMwLBcWFRIrJwoCiCEAOw==\"); }" +
			".smarty-ui { position: absolute; z-index: 999; text-shadow: none; text-align: left; text-decoration: none; }" +
			".smarty-popup { padding: 20px 30px; background: #FFFFFF; display: inline-block;" +
			"box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); }" + ".smarty-popup-header { " +
			"text-transform: uppercase; font: bold 10pt/1em \"Helvetica\", sans-serif; color: #CEA737; padding: 12px 0px 0px; text-align: center;}" +
			".smarty-popup-ambiguous-header { color: #CEA737; }" + ".smarty-popup-invalid-header { color: #D0021B; }" +
			".smarty-popup-missing-input-header { color: #CEA737; }" +
			".smarty-popup-typed-address{ font-family: sans-serif; font-size: 10pt; font-style: italic; text-align: center; margin: 15px 0px;}" +
			".smarty-popup-secondary-number-form { font-family: sans-serif; margin: 10px auto 20px; padding: 0; border: none; float: none; background: none; width: auto; text-align: center; }" +
			"#smarty-popup-secondary-number-input-box {width: 200px; font-size: 11pt; margin-bottom: 10px; text-align: center;}" +
			"#smarty-popup-secondary-number-form-submit-button { line-height: 23px; background: #606060; border: none; color: #fff; border-radius: 3px;" +
			" padding: 2px 15px; font-size: 11pt; width: 215px; }" + "#smarty-popup-secondary-number-form-submit-button:hover { background: #333; }" +
			".smarty-hr { margin-bottom: 15px; }" +
			".smarty-choice-list .smarty-choice { background: #FFF; padding: 10px 15px; color: #9B9B9B; margin-bottom: 10px; }" +
			".smarty-choice { display: block; font: 300 10pt/1em sans-serif; text-decoration: none; " +
			"border: 1px solid #D4D4D4; }" + ".smarty-choice-list .smarty-choice:hover { color: #333; " +
			"background: #F7F7F7; text-decoration: none; border: 1px solid #333 }" + ".smarty-choice-alt { " +
			"background: inherit; clear: both; }" + ".smarty-choice-alt" +
			" .smarty-choice-abort, .smarty-choice-override { padding: 8px 10px; color: #FFF; " +
			"font-size: 10pt; text-decoration: none; background: #606060; border-radius: 3px; border: none; }" +
			" .smarty-choice-override { float: right }" +
			" .smarty-choice-abort { float: left }" + ".smarty-choice-alt " + ".smarty-choice:first-child { border-top: 0; }" +
			".smarty-choice-abort:hover { background: #333; }" +
			".smarty-choice-override:hover { background: #333; }" + ".smarty-tag { position: absolute; " +
			"display: block; overflow: hidden; font: 15px/1.2em sans-serif; text-decoration: none; width: 20px; " +
			"height: 18px; border-radius: 25px; transition: all .25s; -moz-transition: all .25s; " +
			"-webkit-transition: all .25s; -o-transition: all .25s; }" + ".smarty-tag:hover { width: 70px; " +
			"text-decoration: none; color: #999; }" + ".smarty-tag:hover .smarty-tag-text " +
			"{ color: #000; }" + ".smarty-tag-grayed { border: 1px solid #B4B4B4; " +
			"color: #999; background: #DDD; box-shadow: inset 0 9px 15px #FFF; }" +
			".smarty-tag-green { border: 1px solid #407513; color: #407513; " +
			"background: #A6D187; box-shadow: inset 0 9px 15px #E3F6D5; }" + ".smarty-tag-grayed:hover " +
			"{ border-color: #333; }" + ".smarty-tag-check { padding-left: 4px; " +
			"text-decoration: none; }" + ".smarty-tag-text { font-size: 12px; position: absolute; " +
			"top: 0; left: 16px; width: 50px; text-align: center; }" + ".smarty-autocomplete " +
			"{ border: 1px solid #777; background: white; overflow: hidden; white-space: nowrap; " +
			"box-shadow: 1px 1px 3px #555; }" + ".smarty-suggestion { display: block; color: #444; " +
			"text-decoration: none; font-size: 12px; padding: 1px 5px; }" + ".smarty-active-suggestion " +
			"{ background: #EEE; color: #000; border: none; outline: none; }" + ".smarty-no-suggestions " +
			"{ padding: 1px 5px; font-size: 12px; color: #AAA; font-style: italic; } " +
			".smarty-debug-input { background: #ffffcc !important; } " +
			".smarty-debug-button { color: #4ba341 !important; } " + "</style>";

		this.postMappingOperations = function () {
			// Injects materials into the DOM, binds to form submit events, etc... very important.

			if (config.ui) {
				// Prepend CSS to head tag to allow cascading and give their style rules priority
				$("head").prepend(uiCss);

				// For each address on the page, inject the loader and "address verified" markup after the last element
				var addresses = instance.getMappedAddresses();
				for (var i = 0; i < addresses.length; i++) {
					var id = addresses[i].id();
					$("body").append("<div class=\"smarty-ui\"><div title=\"Loading...\" class=\"smarty-dots smarty-addr-" + id + "\"></div></div>");
					if (config.smartyTag) {
						var offset = uiTagOffset(addresses[i].corners(true));
						$("body").append("<div class=\"smarty-ui\" style=\"top: " + offset.top + "px; left: " + offset.left +
							"px;\"><a href=\"javascript:\" class=\"smarty-tag smarty-tag-grayed smarty-addr-" + id +
							"\" title=\"Address not verified. Click to verify.\" data-addressid=\"" + id +
							"\"><span class=\"smarty-tag-check\">&#10003;</span><span class=\"smarty-tag-text\">Verify</span></a></div>");
					}

					// Move the UI elements around when browser window is resized
					$(window).on("resize.smarty", {
						addr: addresses[i]
					}, function (e) {
						var addr = e.data.addr;
						if (config.smartyTag) {
							var offset = uiTagOffset(addr.corners(true)); // Position of lil' tag
							$(".smarty-tag.smarty-addr-" + addr.id())
								.parent(".smarty-ui")
								.css("top", offset.top + "px")
								.css("left", offset.left + "px");
						}

						var addrOffset = addr.corners(); // Position of any popup windows
						$(".smarty-popup.smarty-addr-" + addr.id())
							.parent(".smarty-ui")
							.css("top", addrOffset.top + "px")
							.css("left", addrOffset.left + "px");

						if (config.autocomplete) { // Position of autocomplete boxes
							var containerUi = $(".smarty-autocomplete.smarty-addr-" + addr.id()).closest(".smarty-ui");
							var domFields = addr.getDomFields();
							var mainInput = "";
							if (domFields.address1) {
								mainInput = "address1";
							} else if (domFields.freeform) {
								mainInput = "freeform";
							}
							if (mainInput !== "") {
								containerUi.css({
									"left": $(domFields[mainInput]).offset().left + "px",
									"top": ($(domFields[mainInput]).offset().top + $(domFields[mainInput]).outerHeight(false)) + "px"
								});
							}
						}
					});
				}

				if (config.smartyTag) {
					$("body").on("click", ".smarty-tag-grayed", function (e) {
						// "Verify" clicked -- manually invoke verification
						var addrId = $(this).data("addressid");
						instance.verify(addrId);
					});

					$("body").on("click", ".smarty-undo", function (e) {
						// "Undo" clicked -- replace field values with previous input
						var addrId = $(this).parent().data("addressid");
						var addr = instance.getMappedAddressByID(addrId);
						addr.undo(true);
						// If fields are re-mapped after an address was verified, it loses its "accepted" status even if no values were changed.
						// Thus, in some rare occasions, the undo link and the "verified!" text may not disappear when the user clicks "Undo",
						// The undo functionality still works in those cases, but with no visible changes, the address doesn't fire "AddressChanged"...
					});
				}

				// Prepare autocomplete UI
				if (config.autocomplete && config.key) {
					// For every mapped address, wire up autocomplete
					for (var i = 0; i < forms.length; i++) {
						var f = forms[i];

						for (var j = 0; j < f.addresses.length; j++) {
							var addr = f.addresses[j];
							var domFields = addr.getDomFields();
							var mainInput = "";
							if (domFields.address1) {
								mainInput = "address1";
							} else if (domFields.freeform) {
								mainInput = "freeform";
							}
							if (mainInput !== "") {
								var strField = $(domFields[mainInput]);
								var containerUi = $("<div class=\"smarty-ui\"></div>");
								var autoUi = $("<div class=\"smarty-autocomplete\"></div>");

								autoUi.addClass("smarty-addr-" + addr.id());
								containerUi.data("addrID", addr.id());
								containerUi.append(autoUi);

								containerUi.css({
									"position": "absolute",
									"left": strField.offset().left + "px",
									"top": (strField.offset().top + strField.outerHeight(false)) + "px"
								});

								containerUi.hide().appendTo("body");

								containerUi.on("mousedown", ".smarty-suggestion", {
									addr: addr,
									containerUi: containerUi
								}, function (event) {
									var sugg = autocompleteResponse.suggestions[$(this).data("suggIndex")];
									useAutocompleteSuggestion(event.data.addr, sugg, event.data.containerUi);
								});

								containerUi.on("mouseover", ".smarty-suggestion", function () {
									$(".smarty-active-suggestion").removeClass("smarty-active-suggestion");
									$(this).addClass("smarty-active-suggestion");
								});

								containerUi.on("mouseleave", ".smarty-active-suggestion", function () {
									$(this).removeClass("smarty-active-suggestion");
								});

								strField.keydown({
									containerUi: containerUi,
									addr: addr
								}, function (event) {
									var suggContainer = $(".smarty-autocomplete", event.data.containerUi);
									var currentChoice = $(".smarty-active-suggestion:visible", suggContainer).first();
									var choiceSelectionIsNew = false;

									if (event.keyCode == 9) { // Tab key
										if (currentChoice.length > 0) {
											var domFields = event.data.addr.getDomFields();
											if (domFields.zipcode)
												$(domFields.zipcode).focus();
											else
												$(domFields[mainInput]).blur();
											useAutocompleteSuggestion(event.data.addr, autocompleteResponse.suggestions[currentChoice.data("suggIndex")], event.data.containerUi);
											return addr.isFreeform() ? true : suppress(event);
										} else
											ui.hideAutocomplete(event.data.addr.id());
									} else if (event.keyCode == 40) { // Down arrow
										if (!currentChoice.hasClass("smarty-suggestion")) {
											currentChoice = $(".smarty-suggestion", suggContainer).first().mouseover();
											choiceSelectionIsNew = true;
										}

										if (!choiceSelectionIsNew) {
											if (currentChoice.next(".smarty-addr-" + event.data.addr.id() + " .smarty-suggestion").length > 0)
												currentChoice.next(".smarty-suggestion").mouseover();
											else
												currentChoice.removeClass("smarty-active-suggestion");
										}

										moveCursorToEnd(this);
									} else if (event.keyCode == 38) { // Up arrow
										if (!currentChoice.hasClass("smarty-suggestion")) {
											currentChoice = $(".smarty-suggestion", suggContainer).last().mouseover();
											choiceSelectionIsNew = true;
										}

										if (!choiceSelectionIsNew) {
											if (currentChoice.prev(".smarty-addr-" + event.data.addr.id() + " .smarty-suggestion").length > 0)
												currentChoice.prev(".smarty-suggestion").mouseover();
											else
												currentChoice.removeClass("smarty-active-suggestion");
										}

										moveCursorToEnd(this);
									}
								});

								// Flip the on switch!
								strField.keyup({
									form: f,
									addr: addr,
									streetField: strField,
									containerUi: containerUi
								}, doAutocomplete);
							}
						}

						$(document).keyup(function (event) {
							if (event.keyCode == 27) // Esc key
								$(".smarty-autocomplete").closest(".smarty-ui").hide();
						});
					}

					// Try .5 and 1.5 seconds after the DOM loads to re-position UI elements; hack for Firefox.
					setTimeout(function () {
						$(window).trigger("resize.smarty");
					}, 500);
					setTimeout(function () {
						$(window).trigger("resize.smarty");
					}, 1500);
				}

			}

			if (config.submitVerify) {
				// Bind to form submits through form submit and submit button click events
				for (var i = 0; i < forms.length; i++) {
					var f = forms[i];

					submitHandler = function (e) {
						// Don't invoke verification if it's already processing or autocomplete is open and the user was pressing Enter to use a suggestion
						if ((e.data.form && e.data.form.processing) || $(".smarty-active-suggestion:visible").length > 0)
							return suppress(e);

						/*
						 IMPORTANT!
						 Prior to version 2.4.8, the plugin would call syncWithDom() at submit-time
						 in case programmatic changes were made to the address input fields, including
						 browser auto-fills. The sync function would detect those changes and force
						 a re-verification to not let invalid addresses through. Unfortunately, this
						 frequently caused infinite loops (runaway lookups), ultimately preventing
						 form submission, which is unacceptable. As a safety measure to protect our
						 customer's subscriptions, we've removed syncWithDom(). The website owner is
						 responsible for making sure that any changes to address field values raise the
						 "change" event on that element. Example: $("#city").val("New City").change();
						 */

						if (!e.data.form.allActiveAddressesAccepted()) {
							// We could verify all the addresses at once, but that can overwhelm the user.
							// An API request is usually quick, so let's do one at a time: it's much cleaner.
							var unaccepted = e.data.form.activeAddressesNotAccepted();
							if (unaccepted.length > 0)
								trigger("VerificationInvoked", {
									address: unaccepted[0],
									invoke: e.data.invoke,
									invokeFn: e.data.invokeFn
								});
							return suppress(e);
						}
					};

					// Performs the tricky operation of uprooting existing event handlers that we have references to
					// (either by jQuery's data cache or HTML attributes) planting ours, then laying theirs on top
					var bindSubmitHandler = function (domElement, eventName) {
						if (!domElement || !eventName)
							return;

						var oldHandlers = [],
							eventsRef = $._data(domElement, "events");

						// If there are previously-bound-event-handlers (from jQuery), get those.
						if (eventsRef && eventsRef[eventName] && eventsRef[eventName].length > 0) {
							// Get a reference to the old handlers previously bound by jQuery
							oldHandlers = $.extend(true, [], eventsRef[eventName]);
						}

						// Turn them off...
						$(domElement).off(eventName);

						// ... then turn ours on first ...
						$(domElement)[eventName]({
							form: f,
							invoke: domElement,
							invokeFn: eventName
						}, submitHandler);

						// ... then turn on theirs last:
						// First turn on their onclick="..." or onsubmit="..." handles...
						if (typeof domElement["on" + eventName] === "function") {
							var temp = domElement["on" + eventName];
							domElement["on" + eventName] = null;
							$(domElement)[eventName](temp);
						}

						// ... then finish up with their old jQuery handles.
						for (var j = 0; j < oldHandlers.length; j++)
							$(domElement)[eventName](oldHandlers[j].data, oldHandlers[j].handler);
					};

					// Take any existing handlers (bound via jQuery) and re-bind them for AFTER our handler(s).
					var formSubmitElements = $(config.submitSelector, f.dom);

					// Highlight the submit button
					if (config.debug) {
						for (var j = 0; j < formSubmitElements.length; j++) {
							$(formSubmitElements[j]).addClass("smarty-debug-button");
						}
					}

					// Form submit() events are apparently invoked by CLICKING the submit button (even jQuery does this at its core for binding)
					// (but jQuery, when raising a form submit event with .submit() will NOT necessarily click the submit button)
					formSubmitElements.each(function (idx) {
						bindSubmitHandler(this, "click"); // These get fired first
					});

				}
			}

			trigger("MapInitialized");
		};

		function doAutocomplete(event) {
			var addr = event.data.addr;
			var streetField = event.data.streetField;
			var input = $.trim(event.data.streetField.val());
			var containerUi = event.data.containerUi;
			var suggContainer = $(".smarty-autocomplete", containerUi);

			if (!input) {
				addr.lastStreetInput = input;
				suggContainer.empty();
				ui.hideAutocomplete(addr.id());
			}

			if (event.keyCode == 13) { // Enter/return
				if ($(".smarty-active-suggestion:visible").length > 0)
					useAutocompleteSuggestion(addr, autocompleteResponse.suggestions[$(".smarty-active-suggestion:visible").first().data("suggIndex")], containerUi);
				ui.hideAutocomplete(addr.id());
				streetField.blur();
				return suppress(event);
			}

			if (event.keyCode == 40) { // Down arrow
				moveCursorToEnd(streetField[0]);
				return;
			}

			if (event.keyCode == 38) { // Up arrow
				moveCursorToEnd(streetField[0]);
				return;
			}

			if (!input || input == addr.lastStreetInput || !addr.isDomestic())
				return;

			addr.lastStreetInput = input; // Used so that autocomplete only fires on real changes (i.e. not just whitespace)
			if (addr.isDomestic() && config.target.indexOf("US") >= 0) {
				trigger("AutocompleteInvoked", {
					containerUi: containerUi,
					suggContainer: suggContainer,
					streetField: streetField,
					input: input,
					addr: addr
				});
			}
		}

		this.requestAutocomplete = function (event, data) {
			if (data.input && data.addr.isDomestic() && autocompleteResponse)
				data.containerUi.show();

			var autocplrequest = {
				callback: function (counter, json) {
					var patt = new RegExp("^\\w+\\s\\w+|^[A-Za-z]+$|^[A-Za-z]+\\s\\w*");
					var filtering = patt.test(data.input);
					autocompleteResponse = json;
					data.suggContainer.empty();

					if (!json.suggestions || json.suggestions.length == 0) {
						data.suggContainer.html("<div class=\"smarty-no-suggestions\">" + config.noSuggestionsMessage + "</div>");
						return;
					}

					if (config.waitForStreet && filtering == false) {
						var message = "";
						if (config.stateFilter || config.cityFilter || config.geolocate || config.cityStatePreference) {
							message = "filtered";
						} else {
							message = "address";
						}
						data.suggContainer.html("<div class=\"smarty-no-suggestions\">Type more for " + message + " suggestions</div>")
					} else {
						for (var j = 0; j < json.suggestions.length; j++) {
							var suggAddr = json.suggestions[j].text.replace(/<|>/g, "");
							suggAddr = suggAddr.replace(new RegExp("(" + data.input.replace(/[#-.]|[[-^]|[?|{}]/g, "\\$&") + ")", "ig"), "<b>$1</b>");
							var link = $("<a href=\"javascript:\" class=\"smarty-suggestion\">" + suggAddr + "</a>");
							link.data("suggIndex", j);

							data.suggContainer.append(link);
						}
					}

					data.suggContainer.css({
						"width": Math.max(data.streetField.outerWidth(false), 250) + "px"
					});

					data.containerUi.show();

					// Delete all older callbacks so they don't get executed later because of latency
					autocplRequests.splice(0, counter);
				},
				number: autocplCounter++
			};

			autocplRequests[autocplrequest.number] = autocplrequest;

			var ajaxSettings = {
				url: "https://us-autocomplete.api.smartystreets.com/suggest",
				traditional: true,
				dataType: "json",
				data: {
					"auth-id": config.key,
					"auth-token": config.token,
					prefix: data.input,
					city_filter: config.cityFilter,
					state_filter: config.stateFilter,
					prefer: config.cityStatePreference,
					suggestions: config.autocomplete,
					geolocate: config.geolocate,
					geolocate_precision: config.geolocatePrecision,
					prefer_ratio: config.preferRatio,
					agent: ["smartystreets (plugin:website@" + instance.version + ")", config.agent]
				}
			};

			$.ajax($.extend({}, config.ajaxSettings, ajaxSettings)).done(function (json) {
				trigger("AutocompleteReceived", $.extend(data, {
					json: json,
					autocplrequest: autocplrequest
				}));
			});
		};

		this.showAutocomplete = function (event, data) {
			if (autocplRequests[data.autocplrequest.number])
				autocplRequests[data.autocplrequest.number].callback(data.autocplrequest.number, data.json);
		};

		function useAutocompleteSuggestion(addr, suggestion, containerUi) {
			addr.usedAutocomplete = false;
			var domfields = addr.getDomFields();
			ui.hideAutocomplete(addr.id()); // It's important that the suggestions are hidden before AddressChanged event fires

			if (addr.isFreeform()) {
				$(domfields.freeform).val(suggestion.text).change();
				addr.usedAutocomplete = true;
			} else {
				if (domfields.postal_code) {
					$(domfields.postal_code).val("").change();
				}
				if (domfields.address1)
					$(domfields.address1).val(suggestion.street_line).change();
				// State filled in before city so autoverify is not invoked without finishing using the suggestion
				if (domfields.administrative_area) {
					if (domfields.administrative_area.options) { // Checks for dropdown
						for (var i = 0; i < domfields.administrative_area.options.length; i++) {
							// Checks for abbreviation match and maps full state name to abbreviation
							if (domfields.administrative_area.options[i].text.toUpperCase() === suggestion.state || allStatesByName[domfields.administrative_area.options[i].text.toUpperCase()] === suggestion.state) {
								$(domfields.administrative_area)[0].selectedIndex = i;
								$(domfields.administrative_area).change();
								break;
							}
						}
					} else {
						$(domfields.administrative_area).val(suggestion.state).change();
					}
				}
				if (domfields.locality) {
					$(domfields.locality).val("").change();
					addr.usedAutocomplete = true;
					$(domfields.locality).val(suggestion.city).change();
				}
			}
			if (domfields.country && !domfields.country.options) {
				$(domfields.country).val("USA").change();
			}
			trigger("AutocompleteUsed", {
				address: addr,
				suggestion: suggestion
			});
		}

		// Computes where the little checkmark tag of the UI goes, relative to the boundaries of the last field
		function uiTagOffset(corners) {
			return {
				top: corners.top + corners.height / 2 - 10,
				left: corners.right - 6
			};
		}

		// This function is used to find and properly map elements to their field type
		function filterDomElement(domElement, names, labels) {
			/*
			 Where we look to find a match, in this order:
			 name, id, <label> tags, placeholder, title
			 Our searches first conduct fairly liberal "contains" searches:
			 if the attribute even contains the name or label, we map it.
			 The names and labels we choose to find are very particular.
			 */

			var name = lowercase(domElement.name);
			var id = lowercase(domElement.id);
			var selectorSafeID = id.replace(/[\[|\]|\(|\)|\:|\'|\"|\=|\||\#|\.|\!|\||\@|\^|\&|\*]/g, "\\\\$&");
			var placeholder = lowercase(domElement.placeholder);
			var title = lowercase(domElement.title);

			// First look through name and id attributes of the element, the most common
			for (var i = 0; i < names.length; i++)
				if (name.indexOf(names[i]) > -1 || id.indexOf(names[i]) > -1)
					return true;

			// If we can't find it in name or id, look at labels associated to the element.
			// Webkit automatically associates labels with form elements for us. But for other
			// browsers, we have to find them manually, which this next block does.
			if (!("labels" in domElement)) {
				var lbl = $("label[for=\"" + selectorSafeID + "\"]")[0] || $(domElement).parents("label")[0];
				domElement.labels = !lbl ? [] : [lbl];
			}

			// Iterate through the <label> tags now to search for a match.
			for (var i = 0; i < domElement.labels.length; i++) {
				// This inner loop compares each label value with what we're looking for
				for (var j = 0; j < labels.length; j++)
					if ($(domElement.labels[i]).text().toLowerCase().indexOf(labels[j]) > -1)
						return true;
			}

			// Still not found? Then look in "placeholder" or "title"...
			for (var i = 0; i < labels.length; i++)
				if (placeholder.indexOf(labels[i]) > -1 || title.indexOf(labels[i]) > -1)
					return true;

			// Got all the way to here? Probably not a match then.
			return false;
		}

		// User aborted the verification process (X click or esc keyup)
		function userAborted(uiPopup, e) {
			// Even though there may be more than one bound, and this disables the others,
			// this is for simplicity: and I figure, it won't happen too often.
			// (Otherwise "Completed" events are raised by pressing Esc even if nothing is happening)
			$(document).off("keyup");
			$(uiPopup).slideUp(defaults.speed, function () {
				$(this).parent(".smarty-ui").remove();
			});
			trigger("Completed", e.data);
		}

		// When we're done with a "pop-up" where the user chooses what to do,
		// we need to remove all other events bound on that whole "pop-up"
		// so that it doesn't interfere with any future "pop-ups".
		function turnOffAllClicks(selectors) {
			if (Array.isArray(selectors) || typeof selectors == "object") {
				for (var selector in selectors) {
					if (selectors.hasOwnProperty(selector)) {
						$("body").off("click", selectors[selector]);
					}
				}
			} else if (typeof selectors === "string") {
				$("body").off("click", selectors);
			} else {
				alert("ERROR: Not an array, string, or object passed in to turn off all clicks");
			}
		}

		// Utility function
		function moveCursorToEnd(el) { // Courtesy of http://css-tricks.com/snippets/javascript/move-cursor-to-end-of-input/
			if (typeof el.selectionStart == "number")
				el.selectionStart = el.selectionEnd = el.value.length;
			else if (typeof el.createTextRange != "undefined") {
				el.focus();
				var range = el.createTextRange();
				range.collapse(false);
				range.select();
			}
		}

		// Hides the autocomplete UI
		this.hideAutocomplete = function (addressID) {
			$(".smarty-autocomplete.smarty-addr-" + addressID).closest(".smarty-ui").hide();
		};

		//shows the SmartyUI when activating 1 address
		this.showSmartyUI = function (addressID) {
			var smartyui = $(".deactivated.smarty-addr-" + addressID);
			smartyui.push(smartyui[0].parentElement);
			smartyui.removeClass("deactivated");
			smartyui.addClass("activated");
			smartyui.show();
		};

		//hides the SmartyUI when deactivating 1 address
		this.hideSmartyUI = function (addressID) {
			var smartyui = $(".smarty-addr-" + addressID + ":visible");
			var autocompleteui = $(".smarty-autocomplete.smarty-addr-" + addressID);
			smartyui.addClass("deactivated");
			smartyui.parent().addClass("deactivated");
			autocompleteui.addClass("deactivated");
			smartyui.hide();
			smartyui.parent().hide();
			autocompleteui.hide();
		};

		// If anything was previously mapped, this resets it all for a new mapping.
		this.clean = function () {
			if (forms.length == 0)
				return;

			if (config.debug)
				console.log("Cleaning up old form map data and bindings...");

			// Spare none alive!

			for (var i = 0; i < forms.length; i++) {
				$(forms[i].dom).data(formDataProperty, "");

				// Clean up each form's DOM by resetting the address fields to the way they were
				for (var j = 0; j < forms[i].addresses.length; j++) {
					var doms = forms[i].addresses[j].getDomFields();
					for (var prop in doms) {
						if (doms.hasOwnProperty(prop)) {
							if (config.debug) {
								$(doms[prop]).removeClass("smarty-debug-input").attr("placeholder", "");
								var submitButtons = $(config.submitSelector);
								for (var k = 0; k < submitButtons.length; k++) {
									$(submitButtons[k]).removeClass("smarty-debug-button");
								}
							}
							$(doms[prop]).off("change", actionsOnChange);
						}
					}
					if (doms.address1)
						$(doms.address1).off("keyup").off("keydown").off("blur");
					else if (doms.freeform)
						$(doms.freeform).off("keyup").off("keydown").off("blur");
				}

				// Unbind our form submit and submit-button click handlers
				$.each(forms, function (idx) {
					$(this.dom).off("submit", submitHandler);
				});
				$(config.submitSelector, forms[i].dom).each(function (idx) {
					$(this).off("click", submitHandler);
				});
			}

			$(".smarty-ui").off("click", ".smarty-suggestion").off("mouseover", ".smarty-suggestion").off("mouseleave", ".smarty-suggestion").remove();

			if (config.smartyTag) {
				$("body").off("click", ".smarty-undo");
				$("body").off("click", ".smarty-tag-grayed");
			}

			$(window).off("resize.smarty");
			$(document).off("keyup");

			forms = [];
			mappedAddressCount = 0;

			if (config.debug)
				console.log("Done cleaning up; ready for new mapping.");
		};

		function disableBrowserAutofill(address) {
			//Does not disable autofill if config.autocomplete is disabled
			if (config.autocomplete > 0) {
				Object.keys(address).map(function (key) {
					var elem = $(address[key]);
					if (elem.length > 0) {
						elem.attr("autocomplete", "smartystreets");
					}
				});
			}
		}

		function addDefaultToStateDropdown(dom) {
			if (dom.getElementsByTagName("option").length > 0) {
				if (arrayContains(stateNames, dom.getElementsByTagName("option")[0].text.toUpperCase()) ||
					arrayContains(stateAbbreviations, dom.getElementsByTagName("option")[0].text.toUpperCase())) {
					var option = document.createElement("OPTION");
					option.innerText = "Pick a state";
					option.selected = true;
					$(dom.getElementsByTagName("select")[0]).prepend(option);
					$(dom).change();
				}
			}
		}

		// ** MANUAL MAPPING ** //
		this.mapFields = function (map) {
			// "map" should be an array of objects mapping field types
			// to a field by selector, all supplied by the user.

			if (config.debug)
				console.log("Manually mapping fields given this data:", map);

			this.clean();
			var formsFound = [];
			map = map instanceof Array ? map : [map];

			for (var addrIdx in map) {
				if (map.hasOwnProperty(addrIdx)) {
					var address = map[addrIdx];

					if (!address.country && config.target.indexOf("US") < 0)
						continue;

					// Convert selectors into actual DOM references

					var match = "";

					for (var fieldType in address) {
						if (address.hasOwnProperty(fieldType)) {
							if (fieldType == "match") {
								match = address[fieldType];
								delete address[fieldType];
							}
							if (fieldType != "id") {
								if (!arrayContains(acceptableFields, fieldType)) { // Make sure the field name is allowed
									if (config.debug)
										console.log("NOTICE: Field named " + fieldType + " is not allowed. Skipping...");
									delete address[fieldType];
									continue;
								}
								var matched = $(address[fieldType]);
								if (matched.length == 0) { // Don't try to map an element that couldn't be matched or found at all
									if (config.debug)
										console.log("NOTICE: No matches found for selector " + address[fieldType] + ". Skipping...");
									delete address[fieldType];
								} else if (matched.parents("form").length == 0) { // We should only map elements inside a <form> tag; otherwise we can't turn on submit handlers later
									if (config.debug)
										console.log("NOTICE: Element with selector \"" + address[fieldType] + "\" is not inside a <form> tag. Skipping...");
									delete address[fieldType];
								} else
									address[fieldType] = matched[0];
							}
						}
					}
					if (config.target.indexOf("INTERNATIONAL") >= 0) {
						if (!((address.country && address.freeform) || (address.country && address.address1 && address.postal_code) || (address.country && address.address1 && address.locality && address.administrative_area))) {
							if (config.debug)
								console.log("NOTICE: Address map (index " + addrIdx + ") was not mapped to a complete street address. Skipping...");
							continue;
						}
					} else {
						if (!((address.freeform) || (address.address1 && address.postal_code) || (address.address1 && address.locality && address.administrative_area))) {
							if (config.debug)
								console.log("NOTICE: Address map (index " + addrIdx + ") was not mapped to a complete street address. Skipping...");
							continue;
						}
					}

					// Acquire the form based on the first member
					var formDom = $(address.address1).parents("form")[0];
					if (!formDom) {
						formDom = $(address.freeform).parents("form")[0];
					}
					var form = new Form(formDom);

					// Persist a reference to the form if it wasn't acquired before
					if (!$(formDom).data(formDataProperty)) {
						// Mark the form as mapped then add it to our list
						$(formDom).data(formDataProperty, 1);
						disableBrowserAutofill(address);
						addDefaultToStateDropdown(form.dom);
						formsFound.push(form);
					} else {
						// Find the form in our list since we already put it there
						for (var i = 0; i < formsFound.length; i++) {
							if (formsFound[i].dom == formDom) {
								form = formsFound[i];
								break;
							}
						}
					}

					// Add this address to the form
					mappedAddressCount++;
					form.addresses.push(new Address(address, form, address.id, match));

					if (config.debug)
						console.log("Finished mapping address with ID: " + form.addresses[form.addresses.length - 1].id());
				}
			}

			forms = formsFound;
			trigger("FieldsMapped");
		};

		this.disableFields = function (address) {
			// Given an address, disables the input fields for the address, also the submit button
			if (!config.ui)
				return;

			var fields = address.getDomFields();
			for (var field in fields) {
				if (fields.hasOwnProperty(field)) {
					$(fields[field]).prop ? $(fields[field]).prop("disabled", true) : $(fields[field]).attr("disabled", "disabled");
				}
			}

			// Disable submit buttons
			if (address.form && address.form.dom) {
				var buttons = $(config.submitSelector, address.form.dom);
				buttons.prop ? buttons.prop("disabled", true) : buttons.attr("disabled", "disabled");
			}
		};

		this.enableFields = function (address) {
			// Given an address, re-enables the input fields for the address
			if (!config.ui)
				return;

			var fields = address.getDomFields();
			for (var field in fields) {
				if (fields.hasOwnProperty(field)) {
					$(fields[field]).prop ? $(fields[field]).prop("disabled", false) : $(fields[field]).removeAttr("disabled");
				}
			}

			// Enable submit buttons
			if (address.form && address.form.dom) {
				var buttons = $(config.submitSelector, address.form.dom);
				buttons.prop ? buttons.prop("disabled", false) : buttons.removeAttr("disabled");
			}
		};

		this.showLoader = function (addr) {
			if (!config.ui || !addr.hasDomFields())
				return;

			// Get position information now instead of earlier in case elements shifted since page load
			var lastFieldCorners = addr.corners(true);
			var loaderUI = $(".smarty-dots.smarty-addr-" + addr.id()).parent();

			loaderUI.css("top", (lastFieldCorners.top + lastFieldCorners.height / 2 - loaderHeight / 2) + "px")
				.css("left", (lastFieldCorners.right - loaderWidth - 10) + "px");
			$(".smarty-dots", loaderUI).show();
		};

		this.hideLoader = function (addr) {
			if (config.ui)
				$(".smarty-dots.smarty-addr-" + addr.id()).hide();
		};

		this.markAsValid = function (addr) {
			if (!config.ui || !addr || !config.smartyTag)
				return;

			var domTag = $(".smarty-tag.smarty-tag-grayed.smarty-addr-" + addr.id());
			domTag.removeClass("smarty-tag-grayed").addClass("smarty-tag-green").attr("title", "Address verified! Click to undo.");
			$(".smarty-tag-text", domTag).text("Verified").hover(function () {
				$(this).text("Undo");
			}, function () {
				$(this).text("Verified");
			}).addClass("smarty-undo");
		};

		this.unmarkAsValid = function (addr) {
			var validSelector = ".smarty-tag.smarty-addr-" + addr.id();
			if (!config.ui || !addr || !config.smartyTag || $(validSelector).length == 0)
				return;

			var domTag = $(".smarty-tag.smarty-tag-green.smarty-addr-" + addr.id());
			domTag.removeClass("smarty-tag-green").addClass("smarty-tag-grayed").attr("title", "Address not verified. Click to verify.");
			$(".smarty-tag-text", domTag).text("Verify").off("mouseenter mouseleave").removeClass("smarty-undo");
		};

		this.showAmbiguous = function (data) {
			if (!config.ui || !data.address.hasDomFields())
				return;

			var addr = data.address;
			var response = data.response;
			var corners = addr.corners();
			corners.width = 294;

			var html = "<div class=\"smarty-ui\" style=\"top: " + corners.top + "px; left: " + corners.left + "px;\">" +
				"<div class=\"smarty-popup smarty-addr-" + addr.id() + "\" style=\"width: " + corners.width + "px;\">" +
				"<div class=\"smarty-popup-header smarty-popup-ambiguous-header\">" + config.ambiguousMessage + "</div>" +
				"<div class=\"smarty-popup-typed-address\">" + addr.toString() + "</div>" +
				"<div class=\"smarty-choice-list\">";

			if (addr.isDomestic()) {
				for (var i = 0; i < response.raw.length; i++) {
					var line1 = response.raw[i].delivery_line_1,
						city = response.raw[i].components.city_name,
						st = response.raw[i].components.state_abbreviation,
						zip = response.raw[i].components.zipcode + "-" + response.raw[i].components.plus4_code;
					html += "<a href=\"javascript:\" class=\"smarty-choice\" data-index=\"" + i + "\">" + line1 + "<br>" + city + ", " + st + " " + zip + "</a>";
				}
			} else {
				var numCandidates = config.candidates;
				if (response.raw.length < numCandidates) {
					numCandidates = response.raw.length;
				}
				for (var i = 0; i < numCandidates; i++) {
					var ambigAddr = "";
					if (response.raw[i].address1) {
						ambigAddr += response.raw[i].address1;
					}
					if (response.raw[i].address2) {
						ambigAddr = ambigAddr + "<br>" + response.raw[i].address2;
					}
					if (response.raw[i].address3) {
						ambigAddr = ambigAddr + "<br>" + response.raw[i].address3;
					}
					if (response.raw[i].address4) {
						ambigAddr = ambigAddr + "<br>" + response.raw[i].address4;
					}
					if (response.raw[i].address5) {
						ambigAddr = ambigAddr + "<br>" + response.raw[i].address5;
					}
					if (response.raw[i].address6) {
						ambigAddr = ambigAddr + "<br>" + response.raw[i].address6;
					}
					html += "<a href=\"javascript:\" class=\"smarty-choice\" data-index=\"" + i + "\">" + ambigAddr + "</a>";
				}
			}

			html += "</div><div class=\"smarty-choice-alt\">";
			html += "<a href=\"javascript:\" class=\"smarty-choice smarty-choice-abort smarty-abort\">" + config.changeMessage + "</a>";
			if (!config.enforceVerification) {
				html += "<a href=\"javascript:\" class=\"smarty-choice smarty-choice-override\">" + config.certifyMessage + "</a>";
			}
			html += "</div></div></div>";
			$(html).hide().appendTo("body").show(defaults.speed);

			// Scroll to it if needed
			if ($(document).scrollTop() > corners.top - 100 || $(document).scrollTop() < corners.top - $(window).height() + 100) {
				$("html, body").stop().animate({
					scrollTop: $(".smarty-popup.smarty-addr-" + addr.id()).offset().top - 100
				}, 500);
			}

			data.selectors = {
				goodAddr: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-choice-list .smarty-choice",
				useOriginal: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-choice-override",
				abort: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-abort"
			};

			// User chose a candidate address
			$("body").on("click", data.selectors.goodAddr, data, function (e) {
				$(".smarty-popup.smarty-addr-" + addr.id()).slideUp(defaults.speed, function () {
					$(this).parent(".smarty-ui").remove();
					$(this).remove();
				});

				turnOffAllClicks(e.data.selectors);
				delete e.data.selectors;

				trigger("UsedSuggestedAddress", {
					address: e.data.address,
					response: e.data.response,
					invoke: e.data.invoke,
					invokeFn: e.data.invokeFn,
					chosenCandidate: response.raw[$(this).data("index")]
				});
			});

			// User wants to revert to what they typed (forced accept)
			$("body").on("click", data.selectors.useOriginal, data, function (e) {
				$(this).parents(".smarty-popup").slideUp(defaults.speed, function () {
					$(this).parent(".smarty-ui").remove();
					$(this).remove();
				});

				turnOffAllClicks(e.data.selectors);
				delete e.data.selectors;
				trigger("OriginalInputSelected", e.data);
			});

			// User presses Esc key
			$(document).keyup(data, function (e) {
				if (e.keyCode == 27) { //Esc
					turnOffAllClicks(e.data.selectors);
					delete e.data.selectors;
					userAborted($(".smarty-popup.smarty-addr-" + e.data.address.id()), e);
					suppress(e);
				}
			});

			// User clicks "x" in corner or chooses to try a different address (same effect as Esc key)
			$("body").on("click", data.selectors.abort, data, function (e) {
				turnOffAllClicks(e.data.selectors);
				delete e.data.selectors;
				userAborted($(this).parents(".smarty-popup"), e);
			});
		};

		this.showInvalid = function (data) {
			if (!config.ui || !data.address.hasDomFields())
				return;

			var addr = data.address;
			var corners = addr.corners();
			corners.width = 300;

			var html = "<div class=\"smarty-ui\" style=\"top: " + corners.top + "px; left: " + corners.left + "px;\">" +
				"<div class=\"smarty-popup smarty-addr-" + addr.id() + "\" style=\"width: " + corners.width + "px;\">" +
				"<div class=\"smarty-popup-header smarty-popup-invalid-header\">" + config.invalidMessage + "</div>" +
				"<div class=\"smarty-popup-typed-address\">" + addr.toString() + "</div>" +
				"<div class=\"smarty-choice-alt\">" +
				"<a href=\"javascript:\" class=\"smarty-choice smarty-choice-abort smarty-abort\">" + config.changeMessage + "</a>";
			if (!config.enforceVerification) {
				html += "<a href=\"javascript:\" class=\"smarty-choice smarty-choice-override\">" +
					config.certifyMessage + "</a>";
			}
			html += "</div></div>";

			$(html).hide().appendTo("body").show(defaults.speed);

			data.selectors = {
				useOriginal: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-choice-override ",
				abort: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-abort"
			};

			// Scroll to it if necessary
			if ($(document).scrollTop() > corners.top - 100 || $(document).scrollTop() < corners.top - $(window).height() + 100) {
				$("html, body").stop().animate({
					scrollTop: $(".smarty-popup.smarty-addr-" + addr.id()).offset().top - 100
				}, 500);
			}

			turnOffAllClicks(data.selectors.abort);
			// User rejects original input and agrees to double-check it
			$("body").on("click", data.selectors.abort, data, function (e) {
				userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				delete e.data.selectors;
				trigger("InvalidAddressRejected", e.data);
			});

			turnOffAllClicks(data.selectors.useOriginal);
			// User certifies that what they typed is correct
			$("body").on("click", data.selectors.useOriginal, data, function (e) {
				userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				delete e.data.selectors;
				trigger("OriginalInputSelected", e.data);
			});

			// User presses esc key
			$(document).keyup(data, function (e) {
				if (e.keyCode == 27) { //Esc
					turnOffAllClicks(e.data.selectors);
					$(data.selectors.abort).click();
					userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				}
			});
		};

		this.showInvalidCountry = function (data) {
			if (!config.ui || !data.address.hasDomFields())
				return;

			var addr = data.address;
			var corners = addr.corners();
			corners.width = 300;

			var html = "<div class=\"smarty-ui\" style=\"top: " + corners.top + "px; left: " + corners.left + "px;\">" +
				"<div class=\"smarty-popup smarty-addr-" + addr.id() + "\" style=\"width: " + corners.width + "px;\">" +
				"<div class=\"smarty-popup-header smarty-popup-invalid-header\">" + config.invalidCountryMessage + "</div>" +
				"<div class=\"smarty-popup-typed-address\">" + addr.toString() + "</div>" +
				"<div class=\"smarty-choice-alt\"><a href=\"javascript:\" class=\"smarty-choice smarty-choice-abort smarty-abort\">" +
				config.changeMessage + "</a></div>";
			if (!config.enforceVerification) {
				html += "<a href=\"javascript:\" class=\"smarty-choice smarty-choice-override\">" +
					config.certifyMessage + "</a>";
			}
			html += "</div></div>";

			$(html).hide().appendTo("body").show(defaults.speed);

			data.selectors = {
				useOriginal: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-choice-override ",
				abort: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-abort"
			};

			// Scroll to it if necessary
			if ($(document).scrollTop() > corners.top - 100 || $(document).scrollTop() < corners.top - $(window).height() + 100) {
				$("html, body").stop().animate({
					scrollTop: $(".smarty-popup.smarty-addr-" + addr.id()).offset().top - 100
				}, 500);
			}

			turnOffAllClicks(data.selectors.abort);
			// User rejects original input and agrees to double-check it
			$("body").on("click", data.selectors.abort, data, function (e) {
				userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				delete e.data.selectors;
				trigger("InvalidAddressRejected", e.data);
			});

			turnOffAllClicks(data.selectors.useOriginal);
			// User certifies that what they typed is correct
			$("body").on("click", data.selectors.useOriginal, data, function (e) {
				userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				delete e.data.selectors;
				trigger("OriginalInputSelected", e.data);
			});

			// User presses esc key
			$(document).keyup(data, function (e) {
				if (e.keyCode == 27) { //Esc
					turnOffAllClicks(e.data.selectors);
					$(data.selectors.abort).click();
					userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				}
			});
		};

		this.showMissingSecondary = function (data) {
			if (!config.ui || !data.address.hasDomFields())
				return;
			var addr = data.address;
			var corners = addr.corners();
			corners.width = 300;

			var html = "<div class=\"smarty-ui\" style=\"top: " + corners.top + "px; left: " + corners.left + "px;\">" +
				"<div class=\"smarty-popup smarty-addr-" + addr.id() + "\" style=\"width: " + corners.width + "px;\">" +
				"<div class=\"smarty-popup-header smarty-popup-missing-secondary-header\">" + config.missingSecondaryMessage +
				"</div>" + "<div class=\"smarty-popup-typed-address\">" + addr.toString() + "</div>" +
				"<form class=\"smarty-popup-secondary-number-form\">" +
				"<input id=\"smarty-popup-secondary-number-input-box\" class=\"smarty-addr-" + addr.id() +
				"\" type=\"text\" name=\"secondarynumber\" placeholder=\"Enter number here\"><br>" +
				"<input id=\"smarty-popup-secondary-number-form-submit-button\" class=\"smarty-addr-" + addr.id() +
				"\" type=\"submit\" value=\"Submit\">" +
				"</form>" +
				"<hr class=\"smarty-hr\">" + "<div class=\"smarty-choice-alt\">" + "<a href=\"javascript:\" " +
				"class=\"smarty-choice smarty-choice-abort smarty-abort\">" + config.changeMessage + "</a>";
			if (!config.enforceVerification) {
				html += "<a href=\"javascript:\" class=\"smarty-choice smarty-choice-override\">" +
					config.certifyMessage + "</a>";
			}
			html += "</div></div></div>";

			$(html).hide().appendTo("body").show(defaults.speed);

			data.selectors = {
				useOriginal: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-choice-override ",
				abort: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-abort",
				submit: "#smarty-popup-secondary-number-form-submit-button.smarty-addr-" + addr.id()
			};

			// Scroll to it if necessary
			if ($(document).scrollTop() > corners.top - 100 || $(document).scrollTop() < corners.top - $(window).height() + 100) {
				$("html, body").stop().animate({
					scrollTop: $(".smarty-popup.smarty-addr-" + addr.id()).offset().top - 100
				}, 500);
			}

			turnOffAllClicks(data.selectors.abort);
			// User rejects original input and agrees to double-check it
			$("body").on("click", data.selectors.abort, data, function (e) {
				userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				delete e.data.selectors;
				trigger("InvalidAddressRejected", e.data);
			});

			turnOffAllClicks(data.selectors.useOriginal);
			// User certifies that what they typed is correct
			$("body").on("click", data.selectors.useOriginal, data, function (e) {
				userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				delete e.data.selectors;
				trigger("OriginalInputSelected", e.data);
			});

			turnOffAllClicks(data.selectors.submit);
			// User enters a secondary address
			$("body").on("click", data.selectors.submit, data, function (e) {
				e.data.address.secondary = $("#smarty-popup-secondary-number-input-box.smarty-addr-" + e.data.address.id()).val();
				if (e.data.address.isFreeform()) {
					e.data.address.address1 = e.data.response.raw[0].delivery_line_1;
				}
				e.data.address.zipcode = e.data.response.raw[0].components.zipcode;
				userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				delete e.data.selectors;
				suppress(e);
				trigger("AddedSecondary", e.data);
			});

			// User presses esc key
			$(document).keyup(data, function (e) {
				if (e.keyCode == 27) { //Esc
					turnOffAllClicks(e.data.selectors);
					$(data.selectors.abort).click();
					userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				}
			});
		};

		this.showMissingInput = function (data) {
			if (!config.ui || !data.address.hasDomFields())
				return;

			var addr = data.address;
			var corners = addr.corners();
			corners.width = 300;

			var html = "<div class=\"smarty-ui\" style=\"top: " + corners.top + "px; left: " + corners.left + "px;\">" +
				"<div class=\"smarty-popup smarty-addr-" + addr.id() + "\" style=\"width: " + corners.width + "px;\">" +
				"<div class=\"smarty-popup-header smarty-popup-missing-input-header\">" + config.missingInputMessage + "</div>" +
				"<div class=\"smarty-popup-typed-address\">" + addr.toString() + "</div>" +
				"<div class=\"smarty-choice-alt\"><a href=\"javascript:\" " +
				"class=\"smarty-choice smarty-choice-abort smarty-abort\">" + config.changeMessage + "</a>";
			if (!config.enforceVerification) {
				html += "<a href=\"javascript:\" class=\"smarty-choice smarty-choice-override\">" +
					config.certifyMessage + "</a>";
			}
			html += "</div></div>";

			$(html).hide().appendTo("body").show(defaults.speed);

			data.selectors = {
				useOriginal: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-choice-override ",
				abort: ".smarty-popup.smarty-addr-" + addr.id() + " .smarty-abort"
			};

			// Scroll to it if necessary
			if ($(document).scrollTop() > corners.top - 100 || $(document).scrollTop() < corners.top - $(window).height() + 100) {
				$("html, body").stop().animate({
					scrollTop: $(".smarty-popup.smarty-addr-" + addr.id()).offset().top - 100
				}, 500);
			}

			turnOffAllClicks(data.selectors.abort);
			// User rejects original input and agrees to double-check it
			$("body").on("click", data.selectors.abort, data, function (e) {
				userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				delete e.data.selectors;
				trigger("InvalidAddressRejected", e.data);
			});

			turnOffAllClicks(data.selectors.useOriginal);
			// User certifies that what they typed is correct
			$("body").on("click", data.selectors.useOriginal, data, function (e) {
				userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				delete e.data.selectors;
				trigger("OriginalInputSelected", e.data);
			});

			// User presses esc key
			$(document).keyup(data, function (e) {
				if (e.keyCode == 27) { //Esc
					turnOffAllClicks(e.data.selectors);
					$(data.selectors.abort).click();
					userAborted(".smarty-popup.smarty-addr-" + e.data.address.id(), e);
				}
			});
		};

	}
901853
function doCommand(cmd) {
    //console.log("COMMAND",cmd);
    if (cmd.hasOwnProperty("clear")) {
        doTidyUp(cmd.clear);
    }
    if (cmd.hasOwnProperty("panit")) {
        if (cmd.panit == "true") { panit = true; }
        else { panit = false; }
        document.getElementById("panit").checked = panit;
    }
    if (cmd.hasOwnProperty("hiderightclick")) {
        if (cmd.hiderightclick == "true" || cmd.hiderightclick == true) { hiderightclick = true; }
        else { hiderightclick = false; }
    }
    if (cmd.hasOwnProperty("showmenu")) {
        if ((cmd.showmenu === "hide") && (showUserMenu === true)) {
            showUserMenu = false;
            if (inIframe) {
                if (menuButton) {
                    try { map.removeControl(menuButton); }
                    catch(e) {}
                }
            }
            else { document.getElementById("bars").style.display="none"; }
        }
        else if ((cmd.showmenu === "show") && (showUserMenu === false)) {
            showUserMenu = true;
            if (inIframe) { map.addControl(menuButton); }
            else { document.getElementById("bars").style.display="unset";  }
        }
    }
    if (cmd.hasOwnProperty("showlayers")) {
        if ((cmd.showlayers === "hide") && (showLayerMenu === true)) {
            showLayerMenu = false;
            layercontrol.removeFrom(map);
        }
        else if ((cmd.showlayers === "show") && (showLayerMenu === false)) {
            showLayerMenu = true;
            layercontrol = L.control.layers(basemaps, overlays).addTo(map);
        }
    }
    if (cmd.hasOwnProperty("grid")) {
        if (cmd.grid.hasOwnProperty("showgrid")) {
            var changed = false;
            if ((cmd.grid.showgrid == "true" || cmd.grid.showgrid == true ) && !showGrid) { changed = true; }
            if ((cmd.grid.showgrid == "false" || cmd.grid.showgrid == false ) && showGrid) { changed = true; }
            if (changed) {
                showGrid = !showGrid;
                if (showGrid) { Lgrid.addTo(map); }
                else { Lgrid.removeFrom(map); }
            }
        }
        if (cmd.grid.hasOwnProperty("opt")) {
            Lgrid.initialize(cmd.grid.opt);
            if (showGrid) {
                Lgrid.removeFrom(map);
                Lgrid.addTo(map);
            }
        }
    }
    if (cmd.hasOwnProperty("button")) {
        if (cmd.button.icon) {
            if (!buttons[cmd.button.name]) {
                buttons[cmd.button.name] = L.easyButton( cmd.button.icon, function() {
                    ws.send(JSON.stringify({action:"button",name:cmd.button.name}));
                }, cmd.button.name, { position:cmd.button.position||'topright' }).addTo(map);
            }
        }
        else {
            if (buttons[cmd.button.name]) {
                buttons[cmd.button.name].removeFrom(map);
                delete buttons[cmd.button.name];
            }
        }
    }
    if (cmd.hasOwnProperty("contextmenu")) {
        if (typeof cmd.contextmenu === "string") {
            addmenu = cmd.contextmenu;
            rightmenuMap.setContent(addmenu);
        }
    }
    if (cmd.hasOwnProperty("coords")) {
        try { coords.removeFrom(map); }
        catch(e) {}
        if (cmd.coords == "dms") {
            coords.options.useDMS = true;
            showMouseCoords = "dms";
            coords.addTo(map);
        }
        if (cmd.coords == "deg") {
            coords.options.useDMS = false;
            showMouseCoords = "deg";
            coords.addTo(map);
        }
    }

    var existsalready = false;
    // Add a new base map layer
    if (cmd.map && cmd.map.hasOwnProperty("name") && cmd.map.hasOwnProperty("url") && cmd.map.hasOwnProperty("opt")) {
        console.log("BASE",cmd.map);
        if (basemaps.hasOwnProperty(cmd.map.name)) { existsalready = true; }
        if (cmd.map.hasOwnProperty("wms")) {   // special case for wms
            console.log("New WMS:",cmd.map.name);
            if (cmd.map.wms === "grey") {
                basemaps[cmd.map.name] = L.tileLayer.graywms(cmd.map.url, cmd.map.opt);
            }
            else {
                basemaps[cmd.map.name] = L.tileLayer.wms(cmd.map.url, cmd.map.opt);
            }
        }
        else {
            console.log("New Map:",cmd.map.name);
            basemaps[cmd.map.name] = L.tileLayer(cmd.map.url, cmd.map.opt);
        }
        //if (!existsalready && !inIframe) {
        if (!existsalready) {
            layercontrol.addBaseLayer(basemaps[cmd.map.name],cmd.map.name);
        }
    }
    // Remove one or more map layers (base or overlay)
    if (cmd.map && cmd.map.hasOwnProperty("delete")) {
        if (!Array.isArray(cmd.map.delete)) { cmd.map.delete = [cmd.map.delete]; }
        for (var a=0; a < cmd.map.delete.length; a++) {
            if (basemaps.hasOwnProperty(cmd.map.delete[a])) { delete basemaps[cmd.map.delete[a]]; }
            if (overlays.hasOwnProperty(cmd.map.delete[a])) { delete overlays[cmd.map.delete[a]]; }
        }
        if (showLayerMenu) {
            map.removeControl(layercontrol);
            layercontrol = L.control.layers(basemaps, overlays).addTo(map);
        }
    }
    // Add a new geojson overlay layer
    if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("geojson") ) {
        if (overlays.hasOwnProperty(cmd.map.overlay)) {
            map.removeLayer(overlays[cmd.map.overlay]);
            existsalready = true;
        }
        var opt = cmd.map.opt || { style:function(feature) {
            var st = { stroke:true, weight:2, fill:true };
            if (feature.hasOwnProperty("properties")) {
                st.color = feature.properties.color||feature.properties.roofColor||"black";
                if (feature.properties.hasOwnProperty("color")) { delete feature.properties.color; }
                if (feature.properties.hasOwnProperty("roofColor")) { delete feature.properties.roofColor; }
            }
            if (feature.hasOwnProperty("properties") && feature.properties.hasOwnProperty('style')) {
                if (feature.properties.style.hasOwnProperty('stroke')) {
                    st.color = feature.properties.style.stroke;
                }
                if (feature.properties.style.hasOwnProperty('stroke-width')) {
                    st.weight = feature.properties.style["stroke-width"];
                }
                if (feature.properties.style.hasOwnProperty('stroke-opacity')) {
                    st.opacity = feature.properties.style["stroke-opacity"];
                }
                if (feature.properties.style.hasOwnProperty('fill')) {
                    if (feature.properties.style.fill == "none") { st.fill = false; }
                    else { st.fillColor = feature.properties.style.fill; }
                }
                if (feature.properties.style.hasOwnProperty('fill-opacity')) {
                    st.fillOpacity = feature.properties.style["fill-opacity"];
                }
            }
            delete feature.properties.style;
            return st;
        }};
        opt.onEachFeature = function (f,l) {
            l.bindPopup('<pre>'+JSON.stringify(f.properties,null,' ').replace(/[\{\}"]/g,'')+'</pre>');
        }
        overlays[cmd.map.overlay] = L.geoJson(cmd.map.geojson,opt);
        if (!existsalready) {
            layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
        }
        map.addLayer(overlays[cmd.map.overlay]);
        if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
    }
    // Add a new NVG XML overlay layer
    if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("nvg") ) {
        if (overlays.hasOwnProperty(cmd.map.overlay)) {
            map.removeLayer(overlays[cmd.map.overlay]);
            existsalready = true;
        }
        var parser = new NVG(cmd.map.nvg);
        var geoj = parser.toGeoJSON();

        overlays[cmd.map.overlay] = L.geoJson(geoj,{
            style: function(feature) {
                var st = { stroke:true, color:"black", weight:2, fill:true };
            	if (feature.hasOwnProperty("properties") && feature.properties.hasOwnProperty('style')) {
                    if (feature.properties.style.hasOwnProperty('stroke')) {
                        st.color = feature.properties.style.stroke;
                    }
                    if (feature.properties.style.hasOwnProperty('stroke-width')) {
                        st.weight = feature.properties.style["stroke-width"];
                    }
                    if (feature.properties.style.hasOwnProperty('stroke-opacity')) {
                        st.opacity = feature.properties.style["stroke-opacity"];
                    }
                    if (feature.properties.style.hasOwnProperty('fill')) {
                        if (feature.properties.style.fill == "none") { st.fill = false; }
                        else { st.fillColor = feature.properties.style.fill; }
                    }
                    if (feature.properties.style.hasOwnProperty('fill-opacity')) {
                        st.fillOpacity = feature.properties.style["fill-opacity"];
                    }
                }
                return st;
            }
        });
        if (!existsalready) {
            layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
        }
        map.addLayer(overlays[cmd.map.overlay]);
        if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
    }
    var custIco = function() {
        var customLayer = L.geoJson();
        if (cmd.map.hasOwnProperty("icon")) {
            var col = cmd.map.iconColor || "#910000";
            var myMarker = L.divIcon({
                className:"faicon",
                html: '<center><i class="fa fa-fw '+cmd.map.icon+'" style="color:'+col+'"></i></center>',
                iconSize: [15, 15],
            });
            customLayer = L.geoJson(null, {
                pointToLayer: function(geoJsonPoint, latlng) {
                    return L.marker(latlng, {icon: myMarker, title: geoJsonPoint.properties.name});
                }
            });
        }
        return customLayer;
    }
    // Add a new KML overlay layer
    if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("kml") ) {
        if (overlays.hasOwnProperty(cmd.map.overlay)) {
            map.removeLayer(overlays[cmd.map.overlay]);
            existsalready = true;
        }
        //var opt = {async:true};
        overlays[cmd.map.overlay] = omnivore.kml.parse(cmd.map.kml, null, custIco());
        if (!existsalready) {
            layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
        }
        map.addLayer(overlays[cmd.map.overlay]);
        if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
    }
    // Add a new TOPOJSON overlay layer
    if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("topojson") ) {
        if (overlays.hasOwnProperty(cmd.map.overlay)) {
            map.removeLayer(overlays[cmd.map.overlay]);
            existsalready = true;
        }
        overlays[cmd.map.overlay] = omnivore.topojson.parse(cmd.map.topojson);
        if (!existsalready) {
            layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
        }
        map.addLayer(overlays[cmd.map.overlay]);
        if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
    }
    // Add a new GPX overlay layer
    if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("gpx") ) {
        if (overlays.hasOwnProperty(cmd.map.overlay)) {
            map.removeLayer(overlays[cmd.map.overlay]);
            existsalready = true;
        }
        overlays[cmd.map.overlay] = omnivore.gpx.parse(cmd.map.gpx, null, custIco());

        if (!existsalready) {
            layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
        }
        map.addLayer(overlays[cmd.map.overlay]);
        if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
    }
    // Add a new velocity overlay layer
    if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("velocity") ) {
        if (overlays.hasOwnProperty(cmd.map.overlay)) {
            map.removeLayer(overlays[cmd.map.overlay]);
            existsalready = true;
        }
        overlays[cmd.map.overlay] = L.velocityLayer(cmd.map.velocity);
        if (!existsalready) {
            layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
        }
        map.addLayer(overlays[cmd.map.overlay]);
        if (cmd.map.hasOwnProperty("fit")) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
    }
    // Add a new overlay layer
    if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("url") && cmd.map.hasOwnProperty("opt")) {
        console.log("New overlay:",cmd.map.overlay);
        if (overlays.hasOwnProperty(cmd.map.overlay)) { existsalready = true; }
        if (cmd.map.hasOwnProperty("wms")) {   // special case for wms
            if (cmd.map.wms === "grey") {
                overlays[cmd.map.overlay] = L.tileLayer.graywms(cmd.map.url, cmd.map.opt);
            }
            else {
                overlays[cmd.map.overlay] = L.tileLayer.wms(cmd.map.url, cmd.map.opt);
            }
        }
        else if (cmd.map.hasOwnProperty("bounds")) {            //Image Overlay in the bounds specified (2D Array)
            if (cmd.map.bounds.length === 2 && cmd.map.bounds[0].length === 2 && cmd.map.bounds[1].length === 2) {
                overlays[cmd.map.overlay] = new L.imageOverlay(cmd.map.url, L.latLngBounds(cmd.map.bounds), cmd.map.opt);
            }
        }
        else {
            overlays[cmd.map.overlay] = L.tileLayer(cmd.map.url, cmd.map.opt);
        }
        //if (!existsalready && !inIframe) {
        if (!existsalready) {
            layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
        }
        map.addLayer(overlays[cmd.map.overlay]);
    }
    // Swap a base layer
    if (cmd.layer && basemaps.hasOwnProperty(cmd.layer)) {
        map.removeLayer(basemaps[baselayername]);
        baselayername = cmd.layer;
        basemaps[baselayername].addTo(map);
    }
    if (cmd.layer && (cmd.layer === "none")) {
        map.removeLayer(basemaps[baselayername]);
        baselayername = cmd.layer;
    }
    // Add search command
    if (cmd.hasOwnProperty("search") && (typeof cmd.search === "string")) {
        document.getElementById('search').value = cmd.search;
        if (cmd.search !== "") {
            openMenu();
            doSearch();
        }
        else {
            closeMenu();
            clearSearch();
        }
    }
    // Add side by side control
    if (cmd.side && (cmd.side === "none")) {
        sidebyside.remove();
        map.removeLayer(basemaps[sidebyside.lay]);
        sidebyside = undefined;
    }
    if (cmd.side && basemaps.hasOwnProperty(cmd.side)) {
        if (sidebyside) { sidebyside.remove(); map.removeLayer(basemaps[sidebyside.lay]); }
        basemaps[cmd.side].addTo(map);
        sidebyside = L.control.sideBySide(basemaps[baselayername], basemaps[cmd.side]);
        sidebyside.addTo(map);
        sidebyside.lay = cmd.side;
    }
    if (cmd.split && sidebyside && (cmd.split <= 100) && (cmd.split >= 0)) { sidebyside.setSplit(cmd.split); }
    // Turn on an existing overlay(s)
    if (cmd.hasOwnProperty("showlayer")) {
        if (typeof cmd.showlayer === "string") { cmd.showlayer = [ cmd.showlayer ]; }
        for (var i=0; i < cmd.showlayer.length; i++) {
            if (overlays.hasOwnProperty(cmd.showlayer[i])) {
                map.addLayer(overlays[cmd.showlayer[i]]);
            }
        }
    }
    // Turn off an existing overlay(s)
    if (cmd.hasOwnProperty("hidelayer")) {
        if (typeof cmd.hidelayer === "string") { cmd.hidelayer = [ cmd.hidelayer ]; }
        for (var i=0; i < cmd.hidelayer.length; i++) {
            if (overlays.hasOwnProperty(cmd.hidelayer[i])) {
                map.removeLayer(overlays[cmd.hidelayer[i]]);
            }
        }
    }
    // Lock the pan so map can be moved
    if (cmd.hasOwnProperty("panlock")) {
        if (cmd.panlock == "true" || cmd.panlock == true) { lockit = true; }
        else { lockit = false; doLock(false); }
        document.getElementById("lockit").checked = lockit;
    }
    // move to a new position
    var clat = map.getCenter().lat;
    var clon = map.getCenter().lng;
    var czoom = map.getZoom();
    if (cmd.hasOwnProperty("lat")) { clat = cmd.lat; }
    if (cmd.hasOwnProperty("lon")) { clon = cmd.lon; }
    if (cmd.hasOwnProperty("zoom")) { czoom = cmd.zoom; }
    map.setView([clat,clon],czoom);

    if (cmd.hasOwnProperty("cluster")) {
        clusterAt = cmd.cluster;
        document.getElementById("setclus").value = cmd.cluster;
        setCluster(clusterAt);
    }
    if (cmd.hasOwnProperty("maxage")) {
        document.getElementById("maxage").value = cmd.maxage;
        setMaxAge();
    }
    if (cmd.hasOwnProperty("heatmap")) {
        heat.setOptions(cmd.heatmap);
        document.getElementById("heatall").checked = !!cmd.heatmap;
        heat.redraw();
    }
    if (cmd.hasOwnProperty("panlock") && lockit === true) { doLock(true); }
    if (cmd.hasOwnProperty("zoomlock")) {
        if (cmd.zoomlock == "true" || cmd.zoomlock == true) {
            if (map.doubleClickZoom.enabled()) { map.removeControl(map.zoomControl); }
            map.doubleClickZoom.disable();
            map.scrollWheelZoom.disable();
        }
        else {
            if (!map.doubleClickZoom.enabled()) { map.addControl(map.zoomControl); }
            map.doubleClickZoom.enable();
            map.scrollWheelZoom.enable();
        }
    }
}
197377
function addonsManager_clearSearchField() {
    var textbox = this.getElement({type: "search_textbox"});
    var cmdKey = utils.getEntity(this.dtds, "selectAllCmd.key");

    this._controller.keypress(textbox, cmdKey, {accelKey: true});
    this._controller.keypress(textbox, 'VK_DELETE', {});
  }
510561
def generate_help_text(self):
        
        param_descrip = example = ""
        self.description_docs = u''

        rows, _ = get_window_dim()
        rows = int(rows)

        param_args = self.completer.leftover_args
        last_word = self.completer.unfinished_word
        command = self.completer.current_command
        new_command = ' '.join([command, last_word]).strip()

        if not self.completer.complete_command and new_command in self.completer.command_description:
            command = new_command

        # get command/group help
        if self.completer and command in self.completer.command_description:
            self.description_docs = u'{}'.format(self.completer.command_description[command])

        # get parameter help if full command
        if self.completer and command in self.completer.command_param_info:
            param = param_args[-1] if param_args else ''
            param = last_word if last_word.startswith('-') else param

            if param in self.completer.command_param_info[command] and self.completer.has_description(
                    command + " " + param):
                param_descrip = ''.join([
                    param, ":", '\n', self.completer.param_description.get(command + " " + param, '')])

            if command in self.completer.command_examples:
                string_example = []
                for example in self.completer.command_examples[command]:
                    for part in example:
                        string_example.append(part)
                ''.join(string_example)
                example = self._space_examples(
                    self.completer.command_examples[command], rows, self.example_page)

        return param_descrip, example
67503
function Autocomplete(el, options) {
      _classCallCheck(this, Autocomplete);

      var _this38 = _possibleConstructorReturn(this, (Autocomplete.__proto__ || Object.getPrototypeOf(Autocomplete)).call(this, Autocomplete, el, options));

      _this38.el.M_Autocomplete = _this38;

      /**
       * Options for the autocomplete
       * @member Autocomplete#options
       * @prop {Number} duration
       * @prop {Number} dist
       * @prop {number} shift
       * @prop {number} padding
       * @prop {Boolean} fullWidth
       * @prop {Boolean} indicators
       * @prop {Boolean} noWrap
       * @prop {Function} onCycleTo
       */
      _this38.options = $.extend({}, Autocomplete.defaults, options);

      // Setup
      _this38.isOpen = false;
      _this38.count = 0;
      _this38.activeIndex = -1;
      _this38.oldVal;
      _this38.$inputField = _this38.$el.closest('.input-field');
      _this38.$active = $();
      _this38._setupDropdown();

      _this38._setupEventHandlers();
      return _this38;
    }
1249382
def __complete_cmds(self, text):
        """"""
        return [ name for name in self._cmd_map_visible.keys() if name.startswith(text) ]
188889
function getMatchingCommands(context, prefix) {
  var commands = cli.getMapping(context).requisition.system.commands;
  var reply = commands.getAll().filter(function(command) {
    if (command.hidden) {
      return false;
    }

    if (prefix && command.name.indexOf(prefix) !== 0) {
      // Filtered out because they don't match the search
      return false;
    }
    if (!prefix && command.name.indexOf(' ') != -1) {
      // We don't show sub commands with plain 'help'
      return false;
    }
    return true;
  });

  reply.sort(function(c1, c2) {
    return c1.name.localeCompare(c2.name);
  });

  reply = reply.map(function(command) {
    return command.toJson();
  });

  return reply;
}
703192
function _parseForAutocomplete(fullCommandStr) {
    var fullCommandParsed = CommandParser.parse(fullCommandStr);
    var lastArg = _.last(fullCommandParsed.args);

    // If the last argument does not have an index, it means it's a cliff hanger (e.g., a space at
    // the end of the command string). Therefore, we'll assign it an index at the end of the input
    // string
    if (!_.isNumber(lastArg.i)) {
        lastArg.i = fullCommandStr.length;
    }

    return fullCommandParsed;
}
603082
function (path, options) {
	var settings = options || {};
	var args = [];
	var command = 'omxplayer';

	cache = setDefault();

	cache.path.value = path;
	cache.path.valid = true;

	args.push('"'+path+'"');

	if (['hdmi','local','both'].indexOf(settings.audioOutput) != -1) {
		args.push('-o');
		args.push(settings.audioOutput);
	}

	if (settings.blackBackground !== false) { // defaults to true
		args.push('-b');
	}

	if (settings.disableKeys === true) { //defaults to  false
		args.push('--no-keys')
	}

	if (settings.disableOnScreenDisplay === true) { //defaults to  false
		args.push('--no-osd')
	}

	if (settings.disableGhostbox === true) { //defaults to  false
		args.push('--no-ghost-box');
	}

	if (settings.loop === true) { // defaults to false
		args.push('--loop');
	}

	if (settings.subtitlePath && settings.subtitlePath != "" ){
		args.push('--subtitles');
		args.push('"'+settings.subtitlePath+'"');
	}

	if (settings.startAt){
		args.push('--pos');
		args.push(''+settings.startAt+'');
	}
	if (settings.layer){
		args.push('--layer');
		args.push(settings.layer);
	}
	args.push('--dbus_name');
	args.push('org.mpris.MediaPlayer2.omxplayer');

  exec(command+' '+args.join(' ')+' < omxpipe',function(error, stdout, stderr) {
		update_duration();
		console.log('omxpipe done');
		setTimeout( function() {
			checkProgressHandler();
		}, 1000);
  	console.log(stdout);
  });
  exec(' . > omxpipe');

  update_duration();

}
11226
def tag_autocomplete_js(format_string=None):
    """"""
    if format_string:
        context_list = format_string.split(' ')
        context = {
            'app_label':context_list[0],'model':context_list[1], 'counts':context_list[2]
        }
    else:
        context = {}
    return render_to_string('tagging_ext/tagging_autocomplete_js.html', context)
120436
final public function showCommandList(): void
    {
        $this->beforeShowCommandList();

        $ref   = new \ReflectionClass($this);
        $sName = \lcfirst(self::getName() ?: $ref->getShortName());

        if (!($classDes = self::getDescription())) {
            $classDes = PhpDoc::description($ref->getDocComment()) ?: 'No description for the command group';
        }

        $commands     = [];
        $showDisabled = (bool)$this->getOpt('show-disabled', false);
        $defaultDes   = 'No description message';

        foreach ($this->getAllCommandMethods($ref) as $cmd => $m) {
            if (!$cmd) {
                continue;
            }

            $desc = PhpDoc::firstLine($m->getDocComment()) ?: $defaultDes;

            // is a annotation tag
            if (\strpos($desc, '@') === 0) {
                $desc = $defaultDes;
            }

            if ($this->isDisabled($cmd)) {
                if (!$showDisabled) {
                    continue;
                }

                $desc .= '[<red>DISABLED</red>]';
            }

            $aliases = $this->getCommandAliases($cmd);
            $desc    .= $aliases ? ColorTag::wrap(' [alias: ' . \implode(',', $aliases) . ']', 'info') : '';

            $commands[$cmd] = $desc;
        }

        // sort commands
        \ksort($commands);

        // move 'help' to last.
        if ($helpCmd = $commands['help'] ?? null) {
            unset($commands['help']);
            $commands['help'] = $helpCmd;
        }

        $script = $this->getScriptName();

        if ($this->executionAlone) {
            $name  = $sName . ' ';
            $usage = "$script <info>{command}</info> [--options ...] [arguments ...]";
        } else {
            $name  = $sName . $this->delimiter;
            $usage = "$script {$name}<info>{command}</info> [--options ...] [arguments ...]";
        }

        $globalOptions = \array_merge(Application::getGlobalOptions(), static::$globalOptions);

        $this->output->startBuffer();
        $this->output->write(\ucfirst($classDes) . \PHP_EOL);
        $this->output->mList([
            'Usage:'              => $usage,
            //'Group Name:' => "<info>$sName</info>",
            'Global Options:'     => FormatUtil::alignOptions($globalOptions),
            'Available Commands:' => $commands,
        ], [
            'sepChar' => '  ',
        ]);

        $this->write(\sprintf(
            'More information about a command, please use: <cyan>%s %s{command} -h</cyan>',
            $script,
            $this->executionAlone ? '' : $name
        ));
        $this->output->flush();
    }
1342015
function _Overlay_findSiblings(commands) {
                    // Now make sure they're all in this container
                    var siblings = [];
                    var allCommands = this.element.querySelectorAll(".win-command");
                    var countAll, countIn;
                    for (countAll = 0; countAll < allCommands.length; countAll++) {
                        var found = false;
                        for (countIn = 0; countIn < commands.length; countIn++) {
                            if (commands[countIn] === allCommands[countAll]) {
                                commands.splice(countIn, 1);
                                found = true;
                                break;
                            }
                        }
                        if (!found) {
                            siblings.push(allCommands[countAll]);
                        }
                    }
                    return siblings;
                }
967830
function getMatch(ctx, data, options) {
  // Look for a command match, eliminating and then
  // re-introducing leading spaces.
  var len = ctx.length;
  var trimmed = ctx.replace(/^\s+/g, '');
  var match = autocomplete.match(trimmed, data.slice(), options);
  if (_.isArray(match)) {
    return match;
  }
  var prefix = new Array(len - trimmed.length + 1).join(' ');
  // If we get an autocomplete match on a command, finish it.
  if (match) {
    // Put the leading spaces back in.
    match = prefix + match;
    return match;
  }
  return undefined;
}
117686
function linkAutoComplete() {
    return listFiles('autocomplete')
        .then(filter(endsWith('.js')) & map(path.join('autocomplete', _)))
        .tap(files => all(files.map(file => fs.readFileAsync(file)
            .then(ensureNoImports(file)))));
}