PageSourceSearch

https://www.aeroportoditorino.it/plugins/SearchPhp/static/js/frontend/jquery.autocomplete1.11.3.js

js aeroportoditorino.it collected 2026-10-02 03:34:35 UTC 61,936 bytes, 1,793 lines download raw bytes

vendor: 4,583 bytes, lines 1-130
1
2/*!
3 * jQuery UI Widget 1.11.3
4 * http://jqueryui.com
5 *
6 * Copyright jQuery Foundation and other contributors
7 * Released under the MIT license.
8 * http://jquery.org/license
9 *
10 * http://api.jqueryui.com/jQuery.widget/
11 */
12
13
14var widget_uuid = 0,
15    widget_slice = Array.prototype.slice;
16
17$.cleanData = (function( orig ) {
18    return function( elems ) {
19        var events, elem, i;
20        for ( i = 0; (elem = elems[i]) != null; i++ ) {
21            try {
22
23                // Only trigger remove when necessary to save time
24                events = $._data( elem, "events" );
25                if ( events && events.remove ) {
26                    $( elem ).triggerHandler( "remove" );
27                }
28
29                // http://bugs.jquery.com/ticket/8235
30            } catch ( e ) {}
31        }
32        orig( elems );
33    };
34})( $.cleanData );
35
36$.widget = function( name, base, prototype ) {
37    var fullName, existingConstructor, constructor, basePrototype,
38    // proxiedPrototype allows the provided prototype to remain unmodified
39    // so that it can be used as a mixin for multiple widgets (#8876)
40        proxiedPrototype = {},
41        namespace = name.split( "." )[ 0 ];
42
43    name = name.split( "." )[ 1 ];
44    fullName = namespace + "-" + name;
45
46    if ( !prototype ) {
47        prototype = base;
48        base = $.Widget;
49    }
50
51    // create selector for plugin
52    $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
53        return !!$.data( elem, fullName );
54    };
55
56    $[ namespace ] = $[ namespace ] || {};
57    existingConstructor = $[ namespace ][ name ];
58    constructor = $[ namespace ][ name ] = function( options, element ) {
59        // allow instantiation without "new" keyword
60        if ( !this._createWidget ) {
61            return new constructor( options, element );
62        }
63
64        // allow instantiation without initializing for simple inheritance
65        // must use "new" keyword (the code above always passes args)
66        if ( arguments.length ) {
67            this._createWidget( options, element );
68        }
69    };
70    // extend with the existing constructor to carry over any static properties
71    $.extend( constructor, existingConstructor, {
72        version: prototype.version,
73        // copy the object used to create the prototype in case we need to
74        // redefine the widget later
75        _proto: $.extend( {}, prototype ),
76        // track widgets that inherit from this widget in case this widget is
77        // redefined after a widget inherits from it
78        _childConstructors: []
79    });
80
81    basePrototype = new base();
82    // we need to make the options hash a property directly on the new instance
83    // otherwise we'll modify the options hash on the prototype that we're
84    // inheriting from
85    basePrototype.options = $.widget.extend( {}, basePrototype.options );
86    $.each( prototype, function( prop, value ) {
87        if ( !$.isFunction( value ) ) {
88            proxiedPrototype[ prop ] = value;
89            return;
90        }
91        proxiedPrototype[ prop ] = (function() {
92            var _super = function() {
93                    return base.prototype[ prop ].apply( this, arguments );
94                },
95                _superApply = function( args ) {
96                    return base.prototype[ prop ].apply( this, args );
97                };
98            return function() {
99                var __super = this._super,
100                    __superApply = this._superApply,
101                    returnValue;
102
103                this._super = _super;
104                this._superApply = _superApply;
105
106                returnValue = value.apply( this, arguments );
107
108                this._super = __super;
109                this._superApply = __superApply;
110
111                return returnValue;
112            };
113        })();
114    });
115    constructor.prototype = $.widget.extend( basePrototype, {
116        // TODO: remove support for widgetEventPrefix
117        // always use the name + a colon as the prefix, e.g., draggable:start
118        // don't prefix for widgets that aren't DOM-based
119        widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
120    }, proxiedPrototype, {
121        constructor: constructor,
122        namespace: namespace,
123        widgetName: name,
124        widgetFullName: fullName
125    });
126
127    // If this widget is being redefined then we need to find all widgets that
128    // are inheriting from it and redefine all of them so that they inherit from
129    // the new version of this widget. We're essentially trying to replace one
130    // level in the prototype chain.
vendor: 25,140 bytes, lines 131-845
131    if ( existingConstructor ) {
132        $.each( existingConstructor._childConstructors, function( i, child ) {
133            var childPrototype = child.prototype;
134
135            // redefine the child widget using the same prototype that was
136            // originally used, but inherit from the new version of the base
137            $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
138        });
139        // remove the list of existing child constructors from the old constructor
140        // so the old child constructors can be garbage collected
141        delete existingConstructor._childConstructors;
142    } else {
143        base._childConstructors.push( constructor );
144    }
145
146    $.widget.bridge( name, constructor );
147
148    return constructor;
149};
150
151$.widget.extend = function( target ) {
152    var input = widget_slice.call( arguments, 1 ),
153        inputIndex = 0,
154        inputLength = input.length,
155        key,
156        value;
157    for ( ; inputIndex < inputLength; inputIndex++ ) {
158        for ( key in input[ inputIndex ] ) {
159            value = input[ inputIndex ][ key ];
160            if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
161                // Clone objects
162                if ( $.isPlainObject( value ) ) {
163                    target[ key ] = $.isPlainObject( target[ key ] ) ?
164                        $.widget.extend( {}, target[ key ], value ) :
165                        // Don't extend strings, arrays, etc. with objects
166                        $.widget.extend( {}, value );
167                    // Copy everything else by reference
168                } else {
169                    target[ key ] = value;
170                }
171            }
172        }
173    }
174    return target;
175};
176
177$.widget.bridge = function( name, object ) {
178    var fullName = object.prototype.widgetFullName || name;
179    $.fn[ name ] = function( options ) {
180        var isMethodCall = typeof options === "string",
181            args = widget_slice.call( arguments, 1 ),
182            returnValue = this;
183
184        if ( isMethodCall ) {
185            this.each(function() {
186                var methodValue,
187                    instance = $.data( this, fullName );
188                if ( options === "instance" ) {
189                    returnValue = instance;
190                    return false;
191                }
192                if ( !instance ) {
193                    return $.error( "cannot call methods on " + name + " prior to initialization; " +
194                        "attempted to call method '" + options + "'" );
195                }
196                if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
197                    return $.error( "no such method '" + options + "' for " + name + " widget instance" );
198                }
199                methodValue = instance[ options ].apply( instance, args );
200                if ( methodValue !== instance && methodValue !== undefined ) {
201                    returnValue = methodValue && methodValue.jquery ?
202                        returnValue.pushStack( methodValue.get() ) :
203                        methodValue;
204                    return false;
205                }
206            });
207        } else {
208
209            // Allow multiple hashes to be passed on init
210            if ( args.length ) {
211                options = $.widget.extend.apply( null, [ options ].concat(args) );
212            }
213
214            this.each(function() {
215                var instance = $.data( this, fullName );
216                if ( instance ) {
217                    instance.option( options || {} );
218                    if ( instance._init ) {
219                        instance._init();
220                    }
221                } else {
222                    $.data( this, fullName, new object( options, this ) );
223                }
224            });
225        }
226
227        return returnValue;
228    };
229};
230
231$.Widget = function( /* options, element */ ) {};
232$.Widget._childConstructors = [];
233
234$.Widget.prototype = {
235    widgetName: "widget",
236    widgetEventPrefix: "",
237    defaultElement: "<div>",
238    options: {
239        disabled: false,
240
241        // callbacks
242        create: null
243    },
244    _createWidget: function( options, element ) {
245        element = $( element || this.defaultElement || this )[ 0 ];
246        this.element = $( element );
247        this.uuid = widget_uuid++;
248        this.eventNamespace = "." + this.widgetName + this.uuid;
249
250        this.bindings = $();
251        this.hoverable = $();
252        this.focusable = $();
253
254        if ( element !== this ) {
255            $.data( element, this.widgetFullName, this );
256            this._on( true, this.element, {
257                remove: function( event ) {
258                    if ( event.target === element ) {
259                        this.destroy();
260                    }
261                }
262            });
263            this.document = $( element.style ?
264                // element within the document
265                element.ownerDocument :
266                // element is window or document
267                element.document || element );
268            this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
269        }
270
271        this.options = $.widget.extend( {},
272            this.options,
273            this._getCreateOptions(),
274            options );
275
276        this._create();
277        this._trigger( "create", null, this._getCreateEventData() );
278        this._init();
279    },
280    _getCreateOptions: $.noop,
281    _getCreateEventData: $.noop,
282    _create: $.noop,
283    _init: $.noop,
284
285    destroy: function() {
286        this._destroy();
287        // we can probably remove the unbind calls in 2.0
288        // all event bindings should go through this._on()
289        this.element
290            .unbind( this.eventNamespace )
291            .removeData( this.widgetFullName )
292            // support: jquery <1.6.3
293            // http://bugs.jquery.com/ticket/9413
294            .removeData( $.camelCase( this.widgetFullName ) );
295        this.widget()
296            .unbind( this.eventNamespace )
297            .removeAttr( "aria-disabled" )
298            .removeClass(
299                this.widgetFullName + "-disabled " +
300                "ui-state-disabled" );
301
302        // clean up events and states
303        this.bindings.unbind( this.eventNamespace );
304        this.hoverable.removeClass( "ui-state-hover" );
305        this.focusable.removeClass( "ui-state-focus" );
306    },
307    _destroy: $.noop,
308
309    widget: function() {
310        return this.element;
311    },
312
313    option: function( key, value ) {
314        var options = key,
315            parts,
316            curOption,
317            i;
318
319        if ( arguments.length === 0 ) {
320            // don't return a reference to the internal hash
321            return $.widget.extend( {}, this.options );
322        }
323
324        if ( typeof key === "string" ) {
325            // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
326            options = {};
327            parts = key.split( "." );
328            key = parts.shift();
329            if ( parts.length ) {
330                curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
331                for ( i = 0; i < parts.length - 1; i++ ) {
332                    curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
333                    curOption = curOption[ parts[ i ] ];
334                }
335                key = parts.pop();
336                if ( arguments.length === 1 ) {
337                    return curOption[ key ] === undefined ? null : curOption[ key ];
338                }
339                curOption[ key ] = value;
340            } else {
341                if ( arguments.length === 1 ) {
342                    return this.options[ key ] === undefined ? null : this.options[ key ];
343                }
344                options[ key ] = value;
345            }
346        }
347
348        this._setOptions( options );
349
350        return this;
351    },
352    _setOptions: function( options ) {
353        var key;
354
355        for ( key in options ) {
356            this._setOption( key, options[ key ] );
357        }
358
359        return this;
360    },
361    _setOption: function( key, value ) {
362        this.options[ key ] = value;
363
364        if ( key === "disabled" ) {
365            this.widget()
366                .toggleClass( this.widgetFullName + "-disabled", !!value );
367
368            // If the widget is becoming disabled, then nothing is interactive
369            if ( value ) {
370                this.hoverable.removeClass( "ui-state-hover" );
371                this.focusable.removeClass( "ui-state-focus" );
372            }
373        }
374
375        return this;
376    },
377
378    enable: function() {
379        return this._setOptions({ disabled: false });
380    },
381    disable: function() {
382        return this._setOptions({ disabled: true });
383    },
384
385    _on: function( suppressDisabledCheck, element, handlers ) {
386        var delegateElement,
387            instance = this;
388
389        // no suppressDisabledCheck flag, shuffle arguments
390        if ( typeof suppressDisabledCheck !== "boolean" ) {
391            handlers = element;
392            element = suppressDisabledCheck;
393            suppressDisabledCheck = false;
394        }
395
396        // no element argument, shuffle and use this.element
397        if ( !handlers ) {
398            handlers = element;
399            element = this.element;
400            delegateElement = this.widget();
401        } else {
402            element = delegateElement = $( element );
403            this.bindings = this.bindings.add( element );
404        }
405
406        $.each( handlers, function( event, handler ) {
407            function handlerProxy() {
408                // allow widgets to customize the disabled handling
409                // - disabled as an array instead of boolean
410                // - disabled class as method for disabling individual parts
411                if ( !suppressDisabledCheck &&
412                    ( instance.options.disabled === true ||
413                        $( this ).hasClass( "ui-state-disabled" ) ) ) {
414                    return;
415                }
416                return ( typeof handler === "string" ? instance[ handler ] : handler )
417                    .apply( instance, arguments );
418            }
419
420            // copy the guid so direct unbinding works
421            if ( typeof handler !== "string" ) {
422                handlerProxy.guid = handler.guid =
423                    handler.guid || handlerProxy.guid || $.guid++;
424            }
425
426            var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
427                eventName = match[1] + instance.eventNamespace,
428                selector = match[2];
429            if ( selector ) {
430                delegateElement.delegate( selector, eventName, handlerProxy );
431            } else {
432                element.bind( eventName, handlerProxy );
433            }
434        });
435    },
436
437    _off: function( element, eventName ) {
438        eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
439            this.eventNamespace;
440        element.unbind( eventName ).undelegate( eventName );
441
442        // Clear the stack to avoid memory leaks (#10056)
443        this.bindings = $( this.bindings.not( element ).get() );
444        this.focusable = $( this.focusable.not( element ).get() );
445        this.hoverable = $( this.hoverable.not( element ).get() );
446    },
447
448    _delay: function( handler, delay ) {
449        function handlerProxy() {
450            return ( typeof handler === "string" ? instance[ handler ] : handler )
451                .apply( instance, arguments );
452        }
453        var instance = this;
454        return setTimeout( handlerProxy, delay || 0 );
455    },
456
457    _hoverable: function( element ) {
458        this.hoverable = this.hoverable.add( element );
459        this._on( element, {
460            mouseenter: function( event ) {
461                $( event.currentTarget ).addClass( "ui-state-hover" );
462            },
463            mouseleave: function( event ) {
464                $( event.currentTarget ).removeClass( "ui-state-hover" );
465            }
466        });
467    },
468
469    _focusable: function( element ) {
470        this.focusable = this.focusable.add( element );
471        this._on( element, {
472            focusin: function( event ) {
473                $( event.currentTarget ).addClass( "ui-state-focus" );
474            },
475            focusout: function( event ) {
476                $( event.currentTarget ).removeClass( "ui-state-focus" );
477            }
478        });
479    },
480
481    _trigger: function( type, event, data ) {
482        var prop, orig,
483            callback = this.options[ type ];
484
485        data = data || {};
486        event = $.Event( event );
487        event.type = ( type === this.widgetEventPrefix ?
488            type :
489            this.widgetEventPrefix + type ).toLowerCase();
490        // the original event may come from any element
491        // so we need to reset the target on the new event
492        event.target = this.element[ 0 ];
493
494        // copy original event properties over to the new event
495        orig = event.originalEvent;
496        if ( orig ) {
497            for ( prop in orig ) {
498                if ( !( prop in event ) ) {
499                    event[ prop ] = orig[ prop ];
500                }
501            }
502        }
503
504        this.element.trigger( event, data );
505        return !( $.isFunction( callback ) &&
506            callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
507            event.isDefaultPrevented() );
508    }
509};
510
511$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
512    $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
513        if ( typeof options === "string" ) {
514            options = { effect: options };
515        }
516        var hasOptions,
517            effectName = !options ?
518                method :
519                    options === true || typeof options === "number" ?
520                defaultEffect :
521                options.effect || defaultEffect;
522        options = options || {};
523        if ( typeof options === "number" ) {
524            options = { duration: options };
525        }
526        hasOptions = !$.isEmptyObject( options );
527        options.complete = callback;
528        if ( options.delay ) {
529            element.delay( options.delay );
530        }
531        if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
532            element[ method ]( options );
533        } else if ( effectName !== method && element[ effectName ] ) {
534            element[ effectName ]( options.duration, options.easing, callback );
535        } else {
536            element.queue(function( next ) {
537                $( this )[ method ]();
538                if ( callback ) {
539                    callback.call( element[ 0 ] );
540                }
541                next();
542            });
543        }
544    };
545});
546
547var widget = $.widget;
548
549
550
551/*!
552 * jQuery UI Menu 1.11.3
553 * http://jqueryui.com
554 *
555 * Copyright jQuery Foundation and other contributors
556 * Released under the MIT license.
557 * http://jquery.org/license
558 *
559 * http://api.jqueryui.com/menu/
560 */
561
562
563var menu = $.widget( "ui.menu", {
564    version: "1.11.3",
565    defaultElement: "<ul>",
566    delay: 300,
567    options: {
568        icons: {
569            submenu: "ui-icon-carat-1-e"
570        },
571        items: "> *",
572        menus: "ul",
573        position: {
574            my: "left-1 top",
575            at: "right top"
576        },
577        role: "menu",
578
579        // callbacks
580        blur: null,
581        focus: null,
582        select: null
583    },
584
585    _create: function() {
586        this.activeMenu = this.element;
587
588        // Flag used to prevent firing of the click handler
589        // as the event bubbles up through nested menus
590        this.mouseHandled = false;
591        this.element
592            .uniqueId()
593            .addClass( "ui-menu ui-widget ui-widget-content" )
594            .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
595            .attr({
596                role: this.options.role,
597                tabIndex: 0
598            });
599
600        if ( this.options.disabled ) {
601            this.element
602                .addClass( "ui-state-disabled" )
603                .attr( "aria-disabled", "true" );
604        }
605
606        this._on({
607            // Prevent focus from sticking to links inside menu after clicking
608            // them (focus should always stay on UL during navigation).
609            "mousedown .ui-menu-item": function( event ) {
610                event.preventDefault();
611            },
612            "click .ui-menu-item": function( event ) {
613                var target = $( event.target );
614                if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
615                    this.select( event );
616
617                    // Only set the mouseHandled flag if the event will bubble, see #9469.
618                    if ( !event.isPropagationStopped() ) {
619                        this.mouseHandled = true;
620                    }
621
622                    // Open submenu on click
623                    if ( target.has( ".ui-menu" ).length ) {
624                        this.expand( event );
625                    } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
626
627                        // Redirect focus to the menu
628                        this.element.trigger( "focus", [ true ] );
629
630                        // If the active item is on the top level, let it stay active.
631                        // Otherwise, blur the active item since it is no longer visible.
632                        if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
633                            clearTimeout( this.timer );
634                        }
635                    }
636                }
637            },
638            "mouseenter .ui-menu-item": function( event ) {
639                // Ignore mouse events while typeahead is active, see #10458.
640                // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
641                // is over an item in the menu
642                if ( this.previousFilter ) {
643                    return;
644                }
645                var target = $( event.currentTarget );
646                // Remove ui-state-active class from siblings of the newly focused menu item
647                // to avoid a jump caused by adjacent elements both having a class with a border
648                target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
649                this.focus( event, target );
650            },
651            mouseleave: "collapseAll",
652            "mouseleave .ui-menu": "collapseAll",
653            focus: function( event, keepActiveItem ) {
654                // If there's already an active item, keep it active
655                // If not, activate the first item
656                var item = this.active || this.element.find( this.options.items ).eq( 0 );
657
658                if ( !keepActiveItem ) {
659                    this.focus( event, item );
660                }
661            },
662            blur: function( event ) {
663                this._delay(function() {
664                    if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
665                        this.collapseAll( event );
666                    }
667                });
668            },
669            keydown: "_keydown"
670        });
671
672        this.refresh();
673
674        // Clicks outside of a menu collapse any open menus
675        this._on( this.document, {
676            click: function( event ) {
677                if ( this._closeOnDocumentClick( event ) ) {
678                    this.collapseAll( event );
679                }
680
681                // Reset the mouseHandled flag
682                this.mouseHandled = false;
683            }
684        });
685    },
686
687    _destroy: function() {
688        // Destroy (sub)menus
689        this.element
690            .removeAttr( "aria-activedescendant" )
691            .find( ".ui-menu" ).addBack()
692            .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
693            .removeAttr( "role" )
694            .removeAttr( "tabIndex" )
695            .removeAttr( "aria-labelledby" )
696            .removeAttr( "aria-expanded" )
697            .removeAttr( "aria-hidden" )
698            .removeAttr( "aria-disabled" )
699            .removeUniqueId()
700            .show();
701
702        // Destroy menu items
703        this.element.find( ".ui-menu-item" )
704            .removeClass( "ui-menu-item" )
705            .removeAttr( "role" )
706            .removeAttr( "aria-disabled" )
707            .removeUniqueId()
708            .removeClass( "ui-state-hover" )
709            .removeAttr( "tabIndex" )
710            .removeAttr( "role" )
711            .removeAttr( "aria-haspopup" )
712            .children().each( function() {
713                var elem = $( this );
714                if ( elem.data( "ui-menu-submenu-carat" ) ) {
715                    elem.remove();
716                }
717            });
718
719        // Destroy menu dividers
720        this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
721    },
722
723    _keydown: function( event ) {
724        var match, prev, character, skip,
725            preventDefault = true;
726
727        switch ( event.keyCode ) {
728            case $.ui.keyCode.PAGE_UP:
729                this.previousPage( event );
730                break;
731            case $.ui.keyCode.PAGE_DOWN:
732                this.nextPage( event );
733                break;
734            case $.ui.keyCode.HOME:
735                this._move( "first", "first", event );
736                break;
737            case $.ui.keyCode.END:
738                this._move( "last", "last", event );
739                break;
740            case $.ui.keyCode.UP:
741                this.previous( event );
742                break;
743            case $.ui.keyCode.DOWN:
744                this.next( event );
745                break;
746            case $.ui.keyCode.LEFT:
747                this.collapse( event );
748                break;
749            case $.ui.keyCode.RIGHT:
750                if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
751                    this.expand( event );
752                }
753                break;
754            case $.ui.keyCode.ENTER:
755            case $.ui.keyCode.SPACE:
756                this._activate( event );
757                break;
758            case $.ui.keyCode.ESCAPE:
759                this.collapse( event );
760                break;
761            default:
762                preventDefault = false;
763                prev = this.previousFilter || "";
764                character = String.fromCharCode( event.keyCode );
765                skip = false;
766
767                clearTimeout( this.filterTimer );
768
769                if ( character === prev ) {
770                    skip = true;
771                } else {
772                    character = prev + character;
773                }
774
775                match = this._filterMenuItems( character );
776                match = skip && match.index( this.active.next() ) !== -1 ?
777                    this.active.nextAll( ".ui-menu-item" ) :
778                    match;
779
780                // If no matches on the current filter, reset to the last character pressed
781                // to move down the menu to the first item that starts with that character
782                if ( !match.length ) {
783                    character = String.fromCharCode( event.keyCode );
784                    match = this._filterMenuItems( character );
785                }
786
787                if ( match.length ) {
788                    this.focus( event, match );
789                    this.previousFilter = character;
790                    this.filterTimer = this._delay(function() {
791                        delete this.previousFilter;
792                    }, 1000 );
793                } else {
794                    delete this.previousFilter;
795                }
796        }
797
798        if ( preventDefault ) {
799            event.preventDefault();
800        }
801    },
802
803    _activate: function( event ) {
804        if ( !this.active.is( ".ui-state-disabled" ) ) {
805            if ( this.active.is( "[aria-haspopup='true']" ) ) {
806                this.expand( event );
807            } else {
808                this.select( event );
809            }
810        }
811    },
812
813    refresh: function() {
814        var menus, items,
815            that = this,
816            icon = this.options.icons.submenu,
817            submenus = this.element.find( this.options.menus );
818
819        this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
820
821        // Initialize nested menus
822        submenus.filter( ":not(.ui-menu)" )
823            .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
824            .hide()
825            .attr({
826                role: this.options.role,
827                "aria-hidden": "true",
828                "aria-expanded": "false"
829            })
830            .each(function() {
831                var menu = $( this ),
832                    item = menu.parent(),
833                    submenuCarat = $( "<span>" )
834                        .addClass( "ui-menu-icon ui-icon " + icon )
835                        .data( "ui-menu-submenu-carat", true );
836
837                item
838                    .attr( "aria-haspopup", "true" )
839                    .prepend( submenuCarat );
840                menu.attr( "aria-labelledby", item.attr( "id" ) );
841            });
842
843        menus = submenus.add( this.element );
844        items = menus.find( this.options.items );
845
vendor: 10,338 bytes, lines 846-1165
846        // Initialize menu-items containing spaces and/or dashes only as dividers
847        items.not( ".ui-menu-item" ).each(function() {
848            var item = $( this );
849            if ( that._isDivider( item ) ) {
850                item.addClass( "ui-widget-content ui-menu-divider" );
851            }
852        });
853
854        // Don't refresh list items that are already adapted
855        items.not( ".ui-menu-item, .ui-menu-divider" )
856            .addClass( "ui-menu-item" )
857            .uniqueId()
858            .attr({
859                tabIndex: -1,
860                role: this._itemRole()
861            });
862
863        // Add aria-disabled attribute to any disabled menu item
864        items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
865
866        // If the active item has been removed, blur the menu
867        if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
868            this.blur();
869        }
870    },
871
872    _itemRole: function() {
873        return {
874            menu: "menuitem",
875            listbox: "option"
876        }[ this.options.role ];
877    },
878
879    _setOption: function( key, value ) {
880        if ( key === "icons" ) {
881            this.element.find( ".ui-menu-icon" )
882                .removeClass( this.options.icons.submenu )
883                .addClass( value.submenu );
884        }
885        if ( key === "disabled" ) {
886            this.element
887                .toggleClass( "ui-state-disabled", !!value )
888                .attr( "aria-disabled", value );
889        }
890        this._super( key, value );
891    },
892
893    focus: function( event, item ) {
894        var nested, focused;
895        this.blur( event, event && event.type === "focus" );
896
897        this._scrollIntoView( item );
898
899        this.active = item.first();
900        focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
901        // Only update aria-activedescendant if there's a role
902        // otherwise we assume focus is managed elsewhere
903        if ( this.options.role ) {
904            this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
905        }
906
907        // Highlight active parent menu item, if any
908        this.active
909            .parent()
910            .closest( ".ui-menu-item" )
911            .addClass( "ui-state-active" );
912
913        if ( event && event.type === "keydown" ) {
914            this._close();
915        } else {
916            this.timer = this._delay(function() {
917                this._close();
918            }, this.delay );
919        }
920
921        nested = item.children( ".ui-menu" );
922        if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
923            this._startOpening(nested);
924        }
925        this.activeMenu = item.parent();
926
927        this._trigger( "focus", event, { item: item } );
928    },
929
930    _scrollIntoView: function( item ) {
931        var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
932        if ( this._hasScroll() ) {
933            borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
934            paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
935            offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
936            scroll = this.activeMenu.scrollTop();
937            elementHeight = this.activeMenu.height();
938            itemHeight = item.outerHeight();
939
940            if ( offset < 0 ) {
941                this.activeMenu.scrollTop( scroll + offset );
942            } else if ( offset + itemHeight > elementHeight ) {
943                this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
944            }
945        }
946    },
947
948    blur: function( event, fromFocus ) {
949        if ( !fromFocus ) {
950            clearTimeout( this.timer );
951        }
952
953        if ( !this.active ) {
954            return;
955        }
956
957        this.active.removeClass( "ui-state-focus" );
958        this.active = null;
959
960        this._trigger( "blur", event, { item: this.active } );
961    },
962
963    _startOpening: function( submenu ) {
964        clearTimeout( this.timer );
965
966        // Don't open if already open fixes a Firefox bug that caused a .5 pixel
967        // shift in the submenu position when mousing over the carat icon
968        if ( submenu.attr( "aria-hidden" ) !== "true" ) {
969            return;
970        }
971
972        this.timer = this._delay(function() {
973            this._close();
974            this._open( submenu );
975        }, this.delay );
976    },
977
978    _open: function( submenu ) {
979        var position = $.extend({
980            of: this.active
981        }, this.options.position );
982
983        clearTimeout( this.timer );
984        this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
985            .hide()
986            .attr( "aria-hidden", "true" );
987
988        submenu
989            .show()
990            .removeAttr( "aria-hidden" )
991            .attr( "aria-expanded", "true" )
992            .position( position );
993    },
994
995    collapseAll: function( event, all ) {
996        clearTimeout( this.timer );
997        this.timer = this._delay(function() {
998            // If we were passed an event, look for the submenu that contains the event
999            var currentMenu = all ? this.element :
1000                $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
1001
1002            // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
1003            if ( !currentMenu.length ) {
1004                currentMenu = this.element;
1005            }
1006
1007            this._close( currentMenu );
1008
1009            this.blur( event );
1010            this.activeMenu = currentMenu;
1011        }, this.delay );
1012    },
1013
1014    // With no arguments, closes the currently active menu - if nothing is active
1015    // it closes all menus.  If passed an argument, it will search for menus BELOW
1016    _close: function( startMenu ) {
1017        if ( !startMenu ) {
1018            startMenu = this.active ? this.active.parent() : this.element;
1019        }
1020
1021        startMenu
1022            .find( ".ui-menu" )
1023            .hide()
1024            .attr( "aria-hidden", "true" )
1025            .attr( "aria-expanded", "false" )
1026            .end()
1027            .find( ".ui-state-active" ).not( ".ui-state-focus" )
1028            .removeClass( "ui-state-active" );
1029    },
1030
1031    _closeOnDocumentClick: function( event ) {
1032        return !$( event.target ).closest( ".ui-menu" ).length;
1033    },
1034
1035    _isDivider: function( item ) {
1036
1037        // Match hyphen, em dash, en dash
1038        return !/[^\-\u2014\u2013\s]/.test( item.text() );
1039    },
1040
1041    collapse: function( event ) {
1042        var newItem = this.active &&
1043            this.active.parent().closest( ".ui-menu-item", this.element );
1044        if ( newItem && newItem.length ) {
1045            this._close();
1046            this.focus( event, newItem );
1047        }
1048    },
1049
1050    expand: function( event ) {
1051        var newItem = this.active &&
1052            this.active
1053                .children( ".ui-menu " )
1054                .find( this.options.items )
1055                .first();
1056
1057        if ( newItem && newItem.length ) {
1058            this._open( newItem.parent() );
1059
1060            // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
1061            this._delay(function() {
1062                this.focus( event, newItem );
1063            });
1064        }
1065    },
1066
1067    next: function( event ) {
1068        this._move( "next", "first", event );
1069    },
1070
1071    previous: function( event ) {
1072        this._move( "prev", "last", event );
1073    },
1074
1075    isFirstItem: function() {
1076        return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
1077    },
1078
1079    isLastItem: function() {
1080        return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
1081    },
1082
1083    _move: function( direction, filter, event ) {
1084        var next;
1085        if ( this.active ) {
1086            if ( direction === "first" || direction === "last" ) {
1087                next = this.active
1088                    [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
1089                    .eq( -1 );
1090            } else {
1091                next = this.active
1092                    [ direction + "All" ]( ".ui-menu-item" )
1093                    .eq( 0 );
1094            }
1095        }
1096        if ( !next || !next.length || !this.active ) {
1097            next = this.activeMenu.find( this.options.items )[ filter ]();
1098        }
1099
1100        this.focus( event, next );
1101    },
1102
1103    nextPage: function( event ) {
1104        var item, base, height;
1105
1106        if ( !this.active ) {
1107            this.next( event );
1108            return;
1109        }
1110        if ( this.isLastItem() ) {
1111            return;
1112        }
1113        if ( this._hasScroll() ) {
1114            base = this.active.offset().top;
1115            height = this.element.height();
1116            this.active.nextAll( ".ui-menu-item" ).each(function() {
1117                item = $( this );
1118                return item.offset().top - base - height < 0;
1119            });
1120
1121            this.focus( event, item );
1122        } else {
1123            this.focus( event, this.activeMenu.find( this.options.items )
1124                [ !this.active ? "first" : "last" ]() );
1125        }
1126    },
1127
1128    previousPage: function( event ) {
1129        var item, base, height;
1130        if ( !this.active ) {
1131            this.next( event );
1132            return;
1133        }
1134        if ( this.isFirstItem() ) {
1135            return;
1136        }
1137        if ( this._hasScroll() ) {
1138            base = this.active.offset().top;
1139            height = this.element.height();
1140            this.active.prevAll( ".ui-menu-item" ).each(function() {
1141                item = $( this );
1142                return item.offset().top - base + height > 0;
1143            });
1144
1145            this.focus( event, item );
1146        } else {
1147            this.focus( event, this.activeMenu.find( this.options.items ).first() );
1148        }
1149    },
1150
1151    _hasScroll: function() {
1152        return this.element.outerHeight() < this.element.prop( "scrollHeight" );
1153    },
1154
1155    select: function( event ) {
1156        // TODO: It should never be possible to not have an active item at this
1157        // point, but the tests don't trigger mouseenter before click.
1158        this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
1159        var ui = { item: this.active };
1160        if ( !this.active.has( ".ui-menu" ).length ) {
1161            this.collapseAll( event, true );
1162        }
1163        this._trigger( "select", event, ui );
1164    },
1165
vendor: 5,729 bytes, lines 1166-1318
1166    _filterMenuItems: function(character) {
1167        var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
1168            regex = new RegExp( "^" + escapedCharacter, "i" );
1169
1170        return this.activeMenu
1171            .find( this.options.items )
1172
1173            // Only match on items, not dividers or other content (#10571)
1174            .filter( ".ui-menu-item" )
1175            .filter(function() {
1176                return regex.test( $.trim( $( this ).text() ) );
1177            });
1178    }
1179});
1180
1181
1182
1183/*!
1184 * jQuery UI Autocomplete 1.11.3
1185 * http://jqueryui.com
1186 *
1187 * Copyright jQuery Foundation and other contributors
1188 * Released under the MIT license.
1189 * http://jquery.org/license
1190 *
1191 * http://api.jqueryui.com/autocomplete/
1192 */
1193
1194
1195$.widget( "ui.autocomplete", {
1196    version: "1.11.3",
1197    defaultElement: "<input>",
1198    options: {
1199        appendTo: null,
1200        autoFocus: false,
1201        delay: 300,
1202        minLength: 1,
1203        position: {
1204            my: "left top",
1205            at: "left bottom",
1206            collision: "none"
1207        },
1208        source: null,
1209
1210        // callbacks
1211        change: null,
1212        close: null,
1213        focus: null,
1214        open: null,
1215        response: null,
1216        search: null,
1217        select: null
1218    },
1219
1220    requestIndex: 0,
1221    pending: 0,
1222
1223    _create: function() {
1224        // Some browsers only repeat keydown events, not keypress events,
1225        // so we use the suppressKeyPress flag to determine if we've already
1226        // handled the keydown event. #7269
1227        // Unfortunately the code for & in keypress is the same as the up arrow,
1228        // so we use the suppressKeyPressRepeat flag to avoid handling keypress
1229        // events when we know the keydown event was used to modify the
1230        // search term. #7799
1231        var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
1232            nodeName = this.element[ 0 ].nodeName.toLowerCase(),
1233            isTextarea = nodeName === "textarea",
1234            isInput = nodeName === "input";
1235
1236        this.isMultiLine =
1237            // Textareas are always multi-line
1238            isTextarea ? true :
1239                // Inputs are always single-line, even if inside a contentEditable element
1240                // IE also treats inputs as contentEditable
1241                isInput ? false :
1242                    // All other element types are determined by whether or not they're contentEditable
1243                    this.element.prop( "isContentEditable" );
1244
1245        this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
1246        this.isNewMenu = true;
1247
1248        this.element
1249            .addClass( "ui-autocomplete-input" )
1250            .attr( "autocomplete", "off" );
1251
1252        this._on( this.element, {
1253            keydown: function( event ) {
1254                if ( this.element.prop( "readOnly" ) ) {
1255                    suppressKeyPress = true;
1256                    suppressInput = true;
1257                    suppressKeyPressRepeat = true;
1258                    return;
1259                }
1260
1261                suppressKeyPress = false;
1262                suppressInput = false;
1263                suppressKeyPressRepeat = false;
1264                var keyCode = $.ui.keyCode;
1265                switch ( event.keyCode ) {
1266                    case keyCode.PAGE_UP:
1267                        suppressKeyPress = true;
1268                        this._move( "previousPage", event );
1269                        break;
1270                    case keyCode.PAGE_DOWN:
1271                        suppressKeyPress = true;
1272                        this._move( "nextPage", event );
1273                        break;
1274                    case keyCode.UP:
1275                        suppressKeyPress = true;
1276                        this._keyEvent( "previous", event );
1277                        break;
1278                    case keyCode.DOWN:
1279                        suppressKeyPress = true;
1280                        this._keyEvent( "next", event );
1281                        break;
1282                    case keyCode.ENTER:
1283                        // when menu is open and has focus
1284                        if ( this.menu.active ) {
1285                            // #6055 - Opera still allows the keypress to occur
1286                            // which causes forms to submit
1287                            suppressKeyPress = true;
1288                            event.preventDefault();
1289                            this.menu.select( event );
1290                        }
1291                        break;
1292                    case keyCode.TAB:
1293                        if ( this.menu.active ) {
1294                            this.menu.select( event );
1295                        }
1296                        break;
1297                    case keyCode.ESCAPE:
1298                        if ( this.menu.element.is( ":visible" ) ) {
1299                            if ( !this.isMultiLine ) {
1300                                this._value( this.term );
1301                            }
1302                            this.close( event );
1303                            // Different browsers have different default behavior for escape
1304                            // Single press can mean undo or clear
1305                            // Double press in IE means clear the whole form
1306                            event.preventDefault();
1307                        }
1308                        break;
1309                    default:
1310                        suppressKeyPressRepeat = true;
1311                        // search timeout should be triggered before the input value is changed
1312                        this._searchTimeout( event );
1313                        break;
1314                }
1315            },
1316            keypress: function( event ) {
1317                if ( suppressKeyPress ) {
1318                    suppressKeyPress = false;
vendor: 16,146 bytes, lines 1319-1793
1319                    if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
1320                        event.preventDefault();
1321                    }
1322                    return;
1323                }
1324                if ( suppressKeyPressRepeat ) {
1325                    return;
1326                }
1327
1328                // replicate some key handlers to allow them to repeat in Firefox and Opera
1329                var keyCode = $.ui.keyCode;
1330                switch ( event.keyCode ) {
1331                    case keyCode.PAGE_UP:
1332                        this._move( "previousPage", event );
1333                        break;
1334                    case keyCode.PAGE_DOWN:
1335                        this._move( "nextPage", event );
1336                        break;
1337                    case keyCode.UP:
1338                        this._keyEvent( "previous", event );
1339                        break;
1340                    case keyCode.DOWN:
1341                        this._keyEvent( "next", event );
1342                        break;
1343                }
1344            },
1345            input: function( event ) {
1346                if ( suppressInput ) {
1347                    suppressInput = false;
1348                    event.preventDefault();
1349                    return;
1350                }
1351                this._searchTimeout( event );
1352            },
1353            focus: function() {
1354                this.selectedItem = null;
1355                this.previous = this._value();
1356            },
1357            blur: function( event ) {
1358                if ( this.cancelBlur ) {
1359                    delete this.cancelBlur;
1360                    return;
1361                }
1362
1363                clearTimeout( this.searching );
1364                this.close( event );
1365                this._change( event );
1366            }
1367        });
1368
1369        this._initSource();
1370        this.menu = $( "<ul>" )
1371            .addClass( "ui-autocomplete ui-front" )
1372            .appendTo( this._appendTo() )
1373            .menu({
1374                // disable ARIA support, the live region takes care of that
1375                role: null
1376            })
1377            .hide()
1378            .menu( "instance" );
1379
1380        this._on( this.menu.element, {
1381            mousedown: function( event ) {
1382                // prevent moving focus out of the text field
1383                event.preventDefault();
1384
1385                // IE doesn't prevent moving focus even with event.preventDefault()
1386                // so we set a flag to know when we should ignore the blur event
1387                this.cancelBlur = true;
1388                this._delay(function() {
1389                    delete this.cancelBlur;
1390                });
1391
1392                // clicking on the scrollbar causes focus to shift to the body
1393                // but we can't detect a mouseup or a click immediately afterward
1394                // so we have to track the next mousedown and close the menu if
1395                // the user clicks somewhere outside of the autocomplete
1396                var menuElement = this.menu.element[ 0 ];
1397                if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
1398                    this._delay(function() {
1399                        var that = this;
1400                        this.document.one( "mousedown", function( event ) {
1401                            if ( event.target !== that.element[ 0 ] &&
1402                                event.target !== menuElement &&
1403                                !$.contains( menuElement, event.target ) ) {
1404                                that.close();
1405                            }
1406                        });
1407                    });
1408                }
1409            },
1410            menufocus: function( event, ui ) {
1411                var label, item;
1412                // support: Firefox
1413                // Prevent accidental activation of menu items in Firefox (#7024 #9118)
1414                if ( this.isNewMenu ) {
1415                    this.isNewMenu = false;
1416                    if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
1417                        this.menu.blur();
1418
1419                        this.document.one( "mousemove", function() {
1420                            $( event.target ).trigger( event.originalEvent );
1421                        });
1422
1423                        return;
1424                    }
1425                }
1426
1427                item = ui.item.data( "ui-autocomplete-item" );
1428                if ( false !== this._trigger( "focus", event, { item: item } ) ) {
1429                    // use value to match what will end up in the input, if it was a key event
1430                    if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
1431                        this._value( item.value );
1432                    }
1433                }
1434
1435                // Announce the value in the liveRegion
1436                label = ui.item.attr( "aria-label" ) || item.value;
1437                if ( label && $.trim( label ).length ) {
1438                    this.liveRegion.children().hide();
1439                    $( "<div>" ).text( label ).appendTo( this.liveRegion );
1440                }
1441            },
1442            menuselect: function( event, ui ) {
1443                var item = ui.item.data( "ui-autocomplete-item" ),
1444                    previous = this.previous;
1445
1446                // only trigger when focus was lost (click on menu)
1447                if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
1448                    this.element.focus();
1449                    this.previous = previous;
1450                    // #6109 - IE triggers two focus events and the second
1451                    // is asynchronous, so we need to reset the previous
1452                    // term synchronously and asynchronously :-(
1453                    this._delay(function() {
1454                        this.previous = previous;
1455                        this.selectedItem = item;
1456                    });
1457                }
1458
1459                if ( false !== this._trigger( "select", event, { item: item } ) ) {
1460                    this._value( item.value );
1461                }
1462                // reset the term after the select event
1463                // this allows custom select handling to work properly
1464                this.term = this._value();
1465
1466                this.close( event );
1467                this.selectedItem = item;
1468            }
1469        });
1470
1471        this.liveRegion = $( "<span>", {
1472            role: "status",
1473            "aria-live": "assertive",
1474            "aria-relevant": "additions"
1475        })
1476            .addClass( "ui-helper-hidden-accessible" )
1477            .appendTo( this.document[ 0 ].body );
1478
1479        // turning off autocomplete prevents the browser from remembering the
1480        // value when navigating through history, so we re-enable autocomplete
1481        // if the page is unloaded before the widget is destroyed. #7790
1482        this._on( this.window, {
1483            beforeunload: function() {
1484                this.element.removeAttr( "autocomplete" );
1485            }
1486        });
1487    },
1488
1489    _destroy: function() {
1490        clearTimeout( this.searching );
1491        this.element
1492            .removeClass( "ui-autocomplete-input" )
1493            .removeAttr( "autocomplete" );
1494        this.menu.element.remove();
1495        this.liveRegion.remove();
1496    },
1497
1498    _setOption: function( key, value ) {
1499        this._super( key, value );
1500        if ( key === "source" ) {
1501            this._initSource();
1502        }
1503        if ( key === "appendTo" ) {
1504            this.menu.element.appendTo( this._appendTo() );
1505        }
1506        if ( key === "disabled" && value && this.xhr ) {
1507            this.xhr.abort();
1508        }
1509    },
1510
1511    _appendTo: function() {
1512        var element = this.options.appendTo;
1513
1514        if ( element ) {
1515            element = element.jquery || element.nodeType ?
1516                $( element ) :
1517                this.document.find( element ).eq( 0 );
1518        }
1519
1520        if ( !element || !element[ 0 ] ) {
1521            element = this.element.closest( ".ui-front" );
1522        }
1523
1524        if ( !element.length ) {
1525            element = this.document[ 0 ].body;
1526        }
1527
1528        return element;
1529    },
1530
1531    _initSource: function() {
1532        var array, url,
1533            that = this;
1534        if ( $.isArray( this.options.source ) ) {
1535            array = this.options.source;
1536            this.source = function( request, response ) {
1537                response( $.ui.autocomplete.filter( array, request.term ) );
1538            };
1539        } else if ( typeof this.options.source === "string" ) {
1540            url = this.options.source;
1541            this.source = function( request, response ) {
1542                if ( that.xhr ) {
1543                    that.xhr.abort();
1544                }
1545                that.xhr = $.ajax({
1546                    url: url,
1547                    data: request,
1548                    dataType: "json",
1549                    success: function( data ) {
1550                        response( data );
1551                    },
1552                    error: function() {
1553                        response([]);
1554                    }
1555                });
1556            };
1557        } else {
1558            this.source = this.options.source;
1559        }
1560    },
1561
1562    _searchTimeout: function( event ) {
1563        clearTimeout( this.searching );
1564        this.searching = this._delay(function() {
1565
1566            // Search if the value has changed, or if the user retypes the same value (see #7434)
1567            var equalValues = this.term === this._value(),
1568                menuVisible = this.menu.element.is( ":visible" ),
1569                modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
1570
1571            if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
1572                this.selectedItem = null;
1573                this.search( null, event );
1574            }
1575        }, this.options.delay );
1576    },
1577
1578    search: function( value, event ) {
1579        value = value != null ? value : this._value();
1580
1581        // always save the actual value, not the one passed as an argument
1582        this.term = this._value();
1583
1584        if ( value.length < this.options.minLength ) {
1585            return this.close( event );
1586        }
1587
1588        if ( this._trigger( "search", event ) === false ) {
1589            return;
1590        }
1591
1592        return this._search( value );
1593    },
1594
1595    _search: function( value ) {
1596        this.pending++;
1597        this.element.addClass( "ui-autocomplete-loading" );
1598        this.cancelSearch = false;
1599
1600        this.source( { term: value }, this._response() );
1601    },
1602
1603    _response: function() {
1604        var index = ++this.requestIndex;
1605
1606        return $.proxy(function( content ) {
1607            if ( index === this.requestIndex ) {
1608                this.__response( content );
1609            }
1610
1611            this.pending--;
1612            if ( !this.pending ) {
1613                this.element.removeClass( "ui-autocomplete-loading" );
1614            }
1615        }, this );
1616    },
1617
1618    __response: function( content ) {
1619        if ( content ) {
1620            content = this._normalize( content );
1621        }
1622        this._trigger( "response", null, { content: content } );
1623        if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
1624            this._suggest( content );
1625            this._trigger( "open" );
1626        } else {
1627            // use ._close() instead of .close() so we don't cancel future searches
1628            this._close();
1629        }
1630    },
1631
1632    close: function( event ) {
1633        this.cancelSearch = true;
1634        this._close( event );
1635    },
1636
1637    _close: function( event ) {
1638        if ( this.menu.element.is( ":visible" ) ) {
1639            this.menu.element.hide();
1640            this.menu.blur();
1641            this.isNewMenu = true;
1642            this._trigger( "close", event );
1643        }
1644    },
1645
1646    _change: function( event ) {
1647        if ( this.previous !== this._value() ) {
1648            this._trigger( "change", event, { item: this.selectedItem } );
1649        }
1650    },
1651
1652    _normalize: function( items ) {
1653        // assume all items have the right format when the first item is complete
1654        if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
1655            return items;
1656        }
1657        return $.map( items, function( item ) {
1658            if ( typeof item === "string" ) {
1659                return {
1660                    label: item,
1661                    value: item
1662                };
1663            }
1664            return $.extend( {}, item, {
1665                label: item.label || item.value,
1666                value: item.value || item.label
1667            });
1668        });
1669    },
1670
1671    _suggest: function( items ) {
1672        var ul = this.menu.element.empty();
1673        this._renderMenu( ul, items );
1674        this.isNewMenu = true;
1675        this.menu.refresh();
1676
1677        // size and position menu
1678        ul.show();
1679        this._resizeMenu();
1680        ul.position( $.extend({
1681            of: this.element
1682        }, this.options.position ) );
1683
1684        if ( this.options.autoFocus ) {
1685            this.menu.next();
1686        }
1687    },
1688
1689    _resizeMenu: function() {
1690        var ul = this.menu.element;
1691        ul.outerWidth( Math.max(
1692            // Firefox wraps long text (possibly a rounding bug)
1693            // so we add 1px to avoid the wrapping (#7513)
1694                ul.width( "" ).outerWidth() + 1,
1695            this.element.outerWidth()
1696        ) );
1697    },
1698
1699    _renderMenu: function( ul, items ) {
1700        var that = this;
1701        $.each( items, function( index, item ) {
1702            that._renderItemData( ul, item );
1703        });
1704    },
1705
1706    _renderItemData: function( ul, item ) {
1707        return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
1708    },
1709
1710    _renderItem: function( ul, item ) {
1711        return $( "<li>" ).text( item.label ).appendTo( ul );
1712    },
1713
1714    _move: function( direction, event ) {
1715        if ( !this.menu.element.is( ":visible" ) ) {
1716            this.search( null, event );
1717            return;
1718        }
1719        if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
1720            this.menu.isLastItem() && /^next/.test( direction ) ) {
1721
1722            if ( !this.isMultiLine ) {
1723                this._value( this.term );
1724            }
1725
1726            this.menu.blur();
1727            return;
1728        }
1729        this.menu[ direction ]( event );
1730    },
1731
1732    widget: function() {
1733        return this.menu.element;
1734    },
1735
1736    _value: function() {
1737        return this.valueMethod.apply( this.element, arguments );
1738    },
1739
1740    _keyEvent: function( keyEvent, event ) {
1741        if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
1742            this._move( keyEvent, event );
1743
1744            // prevents moving cursor to beginning/end of the text field in some browsers
1745            event.preventDefault();
1746        }
1747    }
1748});
1749
1750$.extend( $.ui.autocomplete, {
1751    escapeRegex: function( value ) {
1752        return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
1753    },
1754    filter: function( array, term ) {
1755        var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
1756        return $.grep( array, function( value ) {
1757            return matcher.test( value.label || value.value || value );
1758        });
1759    }
1760});
1761
1762// live region extension, adding a `messages` option
1763// NOTE: This is an experimental API. We are still investigating
1764// a full solution for string manipulation and internationalization.
1765$.widget( "ui.autocomplete", $.ui.autocomplete, {
1766    options: {
1767        messages: {
1768            noResults: "No search results.",
1769            results: function( amount ) {
1770                return amount + ( amount > 1 ? " results are" : " result is" ) +
1771                    " available, use up and down arrow keys to navigate.";
1772            }
1773        }
1774    },
1775
1776    __response: function( content ) {
1777        var message;
1778        this._superApply( arguments );
1779        if ( this.options.disabled || this.cancelSearch ) {
1780            return;
1781        }
1782        if ( content && content.length ) {
1783            message = this.options.messages.results( content.length );
1784        } else {
1785            message = this.options.messages.noResults;
1786        }
1787        this.liveRegion.children().hide();
1788        $( "<div>" ).text( message ).appendTo( this.liveRegion );
1789    }
1790});
1791
1792var autocomplete = $.ui.autocomplete;
1793

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.