PageSourceSearch

https://www.ferrari-carano.com/_static/??/wp-content/plugins/foley…/js/dist/hooks.min.js?m=1790308356j

js ferrari-carano.com collected 2026-09-25 21:58:56 UTC 35,526 bytes, 1,007 lines download raw bytes

1(function () {
2	var PRICE_STEP = 1;
3	var SEARCH_MIN_LENGTH = 3;
4	var SEARCH_DEBOUNCE_DELAY = 500;
5
6	function parseConfig(block) {
7		var script = block.querySelector('.js-foley-c7-ui-config');
8
9		if (!script) {
10			return null;
11		}
12
13		try {
14			return JSON.parse(script.textContent || '{}');
15		} catch (error) {
16			return null;
17		}
18	}
19
20	function splitValues(value) {
21		return String(value || '')
22			.split(',')
23			.map(function (item) {
24				return item.trim();
25			})
26			.filter(Boolean);
27	}
28
29	function parseNumber(value) {
30		var parsed = parseFloat(String(value || '').replace(/[^0-9.-]/g, ''));
31
32		return Number.isNaN(parsed) ? null : parsed;
33	}
34
35	function formatDecimal(value) {
36		return String(Math.round(value * 100) / 100);
37	}
38
39	function snapPriceValue(value) {
40		return Math.round(value / PRICE_STEP) * PRICE_STEP;
41	}
42
43	function formatPrice(value) {
44		var rounded = Math.round(value * 100) / 100;
45
46		return '$' + rounded.toLocaleString(undefined, {
47			minimumFractionDigits: Number.isInteger(rounded) ? 0 : 2,
48			maximumFractionDigits: 2
49		});
50	}
51
52	function cleanSearchValue(value) {
53		return String(value || '').trim().slice(0, 100);
54	}
55
56	function normalizeSearchValue(value) {
57		var cleaned = cleanSearchValue(value);
58
59		return Array.from(cleaned).length >= SEARCH_MIN_LENGTH ? cleaned : '';
60	}
61
62	function WineListingController(block) {
63		this.block = block;
64		this.config = parseConfig(block);
65		this.form = block.querySelector('.js-foley-c7-ui-form');
66		this.searchInput = block.querySelector('.js-foley-c7-ui-search-input');
67		this.itemsContainer = block.querySelector('.js-foley-c7-ui-items');
68		this.navigationContainer = block.querySelector('.js-foley-c7-ui-navigation');
69		this.statusNode = block.querySelector('.js-foley-c7-ui-status');
70		this.restUrl = (window.FoleyC7UiWineProductListingView || {}).restUrl || '';
71		this.searchDebounceTimer = null;
72		this.abortController = null;
73		this.requestSequence = 0;
74	}
75
76	WineListingController.prototype.getEmptyState = function (page) {
77		return {
78			filters: {},
79			search: '',
80			priceRange: null,
81			ninetyPlus: false,
82			sort: '',
83			perPage: this.getDefaultPerPage(),
84			page: page || 1
85		};
86	};
87
88	WineListingController.prototype.readStateFromUrl = function () {
89		var stateConfig = this.config.stateConfig || {};
90		var url = new URL(window.location.href);
91		var state = this.getEmptyState(1);
92		var page = parseInt(url.searchParams.get(stateConfig.page || '') || '1', 10);
93		var perPage = parseInt(url.searchParams.get(stateConfig.perPage || '') || '', 10);
94		var priceKeys = stateConfig.priceRange || {};
95		var priceMin = priceKeys.min ? url.searchParams.get(priceKeys.min) : null;
96		var priceMax = priceKeys.max ? url.searchParams.get(priceKeys.max) : null;
97		var ninetyPlusValue = stateConfig.ninetyPlus ? url.searchParams.get(stateConfig.ninetyPlus) : '';
98		var searchValue = stateConfig.search ? url.searchParams.get(stateConfig.search) : '';
99
100		Object.keys(stateConfig.filters || {}).forEach(function (taxonomy) {
101			var queryKey = stateConfig.filters[taxonomy];
102			var values = splitValues(queryKey ? url.searchParams.get(queryKey) : '');
103
104			if (values.length) {
105				state.filters[taxonomy] = values;
106			}
107		});
108
109		if (priceMin !== null || priceMax !== null) {
110			state.priceRange = {
111				min: priceMin !== null ? parseNumber(priceMin) : null,
112				max: priceMax !== null ? parseNumber(priceMax) : null
113			};
114		}
115
116		state.ninetyPlus = ['1', 'true', 'yes', 'on'].indexOf(String(ninetyPlusValue || '').toLowerCase()) > -1;
117		state.search = normalizeSearchValue(searchValue);
118		state.sort = url.searchParams.get(stateConfig.sort || '') || '';
119		state.perPage = Number.isNaN(perPage) || perPage < 1 ? this.getDefaultPerPage() : perPage;
120		state.page = Number.isNaN(page) || page < 1 ? 1 : page;
121
122		return state;
123	};
124
125	WineListingController.prototype.init = function () {
126		if (!this.config || !this.restUrl) {
127			return;
128		}
129
130		this.syncControlsFromUrl();
131		this.syncHiddenInputs();
132		this.bindEvents();
133	};
134
135	WineListingController.prototype.bindEvents = function () {
136		var self = this;
137
138		if (this.form) {
139			this.form.addEventListener('submit', function (event) {
140				event.preventDefault();
141				self.cancelSearchDebounce();
142
143				if (
144					event.submitter
145					&& event.submitter.classList.contains('js-foley-c7-ui-search-submit')
146					&& !normalizeSearchValue(self.searchInput ? self.searchInput.value : '')
147				) {
148					return;
149				}
150
151				self.submit(self.buildState(1), false, true);
152			});
153
154			this.form.addEventListener('change', function (event) {
155				if (event.target.closest('.js-foley-c7-ui-search-input')) {
156					return;
157				}
158
159				self.syncHiddenInputs();
160				self.submit(self.buildState(1), false, true);
161			});
162
163			var resetButton = this.form.querySelector('.js-foley-c7-ui-reset');
164
165				if (resetButton) {
166					resetButton.addEventListener('click', function (event) {
167						event.preventDefault();
168						self.resetControls();
169						self.submit(self.buildState(1, true), false, true);
170					});
171				}
172			}
173
174		if (this.searchInput) {
175			this.searchInput.addEventListener('input', function () {
176				self.handleSearchInput();
177			});
178
179			this.searchInput.addEventListener('keydown', function (event) {
180				if (event.key !== 'Enter') {
181					return;
182				}
183
184				event.preventDefault();
185				self.submitSearchImmediately();
186			});
187		}
188
189		var perPageSelect = this.block.querySelector('.js-foley-c7-ui-per-page');
190		if (perPageSelect) {
191			perPageSelect.addEventListener('change', function () {
192				self.submit(self.buildState(1), false, true);
193			});
194		}
195
196		var sortSelect = this.block.querySelector('.js-foley-c7-ui-sort');
197		if (sortSelect) {
198			sortSelect.addEventListener('change', function () {
199				self.submit(self.buildState(1), false, true);
200			});
201		}
202
203		this.block.addEventListener('click', function (event) {
204			var paginationLink = event.target.closest('.foley-c7-ui-wine-listing__page');
205			var loadMoreLink = event.target.closest('.js-foley-c7-ui-load-more');
206
207			if (paginationLink) {
208				event.preventDefault();
209				self.submit(self.buildState(parseInt(paginationLink.getAttribute('data-page') || '1', 10)), false, true);
210			}
211
212			if (loadMoreLink) {
213				event.preventDefault();
214				self.submit(self.buildState(parseInt(loadMoreLink.getAttribute('data-page') || '1', 10)), true, true);
215			}
216		});
217
218		this.block.addEventListener('pointerdown', function (event) {
219			var priceTarget = event.target.closest('.js-foley-c7-ui-price-handle, .js-foley-c7-ui-price-track');
220
221			if (!priceTarget) {
222				return;
223			}
224
225			self.startPriceDrag(event, priceTarget);
226		});
227
228		this.block.addEventListener('keydown', function (event) {
229			var handle = event.target.closest('.js-foley-c7-ui-price-handle');
230
231			if (!handle) {
232				return;
233			}
234
235			self.handlePriceKeydown(event, handle);
236		});
237	};
238
239	WineListingController.prototype.cancelSearchDebounce = function () {
240		if (this.searchDebounceTimer) {
241			window.clearTimeout(this.searchDebounceTimer);
242			this.searchDebounceTimer = null;
243		}
244	};
245
246	WineListingController.prototype.handleSearchInput = function () {
247		var self = this;
248		var rawValue = cleanSearchValue(this.searchInput ? this.searchInput.value : '');
249
250		this.cancelSearchDebounce();
251
252		if (rawValue === '') {
253			if (this.readStateFromUrl().search !== '') {
254				this.submit(this.buildState(1), false, true);
255			}
256
257			return;
258		}
259
260		if (!normalizeSearchValue(rawValue)) {
261			return;
262		}
263
264		this.searchDebounceTimer = window.setTimeout(function () {
265			self.searchDebounceTimer = null;
266			self.submit(self.buildState(1), false, true);
267		}, SEARCH_DEBOUNCE_DELAY);
268	};
269
270	WineListingController.prototype.submitSearchImmediately = function () {
271		var search = normalizeSearchValue(this.searchInput ? this.searchInput.value : '');
272
273		this.cancelSearchDebounce();
274
275		if (!search) {
276			return;
277		}
278
279		this.submit(this.buildState(1), false, true);
280	};
281
282	WineListingController.prototype.handlePopState = function () {
283		if (!this.config || !this.restUrl) {
284			return;
285		}
286
287		this.syncControlsFromUrl();
288		this.syncHiddenInputs();
289		this.submit(this.buildState(this.getPageFromUrl()), false, false);
290	};
291
292	WineListingController.prototype.resetControls = function () {
293		if (!this.form) {
294			return;
295		}
296
297		this.block.querySelectorAll('.foley-c7-ui-wine-listing__control[data-taxonomy]').forEach(function (control) {
298			var type = control.getAttribute('data-control-type');
299
300			if (type === 'checkbox' || type === 'radio') {
301				control.querySelectorAll('input[type="checkbox"], input[type="radio"]').forEach(function (input) {
302					input.checked = false;
303				});
304
305				if (type === 'radio') {
306					var allRadio = control.querySelector('input[type="radio"][value=""]');
307
308					if (allRadio) {
309						allRadio.checked = true;
310					}
311				}
312			}
313
314			if (type === 'select') {
315				var select = control.querySelector('select');
316				if (select) {
317					select.value = '';
318				}
319			}
320
321			if (type === 'multiselect') {
322				var multiSelect = control.querySelector('select');
323				if (multiSelect) {
324					Array.from(multiSelect.options).forEach(function (option) {
325						option.selected = false;
326					});
327				}
328			}
329		});
330
331		this.block.querySelectorAll('.js-foley-c7-ui-price-control').forEach(function (control) {
332			this.setPriceRangeControl(control, this.getPriceBounds());
333		}, this);
334
335		this.block.querySelectorAll('.js-foley-c7-ui-ninety-plus').forEach(function (input) {
336			input.checked = false;
337		});
338
339		this.cancelSearchDebounce();
340		if (this.searchInput) {
341			this.searchInput.value = '';
342		}
343
344		var sortSelect = this.block.querySelector('.js-foley-c7-ui-sort');
345		if (sortSelect) {
346			sortSelect.value = '';
347		}
348
349		var perPageSelect = this.block.querySelector('.js-foley-c7-ui-per-page');
350		if (perPageSelect) {
351			perPageSelect.value = String(this.getDefaultPerPage());
352		}
353
354		this.syncHiddenInputs();
355	};
356
357	WineListingController.prototype.getPriceBounds = function () {
358		var bounds = this.config.priceBounds || {};
359		var minimum = parseNumber(bounds.min);
360		var maximum = parseNumber(bounds.max);
361
362		if (minimum === null || maximum === null) {
363			return null;
364		}
365
366		return {
367			min: Math.min(minimum, maximum),
368			max: Math.max(minimum, maximum)
369		};
370	};
371
372	WineListingController.prototype.getDefaultPerPage = function () {
373		var attributes = this.config.attributes || {};
374		var perPage = parseInt(attributes.itemsPerPage || '12', 10);
375
376		return Number.isNaN(perPage) || perPage < 1 ? 12 : perPage;
377	};
378
379	WineListingController.prototype.normalizePriceRange = function (range) {
380		var bounds = this.getPriceBounds();
381
382		if (!bounds) {
383			return null;
384		}
385
386		var minimum = range && range.min !== null && range.min !== undefined ? parseNumber(range.min) : null;
387		var maximum = range && range.max !== null && range.max !== undefined ? parseNumber(range.max) : null;
388
389		minimum = minimum === null ? bounds.min : minimum;
390		maximum = maximum === null ? bounds.max : maximum;
391		minimum = Math.min(Math.max(minimum, bounds.min), bounds.max);
392		maximum = Math.min(Math.max(maximum, bounds.min), bounds.max);
393
394		if (minimum > maximum) {
395			var nextMinimum = maximum;
396			maximum = minimum;
397			minimum = nextMinimum;
398		}
399
400		return {
401			min: Math.round(minimum * 100) / 100,
402			max: Math.round(maximum * 100) / 100
403		};
404	};
405
406	WineListingController.prototype.isDefaultPriceRange = function (range) {
407		var bounds = this.getPriceBounds();
408		var normalized = this.normalizePriceRange(range);
409
410		if (!bounds || !normalized) {
411			return true;
412		}
413
414		return Math.abs(normalized.min - bounds.min) < 0.01
415			&& Math.abs(normalized.max - bounds.max) < 0.01;
416	};
417
418	WineListingController.prototype.setPriceRangeControl = function (control, range) {
419		var normalized = this.normalizePriceRange(range);
420		var bounds = this.getPriceBounds();
421
422		if (!normalized || !bounds) {
423			return null;
424		}
425
426		var minInput = control.querySelector('.js-foley-c7-ui-price-min-input');
427		var maxInput = control.querySelector('.js-foley-c7-ui-price-max-input');
428		var minLabel = control.querySelector('.js-foley-c7-ui-price-min-label');
429		var maxLabel = control.querySelector('.js-foley-c7-ui-price-max-label');
430		var minHandle = control.querySelector('.js-foley-c7-ui-price-min-handle');
431		var maxHandle = control.querySelector('.js-foley-c7-ui-price-max-handle');
432		var span = bounds.max - bounds.min || 1;
433		var minPosition = ((normalized.min - bounds.min) / span) * 100;
434		var maxPosition = ((normalized.max - bounds.min) / span) * 100;
435
436		control.style.setProperty('--price-min-position', minPosition + '%');
437		control.style.setProperty('--price-max-position', maxPosition + '%');
438
439		if (minInput) {
440			minInput.value = formatDecimal(normalized.min);
441		}
442
443		if (maxInput) {
444			maxInput.value = formatDecimal(normalized.max);
445		}
446
447		if (minLabel) {
448			minLabel.textContent = formatPrice(normalized.min);
449		}
450
451		if (maxLabel) {
452			maxLabel.textContent = formatPrice(normalized.max);
453		}
454
455		if (minHandle) {
456			minHandle.setAttribute('aria-valuemin', formatDecimal(bounds.min));
457			minHandle.setAttribute('aria-valuemax', formatDecimal(normalized.max));
458			minHandle.setAttribute('aria-valuenow', formatDecimal(normalized.min));
459			minHandle.setAttribute('aria-valuetext', formatPrice(normalized.min));
460		}
461
462		if (maxHandle) {
463			maxHandle.setAttribute('aria-valuemin', formatDecimal(normalized.min));
464			maxHandle.setAttribute('aria-valuemax', formatDecimal(bounds.max)
464);
465			maxHandle.setAttribute('aria-valuenow', formatDecimal(normalized.max));
466			maxHandle.setAttribute('aria-valuetext', formatPrice(normalized.max));
467		}
468
469		return normalized;
470	};
471
472	WineListingController.prototype.getCurrentPriceRange = function (control) {
473		var minInput = control.querySelector('.js-foley-c7-ui-price-min-input');
474		var maxInput = control.querySelector('.js-foley-c7-ui-price-max-input');
475
476		return this.normalizePriceRange({
477			min: minInput ? minInput.value : null,
478			max: maxInput ? maxInput.value : null
479		});
480	};
481
482	WineListingController.prototype.syncPriceRangeControl = function (control, changedHandle) {
483		var current = this.getCurrentPriceRange(control);
484
485		if (!current) {
486			return null;
487		}
488
489		var minimum = current.min;
490		var maximum = current.max;
491
492		if (minimum !== null && maximum !== null && minimum > maximum) {
493			if (changedHandle && changedHandle.getAttribute('data-price-handle') === 'min') {
494				minimum = maximum;
495			} else {
496				maximum = minimum;
497			}
498		}
499
500		return this.setPriceRangeControl(control, {
501			min: minimum,
502			max: maximum
503		});
504	};
505
506	WineListingController.prototype.priceValueFromPointer = function (control, clientX) {
507		var bounds = this.getPriceBounds();
508		var track = control.querySelector('.js-foley-c7-ui-price-track');
509
510		if (!bounds || !track) {
511			return null;
512		}
513
514		var rect = track.getBoundingClientRect();
515		var ratio = rect.width > 0 ? (clientX - rect.left) / rect.width : 0;
516		var value = bounds.min + (Math.min(Math.max(ratio, 0), 1) * (bounds.max - bounds.min));
517
518		return snapPriceValue(value);
519	};
520
521	WineListingController.prototype.getNearestPriceHandle = function (control, clientX) {
522		var value = this.priceValueFromPointer(control, clientX);
523		var current = this.getCurrentPriceRange(control);
524
525		if (value === null || !current) {
526			return control.querySelector('.js-foley-c7-ui-price-min-handle');
527		}
528
529		var minHandle = control.querySelector('.js-foley-c7-ui-price-min-handle');
530		var maxHandle = control.querySelector('.js-foley-c7-ui-price-max-handle');
531
532		return Math.abs(value - current.min) <= Math.abs(value - current.max)
533			? minHandle
534			: maxHandle;
535	};
536
537	WineListingController.prototype.setPriceHandleValue = function (control, handle, value) {
538		var current = this.getCurrentPriceRange(control);
539
540		if (!current || value === null || !handle) {
541			return null;
542		}
543
544		value = snapPriceValue(value);
545
546		if (handle.getAttribute('data-price-handle') === 'min') {
547			current.min = Math.min(value, current.max);
548		} else {
549			current.max = Math.max(value, current.min);
550		}
551
552		return this.setPriceRangeControl(control, current);
553	};
554
555	WineListingController.prototype.startPriceDrag = function (event, target) {
556		var self = this;
557		var control = target.closest('.js-foley-c7-ui-price-control');
558		var handle = target.classList.contains('js-foley-c7-ui-price-handle')
559			? target
560			: this.getNearestPriceHandle(control, event.clientX);
561
562		if (!control || !handle) {
563			return;
564		}
565
566		event.preventDefault();
567		handle.focus();
568		this.setPriceHandleValue(control, handle, this.priceValueFromPointer(control, event.clientX));
569
570		var onMove = function (moveEvent) {
571			self.setPriceHandleValue(control, handle, self.priceValueFromPointer(control, moveEvent.clientX));
572		};
573
574		var onUp = function () {
575			document.removeEventListener('pointermove', onMove);
576			document.removeEventListener('pointerup', onUp);
577			document.removeEventListener('pointercancel', onUp);
578			self.syncHiddenInputs();
579			self.submit(self.buildState(1), false, true);
580		};
581
582		document.addEventListener('pointermove', onMove);
583		document.addEventListener('pointerup', onUp);
584		document.addEventListener('pointercancel', onUp);
585	};
586
587	WineListingController.prototype.handlePriceKeydown = function (event, handle) {
588		var control = handle.closest('.js-foley-c7-ui-price-control');
589		var bounds = this.getPriceBounds();
590		var current = control ? this.getCurrentPriceRange(control) : null;
591
592		if (!control || !bounds || !current) {
593			return;
594		}
595
596		var step = PRICE_STEP;
597		var value = handle.getAttribute('data-price-handle') === 'min' ? current.min : current.max;
598
599		if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') {
600			value -= step;
601		} else if (event.key === 'ArrowRight' || event.key === 'ArrowUp') {
602			value += step;
603		} else if (event.key === 'PageDown') {
604			value -= step * 10;
605		} else if (event.key === 'PageUp') {
606			value += step * 10;
607		} else if (event.key === 'Home') {
608			value = bounds.min;
609		} else if (event.key === 'End') {
610			value = bounds.max;
611		} else {
612			return;
613		}
614
615		event.preventDefault();
616		this.setPriceHandleValue(control, handle, value);
617		this.syncHiddenInputs();
618		this.submit(this.buildState(1), false, true);
619	};
620
621	WineListingController.prototype.getPriceRangeState = function () {
622		var control = this.block.querySelector('.js-foley-c7-ui-price-control');
623
624		if (!control) {
625			return null;
626		}
627
628		return this.syncPriceRangeControl(control);
629	};
630
631	WineListingController.prototype.getSelectedValues = function (control) {
632		var type = control.getAttribute('data-control-type');
633
634		if (type === 'checkbox') {
635			return Array.from(control.querySelectorAll('input[type="checkbox"]:checked')).map(function (input) {
636				return input.value;
637			});
638		}
639
640		if (type === 'radio') {
641			var checked = control.querySelector('input[type="radio"]:checked');
642			return checked && checked.value ? [checked.value] : [];
643		}
644
645		if (type === 'multiselect') {
646			var multiSelect = control.querySelector('select');
647
648			return multiSelect
649				? Array.from(multiSelect.options).filter(function (option) {
650					return option.selected;
651				}).map(function (option) {
652					return option.value;
653				})
654				: [];
655		}
656
657		var select = control.querySelector('select');
658		return select && select.value ? [select.value] : [];
659	};
660
661	WineListingController.prototype.syncHiddenInputs = function () {
662		this.block.querySelectorAll('.foley-c7-ui-wine-listing__control[data-taxonomy]').forEach(function (control) {
663			var hiddenInput = control.querySelector('.js-foley-c7-ui-hidden-input');
664
665			if (!hiddenInput) {
666				return;
667			}
668
669			hiddenInput.value = this.getSelectedValues(control).join(',');
670		}, this);
671
672		this.block.querySelectorAll('.js-foley-c7-ui-price-control').forEach(function (control) {
673			this.syncPriceRangeControl(control);
674		}, this);
675	};
676
677	WineListingController.prototype.buildState = function (page, clearUrlState) {
678		var state = clearUrlState ? this.getEmptyState(page || 1) : this.readStateFromUrl();
679		state.page = page || 1;
680
681		this.block.querySelectorAll('.foley-c7-ui-wine-listing__control[data-taxonomy]').forEach(function (control) {
682			var taxonomy = control.getAttribute('data-taxonomy');
683			var values = this.getSelectedValues(control);
684
685			if (taxonomy) {
686				state.filters[taxonomy] = values;
687			}
688		}, this);
689
690		if (this.form) {
691			if (this.searchInput) {
692				state.search = normalizeSearchValue(this.searchInput.value);
693			}
694
695			if (this.block.querySelector('.js-foley-c7-ui-price-control')) {
696				state.priceRange = this.getPriceRangeState();
697			}
698
699			var ninetyPlus = this.form.querySelector('.js-foley-c7-ui-ninety-plus');
700			if (ninetyPlus) {
701				state.ninetyPlus = !!ninetyPlus.checked;
702			}
703
704		}
705
706		var sortSelect = this.block.querySelector('.js-foley-c7-ui-sort');
707		if (sortSelect) {
708			state.sort = sortSelect.value || '';
709		}
710
711		if (this.block.getAttribute('data-navigation-mode') === 'pagination') {
712			var perPageSelect = this.block.querySelector('.js-foley-c7-ui-per-page');
713			var perPage = perPageSelect ? parseInt(perPageSelect.value || '', 10) : this.getDefaultPerPage();
714
715			state.perPage = Number.isNaN(perPage) || perPage < 1 ? this.getDefaultPerPage() : perPage;
716		}
717
718		if (!this.block.getAttribute('data-navigation-mode') || this.block.getAttribute('data-navigation-mode') === 'none') {
719			state.page = 1;
720		}
721
722		return state;
723	};
724
725	WineListingController.prototype.getPageFromUrl = function () {
726		return this.readStateFromUrl().page;
727	};
728
729	WineListingController.prototype.syncControlsFromUrl = function () {
730		if (!this.config) {
731			return;
732		}
733
734		var stateConfig = this.config.stateConfig || {};
735		var url = new URL(window.location.href);
736
737		if (this.searchInput) {
738			this.searchInput.value = normalizeSearchValue(stateConfig.search ? url.searchParams.get(stateConfig.search) : '');
739		}
740
741		this.block.querySelectorAll('.foley-c7-ui-wine-listing__control[data-taxonomy]').forEach(function (control) {
742			var taxonomy = control.getAttribute('data-taxonomy');
743			var type = control.getAttribute('data-control-type');
744			var queryKey = (stateConfig.filters || {})[taxonomy];
745			var values = splitValues(url.searchParams.get(queryKey || ''));
746
747			if (type === 'checkbox') {
748				control.querySelectorAll('input[type="checkbox"]').forEach(function (input) {
749					input.checked = values.indexOf(input.value) > -1;
750				});
751			}
752
753			if (type === 'radio') {
754				control.querySelectorAll('input[type="radio"]').forEach(function (input) {
755					input.checked = values.length
756						? values.indexOf(input.value) > -1
757						: input.value === '';
758				});
759			}
760
761			if (type === 'select') {
762				var select = control.querySelector('select');
763				if (select) {
764					select.value = values[0] || '';
765				}
766			}
767
768			if (type === 'multiselect') {
769				var multiSelect = control.querySelector('select');
770				if (multiSelect) {
771					Array.from(multiSelect.options).forEach(function (option) {
772						option.selected = values.indexOf(option.value) > -1;
773					});
774				}
775			}
776		});
777
778		this.block.querySelectorAll('.js-foley-c7-ui-price-control').forEach(function (control) {
779			var priceKeys = stateConfig.priceRange || {};
780			var minimum = priceKeys.min ? parseNumber(url.searchParams.get(priceKeys.min)) : null;
781			var maximum = priceKeys.max ? parseNumber(url.searchParams.get(priceKeys.max)) : null;
782
783			this.setPriceRangeControl(control, {
784				min: minimum,
785				max: maximum
786			});
787		}, this);
788
789		var ninetyPlus = this.form ? this.form.querySelector('.js-foley-c7-ui-ninety-plus') : null;
790		if (ninetyPlus) {
791			var ninetyPlusValue = stateConfig.ninetyPlus ? url.searchParams.get(stateConfig.ninetyPlus) : '';
792			ninetyPlus.checked = ['1', 'true', 'yes', 'on'].indexOf(String(ninetyPlusValue || '').toLowerCase()) > -1;
793		}
794
795		var sortSelect = this.block.querySelector('.js-foley-c7-ui-sort');
796		if (sortSelect) {
797			sortSelect.value = url.searchParams.get(stateConfig.sort || '') || '';
798		}
799
800		var perPageSelect = this.block.querySelector('.js-foley-c7-ui-per-page');
801		if (perPageSelect) {
802			var perPageValue = stateConfig.perPage ? url.searchParams.get(stateConfig.perPage) : '';
803			var selectedPerPage = perPageValue || String(this.getDefaultPerPage());
804			var hasPerPageOption = Array.from(perPageSelect.options).some(function (option) {
805				return option.value === selectedPerPage;
806			});
807
808			perPageSelect.value = hasPerPageOption ? selectedPerPage : String(this.getDefaultPerPage());
809		}
810	};
811
812	WineListingController.prototype.buildUrl = function (state) {
813		var stateConfig = this.config.stateConfig || {};
814		var url = new URL(window.location.href);
815		var normalizedPriceRange = this.normalizePriceRange(state.priceRange);
816
817		[stateConfig.search, stateConfig.sort, stateConfig.page, stateConfig.perPage].forEach(function (queryKey) {
818			if (queryKey) {
819				url.searchParams.delete(queryKey);
820			}
821		});
822
823		Object.keys(stateConfig.filters || {}).forEach(function (taxonomy) {
824			url.searchParams.delete(stateConfig.filters[taxonomy]);
825		});
826
827		Object.keys(stateConfig.priceRange || {}).forEach(function (key) {
828			url.searchParams.delete(stateConfig.priceRange[key]);
829		});
830
831		if (stateConfig.ninetyPlus) {
832			url.searchParams.delete(stateConfig.ninetyPlus);
833		}
834
835		Array.from(url.searchParams.keys()).forEach(function (queryKey) {
836			if (queryKey.indexOf('c7ui_wine_listing_') === 0) {
837				url.searchParams.delete(queryKey);
838			}
839		});
840
841		Object.keys(state.filters || {}).forEach(function (taxonomy) {
842			var values = state.filters[taxonomy];
843			var queryKey = (stateConfig.filters || {})[taxonomy];
844
845			if (queryKey && values && values.length) {
846				url.searchParams.set(queryKey, values.join(','));
847			}
848		});
849
850		if (normalizedPriceRange && !this.isDefaultPriceRange(normalizedPriceRange)) {
851			if (stateConfig.priceRange && stateConfig.priceRange.min && stateConfig.priceRange.max) {
852				url.searchParams.set(stateConfig.priceRange.min, formatDecimal(normalizedPriceRange.min));
853				url.searchParams.set(stateConfig.priceRange.max, formatDecimal(normalizedPriceRange.max));
854			}
855		}
856
857		if (state.ninetyPlus && stateConfig.ninetyPlus) {
858			url.searchParams.set(stateConfig.ninetyPlus, '1');
859		}
860
861		if (state.search && stateConfig.search) {
862			url.searchParams.set(stateConfig.search, state.search);
863		}
864
865		if (state.sort) {
866			url.searchParams.set(stateConfig.sort, state.sort);
867		}
868
869		if (stateConfig.perPage && state.perPage && state.perPage !== this.getDefaultPerPage()) {
870			url.searchParams.set(stateConfig.perPage, String(state.perPage));
871		}
872
873		if (state.page > 1) {
874			url.searchParams.set(stateConfig.page, String(state.page));
875		}
876
877		return url;
878	};
879
880	WineListingController.prototype.setLoading = function (isLoading) {
881		this.block.classList.toggle('is-loading', !!isLoading);
882
883		if (this.statusNode) {
884			this.statusNode.textContent = isLoading
885				? ((window.FoleyC7UiWineProductListingView || {}).i18n || {}).loading || 'Loading'
886				: '';
887		}
888	};
889
890	WineListingController.prototype.request = function (state, appendMode, signal) {
891		return fetch(this.restUrl, {
892			method: 'POST',
893			headers: {
894				'Content-Type': 'application/json'
895			},
896			signal: signal,
897			body: JSON.stringify({
898				attributes: this.config.attributes || {},
899				state: state,
900				append: !!appendMode
901			})
902		}).then(function (response) {
903			return response.json();
904		});
905	};
906
907	WineListingController.prototype.emitListImpression = function (startIndex, reset) {
908		var analytics = window.foleyC7UiGa4Analytics;
909
910		if (!analytics || typeof analytics.emitViewItemList !== 'function') {
911			return;
912		}
913
914		analytics.emitViewItemList(this.block, {
915			startIndex: startIndex,
916			reset: !!reset
917		});
918	};
919
920	WineListingController.prototype.updateDom = function (payload, appendMode) {
921		if (!this.itemsContainer || !this.navigationContainer) {
922			return;
923		}
924
925		var startIndex = appendMode
926			? this.itemsContainer.querySelectorAll('.foley-c7-ui-wine-card[data-ga4-item-id]').length
927			: 0;
928
929		if (appendMode && payload.itemsHtml) {
930			this.itemsContainer.insertAdjacentHTML('beforeend', payload.itemsHtml);
931		} else {
932			this.itemsContainer.innerHTML = payload.itemsHtml || payload.emptyHtml || '';
933		}
934
935		this.navigationContainer.innerHTML = payload.navigationHtml || '';
936		this.emitListImpression(startIndex, !appendMode);
937	};
938
939	WineListingController.prototype.submit = function (state, appendMode, pushState) {
940		var self = this;
941		var url = this.buildUrl(state);
942		var requestSequence = ++this.requestSequence;
943
944		if (this.abortController) {
945			this.abortController.abort();
946		}
947
948		this.abortController = typeof window.AbortController === 'function'
949			? new window.AbortController()
950			: null;
951
952		if (pushState) {
953			window.history.pushState({}, '', url);
954		}
955
956		this.setLoading(true);
957
958		this.request(state, appendMode, this.abortController ? this.abortController.signal : undefined)
959			.then(function (payload) {
960				if (requestSequence === self.requestSequence) {
961					self.updateDom(payload, appendMode);
962				}
963			})
964			.catch(function (error) {
965				if (!error || error.name !== 'AbortError') {
966					window.console.error('Wine Product Listing request failed.', error);
967				}
968			})
969			.finally(function () {
970				if (requestSequence === self.requestSequence) {
971					self.abortController = null;
972					self.setLoading(false);
973				}
974			});
975	};
976
977	var controllers = [];
978
979	document.addEventListener('DOMContentLoaded', function () {
980		document.querySelectorAll('.js-foley-c7-ui-wine-listing').forEach(function (block) {
981			var controller = new WineListingController(block);
982			controller.init();
983			controller.emitListImpression(0, true);
984			controllers.push(controller);
985		});
986	});
987
988	window.addEventListener('popstate', function () {
989		controllers.forEach(function (controller) {
990			controller.handlePopState();
991		});
992	});
993})();
994;
995/*! This file is auto-generated */
996(function() {
997"use strict";var wp;(wp||={}).domReady=(()=>{var o=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var f=(e,t)=>{for(var n in t)o(e,n,{get:t[n],enumerable:!0})},m=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let d of a(t))!i.call(e,d)&&d!==n&&o(e,d,{get:()=>t[d],enumerable:!(r=u(t,d))||r.enumerable});return e};var c=e=>m(o({},"__esModule",{value:!0}),e);var p={};f(p,{default:()=>y});function y(e){if(!(typeof document>"u")){if(document.readyState==="complete"||document.readyState==="interactive")return void e();document.addEventListener("DOMContentLoaded",e)}}return c(p);})();
998if (typeof wp.domReady === 'object' && wp.domReady.default) { wp.domReady = wp.domReady.default; }
999(window.wp ||= {}).domReady = wp.domReady;
1000})();
1001;
1002/*! This file is auto-generated */
1003(function() {
1004"use strict";var wp;(wp||={}).hooks=(()=>{var v=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var w=(e,n)=>{for(var s in n)v(e,s,{get:n[s],enumerable:!0})},D=(e,n,s,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of g(n))!I.call(e,t)&&t!==s&&v(e,t,{get:()=>n[t],enumerable:!(r=S(n,t))||r.enumerable});return e};var T=e=>D(v({},"__esModule",{value:!0}),e);var le={};w(le,{actions:()=>ae,addAction:()=>J,addFilter:()=>K,applyFilters:()=>N,applyFiltersAsync:()=>ee,createHooks:()=>F,currentAction:()=>te,currentFilter:()=>re,defaultHooks:()=>b,didAction:()=>ie,didFilter:()=>se,doAction:()=>X,doActionAsync:()=>Y,doingAction:()=>ne,doingFilter:()=>oe,filters:()=>ce,hasAction:()=>P,hasFilter:()=>Q,removeAction:()=>L,removeAllActions:()=>U,removeAllFilters:()=>W,removeFilter:()=>M});function z(e){return typeof e!="string"||e===""?(console.error("The namespace must be a non-empty string."),!1):/^[a-zA-Z][a-zA-Z0-9_.\-\/]*$/.test(e)?!0:(console.error("The namespace can only contain numbers, letters, dashes, periods, underscores and slashes."),!1)}var m=z;function E(e){return typeof e!="string"||e===""?(console.error("The hook name must be a non-empty string."),!1):/^__/.test(e)?(console.error("The hook name cannot begin with `__`."),!1):/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(e)?!0:(console.error("The hook name can only contain numbers, letters, dashes, periods and underscores."),!1)}var f=E;function Z(e,n){return function(r,t,a,i=10){let c=e[n];if(!f(r)||!m(t))return;if(typeof a!="function"){console.error("The hook callback must be a function.");return}if(typeof i!="number"){console.error("If specified, the hook priority must be a number.");return}let l={callback:a,priority:i,namespace:t};if(c[r]){let o=c[r].handlers,d;for(d=o.length;d>0&&!(i>=o[d-1].priority);d--);d===o.length?o[d]=l:o.splice(d,0,l),c.__current.forEach(h=>{h.name===r&&h.currentIndex>=d&&h.currentIndex++})}else c[r]={handlers:[l],runs:0};r!=="hookAdded"&&e.doAction("hookAdded",r,t,a,i)}}var H=Z;function C(e,n,s=!1){return function(t,a){let i=e[n];if(!f(t)||!s&&!m(a))return;if(!i[t])return 0;let c=0;if(s)c=i[t].handlers.length,i[t]={runs:i[t].runs,handlers:[]};else{let l=i[t].handlers;for(let o=l.length-1;o>=0;o--)l[o].namespace===a&&(l.splice(o,1),c++,i.__current.forEach(d=>{d.name===t&&d.currentIndex>=o&&d.currentIndex--}))}return t!=="hookRemoved"&&e.doAction("hookRemoved",t,a),c}}var p=C;function O(e,n){return function(r,t){let a=e[n];return typeof t<"u"?r in a&&a[r].handlers.some(i=>i.namespace===t):r in a}}var _=O;function j(e,n,s,r){return function(a,...i){let c=e[n];c[a]||(c[a]={handlers:[],runs:0}),c[a].runs++;let l=c[a].handlers;if(!l||!l.length)return s?i[0]:void 0;let o={name:a,currentIndex:0};async function d(){try{c.__current.add(o);let u=s?i[0]:void 0;for(;o.currentIndex<l.length;
1004)u=await l[o.currentIndex].callback.apply(null,i),s&&(i[0]=u),o.currentIndex++;return s?u:void 0}finally{c.__current.delete(o)}}function h(){try{c.__current.add(o);let u=s?i[0]:void 0;for(;o.currentIndex<l.length;)u=l[o.currentIndex].callback.apply(null,i),s&&(i[0]=u),o.currentIndex++;return s?u:void 0}finally{c.__current.delete(o)}}return(r?d:h)()}}var A=j;function $(e,n){return function(){let r=e[n];return Array.from(r.__current).at(-1)?.name??null}}var y=$;function V(e,n){return function(r){let t=e[n];return typeof r>"u"?t.__current.size>0:Array.from(t.__current).some(a=>a.name===r)}}var k=V;function q(e,n){return function(r){let t=e[n];if(f(r))return t[r]&&t[r].runs?t[r].runs:0}}var x=q;var B=class{actions;filters;addAction;addFilter;removeAction;removeFilter;hasAction;hasFilter;removeAllActions;removeAllFilters;doAction;doActionAsync;applyFilters;applyFiltersAsync;currentAction;currentFilter;doingAction;doingFilter;didAction;didFilter;constructor(){this.actions=Object.create(null),this.actions.__current=new Set,this.filters=Object.create(null),this.filters.__current=new Set,this.addAction=H(this,"actions"),this.addFilter=H(this,"filters"),this.removeAction=p(this,"actions"),this.removeFilter=p(this,"filters"),this.hasAction=_(this,"actions"),this.hasFilter=_(this,"filters"),this.removeAllActions=p(this,"actions",!0),this.removeAllFilters=p(this,"filters",!0),this.doAction=A(this,"actions",!1,!1),this.doActionAsync=A(this,"actions",!1,!0),this.applyFilters=A(this,"filters",!0,!1),this.applyFiltersAsync=A(this,"filters",!0,!0),this.currentAction=y(this,"actions"),this.currentFilter=y(this,"filters"),this.doingAction=k(this,"actions"),this.doingFilter=k(this,"filters"),this.didAction=x(this,"actions"),this.didFilter=x(this,"filters")}};function G(){return new B}var F=G;var b=F(),{addAction:J,addFilter:K,removeAction:L,removeFilter:M,hasAction:P,hasFilter:Q,removeAllActions:U,removeAllFilters:W,doAction:X,doActionAsync:Y,applyFilters:N,applyFiltersAsync:ee,currentAction:te,currentFilter:re,doingAction:ne,doingFilter:oe,didAction:ie,didFilter:se,actions:ae,filters:ce}=b;return T(le);})();
1005(window.wp ||= {}).hooks = wp.hooks;
1006})();
1007;

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.