PageSourceSearch

https://www.ptotoday.com/media/com_minitekwall/js/minitekwall.js?33c5fc

js ptotoday.com collected 2026-09-24 09:25:38 UTC 173,728 bytes, 3,939 lines download raw bytes

1((document, Joomla) => {
2    "use strict";
3
4    class Mwall {
5        /*
6         * Constructor
7         */
8        constructor(options, id, count, source, path, elements, itemid) {
9            this.options = options;
10            this.widgetId = parseInt(id, 10);
11            this.totalCount = parseInt(count, 10);
12            this.sourceId = source;
13            this.path = path;
14            this.elements = elements;
15            this.itemid = itemid;
16
17            this.urlHash =
18                typeof this.options.mas_url_hash === "undefined" ||
19                this.options.mas_url_hash == 0
20                    ? false
21                    : true;
22            this.filtersMode = this.options.mas_filters_mode;
23            var wallSortings =
24                this.options.mas_title_sorting != 0 ||
25                this.options.mas_date_sorting != 0 ||
26                this.options.mas_hits_sorting != 0 ||
27                this.options.mas_sorting_direction != 0
28                    ? true
29                    : false;
30            this.filtersEnabled =
31                this.options.mas_category_filters != 0 ||
32                this.options.mas_tag_filters != 0 ||
33                this.options.mas_date_filters != 0 ||
34                wallSortings
35                    ? true
36                    : false;
37            this.multipleFilters =
38                typeof this.options.mas_multiple_filters === "undefined" ||
39                this.options.mas_multiple_filters == 0
40                    ? false
41                    : true;
42            this.tagsLogicalOperator =
43                typeof this.options.mas_tags_logical_operator === "undefined"
44                    ? "OR"
45                    : this.options.mas_tags_logical_operator;
46            this.pagination = parseInt(this.options.mas_pagination, 10);
47            this.hoverBox = this.options.mas_hb != 0 ? true : false;
48            this.dateFiltersFormat =
49                typeof this.options.mas_date_filters_format === "undefined"
50                    ? "Y-m"
51                    : this.options.mas_date_filters_format;
52            this.timer;
53            this.ignoreVideos = true;
54            this.fluidHeight = false;
55            this.videoSource =
56                typeof this.options.videoSource === "undefined"
57                    ? false
58                    : this.options.videoSource;
59
60            // Hash filters
61            if (this.urlHash) this.hash_filters = this.getHashFilters();
62
63            // Initialize wall
64            this.initializeWall();
65
66            // Initialize filters
67            this.filters = {
68                category: [],
69                tag: [],
70                date: [],
71                ordering: "",
72                direction: "",
73                search: "",
74            };
75
76            // Dynamic filters
77            if (
78                this.container &&
79                this.filtersEnabled &&
80                this.filtersMode == "dynamic"
81            )
82                this.dynamicFilters();
83
84            // Dynamic search filter
85            if (
86                this.container &&
87                this.options.mas_search_filter &&
88                this.filtersMode == "dynamic"
89            )
90                this.dynamicSearch();
91
92            // Trigger reset buttons
93            if (
94                this.container &&
95                this.filtersMode == "dynamic" &&
96                (this.filtersEnabled || this.options.mas_search_filter)
97            )
98                this.triggerResetButtons();
99
100            // Static filters
101            if (
102                this.container &&
103                this.filtersEnabled &&
104                this.filtersMode == "static"
105            )
106                this.staticFilters();
107
108            // Pagination
109            if (this.container && this.pagination != 0)
110                this.initializePagination();
111
112            // Pagination - Append
113            if (this.container && this.pagination === 1)
114                this.appendPagination();
115
116            // Pagination - Infinite
117            if (this.container && this.pagination === 4) {
118                this.infScroll = false;
119                this.infinitePagination();
120            }
121
122            // Pagination - Pages
123            if (this.container && this.pagination === 3) this.pagesPagination();
124
125            // Pagination - Arrows
126            if (this.container && this.pagination === 2)
127                this.arrowsPagination();
128
129            if (this.container && this.hoverBox) {
130                // Modal images
131                if (parseInt(this.options.mas_hb_zoom, 10))
132                    this.initModalMessages();
133            }
134
135            // Check if we are inside an iframe
136            this.isIframe = window.frameElement ? true : false;
137
138            if (this.isIframe) {
139                if (document.querySelector(".mwall-description"))
140                    document.querySelector(".mwall-description").style.padding =
141                        "20px";
142
143                if (document.querySelector(".mwall-results-empty-results"))
144                    document.querySelector(
145                        ".mwall-results-empty-results"
146                    ).style.padding = "20px";
147                else if (this.container) this.container.style.padding = "20px";
148            }
149        }
150
151        initializeWall() {
152            const self = this;
153
154            this.pageLimit = parseInt(this.options.mas_page_limit, 10);
155            this.closeFilters =
156                this.options.mas_close_filters != 0 ? true : false;
157            this.scrollToTop =
158                this.options.mas_pag_scroll_to_top != 0 ? true : false;
159            this.container = document.querySelector(
160                "#mwall_container_" + this.widgetId
161            );
162
163            if (this.container == null) return;
164
165            this.gridType = parseInt(this.options.mas_grid, 10);
166            if (this.gridType == 999) this.gridType = self.elements.length;
167
168            switch (this.gridType) {
169                case 98:
170                    this.layoutType = "columns";
171                    break;
172                case 99:
173                    this.layoutType = "list";
174                    break;
175                default:
176                    this.layoutType = "masonry";
177                    break;
178            }
179
180            this.fluidHeight =
181                this.layoutType == "list" ||
182                (this.layoutType == "columns" &&
183                    (this.options.mas_preserve_aspect_ratio ||
184                        this.options.videoSource));
185
186            this.layoutMode = this.options.mas_layout_mode;
187            this.dbPosition = this.options.mas_db_position_columns;
188            this.equalHeight =
189                this.options.mas_force_equal_height != 0 ? true : false;
190            this.sortBy = this.container.getAttribute("data-order");
191            this.sortDirection =
192                this.container.getAttribute("data-direction") == null
193                    ? ""
194                    : this.container
195                          .getAttribute("data-direction")
196                          .toLowerCase();
197            this.sortAscending = this.sortDirection == "asc" ? true : false;
198
199            if (
200                this.sortBy == "RAND()" ||
201                this.sortBy == "rand" ||
202                this.sortBy == "random" ||
203                this.sourceId == "rss"
204            ) {
205                this.sortBy = ["index"];
206                this.sortAscending = true;
207            } else this.sortBy = [this.sortBy, "id", "title"];
208
209            this.createSpinner(
210                document.querySelector("#mwall_loader_" + this.widgetId)
211            );
212            document.querySelector(
213                "#mwall_loader_" + this.widgetId
214            ).style.display = "block";
215            this.transitionDuration = parseInt(
216                this.options.mas_transition_duration,
217                10
218            );
219            this.transitionStagger = parseInt(
220                this.options.mas_transition_stagger,
221                10
222            );
223            this.scrollThreshold = 100;
224            this.iso_container = document.querySelector(
225                "#mwall_items_" + this.widgetId
226            );
227            this.wall;
228            var effects = this.options.mas_effects
229                ? this.options.mas_effects
230                : ["fade"];
231            var hiddenOpacity = 1;
232            var hiddenTransform = "scale(1)";
233
234            if (effects.includes("fade")) hiddenOpacity = 0;
235            if (effects.includes("scale")) hiddenTransform = "scale(0.001)";
236
237            var imgLoad = imagesLoaded(self.iso_container, {
238                background: ".mwall-photo-link",
239            });
240
241            imgLoad.on("done", function () {
242                let update_wall = function () {
243                    self.wall = new Isotope(self.iso_container, {
244                        itemSelector: ".mwall-item",
245                        layoutMode: self.layoutMode,
246                        vertical: {
247                            horizontalAlignment: 0,
248                        },
249                        initLayout: false,
250                        stagger: self.transitionStagger,
251                        transitionDuration: self.transitionDuration,
252                        hiddenStyle: {
253                            opacity: hiddenOpacity,
254                            transform: hiddenTransform,
255                        },
256                        visibleStyle: {
257                            opacity: 1,
258                            transform: "scale(1)",
259                        },
260                        getSortData: {
261                            ordering: "[data-ordering] parseInt",
262                            fordering: "[data-fordering] parseInt",
263                            hits: "[data-hits] parseInt",
264                            title: function (itemElem) {
265                                if (itemElem.querySelector(".mwall-title")) {
266                                    let title =
267                                        itemElem.querySelector(
268                                            ".mwall-title"
269                                        ).textContent;
270
271                                    return self.removeAccents(title);
272                                }
273                            },
274                            id: "[data-id] parseInt",
275                            alias: "[data-alias]",
276                            date: "[data-date]",
277                            modified: "[data-modified]",
278                            start: "[data-start]",
279                            finish: "[data-finish]",
280                            index: "[data-index] parseInt",
281                        },
282                    });
283
284                    self.container.style.display = "block";
285
286                    if (self.filtersEnabled && self.filtersMode == "static") {
287                        self.wall.arrange({
288                            sortBy: ["index"],
289                            sortAscending: { index: true },
290                        });
291                    } else {
292                        self.wall.arrange({
293                            sortBy: self.sortBy,
294                            sortAscending: self.sortAscending,
295                        });
296                    }
297
298                    self.fixEqualHeights("all");
299                    self.container.style.opacity = 1;
300                    document.querySelector(
301                        "#mwall_loader_" + self.widgetId
302                    ).style.display = "none";
303
304                    // Hash filters
305                    if (self.urlHash && self.filtersEnabled) self.hashFilters();
306                };
307
308                if (self.videoSource) self.videosReady(update_wall);
309
310                if (self.ignoreVideos) update_wall();
311            });
312
313            // Handle broken images
314            imgLoad.on("progress", function (instance, image) {
315                var result = image.isLoaded ? "loaded" : "broken";
316                if (result == "broken") {
317                    console.log("Image not found: " + image.img.src);
318
319                    let div = document.createElement("div");
320                    div.innerHTML =
321                        "Image not found: <b>" + image.img.src + "</b>";
322                    let targetDiv = self.container;
323                    let parentDiv = targetDiv.parentNode;
324                    parentDiv.insertBefore(div, targetDiv);
325
326                    document.querySelector(
327                        "#mwall_loader_" + self.widgetId
328                    ).style.display = "none";
329                }
330            });
331
332            // Handle resize
333            var _resize;
334
335            window.addEventListener("resize", function () {
336                clearTimeout(_resize);
337
338                _resize = setTimeout(function () {
339                    self.doneBrowserResizing();
340                }, 500);
341            });
342        }
343
344        removeAccents(string) {
345            return string
346                .toLowerCase()
347                .replace(/[áàãâä]/gi, "a")
348                .replace(/[éèëê]/gi, "e")
349                .replace(/[íìïî]/gi, "i")
350                .replace(/[óòöôõø]/gi, "o")
351                .replace(/[úùüû]/gi, "u")
352                .replace(/[ç]/gi, "c")
353                .replace(/[ñ]/gi, "n");
354        }
355
356        videosReady(callback) {
357            const self = this;
358            self.ignoreVideos = true;
359            const _videos = self.iso_container.querySelectorAll("video");
360
361            if (_videos.length) {
362                let videos = [];
363
364                _videos.forEach((a) => {
365                    if (a.readyState == 0) videos.push(a);
366                });
367
368                if (videos.length) {
369                    self.ignoreVideos = false;
370                    let states = [];
371
372                    for (let i = 0; i < videos.length; i++) {
373                        states.push(0);
374                    }
375
376                    let promise = new Promise(function (resolve) {
377                        Object.keys(videos).forEach((key) => {
378                            videos[key].addEventListener("loadeddata", () => {
379                                states[key] = videos[key].readyState;
380
381                                // If all videos ready (readyState >=3), resolve promise
382                                if (states.every((v) => v >= 3))
383                                    resolve(states);
384                            });
385                        });
386                    });
387
388                    promise.then(function (value) {
389                        callback();
390                    });
391                }
392            }
393        }
394
395        hashFilters() {
396            const self = this;
397
398            let hash_category = self.hash_filters.get("category");
399            let hash_tag = self.hash_filters.get("tag");
400            let hash_date = self.hash_filters.get("date");
401            let hash_ordering = self.hash_filters.get("ordering");
402            let hash_direction = self.hash_filters.get("direction");
403            let hash_filters =
404                hash_category ||
405                hash_tag ||
406                hash_date ||
407                hash_ordering ||
408                hash_direction;
409
410            if (self.filtersMode == "dynamic") {
411                if (hash_category)
412                    self.filters["category"] = hash_category.split(",");
413                if (hash_tag) self.filters["tag"] = hash_tag.split(",");
414
415                var data_attr = "data-filter";
416            } else if (self.filtersMode == "static") {
417                if (hash_category)
418                    self.filters["category"] = hash_category
419                        .split(",")
420                        .map(Number);
421                if (hash_tag)
422                    self.filters["tag"] = hash_tag.split(",").map(Number);
423                if (hash_ordering) self.filters["ordering"] = hash_ordering;
424                if (hash_direction) self.filters["direction"] = hash_direction;
425
426                var data_attr = "data-id";
427            }
428
429            if (hash_date) self.filters["date"] = hash_date.split(",");
430
431            if (hash_filters) {
432                if (self.filtersMode == "static") {
433                    // Show loader
434                    document.querySelector(
435                        "#mwall_loader_" + self.widgetId
436                    ).style.display = "block";
437
438                    // Hide container
439                    self.container.style.display = "none";
440                    self.container.style.opacity = 0;
441                }
442
443                // Hide results message
444                self.container.querySelector(".mwall-no-items").style.display =
445                    "none";
446
447                // Show reset button in pagination
448                if (
449                    self.filters["category"].length ||
450                    self.filters["tag"].length ||
451                    self.filters["date"].length
452                ) {
453                    if (self.container.querySelector(".mwall-reset-btn")) {
454                        self.container.querySelector(
455                            ".mwall-reset-btn"
456                        ).style.display = "inline-block";
457
458                        if (self.filtersMode == "static") {
459                            self.container
460                                .querySelector(".mwall-reset-btn")
461                                .addEventListener("click", function (e) {
462                                    e.preventDefault();
463
464                                    self.resetStaticFilters();
465                                });
466                        }
467                    }
468                }
469
470                // Set active categories
471                if (
472                    self.filters["category"].length &&
473                    self.container.querySelector(".button-group-category")
474                ) {
475                    self.container
476                        .querySelector(".button-group-category")
477                        .querySelector(".mwall-filter[data-filter='']")
478                        .classList.remove("mwall-filter-active");
479
480                    self.filters["category"].forEach(function (a) {
481                        if (
482                            self.container
483                                .querySelector(".button-group-category")
484                                .querySelector(
485                                    ".mwall-filter[" +
486                                        data_attr +
487                                        "='" +
488                                        a +
489                                        "']"
490                                )
491                        )
492                            self.container
493                                .querySelector(".button-group-category")
494                                .querySelector(
495                                    ".mwall-filter[" +
496                                        data_attr +
497                                        "='" +
498                                        a +
499                                        "']"
500                                )
501                                .classList.add("mwall-filter-active");
502                    });
503
504                    // Show name in dropdown
505                    if (
506                        self.container
507                            .querySelector(".button-group-category")
508                            .closest(".mwall-dropdown")
509                    ) {
510                        let cat_text = self.container
511                            .querySelector(".button-group-category")
512                            .querySelector(".mwall-filter-active").textContent;
513                        self.container
514                            .querySelector(".button-group-category")
515                            .closest(".mwall-dropdown")
516                            .querySelector(
517                                ".dropdown-label span span"
518                            ).textContent = cat_text;
519                    }
520                }
521
522                // Set active tags
523                if (
524                    self.filters["tag"].length &&
525                    self.container.querySelector(".button-group-tag")
526                ) {
527                    self.container
528                        .querySelector(".button-group-tag")
529                        .querySelector(".mwall-filter[data-filter='']")
530                        .classList.remove("mwall-filter-active");
531
532                    self.filters["tag"].forEach(function (a) {
533                        if (
534                            self.container
535                                .querySelector(".button-group-tag")
536                                .querySelector(
537                                    ".mwall-filter[" +
538                                        data_attr +
539                                        "='" +
540                                        a +
541                                        "']"
542                                )
543                        )
544                            self.container
545                                .querySelector(".button-group-tag")
546                                .querySelector(
547                                    ".mwall-filter[" +
548                                        data_attr +
549                                        "='" +
550                                        a +
551                                        "']"
552                                )
553                                .classList.add("mwall-filter-active");
554                    });
555
556                    // Show name in dropdown
557                    if (
558                        self.container
559                            .querySelector(".button-group-tag")
560                            .closest(".mwall-dropdown")
561                    ) {
562                        let tag_text = self.container
563                            .querySelector(".button-group-tag")
564                            .querySelector(".mwall-filter-active").textContent;
565                        self.container
566                            .querySelector(".button-group-tag")
567                            .closest(".mwall-dropdown")
568                            .querySelector(
569                                ".dropdown-label span span"
570                            ).textContent = tag_text;
571                    }
572                }
573
574                // Set active dates
575                if (
576                    self.filters["date"].length &&
577                    self.container.querySelector(".button-group-date")
578                ) {
579                    self.container
580                        .querySelector(".button-group-date")
581                        .querySelector(".mwall-filter[data-filter='']")
582                        .classList.remove("mwall-filter-active");
583
584                    self.filters["date"].forEach(function (a) {
585                        if (
586                            self.container
587                                .querySelector(".button-group-date")
588                                .querySelector(
589                                    ".mwall-filter[" +
590                                        data_attr +
591                                        "='" +
592                                        a +
593                                        "']"
594                                )
595                        )
596                            self.container
597                                .querySelector(".button-group-date")
598                                .querySelector(
599                                    ".mwall-filter[" +
600                                        data_attr +
601                                        "='" +
602                                        a +
603                                        "']"
604                                )
605                                .classList.add("mwall-filter-active");
606                    });
607
608                    // Show name in dropdown
609                    if (
610                        self.container
611                            .querySelector(".button-group-date")
612                            .closest(".mwall-dropdown")
613                    ) {
614                        let date_text = self.container
615                            .querySelector(".button-group-date")
616                            .querySelector(".mwall-filter-active").textContent;
617                        self.container
618                            .querySelector(".button-group-date")
619                            .closest(".mwall-dropdown")
620                            .querySelector(
621                                ".dropdown-label span span"
622                            ).textContent = date_text;
623                    }
624                }
625
626                if (self.filtersMode == "dynamic") {
627                    // Create all permutations from all filters
628                    var permutations = self.combineArrays(self.filters);
629                    var filterValue = permutations.join(", ");
630
631                    // Show results message
632                    self.wall.once("layoutComplete", function (items) {
633                        self.resultsMessage(self, items);
634                    });
635                }
636
637                // Ordering
638                if (
639                    self.container.querySelector(".sorting-group-filters") &&
640                    (hash_ordering == "title" ||
641                        hash_ordering == "date" ||
642                        hash_ordering == "hits")
643                ) {
644                    if (self.filtersMode == "dynamic") {
645                        // Add second ordering: id
646                        let sort_Ordering = [hash_ordering, "id"];
647
648                        // Update Isotope
649                        self.wall.arrange({
650                            sortBy: sort_Ordering,
651                        });
652                    }
653
654                    // Change active class
655                    self.container
656                        .querySelector(".sorting-group-filters")
657                        .querySelectorAll(".mwall-filter")
658                        .forEach(function (a) {
659                            a.classList.remove("mwall-filter-active");
660                        });
661                    self.container
662                        .querySelector(".sorting-group-filters")
663                        .querySelector(
664                            ".mwall-filter[data-sort-value='" +
665                                hash_ordering +
666                                "']"
667                        )
668                        .classList.add("mwall-filter-active");
669
670                    // Show name in dropdown
671                    if (
672                        self.container
673                            .querySelector(".sorting-group-filters")
674                            .closest(".mwall-dropdown")
675                    ) {
676                        let sorting_text = self.container
677                            .querySelector(".sorting-group-filters")
678                            .querySelector(".mwall-filter-active").textContent;
679                        self.container
680                            .querySelector(".sorting-group-filters")
681                            .closest(".mwall-dropdown")
682                            .querySelector(
683                                ".dropdown-label span span"
684                            ).textContent = sorting_text;
685                    }
686                }
687
688                // Direction
689                if (
690                    self.container.querySelector(".sorting-group-direction") &&
691                    (hash_direction == "asc" || hash_direction == "de
691sc")
692                ) {
693                    if (self.filtersMode == "dynamic") {
694                        let sort_Direction;
695
696                        if (hash_direction == "asc") sort_Direction = true;
697                        else sort_Direction = false;
698
699                        // Update Isotope
700                        self.wall.arrange({
701                            sortAscending: sort_Direction,
702                        });
703                    }
704
705                    // Change active class
706                    self.container
707                        .querySelector(".sorting-group-direction")
708                        .querySelectorAll(".mwall-filter")
709                        .forEach(function (a) {
710                            a.classList.remove("mwall-filter-active");
711                        });
712                    self.container
713                        .querySelector(".sorting-group-direction")
714                        .querySelector(
715                            ".mwall-filter[data-sort-value='" +
716                                hash_direction +
717                                "']"
718                        )
719                        .classList.add("mwall-filter-active");
720
721                    // Show name in dropdown
722                    if (
723                        self.container
724                            .querySelector(".sorting-group-direction")
725                            .closest(".mwall-dropdown")
726                    ) {
727                        let sorting_text = self.container
728                            .querySelector(".sorting-group-direction")
729                            .querySelector(".mwall-filter-active").textContent;
730                        self.container
731                            .querySelector(".sorting-group-direction")
732                            .closest(".mwall-dropdown")
733                            .querySelector(
734                                ".dropdown-label span span"
735                            ).textContent = sorting_text;
736                    }
737                }
738
739                if (self.filtersMode == "dynamic") {
740                    // Update Isotope
741                    self.wall.arrange({
742                        filter: filterValue,
743                    });
744
745                    self.resizeItems();
746
747                    // Hide reset button in pagination
748                    if (
749                        filterValue == "" &&
750                        self.container.querySelector(".mwall-reset-btn")
751                    )
752                        self.container.querySelector(
753                            ".mwall-reset-btn"
754                        ).style.display = "none";
755                } else if (self.filtersMode == "static") {
756                    // Filters data
757                    let data = {
758                        category: self.filters["category"],
759                        tag: self.filters["tag"],
760                        date: self.filters["date"],
761                        ordering: self.filters["ordering"],
762                        direction: self.filters["direction"],
763                    };
764
765                    // Remove current items
766                    var elems = self.wall.getItemElements();
767                    self.wall.remove(elems);
768
769                    // Ajax request
770                    Joomla.request({
771                        url:
772                            self.path +
773                            "index.php?option=com_minitekwall&task=masonry.getContent&widget_id=" +
774                            self.widgetId +
775                            "&page=1" +
776                            "&tag_operator=" +
777                            self.tagsLogicalOperator +
778                            "&date_format=" +
779                            self.dateFiltersFormat +
780                            "&grid=" +
781                            self.layoutType +
782                            "&Itemid=" +
783                            self.itemid,
784                        method: "POST",
785                        data: JSON.stringify(data),
786                        onSuccess: (response, xhr) => {
787                            if (response.length > 3) {
788                                // Show container
789                                self.container.style.display = "block";
790
791                                var newItems = self.htmlToElements(
792                                    response,
793                                    ".mwall-item"
794                                );
795
796                                newItems.forEach(function (a) {
797                                    a.style.visibility = "hidden";
798                                    if (self.fluidHeight)
799                                        self.iso_container.appendChild(a);
800                                });
801
802                                self.wall.once(
803                                    "layoutComplete",
804                                    function (items) {
805                                        self.resultsMessage(self, items);
806                                    }
807                                );
808
809                                var imgLoad = imagesLoaded(self.iso_container, {
810                                    background: ".mwall-photo-link",
811                                });
812
813                                imgLoad.on("done", function () {
814                                    let update_wall = function () {
815                                        if (self.fluidHeight)
816                                            self.wall.appended(newItems);
817                                        else self.wall.insert(newItems);
818                                        self.wall.arrange();
819                                        self.wall.updateSortData();
820                                        self.fixEqualHeights(newItems);
821
822                                        newItems.forEach(function (a) {
823                                            a.style.visibility = "visible";
824                                        });
825
826                                        // Hide loader
827                                        document.querySelector(
828                                            "#mwall_loader_" + self.widgetId
829                                        ).style.display = "none";
830
831                                        // Show container
832                                        self.container.style.opacity = 1;
833
834                                        if (self.pagination != 0)
835                                            self.updatePagination(data);
836                                    };
837
838                                    if (self.videoSource)
839                                        self.videosReady(update_wall);
840
841                                    if (self.ignoreVideos) update_wall();
842                                });
843                            }
844                        },
845                        onError: function onError(xhr) {
846                            if (xhr.status > 0) {
847                                Joomla.renderMessages(
848                                    Joomla.ajaxErrorsMessages(xhr)
849                                );
850                            }
851                        },
852                    });
853                }
854            }
855        }
856
857        resultsMessage(self, items) {
858            if (items.length == 0) {
859                self.container.querySelector(".mwall-no-items").style.display =
860                    "block";
861            } else {
862                self.container.querySelector(".mwall-no-items").style.display =
863                    "none";
864            }
865        }
866
867        reindexItem(grid, index) {
868            const self = this;
869
870            if (index > grid) {
871                index = index - grid;
872                index = self.reindexItem(grid, index);
873            }
874
875            return index;
876        }
877
878        resizeItem(grid, index) {
879            const self = this;
880            let size;
881
882            switch (grid) {
883                // Custom grids
884                case "999c":
885                    let elements = self.elements;
886
887                    switch (elements[index - 1].size) {
888                        case "S":
889                            size = "mwall-small";
890                            break;
891                        case "L":
892                            size = "mwall-horizontal";
893                            break;
894                        case "P":
895                            size = "mwall-vertical";
896                            break;
897                        case "B":
898                            size = "mwall-big";
899                            break;
900                    }
901                    break;
902
903                // Preset grids
904                case "1":
905                    size = "mwall-big";
906                    break;
907
908                case "3a":
909                    if (index == "1") {
910                        size = "mwall-big";
911                    } else {
912                        size = "mwall-horizontal";
913                    }
914                    break;
915
916                case "3b":
917                    if (index == "2") {
918                        size = "mwall-big";
919                    } else {
920                        size = "mwall-horizontal";
921                    }
922                    break;
923
924                case "3c":
925                    if (index == "1") {
926                        size = "mwall-big";
927                    } else {
928                        size = "mwall-vertical";
929                    }
930                    break;
931
932                case "4":
933                    if (index == "1") {
934                        size = "mwall-big";
935                    } else if (index == "2") {
936                        size = "mwall-horizontal";
937                    } else {
938                        size = "mwall-small";
939                    }
940                    break;
941
942                case "5":
943                    if (index == "1" || index == "5") {
944                        size = "mwall-horizontal";
945                    } else if (index == "2" || index == "4") {
946                        size = "mwall-small";
947                    } else {
948                        size = "mwall-big";
949                    }
950                    break;
951
952                case "5b":
953                    if (index == "3") {
954                        size = "mwall-big";
955                    } else {
956                        size = "mwall-small";
957                    }
958                    break;
959
960                case "6":
961                    if (index == "1") {
962                        size = "mwall-big";
963                    } else if (index == "3") {
964                        size = "mwall-horizontal";
965                    } else {
966                        size = "mwall-small";
967                    }
968                    break;
969
970                case "7":
971                    if (index == "1") {
972                        size = "mwall-big";
973                    } else if (index == "2") {
974                        size = "mwall-horizontal";
975                    } else if (index == "4") {
976                        size = "mwall-vertical";
977                    } else {
978                        size = "mwall-small";
979                    }
980                    break;
981
982                case "8":
983                    if (index == "1" || index == "7" || index == "8") {
984                        size = "mwall-horizontal";
985                    } else if (index == "2") {
986                        size = "mwall-big";
987                    } else if (index == "6") {
988                        size = "mwall-vertical";
989                    } else {
990                        size = "mwall-small";
991                    }
992                    break;
993
994                case "9":
995                    if (index == "1") {
996                        size = "mwall-big";
997                    } else if (index == "2") {
998                        size = "mwall-horizontal";
999                    } else if (index == "4" || index == "5" || index == "6") {
1000                        size = "mwall-vertical";
1001                    } else {
1002                        size = "mwall-small";
1003                    }
1004                    break;
1005
1006                case "9r":
1007                    if (index == "1" || index == "2" || index == "3") {
1008                        size = "mwall-horizontal";
1009                    } else if (index == "4" || index == "5") {
1010                        size = "mwall-big";
1011                    } else {
1012                        size = "mwall-small";
1013                    }
1014                    break;
1015
1016                case "12r":
1017                    if (
1018                        index == "1" ||
1019                        index == "2" ||
1020                        index == "3" ||
1021                        index == "4"
1022                    ) {
1023                        size = "mwall-horizontal";
1024                    } else if (
1025                        index == "10" ||
1026                        index == "11" ||
1027                        index == "12"
1028                    ) {
1029                        size = "mwall-big";
1030                    } else {
1031                        size = "mwall-small";
1032                    }
1033                    break;
1034
1035                case "16r":
1036                    if (
1037                        index == "1" ||
1038                        index == "5" ||
1039                        index == "7" ||
1040                        index == "15"
1041                    ) {
1042                        size = "mwall-horizontal";
1043                    } else {
1044                        size = "mwall-small";
1045                    }
1046                    break;
1047            }
1048
1049            return size;
1050        }
1051
1052        resizeItems() {
1053            const self = this;
1054            let items = self.wall.getFilteredItemElements();
1055
1056            // Resize items
1057            if (self.layoutType == "masonry") {
1058                items.forEach((item, i) => {
1059                    // Remove classes
1060                    item.classList.remove(
1061                        "mwall-small",
1062                        "mwall-horizontal",
1063                        "mwall-vertical",
1064                        "mwall-big",
1065                        "mwall-item1",
1066                        "mwall-item2",
1067                        "mwall-item3",
1068                        "mwall-item4",
1069                        "mwall-item5",
1070                        "mwall-item6",
1071                        "mwall-item7",
1072                        "mwall-item8",
1073                        "mwall-item9",
1074                        "mwall-item10",
1075                        "mwall-item11",
1076                        "mwall-item12",
1077                        "mwall-item13",
1078                        "mwall-item14",
1079                        "mwall-item15",
1080                        "mwall-item16"
1081                    );
1082
1083                    // Re-index
1084                    let index = i + 1;
1085                    item.setAttribute("data-index", index);
1086                    index = self.reindexItem(self.gridType, index);
1087
1088                    // Resize
1089                    let size = self.resizeItem(self.options.mas_grid, index);
1090
1091                    // Add new classes
1092                    item.classList.add(size, "mwall-item" + index);
1093                });
1094            }
1095
1096            self.wall.arrange();
1097        }
1098
1099        arrowsPagination() {
1100            const self = this;
1101            let wrapper = self.container.querySelector(
1102                ".mwall-pagination-wrapper"
1103            );
1104
1105            wrapper.addEventListener("click", function (e) {
1106                e.preventDefault();
1107
1108                if (e.target.classList.contains("mwall-arrow"))
1109                    var _this = e.target;
1110                else if (e.target.closest(".mwall-arrow"))
1111                    var _this = e.target.closest(".mwall-arrow");
1112                else return false;
1113
1114                if (
1115                    _this.classList.contains("disabled") ||
1116                    self.container.classList.contains("mwall-loading")
1117                )
1118                    return false;
1119
1120                // Find page
1121                var page = _this.getAttribute("data-page");
1122                page = parseInt(page, 10);
1123
1124                var prev_page = page - 1;
1125                var next_page = page + 1;
1126
1127                // Check if there is a pending ajax request
1128                if (typeof ajax_request !== "undefined") {
1129                    ajax_request.abort();
1130                    self.container.classList.remove("mwall-loading");
1131                    self.container.querySelector(
1132                        ".mwall-more-results"
1133                    ).style.display = "block";
1134                    self.container.querySelector(
1135                        ".mwall-arrow-loader"
1136                    ).style.display = "none";
1137                }
1138
1139                // Show loader
1140                self.container.classList.add("mwall-loading");
1141                _this.classList.add("arrow-loading");
1142                _this.querySelector(".mwall-more-results").style.display =
1143                    "none";
1144                _this.querySelector(".mwall-arrow-loader").style.display =
1145                    "block";
1146
1147                // Filters data
1148                var data = {};
1149
1150                if (self.filtersMode == "static") {
1151                    data = {
1152                        category: self.filters["category"],
1153                        tag: self.filters["tag"],
1154                        date: self.filters["date"],
1155                        ordering: self.filters["ordering"],
1156                        direction: self.filters["direction"],
1157                        search: self.filters["search"],
1158                    };
1159                }
1160
1161                // Remove current items
1162                var elems = self.wall.getItemElements();
1163                self.wall.remove(elems);
1164
1165                // Ajax request
1166                var ajax_request = Joomla.request({
1167                    url:
1168                        self.path +
1169                        "index.php?option=com_minitekwall&task=masonry.getContent&widget_id=" +
1170                        self.widgetId +
1171                        "&page=" +
1172                        page +
1173                        "&tag_operator=" +
1174                        self.tagsLogicalOperator +
1175                        "&date_format=" +
1176                        self.dateFiltersFormat +
1177                        "&grid=" +
1178                        self.layoutType +
1179                        "&Itemid=" +
1180                        self.itemid,
1181                    method: "POST",
1182                    data: JSON.stringify(data),
1183                    onSuccess: (response, xhr) => {
1184                        if (response.length > 3) {
1185                            // Increment/decrement page
1186                            self.container
1187                                .querySelector(".mwall-arrow-prev")
1188                                .setAttribute("data-page", prev_page);
1189                            self.container
1190                                .querySelector(".mwall-arrow-next")
1191                                .setAttribute("data-page", next_page);
1192
1193                            // Reset filters
1194                            if (
1195                                self.filtersMode == "dynamic" &&
1196                                (self.filtersEnabled ||
1197                                    self.options.mas_search_filter)
1198                            )
1199                                self.resetFilters();
1200
1201                            var newItems = self.htmlToElements(
1202                                response,
1203                                ".mwall-item"
1204                            );
1205
1206                            newItems.forEach(function (a) {
1207                                a.style.visibility = "hidden";
1208                                if (self.fluidHeight)
1209                                    self.iso_container.appendChild(a);
1210                            });
1211
1212                            var imgLoad = imagesLoaded(self.iso_container, {
1213                                background: ".mwall-photo-link",
1214                            });
1215
1216                            imgLoad.on("done", function () {
1217                                let update_wall = function () {
1218                                    if (self.fluidHeight)
1219                                        self.wall.appended(newItems);
1220                                    else self.wall.insert(newItems);
1221                                    self.wall.arrange();
1222                                    self.wall.updateSortData();
1223                                    self.fixEqualHeights(newItems);
1224
1225                                    newItems.forEach(function (a) {
1226                                        a.style.visibility = "visible";
1227                                    });
1228
1229                                    // Update filters
1230                                    if (
1231                                        self.filtersEnabled &&
1232                                        self.filtersMode == "dynamic"
1233                                    ) {
1234                                        Joomla.request({
1235                                            url:
1236                                                self.path +
1237                                                "index.php?option=com_minitekwall&task=masonry.getFilters&widget_id=" +
1238                                                self.widgetId +
1239                                                "&page=" +
1240                                                page +
1241                                                "&pagination=" +
1242                                                self.pagination +
1243                                                "&Itemid=" +
1244                                                self.itemid,
1245                                            method: "GET",
1246                                            onSuccess: (response, xhr) => {
1247                                                if (response.length > 3) {
1248                                                    // Add new filters
1249                                                    self.container.querySelector(
1250                                                        ".mwall-filters"
1251                                                    ).innerHTML = response;
1252                                                }
1253
1254                                                self.activeFilters();
1255                                                self.dropdownFilters();
1256                                            },
1257                                            onError: function onError(xhr) {
1258                                                if (xhr.status > 0) {
1259                                                    Joomla.renderMessages(
1260                                                        Joomla.ajaxErrorsMessages(
1261                                                            xhr
1262                                                        )
1263                                                    );
1264                                                }
1265                                            },
1266                                        });
1267                                    }
1268
1269                                    // Hide loader
1270                                    self.container.classList.remove(
1271                                        "mwall-loading"
1272                                    );
1273                                    _this.classList.remove("arrow-loading");
1274                                    _this.querySelector(
1275                                        ".mwall-more-results"
1276                                    ).style.display = "block";
1277                                    _this.querySelector(
1278                                        ".mwall-arrow-loader"
1279                                    ).style.display = "none";
1280
1281                                    // Enable buttons
1282                                    self.container
1283                                        .querySelectorAll(".mwall-arrow")
1284                                        .forEach((a) => {
1285                                            a.classList.remove("disabled");
1286                                        });
1287
1288                                    // First page
1289                                    if (prev_page <= 0) {
1290                                        if (prev_page < 0) {
1291                                            self.container
1292                                                .querySelector(
1293                                                    ".mwall-arrow-prev"
1294                                                )
1295                                                .setAttribute("data-page", 0);
1296                                            _this.setAttribute("data-page", 2);
1297                                        }
1298
1299                                        self.container
1300                                            .querySelector(".mwall-arrow-prev")
1301                                            .classList.add("disabled");
1302                                    }
1303
1304                                    // Last page
1305                                    var lastPage = parseInt(
1306                                        _this
1307                                            .closest(".mwall-arrows")
1308                                            .getAttribute("data-last-page"),
1309                                        10
1310                                    );
1311
1312                                    if (next_page > lastPage)
1313                                        self.container
1314                                            .querySelector(".mwall-arrow-next")
1315                                            .classList.add("disabled");
1316
1317                                    // Scroll to top
1318                                    if (self.scrollToTop) {
1319                                        setTimeout(function () {
1320                                            self.container.firstChild.scrollIntoView(
1321                                                true
1322                                            );
1323                                        }, self.transitionDuration);
1324                                    }
1325                                };
1326
1327                                if (self.videoSource)
1328                                    self.videosReady(update_wall);
1329
1330                                if (self.ignoreVideos) update_wall();
1331                            });
1332                        } else {
1333                            // Disable button / Hide loader
1334                            _this.classList.add("disabled");
1335                            self.container.querySelector(
1336                                ".mwall-arrow-loader"
1337                            ).style.display = "none";
1338                        }
1339                    },
1340                    onError: function onError(xhr) {
1341                        if (xhr.status > 0) {
1342                            Joomla.renderMessages(
1343                                Joomla.ajaxErrorsMessages(xhr)
1344                            );
1345                        }
1346                    },
1347                });
1348            });
1349        }
1350
1351        pagesPagination() {
1352            const self = this;
1353            let wrapper = self.container.querySelector(
1354                ".mwall-pagination-wrapper"
1355            );
1356
1357            wrapper.addEventListener("click", function (e) {
1358                e.preventDefault();
1359
1360                if (e.target.classList.contains("mwall-page"))
1361                    var _this = e.target;
1362                else if (e.target.closest(".mwall-page"))
1363                    var _this = e.target.closest(".mwall-page");
1364                else return false;
1365
1366                if (self.container.classList.contains("mwall-loading"))
1367                    return false;
1368
1369                self.container
1370                    .querySelectorAll(".mwall-page")
1371                    .forEach(function (a) {
1372                        a.classList.remove("mwall-active");
1373                    });
1374
1375                // Find page
1376                var page = _this.getAttribute("data-page");
1377                page = parseInt(page, 10);
1378
1379                // Check if there is a pending ajax request
1380                if (typeof ajax_request !== "undefined") {
1381                    ajax_request.abort();
1382                    self.container.classList.remove("mwall-loading");
1383                    self.container.querySelector(".page-number").style.display =
1384                        "inline-block";
1385                    self.container.querySelector(
1386                        ".mwall-page-loader"
1387                    ).style.display = "none";
1388                }
1389
1390                // Show loader
1391                self.container.classList.add("mwall-loading");
1392                _this.querySelector(".page-number").style.display = "none";
1393                _this.querySelector(".mwall-page-loader").style.display =
1394                    "block";
1395
1396                // Filters data
1397                var data = {};
1398
1399                if (self.filtersMode == "static") {
1400                    data = {
1401                        category: self.filters["category"],
1402                        tag: self.filters["tag"],
1403                        date: self.filters["date"],
1404                        ordering: self.filters["ordering"],
1405                        direction: self.filters["direction"],
1406                        search: self.filters["search"],
1407                    };
1408                }
1409
1410                // Remove current items
1411                var elems = self.wall.getItemElements();
1412                self.wall.remove(elems);
1413
1414                // Ajax request
1415                var ajax_request = Joomla.request({
1416                    url:
1417                        self.path +
1418                        "index.php?option=com_minitekwall&task=masonry.getContent&widget_id=" +
1419                        self.widgetId +
1420                        "&page=" +
1421                        page +
1422                        "&tag_operator=" +
1423                        self.tagsLogicalOperator +
1424                        "&date_format=" +
1425                        self.dateFiltersFormat +
1426                        "&grid=" +
1427                        self.layoutType +
1428                        "&Itemid=" +
1429                        self.itemid,
1430                    method: "POST",
1431                    data: JSON.stringify(data),
1432                    onSuccess: (response, xhr) => {
1433                        if (response.length > 3) {
1434                            // Reset filters
1435                            if (
1436                                self.filtersMode == "dynamic" &&
1437                                (self.filtersEnabled ||
1438                                    self.options.mas_search_filter)
1439                            )
1440                                self.resetFilters();
1441
1442                            var newItems = self.htmlToElements(
1443                                response,
1444                                ".mwall-item"
1445                            );
1446
1447                            newItems.forEach(function (a) {
1448                                a.style.visibility = "hidden";
1449                                if (self.fluidHeight)
1450                                    self.iso_container.appendChild(a);
1451                            });
1452
1453                            var imgLoad = imagesLoaded(self.iso_container, {
1454                                background: ".mwall-photo-link",
1455                            });
1456
1457                            imgLoad.on("done", function () {
1458                                let update_wall = function () {
1459                                    if (self.fluidHeight)
1460                                        self.wall.appended(newItems);
1461                                    else self.wall.insert(newItems);
1462                                    self.wall.arrange();
1463                                    self.wall.updateSortData();
1464                                    self.fixEqualHeights(newItems);
1465
1466                                    newItems.forEach(function (a) {
1467                                        a.style.visibility = "visible";
1468                                    });
1469
1470                                    if (
1471                                        self.filtersEnabled &&
1472                                        self.filtersMode == "dynamic"
1473                                    ) {
1474                                        // Update filters
1475                                        Joomla.request({
1476                                            url:
1477                                                self.path +
1478                                                "index.php?option=com_minitekwall&task=masonry.getFilters&widget_id=" +
1479                                                self.widgetId +
1480                                                "&page=" +
1481                                                page +
1482                                                "&pagination=" +
1483                                                self.pagination +
1484                                                "&Itemid=" +
1485                                                self.itemid,
1486                                            method: "GET",
1487                                            onSuccess: (response, xhr) => {
1488                                                if (response.length > 3) {
1489                                                    // Add new filters
1490                                                    self.container.querySelector(
1491                                                        ".mwall-filters"
1492                                                    ).innerHTML = response;
1493                                                }
1494
1495                                                self.activeFilters();
1496                                                self.dropdownFilters();
1497                                            },
1498                                            onError: function onError(xhr) {
1499                                                if (xhr.status > 0) {
1500                                                    Joomla.renderMessages(
1501                                                        Joomla.ajaxErrorsMessages(
1502                                                            xhr
1503                                                        )
1504                                                    );
1505                                                }
1506                                            },
1507                                        });
1508                                    }
1509
1510                                    // Hide loader
1511                                    self.container.classList.remove(
1512                                        "mwall-loading"
1513                                    );
1514                                    _this.querySelector(
1515                                        ".page-number"
1516                                    ).style.display = "inline-block";
1517                                    _this.querySelector(
1518                                        ".mwall-page-loader"
1519                                    ).style.display = "none";
1520
1521                                    // Remove active class
1522                                    if (
1523                                        !_this.classList.contains(
1524                                            "mwall-active"
1525                                        )
1526                                    )
1527                                        _this.classList.add("mwall-active");
1528
1529                                    // Scroll to top
1530                                    if (self.scrollToTop) {
1531                                        setTimeout(function () {
1532                                            self.container.firstChild.scrollIntoView(
1533                                                true
1534                                            );
1535                                        }, self.transitionDuration);
1536                                    }
1537                                };
1538
1539                                if (self.videoSource)
1540                                    self.videosReady(update_wall);
1541
1542                                if (self.ignoreVideos) update_wall();
1543                            });
1544                        } else {
1545                            // Hide loader
1546                            self.container.classList.remove("mwall-loading");
1547                            self.container.querySelector(
1548                                ".mwall-page-loader"
1549                            ).style.display = "none";
1550                        }
1551                    },
1552                    onError: function onError(xhr) {
1553                        if (xhr.status > 0) {
1554                            Joomla.renderMessages(
1555                                Joomla.ajaxErrorsMessages(xhr)
1556                            );
1557                        }
1558                    },
1559                });
1560            });
1561        }
1562
1563        infinitePagination(prefill = false) {
1564            const self = this;
1565
1566            let parent = self.container.querySelector(".mwall-more-results");
1567            var lastPage = parseInt(
1568                self.container
1569                    .querySelector(".mwall-infinite")
1570                    .getAttribute("data-last-page"),
1571                10
1572            );
1573            var page;
1574            var data = {};
1575
1576            self.infScroll = new InfiniteScroll(self.iso_container, {
1577                path: function () {
1578                    page = parent.getAttribute("data-page");
1579                    page = parseInt(page, 10);
1580
1581                    if (page <= lastPage)
1582                        return (
1583                            self.path +
1584                            "index.php?option=com_minitekwall&task=masonry.getContent&widget_id=" +
1585                            self.widgetId +
1586                            "&page=" +
1587                            page +
1588                            "&grid=" +
1589                            self.layoutType
1590                        );
1591                },
1592                checkLastPage: true,
1593                prefill: prefill,
1594                domParseResponse: true,
1595                fetchOptions: function () {
1596                    // Filters data
1597                    if (self.filtersMode == "static") {
1598                        data = {
1599                            category: self.filters["category"],
1600                            tag: self.filters["tag"],
1601                            date: self.filters["date"],
1602                            ordering: self.filters["ordering"],
1603                            direction: self.filters["direction"],
1604                            search: self.filters["search"],
1605                        };
1606                    }
1607
1608                    return {
1609                        method: "POST",
1610                        body: JSON.stringify(data),
1611                    };
1612                },
1613                scrollThreshold: self.scrollThreshold,
1614                loadOnScroll: true,
1615                outlayer: self.wall,
1616                history: false,
1617            });
1618
1619            self.infScroll.on("load", function (body) {
1620                onLoad(body);
1621            });
1622
1623            // Triggered after infinite scroll has appended items
1624            function onLoad(body) {
1625                if (page > lastPage) return;
1626                if (self.container.classList.contains("mwall-loading"))
1627                    return false;
1628
1629                // Show loader
1630                parent.style.display = "block";
1631                self.container.classList.add("mwall-loading");
1632                self.container.querySelector(
1633                    ".mwall-append-loader"
1634                ).style.display = "block";
1635
1636                let newItems = body.querySelectorAll(".mwall-item");
1637
1638                if (newItems) {
1639                    newItems.forEach(function (a) {
1640                        a.style.visibility = "hidden";
1641                        self.iso_container.appendChild(a);
1642                    });
1643
1644                    // Increment page
1645                    parent.setAttribute("data-page", page + 1);
1646
1647                    var imgLoad = imagesLoaded(self.iso_container, {
1648                        background: ".mwall-photo-link",
1649                    });
1650
1651                    imgLoad.on("done", function () {
1652                        let update_wall = function () {
1653                            // Reset filters
1654                            if (
1655                                self.filtersMode == "dynamic" &&
1656                                (self.filtersEnabled ||
1657                                    self.options.mas_search_filter)
1658                            )
1659                                self.resetFilters();
1660
1661                            self.wall.appended(newItems);
1662                            self.wall.arrange();
1663                            self.wall.updateSortData();
1664                            self.fixEqualHeights("all");
1665
1666                            newItems.forEach(function (a) {
1667                                a.style.visibility = "visible";
1668                            });
1669
1670                            if (
1671                                self.filtersEnabled &&
1672                                self.filtersMode == "dynamic"
1673                            ) {
1674                                // Update filters
1675                                Joomla.request({
1676                                    url:
1677                                        self.path +
1678                                        "index.php?option=com_minitekwall&task=masonry.getFilters&widget_id=" +
1679                                        self.widgetId +
1680                                        "&page=" +
1681                                        page +
1682                                        "&pagination=" +
1683                                        self.pagination +
1684                                        "&Itemid=" +
1685                                        self.itemid,
1686                                    method: "GET",
1687                                    onSuccess: (response, xhr) => {
1688                                        if (response.length > 3) {
1689                                            // Add new filters
1690                                            self.container.querySelector(
1691                                                ".mwall-filters"
1692                                            ).innerHTML = response;
1693                                        }
1694
1695                                        self.activeFilters();
1696                                        self.dropdownFilters();
1697                                    },
1698                                    onError: function onError(xhr) {
1699                                        if (xhr.status > 0) {
1700                                            Joomla.renderMessages(
1701                                                Joomla.ajaxErrorsMessages(xhr)
1702                                            );
1703                                        }
1704                                    },
1705                                });
1706                            }
1707
1708                            // Hide loader
1709                            self.container.classList.remove("mwall-loading");
1710                            parent.style.display = "none";
1711                            self.container.querySelector(
1712                                ".mwall-append-loader"
1713                            ).style.display = "none";
1714                        };
1715
1716                        if (self.videoSource) self.videosReady(update_wall);
1717
1718                        if (self.ignoreVideos) update_wall();
1719                    });
1720                }
1721            }
1722        }
1723
1724        appendPagination() {
1725            const self = this;
1726            let wrapper = self.container.querySelector(
1727                ".mwall-pagination-wrapper"
1728            );
1729
1730            wrapper.addEventListener("click", function (e) {
1731                e.preventDefault();
1732
1733                if (e.target && e.target.closest(".mwall-button")) {
1734                    var _this = self.container.querySelector(".mwall-button");
1735
1736                    if (
1737                        _this.classList.contains("disabled") ||
1738                        self.container.classList.contains("mwall-loading")
1739                    )
1740                        return false;
1741
1742                    var page = _this.getAttribute("data-page");
1743                    page = parseInt(page, 10);
1744
1745                    // Increment page
1746                    var new_page = page + 1;
1747                    _this.setAttribute("data-page", new_page);
1748
1749                    // Check if there is a pending ajax request
1750                    if (typeof ajax_request !== "undefined") {
1751                        ajax_request.abort();
1752                        self.container.classList.remove("mwall-loading");
1753                        self.container.querySelector(
1754                            ".mwall-more-results"
1755                        ).style.display = "block";
1756                        self.container.querySelector(
1757                            ".mwall-append-loader"
1758                        ).style.display = "none";
1759                    }
1760
1761                    // Show loader
1762                    self.container.classList.add("mwall-loading");
1763                    self.container.querySelector(
1764                        ".mwall-more-results"
1765                    ).style.display = "none";
1766                    self.container.querySelector(
1767                        ".mwall-append-loader"
1768                    ).style.display = "block";
1769
1770                    // Filters data
1771                    var data = {};
1772
1773                    if (self.filtersMode == "static") {
1774                        var data = {
1775                            category: self.filters["category"],
1776                            tag: self.filters["tag"],
1777                            date: self.filters["date"],
1778                            ordering: self.filters["ordering"],
1779                            direction: self.filters["direction"],
1780                            search: self.filters["search"],
1781                        };
1782                    }
1783
1784                    // Ajax request
1785                    var ajax_request = Joomla.request({
1786                        url:
1787                            self.path +
1788                            "index.php?option=com_minitekwall&task=masonry.getContent&widget_id=" +
1789                            self.widgetId +
1790                            "&page=" +
1791                            page +
1792                            "&tag_operator=" +
1793                            self.tagsLogicalOperator +
1794                            "&date_format=" +
1795                            self.dateFiltersFormat +
1796                            "&grid=" +
1797                            self.layoutType +
1798                            "&Itemid=" +
1799                            self.itemid,
1800                        method: "POST",
1801                        data: JSON.stringify(data),
1802                        onSuccess: (response, xhr) => {
1803                            if (response.length > 3) {
1804                                // Reset filters
1805                                if (
1806                                    self.filtersMode == "dynamic" &&
1807                                    (self.filtersEnabled ||
1808                                        self.options.mas_search_filter)
1809                                )
1810                                    self.resetFilters();
1811
1812                                var newItems = self.htmlToElements(
1813                                    response,
1814                                    ".mwall-item"
1815                                );
1816
1817                                newItems.forEach(function (a) {
1818                                    a.style.visibility = "hidden";
1819                                    self.iso_container.appendChild(a);
1820                                });
1821
1822                                var imgLoad = imagesLoaded(self.iso_container, {
1823                                    background: ".mwall-photo-link",
1824                                });
1825
1826                                imgLoad.on("done", function () {
1827                                    let update_wall = function () {
1828                                        self.wall.appended(newItems);
1829                                        self.wall.arrange();
1830                                        self.wall.updateSortData();
1831                                        self.fixEqualHeights("all");
1832
1833                                        newItems.forEach(function (a) {
1834                                            a.style.visibility = "visible";
1835                                        });
1836
1837                                        // Update filters
1838                                        if (
1839                                            self.filtersEnabled &&
1840                                            self.filtersMode == "dynamic"
1841                                        ) {
1842                                            Joomla.request({
1843                                                url:
1844                                                    self.path +
1845                                                    "index.php?option=com_minitekwall&task=masonry.getFilters&widget_id=" +
1846                                                    self.widgetId +
1847                                                    "&page=" +
1848                                                    page +
1849                                                    "&pagination=" +
1850                                                    self.pagination +
1851                                                    "&Itemid=" +
1852                                                    self.itemid,
1853                                                method: "GET",
1854                                                onSuccess: (response, xhr) => {
1855                                                    if (response.length > 3) {
1856                                                        self.container.querySelector(
1857                                                            ".mwall-filters"
1858                                                        ).innerHTML = response;
1859                                                    }
1860
1861                                                    self.activeFilters();
1862                                                    self.dropdownFilters();
1863                                                },
1864                                                onError: function onError(xhr) {
1865                                                    if (xhr.status > 0) {
1866                                                        Joomla.renderMessages(
1867                                                            Joomla.ajaxErrorsMessages(
1868                                                                xhr
1869                                                            )
1870                                                        );
1871                                                    }
1872                                                },
1873                                            });
1874                                        }
1875
1876                                        // Hide loader
1877                                        self.container.classList.remove(
1878                                            "mwall-loading"
1879                                        );
1880                                        self.container.querySelector(
1881                                            ".mwall-more-results"
1882                                        ).style.display = "block";
1883                                        self.container.querySelector(
1884                                            ".mwall-append-loader"
1885                                        ).style.display = "none";
1886                                        self.container
1887                                            .querySelector(".mwall-button")
1888                                            .blur();
1889
1890                                        // Deduct remaining items number in button
1891                                        var _remaining =
1892                                            self.container.querySelector(
1893                                                ".mwall-total-items"
1894                                            ).textContent;
1895                                        var remaining =
1896                                            parseInt(_remaining, 10) -
1897                                            self.pageLimit;
1898                                        self.container.querySelector(
1899                                            ".mwall-total-items"
1900                                        ).innerHTML = remaining;
1901
1902                                        // Remove button if no items left
1903                                        if (remaining <= 0) {
1904                                            self.container
1905                                                .querySelector(".mwall-button")
1906                                                .remove();
1907                                        }
1908                                    };
1909
1910                                    if (self.videoSource)
1911                                        self.videosReady(update_wall);
1912
1913                                    if (self.ignoreVideos) update_wall();
1914                                });
1915                            }
1916                        },
1917                        onError: function onError(xhr) {
1918                            if (xhr.status > 0) {
1919                                Joomla.renderMessages(
1920                                    Joomla.ajaxErrorsMessages(xhr)
1921                                );
1922                            }
1923                        },
1924                    });
1925                }
1926            });
1927        }
1928
1929        initializePagination() {
1930            const self = this;
1931
1932            self.container
1933                .querySelectorAll(".mwall-loader")
1934                .forEach(function (a) {
1935                    self.createSpinner(a);
1936                });
1937        }
1938
1939        // Get filters permutations
1940        combineArrays(filters) {
1941            const self = this;
1942
1943            if (!filters) {
1944                return [];
1945            }
1946
1947            if (typeof filters !== "object") {
1948                return [];
1949            }
1950
1951            if (Object.keys(filters).length == 0) {
1952                return [];
1953            }
1954
1955            let _filters = {};
1956
1957            for (var group in filters) {
1958                if (
1959                    !Array.isArray(filters[group]) ||
1960                    filters[group].length == 0
1961                )
1962                    continue;
1963                else {
1964                    if (group == "tag" && self.tagsLogicalOperator == "AND")
1965                        _filters[group] = [filters[group].join("")];
1966                    else _filters[group] = filters[group];
1967                }
1968            }
1969
1970            // Start "odometer" with a 0 for each array in filters.
1971            let odometer = new Array(Object.keys(_filters).length);
1972            odometer.fill(0);
1973
1974            let output = [];
1975
1976            let newCombination = self.formCombination(odometer, _filters);
1977
1978            output.push(newCombination);
1979
1980            while (self.odometer_increment(odometer, _filters)) {
1981                newCombination = self.formCombination(odometer, _filters);
1982                output.push(newCombination);
1983            }
1984
1985            return output;
1986        }
1987
1988        // Create a new combination
1989        formCombination(odometer, filters) {
1990            let s_output = "";
1991
1992            for (let i = 0; i < odometer.length; i++) {
1993                if (Object.values(filters)[i][odometer[i]])
1994                    s_output += "" + Object.values(filters)[i][odometer[i]];
1995            }
1996
1997            return s_output;
1998        }
1999
2000        odometer_increment(odometer, filters) {
2001            for (
2002                let i_odometer_digit = odometer.length - 1;
2003                i_odometer_digit >= 0;
2004                i_odometer_digit--
2005            ) {
2006                let maxee = Object.values(filters)[i_odometer_digit].length - 1;
2007
2008                if (odometer[i_odometer_digit] + 1 <= maxee) {
2009                    odometer[i_odometer_digit]++;
2010                    return true;
2011                } else {
2012                    if (i_odometer_digit - 1 < 0) {
2013                        return false;
2014                    } else {
2015                        odometer[i_odometer_digit] = 0;
2016                        continue;
2017                    }
2018                }
2019            }
2020        }
2021
2022        // Set active filters
2023        activeFilters() {
2024            const self = this;
2025
2026            self.container
2027                .querySelectorAll(".button-group")
2028                .forEach(function (buttonGroup) {
2029                    buttonGroup
2030                        .querySelectorAll(".mwall-filter")
2031                        .forEach(function (a) {
2032                            a.addEventListener("click", function (e) {
2033                                e.preventDefault();
2034
2035                                var filter = this.getAttribute("data-filter");
2036                                var filterGroup =
2037                                    buttonGroup.getAttribute(
2038                                        "data-filter-group"
2039                                    );
2040
2041                                // Single filter
2042                                if (!self.multipleFilters) {
2043                                    if (
2044                                        buttonGroup.querySelector(
2045                                            ".mwall-filter-active"
2046                                        )
2047                                    )
2048                                        buttonGroup
2049                                            .querySelector(
2050                                                ".mwall-filter-active"
2051                                            )
2052                                            .classList.remove(
2053                                                "mwall-filter-active"
2054                                            );
2055                                }
2056                                // Multiple filters
2057                                else {
2058                                    if (!filter) {
2059                                        buttonGroup
2060                                            .querySelectorAll(
2061                                                ".mwall-filter-active"
2062                                            )
2063                                            .forEach(function (a) {
2064                                                a.classList.remove(
2065                                                    "mwall-filter-active"
2066                                                );
2067                                            });
2068
2069                                        a.classList.add("mwall-filter-active");
2070                                    } else {
2071                                        buttonGroup
2072                                            .querySelector(
2073                                                ".mwall-filter[data-filter='']"
2074                                            )
2075                                            .classList.remove(
2076                                                "mwall-filter-active"
2077                                            );
2078                                    }
2079                                }
2080
2081                                // Toggle active filter
2082                                if (self.filters[filterGroup].includes(filter))
2083                                    a.classList.remove("mwall-filter-active");
2084                                else a.classList.add("mwall-filter-active");
2085
2086                                if (
2087                                    !buttonGroup.querySelectorAll(
2088                                        ".mwall-filter-active"
2089                                    ).length
2090                                )
2091                                    buttonGroup
2092                                        .querySelector(
2093                                            ".mwall-filter[data-filter='']"
2094                                        )
2095                                        .classList.add("mwall-filter-active");
2096                            });
2097                        });
2098                });
2099        }
2100
2101        // Activate dropdown filters actions
2102        dropdownFilters() {
2103            const self = this;
2104
2105            if (self.container.querySelector(".mwall-filters-container")) {
2106                self.container
2107                    .querySelector(".mwall-filters-container")
2108                    .querySelectorAll(".mwall-dropdown")
2109                    .forEach(function (dropdownGroup) {
2110                        dropdownGroup
2111                            .querySelector(".dropdown-label")
2112                            .addEventListener("click", function (e) {
2113                                e.preventDefault();
2114                                var filter_open;
2115
2116                                if (
2117                                    this.closest(
2118                                        ".mwall-dropdown"
2119                                    ).classList.contains("expanded")
2120                                )
2121                                    filter_open = true;
2122                                else filter_open = false;
2123
2124                                self.container
2125                                    .querySelectorAll(".mwall-dropdown")
2126                                    .forEach(function (a) {
2127                                        a.classList.remove("expanded");
2128                                    });
2129
2130                                if (!filter_open)
2131                                    this.closest(
2132                                        ".mwall-dropdown"
2133                                    ).classList.add("expanded");
2134                            });
2135                    });
2136            }
2137
2138            // Close dropdowns
2139            document.addEventListener("mouseup", function (e) {
2140                var _target = e.target;
2141                var dropdowncontainers =
2142                    self.container.querySelectorAll(".mwall-dropdown");
2143
2144                if (!dropdowncontainers) return;
2145
2146                if (!this.closeFilters) {
2147                    // Close when click outside
2148                    if (!_target.closest(".mwall-dropdown")) {
2149                        dropdowncontainers.forEach(function (a) {
2150                            a.classList.remove("expanded");
2151                        });
2152                    }
2153                } else {
2154                    // Close when click inside
2155                    if (
2156                        _target.closest(".mwall-dropdown") &&
2157                        !_target.closest(".dropdown-label")
2158                    ) {
2159                        dropdowncontainers.forEach(function (a) {
2160                            a.classList.remove("expanded");
2161                        });
2162                    }
2163                }
2164            });
2165        }
2166
2167        // Activate dropdown sortings actions
2168        dropdownSortings() {
2169            const self = this;
2170
2171            if (self.container.querySelector(".mwall-sortings")) {
2172                self.container
2173                    .querySelector(".mwall-sortings")
2174                    .querySelectorAll(".mwall-dropdown")
2175                    .forEach(function (dropdownSorting) {
2176                        dropdownSorting
2177                            .querySelector(".dropdown-label")
2178                            .addEventListener("click", function (e) {
2179                                e.preventDefault();
2180                                var sorting_open;
2181
2182                                if (
2183                                    this.closest(
2184                                        ".mwall-dropdown"
2185                                    ).classList.contains("expanded")
2186                                )
2187                                    sorting_open = true;
2188                                else sorting_open = false;
2189
2190                                self.container
2191                                    .querySelectorAll(".mwall-dropdown")
2192                                    .forEach(function (a) {
2193                                        a.classList.remove("expanded");
2194                                    });
2195
2196                                if (!sorting_open)
2197                                    this.closest(
2198                                        ".mwall-dropdown"
2199                                    ).classList.add("expanded");
2200                            });
2201                    });
2202            }
2203        }
2204
2205        updatePagination(data) {
2206            const self = this;
2207
2208            self.container.querySelector(
2209                ".mwall-pagination-wrapper"
2210            ).style.display = "none";
2211
2212            if (
2213                (data["category"].length &&
2214                    data["category"][0] &&
2215                    data["category"][0] > 0) ||
2216                (data["tag"].length && data["tag"][0] && data["tag"][0] > 0) ||
2217                (data["date"] && data["date"] != "0") ||
2218                (data["search"] && data["search"].length)
2219            ) {
2220                var filters_active = true;
2221            } else var filters_active = false;
2222
2223            Joomla.request({
2224                url:
2225                    self.path +
2226                    "index.php?option=com_minitekwall&task=masonry.getPagination&widget_id=" +
2227                    self.widgetId +
2228                    "&page=1" +
2229                    "&tag_operator=" +
2230                    self.tagsLogicalOperator +
2231                    "&date_format=" +
2232                    self.dateFiltersFormat +
2233                    "&pagination=" +
2234                    self.pagination +
2235                    "&Itemid=" +
2236                    self.itemid,
2237                method: "POST",
2238                data: JSON.stringify(data),
2239                onSuccess: (response, xhr) => {
2240                    if (response.length > 3) {
2241                        self.container.querySelector(
2242                            ".mwall-pagination-wrapper"
2243                        ).innerHTML = response;
2244
2245                        self.container.querySelector(
2246                            ".mwall-pagination-wrapper"
2247                        ).style.display = "block";
2248
2249                        self.container
2250                            .querySelectorAll(".mwall-loader")
2251                            .forEach(function (a) {
2252                                self.createSpinner(a);
2253                            });
2254
2255                        // Show reset button in pagination
2256                        if (
2257                            self.container.querySelector(".mwall-reset-btn") &&
2258                            filters_active
2259                        ) {
2260                            self.container.querySelector(
2261                                ".mwall-reset-btn"
2262                            ).style.display = "inline-block";
2263
2264                            self.container
2265                                .querySelector(".mwall-reset-btn")
2266                                .addEventListener("click", function (e) {
2267                                    e.preventDefault();
2268
2269                                    self.resetStaticFilters();
2270                                });
2271                        }
2272
2273                        // Re-initialize infinite pagination
2274                        if (self.pagination === 4) {
2275                            var wrapper = self.container.querySelector(
2276                                ".mwall-more-results"
2277                            );
2278                            wrapper.setAttribute("data-page", "2");
2279                            self.infScroll.destroy();
2280                            self.infinitePagination();
2281                        }
2282                    }
2283                },
2284                onError: function onError(xhr) {
2285                    if (xhr.status > 0) {
2286                        Joomla.renderMessages(Joomla.ajaxErrorsMessages(xhr));
2287                    }
2288                },
2289            });
2290        }
2291
2292        // Reset static filters and sortings
2293        resetStaticFilters() {
2294            const self = this;
2295
2296            if (self.container.classList.contains("mwall-loading"))
2297                return false;
2298
2299            self.container.querySelector(".mwall-no-items").style.display =
2300                "none";
2301
2302            // Reset filters
2303            self.filters["category"] = [];
2304            self.filters["tag"] = [];
2305            self.filters["date"] = [];
2306            self.filters["ordering"] = "";
2307            self.filters["direction"] = "";
2308            self.filters["search"] = "";
2309
2310            // Check if there is a pending ajax request
2311            if (typeof ajax_request !== "undefined") ajax_request.abort();
2312
2313            // Show loader
2314            self.container.classList.add("mwall-loading");
2315            if (self.container.querySelector(".mwall-reset-container"))
2316                self.container
2317                    .querySelector(".mwall-reset-container")
2318                    .querySelector(".mwall-filters-loader").style.display =
2319                    "inline-block";
2320
2321            // Hide pagination
2322            if (self.container.querySelector(".mwall-pagination-wrapper"))
2323                self.container.querySelector(
2324                    ".mwall-pagination-wrapper"
2325                ).style.display = "none";
2326
2327            // Filters data
2328            var data = {
2329                category: self.filters["category"],
2330                tag: self.filters["tag"],
2331                date: self.filters["date"],
2332                ordering: self.filters["ordering"],
2333                direction: self.filters["direction"],
2334                search: self.filters["search"],
2335            };
2336
2337            // Remove current items
2338            var elems = self.wall.getItemElements();
2339            self.wall.remove(elems);
2340
2341            // Ajax request
2342            var ajax_request = Joomla.request({
2343                url:
2344                    self.path +
2345                    "index.php?option=com_minitekwall&task=masonry.getContent&widget_id=" +
2346                    self.widgetId +
2347                    "&page=1" +
2348                    "&tag_operator=" +
2349                    self.tagsLogicalOperator +
2350                    "&date_format=" +
2351                    self.dateFiltersFormat +
2352                    "&grid=" +
2353                    self.layoutType +
2354                    "&Itemid=" +
2355                    self.itemid,
2356                method: "POST",
2357                data: JSON.stringify(data),
2358                onSuccess: (response, xhr) => {
2359                    if (response.length > 3) {
2360                        var newItems = self.htmlToElements(
2361                            response,
2362                            ".mwall-item"
2363                        );
2364
2365                        newItems.forEach(function (a) {
2366                            a.style.visibility = "hidden";
2367                            if (self.fluidHeight)
2368                                self.iso_container.appendChild(a);
2369                        });
2370
2371                        var imgLoad = imagesLoaded(self.iso_container, {
2372                            background: ".mwall-photo-link",
2373                        });
2374
2375                        imgLoad.on("done", function () {
2376                            let update_wall = function () {
2377                                if (self.fluidHeight)
2378                                    self.wall.appended(newItems);
2379                                else self.wall.insert(newItems);
2380                                self.wall.arrange();
2381                                self.wall.updateSortData();
2382                                self.fixEqualHeights(newItems);
2383
2384                                newItems.forEach(function (a) {
2385                                    a.style.visibility = "visible";
2386                                });
2387
2388                                // Reset active buttons
2389                                self.container
2390                                    .querySelectorAll(".button-group")
2391                                    .forEach(function (buttonGroup) {
2392                                        if (
2393                                            buttonGroup.querySelector(
2394                                                ".mwall-filter-active"
2395                                            )
2396                                        )
2397                                            buttonGroup
2398                                                .querySelectorAll(
2399                                                    ".mwall-filter-active"
2400                                                )
2401                                                .forEach(function (a) {
2402                                                    a.classList.remove(
2403                                                        "mwall-filter-active"
2404                                                    );
2405                                                });
2406
2407                                        buttonGroup
2408                                            .querySelector("li:first-child a")
2409                                            .classList.add(
2410                                                "mwall-filter-active"
2411                                            );
2412
2413                                        // Hide reset button in pagination
2414                                        if (
2415                                            self.container.querySelector(
2416                                                ".mwall-reset-btn"
2417                                            )
2418                                        )
2419                                            self.container.querySelector(
2420                                                ".mwall-reset-btn"
2421                                            ).style.display = "none";
2422                                    });
2423
2424                                // Reset dropdown filters text
2425                                self.container
2426                                    .querySelectorAll(".mwall-dropdown")
2427                                    .forEach(function (dropdownGroup) {
2428                                        var filter_text = dropdownGroup
2429                                            .querySelector(
2430                                                ".dropdown-label span"
2431                                            )
2432                                            .getAttribute("data-label");
2433                                        dropdownGroup.querySelector(
2434                                            ".dropdown-label span span"
2435                                        ).textContent = filter_text;
2436                                    });
2437
2438                                // Reset search filter
2439                                if (
2440                                    self.container.querySelector(
2441                                        ".mwall-search-input"
2442                                    )
2443                                ) {
2444                                    self.container.querySelector(
2445                                        ".mwall-search-input"
2446                                    ).value = "";
2447                                    self.filters["search"] = "";
2448                                }
2449
2450                                // Reset sortings
2451                                self.container
2452                                    .querySelectorAll(".sorting-group-filters")
2453                                    .forEach(function (sortingGroup) {
2454                                        sortingGroup
2455                                            .querySelectorAll(".mwall-filter")
2456                                            .forEach(function (a) {
2457                                                a.classList.remove(
2458                                                    "mwall-filter-active"
2459                                                );
2460                                            });
2461                                        if (
2462                                            sortingGroup.querySelector(
2463                                                'li a[data-sort-value="' +
2464                                                    self.sortBy[0] +
2465                                                    '"]'
2466                                            )
2467                                        ) {
2468                                            sortingGroup
2469                                                .querySelector(
2470                                                    'li a[data-sort-value="' +
2471                                                        self.sortBy[0] +
2472                                                        '"]'
2473                                                )
2474                                                .classList.add(
2475                                                    "mwall-filter-active"
2476                                                );
2477                                        }
2478                                    });
2479
2480                                self.container
2481                                    .querySelectorAll(
2482                                        ".sorting-group-direction"
2483                                    )
2484                                    .forEach(function (sortingGroupDirection) {
2485                                        sortingGroupDirection
2486                                            .querySelector(
2487                                                ".mwall-filter-active"
2488                                            )
2489                                            .classList.remove(
2490                                                "mwall-filter-active"
2491                                            );
2492                                        sortingGroupDirection
2493                                            .querySelector(
2494                                                'li a[data-sort-value="' +
2495                                                    self.sortDirection +
2496                                                    '"]'
2497                                            )
2498                                            .classList.add(
2499                                                "mwall-filter-active"
2500                                            );
2501                                    });
2502
2503                                // Hide loader
2504                                self.container.classList.remove(
2505                                    "mwall-loading"
2506                                );
2507                                if (
2508                                    self.container.querySelector(
2509                                        ".mwall-reset-container"
2510                                    )
2511                                )
2512                                    self.container
2513                                        .querySelector(".mwall-reset-container")
2514                                        .querySelector(
2515                                            ".mwall-filters-loader"
2516                                        ).style.display = "none";
2517
2518                                if (self.pagination != 0)
2519                                    self.updatePagination(data);
2520                            };
2521
2522                            if (self.videoSource) self.videosReady(update_wall);
2523
2524                            if (self.ignoreVideos) update_wall();
2525                        });
2526
2527                        if (self.urlHash) self.removeHash();
2528                    }
2529                },
2530                onError: function onError(xhr) {
2531                    if (xhr.status > 0) {
2532                        Joomla.renderMessages(Joomla.ajaxErrorsMessages(xhr));
2533                    }
2534                },
2535            });
2536        }
2537
2538        staticFilters() {
2539            const self = this;
2540
2541            // Create loader
2542            self.container
2543                .querySelectorAll(".mwall-filters-loader")
2544                .forEach(function (a) {
2545                    self.createSpinner(a);
2546                });
2547
2548            // Search filter
2549            if (self.container.querySelector(".mwall-search-input")) {
2550                self.container
2551                    .querySelector(".mwall-search-input")
2552                    .addEventListener("input", function (e) {
2553                        e.preventDefault();
2554
2555                        if (self.container.classList.contains("mwall-loading"))
2556                            return false;
2557
2558                        let _this = e.target;
2559
2560                        // Wait for 800ms before searching
2561                        window.clearTimeout(self.timer);
2562
2563                        self.timer = window.setTimeout(function () {
2564                            // Sanitize value
2565                            let value = self.escapeRegex(_this.value);
2566                            self.filters["search"] = value;
2567
2568                            // Check if there is a pending ajax request
2569                            if (typeof ajax_request !== "undefined")
2570                                ajax_request.abort();
2571
2572                            // Show loader
2573                            self.container.classList.add("mwall-loading");
2574                            _this
2575                                .closest(".mwall-filters-group")
2576                                .querySelector(
2577                                    ".mwall-filters-loader"
2578                                ).style.display = "inline-block";
2579
2580                            // Hide pagination
2581                            if (
2582                                self.container.querySelector(
2583                                    ".mwall-pagination-wrapper"
2584                                )
2585                            )
2586                                self.container.querySelector(
2587                                    ".mwall-pagination-wrapper"
2588                                ).style.display = "none";
2589
2590                            // Filters data
2591                            var data = {
2592                                category: self.filters["category"],
2593                                tag: self.filters["tag"],
2594                                date: self.filters["date"],
2595                                ordering: self.filters["ordering"],
2596                                direction: self.filters["direction"],
2597                                search: self.filters["search"],
2598                            };
2599
2600                            // Remove current items
2601                            var elems = self.wall.getItemElements();
2602                            self.wall.remove(elems);
2603
2604                            // Ajax request
2605                            var ajax_request = Joomla.request({
2606                                url:
2607                                    self.path +
2608                                    "index.php?option=com_minitekwall&task=masonry.getContent&widget_id=" +
2609                                    self.widgetId +
2610                                    "&page=1" +
2611                                    "&tag_operator=" +
2612                                    self.tagsLogicalOperator +
2613                                    "&date_format=" +
2614                                    self.dateFiltersFormat +
2615                                    "&grid=" +
2616                                    self.layoutType +
2617                                    "&Itemid=" +
2618                                    self.itemid,
2619                                method: "POST",
2620                                data: JSON.stringify(data),
2621                                onSuccess: (response, xhr) => {
2622                                    if (response.length > 3) {
2623                                        var newItems = self.htmlToElements(
2624                                            response,
2625                                            ".mwall-item"
2626                                        );
2627
2628                                        newItems.forEach(function (a) {
2629                                            a.style.visibility = "hidden";
2630                                            if (self.fluidHeight)
2631                                                self.iso_container.appendChild(
2632                                                    a
2633                                                );
2634                                        });
2635
2636                                        self.wall.once(
2637                                            "layoutComplete",
2638                                            function (items) {
2639                                                self.resultsMessage(
2640                                                    self,
2641                                                    items
2642                                                );
2643                                            }
2644                                        );
2645
2646                                        var imgLoad = imagesLoaded(
2647                                            self.iso_container,
2648                                            {
2649                                                background: ".mwall-photo-link",
2650                                            }
2651                                        );
2652
2653                                        imgLoad.on("done", function () {
2654                                            let update_wall = function () {
2655                                                if (self.fluidHeight)
2656                                                    self.wall.appended(
2657                                                        newItems
2658                                                    );
2659                                                else self.wall.insert(newItems);
2660                                                self.wall.arrange();
2661                                                self.wall.updateSortData();
2662                                                self.fixEqualHeights(newItems);
2663
2664                                                newItems.forEach(function (a) {
2665                                                    a.style.visibility =
2666                                                        "visible";
2667                                                });
2668
2669                                                // Hide loader
2670                                                self.container.classList.remove(
2671                                                    "mwall-loading"
2672                                                );
2673                                                _this
2674                                                    .closest(
2675                                                        ".mwall-filters-group"
2676                                                    )
2677                                                    .querySelector(
2678                                                        ".mwall-filters-loader"
2679                                                    ).style.display = "none";
2680
2681                                                if (self.pagination != 0)
2682                                                    self.updatePagination(data);
2683                                            };
2684
2685                                            if (self.videoSource)
2686                                                self.videosReady(update_wall);
2687
2688                                            if (self.ignoreVideos)
2689                                                update_wall();
2690                                        });
2691                                    }
2692                                },
2693                                onError: function onError(xhr) {
2694                                    if (xhr.status > 0) {
2695                                        Joomla.renderMessages(
2696                                            Joomla.ajaxErrorsMessages(xhr)
2697                                        );
2698                                    }
2699                                },
2700                            });
2701                        }, 800);
2702                    });
2703            }
2704
2705            // Filters
2706            self.container
2707                .querySelectorAll(".mwall-filters-group")
2708                .forEach(function (group) {
2709                    group
2710                        .querySelectorAll(".mwall-filter")
2711                        .forEach(function (a) {
2712                            a.addEventListener("click", function (e) {
2713                                e.preventDefault();
2714
2715                                if (
2716                                    self.container.classList.contains(
2717                                        "mwall-loading"
2718                                    )
2719                                )
2720                                    return false;
2721
2722                                var filterGroup = a
2723                                    .closest(".button-group")
2724                                    .getAttribute("data-filter-group");
2725                                var data_id = a.getAttribute("data-id");
2726
2727                                // Check whether filter exists
2728                                let index =
2729                                    self.filters[filterGroup].indexOf(data_id);
2730
2731                                // Store filter
2732                                if (
2733                                    filterGroup == "category" ||
2734                                    filterGroup == "tag" ||
2735                                    filterGroup == "date"
2736                                ) {
2737                                    if (parseInt(data_id, 10)) {
2738                                        // Multiple filters
2739                                        if (self.multipleFilters) {
2740                                            if (
2741                                                !self.filters[
2742                                                    filterGroup
2743                                                ].includes(data_id)
2744                                            )
2745                                                self.filters[filterGroup].push(
2746                                                    data_id
2747                                                );
2748                                            else
2749                                                self.filters[
2750                                                    filterGroup
2751                                                ].splice(index, 1);
2752                                        }
2753                                        // Single filter
2754                                        else {
2755                                            if (
2756                                                !self.filters[
2757                                                    filterGroup
2758                                                ].includes(data_id)
2759                                            )
2760                                                self.filters[filterGroup] = [
2761                                                    data_id,
2762                                                ];
2763                                            else self.filters[filterGroup] = [];
2764                                        }
2765                                    } else self.filters[filterGroup] = [];
2766                                } else self.filters[filterGroup] = data_id;
2767
2768                                var data_filter = a.getAttribute("data-filter");
2769
2770                                // Single filter
2771                                if (!self.multipleFilters) {
2772                                    if (
2773                                        group.querySelector(
2774                                            ".mwall-filter-active"
2775                                        )
2776                                    )
2777                                        group
2778                                            .querySelector(
2779                                                ".mwall-filter-active"
2780                                            )
2781                                            .classList.remove(
2782                                                "mwall-filter-active"
2783                                            );
2784                                }
2785                                // Multiple filters
2786                                else {
2787                                    if (!data_filter) {
2788                                        group
2789                                            .querySelectorAll(
2790                                                ".mwall-filter-active"
2791                                            )
2792                                            .forEach(function (a) {
2793                                                a.classList.remove(
2794                                                    "mwall-filter-active"
2795                                                );
2796                                            });
2797
2798                                        a.classList.add("mwall-filter-active");
2799                                    } else {
2800                                        group
2801                                            .querySelector(
2802                                                ".mwall-filter[data-filter='']"
2803                                            )
2804                                            .classList.remove(
2805                                                "mwall-filter-active"
2806                                            );
2807                                    }
2808                                }
2809
2810                                // Toggle active filter
2811                                if (self.filters[filterGroup].includes(data_id))
2812                                    a.classList.add("mwall-filter-active");
2813                                else a.classList.remove("mwall-filter-active");
2814
2815                                if (
2816                                    !group.querySelectorAll(
2817                                        ".mwall-filter-active"
2818                                    ).length
2819                                )
2820                                    group
2821                                        .querySelector(
2822                                            ".mwall-filter[data-filter='']"
2823                                        )
2824                                        .classList.add("mwall-filter-active");
2825
2826                                // Show filter name in dropdown
2827                                if (a.closest(".mwall-dropdown")) {
2828                                    if (
2829                                        typeof data_filter !==
2830                                            typeof undefined &&
2831                                        data_filter !== false
2832                                    ) {
2833                                        var filter_text;
2834
2835                                        if (data_filter.length) {
2836                                            if (index === -1)
2837                                                filter_text = a.textContent;
2838                                            // Deselect filter
2839                                            else if (index >= 0) {
2840                                                filter_text = a
2841                                                    .closest(".mwall-dropdown")
2842                                                    .querySelector(
2843                                                        ".dropdown-label span"
2844                                                    )
2845                                                    .getAttribute("data-label");
2846                                            }
2847                                        } else
2848                                            filter_text = a
2849                                                .closest(".mwall-dropdown")
2850                                                .querySelector(
2851                                                    ".dropdown-label span"
2852                                                )
2853                                                .getAttribute("data-label");
2854
2855                                        a
2856                                            .closest(".mwall-dropdown")
2857                                            .querySelector(
2858                                                ".dropdown-label span span"
2859                                            ).textContent = filter_text;
2860                                    }
2861                                }
2862
2863                                // Check if there is a pending ajax request
2864                                if (typeof ajax_request !== "undefined")
2865                                    ajax_request.abort();
2866
2867                                // Show loader
2868                                self.container.classList.add("mwall-loading");
2869                                a
2870                                    .closest(".mwall-filters-group")
2871                                    .querySelector(
2872                                        ".mwall-filters-loader"
2873                                    ).style.display = "inline-block";
2874
2875                                // Hide pagination
2876                                if (
2877                                    self.container.querySelector(
2878                                        ".mwall-pagination-wrapper"
2879                                    )
2880                                )
2881                                    self.container.querySelector(
2882                                        ".mwall-pagination-wrapper"
2883                                    ).style.display = "none";
2884
2885                                // Update url hash
2886                                if (self.urlHash) {
2887                                    if (self.filters[filterGroup].length)
2888                                        self.hash_filters.set(
2889                                            filterGroup,
2890                                            self.filters[filterGroup].join()
2891                                        );
2892                                    else self.hash_filters.delete(filterGroup);
2893
2894                                    self.updateHash();
2895                                }
2896
2897                                // Filters data
2898                                var data = {
2899                                    category: self.filters["category"],
2900                                    tag: self.filters["tag"],
2901                                    date: self.filters["date"],
2902                                    ordering: self.filters["ordering"],
2903                                    direction: self.filters["direction"],
2904                                    search: self.filters["search"],
2905                                };
2906
2907                                // Remove current items
2908                                var elems = self.wall.getItemElements();
2909                                self.wall.remove(elems);
2910
2911                                // Ajax request
2912                                var ajax_request = Joomla.request({
2913                                    url:
2914                                        self.path +
2915                                        "index.php?option=com_minitekwall&task=masonry.getContent&widget_id=" +
2916                                        self.widgetId +
2917                                        "&page=1" +
2918                                        "&tag_operator=" +
2919                                        self.tagsLogicalOperator +
2920                                        "&date_format=" +
2921                                        self.dateFiltersFormat +
2922                                        "&grid=" +
2923                                        self.layoutType +
2924                                        "&Itemid=" +
2925                                        self.itemid,
2926                                    method: "POST",
2927                                    data: JSON.stringify(data),
2928                                    onSuccess: (response, xhr) => {
2929                                        if (response.length > 3) {
2930                                            var newItems = self.htmlToElements(
2931                                                response,
2932                                                ".mwall-item"
2933                                            );
2934
2935                                            newItems.forEach(function (a) {
2936                                                a.style.visibility = "hidden";
2937                                                if (self.fluidHeight)
2938                                                    self.iso_container.appendChild(
2939                                                        a
2940                                                    );
2941                                            });
2942
2943                                            self.wall.once(
2944                                                "layoutComplete",
2945                                                function (items) {
2946                                                    self.resultsMessage(
2947                                                        self,
2948                                                        items
2949                                                    );
2950                                                }
2951                                            );
2952
2953                                            var imgLoad = imagesLoaded(
2954                                                self.iso_container,
2955                                                {
2956                                                    background:
2957                                                        ".mwall-photo-link",
2958                                                }
2959                                            );
2960
2961                                            imgLoad.on("done", function () {
2962                                                let update_wall = function () {
2963                                                    if (self.fluidHeight)
2964                                                        self.wall.appended(
2965                                                            newItems
2966                                                        );
2967                                                    else
2968                                                        self.wall.insert(
2969                                                            newItems
2970                                                        );
2971                                                    self.wall.arrange();
2972                                                    self.wall.updateSortData();
2973                                                    self.fixEqualHeights(
2974                                                        newItems
2975                                                    );
2976
2977                                                    newItems.forEach(function (
2978                                                        a
2979                                                    ) {
2980                                                        a.style.visibility =
2981                                                            "visible";
2982                                                    });
2983
2984                                                    // Hide loader
2985                                                    self.container.classList.remove(
2986                                                        "mwall-loading"
2987                                                    );
2988                                                    a
2989                                                        .closest(
2990                                                            ".mwall-filters-group"
2991                                                        )
2992                                                        .querySelector(
2993                                                            ".mwall-filters-loader"
2994                                                        ).style.display =
2995                                                        "none";
2996
2997                                                    if (self.pagination != 0)
2998                                                        self.updatePagination(
2999                                                            data
3000                                                        );
3001                                                };
3002
3003                                                if (self.videoSource)
3004                                                    self.videosReady(
3005                                                        update_wall
3006                                                    );
3007
3008                                                if (self.ignoreVideos)
3009                                                    update_wall();
3010                                            });
3011                                        }
3012                                    },
3013                                    onError: function onError(xhr) {
3014                                        if (xhr.status > 0) {
3015                                            Joomla.renderMessages(
3016                                                Joomla.ajaxErrorsMessages(xhr)
3017                                            );
3018                                        }
3019                                    },
3020                                });
3021                            });
3022                        });
3023                });
3024
3025            self.dropdownFilters();
3026
3027            // Ordering / Direction
3028            if (self.container.querySelector(".mwall-sortings-group")) {
3029                self.container
3030                    .querySelectorAll(".mwall-sortings-group")
3031                    .forEach(function (group) {
3032                        group
3033                            .querySelectorAll(".mwall-filter")
3034                            .forEach(function (a) {
3035                                a.addEventListener("click", function (e) {
3036                                    e.preventDefault();
3037
3038                                    if (
3039                                        self.container.classList.contains(
3040                                            "mwall-loading"
3041                                        )
3042                                    )
3043                                        return false;
3044
3045                                    // Show sorting name in dropdown
3046                                    if (a.closest(".mwall-dropdown")) {
3047                                        var sorting_text = a.textContent;
3048                                        a
3049                                            .closest(".mwall-dropdown")
3050                                            .querySelector(
3051                                                ".dropdown-label span span"
3052                                            ).textContent = sorting_text;
3053                                    }
3054
3055                                    // Change active class on sorting filters
3056                                    a.closest(".mwall-sortings-group")
3057                                        .querySelectorAll(".mwall-filter")
3058                                        .forEach(function (a) {
3059                                            a.classList.remove(
3060                                                "mwall-filter-active"
3061                                            );
3062                                        });
3063                                    a.classList.add("mwall-filter-active");
3064
3065                                    // Store ordering
3066                                    if (a.closest(".sorting-group-filters"))
3067                                        self.filters["ordering"] =
3068                                            a.getAttribute("data-sort-value");
3069
3070                                    // Store direction
3071                                    if (a.closest(".sorting-group-direction"))
3072                                        self.filters["direction"] =
3073                                            a.getAttribute("data-sort-value");
3074
3075                                    // Check if there is a pending ajax request
3076                                    if (typeof ajax_request !== "undefined")
3077                                        ajax_request.abort();
3078
3079                                    // Show loader
3080                                    self.container.classList.add(
3081                                        "mwall-loading"
3082                                    );
3083                                    a
3084                                        .closest(".mwall-sortings-group")
3085                                        .querySelector(
3086                                            ".mwall-filters-loader"
3087                                        ).style.display = "inline-block";
3088
3089                                    // Hide pagination
3090                                    if (
3091                                        self.container.querySelector(
3092                                            ".mwall-pagination-wrapper"
3093                                        )
3094                                    )
3095                                        self.container.querySelector(
3096                                            ".mwall-pagination-wrapper"
3097                                        ).style.display = "none";
3098
3099                                    // Update url hash
3100                                    if (self.urlHash) {
3101                                        let filter_type;
3102
3103                                        if (a.closest(".sorting-group-filters"))
3104                                            filter_type = "ordering";
3105                                        else if (
3106                                            a.closest(
3107                                                ".sorting-group-direction"
3108                                            )
3109                                        )
3110                                            filter_type = "direction";
3111
3112                                        self.hash_filters.set(
3113                                            filter_type,
3114                                            self.filters[filter_type]
3115                                        );
3116                                        self.updateHash();
3117                                    }
3118
3119                                    // Filters data
3120                                    var data = {
3121                                        category: self.filters["category"],
3122                                        tag: self.filters["tag"],
3123                                        date: self.filters["date"],
3124                                        ordering: self.filters["ordering"],
3125                                        direction: self.filters["direction"],
3126                                        search: self.filters["search"],
3127                                    };
3128
3129                                    // Remove current items
3130                                    var elems = self.wall.getItemElements();
3131                                    self.wall.remove(elems);
3132
3133                                    // Ajax request
3134                                    var ajax_request = Joomla.request({
3135                                        url:
3136                                            self.path +
3137                                            "index.php?option=com_minitekwall&task=masonry.getContent&widget_id=" +
3138                                            self.widgetId +
3139                                            "&page=1" +
3140                                            "&tag_operator=" +
3141                                            self.tagsLogicalOperator +
3142                                            "&date_format=" +
3143                                            self.dateFiltersFormat +
3144                                            "&grid=" +
3145                                            self.layoutType +
3146                                            "&Itemid=" +
3147                                            self.itemid,
3148                                        method: "POST",
3149                                        data: JSON.stringify(data),
3150                                        onSuccess: (response, xhr) => {
3151                                            if (response.length > 3) {
3152                                                var newItems =
3153                                                    self.htmlToElements(
3154                                                        response,
3155                                                        ".mwall-item"
3156                                                    );
3157
3158                                                newItems.forEach(function (a) {
3159                                                    a.style.visibility =
3160                                                        "hidden";
3161                                                    if (self.fluidHeight)
3162                                                        self.iso_container.appendChild(
3163                                                            a
3164                                                        );
3165                                                });
3166
3167                                                var imgLoad = imagesLoaded(
3168                                                    self.iso_container,
3169                                                    {
3170                                                        background:
3171                                                            ".mwall-photo-link",
3172                                                    }
3173                                                );
3174
3175                                                imgLoad.on("done", function () {
3176                                                    let update_wall =
3177                                                        function () {
3178                                                            if (
3179                                                                self.fluidHeight
3180                                                            )
3181                                                                self.wall.appended(
3182                                                                    newItems
3183                                                                );
3184                                                            else
3185                                                                self.wall.insert(
3186                                                                    newItems
3187                                                                );
3188                                                            self.wall.arrange();
3189                                                            self.wall.updateSortData();
3190                                                            self.fixEqualHeights(
3191                                                                newItems
3192                                                            );
3193
3194                                                            newItems.forEach(
3195                                                                function (a) {
3196                                                                    a.style.visibility =
3197                                                                        "visible";
3198                                                                }
3199                                                            );
3200
3201                                                            // Hide loader
3202                                                            self.container.classList.remove(
3203                                                                "mwall-loading"
3204                                                            );
3205                                                            a
3206                                                                .closest(
3207                                                                    ".mwall-sortings-group"
3208                                                                )
3209                                                                .querySelector(
3210                                                                    ".mwall-filters-loader"
3211                                                                ).style.display =
3212                                                                "none";
3213
3214                                                            if (
3215                                                                self.pagination !=
3216                                                                0
3217                                                            )
3218                                                                self.updatePagination(
3219                                                                    data
3220                                                                );
3221                                                        };
3222
3223                                                    if (self.videoSource)
3224                                                        self.videosReady(
3225                                                            update_wall
3226                                                        );
3227
3228                                                    if (self.ignoreVideos)
3229                                                        update_wall();
3230                                                });
3231                                            }
3232                                        },
3233                                        onError: function onError(xhr) {
3234                                            if (xhr.status > 0) {
3235                                                Joomla.renderMessages(
3236                                                    Joomla.ajaxErrorsMessages(
3237                                                        xhr
3238                                                    )
3239                                                );
3240                                            }
3241                                        },
3242                                    });
3243                                });
3244                            });
3245                    });
3246            }
3247
3248            self.dropdownSortings();
3249
3250            // Reset button
3251            if (self.container.querySelector(".btn-reset")) {
3252                self.container
3253                    .querySelector(".btn-reset")
3254                    .addEventListener("click", function (e) {
3255                        e.preventDefault();
3256
3257                        self.resetStaticFilters();
3258                    });
3259            }
3260        }
3261
3262        getHashFilters() {
3263            const hash_filters = new URLSearchParams(
3264                window.location.hash.substring(1)
3265            );
3266
3267            return hash_filters;
3268        }
3269
3270        escapeRegex(string) {
3271            return string.replace(/[/\-\\^$*+?.()|[\]{}]/g, "\\$&");
3272        }
3273
3274        dynamicSearch() {
3275            const self = this;
3276
3277            if (self.container.querySelector(".mwall-search-input")) {
3278                var search_regex;
3279
3280                self.container
3281                    .querySelector(".mwall-search-input")
3282                    .addEventListener("input", function (e) {
3283                        e.preventDefault();
3284                        let _this = e.target;
3285
3286                        // Wait for 800ms before searching
3287                        window.clearTimeout(self.timer);
3288
3289                        self.timer = window.setTimeout(function () {
3290                            // Sanitize value
3291                            let value = self.escapeRegex(_this.value);
3292                            self.filters["search"] = value;
3293                            search_regex = new RegExp(value, "gi");
3294
3295                            // Get active filters
3296                            var filterValue = "";
3297
3298                            // Multiple filters
3299                            if (self.multipleFilters) {
3300                                // Create all permutations from all filters
3301                                var permutations = self.combineArrays(
3302                                    self.filters
3303                                );
3304
3305                                filterValue = permutations.join(", ");
3306                            }
3307                            // Single filters
3308                            else {
3309                                for (var prop in self.filters) {
3310                                    if (prop == "search") continue;
3311
3312                                    for (var filter in prop) {
3313                                        if (self.filters[prop][filter])
3314                                            filterValue +=
3315                                                self.filters[prop][filter];
3316                                    }
3317                                }
3318                            }
3319
3320                            // Hide results message
3321                            self.container.querySelector(
3322                                ".mwall-no-items"
3323                            ).style.display = "none";
3324
3325                            // Show reset button in pagination
3326                            if (
3327                                self.container.querySelector(
3328                                    ".mwall-reset-btn"
3329                                ) &&
3330                                value
3331                            )
3332                                self.container.querySelector(
3333                                    ".mwall-reset-btn"
3334                                ).style.display = "inline-block";
3335
3336                            // Show results message
3337                            self.wall.once("layoutComplete", function (items) {
3338                                self.resultsMessage(self, items);
3339                            });
3340
3341                            // Update Isotope
3342                            self.wall.arrange({
3343                                filter: function () {
3344                                    if (this.querySelector(".mwall-title")) {
3345                                        var filtersResult = true;
3346
3347                                        // Search filter
3348                                        var title =
3349                                            this.querySelector(
3350                                                ".mwall-title"
3351                                            ).textContent;
3352
3353                                        var searchResult = search_regex
3354                                            ? title.match(search_regex)
3355                                            : true;
3356
3357                                        // Filters
3358                                        filtersResult = filterValue
3359                                            ? this.matches(filterValue)
3360                                            : true;
3361
3362                                        return filtersResult && searchResult;
3363                                    } else return true;
3364                                },
3365                            });
3366
3367                            self.resizeItems();
3368
3369                            // Hide reset button in pagination
3370                            if (
3371                                value == "" &&
3372                                self.container.querySelector(".mwall-reset-btn")
3373                            )
3374                                self.container.querySelector(
3375                                    ".mwall-reset-btn"
3376                                ).style.display = "none";
3377                        }, 800);
3378                    });
3379            }
3380        }
3381
3382        dynamicFilters() {
3383            const self = this;
3384
3385            if (self.container.querySelector(".mwall-filters-container")) {
3386                self.container
3387                    .querySelector(".mwall-filters-container")
3388                    .addEventListener("click", function (e) {
3389                        e.preventDefault();
3390
3391                        // Hide results message
3392                        self.container.querySelector(
3393                            ".mwall-no-items"
3394                        ).style.display = "none";
3395
3396                        if (
3397                            e.target &&
3398                            e.target.classList.contains("mwall-filter")
3399                        ) {
3400                            var _this = e.target;
3401                            var data_filter = _this.getAttribute("data-filter");
3402
3403                            // Show reset button in pagination
3404                            if (
3405                                self.container.querySelector(".mwall-reset-btn")
3406                            )
3407                                self.container.querySelector(
3408                                    ".mwall-reset-btn"
3409                                ).style.display = "inline-block";
3410
3411                            // Get group key
3412                            var filterGroup = _this
3413                                .closest(".button-group")
3414                                .getAttribute("data-filter-group");
3415
3416                            // Check whether filter exists
3417                            let index =
3418                                self.filters[filterGroup].indexOf(data_filter);
3419
3420                            // Multiple filters
3421                            if (self.multipleFilters) {
3422                                // Add filter to group if it does not exist
3423                                if (index === -1) {
3424                                    if (data_filter)
3425                                        self.filters[filterGroup].push(
3426                                            data_filter
3427                                        );
3428                                    else self.filters[filterGroup] = [];
3429                                } else {
3430                                    self.filters[filterGroup].splice(index, 1);
3431                                }
3432
3433                                // Create all permutations from all filters
3434                                var permutations = self.combineArrays(
3435                                    self.filters
3436                                );
3437
3438                                var filterValue = permutations.join(", ");
3439                            }
3440                            // Single filters
3441                            else {
3442                                // Add filter to group if it does not exist
3443                                if (index === -1) {
3444                                    if (data_filter)
3445                                        self.filters[filterGroup] = [
3446                                            data_filter,
3447                                        ];
3448                                    else self.filters[filterGroup] = [];
3449                                } else {
3450                                    self.filters[filterGroup] = [];
3451                                }
3452
3453                                var filterValue = "";
3454
3455                                for (var prop in self.filters) {
3456                                    if (prop == "search") continue;
3457
3458                                    for (var filter in prop) {
3459                                        if (self.filters[prop][filter])
3460                                            filterValue +=
3461                                                self.filters[prop][filter];
3462                                    }
3463                                }
3464                            }
3465
3466                            // Show filter name in dropdown
3467                            if (_this.closest(".mwall-dropdown")) {
3468                                if (
3469                                    typeof data_filter !== typeof undefined &&
3470                                    data_filter !== false
3471                                ) {
3472                                    var filter_text;
3473
3474                                    if (data_filter.length) {
3475                                        if (index === -1)
3476                                            filter_text = _this.textContent;
3477                                        // Deselect filter
3478                                        else if (index >= 0) {
3479                                            filter_text = _this
3480                                                .closest(".mwall-dropdown")
3481                                                .querySelector(
3482                                                    ".dropdown-label span"
3483                                                )
3484                                                .getAttribute("data-label");
3485                                        }
3486                                    } else
3487                                        filter_text = _this
3488                                            .closest(".mwall-dropdown")
3489                                            .querySelector(
3490                                                ".dropdown-label span"
3491                                            )
3492                                            .getAttribute("data-label");
3493
3494                                    _this
3495                                        .closest(".mwall-dropdown")
3496                                        .querySelector(
3497                                            ".dropdown-label span span"
3498                                        ).textContent = filter_text;
3499                                }
3500                            }
3501
3502                            // Show results message
3503                            self.wall.once("layoutComplete", function (items) {
3504                                self.resultsMessage(self, items);
3505                            });
3506
3507                            // Filters & Search
3508                            if (
3509                                self.container.querySelector(
3510                                    ".mwall-search-input"
3511                                ) &&
3512                                self.filters["search"].length
3513                            ) {
3514                                self.wall.arrange({
3515                                    filter: function () {
3516                                        if (
3517                                            this.querySelector(".mwall-title")
3518                                        ) {
3519                                            // Search filter
3520                                            var search_regex = new RegExp(
3521                                                self.filters["search"],
3522                                                "gi"
3523                                            );
3524                                            var title =
3525                                                this.querySelector(
3526                                                    ".mwall-title"
3527                                                ).textContent;
3528
3529                                            var searchResult = search_regex
3530                                                ? title.match(search_regex)
3531                                                : true;
3532
3533                                            // Filters
3534                                            var filtersResult = filterValue
3535                                                ? this.matches(filterValue)
3536                                                : true;
3537
3538                                            return (
3539                                                filtersResult && searchResult
3540                                            );
3541                                        } else return true;
3542                                    },
3543                                });
3544                            }
3545                            // Filters
3546                            else {
3547                                self.wall.arrange({
3548                                    filter: filterValue,
3549                                });
3550                            }
3551
3552                            self.resizeItems();
3553
3554                            // Hide reset button in pagination
3555                            if (
3556                                filterValue == "" &&
3557                                self.container.querySelector(".mwall-reset-btn")
3558                            )
3559                                self.container.querySelector(
3560                                    ".mwall-reset-btn"
3561                                ).style.display = "none";
3562
3563                            // Update url hash
3564                            if (self.urlHash) {
3565                                if (self.filters[filterGroup].length)
3566                                    self.hash_filters.set(
3567                                        filterGroup,
3568                                        self.filters[filterGroup].join()
3569                                    );
3570                                else self.hash_filters.delete(filterGroup);
3571
3572                                self.updateHash();
3573                            }
3574                        }
3575                    });
3576            }
3577
3578            self.activeFilters();
3579            self.dropdownFilters();
3580
3581            // Ordering
3582            if (self.container.querySelector(".sorting-group-filters")) {
3583                self.container
3584                    .querySelector(".sorting-group-filters")
3585                    .querySelectorAll(".mwall-filter")
3586                    .forEach(function (a) {
3587                        a.addEventListener("click", function (e) {
3588                            e.preventDefault();
3589
3590                            // Show sorting name in dropdown
3591                            if (this.closest(".mwall-dropdown")) {
3592                                var sorting_text = this.textContent;
3593                                this.closest(".mwall-dropdown").querySelector(
3594                                    ".dropdown-label span span"
3595                                ).textContent = sorting_text;
3596                            }
3597
3598                            var sortValue =
3599                                this.getAttribute("data-sort-value");
3600
3601                            // Update Isotope
3602                            self.wall.arrange({
3603                                sortBy: [sortValue, "id"],
3604                            });
3605
3606                            self.resizeItems();
3607
3608                            // Change active class on sorting filters
3609                            self.container
3610                                .querySelector(".sorting-group-filters")
3611                                .querySelectorAll(".mwall-filter")
3612                                .forEach(function (a) {
3613                                    a.classList.remove("mwall-filter-active");
3614                                });
3615                            this.classList.add("mwall-filter-active");
3616
3617                            // Update url hash
3618                            if (self.urlHash) {
3619                                self.hash_filters.set("ordering", sortValue);
3620                                self.updateHash();
3621                            }
3622                        });
3623                    });
3624            }
3625
3626            // Direction
3627            if (self.container.querySelector(".sorting-group-direction")) {
3628                self.container
3629                    .querySelector(".sorting-group-direction")
3630                    .querySelectorAll(".mwall-filter")
3631                    .forEach(function (a) {
3632                        a.addEventListener("click", function (e) {
3633                            e.preventDefault();
3634
3635                            // Show sorting name in dropdown
3636                            if (this.closest(".mwall-dropdown")) {
3637                                var sorting_text = this.textContent;
3638                                this.closest(".mwall-dropdown").querySelector(
3639                                    ".dropdown-label span span"
3640                                ).textContent = sorting_text;
3641                            }
3642
3643                            var sortDirection =
3644                                this.getAttribute("data-sort-value");
3645                            var sort_Direction;
3646
3647                            if (sortDirection == "asc") sort_Direction = true;
3648                            else sort_Direction = false;
3649
3650                            // Update Isotope
3651                            self.wall.arrange({
3652                                sortAscending: sort_Direction,
3653                            });
3654
3655                            self.resizeItems();
3656
3657                            // Change active class on sorting direction
3658                            self.container
3659                                .querySelector(".sorting-group-direction")
3660                                .querySelectorAll(".mwall-filter")
3661                                .forEach(function (a) {
3662                                    a.classList.remove("mwall-filter-active");
3663                                });
3664                            this.classList.add("mwall-filter-active");
3665
3666                            // Update url hash
3667                            if (self.urlHash) {
3668                                self.hash_filters.set(
3669                                    "direction",
3670                                    sortDirection
3671                                );
3672                                self.updateHash();
3673                            }
3674                        });
3675                    });
3676            }
3677
3678            self.dropdownSortings();
3679        }
3680
3681        // Reset dynamic filters and sortings
3682        resetFilters() {
3683            const self = this;
3684
3685            self.container.querySelector(".mwall-no-items").style.display =
3686                "none";
3687
3688            // Reset active buttons
3689            self.container
3690                .querySelectorAll(".button-group")
3691                .forEach(function (buttonGroup) {
3692                    if (buttonGroup.querySelector(".mwall-filter-active"))
3693                        buttonGroup
3694                            .querySelectorAll(".mwall-filter-active")
3695                            .forEach(function (a) {
3696                                a.classList.remove("mwall-filter-active");
3697                            });
3698
3699                    buttonGroup
3700                        .querySelector("li:first-child a")
3701                        .classList.add("mwall-filter-active");
3702
3703                    // Reset filters
3704                    var filterGroup =
3705                        buttonGroup.getAttribute("data-filter-group");
3706                    self.filters[filterGroup] = [];
3707
3708                    // Hide reset button in pagination
3709                    if (self.container.querySelector(".mwall-reset-btn"))
3710                        self.container.querySelector(
3711                            ".mwall-reset-btn"
3712                        ).style.display = "none";
3713                });
3714
3715            // Reset dropdown filters text
3716            self.container
3717                .querySelectorAll(".mwall-dropdown")
3718                .forEach(function (dropdownGroup) {
3719                    var filter_text = dropdownGroup
3720                        .querySelector(".dropdown-label span")
3721                        .getAttribute("data-label");
3722                    dropdownGroup.querySelector(
3723                        ".dropdown-label span span"
3724                    ).textContent = filter_text;
3725                });
3726
3727            // Reset sortings
3728            self.container
3729                .querySelectorAll(".sorting-group-filters")
3730                .forEach(function (sortingGroup) {
3731                    sortingGroup
3732                        .querySelectorAll(".mwall-filter")
3733                        .forEach(function (a) {
3734                            a.classList.remove("mwall-filter-active");
3735                        });
3736                    if (
3737                        sortingGroup.querySelector(
3738                            'li a[data-sort-value="' + self.sortBy[0] + '"]'
3739                        )
3740                    ) {
3741                        sortingGroup
3742                            .querySelector(
3743                                'li a[data-sort-value="' + self.sortBy[0] + '"]'
3744                            )
3745                            .classList.add("mwall-filter-active");
3746                    }
3747                });
3748
3749            self.container
3750                .querySelectorAll(".sorting-group-direction")
3751                .forEach(function (sortingGroupDirection) {
3752                    sortingGroupDirection
3753                        .querySelector(".mwall-filter-active")
3754                        .classList.remove("mwall-filter-active");
3755                    sortingGroupDirection
3756                        .querySelector(
3757                            'li a[data-sort-value="' + self.sortDirection + '"]'
3758                        )
3759                        .classList.add("mwall-filter-active");
3760                });
3761
3762            // Reset search filter
3763            if (self.container.querySelector(".mwall-search-input")) {
3764                self.container.querySelector(".mwall-search-input").value = "";
3765                self.filters["search"] = "";
3766            }
3767
3768            // Update Isotope
3769            self.wall.arrange({
3770                filter: "",
3771                sortBy: self.sortBy,
3772                sortAscending: self.sortAscending,
3773            });
3774
3775            if (self.urlHash) self.removeHash();
3776
3777            self.resizeItems();
3778        }
3779
3780        triggerResetButtons() {
3781            const self = this;
3782
3783            document
3784                .querySelectorAll(
3785                    "#mwall_reset_" +
3786                        this.widgetId +
3787                        ", #mwall_container_" +
3788                        this.widgetId +
3789                        " .mwall-reset-btn"
3790                )
3791                .forEach(function (a) {
3792                    a.addEventListener("click", function (e) {
3793                        e.preventDefault();
3794
3795                        self.resetFilters();
3796                    });
3797                });
3798        }
3799
3800        removeHash() {
3801            const self = this;
3802            self.hash_filters = new URLSearchParams();
3803
3804            history.pushState(
3805                "",
3806                document.title,
3807                window.location.pathname + window.location.search
3808            );
3809        }
3810
3811        updateHash() {
3812            const self = this;
3813
3814            history.pushState(
3815                "",
3816                document.title,
3817                "#" + self.hash_filters.toString()
3818            );
3819        }
3820
3821        doneBrowserResizing() {
3822            const self = this;
3823
3824            self.fixEqualHeights("all");
3825            self.wall.arrange();
3826        }
3827
3828        fixEqualHeights(items) {
3829            const self = this;
3830
3831            if (
3832                this.gridType == 98 &&
3833                this.layoutMode == "fitRows" &&
3834                this.dbPosition == "below" &&
3835                this.equalHeight
3836            ) {
3837                var max_height = 0;
3838
3839                if (items == "all") {
3840                    this.container
3841                        .querySelectorAll(".mwall-item-inner")
3842                        .forEach(function (a) {
3843                            a.style.height = "auto";
3844
3845                            if (a.offsetHeight > max_height)
3846                                max_height = a.offsetHeight;
3847                        });
3848                } else {
3849                    items.forEach(function (a) {
3850                        var _this_item_inner =
3851                            a.querySelector(".mwall-item-inner");
3852                        _this_item_inner.style.height = "auto";
3853
3854                        if (_this_item_inner.offsetHeight > max_height)
3855                            max_height = _this_item_inner.offsetHeight;
3856                    });
3857                }
3858
3859                this.container
3860                    .querySelectorAll(".mwall-item-inner")
3861                    .forEach(function (a) {
3862                        a.style.height = max_height + "px";
3863                    });
3864
3865                setTimeout(function () {
3866                    self.wall.arrange();
3867                }, 1);
3868            }
3869        }
3870
3871        createSpinner(divIdentifier) {
3872            var spinner_options = {
3873                lines: 9,
3874                length: 4,
3875                width: 3,
3876                radius: 3,
3877                corners: 1,
3878                rotate: 0,
3879                direction: 1,
3880                color: "#000",
3881                speed: 1,
3882                trail: 52,
3883                shadow: false,
3884                hwaccel: false,
3885                className: "spinner",
3886                zIndex: 2e9,
3887                top: "50%",
3888                left: "50%",
3889            };
3890
3891            var target = divIdentifier;
3892
3893            if (target) {
3894                var spinner = new Spinner(spinner_options).spin();
3895                target.innerHTML = "";
3896                target.appendChild(spinner.el);
3897            }
3898
3899            return;
3900        }
3901
3902        htmlToElements(htmlString, selector) {
3903            var div = document.createElement("div");
3904            div.innerHTML = htmlString.trim();
3905
3906            return div.querySelectorAll(selector);
3907        }
3908
3909        initModalMessages() {
3910            var zoomWall = document.querySelector("#zoomWall_" + this.widgetId);
3911
3912            if (!zoomWall) return;
3913
3914            zoomWall.addEventListener("show.bs.modal", function (e) {
3915                // Button that triggered the modal
3916                var button = e.relatedTarget;
3917
3918                // Update the title
3919                if (zoomWall.querySelector(".modal-title")) {
3920                    var title = button.getAttribute("data-mw-title");
3921                    zoomWall.querySelector(".modal-title").textContent = title;
3922                }
3923
3924                // Update the image
3925                var image = button.getAttribute("data-src");
3926                zoomWall.querySelector("img").setAttribute("src", image);
3927            });
3928
3929            zoomWall.addEventListener("hidden.bs.modal", function (e) {
3930                zoomWall.querySelector("img").setAttribute("src", "");
3931            });
3932        }
3933    }
3934
3935    window.Mwall = {
3936        initialise: (options, id, count, source, path, elements, itemid) =>
3937            new Mwall(options, id, count, source, path, elements, itemid),
3938    };
3939})(document, Joomla);

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.