{"id":44170,"date":"2023-09-26T12:34:57","date_gmt":"2023-09-26T10:34:57","guid":{"rendered":"https:\/\/test.asianfilmfestival.barcelona\/2023\/search\/"},"modified":"2025-09-24T15:38:13","modified_gmt":"2025-09-24T13:38:13","slug":"search","status":"publish","type":"page","link":"https:\/\/asianfilmfestival.barcelona\/2025\/search\/","title":{"rendered":"Search"},"content":{"rendered":"\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-ln0hpjgw-86c14ce76e457470e4b58c1bce229845\">\n.avia-section.av-ln0hpjgw-86c14ce76e457470e4b58c1bce229845{\nbackground-color:#e5e4e2;\nbackground-image:unset;\n}\n<\/style>\n<div id='av_section_1'  class='avia-section av-ln0hpjgw-86c14ce76e457470e4b58c1bce229845 main_color avia-section-default avia-no-border-styling  avia-builder-el-0  avia-builder-el-no-sibling  avia-bg-style-scroll container_wrap fullsize'  ><div class='container av-section-cont-open' ><main  role=\"main\" itemprop=\"mainContentOfPage\"  class='template-page content  av-content-full alpha units'><div class='post-entry post-entry-type-page post-entry-44170'><div class='entry-content-wrapper clearfix'>\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-1amg1ig-ed9a8ef185fc33f36bd8c4a93f0b3430\">\n.flex_column.av-1amg1ig-ed9a8ef185fc33f36bd8c4a93f0b3430{\nbackground-color:#e5e4e2;\n}\n<\/style>\n<div  class='flex_column av-1amg1ig-ed9a8ef185fc33f36bd8c4a93f0b3430 av_one_full  avia-builder-el-1  avia-builder-el-no-sibling  first flex_column_div  '     ><section  class='av_textblock_section av-ln06lnsc-a27745ac765fea51b6fffa6d19aa1b2c '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/CreativeWork\" ><div class='avia_textblock'  itemprop=\"text\" >    <div x-data=\"portfolioFilters()\" x-init=\"init()\" class=\"portfolio-filters-app\">\n        <!-- Loading Overlay -->\n        <div x-show=\"loading\" x-transition class=\"loading-overlay\">\n            <div class=\"spinner\"><\/div>\n        <\/div>\n\n        <!-- Toggle Button per Mobile -->\n        <button @click=\"toggleFilters()\" class=\"filters-toggle-btn\">\n            <span>Film Filters<\/span>\n            <svg class=\"filters-toggle-icon\" :class=\"{ 'rotated': !filtersVisible }\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                <path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\" \/>\n            <\/svg>\n        <\/button>\n\n        <!-- Filters Container -->\n        <div class=\"portfolio-filters-container\" :class=\"{ 'filters-hidden': !filtersVisible, 'filters-visible': filtersVisible }\">\n            <!-- First Row - Main Filters -->\n            <div class=\"filters-row-main\">\n\n                <!-- Date Filter Dropdown -->\n                <div class=\"custom-dropdown\" x-data=\"{ open: false }\" @click.outside=\"open = false\">\n                    <button @click=\"open = !open\" class=\"dropdown-button\">\n                        <span x-text=\"getDateFilterLabel()\"><\/span>\n                        <svg class=\"dropdown-arrow\" :class=\"{ 'rotated': open }\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                            <path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\" \/>\n                        <\/svg>\n                    <\/button>\n\n                    <div x-show=\"open\" x-transition class=\"dropdown-menu\">\n                        <template x-for=\"date in availableDates\" :key=\"date.slug\">\n                            <label class=\"dropdown-option\">\n                                <input\n                                    type=\"checkbox\"\n                                    :value=\"date.slug\"\n                                    x-model=\"filters.date\"\n                                    @change=\"applyFilters()\">\n                                <span x-text=\"`${date.name} (${date.count})`\"><\/span>\n                            <\/label>\n                        <\/template>\n                    <\/div>\n                <\/div>\n\n                <!-- Country Filter Dropdown -->\n                <div class=\"custom-dropdown\" x-data=\"{ open: false }\" @click.outside=\"open = false\">\n                    <button @click=\"open = !open\" class=\"dropdown-button\">\n                        <span x-text=\"getCountryFilterLabel()\"><\/span>\n                        <svg class=\"dropdown-arrow\" :class=\"{ 'rotated': open }\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                            <path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\" \/>\n                        <\/svg>\n                    <\/button>\n\n                    <div x-show=\"open\" x-transition class=\"dropdown-menu\">\n                        <template x-for=\"country in availableCountries\" :key=\"country.name\">\n                            <label class=\"dropdown-option\">\n                                <input\n                                    type=\"checkbox\"\n                                    :value=\"country.name\"\n                                    x-model=\"filters.country\"\n                                    @change=\"applyFilters()\">\n                                <span x-text=\"`${country.name} (${country.count})`\"><\/span>\n                            <\/label>\n                        <\/template>\n                    <\/div>\n                <\/div>\n\n                <!-- Section Filter Dropdown -->\n                <div class=\"custom-dropdown\" x-data=\"{ open: false }\" @click.outside=\"open = false\">\n                    <button @click=\"open = !open\" class=\"dropdown-button\">\n                        <span x-text=\"getSectionFilterLabel()\"><\/span>\n                        <svg class=\"dropdown-arrow\" :class=\"{ 'rotated': open }\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                            <path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\" \/>\n                        <\/svg>\n                    <\/button>\n\n                    <div x-show=\"open\" x-transition class=\"dropdown-menu\">\n                        <template x-for=\"section in availableSections\" :key=\"section.name\">\n                            <label class=\"dropdown-option\">\n                                <input\n                                    type=\"checkbox\"\n                                    :value=\"section.name\"\n                                    x-model=\"filters.section\"\n                                    @change=\"applyFilters()\">\n                                <span x-text=\"`${section.name} (${section.count})`\"><\/span>\n                            <\/label>\n                        <\/template>\n                    <\/div>\n                <\/div>\n\n                <button @click=\"resetFilters()\" class=\"reset-button\">RESET<\/button>\n            <\/div>\n\n            <!-- Second Row - Search and Sort -->\n            <div class=\"filters-row-search\">\n\n                <div class=\"search-wrapper\">\n                    <input\n                        type=\"text\"\n                        x-model=\"searchQuery\"\n                        @input.debounce.300ms=\"applyFilters()\"\n                        placeholder=\"Search by title...\"\n                        class=\"search-input\">\n                    <svg class=\"search-icon\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n                        <circle cx=\"11\" cy=\"11\" r=\"8\"><\/circle>\n                        <path d=\"m21 21-4.35-4.35\"><\/path>\n                    <\/svg>\n                <\/div>\n\n                <span class=\"sort-label\">Sort by:<\/span>\n\n                <div class=\"sort-options\">\n                    <div class=\"sort-radio\">\n                        <input\n                            type=\"radio\"\n                            id=\"sort-title\"\n                            value=\"title\"\n                            x-model=\"sortBy\"\n                            @change=\"applyFilters()\">\n                        <label for=\"sort-title\">Film Title<\/label>\n                    <\/div>\n                    <div class=\"sort-radio\">\n                        <input\n                            type=\"radio\"\n                            id=\"sort-date\"\n                            value=\"date\"\n                            x-model=\"sortBy\"\n                            @change=\"applyFilters()\">\n                        <label for=\"sort-date\">Projection Date<\/label>\n                    <\/div>\n                <\/div>\n\n                <!-- View Toggle Buttons -->\n                <div class=\"view-toggle\">\n                    <button\n                        @click=\"switchToGridView()\"\n                        :class=\"{ 'active': viewMode === 'grid' }\"\n                        class=\"view-toggle-btn\"\n                        title=\"Grid View\">\n                        <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-layout-grid\">\n                            <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" \/>\n                            <path d=\"M4 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z\" \/>\n                            <path d=\"M14 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z\" \/>\n                            <path d=\"M4 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z\" \/>\n                            <path d=\"M14 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z\" \/>\n                        <\/svg>\n                    <\/button>\n                    <button\n                        @click=\"switchToCalendarView()\"\n                        :class=\"{ 'active': viewMode === 'calendar' }\"\n                        class=\"view-toggle-btn\"\n                        title=\"Calendar View\">\n                        <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-menu-2\">\n                            <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" \/>\n                            <path d=\"M4 6l16 0\" \/>\n                            <path d=\"M4 12l16 0\" \/>\n                            <path d=\"M4 18l16 0\" \/>\n                        <\/svg>\n                    <\/button>\n                <\/div>\n            <\/div>\n\n            <!-- Active Filters Display -->\n            <div x-show=\"hasActiveFilters()\" x-transition class=\"active-filters\">\n                <div class=\"filter-tags\">\n                    <template x-for=\"dateSlug in filters.date\" :key=\"'date-' + dateSlug\">\n                        <div class=\"filter-tag\">\n                            <span x-text=\"getDateLabel(dateSlug)\"><\/span>\n                            <span @click=\"removeFilter('date', dateSlug)\" class=\"filter-tag-remove\">\u00d7<\/span>\n                        <\/div>\n                    <\/template>\n\n                    <template x-for=\"country in filters.country\" :key=\"'country-' + country\">\n                        <div class=\"filter-tag\">\n                            <span x-text=\"country\"><\/span>\n                            <span @click=\"removeFilter('country', country)\" class=\"filter-tag-remove\">\u00d7<\/span>\n                        <\/div>\n                    <\/template>\n\n                    <template x-for=\"section in filters.section\" :key=\"'section-' + section\">\n                        <div class=\"filter-tag\">\n                            <span x-text=\"section\"><\/span>\n                            <span @click=\"removeFilter('section', section)\" class=\"filter-tag-remove\">\u00d7<\/span>\n                        <\/div>\n                    <\/template>\n\n                    <template x-if=\"searchQuery\">\n                        <div class=\"filter-tag\">\n                            <span>Search: <span x-text=\"searchQuery\"><\/span><\/span>\n                            <span @click=\"searchQuery = ''; applyFilters()\" class=\"filter-tag-remove\">\u00d7<\/span>\n                        <\/div>\n                    <\/template>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Results Section -->\n        <div class=\"films-grid-wrapper\">\n            <!-- Grid View -->\n            <div x-show=\"viewMode === 'grid'\" class=\"grid-view\">\n                <div class=\"films-info\">\n                    <p>\n                        Showing <strong x-text=\"filteredPosts.length\"><\/strong> films.\n                        Sort by <strong x-text=\"sortBy === 'title' ? 'Title' : 'Date'\"><\/strong>.\n                    <\/p>\n                <\/div>\n\n                <div class=\"films-grid\">\n                    <template x-for=\"post in filteredPosts\" :key=\"post.ID\">\n                        <article class=\"film-item\">\n                            <div class=\"film-image-wrapper\">\n                                <template x-if=\"post.related_films\">\n                                    <div class=\"film-related\">\n                                        <span class=\"film-related-text\">Multi Screening<\/span>\n                                    <\/div>\n                                <\/template>\n                                <a :href=\"post.permalink\" class=\"film-link\">\n                                    <img :src=\"post.featured_image || 'https:\/\/asianfilmfestival.barcelona\/2025\/wp-content\/plugins\/film-festival-portfolio-2\/images\/placeholder.jpg'\" :alt=\"post.title\" class=\"film-image\">\n                                <\/a>\n                            <\/div>\n                            <div class=\"film-date\">\n                                <span x-text=\"getFilmDate(post)\"><\/span>\n                            <\/div>\n                            <div class=\"film-info\">\n                                <a :href=\"post.permalink\" class=\"film-link\">\n                                    <h2 class=\"film-title\" x-text=\"post.title\"><\/h2>\n                                <\/a>\n                                <p class=\"film-meta\">\n                                    <span x-text=\"post.director_film\"><\/span>\n                                    <template x-if=\"post.year\">\n                                        <span> \/ <span x-text=\"post.year\"><\/span><\/span>\n                                    <\/template>\n                                <\/p>\n                                <p class=\"film-meta\">\n                                    <span x-text=\"post.pais\"><\/span>\n                                    <template x-if=\"post.seccio\">\n                                        <span> \/ <strong x-text=\"post.seccio\"><\/strong><\/span>\n                                    <\/template>\n                                <\/p>\n                                <p class=\"film-meta film-meta__icon\">\n                                    <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" fill=\"none\">\n                                        <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"><\/path>\n                                        <path d=\"M18.364 4.636a9 9 0 0 1 .203 12.519l-.203 .21l-4.243 4.242a3 3 0 0 1 -4.097 .135l-.144 -.135l-4.244 -4.243a9 9 0 0 1 12.728 -12.728zm-6.364 3.364a3 3 0 1 0 0 6a3 3 0 0 0 0 -6z\" stroke-width=\"0\" fill=\"currentColor\"><\/path>\n                                    <\/svg>\n                                    <span x-text=\"post.sala\"><\/span>\n                                <\/p>\n                            <\/div>\n                        <\/article>\n                    <\/template>\n                <\/div>\n            <\/div>\n\n            <!-- Calendar View -->\n            <div x-show=\"viewMode === 'calendar'\" class=\"calendar-view\">\n                <div class=\"calendar-days\">\n                    <template x-for=\"(filmsForDay, dayKey) in groupedByDay\" :key=\"dayKey\">\n                        <div class=\"calendar-day-section\">\n                            <div class=\"calendar-day-header\" @click=\"toggleDay(dayKey)\" :class=\"{ 'expanded': expandedDays[dayKey] }\">\n                                <h3 x-text=\"formatDayHeader(dayKey)\"><\/h3>\n                                <svg class=\"calendar-chevron\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                                    <path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\" \/>\n                                <\/svg>\n                            <\/div>\n\n                            <div x-show=\"expandedDays[dayKey]\" x-transition class=\"calendar-day-content\">\n                                <template x-for=\"film in filmsForDay\" :key=\"film.ID\">\n                                    <div class=\"calendar-film-item\">\n                                        <!-- Nom\u00e9s mostrar temps per dates normals, no per les especials -->\n                                        <template x-if=\"!isSpecialDateKey(dayKey)\">\n                                            <div class=\"calendar-film-time\">\n                                                <span x-text=\"extractTime(film.projection_date_film)\"><\/span>\n                                            <\/div>\n                                        <\/template>\n                                        <div class=\"calendar-film-image\">\n                                            <template x-if=\"film.related_films\">\n                                                <div class=\"calendar-film-bookmark\">\n                                                    <svg width=\"16\" height=\"20\" viewBox=\"0 0 16 20\" fill=\"currentColor\">\n                                                        <path d=\"M0 0v20l8-6 8 6V0H0z\" \/>\n                                                    <\/svg>\n                                                <\/div>\n                                            <\/template>\n                                            <a :href=\"film.permalink\">\n                                                <img :src=\"film.featured_image || 'https:\/\/asianfilmfestival.barcelona\/2025\/wp-content\/plugins\/film-festival-portfolio-2\/images\/placeholder.jpg'\" :alt=\"film.title\">\n                                            <\/a>\n                                        <\/div>\n                                        <div class=\"calendar-film-details\">\n                                            <a :href=\"film.permalink\" class=\"calendar-film-link\">\n                                                <h4 class=\"calendar-film-title\" x-text=\"film.title\"><\/h4>\n                                            <\/a>\n                                            <p class=\"calendar-film-meta\">\n                                                <span x-text=\"film.director_film\"><\/span>\n                                                <template x-if=\"film.year\">\n                                                    <span> \/ <span x-text=\"film.year\"><\/span><\/span>\n                                                <\/template>\n                                            <\/p>\n                                            <p class=\"calendar-film-meta\">\n                                                <span x-text=\"film.pais\"><\/span>\n                                                <template x-if=\"film.seccio\">\n                                                    <span> \/ <span x-text=\"film.seccio\"><\/span><\/span>\n                                                <\/template>\n                                            <\/p>\n                                            <p class=\"calendar-film-location\">\n                                                <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" fill=\"none\">\n                                                    <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"><\/path>\n                                                    <path d=\"M18.364 4.636a9 9 0 0 1 .203 12.519l-.203 .21l-4.243 4.242a3 3 0 0 1 -4.097 .135l-.144 -.135l-4.244 -4.243a9 9 0 0 1 12.728 -12.728zm-6.364 3.364a3 3 0 1 0 0 6a3 3 0 0 0 0 -6z\" stroke-width=\"0\" fill=\"currentColor\"><\/path>\n                                                <\/svg>\n                                                <span x-text=\"film.sala\"><\/span>\n                                            <\/p>\n                                        <\/div>\n                                    <\/div>\n                                <\/template>\n                            <\/div>\n                        <\/div>\n                    <\/template>\n                <\/div>\n            <\/div>\n\n            <div x-show=\"filteredPosts.length === 0\" class=\"no-results\">\n                <p>No films found with the selected filters.<\/p>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n        function portfolioFilters() {\n            return {\n                loading: false,\n                allPosts: [],\n                filteredPosts: [],\n                searchQuery: '',\n                sortBy: 'title',\n                viewMode: 'grid', \/\/ 'grid' o 'calendar'\n                filters: {\n                    date: [],\n                    country: [],\n                    section: []\n                },\n                availableCountries: [],\n                availableSections: [],\n                availableDates: [],\n\n                \/\/ Variables per recordar l'estat abans del calendari\n                previousSortBy: '',\n\n                \/\/ Calendar view\n                groupedByDay: {},\n                expandedDays: {},\n\n                \/\/ Filtres\n                filtersVisible: false,\n\n\n                async init() {\n                    \/\/ Configurar moment\n                    if (typeof portfolio_ajax !== 'undefined' && portfolio_ajax.locale) {\n                        moment.locale(portfolio_ajax.locale);\n                    }\n\n                    \/\/ Inicialitzar visibilitat dels filtres segons la mida de pantalla\n                    this.initFiltersVisibility();\n\n                    \/\/ Escoltar canvis de mida de finestra\n                    window.addEventListener('resize', () => {\n                        this.initFiltersVisibility();\n                    });\n\n                    \/\/ Comprovar si hi ha par\u00e0metres URL\n                    const seccioFromUrl = this.getUrlParameter('_sft_seccio');\n                    const paisFromUrl = this.getUrlParameter('_sft_pais');\n                    const dataFromUrl = this.getUrlParameter('_sft_data');\n\n                    const lang = portfolio_ajax.locale || 'ca';\n\n                    \/\/ Si hi ha par\u00e0metres URL, prioritzar-los i esborrar localStorage\n                    if (seccioFromUrl || paisFromUrl || dataFromUrl) {\n                        \/\/ Esborrar filtres guardats\n                        localStorage.removeItem(`portfolioFilters_${lang}`);\n\n                        \/\/ Aplicar filtres des de la URL\n                        if (seccioFromUrl) {\n                            \/\/ Dividir per comes i guardar com array\n                            this.pendingSeccioSlugs = seccioFromUrl.split(',').map(s => s.trim()).filter(s => s);\n                        }\n                        if (paisFromUrl) {\n                            \/\/ Dividir per comes i guardar com array\n                            this.pendingPaisSlugs = paisFromUrl.split(',').map(s => s.trim()).filter(s => s);\n                        }\n                        if (dataFromUrl) {\n                            \/\/ Dividir per comes per dates tamb\u00e9\n                            this.filters.date = dataFromUrl.split(',').map(s => s.trim()).filter(s => s);\n                        }\n                    } else {\n                        \/\/ Recuperar filtres guardats nom\u00e9s si no hi ha par\u00e0metres URL\n                        const savedFilters = localStorage.getItem(`portfolioFilters_${lang}`);\n                        if (savedFilters) {\n                            const parsed = JSON.parse(savedFilters);\n                            this.filters = parsed.filters || this.filters;\n                            this.searchQuery = parsed.searchQuery || '';\n                            this.sortBy = parsed.sortBy || 'title';\n                            this.viewMode = parsed.viewMode || 'grid';\n                            if (parsed.filtersVisible !== undefined) {\n                                this.filtersVisible = parsed.filtersVisible;\n                            }\n                        }\n                    }\n\n                    \/\/ Carregar posts\n                    await this.loadPosts();\n\n                    \/\/ Aplicar filtres pendents de la URL despr\u00e9s de carregar posts\n                    \/\/ Aplicar filtres pendents de la URL despr\u00e9s de carregar posts\n                    if (this.pendingSeccioSlugs) {\n                        this.pendingSeccioSlugs.forEach(slug => this.applySeccioFromSlug(slug));\n                        delete this.pendingSeccioSlugs;\n                    }\n                    if (this.pendingPaisSlugs) {\n                        this.pendingPaisSlugs.forEach(slug => this.applyPaisFromSlug(slug));\n                        delete this.pendingPaisSlugs;\n                    }\n\n                    \/\/ Si s'han aplicat filtres des de la URL, aplicar-los ara\n                    if (seccioFromUrl || paisFromUrl || dataFromUrl) {\n                        this.applyFilters();\n                    }\n                },\n\n                applySeccioFromSlug(slug) {\n                    \/\/ Buscar en TOTS els posts quin t\u00e9 aquest slug\n                    for (const post of this.allPosts) {\n                        if (post.seccio_data && Array.isArray(post.seccio_data)) {\n                            const match = post.seccio_data.find(s => s.slug === slug);\n                            if (match && !this.filters.section.includes(match.name)) {\n                                this.filters.section.push(match.name);\n                                return; \/\/ Ja hem trobat el match, sortir\n                            }\n                        }\n                    }\n                },\n\n                applyPaisFromSlug(slug) {\n                    for (const post of this.allPosts) {\n                        if (post.pais_data && Array.isArray(post.pais_data)) {\n                            const match = post.pais_data.find(p => p.slug === slug);\n                            if (match && !this.filters.country.includes(match.name)) {\n                                this.filters.country.push(match.name);\n                                return;\n                            }\n                        }\n                    }\n                },\n\n                slugify(text) {\n                    \/\/ Convertir text a slug (igual que WordPress)\n                    return text\n                        .toString()\n                        .toLowerCase()\n                        .normalize('NFD')\n                        .replace(\/[\\u0300-\\u036f]\/g, '') \/\/ Treure accents\n                        .replace(\/[^a-z0-9\\s-]\/g, '') \/\/ Treure car\u00e0cters especials\n                        .trim()\n                        .replace(\/\\s+\/g, '-') \/\/ Espais a guions\n                        .replace(\/-+\/g, '-'); \/\/ Guions m\u00faltiples a un sol\n                },\n\n                getUrlParameter(name) {\n                    const urlParams = new URLSearchParams(window.location.search);\n                    return urlParams.get(name);\n                },\n\n                getFilmDate(post) {\n                    \/\/ Si t\u00e9 filming, mostrar-lo\n                    if (post.filming && post.filming.trim() !== '') {\n                        return post.filming;\n                    }\n\n                    \/\/ Si t\u00e9 data de projecci\u00f3 v\u00e0lida, formatar-la\n                    if (post.projection_date_film && post.projection_date_film.trim() !== '') {\n                        return this.formatDate(post.projection_date_film);\n                    }\n\n                    \/\/ Si no t\u00e9 data per\u00f2 t\u00e9 data_slug amb ID 761 (PENDING DATE)\n                    if (post.data_slug && post.data) {\n                        \/\/ Retornar el nom de la taxonomia (ja ve tradu\u00eft segons l'idioma actiu)\n                        return post.data;\n                    }\n\n                    return '';\n                },\n\n                initFiltersVisibility() {\n                    \/\/ Si \u00e9s desktop (m\u00e9s de 768px), sempre mostrar filtres\n                    \/\/ Si \u00e9s mobile, utilitzar l'estat guardat o amagar per defecte\n                    if (window.innerWidth > 768) {\n                        this.filtersVisible = true;\n                    } else {\n                        const lang = portfolio_ajax.locale || 'ca';\n                        const savedFilters = localStorage.getItem(`portfolioFilters_${lang}`);\n                        if (savedFilters) {\n                            const parsed = JSON.parse(savedFilters);\n                            this.filtersVisible = parsed.filtersVisible !== undefined ? parsed.filtersVisible : false;\n                        } else {\n                            this.filtersVisible = false;\n                        }\n                    }\n                },\n\n                toggleFilters() {\n                    this.filtersVisible = !this.filtersVisible;\n                    this.saveFilters(); \/\/ Guardar el nou estat\n                },\n\n                async loadPosts() {\n                    this.loading = true;\n\n                    try {\n                        const formData = new FormData();\n                        formData.append('action', 'get_portfolio_posts');\n                        formData.append('nonce', portfolio_ajax.nonce);\n                        formData.append('lang', portfolio_ajax.lang);\n\n                        const response = await fetch(portfolio_ajax.ajax_url, {\n                            method: 'POST',\n                            body: formData\n                        });\n\n                        const data = await response.json();\n\n                        if (data.success) {\n                            this.allPosts = data.data;\n                            this.extractUniqueValues();\n                            this.applyFilters();\n                        }\n                    } catch (error) {\n                        console.error('Error loading posts:', error);\n                    } finally {\n                        this.loading = false;\n                    }\n                },\n\n                extractUniqueValues() {\n                    \/\/ Pa\u00efsos \u00fanics amb comptatge inicial\n                    const countryCount = {};\n                    this.allPosts.forEach(post => {\n                        if (post.pais) {\n                            \/\/ Separar els pa\u00efsos si n'hi ha m\u00e9s d'un\n                            const countries = post.pais.split(',').map(c => c.trim());\n                            countries.forEach(country => {\n                                if (country) {\n                                    countryCount[country] = (countryCount[country] || 0) + 1;\n                                }\n                            });\n                        }\n                    });\n                    this.availableCountries = Object.keys(countryCount)\n                        .sort((a, b) => a.localeCompare(b, portfolio_ajax.locale || 'ca', {\n                            sensitivity: 'base'\n                        }))\n                        .map(country => ({\n                            name: country,\n                            count: countryCount[country]\n                        }));\n\n                    \/\/ Seccions \u00faniques amb comptatge inicial\n                    const sectionCount = {};\n                    this.allPosts.forEach(post => {\n                        if (post.seccio) {\n                            \/\/ Separar les seccions si n'hi ha m\u00e9s d'una\n                            const sections = post.seccio.split(',').map(s => s.trim());\n                            sections.forEach(section => {\n                                if (section) {\n                                    sectionCount[section] = (sectionCount[section] || 0) + 1;\n                                }\n                            });\n                        }\n                    });\n                    this.availableSections = Object.keys(sectionCount)\n                        .sort((a, b) => a.localeCompare(b, portfolio_ajax.locale || 'ca', {\n                            sensitivity: 'base'\n                        }))\n                        .map(section => ({\n                            name: section,\n                            count: sectionCount[section]\n                        }));\n\n                    \/\/ Dates - aix\u00f2 ja est\u00e0 b\u00e9\n                    const datesMap = new Map();\n                    const dateCount = {};\n                    this.allPosts.forEach(post => {\n                        if (post.data && post.data_slug) {\n                            datesMap.set(post.data_slug, post.data);\n                            dateCount[post.data_slug] = (dateCount[post.data_slug] || 0) + 1;\n                        }\n                    });\n\n                    this.availableDates = Array.from(datesMap.entries())\n                        .map(([slug, name]) => ({\n                            slug,\n                            name,\n                            count: dateCount[slug]\n                        }))\n                        .filter(date => date.count > 0)\n                        .sort((a, b) => a.slug.localeCompare(b.slug));\n                },\n\n                updateAvailableOptions() {\n                    \/\/ Comen\u00e7ar amb tots els posts\n                    let postsForCounting = [...this.allPosts];\n\n                    \/\/ 1. Calcular opcions disponibles per DATES\n                    let postsForDateCount = [...postsForCounting];\n\n                    \/\/ Aplicar filtres de pa\u00eds i secci\u00f3 (per\u00f2 no data)\n                    if (this.filters.country.length > 0) {\n                        postsForDateCount = postsForDateCount.filter(post =>\n                            this.filters.country.includes(post.pais)\n                        );\n                    }\n                    if (this.filters.section.length > 0) {\n                        postsForDateCount = postsForDateCount.filter(post =>\n                            this.filters.section.includes(post.seccio)\n                        );\n                    }\n                    \/\/ Aplicar cerca\n                    if (this.searchQuery) {\n                        const query = this.searchQuery.toLowerCase();\n                        postsForDateCount = postsForDateCount.filter(post =>\n                            post.title.toLowerCase().includes(query) ||\n                            (post.director_film && post.director_film.toLowerCase().includes(query))\n                        );\n                    }\n\n                    \/\/ Calcular recompte per dates\n                    const dateCount = {};\n                    const datesMap = new Map();\n                    postsForDateCount.forEach(post => {\n                        if (post.data && post.data_slug) {\n                            datesMap.set(post.data_slug, post.data);\n                            dateCount[post.data_slug] = (dateCount[post.data_slug] || 0) + 1;\n                        }\n                    });\n\n                    this.availableDates = Array.from(datesMap.entries())\n                        .map(([slug, name]) => ({\n                            slug,\n                            name,\n                            count: dateCount[slug]\n                        }))\n                        .filter(date => date.count > 0)\n                        .sort((a, b) => a.slug.localeCompare(b.slug));\n\n                    \/\/ 2. Calcular opcions disponibles per PA\u00cfSOS\n                    let postsForCountryCount = [...postsForCounting];\n\n                    \/\/ Aplicar filtres de data i secci\u00f3 (per\u00f2 no pa\u00eds)\n                    if (this.filters.date.length > 0) {\n                        postsForCountryCount = postsForCountryCount.filter(post =>\n                            this.filters.date.includes(post.data_slug)\n                        );\n                    }\n                    if (this.filters.section.length > 0) {\n                        postsForCountryCount = postsForCountryCount.filter(post => {\n                            if (!post.seccio) return false;\n                            const postSections = post.seccio.split(',').map(s => s.trim());\n                            return postSections.some(section => this.filters.section.includes(section));\n                        });\n                    }\n                    \/\/ Aplicar cerca\n                    if (this.searchQuery) {\n                        const query = this.searchQuery.toLowerCase();\n                        postsForCountryCount = postsForCountryCount.filter(post =>\n                            post.title.toLowerCase().includes(query) ||\n                            (post.director_film && post.director_film.toLowerCase().includes(query))\n                        );\n                    }\n\n                    \/\/ Calcular recompte per pa\u00efsos\n                    const countryCount = {};\n                    postsForCountryCount.forEach(post => {\n                        if (post.pais) {\n                            const countries = post.pais.split(',').map(c => c.trim());\n                            countries.forEach(country => {\n                                if (country) {\n                                    countryCount[country] = (countryCount[country] || 0) + 1;\n                                }\n                            });\n                        }\n                    });\n\n                    this.availableCountries = Object.keys(countryCount)\n                        .filter(country => countryCount[country] > 0)\n                        .sort((a, b) => a.localeCompare(b, portfolio_ajax.locale || 'ca', {\n                            sensitivity: 'base'\n                        }))\n                        .map(country => ({\n                            name: country,\n                            count: countryCount[country]\n                        }));\n\n                    \/\/ 3. Calcular opcions disponibles per SECCIONS\n                    let postsForSectionCount = [...postsForCounting];\n\n                    \/\/ Aplicar filtres de data i pa\u00eds (per\u00f2 no secci\u00f3)\n                    if (this.filters.date.length > 0) {\n                        postsForSectionCount = postsForSectionCount.filter(post =>\n                            this.filters.date.includes(post.data_slug)\n                        );\n                    }\n                    if (this.filters.country.length > 0) {\n                        postsForSectionCount = postsForSectionCount.filter(post => {\n                            if (!post.pais) return false;\n                            const postCountries = post.pais.split(',').map(c => c.trim());\n                            return postCountries.some(country => this.filters.country.includes(country));\n                        });\n                    }\n                    \/\/ Aplicar cerca\n                    if (this.searchQuery) {\n                        const query = this.searchQuery.toLowerCase();\n                        postsForSectionCount = postsForSectionCount.filter(post =>\n                            post.title.toLowerCase().includes(query) ||\n                            (post.director_film && post.director_film.toLowerCase().includes(query))\n                        );\n                    }\n\n                    \/\/ Calcular recompte per seccions\n                    const sectionCount = {};\n                    postsForSectionCount.forEach(post => {\n                        if (post.seccio) {\n                            const sections = post.seccio.split(',').map(s => s.trim());\n                            sections.forEach(section => {\n                                if (section) {\n                                    sectionCount[section] = (sectionCount[section] || 0) + 1;\n                                }\n                            });\n                        }\n                    });\n\n                    this.availableSections = Object.keys(sectionCount)\n                        .filter(section => sectionCount[section] > 0)\n                        .sort((a, b) => a.localeCompare(b, portfolio_ajax.locale || 'ca', {\n                            sensitivity: 'base'\n                        }))\n                        .map(section => ({\n                            name: section,\n                            count: sectionCount[section]\n                        }));\n                },\n\n                applyFilters() {\n                    let filtered = [...this.allPosts];\n\n                    \/\/ Filtre per cerca\n                    if (this.searchQuery) {\n                        const query = this.searchQuery.toLowerCase();\n                        filtered = filtered.filter(post =>\n                            post.title.toLowerCase().includes(query) ||\n                            (post.director_film && post.director_film.toLowerCase().includes(query))\n                        );\n                    }\n\n                    \/\/ Filtre per pa\u00eds (multi-selecci\u00f3)\n                    if (this.filters.country.length > 0) {\n                        filtered = filtered.filter(post => {\n                            if (!post.pais) return false;\n                            \/\/ Separar els pa\u00efsos del post\n                            const postCountries = post.pais.split(',').map(c => c.trim());\n                            \/\/ Comprovar si algun pa\u00eds del post coincideix amb els filtres\n                            return postCountries.some(country => this.filters.country.includes(country));\n                        });\n                    }\n\n                    \/\/ Filtre per secci\u00f3 (multi-selecci\u00f3)\n                    if (this.filters.section.length > 0) {\n                        filtered = filtered.filter(post => {\n                            if (!post.seccio) return false;\n                            \/\/ Separar les seccions del post\n                            const postSections = post.seccio.split(',').map(s => s.trim());\n                            \/\/ Comprovar si alguna secci\u00f3 del post coincideix amb els filtres\n                            return postSections.some(section => this.filters.section.includes(section));\n                        });\n                    }\n\n                    \/\/ Filtre per data (taxonomia) (multi-selecci\u00f3)\n                    if (this.filters.date.length > 0) {\n                        filtered = filtered.filter(post =>\n                            this.filters.date.includes(post.data_slug)\n                        );\n                    }\n\n                    \/\/ Ordenar\n                    filtered = this.sortPosts(filtered);\n\n                    this.filteredPosts = filtered;\n\n                    \/\/ Actualitzar opcions disponibles amb els filtres creuats\n                    this.updateAvailableOptions();\n\n                    \/\/ Actualitzar vista calendari\n                    this.groupPostsByDay();\n\n                    this.saveFilters();\n                },\n\n                groupPostsByDay() {\n                    const grouped = {};\n\n                    this.filteredPosts.forEach(post => {\n                        \/\/ Si t\u00e9 projection_date_film amb contingut\n                        if (post.projection_date_film && post.projection_date_film.trim() !== '') {\n                            const momentDate = moment(post.projection_date_film, \"DD-MM-YYYY \/ HH:mm\");\n\n                            if (momentDate.isValid()) {\n                                const dayKey = momentDate.format('YYYY-MM-DD');\n                                if (!grouped[dayKey]) {\n                                    grouped[dayKey] = [];\n                                }\n                                grouped[dayKey].push(post);\n                            } else {\n                                \/\/ Data no v\u00e0lida per\u00f2 amb contingut\n                                const specialKey = `zzzz-${post.data_slug || 'other'}`;\n                                if (!grouped[specialKey]) {\n                                    grouped[specialKey] = [];\n                                }\n                                grouped[specialKey].push(post);\n                            }\n                        } else if (post.data_slug) {\n                            \/\/ Si no t\u00e9 projection_date_film per\u00f2 s\u00ed data_slug, \u00e9s especial\n                            const specialKey = `zzzz-${post.data_slug}`;\n                            if (!grouped[specialKey]) {\n                                grouped[specialKey] = [];\n                            }\n                            grouped[specialKey].push(post);\n                        }\n                    });\n\n                    \/\/ Ordenar films dins de cada dia per hora (nom\u00e9s per dates v\u00e0lides)\n                    Object.keys(grouped).forEach(dayKey => {\n                        if (!dayKey.startsWith('zzzz-')) {\n                            grouped[dayKey].sort((a, b) => {\n                                const timeA = moment(a.projection_date_film, \"DD-MM-YYYY \/ HH:mm\");\n                                const timeB = moment(b.projection_date_film, \"DD-MM-YYYY \/ HH:mm\");\n                                return timeA.isAfter(timeB) ? 1 : -1;\n                            });\n                        } else {\n                            \/\/ Per dates especials, ordenar per t\u00edtol\n                            grouped[dayKey].sort((a, b) => a.title.localeCompare(b.title));\n                        }\n                    });\n\n                    \/\/ Crear un objecte ordenat: primer les dates cronol\u00f2gicament, despr\u00e9s les especials\n                    const orderedGrouped = {};\n\n                    \/\/ Afegir dates v\u00e0lides ordenades cronol\u00f2gicament\n                    Object.keys(grouped)\n                        .filter(key => !key.startsWith('zzzz-'))\n                        .sort() \/\/ Les dates YYYY-MM-DD ja s'ordenen cronol\u00f2gicament\n                        .forEach(key => {\n                            orderedGrouped[key] = grouped[key];\n                        });\n\n                    \/\/ Afegir les dates especials al final\n                    Object.keys(grouped)\n                        .filter(key => key.startsWith('zzzz-'))\n                        .sort()\n                        .forEach(key => {\n                            orderedGrouped[key] = grouped[key];\n                        });\n\n                    \/\/ Inicialitzar tots els dies com a expandits\n                    Object.keys(orderedGrouped).forEach(dayKey => {\n                        if (!(dayKey in this.expandedDays)) {\n                            this.expandedDays[dayKey] = true;\n                        }\n                    });\n\n                    this.groupedByDay = orderedGrouped;\n                },\n\n                sortPosts(posts) {\n                    if (this.sortBy === 'title') {\n                        return posts.sort((a, b) => a.title.localeCompare(b.title));\n                    } else if (this.sortBy === 'date') {\n                        return posts.sort((a, b) => {\n                            const dateA = moment(a.projection_date_film, \"DD-MM-YYYY \/ HH:mm\");\n                            const dateB = moment(b.projection_date_film, \"DD-MM-YYYY \/ HH:mm\");\n\n                            \/\/ Si ambdues dates s\u00f3n inv\u00e0lides (PENDING), ordenar per t\u00edtol\n                            if (!dateA.isValid() && !dateB.isValid()) {\n                                return a.title.localeCompare(b.title);\n                            }\n\n                            \/\/ Si A \u00e9s inv\u00e0lida (PENDING), va al final\n                            if (!dateA.isValid()) {\n                                return 1;\n                            }\n\n                            \/\/ Si B \u00e9s inv\u00e0lida (PENDING), va al final\n                            if (!dateB.isValid()) {\n                                return -1;\n                            }\n\n                            \/\/ Ambdues dates v\u00e0lides, ordenar cronol\u00f2gicament\n                            return dateA.isAfter(dateB) ? 1 : -1;\n                        });\n                    }\n                    return posts;\n                },\n\n                formatDate(dateStr) {\n                    if (!dateStr) return '';\n                    const momentDate = moment(dateStr, \"DD-MM-YYYY \/ HH:mm\");\n                    return momentDate.format('dddd D MMM \/ HH:mm') + 'h';\n                },\n\n                formatDayHeader(dayKey) {\n                    if (dayKey.startsWith('zzzz-')) {\n                        \/\/ Per claus especials, buscar el post corresponent per agafar el nom de la data\n                        const matchingPosts = Object.values(this.groupedByDay[dayKey] || []);\n                        if (matchingPosts.length > 0 && matchingPosts[0].data) {\n                            return matchingPosts[0].data.toUpperCase();\n                        }\n                        return 'ALTRES DATES';\n                    }\n                    const momentDate = moment(dayKey, 'YYYY-MM-DD');\n                    return momentDate.format('dddd D MMM').toUpperCase();\n                },\n\n                extractTime(dateStr) {\n                    if (!dateStr) return '';\n                    const momentDate = moment(dateStr, \"DD-MM-YYYY \/ HH:mm\");\n                    if (momentDate.isValid()) {\n                        return momentDate.format('HH:mm') + 'h';\n                    }\n                    \/\/ Si no \u00e9s v\u00e0lida, retornar el text original o buit\n                    return '';\n                },\n\n                isSpecialDateKey(dayKey) {\n                    return dayKey.startsWith('zzzz-');\n                },\n\n                toggleDay(dayKey) {\n                    this.expandedDays[dayKey] = !this.expandedDays[dayKey];\n                },\n\n                getDateLabel(slug) {\n                    const dateObj = this.availableDates.find(d => d.slug === slug);\n                    return dateObj ? dateObj.name : slug;\n                },\n\n                hasActiveFilters() {\n                    return this.filters.date.length > 0 || this.filters.country.length > 0 ||\n                        this.filters.section.length > 0 || this.searchQuery;\n                },\n\n                getDateFilterLabel() {\n                    if (this.filters.date.length === 0) {\n                        return portfolio_i18n.date;\n                    }\n                    return `${portfolio_i18n.date} (${this.filters.date.length})`;\n                },\n\n                getCountryFilterLabel() {\n                    if (this.filters.country.length === 0) {\n                        return portfolio_i18n.countries;\n                    }\n                    return `${portfolio_i18n.countries} (${this.filters.country.length})`;\n                },\n\n                getSectionFilterLabel() {\n                    if (this.filters.section.length === 0) {\n                        return portfolio_i18n.sections;\n                    }\n                    return `${portfolio_i18n.sections} (${this.filters.section.length})`;\n                },\n\n                removeFilter(filterType, value) {\n                    const index = this.filters[filterType].indexOf(value);\n                    if (index > -1) {\n                        this.filters[filterType].splice(index, 1);\n                        this.applyFilters();\n                    }\n                },\n\n                switchToGridView() {\n                    \/\/ Si estem canviant des de calendari a grid, restaurar l'ordenaci\u00f3 anterior\n                    if (this.viewMode === 'calendar' && this.previousSortBy) {\n                        this.sortBy = this.previousSortBy;\n                    }\n                    this.viewMode = 'grid';\n                    this.applyFilters();\n                },\n\n                switchToCalendarView() {\n                    \/\/ Guardar l'ordenaci\u00f3 actual abans de canviar a calendari\n                    this.previousSortBy = this.sortBy;\n                    \/\/ For\u00e7ar ordenaci\u00f3 per data en vista calendari\n                    this.sortBy = 'date';\n                    this.viewMode = 'calendar';\n                    this.applyFilters();\n                },\n\n                resetFilters() {\n                    this.filters = {\n                        date: [],\n                        country: [],\n                        section: []\n                    };\n                    this.searchQuery = '';\n                    this.sortBy = 'title';\n                    this.applyFilters();\n                },\n\n                saveFilters() {\n                    const lang = portfolio_ajax.locale || 'ca';\n                    localStorage.setItem(`portfolioFilters_${lang}`, JSON.stringify({\n                        filters: this.filters,\n                        searchQuery: this.searchQuery,\n                        sortBy: this.sortBy,\n                        viewMode: this.viewMode,\n                        filtersVisible: this.filtersVisible\n                    }));\n                },\n            }\n        }\n    <\/script>\n\n<\/div><\/section><\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":10,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-44170","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/asianfilmfestival.barcelona\/2025\/wp-json\/wp\/v2\/pages\/44170","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/asianfilmfestival.barcelona\/2025\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/asianfilmfestival.barcelona\/2025\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/asianfilmfestival.barcelona\/2025\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/asianfilmfestival.barcelona\/2025\/wp-json\/wp\/v2\/comments?post=44170"}],"version-history":[{"count":8,"href":"https:\/\/asianfilmfestival.barcelona\/2025\/wp-json\/wp\/v2\/pages\/44170\/revisions"}],"predecessor-version":[{"id":58448,"href":"https:\/\/asianfilmfestival.barcelona\/2025\/wp-json\/wp\/v2\/pages\/44170\/revisions\/58448"}],"wp:attachment":[{"href":"https:\/\/asianfilmfestival.barcelona\/2025\/wp-json\/wp\/v2\/media?parent=44170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}