PageSourceSearch

https://littlebirdelectronics.com.au/assets/stimulus-d59b3b7f.js

js littlebirdelectronics.com.au collected 2026-09-25 14:07:54 UTC 88,790 bytes, 2,567 lines download raw bytes

1//= link ./stimulus-autoloader.js
2//= link ./stimulus-importmap-autoloader.js
3//= link ./stimulus-loading.js
4
5/*
6Stimulus 3.2.2
vendor: 88,663 bytes, lines 6-2567
6
7Copyright © 2023 Basecamp, LLC
8 */
9class EventListener {
10    constructor(eventTarget, eventName, eventOptions) {
11        this.eventTarget = eventTarget;
12        this.eventName = eventName;
13        this.eventOptions = eventOptions;
14        this.unorderedBindings = new Set();
15    }
16    connect() {
17        this.eventTarget.addEventListener(this.eventName, this, this.eventOptions);
18    }
19    disconnect() {
20        this.eventTarget.removeEventListener(this.eventName, this, this.eventOptions);
21    }
22    bindingConnected(binding) {
23        this.unorderedBindings.add(binding);
24    }
25    bindingDisconnected(binding) {
26        this.unorderedBindings.delete(binding);
27    }
28    handleEvent(event) {
29        const extendedEvent = extendEvent(event);
30        for (const binding of this.bindings) {
31            if (extendedEvent.immediatePropagationStopped) {
32                break;
33            }
34            else {
35                binding.handleEvent(extendedEvent);
36            }
37        }
38    }
39    hasBindings() {
40        return this.unorderedBindings.size > 0;
41    }
42    get bindings() {
43        return Array.from(this.unorderedBindings).sort((left, right) => {
44            const leftIndex = left.index, rightIndex = right.index;
45            return leftIndex < rightIndex ? -1 : leftIndex > rightIndex ? 1 : 0;
46        });
47    }
48}
49function extendEvent(event) {
50    if ("immediatePropagationStopped" in event) {
51        return event;
52    }
53    else {
54        const { stopImmediatePropagation } = event;
55        return Object.assign(event, {
56            immediatePropagationStopped: false,
57            stopImmediatePropagation() {
58                this.immediatePropagationStopped = true;
59                stopImmediatePropagation.call(this);
60            },
61        });
62    }
63}
64
65class Dispatcher {
66    constructor(application) {
67        this.application = application;
68        this.eventListenerMaps = new Map();
69        this.started = false;
70    }
71    start() {
72        if (!this.started) {
73            this.started = true;
74            this.eventListeners.forEach((eventListener) => eventListener.connect());
75        }
76    }
77    stop() {
78        if (this.started) {
79            this.started = false;
80            this.eventListeners.forEach((eventListener) => eventListener.disconnect());
81        }
82    }
83    get eventListeners() {
84        return Array.from(this.eventListenerMaps.values()).reduce((listeners, map) => listeners.concat(Array.from(map.values())), []);
85    }
86    bindingConnected(binding) {
87        this.fetchEventListenerForBinding(binding).bindingConnected(binding);
88    }
89    bindingDisconnected(binding, clearEventListeners = false) {
90        this.fetchEventListenerForBinding(binding).bindingDisconnected(binding);
91        if (clearEventListeners)
92            this.clearEventListenersForBinding(binding);
93    }
94    handleError(error, message, detail = {}) {
95        this.application.handleError(error, `Error ${message}`, detail);
96    }
97    clearEventListenersForBinding(binding) {
98        const eventListener = this.fetchEventListenerForBinding(binding);
99        if (!eventListener.hasBindings()) {
100            eventListener.disconnect();
101            this.removeMappedEventListenerFor(binding);
102        }
103    }
104    removeMappedEventListenerFor(binding) {
105        const { eventTarget, eventName, eventOptions } = binding;
106        const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget);
107        const cacheKey = this.cacheKey(eventName, eventOptions);
108        eventListenerMap.delete(cacheKey);
109        if (eventListenerMap.size == 0)
110            this.eventListenerMaps.delete(eventTarget);
111    }
112    fetchEventListenerForBinding(binding) {
113        const { eventTarget, eventName, eventOptions } = binding;
114        return this.fetchEventListener(eventTarget, eventName, eventOptions);
115    }
116    fetchEventListener(eventTarget, eventName, eventOptions) {
117        const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget);
118        const cacheKey = this.cacheKey(eventName, eventOptions);
119        let eventListener = eventListenerMap.get(cacheKey);
120        if (!eventListener) {
121            eventListener = this.createEventListener(eventTarget, eventName, eventOptions);
122            eventListenerMap.set(cacheKey, eventListener);
123        }
124        return eventListener;
125    }
126    createEventListener(eventTarget, eventName, eventOptions) {
127        const eventListener = new EventListener(eventTarget, eventName, eventOptions);
128        if (this.started) {
129            eventListener.connect();
130        }
131        return eventListener;
132    }
133    fetchEventListenerMapForEventTarget(eventTarget) {
134        let eventListenerMap = this.eventListenerMaps.get(eventTarget);
135        if (!eventListenerMap) {
136            eventListenerMap = new Map();
137            this.eventListenerMaps.set(eventTarget, eventListenerMap);
138        }
139        return eventListenerMap;
140    }
141    cacheKey(eventName, eventOptions) {
142        const parts = [eventName];
143        Object.keys(eventOptions)
144            .sort()
145            .forEach((key) => {
146            parts.push(`${eventOptions[key] ? "" : "!"}${key}`);
147        });
148        return parts.join(":");
149    }
150}
151
152const defaultActionDescriptorFilters = {
153    stop({ event, value }) {
154        if (value)
155            event.stopPropagation();
156        return true;
157    },
158    prevent({ event, value }) {
159        if (value)
160            event.preventDefault();
161        return true;
162    },
163    self({ event, value, element }) {
164        if (value) {
165            return element === event.target;
166        }
167        else {
168            return true;
169        }
170    },
171};
172const descriptorPattern = /^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;
173function parseActionDescriptorString(descriptorString) {
174    const source = descriptorString.trim();
175    const matches = source.match(descriptorPattern) || [];
176    let eventName = matches[2];
177    let keyFilter = matches[3];
178    if (keyFilter && !["keydown", "keyup", "keypress"].includes(eventName)) {
179        eventName += `.${keyFilter}`;
180        keyFilter = "";
181    }
182    return {
183        eventTarget: parseEventTarget(matches[4]),
184        eventName,
185        eventOptions: matches[7] ? parseEventOptions(matches[7]) : {},
186        identifier: matches[5],
187        methodName: matches[6],
188        keyFilter: matches[1] || keyFilter,
189    };
190}
191function parseEventTarget(eventTargetName) {
192    if (eventTargetName == "window") {
193        return window;
194    }
195    else if (eventTargetName == "document") {
196        return document;
197    }
198}
199function parseEventOptions(eventOptions) {
200    return eventOptions
201        .split(":")
202        .reduce((options, token) => Object.assign(options, { [token.replace(/^!/, "")]: !/^!/.test(token) }), {});
203}
204function stringifyEventTarget(eventTarget) {
205    if (eventTarget == window) {
206        return "window";
207    }
208    else if (eventTarget == document) {
209        return "document";
210    }
211}
212
213function camelize(value) {
214    return value.replace(/(?:[_-])([a-z0-9])/g, (_, char) => char.toUpperCase());
215}
216function namespaceCamelize(value) {
217    return camelize(value.replace(/--/g, "-").replace(/__/g, "_"));
218}
219function capitalize(value) {
220    return value.charAt(0).toUpperCase() + value.slice(1);
221}
222function dasherize(value) {
223    return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`);
224}
225function tokenize(value) {
226    return value.match(/[^\s]+/g) || [];
227}
228
229function isSomething(object) {
230    return object !== null && object !== undefined;
231}
232function hasProperty(object, property) {
233    return Object.prototype.hasOwnProperty.call(object, property);
234}
235
236const allModifiers = ["meta", "ctrl", "alt", "shift"];
237class Action {
238    constructor(element, index, descriptor, schema) {
239        this.element = element;
240        this.index = index;
241        this.eventTarget = descriptor.eventTarget || element;
242        this.eventName = descriptor.eventName || getDefaultEventNameForElement(element) || error("missing event name");
243        this.eventOptions = descriptor.eventOptions || {};
244        this.identifier = descriptor.identifier || error("missing identifier");
245        this.methodName = descriptor.methodName || error("missing method name");
246        this.keyFilter = descriptor.keyFilter || "";
247        this.schema = schema;
248    }
249    static forToken(token, schema) {
250        return new this(token.element, token.index, parseActionDescriptorString(token.content), schema);
251    }
252    toString() {
253        const eventFilter = this.keyFilter ? `.${this.keyFilter}` : "";
254        const eventTarget = this.eventTargetName ? `@${this.eventTargetName}` : "";
255        return `${this.eventName}${eventFilter}${eventTarget}->${this.identifier}#${this.methodName}`;
256    }
257    shouldIgnoreKeyboardEvent(event) {
258        if (!this.keyFilter) {
259            return false;
260        }
261        const filters = this.keyFilter.split("+");
262        if (this.keyFilterDissatisfied(event, filters)) {
263            return true;
264        }
265        const standardFilter = filters.filter((key) => !allModifiers.includes(key))[0];
266        if (!standardFilter) {
267            return false;
268        }
269        if (!hasProperty(this.keyMappings, standardFilter)) {
270            error(`contains unknown key filter: ${this.keyFilter}`);
271        }
272        return this.keyMappings[standardFilter].toLowerCase() !== event.key.toLowerCase();
273    }
274    shouldIgnoreMouseEvent(event) {
275        if (!this.keyFilter) {
276            return false;
277        }
278        const filters = [this.keyFilter];
279        if (this.keyFilterDissatisfied(event, filters)) {
280            return true;
281        }
282        return false;
283    }
284    get params() {
285        const params = {};
286        const pattern = new RegExp(`^data-${this.identifier}-(.+)-param$`, "i");
287        for (const { name, value } of Array.from(this.element.attributes)) {
288            const match = name.match(pattern);
289            const key = match && match[1];
290            if (key) {
291                params[camelize(key)] = typecast(value);
292            }
293        }
294        return params;
295    }
296    get eventTargetName() {
297        return stringifyEventTarget(this.eventTarget);
298    }
299    get keyMappings() {
300        return this.schema.keyMappings;
301    }
302    keyFilterDissatisfied(event, filters) {
303        const [meta, ctrl, alt, shift] = allModifiers.map((modifier) => filters.includes(modifier));
304        return event.metaKey !== meta || event.ctrlKey !== ctrl || event.altKey !== alt || event.shiftKey !== shift;
305    }
306}
307const defaultEventNames = {
308    a: () => "click",
309    button: () => "click",
310    form: () => "submit",
311    details: () => "toggle",
312    input: (e) => (e.getAttribute("type") == "submit" ? "click" : "input"),
313    select: () => "change",
314    textarea: () => "input",
315};
316function getDefaultEventNameForElement(element) {
317    const tagName = element.tagName.toLowerCase();
318    if (tagName in defaultEventNames) {
319        return defaultEventNames[tagName](element);
320    }
321}
322function error(message) {
323    throw new Error(message);
324}
325function typecast(value) {
326    try {
327        return JSON.parse(value);
328    }
329    catch (o_O) {
330        return value;
331    }
332}
333
334class Binding {
335    constructor(context, action) {
336        this.context = context;
337        this.action = action;
338    }
339    get index() {
340        return this.action.index;
341    }
342    get eventTarget() {
343        return this.action.eventTarget;
344    }
345    get eventOptions() {
346        return this.action.eventOptions;
347    }
348    get identifier() {
349        return this.context.identifier;
350    }
351    handleEvent(event) {
352        const actionEvent = this.prepareActionEvent(event);
353        if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(actionEvent)) {
354            this.invokeWithEvent(actionEvent);
355        }
356    }
357    get eventName() {
358        return this.action.eventName;
359    }
360    get method() {
361        const method = this.controller[this.methodName];
362        if (typeof method == "function") {
363            return method;
364        }
365        throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`);
366    }
367    applyEventModifiers(event) {
368        const { element } = this.action;
369        const { actionDescriptorFilters } = this.context.application;
370        const { controller } = this.context;
371        let passes = true;
372        for (const [name, value] of Object.entries(this.eventOptions)) {
373            if (name in actionDescriptorFilters) {
374                const filter = actionDescriptorFilters[name];
375                passes = passes && filter({ name, value, event, element, controller });
376            }
377            else {
378                continue;
379            }
380        }
381        return passes;
382    }
383    prepareActionEvent(event) {
384        return Object.assign(event, { params: this.action.params });
385    }
386    invokeWithEvent(event) {
387        const { target, currentTarget } = event;
388        try {
389            this.method.call(this.controller, event);
390            this.context.logDebugActivity(this.methodName, { event, target, currentTarget, action: this.methodName });
391        }
392        catch (error) {
393            const { identifier, controller, element, index } = this;
394            const detail = { identifier, controller, element, index, event };
395            this.context.handleError(error, `invoking action "${this.action}"`, detail);
396        }
397    }
398    willBeInvokedByEvent(event) {
399        const eventTarget = event.target;
400        if (event instanceof KeyboardEvent && this.action.shouldIgnoreKeyboardEvent(event)) {
401            return false;
402        }
403        if (event instanceof MouseEvent && this.action.shouldIgnoreMouseEvent(event)) {
404            return false;
405        }
406        if (this.element === eventTarget) {
407            return true;
408        }
409        else if (eventTarget instanceof Element && this.element.contains(eventTarget)) {
410            return this.scope.containsElement(eventTarget);
411        }
412        else {
413            return this.scope.containsElement(this.action.element);
414        }
415    }
416    get controller() {
417        return this.context.controller;
418    }
419    get methodName() {
420        return this.action.methodName;
421    }
422    get element() {
423        return this.scope.element;
424    }
425    get scope() {
426        return this.context.scope;
427    }
428}
429
430class ElementObserver {
431    constructor(element, delegate) {
432        this.mutationObserverInit = { attributes: true, childList: true, subtree: true };
433        this.element = element;
434        this.started = false;
435        this.delegate = delegate;
436        this.elements = new Set();
437        this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations));
438    }
439    start() {
440        if (!this.started) {
441            this.started = true;
442            this.mutationObserver.observe(this.element, this.mutationObserverInit);
443            this.refresh();
444        }
445    }
446    pause(callback) {
447        if (this.started) {
448            this.mutationObserver.disconnect();
449            this.started = false;
450        }
451        callback();
452        if (!this.started) {
453            this.mutationObserver.observe(this.element, this.mutationObserverInit);
454            this.started = true;
455        }
456    }
457    stop() {
458        if (this.started) {
459            this.mutationObserver.takeRecords();
460            this.mutationObserver.disconnect();
461            this.started = false;
462        }
463    }
464    refresh() {
465        if (this.started) {
466            const matches = new Set(this.matchElementsInTree());
467            for (const element of Array.from(this.elements)) {
468                if (!matches.has(element)) {
469                    this.removeElement(element);
470                }
471            }
472            for (const element of Array.from(matches)) {
473                this.addElement(element);
474            }
475        }
476    }
477    processMutations(mutations) {
478        if (this.started) {
479            for (const mutation of mutations) {
480                this.processMutation(mutation);
481            }
482        }
483    }
484    processMutation(mutation) {
485        if (mutation.type == "attributes") {
486            this.processAttributeChange(mutation.target, mutation.attributeName);
487        }
488        else if (mutation.type == "childList") {
489            this.processRemovedNodes(mutation.removedNodes);
490            this.processAddedNodes(mutation.addedNodes);
491        }
492    }
493    processAttributeChange(element, attributeName) {
494        if (this.elements.has(element)) {
495            if (this.delegate.elementAttributeChanged && this.matchElement(element)) {
496                this.delegate.elementAttributeChanged(element, attributeName);
497            }
498            else {
499                this.removeElement(element);
500            }
501        }
502        else if (this.matchElement(element)) {
503            this.addElement(element);
504        }
505    }
506    processRemovedNodes(nodes) {
507        for (const node of Array.from(nodes)) {
508            const element = this.elementFromNode(node);
509            if (element) {
510                this.processTree(element, this.removeElement);
511            }
512        }
513    }
514    processAddedNodes(nodes) {
515        for (const node of Array.from(nodes)) {
516            const element = this.elementFromNode(node);
517            if (element && this.elementIsActive(element)) {
518                this.processTree(element, this.addElement);
519            }
520        }
521    }
522    matchElement(element) {
523        return this.delegate.matchElement(element);
524    }
525    matchElementsInTree(tree = this.element) {
526        return this.delegate.matchElementsInTree(tree);
527    }
528    processTree(tree, processor) {
529        for (const element of this.matchElementsInTree(tree)) {
530            processor.call(this, element);
531        }
532    }
533    elementFromNode(node) {
534        if (node.nodeType == Node.ELEMENT_NODE) {
535            return node;
536        }
537    }
538    elementIsActive(element) {
539        if (element.isConnected != this.element.isConnected) {
540            return false;
541        }
542        else {
543            return this.element.contains(element);
544        }
545    }
546    addElement(element) {
547        if (!this.elements.has(element)) {
548            if (this.elementIsActive(element)) {
549                this.elements.add(element);
550                if (this.delegate.elementMatched) {
551                    this.delegate.elementMatched(element);
552                }
553            }
554        }
555    }
556    removeElement(element) {
557        if (this.elements.has(element)) {
558            this.elements.delete(element);
559            if (this.delegate.elementUnmatched) {
560                this.delegate.elementUnmatched(element);
561            }
562        }
563    }
564}
565
566class AttributeObserver {
567    constructor(element, attributeName, delegate) {
568        this.attributeName = attributeName;
569        this.delegate = delegate;
570        this.elementObserver = new ElementObserver(element, this);
571    }
572    get element() {
573        return this.elementObserver.element;
574    }
575    get selector() {
576        return `[${this.attributeName}]`;
577    }
578    start() {
579        this.elementObserver.start();
580    }
581    pause(callback) {
582        this.elementObserver.pause(callback);
583    }
584    stop() {
585        this.elementObserver.stop();
586    }
587    refresh() {
588        this.elementObserver.refresh();
589    }
590    get started() {
591        return this.elementObserver.started;
592    }
593    matchElement(element) {
594        return element.hasAttribute(this.attributeName);
595    }
596    matchElementsInTree(tree) {
597        const match = this.matchElement(tree) ? [tree] : [];
598        const matches = Array.from(tree.querySelectorAll(this.selector));
599        return match.concat(matches);
600    }
601    elementMatched(element) {
602        if (this.delegate.elementMatchedAttribute) {
603            this.delegate.elementMatchedAttribute(element, this.attributeName);
604        }
605    }
606    elementUnmatched(element) {
607        if (this.delegate.elementUnmatchedAttribute) {
608            this.delegate.elementUnmatchedAttribute(element, this.attributeName);
609        }
610    }
611    elementAttributeChanged(element, attributeName) {
612        if (this.delegate.elementAttributeValueChanged && this.attributeName == attributeName) {
613            this.delegate.elementAttributeValueChanged(element, attributeName);
614        }
615    }
616}
617
618function add(map, key, value) {
619    fetch(map, key).add(value);
620}
621function del(map, key, value) {
622    fetch(map, key).delete(value);
623    prune(map, key);
624}
625function fetch(map, key) {
626    let values = map.get(key);
627    if (!values) {
628        values = new Set();
629        map.set(key, values);
630    }
631    return values;
632}
633function prune(map, key) {
634    const values = map.get(key);
635    if (values != null && values.size == 0) {
636        map.delete(key);
637    }
638}
639
640class Multimap {
641    constructor() {
642        this.valuesByKey = new Map();
643    }
644    get keys() {
645        return Array.from(this.valuesByKey.keys());
646    }
647    get values() {
648        const sets = Array.from(this.valuesByKey.values());
649        return sets.reduce((values, set) => values.concat(Array.from(set)), []);
650    }
651    get size() {
652        const sets = Array.from(this.valuesByKey.values());
653        return sets.reduce((size, set) => size + set.size, 0);
654    }
655    add(key, value) {
656        add(this.valuesByKey, key, value);
657    }
658    delete(key, value) {
659        del(this.valuesByKey, key, value);
660    }
661    has(key, value) {
662        const values = this.valuesByKey.get(key);
663        return values != null && values.has(value);
664    }
665    hasKey(key) {
666        return this.valuesByKey.has(key);
667    }
668    hasValue(value) {
669        const sets = Array.from(this.valuesByKey.values());
670        return sets.some((set) => set.has(value));
671    }
672    getValuesForKey(key) {
673        const values = this.valuesByKey.get(key);
674        return values ? Array.from(values) : [];
675    }
676    getKeysForValue(value) {
677        return Array.from(this.valuesByKey)
678            .filter(([_key, values]) => values.has(value))
679            .map(([key, _values]) => key);
680    }
681}
682
683class IndexedMultimap extends Multimap {
684    constructor() {
685        super();
686        this.keysByValue = new Map();
687    }
688    get values() {
689        return Array.from(this.keysByValue.keys());
690    }
691    add(key, value) {
692        super.add(key, value);
693        add(this.keysByValue, value, key);
694    }
695    delete(key, value) {
696        super.delete(key, value);
697        del(this.keysByValue, value, key);
698    }
699    hasValue(value) {
700        return this.keysByValue.has(value);
701    }
702    getKeysForValue(value) {
703        const set = this.keysByValue.get(value);
704        return set ? Array.from(set) : [];
705    }
706}
707
708class SelectorObserver {
709    constructor(element, selector, delegate, details) {
710        this._selector = selector;
711        this.details = details;
712        this.elementObserver = new ElementObserver(element, this);
713        this.delegate = delegate;
714        this.matchesByElement = new Multimap();
715    }
716    get started() {
717        return this.elementObserver.started;
718    }
719    get selector() {
720        return this._selector;
721    }
722    set selector(selector) {
723        this._selector = selector;
724        this.refresh();
725    }
726    start() {
727        this.elementObserver.start();
728    }
729    pause(callback) {
730        this.elementObserver.pause(callback);
731    }
732    stop() {
733        this.elementObserver.stop();
734    }
735    refresh() {
736        this.elementObserver.refresh();
737    }
738    get element() {
739        return this.elementObserver.element;
740    }
741    matchElement(element) {
742        const { selector } = this;
743        if (selector) {
744            const matches = element.matches(selector);
745            if (this.delegate.selectorMatchElement) {
746                return matches && this.delegate.selectorMatchElement(element, this.details);
747            }
748            return matches;
749        }
750        else {
751            return false;
752        }
753    }
754    matchElementsInTree(tree) {
755        const { selector } = this;
756        if (selector) {
757            const match = this.matchElement(tree) ? [tree] : [];
758            const matches = Array.from(tree.querySelectorAll(selector)).filter((match) => this.matchElement(match));
759            return match.concat(matches);
760        }
761        else {
762            return [];
763        }
764    }
765    elementMatched(element) {
766        const { selector } = this;
767        if (selector) {
768            this.selectorMatched(element, selector);
769        }
770    }
771    elementUnmatched(element) {
772        const selectors = this.matchesByElement.getKeysForValue(element);
773        for (const selector of selectors) {
774            this.selectorUnmatched(element, selector);
775        }
776    }
777    elementAttributeChanged(element, _attributeName) {
778        const { selector } = this;
779        if (selector) {
780            const matches = this.matchElement(element);
781            const matchedBefore = this.matchesByElement.has(selector, element);
782            if (matches && !matchedBefore) {
783                this.selectorMatched(element, selector);
784            }
785            else if (!matches && matchedBefore) {
786                this.selectorUnmatched(element, selector);
787            }
788        }
789    }
790    selectorMatched(element, selector) {
791        this.delegate.selectorMatched(element, selector, this.details);
792        this.matchesByElement.add(selector, element);
793    }
794    selectorUnmatched(element, selector) {
795        this.delegate.selectorUnmatched(element, selector, this.details);
796        this.matchesByElement.delete(selector, element);
797    }
798}
799
800class StringMapObserver {
801    constructor(element, delegate) {
802        this.element = element;
803        this.delegate = delegate;
804        this.started = false;
805        this.stringMap = new Map();
806        this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations));
807    }
808    start() {
809        if (!this.started) {
810            this.started = true;
811            this.mutationObserver.observe(this.element, { attributes: true, attributeOldValue: true });
812            this.refresh();
813        }
814    }
815    stop() {
816        if (this.started) {
817            this.mutationObserver.takeRecords();
818            this.mutationObserver.disconnect();
819            this.started = false;
820        }
821    }
822    refresh() {
823        if (this.started) {
824            for (const attributeName of this.knownAttributeNames) {
825                this.refreshAttribute(attributeName, null);
826            }
827        }
828    }
829    processMutations(mutations) {
830        if (this.started) {
831            for (const mutation of mutations) {
832                this.processMutation(mutation);
833            }
834        }
835    }
836    processMutation(mutation) {
837        const attributeName = mutation.attributeName;
838        if (attributeName) {
839            this.refreshAttribute(attributeName, mutation.oldValue);
840        }
841    }
842    refreshAttribute(attributeName, oldValue) {
843        const key = this.delegate.getStringMapKeyForAttribute(attributeName);
844        if (key != null) {
845            if (!this.stringMap.has(attributeName)) {
846                this.stringMapKeyAdded(key, attributeName);
847            }
848            const value = this.element.getAttribute(attributeName);
849            if (this.stringMap.get(attributeName) != value) {
850                this.stringMapValueChanged(value, key, oldValue);
851            }
852            if (value == null) {
853                const oldValue = this.stringMap.get(attributeName);
854                this.stringMap.delete(attributeName);
855                if (oldValue)
856                    this.stringMapKeyRemoved(key, attributeName, oldValue);
857            }
858            else {
859                this.stringMap.set(attributeName, value);
860            }
861        }
862    }
863    stringMapKeyAdded(key, attributeName) {
864        if (this.delegate.stringMapKeyAdded) {
865            this.delegate.stringMapKeyAdded(key, attributeName);
866        }
867    }
868    stringMapValueChanged(value, key, oldValue) {
869        if (this.delegate.stringMapValueChanged) {
870            this.delegate.stringMapValueChanged(value, key, oldValue);
871        }
872    }
873    stringMapKeyRemoved(key, attributeName, oldValue) {
874        if (this.delegate.stringMapKeyRemoved) {
875            this.delegate.stringMapKeyRemoved(key, attributeName, oldValue);
876        }
877    }
878    get knownAttributeNames() {
879        return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)));
880    }
881    get currentAttributeNames() {
882        return Array.from(this.element.attributes).map((attribute) => attribute.name);
883    }
884    get recordedAttributeNames() {
885        return Array.from(this.stringMap.keys());
886    }
887}
888
889class TokenListObserver {
890    constructor(element, attributeName, delegate) {
891        this.attributeObserver = new AttributeObserver(element, attributeName, this);
892        this.delegate = delegate;
893        this.tokensByElement = new Multimap();
894    }
895    get started() {
896        return this.attributeObserver.started;
897    }
898    start() {
899        this.attributeObserver.start();
900    }
901    pause(callback) {
902        this.attributeObserver.pause(callback);
903    }
904    stop() {
905        this.attributeObserver.stop();
906    }
907    refresh() {
908        this.attributeObserver.refresh();
909    }
910    get element() {
911        return this.attributeObserver.element;
912    }
913    get attributeName() {
914        return this.attributeObserver.attributeName;
915    }
916    elementMatchedAttribute(element) {
917        this.tokensMatched(this.readTokensForElement(element));
918    }
919    elementAttributeValueChanged(element) {
920        const [unmatchedTokens, matchedTokens] = this.refreshTokensForElement(element);
921        this.tokensUnmatched(unmatchedTokens);
922        this.tokensMatched(matchedTokens);
923    }
924    elementUnmatchedAttribute(element) {
925        this.tokensUnmatched(this.tokensByElement.getValuesForKey(element));
926    }
927    tokensMatched(tokens) {
928        tokens.forEach((token) => this.tokenMatched(token));
929    }
930    tokensUnmatched(tokens) {
931        tokens.forEach((token) => this.tokenUnmatched(token));
932    }
933    tokenMatched(token) {
934        this.delegate.tokenMatched(token);
935        this.tokensByElement.add(token.element, token);
936    }
937    tokenUnmatched(token) {
938        this.delegate.tokenUnmatched(token);
939        this.tokensByElement.delete(token.element, token);
940    }
941    refreshTokensForElement(element) {
942        const previousTokens = this.tokensByElement.getValuesForKey(element);
943        const currentTokens = this.readTokensForElement(element);
944        const firstDifferingIndex = zip(previousTokens, currentTokens).findIndex(([previousToken, currentToken]) => !tokensAreEqual(previousToken, currentToken));
945        if (firstDifferingIndex == -1) {
946            return [[], []];
947        }
948        else {
949            return [previousTokens.slice(firstDifferingIndex), currentTokens.slice(firstDifferingIndex)];
950        }
951    }
952    readTokensForElement(element) {
953        const attributeName = this.attributeName;
954        const tokenString = element.getAttribute(attributeName) || "";
955        return parseTokenString(tokenString, element, attributeName);
956    }
957}
958function parseTokenString(tokenString, element, attributeName) {
959    return tokenString
960        .trim()
961        .split(/\s+/)
962        .filter((content) => content.length)
963        .map((content, index) => ({ element, attributeName, content, index }));
964}
965function zip(left, right) {
966    const length = Math.max(left.length, right.length);
967    return Array.from({ length }, (_, index) => [left[index], right[index]]);
968}
969function tokensAreEqual(left, right) {
970    return left && right && left.index == right.index && left.content == right.content;
971}
972
973class ValueListObserver {
974    constructor(element, attributeName, delegate) {
975        this.tokenListObserver = new TokenListObserver(element, attributeName, this);
976        this.delegate = delegate;
977        this.parseResultsByToken = new WeakMap();
978        this.valuesByTokenByElement = new WeakMap();
979    }
980    get started() {
981        return this.tokenListObserver.started;
982    }
983    start() {
984        this.tokenListObserver.start();
985    }
986    stop() {
987        this.tokenListObserver.stop();
988    }
989    refresh() {
990        this.tokenListObserver.refresh();
991    }
992    get element() {
993        return this.tokenListObserver.element;
994    }
995    get attributeName() {
996        return this.tokenListObserver.attributeName;
997    }
998    tokenMatched(token) {
999        const { element } = token;
1000        const { value } = this.fetchParseResultForToken(token);
1001        if (value) {
1002            this.fetchValuesByTokenForElement(element).set(token, value);
1003            this.delegate.elementMatchedValue(element, value);
1004        }
1005    }
1006    tokenUnmatched(token) {
1007        const { element } = token;
1008        const { value } = this.fetchParseResultForToken(token);
1009        if (value) {
1010            this.fetchValuesByTokenForElement(element).delete(token);
1011            this.delegate.elementUnmatchedValue(element, value);
1012        }
1013    }
1014    fetchParseResultForToken(token) {
1015        let parseResult = this.parseResultsByToken.get(token);
1016        if (!parseResult) {
1017            parseResult = this.parseToken(token);
1018            this.parseResultsByToken.set(token, parseResult);
1019        }
1020        return parseResult;
1021    }
1022    fetchValuesByTokenForElement(element) {
1023        let valuesByToken = this.valuesByTokenByElement.get(element);
1024        if (!valuesByToken) {
1025            valuesByToken = new Map();
1026            this.valuesByTokenByElement.set(element, valuesByToken);
1027        }
1028        return valuesByToken;
1029    }
1030    parseToken(token) {
1031        try {
1032            const value = this.delegate.parseValueForToken(token);
1033            return { value };
1034        }
1035        catch (error) {
1036            return { error };
1037        }
1038    }
1039}
1040
1041class BindingObserver {
1042    constructor(context, delegate) {
1043        this.context = context;
1044        this.delegate = delegate;
1045        this.bindingsByAction = new Map();
1046    }
1047    start() {
1048        if (!this.valueListObserver) {
1049            this.valueListObserver = new ValueListObserver(this.element, this.actionAttribute, this);
1050            this.valueListObserver.start();
1051        }
1052    }
1053    stop() {
1054        if (this.valueListObserver) {
1055            this.valueListObserver.stop();
1056            delete this.valueListObserver;
1057            this.disconnectAllActions();
1058        }
1059    }
1060    get element() {
1061        return this.context.element;
1062    }
1063    get identifier() {
1064        return this.context.identifier;
1065    }
1066    get actionAttribute() {
1067        return this.schema.actionAttribute;
1068    }
1069    get schema() {
1070        return this.context.schema;
1071    }
1072    get bindings() {
1073        return Array.from(this.bindingsByAction.values());
1074    }
1075    connectAction(action) {
1076        const binding = new Binding(this.context, action);
1077        this.bindingsByAction.set(action, binding);
1078        this.delegate.bindingConnected(binding);
1079    }
1080    disconnectAction(action) {
1081        const binding = this.bindingsByAction.get(action);
1082        if (binding) {
1083            this.bindingsByAction.delete(action);
1084            this.delegate.bindingDisconnected(binding);
1085        }
1086    }
1087    disconnectAllActions() {
1088        this.bindings.forEach((binding) => this.delegate.bindingDisconnected(binding, true));
1089        this.bindingsByAction.clear();
1090    }
1091    parseValueForToken(token) {
1092        const action = Action.forToken(token, this.schema);
1093        if (action.identifier == this.identifier) {
1094            return action;
1095        }
1096    }
1097    elementMatchedValue(element, action) {
1098        this.connectAction(action);
1099    }
1100    elementUnmatchedValue(element, action) {
1101        this.disconnectAction(action);
1102    }
1103}
1104
1105class ValueObserver {
1106    constructor(context, receiver) {
1107        this.context = context;
1108        this.receiver = receiver;
1109        this.stringMapObserver = new StringMapObserver(this.element, this);
1110        this.valueDescriptorMap = this.controller.valueDescriptorMap;
1111    }
1112    start() {
1113        this.stringMapObserver.start();
1114        this.invokeChangedCallbacksForDefaultValues();
1115    }
1116    stop() {
1117        this.stringMapObserver.stop();
1118    }
1119    get element() {
1120        return this.context.element;
1121    }
1122    get controller() {
1123        return this.context.controller;
1124    }
1125    getStringMapKeyForAttribute(attributeName) {
1126        if (attributeName in this.valueDescriptorMap) {
1127            return this.valueDescriptorMap[attributeName].name;
1128        }
1129    }
1130    stringMapKeyAdded(key, attributeName) {
1131        const descriptor = this.valueDescriptorMap[attributeName];
1132        if (!this.hasValue(key)) {
1133            this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), descriptor.writer(descriptor.defaultValue));
1134        }
1135    }
1136    stringMapValueChanged(value, name, oldValue) {
1137        const descriptor = this.valueDescriptorNameMap[name];
1138        if (value === null)
1139            return;
1140        if (oldValue === null) {
1141            oldValue = descriptor.writer(descriptor.defaultValue);
1142        }
1143        this.invokeChangedCallback(name, value, oldValue);
1144    }
1145    stringMapKeyRemoved(key, attributeName, oldValue) {
1146        const descriptor = this.valueDescriptorNameMap[key];
1147        if (this.hasValue(key)) {
1148            this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), oldValue);
1149        }
1150        else {
1151            this.invokeChangedCallback(key, descriptor.writer(descriptor.defaultValue), oldValue);
1152        }
1153    }
1154    invokeChangedCallbacksForDefaultValues() {
1155        for (const { key, name, defaultValue, writer } of this.valueDescriptors) {
1156            if (defaultValue != undefined && !this.controller.data.has(key)) {
1157                this.invokeChangedCallback(name, writer(defaultValue), undefined);
1158            }
1159        }
1160    }
1161    invokeChangedCallback(name, rawValue, rawOldValue) {
1162        const changedMethodName = `${name}Changed`;
1163        const changedMethod = this.receiver[changedMethodName];
1164        if (typeof changedMethod == "function") {
1165            const descriptor = this.valueDescriptorNameMap[name];
1166            try {
1167                const value = descriptor.reader(rawValue);
1168                let oldValue = rawOldValue;
1169                if (rawOldValue) {
1170                    oldValue = descriptor.reader(rawOldValue);
1171                }
1172                changedMethod.call(this.receiver, value, oldValue);
1173            }
1174            catch (error) {
1175                if (error instanceof TypeError) {
1176                    error.message = `Stimulus Value "${this.context.identifier}.${descriptor.name}" - ${error.message}`;
1177                }
1178                throw error;
1179            }
1180        }
1181    }
1182    get valueDescriptors() {
1183        const { valueDescriptorMap } = this;
1184        return Object.keys(valueDescriptorMap).map((key) => valueDescriptorMap[key]);
1185    }
1186    get valueDescriptorNameMap() {
1187        const descriptors = {};
1188        Object.keys(this.valueDescriptorMap).forEach((key) => {
1189            const descriptor = this.valueDescriptorMap[key];
1190            descriptors[descriptor.name] = descriptor;
1191        });
1192        return descriptors;
1193    }
1194    hasValue(attributeName) {
1195        const descriptor = this.valueDescriptorNameMap[attributeName];
1196        const hasMethodName = `has${capitalize(descriptor.name)}`;
1197        return this.receiver[hasMethodName];
1198    }
1199}
1200
1201class TargetObserver {
1202    constructor(context, delegate) {
1203        this.context = context;
1204        this.delegate = delegate;
1205        this.targetsByName = new Multimap();
1206    }
1207    start() {
1208        if (!this.tokenListObserver) {
1209            this.tokenListObserver = new TokenListObserver(this.element, this.attributeName, this);
1210            this.tokenListObserver.start();
1211        }
1212    }
1213    stop() {
1214        if (this.tokenListObserver) {
1215            this.disconnectAllTargets();
1216            this.tokenListObserver.stop();
1217            delete this.tokenListObserver;
1218        }
1219    }
1220    tokenMatched({ element, content: name }) {
1221        if (this.scope.containsElement(element)) {
1222            this.connectTarget(element, name);
1223        }
1224    }
1225    tokenUnmatched({ element, content: name }) {
1226        this.disconnectTarget(element, name);
1227    }
1228    connectTarget(element, name) {
1229        var _a;
1230        if (!this.targetsByName.has(name, element)) {
1231            this.targetsByName.add(name, element);
1232            (_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetConnected(element, name));
1233        }
1234    }
1235    disconnectTarget(element, name) {
1236        var _a;
1237        if (this.targetsByName.has(name, element)) {
1238            this.targetsByName.delete(name, element);
1239            (_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetDisconnected(element, name));
1240        }
1241    }
1242    disconnectAllTargets() {
1243        for (const name of this.targetsByName.keys) {
1244            for (const element of this.targetsByName.getValuesForKey(name)) {
1245                this.disconnectTarget(element, name);
1246            }
1247        }
1248    }
1249    get attributeName() {
1250        return `data-${this.context.identifier}-target`;
1251    }
1252    get element() {
1253        return this.context.element;
1254    }
1255    get scope() {
1256        return this.context.scope;
1257    }
1258}
1259
1260function readInheritableStaticArrayValues(constructor, propertyName) {
1261    const ancestors = getAncestorsForConstructor(constructor);
1262    return Array.from(ancestors.reduce((values, constructor) => {
1263        getOwnStaticArrayValues(constructor, propertyName).forEach((name) => values.add(name));
1264        return values;
1265    }, new Set()));
1266}
1267function readInheritableStaticObjectPairs(constructor, propertyName) {
1268    const ancestors = getAncestorsForConstructor(constructor);
1269    return ancestors.reduce((pairs, constructor) => {
1270        pairs.push(...getOwnStaticObjectPairs(constructor, propertyName));
1271        return pairs;
1272    }, []);
1273}
1274function getAncestorsForConstructor(constructor) {
1275    const ancestors = [];
1276    while (constructor) {
1277        ancestors.push(constructor);
1278        constructor = Object.getPrototypeOf(constructor);
1279    }
1280    return ancestors.reverse();
1281}
1282function getOwnStaticArrayValues(constructor, propertyName) {
1283    const definition = constructor[propertyName];
1284    return Array.isArray(definition) ? definition : [];
1285}
1286function getOwnStaticObjectPairs(constructor, propertyName) {
1287    const definition = constructor[propertyName];
1288    return definition ? Object.keys(definition).map((key) => [key, definition[key]]) : [];
1289}
1290
1291class OutletObserver {
1292    constructor(context, delegate) {
1293        this.started = false;
1294        this.context = context;
1295        this.delegate = delegate;
1296        this.outletsByName = new Multimap();
1297        this.outletElementsByName = new Multimap();
1298        this.selectorObserverMap = new Map();
1299        this.attributeObserverMap = new Map();
1300    }
1301    start() {
1302        if (!this.started) {
1303            this.outletDefinitions.forEach((outletName) => {
1304                this.setupSelectorObserverForOutlet(outletName);
1305                this.setupAttributeObserverForOutlet(outletName);
1306            });
1307            this.started = true;
1308            this.dependentContexts.forEach((context) => context.refresh());
1309        }
1310    }
1311    refresh() {
1312        this.selectorObserverMap.forEach((observer) => observer.refresh());
1313        this.attributeObserverMap.forEach((observer) => observer.refresh());
1314    }
1315    stop() {
1316        if (this.started) {
1317            this.started = false;
1318            this.disconnectAllOutlets();
1319            this.stopSelectorObservers();
1320            this.stopAttributeObservers();
1321        }
1322    }
1323    stopSelectorObservers() {
1324        if (this.selectorObserverMap.size > 0) {
1325            this.selectorObserverMap.forEach((observer) => observer.stop());
1326            this.selectorObserverMap.clear();
1327        }
1328    }
1329    stopAttributeObservers() {
1330        if (this.attributeObserverMap.size > 0) {
1331            this.attributeObserverMap.forEach((observer) => observer.stop());
1332            this.attributeObserverMap.clear();
1333        }
1334    }
1335    selectorMatched(element, _selector, { outletName }) {
1336        const outlet = this.getOutlet(element, outletName);
1337        if (outlet) {
1338            this.connectOutlet(outlet, element, outletName);
1339        }
1340    }
1341    selectorUnmatched(element, _selector, { outletName }) {
1342        const outlet = this.getOutletFromMap(element, outletName);
1343        if (outlet) {
1344            this.disconnectOutlet(outlet, element, outletName);
1345        }
1346    }
1347    selectorMatchElement(element, { outletName }) {
1348        const selector = this.selector(outletName);
1349        const hasOutlet = this.hasOutlet(element, outletName);
1350        const hasOutletController = element.matches(`[${this.schema.controllerAttribute}~=${outletName}]`);
1351        if (selector) {
1352            return hasOutlet && hasOutletController && element.matches(selector);
1353        }
1354        else {
1355            return false;
1356        }
1357    }
1358    elementMatchedAttribute(_element, attributeName) {
1359        const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
1360        if (outletName) {
1361            this.updateSelectorObserverForOutlet(outletName);
1362        }
1363    }
1364    elementAttributeValueChanged(_element, attributeName) {
1365        const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
1366        if (outletName) {
1367            this.updateSelectorObserverForOutlet(outletName);
1368        }
1369    }
1370    elementUnmatchedAttribute(_element, attributeName) {
1371        const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
1372        if (outletName) {
1373            this.updateSelectorObserverForOutlet(outletName);
1374        }
1375    }
1376    connectOutlet(outlet, element, outletName) {
1377        var _a;
1378        if (!this.outletElementsByName.has(outletName, element)) {
1379            this.outletsByName.add(outletName, outlet);
1380            this.outletElementsByName.add(outletName, element);
1381            (_a = this.selectorObserverMap.get(outletName)) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.outletConnected(outlet, element, outletName));
1382        }
1383    }
1384    disconnectOutlet(outlet, element, outletName) {
1385        var _a;
1386        if (this.outletElementsByName.has(outletName, element)) {
1387            this.outletsByName.delete(outletName, outlet);
1388            this.outletElementsByName.delete(outletName, element);
1389            (_a = this.selectorObserverMap
1390                .get(outletName)) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.outletDisconnected(outlet, element, outletName));
1391        }
1392    }
1393    disconnectAllOutlets() {
1394        for (const outletName of this.outletElementsByName.keys) {
1395            for (const element of this.outletElementsByName.getValuesForKey(outletName)) {
1396                for (const outlet of this.outletsByName.getValuesForKey(outletName)) {
1397                    this.disconnectOutlet(outlet, element, outletName);
1398                }
1399            }
1400        }
1401    }
1402    updateSelectorObserverForOutlet(outletName) {
1403        const observer = this.selectorObserverMap.get(outletName);
1404        if (observer) {
1405            observer.selector = this.selector(outletName);
1406        }
1407    }
1408    setupSelectorObserverForOutlet(outletName) {
1409        const selector = this.selector(outletName);
1410        const selectorObserver = new SelectorObserver(document.body, selector, this, { outletName });
1411        this.selectorObserverMap.set(outletName, selectorObserver);
1412        selectorObserver.start();
1413    }
1414    setupAttributeObserverForOutlet(outletName) {
1415        const attributeName = this.attributeNameForOutletName(outletName);
1416        const attributeObserver = new AttributeObserver(this.scope.element, attributeName, this);
1417        this.attributeObserverMap.set(outletName, attributeObserver);
1418        attributeObserver.start();
1419    }
1420    selector(outletName) {
1421        return this.scope.outlets.getSelectorForOutletName(outletName);
1422    }
1423    attributeNameForOutletName(outletName) {
1424        return this.scope.schema.outletAttributeForScope(this.identifier, outletName);
1425    }
1426    getOutletNameFromOutletAttributeName(attributeName) {
1427        return this.outletDefinitions.find((outletName) => this.attributeNameForOutletName(outletName) === attributeName);
1428    }
1429    get outletDependencies() {
1430        const dependencies = new Multimap();
1431        this.router.modules.forEach((module) => {
1432            const constructor = module.definition.controllerConstructor;
1433            const outlets = readInheritableStaticArrayValues(constructor, "outlets");
1434            outlets.forEach((outlet) => dependencies.add(outlet, module.identifier));
1435        });
1436        return dependencies;
1437    }
1438    get outletDefinitions() {
1439        return this.outletDependencies.getKeysForValue(this.identifier);
1440    }
1441    get dependentControllerIdentifiers() {
1442        return this.outletDependencies.getValuesForKey(this.identifier);
1443    }
1444    get dependentContexts() {
1445        const identifiers = this.dependentControllerIdentifiers;
1446        return this.router.contexts.filter((context) => identifiers.includes(context.identifier));
1447    }
1448    hasOutlet(element, outletName) {
1449        return !!this.getOutlet(element, outletName) || !!this.getOutletFromMap(element, outletName);
1450    }
1451    getOutlet(element, outletName) {
1452        return this.application.getControllerForElementAndIdentifier(element, outletName);
1453    }
1454    getOutletFromMap(element, outletName) {
1455        return this.outletsByName.getValuesForKey(outletName).find((outlet) => outlet.element === element);
1456    }
1457    get scope() {
1458        return this.context.scope;
1459    }
1460    get schema() {
1461        return this.context.schema;
1462    }
1463    get identifier() {
1464        return this.context.identifier;
1465    }
1466    get application() {
1467        return this.context.application;
1468    }
1469    get router() {
1470        return this.application.router;
1471    }
1472}
1473
1474class Context {
1475    constructor(module, scope) {
1476        this.logDebugActivity = (functionName, detail = {}) => {
1477            const { identifier, controller, element } = this;
1478            detail = Object.assign({ identifier, controller, element }, detail);
1479            this.application.logDebugActivity(this.identifier, functionName, detail);
1480        };
1481        this.module = module;
1482        this.scope = scope;
1483        this.controller = new module.controllerConstructor(this);
1484        this.bindingObserver = new BindingObserver(this, this.dispatcher);
1485        this.valueObserver = new ValueObserver(this, this.controller);
1486        this.targetObserver = new TargetObserver(this, this);
1487        this.outletObserver = new OutletObserver(this, this);
1488        try {
1489            this.controller.initialize();
1490            this.logDebugActivity("initialize");
1491        }
1492        catch (error) {
1493            this.handleError(error, "initializing controller");
1494        }
1495    }
1496    connect() {
1497        this.bindingObserver.start();
1498        this.valueObserver.start();
1499        this.targetObserver.start();
1500        this.outletObserver.start();
1501        try {
1502            this.controller.connect();
1503            this.logDebugActivity("connect");
1504        }
1505        catch (error) {
1506            this.handleError(error, "connecting controller");
1507        }
1508    }
1509    refresh() {
1510        this.outletObserver.refresh();
1511    }
1512    disconnect() {
1513        try {
1514            this.controller.disconnect();
1515            this.logDebugActivity("disconnect");
1516        }
1517        catch (error) {
1518            this.handleError(error, "disconnecting controller");
1519        }
1520        this.outletObserver.stop();
1521        this.targetObserver.stop();
1522        this.valueObserver.stop();
1523        this.bindingObserver.stop();
1524    }
1525    get application() {
1526        return this.module.application;
1527    }
1528    get identifier() {
1529        return this.module.identifier;
1530    }
1531    get schema() {
1532        return this.application.schema;
1533    }
1534    get dispatcher() {
1535        return this.application.dispatcher;
1536    }
1537    get element() {
1538        return this.scope.element;
1539    }
1540    get parentElement() {
1541        return this.element.parentElement;
1542    }
1543    handleError(error, message, detail = {}) {
1544        const { identifier, controller, element } = this;
1545        detail = Object.assign({ identifier, controller, element }, detail);
1546        this.application.handleError(error, `Error ${message}`, detail);
1547    }
1548    targetConnected(element, name) {
1549        this.invokeControllerMethod(`${name}TargetConnected`, element);
1550    }
1551    targetDisconnected(element, name) {
1552        this.invokeControllerMethod(`${name}TargetDisconnected`, element);
1553    }
1554    outletConnected(outlet, element, name) {
1555        this.invokeControllerMethod(`${namespaceCamelize(name)}OutletConnected`, outlet, element);
1556    }
1557    outletDisconnected(outlet, element, name) {
1558        this.invokeControllerMethod(`${namespaceCamelize(name)}OutletDisconnected`, outlet, element);
1559    }
1560    invokeControllerMethod(methodName, ...args) {
1561        const controller = this.controller;
1562        if (typeof controller[methodName] == "function") {
1563            controller[methodName](...args);
1564        }
1565    }
1566}
1567
1568function bless(constructor) {
1569    return shadow(constructor, getBlessedProperties(constructor));
1570}
1571function shadow(constructor, properties) {
1572    const shadowConstructor = extend(constructor);
1573    const shadowProperties = getShadowProperties(constructor.prototype, properties);
1574    Object.defineProperties(shadowConstructor.prototype, shadowProperties);
1575    return shadowConstructor;
1576}
1577function getBlessedProperties(constructor) {
1578    const blessings = readInheritableStaticArrayValues(constructor, "blessings");
1579    return blessings.reduce((blessedProperties, blessing) => {
1580        const properties = blessing(constructor);
1581        for (const key in properties) {
1582            const descriptor = blessedProperties[key] || {};
1583            blessedProperties[key] = Object.assign(descriptor, properties[key]);
1584        }
1585        return blessedProperties;
1586    }, {});
1587}
1588function getShadowProperties(prototype, properties) {
1589    return getOwnKeys(properties).reduce((shadowProperties, key) => {
1590        const descriptor = getShadowedDescriptor(prototype, properties, key);
1591        if (descriptor) {
1592            Object.assign(shadowProperties, { [key]: descriptor });
1593        }
1594        return shadowProperties;
1595    }, {});
1596}
1597function getShadowedDescriptor(prototype, properties, key) {
1598    const shadowingDescriptor = Object.getOwnPropertyDescriptor(prototype, key);
1599    const shadowedByValue = shadowingDescriptor && "value" in shadowingDescriptor;
1600    if (!shadowedByValue) {
1601        const descriptor = Object.getOwnPropertyDescriptor(properties, key).value;
1602        if (shadowingDescriptor) {
1603            descriptor.get = shadowingDescriptor.get || descriptor.get;
1604            descriptor.set = shadowingDescriptor.set || descriptor.set;
1605        }
1606        return descriptor;
1607    }
1608}
1609const getOwnKeys = (() => {
1610    if (typeof Object.getOwnPropertySymbols == "function") {
1611        return (object) => [...Object.getOwnPropertyNames(object), ...Object.getOwnPropertySymbols(object)];
1612    }
1613    else {
1614        return Object.getOwnPropertyNames;
1615    }
1616})();
1617const extend = (() => {
1618    function extendWithReflect(constructor) {
1619        function extended() {
1620            return Reflect.construct(constructor, arguments, new.target);
1621        }
1622        extended.prototype = Object.create(constructor.prototype, {
1623            constructor: { value: extended },
1624        });
1625        Reflect.setPrototypeOf(extended, constructor);
1626        return extended;
1627    }
1628    function testReflectExtension() {
1629        const a = function () {
1630            this.a.call(this);
1631        };
1632        const b = extendWithReflect(a);
1633        b.prototype.a = function () { };
1634        return new b();
1635    }
1636    try {
1637        testReflectExtension();
1638        return extendWithReflect;
1639    }
1640    catch (error) {
1641        return (constructor) => class extended extends constructor {
1642        };
1643    }
1644})();
1645
1646function blessDefinition(definition) {
1647    return {
1648        identifier: definition.identifier,
1649        controllerConstructor: bless(definition.controllerConstructor),
1650    };
1651}
1652
1653class Module {
1654    constructor(application, definition) {
1655        this.application = application;
1656        this.definition = blessDefinition(definition);
1657        this.contextsByScope = new WeakMap();
1658        this.connectedContexts = new Set();
1659    }
1660    get identifier() {
1661        return this.definition.identifier;
1662    }
1663    get controllerConstructor() {
1664        return this.definition.controllerConstructor;
1665    }
1666    get contexts() {
1667        return Array.from(this.connectedContexts);
1668    }
1669    connectContextForScope(scope) {
1670        const context = this.fetchContextForScope(scope);
1671        this.connectedContexts.add(context);
1672        context.connect();
1673    }
1674    disconnectContextForScope(scope) {
1675        const context = this.contextsByScope.get(scope);
1676        if (context) {
1677            this.connectedContexts.delete(context);
1678            context.disconnect();
1679        }
1680    }
1681    fetchContextForScope(scope) {
1682        let context = this.contextsByScope.get(scope);
1683        if (!context) {
1684            context = new Context(this, scope);
1685            this.contextsByScope.set(scope, context);
1686        }
1687        return context;
1688    }
1689}
1690
1691class ClassMap {
1692    constructor(scope) {
1693        this.scope = scope;
1694    }
1695    has(name) {
1696        return this.data.has(this.getDataKey(name));
1697    }
1698    get(name) {
1699        return this.getAll(name)[0];
1700    }
1701    getAll(name) {
1702        const tokenString = this.data.get(this.getDataKey(name)) || "";
1703        return tokenize(tokenString);
1704    }
1705    getAttributeName(name) {
1706        return this.data.getAttributeNameForKey(this.getDataKey(name));
1707    }
1708    getDataKey(name) {
1709        return `${name}-class`;
1710    }
1711    get data() {
1712        return this.scope.data;
1713    }
1714}
1715
1716class DataMap {
1717    constructor(scope) {
1718        this.scope = scope;
1719    }
1720    get element() {
1721        return this.scope.element;
1722    }
1723    get identifier() {
1724        return this.scope.identifier;
1725    }
1726    get(key) {
1727        const name = this.getAttributeNameForKey(key);
1728        return this.element.getAttribute(name);
1729    }
1730    set(key, value) {
1731        const name = this.getAttributeNameForKey(key);
1732        this.element.setAttribute(name, value);
1733        return this.get(key);
1734    }
1735    has(key) {
1736        const name = this.getAttributeNameForKey(key);
1737        return this.element.hasAttribute(name);
1738    }
1739    delete(key) {
1740        if (this.has(key)) {
1741            const name = this.getAttributeNameForKey(key);
1742            this.element.removeAttribute(name);
1743            return true;
1744        }
1745        else {
1746            return false;
1747        }
1748    }
1749    getAttributeNameForKey(key) {
1750        return `data-${this.identifier}-${dasherize(key)}`;
1751    }
1752}
1753
1754class Guide {
1755    constructor(logger) {
1756        this.warnedKeysByObject = new WeakMap();
1757        this.logger = logger;
1758    }
1759    warn(object, key, message) {
1760        let warnedKeys = this.warnedKeysByObject.get(object);
1761        if (!warnedKeys) {
1762            warnedKeys = new Set();
1763            this.warnedKeysByObject.set(object, warnedKeys);
1764        }
1765        if (!warnedKeys.has(key)) {
1766            warnedKeys.add(key);
1767            this.logger.warn(message, object);
1768        }
1769    }
1770}
1771
1772function attributeValueContainsToken(attributeName, token) {
1773    return `[${attributeName}~="${token}"]`;
1774}
1775
1776class TargetSet {
1777    constructor(scope) {
1778        this.scope = scope;
1779    }
1780    get element() {
1781        return this.scope.element;
1782    }
1783    get identifier() {
1784        return this.scope.identifier;
1785    }
1786    get schema() {
1787        return this.scope.schema;
1788    }
1789    has(targetName) {
1790        return this.find(targetName) != null;
1791    }
1792    find(...targetNames) {
1793        return targetNames.reduce((target, targetName) => target || this.findTarget(targetName) || this.findLegacyTarget(targetName), undefined);
1794    }
1795    findAll(...targetNames) {
1796        return targetNames.reduce((targets, targetName) => [
1797            ...targets,
1798            ...this.findAllTargets(targetName),
1799            ...this.findAllLegacyTargets(targetName),
1800        ], []);
1801    }
1802    findTarget(targetName) {
1803        const selector = this.getSelectorForTargetName(targetName);
1804        return this.scope.findElement(selector);
1805    }
1806    findAllTargets(targetName) {
1807        const selector = this.getSelectorForTargetName(targetName);
1808        return this.scope.findAllElements(selector);
1809    }
1810    getSelectorForTargetName(targetName) {
1811        const attributeName = this.schema.targetAttributeForScope(this.identifier);
1812        return attributeValueContainsToken(attributeName, targetName);
1813    }
1814    findLegacyTarget(targetName) {
1815        const selector = this.getLegacySelectorForTargetName(targetName);
1816        return this.deprecate(this.scope.findElement(selector), targetName);
1817    }
1818    findAllLegacyTargets(targetName) {
1819        const selector = this.getLegacySelectorForTargetName(targetName);
1820        return this.scope.findAllElements(selector).map((element) => this.deprecate(element, targetName));
1821    }
1822    getLegacySelectorForTargetName(targetName) {
1823        const targetDescriptor = `${this.identifier}.${targetName}`;
1824        return attributeValueContainsToken(this.schema.targetAttribute, targetDescriptor);
1825    }
1826    deprecate(element, targetName) {
1827        if (element) {
1828            const { identifier } = this;
1829            const attributeName = this.schema.targetAttribute;
1830            const revisedAttributeName = this.schema.targetAttributeForScope(identifier);
1831            this.guide.warn(element, `target:${targetName}`, `Please replace ${attributeName}="${identifier}.${targetName}" with ${revisedAttributeName}="${targetName}". ` +
1832                `The ${attributeName} attribute is deprecated and will be removed in a future version of Stimulus.`);
1833        }
1834        return element;
1835    }
1836    get guide() {
1837        return this.scope.guide;
1838    }
1839}
1840
1841class OutletSet {
1842    constructor(scope, controllerElement) {
1843        this.scope = scope;
1844        this.controllerElement = controllerElement;
1845    }
1846    get element() {
1847        return this.scope.element;
1848    }
1849    get identifier() {
1850        return this.scope.identifier;
1851    }
1852    get schema() {
1853        return this.scope.schema;
1854    }
1855    has(outletName) {
1856        return this.find(outletName) != null;
1857    }
1858    find(...outletNames) {
1859        return outletNames.reduce((outlet, outletName) => outlet || this.findOutlet(outletName), undefined);
1860    }
1861    findAll(...outletNames) {
1862        return outletNames.reduce((outlets, outletName) => [...outlets, ...this.findAllOutlets(outletName)], []);
1863    }
1864    getSelectorForOutletName(outletName) {
1865        const attributeName = this.schema.outletAttributeForScope(this.identifier, outletName);
1866        return this.controllerElement.getAttribute(attributeName);
1867    }
1868    findOutlet(outletName) {
1869        const selector = this.getSelectorForOutletName(outletName);
1870        if (selector)
1871            return this.findElement(selector, outletName);
1872    }
1873    findAllOutlets(outletName) {
1874        const selector = this.getSelectorForOutletName(outletName);
1875        return selector ? this.findAllElements(selector, outletName) : [];
1876    }
1877    findElement(selector, outletName) {
1878        const elements = this.scope.queryElements(selector);
1879        return elements.filter((element) => this.matchesElement(element, selector, outletName))[0];
1880    }
1881    findAllElements(selector, outletName) {
1882        const elements = this.scope.queryElements(selector);
1883        return elements.filter((element) => this.matchesElement(element, selector, outletName));
1884    }
1885    matchesElement(element, selector, outletName) {
1886        const controllerAttribute = element.getAttribute(this.scope.schema.controllerAttribute) || "";
1887        return element.matches(selector) && controllerAttribute.split(" ").includes(outletName);
1888    }
1889}
1890
1891class Scope {
1892    constructor(schema, element, identifier, logger) {
1893        this.targets = new TargetSet(this);
1894        this.classes = new ClassMap(this);
1895        this.data = new DataMap(this);
1896        this.containsElement = (element) => {
1897            return element.closest(this.controllerSelector) === this.element;
1898        };
1899        this.schema = schema;
1900        this.element = element;
1901        this.identifier = identifier;
1902        this.guide = new Guide(logger);
1903        this.outlets = new OutletSet(this.documentScope, element);
1904    }
1905    findElement(selector) {
1906        return this.element.matches(selector) ? this.element : this.queryElements(selector).find(this.containsElement);
1907    }
1908    findAllElements(selector) {
1909        return [
1910            ...(this.element.matches(selector) ? [this.element] : []),
1911            ...this.queryElements(selector).filter(this.containsElement),
1912        ];
1913    }
1914    queryElements(selector) {
1915        return Array.from(this.element.querySelectorAll(selector));
1916    }
1917    get controllerSelector() {
1918        return attributeValueContainsToken(this.schema.controllerAttribute, this.identifier);
1919    }
1920    get isDocumentScope() {
1921        return this.element === document.documentElement;
1922    }
1923    get documentScope() {
1924        return this.isDocumentScope
1925            ? this
1926            : new Scope(this.schema, document.documentElement, this.identifier, this.guide.logger);
1927    }
1928}
1929
1930class ScopeObserver {
1931    constructor(element, schema, delegate) {
1932        this.element = element;
1933        this.schema = schema;
1934        this.delegate = delegate;
1935        this.valueListObserver = new ValueListObserver(this.element, this.controllerAttribute, this);
1936        this.scopesByIdentifierByElement = new WeakMap();
1937        this.scopeReferenceCounts = new WeakMap();
1938    }
1939    start() {
1940        this.valueListObserver.start();
1941    }
1942    stop() {
1943        this.valueListObserver.stop();
1944    }
1945    get controllerAttribute() {
1946        return this.schema.controllerAttribute;
1947    }
1948    parseValueForToken(token) {
1949        const { element, content: identifier } = token;
1950        return this.parseValueForElementAndIdentifier(element, identifier);
1951    }
1952    parseValueForElementAndIdentifier(element, identifier) {
1953        const scopesByIdentifier = this.fetchScopesByIdentifierForElement(element);
1954        let scope = scopesByIdentifier.get(identifier);
1955        if (!scope) {
1956            scope = this.delegate.createScopeForElementAndIdentifier(element, identifier);
1957            scopesByIdentifier.set(identifier, scope);
1958        }
1959        return scope;
1960    }
1961    elementMatchedValue(element, value) {
1962        const referenceCount = (this.scopeReferenceCounts.get(value) || 0) + 1;
1963        this.scopeReferenceCounts.set(value, referenceCount);
1964        if (referenceCount == 1) {
1965            this.delegate.scopeConnected(value);
1966        }
1967    }
1968    elementUnmatchedValue(element, value) {
1969        const referenceCount = this.scopeReferenceCounts.get(value);
1970        if (referenceCount) {
1971            this.scopeReferenceCounts.set(value, referenceCount - 1);
1972            if (referenceCount == 1) {
1973                this.delegate.scopeDisconnected(value);
1974            }
1975        }
1976    }
1977    fetchScopesByIdentifierForElement(element) {
1978        let scopesByIdentifier = this.scopesByIdentifierByElement.get(element);
1979        if (!scopesByIdentifier) {
1980            scopesByIdentifier = new Map();
1981            this.scopesByIdentifierByElement.set(element, scopesByIdentifier);
1982        }
1983        return scopesByIdentifier;
1984    }
1985}
1986
1987class Router {
1988    constructor(application) {
1989        this.application = application;
1990        this.scopeObserver = new ScopeObserver(this.element, this.schema, this);
1991        this.scopesByIdentifier = new Multimap();
1992        this.modulesByIdentifier = new Map();
1993    }
1994    get element() {
1995        return this.application.element;
1996    }
1997    get schema() {
1998        return this.application.schema;
1999    }
2000    get logger() {
2001        return this.application.logger;
2002    }
2003    get controllerAttribute() {
2004        return this.schema.controllerAttribute;
2005    }
2006    get modules() {
2007        return Array.from(this.modulesByIdentifier.values());
2008    }
2009    get contexts() {
2010        return this.modules.reduce((contexts, module) => contexts.concat(module.contexts), []);
2011    }
2012    start() {
2013        this.scopeObserver.start();
2014    }
2015    stop() {
2016        this.scopeObserver.stop();
2017    }
2018    loadDefinition(definition) {
2019        this.unloadIdentifier(definition.identifier);
2020        const module = new Module(this.application, definition);
2021        this.connectModule(module);
2022        const afterLoad = definition.controllerConstructor.afterLoad;
2023        if (afterLoad) {
2024            afterLoad.call(definition.controllerConstructor, definition.identifier, this.application);
2025        }
2026    }
2027    unloadIdentifier(identifier) {
2028        const module = this.modulesByIdentifier.get(identifier);
2029        if (module) {
2030            this.disconnectModule(module);
2031        }
2032    }
2033    getContextForElementAndIdentifier(element, identifier) {
2034        const module = this.modulesByIdentifier.get(identifier);
2035        if (module) {
2036            return module.contexts.find((context) => context.element == element);
2037        }
2038    }
2039    proposeToConnectScopeForElementAndIdentifier(element, identifier) {
2040        const scope = this.scopeObserver.parseValueForElementAndIdentifier(element, identifier);
2041        if (scope) {
2042            this.scopeObserver.elementMatchedValue(scope.element, scope);
2043        }
2044        else {
2045            console.error(`Couldn't find or create scope for identifier: "${identifier}" and element:`, element);
2046        }
2047    }
2048    handleError(error, message, detail) {
2049        this.application.handleError(error, message, detail);
2050    }
2051    createScopeForElementAndIdentifier(element, identifier) {
2052        return new Scope(this.schema, element, identifier, this.logger);
2053    }
2054    scopeConnected(scope) {
2055        this.scopesByIdentifier.add(scope.identifier, scope);
2056        const module = this.modulesByIdentifier.get(scope.identifier);
2057        if (module) {
2058            module.connectContextForScope(scope);
2059        }
2060    }
2061    scopeDisconnected(scope) {
2062        this.scopesByIdentifier.delete(scope.identifier, scope);
2063        const module = this.modulesByIdentifier.get(scope.identifier);
2064        if (module) {
2065            module.disconnectContextForScope(scope);
2066        }
2067    }
2068    connectModule(module) {
2069        this.modulesByIdentifier.set(module.identifier, module);
2070        const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier);
2071        scopes.forEach((scope) => module.connectContextForScope(scope));
2072    }
2073    disconnectModule(module) {
2074        this.modulesByIdentifier.delete(module.identifier);
2075        const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier);
2076        scopes.forEach((scope) => module.disconnectContextForScope(scope));
2077    }
2078}
2079
2080const defaultSchema = {
2081    controllerAttribute: "data-controller",
2082    actionAttribute: "data-action",
2083    targetAttribute: "data-target",
2084    targetAttributeForScope: (identifier) => `data-${identifier}-target`,
2085    outletAttributeForScope: (identifier, outlet) => `data-${identifier}-${outlet}-outlet`,
2086    keyMappings: Object.assign(Object.assign({ enter: "Enter", tab: "Tab", esc: "Escape", space: " ", up: "ArrowUp", down: "ArrowDown", left: "ArrowLeft", right: "ArrowRight", home: "Home", end: "End", page_up: "PageUp", page_down: "PageDown" }, objectFromEntries("abcdefghijklmnopqrstuvwxyz".split("").map((c) => [c, c]))), objectFromEntries("0123456789".split("").map((n) => [n, n]))),
2087};
2088function objectFromEntries(array) {
2089    return array.reduce((memo, [k, v]) => (Object.assign(Object.assign({}, memo), { [k]: v })), {});
2090}
2091
2092class Application {
2093    constructor(element = document.documentElement, schema = defaultSchema) {
2094        this.logger = console;
2095        this.debug = false;
2096        this.logDebugActivity = (identifier, functionName, detail = {}) => {
2097            if (this.debug) {
2098                this.logFormattedMessage(identifier, functionName, detail);
2099            }
2100        };
2101        this.element = element;
2102        this.schema = schema;
2103        this.dispatcher = new Dispatcher(this);
2104        this.router = new Router(this);
2105        this.actionDescriptorFilters = Object.assign({}, defaultActionDescriptorFilters);
2106    }
2107    static start(element, schema) {
2108        const application = new this(element, schema);
2109        application.start();
2110        return application;
2111    }
2112    async start() {
2113        await domReady();
2114        this.logDebugActivity("application", "starting");
2115        this.dispatcher.start();
2116        this.router.start();
2117        this.logDebugActivity("application", "start");
2118    }
2119    stop() {
2120        this.logDebugActivity("application", "stopping");
2121        this.dispatcher.stop();
2122        this.router.stop();
2123        this.logDebugActivity("application", "stop");
2124    }
2125    register(identifier, controllerConstructor) {
2126        this.load({ identifier, controllerConstructor });
2127    }
2128    registerActionOption(name, filter) {
2129        this.actionDescriptorFilters[name] = filter;
2130    }
2131    load(head, ...rest) {
2132        const definitions = Array.isArray(head) ? head : [head, ...rest];
2133        definitions.forEach((definition) => {
2134            if (definition.controllerConstructor.shouldLoad) {
2135                this.router.loadDefinition(definition);
2136            }
2137        });
2138    }
2139    unload(head, ...rest) {
2140        const identifiers = Array.isArray(head) ? head : [head, ...rest];
2141        identifiers.forEach((identifier) => this.router.unloadIdentifier(identifier));
2142    }
2143    get controllers() {
2144        return this.router.contexts.map((context) => context.controller);
2145    }
2146    getControllerForElementAndIdentifier(element, identifier) {
2147        const context = this.router.getContextForElementAndIdentifier(element, identifier);
2148        return context ? context.controller : null;
2149    }
2150    handleError(error, message, detail) {
2151        var _a;
2152        this.logger.error(`%s\n\n%o\n\n%o`, message, error, detail);
2153        (_a = window.onerror) === null || _a === void 0 ? void 0 : _a.call(window, message, "", 0, 0, error);
2154    }
2155    logFormattedMessage(identifier, functionName, detail = {}) {
2156        detail = Object.assign({ application: this }, detail);
2157        this.logger.groupCollapsed(`${identifier} #${functionName}`);
2158        this.logger.log("details:", Object.assign({}, detail));
2159        this.logger.groupEnd();
2160    }
2161}
2162function domReady() {
2163    return new Promise((resolve) => {
2164        if (document.readyState == "loading") {
2165            document.addEventListener("DOMContentLoaded", () => resolve());
2166        }
2167        else {
2168            resolve();
2169        }
2170    });
2171}
2172
2173function ClassPropertiesBlessing(constructor) {
2174    const classes = readInheritableStaticArrayValues(constructor, "classes");
2175    return classes.reduce((properties, classDefinition) => {
2176        return Object.assign(properties, propertiesForClassDefinition(classDefinition));
2177    }, {});
2178}
2179function propertiesForClassDefinition(key) {
2180    return {
2181        [`${key}Class`]: {
2182            get() {
2183                const { classes } = this;
2184                if (classes.has(key)) {
2185                    return classes.get(key);
2186                }
2187                else {
2188                    const attribute = classes.getAttributeName(key);
2189                    throw new Error(`Missing attribute "${attribute}"`);
2190                }
2191            },
2192        },
2193        [`${key}Classes`]: {
2194            get() {
2195                return this.classes.getAll(key);
2196            },
2197        },
2198        [`has${capitalize(key)}Class`]: {
2199            get() {
2200                return this.classes.has(key);
2201            },
2202        },
2203    };
2204}
2205
2206function OutletPropertiesBlessing(constructor) {
2207    const outlets = readInheritableStaticArrayValues(constructor, "outlets");
2208    return outlets.reduce((properties, outletDefinition) => {
2209        return Object.assign(properties, propertiesForOutletDefinition(outletDefinition));
2210    }, {});
2211}
2212function getOutletController(controller, element, identifier) {
2213    return controller.application.getControllerForElementAndIdentifier(element, identifier);
2214}
2215function getControllerAndEnsureConnectedScope(controller, element, outletName) {
2216    let outletController = getOutletController(controller, element, outletName);
2217    if (outletController)
2218        return outletController;
2219    controller.application.router.proposeToConnectScopeForElementAndIdentifier(element, outletName);
2220    outletController = getOutletController(controller, element, outletName);
2221    if (outletController)
2222        return outletController;
2223}
2224function propertiesForOutletDefinition(name) {
2225    const camelizedName = namespaceCamelize(name);
2226    return {
2227        [`${camelizedName}Outlet`]: {
2228            get() {
2229                const outletElement = this.outlets.find(name);
2230                const selector = this.outlets.getSelectorForOutletName(name);
2231                if (outletElement) {
2232                    const outletController = getControllerAndEnsureConnectedScope(this, outletElement, name);
2233                    if (outletController)
2234                        return outletController;
2235                    throw new Error(`The provided outlet element is missing an outlet controller "${name}" instance for host controller "${this.identifier}"`);
2236                }
2237                throw new Error(`Missing outlet element "${name}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${selector}".`);
2238            },
2239        },
2240        [`${camelizedName}Outlets`]: {
2241            get() {
2242                const outlets = this.outlets.findAll(name);
2243                if (outlets.length > 0) {
2244                    return outlets
2245                        .map((outletElement) => {
2246                        const outletController = getControllerAndEnsureConnectedScope(this, outletElement, name);
2247                        if (outletController)
2248                            return outletController;
2249                        console.warn(`The provided outlet element is missing an outlet controller "${name}" instance for host controller "${this.identifier}"`, outletElement);
2250                    })
2251                        .filter((controller) => controller);
2252                }
2253                return [];
2254            },
2255        },
2256        [`${camelizedName}OutletElement`]: {
2257            get() {
2258                const outletElement = this.outlets.find(name);
2259                const selector = this.outlets.getSelectorForOutletName(name);
2260                if (outletElement) {
2261                    return outletElement;
2262                }
2263                else {
2264                    throw new Error(`Missing outlet element "${name}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${selector}".`);
2265                }
2266            },
2267        },
2268        [`${camelizedName}OutletElements`]: {
2269            get() {
2270                return this.outlets.findAll(name);
2271            },
2272        },
2273        [`has${capitalize(camelizedName)}Outlet`]: {
2274            get() {
2275                return this.outlets.has(name);
2276            },
2277        },
2278    };
2279}
2280
2281function TargetPropertiesBlessing(constructor) {
2282    const targets = readInheritableStaticArrayValues(constructor, "targets");
2283    return targets.reduce((properties, targetDefinition) => {
2284        return Object.assign(properties, propertiesForTargetDefinition(targetDefinition));
2285    }, {});
2286}
2287function propertiesForTargetDefinition(name) {
2288    return {
2289        [`${name}Target`]: {
2290            get() {
2291                const target = this.targets.find(name);
2292                if (target) {
2293                    return target;
2294                }
2295                else {
2296                    throw new Error(`Missing target element "${name}" for "${this.identifier}" controller`);
2297                }
2298            },
2299        },
2300        [`${name}Targets`]: {
2301            get() {
2302                return this.targets.findAll(name);
2303            },
2304        },
2305        [`has${capitalize(name)}Target`]: {
2306            get() {
2307                return this.targets.has(name);
2308            },
2309        },
2310    };
2311}
2312
2313function ValuePropertiesBlessing(constructor) {
2314    const valueDefinitionPairs = readInheritableStaticObjectPairs(constructor, "values");
2315    const propertyDescriptorMap = {
2316        valueDescriptorMap: {
2317            get() {
2318                return valueDefinitionPairs.reduce((result, valueDefinitionPair) => {
2319                    const valueDescriptor = parseValueDefinitionPair(valueDefinitionPair, this.identifier);
2320                    const attributeName = this.data.getAttributeNameForKey(valueDescriptor.key);
2321                    return Object.assign(result, { [attributeName]: valueDescriptor });
2322                }, {});
2323            },
2324        },
2325    };
2326    return valueDefinitionPairs.reduce((properties, valueDefinitionPair) => {
2327        return Object.assign(properties, propertiesForValueDefinitionPair(valueDefinitionPair));
2328    }, propertyDescriptorMap);
2329}
2330function propertiesForValueDefinitionPair(valueDefinitionPair, controller) {
2331    const definition = parseValueDefinitionPair(valueDefinitionPair, controller);
2332    const { key, name, reader: read, writer: write } = definition;
2333    return {
2334        [name]: {
2335            get() {
2336                const value = this.data.get(key);
2337                if (value !== null) {
2338                    return read(value);
2339                }
2340                else {
2341                    return definition.defaultValue;
2342                }
2343            },
2344            set(value) {
2345                if (value === undefined) {
2346                    this.data.delete(key);
2347                }
2348                else {
2349                    this.data.set(key, write(value));
2350                }
2351            },
2352        },
2353        [`has${capitalize(name)}`]: {
2354            get() {
2355                return this.data.has(key) || definition.hasCustomDefaultValue;
2356            },
2357        },
2358    };
2359}
2360function parseValueDefinitionPair([token, typeDefinition], controller) {
2361    return valueDescriptorForTokenAndTypeDefinition({
2362        controller,
2363        token,
2364        typeDefinition,
2365    });
2366}
2367function parseValueTypeConstant(constant) {
2368    switch (constant) {
2369        case Array:
2370            return "array";
2371        case Boolean:
2372            return "boolean";
2373        case Number:
2374            return "number";
2375        case Object:
2376            return "object";
2377        case String:
2378            return "string";
2379    }
2380}
2381function parseValueTypeDefault(defaultValue) {
2382    switch (typeof defaultValue) {
2383        case "boolean":
2384            return "boolean";
2385        case "number":
2386            return "number";
2387        case "string":
2388            return "string";
2389    }
2390    if (Array.isArray(defaultValue))
2391        return "array";
2392    if (Object.prototype.toString.call(defaultValue) === "[object Object]")
2393        return "object";
2394}
2395function parseValueTypeObject(payload) {
2396    const { controller, token, typeObject } = payload;
2397    const hasType = isSomething(typeObject.type);
2398    const hasDefault = isSomething(typeObject.default);
2399    const fullObject = hasType && hasDefault;
2400    const onlyType = hasType && !hasDefault;
2401    const onlyDefault = !hasType && hasDefault;
2402    const typeFromObject = parseValueTypeConstant(typeObject.type);
2403    const typeFromDefaultValue = parseValueTypeDefault(payload.typeObject.default);
2404    if (onlyType)
2405        return typeFromObject;
2406    if (onlyDefault)
2407        return typeFromDefaultValue;
2408    if (typeFromObject !== typeFromDefaultValue) {
2409        const propertyPath = controller ? `${controller}.${token}` : token;
2410        throw new Error(`The specified default value for the Stimulus Value "${propertyPath}" must match the defined type "${typeFromObject}". The provided default value of "${typeObject.default}" is of type "${typeFromDefaultValue}".`);
2411    }
2412    if (fullObject)
2413        return typeFromObject;
2414}
2415function parseValueTypeDefinition(payload) {
2416    const { controller, token, typeDefinition } = payload;
2417    const typeObject = { controller, token, typeObject: typeDefinition };
2418    const typeFromObject = parseValueTypeObject(typeObject);
2419    const typeFromDefaultValue = parseValueTypeDefault(typeDefinition);
2420    const typeFromConstant = parseValueTypeConstant(typeDefinition);
2421    const type = typeFromObject || typeFromDefaultValue || typeFromConstant;
2422    if (type)
2423        return type;
2424    const propertyPath = controller ? `${controller}.${typeDefinition}` : token;
2425    throw new Error(`Unknown value type "${propertyPath}" for "${token}" value`);
2426}
2427function defaultValueForDefinition(typeDefinition) {
2428    const constant = parseValueTypeConstant(typeDefinition);
2429    if (constant)
2430        return defaultValuesByType[constant];
2431    const hasDefault = hasProperty(typeDefinition, "default");
2432    const hasType = hasProperty(typeDefinition, "type");
2433    const typeObject = typeDefinition;
2434    if (hasDefault)
2435        return typeObject.default;
2436    if (hasType) {
2437        const { type } = typeObject;
2438        const constantFromType = parseValueTypeConstant(type);
2439        if (constantFromType)
2440            return defaultValuesByType[constantFromType];
2441    }
2442    return typeDefinition;
2443}
2444function valueDescriptorForTokenAndTypeDefinition(payload) {
2445    const { token, typeDefinition } = payload;
2446    const key = `${dasherize(token)}-value`;
2447    const type = parseValueTypeDefinition(payload);
2448    return {
2449        type,
2450        key,
2451        name: camelize(key),
2452        get defaultValue() {
2453            return defaultValueForDefinition(typeDefinition);
2454        },
2455        get hasCustomDefaultValue() {
2456            return parseValueTypeDefault(typeDefinition) !== undefined;
2457        },
2458        reader: readers[type],
2459        writer: writers[type] || writers.default,
2460    };
2461}
2462const defaultValuesByType = {
2463    get array() {
2464        return [];
2465    },
2466    boolean: false,
2467    number: 0,
2468    get object() {
2469        return {};
2470    },
2471    string: "",
2472};
2473const readers = {
2474    array(value) {
2475        const array = JSON.parse(value);
2476        if (!Array.isArray(array)) {
2477            throw new TypeError(`expected value of type "array" but instead got value "${value}" of type "${parseValueTypeDefault(array)}"`);
2478        }
2479        return array;
2480    },
2481    boolean(value) {
2482        return !(value == "0" || String(value).toLowerCase() == "false");
2483    },
2484    number(value) {
2485        return Number(value.replace(/_/g, ""));
2486    },
2487    object(value) {
2488        const object = JSON.parse(value);
2489        if (object === null || typeof object != "object" || Array.isArray(object)) {
2490            throw new TypeError(`expected value of type "object" but instead got value "${value}" of type "${parseValueTypeDefault(object)}"`);
2491        }
2492        return object;
2493    },
2494    string(value) {
2495        return value;
2496    },
2497};
2498const writers = {
2499    default: writeString,
2500    array: writeJSON,
2501    object: writeJSON,
2502};
2503function writeJSON(value) {
2504    return JSON.stringify(value);
2505}
2506function writeString(value) {
2507    return `${value}`;
2508}
2509
2510class Controller {
2511    constructor(context) {
2512        this.context = context;
2513    }
2514    static get shouldLoad() {
2515        return true;
2516    }
2517    static afterLoad(_identifier, _application) {
2518        return;
2519    }
2520    get application() {
2521        return this.context.application;
2522    }
2523    get scope() {
2524        return this.context.scope;
2525    }
2526    get element() {
2527        return this.scope.element;
2528    }
2529    get identifier() {
2530        return this.scope.identifier;
2531    }
2532    get targets() {
2533        return this.scope.targets;
2534    }
2535    get outlets() {
2536        return this.scope.outlets;
2537    }
2538    get classes() {
2539        return this.scope.classes;
2540    }
2541    get data() {
2542        return this.scope.data;
2543    }
2544    initialize() {
2545    }
2546    connect() {
2547    }
2548    disconnect() {
2549    }
2550    dispatch(eventName, { target = this.element, detail = {}, prefix = this.identifier, bubbles = true, cancelable = true, } = {}) {
2551        const type = prefix ? `${prefix}:${eventName}` : eventName;
2552        const event = new CustomEvent(type, { detail, bubbles, cancelable });
2553        target.dispatchEvent(event);
2554        return event;
2555    }
2556}
2557Controller.blessings = [
2558    ClassPropertiesBlessing,
2559    TargetPropertiesBlessing,
2560    ValuePropertiesBlessing,
2561    OutletPropertiesBlessing,
2562];
2563Controller.targets = [];
2564Controller.outlets = [];
2565Controller.values = {};
2566
2567export { Application, AttributeObserver, Context, Controller, ElementObserver, IndexedMultimap, Multimap, SelectorObserver, StringMapObserver, TokenListObserver, ValueListObserver, add, defaultSchema, del, fetch, prune };

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.