diff --git a/Build.PL b/Build.PL index 5d0170a..5f922d4 100755 --- a/Build.PL +++ b/Build.PL @@ -17,6 +17,7 @@ my $build = Module::Build->new( 'DBD::Pg' => 0, 'DateTime::Format::ISO8601.pm' => 0, 'DateTime::Format::Mail.pm' => 0, + 'DateTime::Format::Pg' => 0, 'SVG' => 0, 'XML::Twig' => 0, 'JSON' => 0, diff --git a/content/posts/0000036-farmacia-de-guardia.xml b/content/posts/0000036-farmacia-de-guardia.xml new file mode 100644 index 0000000..fc0ee81 --- /dev/null +++ b/content/posts/0000036-farmacia-de-guardia.xml @@ -0,0 +1,15 @@ + + Burguillos.info + 2023-09-07T16:11:00+00:00 + Farmacia de Guardia en Burguillos. + Farmacia de Guardia en Burguillos. + + index + farmacia-guardia + + Imagen de cruz de Farmacia +

Este artículo se rellena automáticamente con los datos de la Farmacia de Guardia, tu navegador o móvil debe soportar Javascript para que funcione.

+ +

La farmacia de guardia esta semana y hasta la siguiente vez que sean las 9:30 un lunes es se encuentra ubicada en .

+
+
diff --git a/js-src/index.js b/js-src/index.js index 2b26409..96c0526 100644 --- a/js-src/index.js +++ b/js-src/index.js @@ -10,6 +10,7 @@ window.onload = () => { const mobile_foldable = document.querySelector('nav.mobile-foldable'); const tables = document.querySelectorAll('table') + fillFarmaciaGuardia(); loadAd() addEasterEggAnimation() @@ -39,6 +40,26 @@ window.onload = () => { addListenersSearch() }; +function fillFarmaciaGuardia() { + const farmaciaName = document.querySelector('#farmacia-name'); + const farmaciaAddress = document.querySelector('#farmacia-address'); + if (farmaciaName !== null || farmaciaAddress !== null) { + const port = _port() + const url = new URL(window.location.protocol + + "//" + + window.location.hostname + + port + + '/farmacia-guardia.json'); + fetch(url).then(async (res) => { + const farmacia = await res.json() + if (farmaciaName !== null) { + farmaciaName.innerText = farmacia.name; + farmaciaAddress.innerText = farmacia.address; + } + }) + } +} + function addListenersSearch() { if (searchMobile !== null) { const searchIcon = searchMobile.querySelector('div.search-icon') @@ -62,6 +83,14 @@ function addListenersSearch() { } } +function _port() { + let port = window.location.port; + if (port !== '') { + port = ':' + port + } + return port; +} + function onSearchChange() { const search = document.querySelector('div.search-overlay div.search input'); const searchResults = document.querySelector('div.search-overlay div.search-results'); @@ -70,10 +99,7 @@ function onSearchChange() { } const query = search.value; fakeSearchInput.value = search.value - let port = window.location.port; - if (port !== '') { - port = ':' + port - } + const port = _port() const url = new URL(window.location.protocol + "//" + window.location.hostname diff --git a/lib/BurguillosInfo.pm b/lib/BurguillosInfo.pm index 7963d29..e83e36a 100644 --- a/lib/BurguillosInfo.pm +++ b/lib/BurguillosInfo.pm @@ -52,6 +52,7 @@ sub startup ($self) { # $r->get('/:post')->to('Page#post'); $r->get('/stats')->to('Metrics#stats'); $r->get('/search.json')->to('Search#search'); + $r->get('/farmacia-guardia.json')->to('FarmaciaGuardia#current'); $r->get('/<:category>.rss')->to('Page#category_rss'); $r->get('/:category_slug/atributo/<:attribute_slug>-preview.png')->to('Attribute#get_attribute_preview'); $r->get('/:category_slug/atributo/:attribute_slug')->to('Attribute#get'); diff --git a/lib/BurguillosInfo/Ads.pm b/lib/BurguillosInfo/Ads.pm index da651c7..ce26172 100644 --- a/lib/BurguillosInfo/Ads.pm +++ b/lib/BurguillosInfo/Ads.pm @@ -60,7 +60,7 @@ sub get_rand_ad($self, $array) { my $max_weight = $self->sum_weights($array); my $rand = int(rand() * $max_weight); my $sum_weight = 0; - for my $ad (@$array) { + for my $ad (@$valid_ads) { $sum_weight += $ad->weight; if ($rand < $sum_weight) { return $ad; diff --git a/lib/BurguillosInfo/DB/Migrations.pm b/lib/BurguillosInfo/DB/Migrations.pm index 6bf89b7..2e9c5f6 100644 --- a/lib/BurguillosInfo/DB/Migrations.pm +++ b/lib/BurguillosInfo/DB/Migrations.pm @@ -43,6 +43,12 @@ sub MIGRATIONS { \&_populate_locations, \&_populate_locations, \&_populate_locations, + 'CREATE TABLE farmacia_guardia ( + uuid UUID DEFAULT uuid_generate_v4() PRIMARY KEY, + date timestamp NOT NULL, + id_farmacia TEXT NOT NULL + );', + 'CREATE INDEX farmacia_guardia_index on farmacia_guardia (date, id_farmacia, uuid);', ); } diff --git a/lib/BurguillosInfo/Farmacia.pm b/lib/BurguillosInfo/Farmacia.pm new file mode 100644 index 0000000..5abec41 --- /dev/null +++ b/lib/BurguillosInfo/Farmacia.pm @@ -0,0 +1,20 @@ +package BurguillosInfo::Farmacia; + +use v5.36.0; + +use strict; +use warnings; +use utf8; + +use Moo::Role; + +requires qw(id name address); + +sub serialize ($self) { + return { + id => $self->id, + name => $self->name, + address => $self->address, + }; +} +1; diff --git a/lib/BurguillosInfo/FarmaciaGuardia.pm b/lib/BurguillosInfo/FarmaciaGuardia.pm new file mode 100644 index 0000000..f847749 --- /dev/null +++ b/lib/BurguillosInfo/FarmaciaGuardia.pm @@ -0,0 +1,141 @@ +package BurguillosInfo::FarmaciaGuardia; + +use v5.36.0; + +use strict; +use warnings; +use utf8; + +use feature 'signatures'; + +use Data::Dumper; + +use Moo; +use DateTime; +use DateTime::Format::Pg; + +use Mojo::UserAgent; + +use BurguillosInfo::Farmacias; +use BurguillosInfo::Farmacias::CruzDeLaErmita; +use BurguillosInfo::Farmacias::Morera; + +has _app => ( is => 'lazy', ); +has _db => ( is => 'lazy' ); + +sub _build__app { + require BurguillosInfo; + return BurguillosInfo->new; +} + +sub get_current ($self) { + my $date_search = $self->_get_search_date; + my $farmacia_db = $self->_search_horario_db($date_search); + if (defined $farmacia_db) { + return $farmacia_db; + } + my $farmacia; + eval { + $farmacia = $self->_request_horario_internet($date_search); + }; + if (!defined $farmacia) { + die "API possibly broken for Farmacia de Guardia. $@"; + } + $self->_register_farmacia($date_search, $farmacia); + return $farmacia; +} + +sub _register_farmacia($self, $date_search, $farmacia) { + my $f = DateTime::Format::Pg->new; + my $dbh = $self->_db; + $dbh->do(<<'EOF', undef, $f->format_datetime($date_search), $farmacia->id); +INSERT INTO farmacia_guardia (date, id_farmacia) VALUES (?, ?); +EOF +} + +sub _search_horario_db ( $self, $date_search ) { + my $f = DateTime::Format::Pg->new; + my $db = $self->_db; + $date_search = $date_search->clone; + $date_search->set_time_zone('UTC'); + my $start_farmacia_week = $self->_get_start_date_week($date_search); + my $end_farmacia_week = $self->_get_end_date_week($date_search); + my $horarios = $db->selectall_arrayref( + <<'EOF', { Slice => {} }, $f->format_datetime($start_farmacia_week), $f->format_datetime($end_farmacia_week) ); +SELECT id_farmacia from farmacia_guardia where date > ? and date < ?; +EOF + if (!scalar @$horarios) { + return; + } + my $id = $horarios->[0]{id_farmacia}; + return BurguillosInfo::Farmacias->new->by_id($id); +} + +sub _request_horario_internet ( $self, $date_search ) { + my $ua = $self->_ua; + my $result = $ua->get( +'http://www.farmaciacruzdelaermita.com/index.php/component/dpcalendar/events', + form => { + limit => 0, + compact => 0, + my => 0, + format => 'raw', + ids => 10, + 'date-start' => $date_search->epoch, + 'date-end' => $date_search->epoch, + _ => $date_search->epoch * 1000, + } + )->result; + my $json; + eval { $json = $result->json; }; + if ($@) { + die "Unable to recover data of Farmacia de Guardia $@."; + } + my $data; + eval { $data = $json->[0]{data}; }; + if ( $@ || !defined $data ) { + die "Unable to get data of calendar."; + } + if ( scalar @$data ) { + return BurguillosInfo::Farmacias::CruzDeLaErmita->new; + } + return BurguillosInfo::Farmacias::Morera->new; +} + +sub _ua { + return Mojo::UserAgent->new; +} + +sub _get_search_date ($self) { + my $current_date = DateTime->now; + my $date_search = $current_date->clone; + if ( $date_search < $self->_get_start_date_week($current_date) ) { + $date_search = $date_search->add( days => -1 ); + } + return $date_search; +} + +sub _get_end_date_week ( $self, $date_search ) { + my $start_farmacia_week = $self->_get_start_date_week($date_search); + my $end_farmacia_week = $start_farmacia_week->clone->add( weeks => 1 ); + $end_farmacia_week->set_time_zone('Europe/Madrid'); + $end_farmacia_week->set_hour(9); + $end_farmacia_week->set_minute(30); + $end_farmacia_week->set_time_zone('UTC'); + return $end_farmacia_week; +} + +sub _get_start_date_week ( $self, $date_search ) { + my $start_farmacia_week = $date_search->clone->truncate( to => 'week' ); + $start_farmacia_week->set_time_zone('Europe/Madrid'); + $start_farmacia_week->set_hour(9); + $start_farmacia_week->set_minute(30); + $start_farmacia_week->set_time_zone('UTC'); + return $start_farmacia_week; +} + +sub _build__db ($self) { + require BurguillosInfo::DB; + return BurguillosInfo::DB->connect( $self->_app ); +} +1; diff --git a/lib/BurguillosInfo/Farmacias.pm b/lib/BurguillosInfo/Farmacias.pm new file mode 100644 index 0000000..2783083 --- /dev/null +++ b/lib/BurguillosInfo/Farmacias.pm @@ -0,0 +1,66 @@ +package BurguillosInfo::Farmacias; + +use v5.36.0; + +use strict; +use warnings; +use utf8; + +use Moo; + +use Module::Pluggable + search_path => ['BurguillosInfo::Farmacias'], + instantiate => 'new', + on_require_error => sub ( $plugin, $error ) { + die $error; + }; + +{ + my $array; + sub array($self) { + if (!defined $array) { + $self->_populate_farmacias; + } + return $array; + } + + sub _populate_farmacias($self) { + $array = []; + @$array = $self->plugins(); + for my $farmacia (@$array) { + $self->_check_farmacia_valid($farmacia); + } + } +} + +{ + my $farmacias_by_id; + sub by_id($self, $target_id) { + if (!defined $farmacias_by_id) { + $self->_populate_farmacias_by_id; + } + if (!defined $target_id) { + die 'You must pass $target_id.'; + } + my $farmacia = $farmacias_by_id->{$target_id}; + if (!defined $farmacia) { + die "Farmacia $target_id not found."; + } + return $farmacia; + } + + sub _populate_farmacias_by_id($self) { + $farmacias_by_id = {}; + my $farmacias = $self->array; + for my $farmacia (@$farmacias) { + $farmacias_by_id->{$farmacia->id} = $farmacia; + } + } +} + +sub _check_farmacia_valid($self, $farmacia) { + if ( !$farmacia->does('BurguillosInfo::Farmacia') ) { + die "$farmacia does not implement BurguillosInfo::Farmacia."; + } +} +1; diff --git a/lib/BurguillosInfo/Farmacias/CruzDeLaErmita.pm b/lib/BurguillosInfo/Farmacias/CruzDeLaErmita.pm new file mode 100644 index 0000000..be2e659 --- /dev/null +++ b/lib/BurguillosInfo/Farmacias/CruzDeLaErmita.pm @@ -0,0 +1,27 @@ +package BurguillosInfo::Farmacias::CruzDeLaErmita; + +use v5.36.0; + + +use strict; +use warnings; +use utf8; + +use feature 'signatures'; + +use Moo; +use parent 'BurguillosInfo::Farmacia'; + +sub id { + return 'cruz_de_la_ermita'; +} + +sub name { + return 'Farmacia Cruz de La Ermita'; +} + +sub address { + return 'Avenida. Alcalde José Cuesta Godoy, Nº 21. (La calle aun es como Avenida Cruz de la Ermita si lo buscas en Google Maps.)'; +} + +1; diff --git a/lib/BurguillosInfo/Farmacias/Morera.pm b/lib/BurguillosInfo/Farmacias/Morera.pm new file mode 100644 index 0000000..b19daef --- /dev/null +++ b/lib/BurguillosInfo/Farmacias/Morera.pm @@ -0,0 +1,24 @@ +package BurguillosInfo::Farmacias::Morera; + +use v5.36.0; + +use strict; +use warnings; +use utf8; + +use Moo; + +sub id { + return 'morera'; +} + +sub name { + return 'Farmacia Óptica Morera'; +} + +sub address { + return 'Calle Virgen del Rosario número 13'; +}; + +use parent 'BurguillosInfo::Farmacia'; +1; diff --git a/public/img/farmacia.webp b/public/img/farmacia.webp new file mode 100644 index 0000000..6cfef84 Binary files /dev/null and b/public/img/farmacia.webp differ diff --git a/public/js/bundle.js b/public/js/bundle.js index 86845fe..1b58155 100644 --- a/public/js/bundle.js +++ b/public/js/bundle.js @@ -16,7 +16,7 @@ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var tablesort__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tablesort */ \"./node_modules/tablesort/src/tablesort.js\");\n/* harmony import */ var tablesort__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(tablesort__WEBPACK_IMPORTED_MODULE_0__);\n\n\nwindow.Tablesort = __webpack_require__(/*! tablesort */ \"./node_modules/tablesort/src/tablesort.js\");\n__webpack_require__(/*! tablesort/src/sorts/tablesort.number */ \"./node_modules/tablesort/src/sorts/tablesort.number.js\");\n\nlet fakeSearchInput\nlet searchMobile\nwindow.onload = () => {\n const menu_expand = document.querySelector('a.menu-expand');\n const mobile_foldable = document.querySelector('nav.mobile-foldable');\n const tables = document.querySelectorAll('table')\n\n loadAd()\n addEasterEggAnimation()\n\n if (menu_expand !== null && mobile_foldable !== null) {\n menu_expand.addEventListener('click', () => {\n mobile_foldable.classList.toggle('show');\n });\n }\n\n for (const table of tables) {\n const header = table.querySelector('tr');\n if (header !== null) {\n header.setAttribute('data-sort-method', 'none')\n for (const th of header.querySelectorAll('th')) {\n if (th.getAttribute('data-sort-method') == null) {\n th.setAttribute('data-sort-method', 'thead')\n }\n }\n }\n new (tablesort__WEBPACK_IMPORTED_MODULE_0___default())(table)\n }\n if (window !== undefined && window.Android !== undefined) {\n executeAndroidExclusiveCode(Android)\n } \n searchMobile = document.querySelector('nav.mobile-shortcuts div.search')\n fakeSearchInput = searchMobile.querySelector('input')\n addListenersSearch()\n};\n\nfunction addListenersSearch() {\n if (searchMobile !== null) {\n const searchIcon = searchMobile.querySelector('div.search-icon')\n searchIcon.addEventListener('click', onFakeSearchClick);\n fakeSearchInput.addEventListener('change', (e) => {\n const searchOverlay = document.querySelector('div.search-overlay');\n const searchInput = searchOverlay.querySelector('div.search input');\n searchInput.value = fakeSearchInput.value;\n onSearchChange(e)\n onFakeSearchClick(e)\n });\n }\n const exitSearch = document.querySelector('a.exit-search')\n const searchOverlay = document.querySelector('div.search-overlay');\n const searchInput = searchOverlay.querySelector('div.search input');\n fakeSearchInput.value = searchInput.value;\n exitSearch.addEventListener('click', onExitSearch)\n const search = document.querySelector('div.search-overlay div.search input');\n if (search !== null) {\n search.addEventListener('change', onSearchChange);\n }\n}\n\nfunction onSearchChange() {\n const search = document.querySelector('div.search-overlay div.search input');\n const searchResults = document.querySelector('div.search-overlay div.search-results');\n if (search === null || searchResults === null) {\n return;\n }\n const query = search.value;\n fakeSearchInput.value = search.value\n let port = window.location.port;\n if (port !== '') {\n port = ':' + port\n }\n const url = new URL(window.location.protocol\n + \"//\"\n + window.location.hostname\n + port\n + '/search.json');\n url.searchParams.set('q', query);\n fetch(url).then(async (res) => {\n const json = await res.json()\n if (!json.ok) {\n noResults(searchResults);\n return\n }\n console.log(json.searchObjects.length)\n if (json.searchObjects.length < 1) {\n noResults(searchResults);\n return;\n }\n showResults(searchResults, json.searchObjects);\n })\n search.focus()\n}\n\nfunction showResults(searchResults, searchObjects) {\n searchResults.innerHTML = \"\";\n for (let searchObject of searchObjects) {\n const searchResultContainer = document.createElement('div')\n searchResultContainer.classList.add('search-result')\n const title = document.createElement('b')\n const url = document.createElement('a')\n const content = document.createElement('p')\n\n title.innerText = searchObject.title\n let port = window.location.port;\n if (port !== '') {\n port = ':' + port\n }\n if (searchObject.url.match(/^\\//)) {\n searchObject.url = window.location.protocol \n + \"//\" + window.location.hostname \n + port\n + searchObject.url\n }\n url.href = searchObject.url\n url.innerText = searchObject.url\n content.innerText = searchObject.content\n\n searchResultContainer.appendChild(title)\n searchResultContainer.appendChild(document.createElement('br'))\n searchResultContainer.appendChild(url)\n searchResultContainer.appendChild(content)\n searchResults.appendChild(searchResultContainer)\n }\n}\n\nfunction noResults(searchResults) {\n searchResults.innerHTML = \"\"\n const p = document.createElement('p')\n p.innerText = 'No se han encontrado resultados.'\n searchResults.appendChild(p)\n}\n\nfunction onExitSearch() {\n const searchOverlay = document.querySelector('div.search-overlay');\n if (searchOverlay !== null) {\n searchOverlay.classList.toggle('active');\n }\n}\n\nfunction onFakeSearchClick(e) {\n e.preventDefault();\n const searchOverlay = document.querySelector('div.search-overlay');\n if (searchOverlay === null) {\n return\n }\n searchOverlay.classList.toggle('active');\n const search = searchOverlay.querySelector('div.search input');\n if (search !== null) {\n search.focus()\n }\n return false;\n}\n\nfunction absoluteToHost(imageUrl) {\n if (imageUrl.match(/^\\//)) {\n imageUrl = window.location.protocol + \"//\" + window.location.host + imageUrl \n }\n return imageUrl.replace(/\\?.*$/, '');\n}\n\nfunction addListenerOpenInBrowserButton(android) {\n const openInBrowserLink = document.querySelector('a.open-in-browser')\n if (openInBrowserLink === null) {\n return\n }\n openInBrowserLink.addEventListener('click', () => {\n android.openInBrowser(window.location.href)\n })\n}\nfunction executeAndroidExclusiveCode(android) {\n document.querySelectorAll('*.android').forEach((element) => {\n element.classList.remove('android')\n })\n document.querySelectorAll('*.no-android-app').forEach((element) => {\n element.style.display = 'none';\n })\n addListenerOpenInBrowserButton(android)\n const pinToHomeUrl = document.querySelector('a.pin-to-home')\n if (pinToHomeUrl === null) {\n return;\n }\n pinToHomeUrl.addEventListener('click', () => {\n const url = new URL(window.location.href)\n const pathandQuery = url.pathname + url.search;\n const label = (url.pathname.replace(/^.*\\//g, '')\n .replace(/(?:^|-)\\w/g, function(character) {\n return character.toUpperCase() \n })\n .replace(/-/g, ' ')) + ' - Burguillos.info';\n const firstImg = document.querySelector('div.description img');\n let iconUrl;\n if (firstImg !== null) {\n if (!firstImg.src.match(/\\.svg(?:\\?|$)/)) {\n iconUrl = absoluteToHost(firstImg.src);\n }\n }\n if (iconUrl === undefined) {\n const imagePreview = document.querySelector('meta[name=\"image\"]');\n iconUrl = absoluteToHost(imagePreview.content);\n }\n android.pinPage(pathandQuery, label, iconUrl)\n })\n}\n\nfunction addEasterEggAnimation() {\n const logoContainer = document.querySelector('div.burguillos-logo-container')\n if (logoContainer === null) {\n return;\n }\n logoContainer.addEventListener('click', () => {\n logoContainer.classList.toggle('active')\n })\n}\n\nlet current_ad_number = null\n\nfunction expand_page_contents() {\n const page_contents = document.querySelector('div.page-contents'); \n if (page_contents === null) {\n return;\n }\n page_contents.classList.add('no-carousel');\n}\n\nfunction no_more_ads() {\n const carousel = document.querySelector('.carousel');\n if (carousel !== null) {\n carousel.remove();\n }\n expand_page_contents();\n}\n\nfunction loadAd() {\n const params = new URLSearchParams();\n if (current_ad_number !== null) {\n params.append('n', \"\"+current_ad_number);\n }\n fetch('/next-ad.json?' + params).then((res) => {\n return res.json()\n }).then((res) => {\n current_ad_number = res.current_ad_number\n const ad = res.ad\n const must_continue = res.continue\n const carousel = document.querySelector('.carousel');\n if (must_continue === 0\n || carousel === null\n || carousel.offsetWidth === 0) {\n no_more_ads();\n return;\n }\n const a = _retrieveLinkCarousel(carousel)\n a.innerHTML = \"\"\n const image = document.createElement('img')\n const text_container = document.createElement('div')\n const text = document.createElement('h4')\n const promoted = document.createElement('p')\n\n promoted.classList.add('promoted-tag')\n promoted.innerText = \"Promocionado\"\n image.src = ad.img\n image.alt = \"\"\n text.innerText = ad.text\n a.href = ad.href\n\n a.append(image)\n text_container.append(promoted)\n text_container.append(text)\n a.append(text_container)\n\n window.setTimeout(() => {\n loadAd()\n }, ad.seconds * 1000)\n }).catch(() => {\n window.setTimeout(() => {\n loadAd()\n }, 1000)\n });\n}\n\nfunction _retrieveLinkCarousel(carousel) {\n const maybeA = carousel.querySelector('a')\n if (maybeA !== null) {\n return maybeA\n }\n const a = document.createElement('a')\n carousel.innerHTML = \"\"\n carousel.append(a)\n return a\n}\n\n\n//# sourceURL=webpack://BurguillosInfo/./js-src/index.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var tablesort__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tablesort */ \"./node_modules/tablesort/src/tablesort.js\");\n/* harmony import */ var tablesort__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(tablesort__WEBPACK_IMPORTED_MODULE_0__);\n\n\nwindow.Tablesort = __webpack_require__(/*! tablesort */ \"./node_modules/tablesort/src/tablesort.js\");\n__webpack_require__(/*! tablesort/src/sorts/tablesort.number */ \"./node_modules/tablesort/src/sorts/tablesort.number.js\");\n\nlet fakeSearchInput\nlet searchMobile\nwindow.onload = () => {\n const menu_expand = document.querySelector('a.menu-expand');\n const mobile_foldable = document.querySelector('nav.mobile-foldable');\n const tables = document.querySelectorAll('table')\n\n fillFarmaciaGuardia();\n loadAd()\n addEasterEggAnimation()\n\n if (menu_expand !== null && mobile_foldable !== null) {\n menu_expand.addEventListener('click', () => {\n mobile_foldable.classList.toggle('show');\n });\n }\n\n for (const table of tables) {\n const header = table.querySelector('tr');\n if (header !== null) {\n header.setAttribute('data-sort-method', 'none')\n for (const th of header.querySelectorAll('th')) {\n if (th.getAttribute('data-sort-method') == null) {\n th.setAttribute('data-sort-method', 'thead')\n }\n }\n }\n new (tablesort__WEBPACK_IMPORTED_MODULE_0___default())(table)\n }\n if (window !== undefined && window.Android !== undefined) {\n executeAndroidExclusiveCode(Android)\n } \n searchMobile = document.querySelector('nav.mobile-shortcuts div.search')\n fakeSearchInput = searchMobile.querySelector('input')\n addListenersSearch()\n};\n\nfunction fillFarmaciaGuardia() {\n const farmaciaName = document.querySelector('#farmacia-name');\n const farmaciaAddress = document.querySelector('#farmacia-address');\n if (farmaciaName !== null || farmaciaAddress !== null) {\n const port = _port()\n const url = new URL(window.location.protocol\n + \"//\"\n + window.location.hostname\n + port\n + '/farmacia-guardia.json');\n fetch(url).then(async (res) => {\n const farmacia = await res.json()\n if (farmaciaName !== null) {\n farmaciaName.innerText = farmacia.name;\n farmaciaAddress.innerText = farmacia.address;\n }\n })\n }\n}\n\nfunction addListenersSearch() {\n if (searchMobile !== null) {\n const searchIcon = searchMobile.querySelector('div.search-icon')\n searchIcon.addEventListener('click', onFakeSearchClick);\n fakeSearchInput.addEventListener('change', (e) => {\n const searchOverlay = document.querySelector('div.search-overlay');\n const searchInput = searchOverlay.querySelector('div.search input');\n searchInput.value = fakeSearchInput.value;\n onSearchChange(e)\n onFakeSearchClick(e)\n });\n }\n const exitSearch = document.querySelector('a.exit-search')\n const searchOverlay = document.querySelector('div.search-overlay');\n const searchInput = searchOverlay.querySelector('div.search input');\n fakeSearchInput.value = searchInput.value;\n exitSearch.addEventListener('click', onExitSearch)\n const search = document.querySelector('div.search-overlay div.search input');\n if (search !== null) {\n search.addEventListener('change', onSearchChange);\n }\n}\n\nfunction _port() {\n let port = window.location.port;\n if (port !== '') {\n port = ':' + port\n }\n return port;\n}\n\nfunction onSearchChange() {\n const search = document.querySelector('div.search-overlay div.search input');\n const searchResults = document.querySelector('div.search-overlay div.search-results');\n if (search === null || searchResults === null) {\n return;\n }\n const query = search.value;\n fakeSearchInput.value = search.value\n const port = _port()\n const url = new URL(window.location.protocol\n + \"//\"\n + window.location.hostname\n + port\n + '/search.json');\n url.searchParams.set('q', query);\n fetch(url).then(async (res) => {\n const json = await res.json()\n if (!json.ok) {\n noResults(searchResults);\n return\n }\n console.log(json.searchObjects.length)\n if (json.searchObjects.length < 1) {\n noResults(searchResults);\n return;\n }\n showResults(searchResults, json.searchObjects);\n })\n search.focus()\n}\n\nfunction showResults(searchResults, searchObjects) {\n searchResults.innerHTML = \"\";\n for (let searchObject of searchObjects) {\n const searchResultContainer = document.createElement('div')\n searchResultContainer.classList.add('search-result')\n const title = document.createElement('b')\n const url = document.createElement('a')\n const content = document.createElement('p')\n\n title.innerText = searchObject.title\n let port = window.location.port;\n if (port !== '') {\n port = ':' + port\n }\n if (searchObject.url.match(/^\\//)) {\n searchObject.url = window.location.protocol \n + \"//\" + window.location.hostname \n + port\n + searchObject.url\n }\n url.href = searchObject.url\n url.innerText = searchObject.url\n content.innerText = searchObject.content\n\n searchResultContainer.appendChild(title)\n searchResultContainer.appendChild(document.createElement('br'))\n searchResultContainer.appendChild(url)\n searchResultContainer.appendChild(content)\n searchResults.appendChild(searchResultContainer)\n }\n}\n\nfunction noResults(searchResults) {\n searchResults.innerHTML = \"\"\n const p = document.createElement('p')\n p.innerText = 'No se han encontrado resultados.'\n searchResults.appendChild(p)\n}\n\nfunction onExitSearch() {\n const searchOverlay = document.querySelector('div.search-overlay');\n if (searchOverlay !== null) {\n searchOverlay.classList.toggle('active');\n }\n}\n\nfunction onFakeSearchClick(e) {\n e.preventDefault();\n const searchOverlay = document.querySelector('div.search-overlay');\n if (searchOverlay === null) {\n return\n }\n searchOverlay.classList.toggle('active');\n const search = searchOverlay.querySelector('div.search input');\n if (search !== null) {\n search.focus()\n }\n return false;\n}\n\nfunction absoluteToHost(imageUrl) {\n if (imageUrl.match(/^\\//)) {\n imageUrl = window.location.protocol + \"//\" + window.location.host + imageUrl \n }\n return imageUrl.replace(/\\?.*$/, '');\n}\n\nfunction addListenerOpenInBrowserButton(android) {\n const openInBrowserLink = document.querySelector('a.open-in-browser')\n if (openInBrowserLink === null) {\n return\n }\n openInBrowserLink.addEventListener('click', () => {\n android.openInBrowser(window.location.href)\n })\n}\nfunction executeAndroidExclusiveCode(android) {\n document.querySelectorAll('*.android').forEach((element) => {\n element.classList.remove('android')\n })\n document.querySelectorAll('*.no-android-app').forEach((element) => {\n element.style.display = 'none';\n })\n addListenerOpenInBrowserButton(android)\n const pinToHomeUrl = document.querySelector('a.pin-to-home')\n if (pinToHomeUrl === null) {\n return;\n }\n pinToHomeUrl.addEventListener('click', () => {\n const url = new URL(window.location.href)\n const pathandQuery = url.pathname + url.search;\n const label = (url.pathname.replace(/^.*\\//g, '')\n .replace(/(?:^|-)\\w/g, function(character) {\n return character.toUpperCase() \n })\n .replace(/-/g, ' ')) + ' - Burguillos.info';\n const firstImg = document.querySelector('div.description img');\n let iconUrl;\n if (firstImg !== null) {\n if (!firstImg.src.match(/\\.svg(?:\\?|$)/)) {\n iconUrl = absoluteToHost(firstImg.src);\n }\n }\n if (iconUrl === undefined) {\n const imagePreview = document.querySelector('meta[name=\"image\"]');\n iconUrl = absoluteToHost(imagePreview.content);\n }\n android.pinPage(pathandQuery, label, iconUrl)\n })\n}\n\nfunction addEasterEggAnimation() {\n const logoContainer = document.querySelector('div.burguillos-logo-container')\n if (logoContainer === null) {\n return;\n }\n logoContainer.addEventListener('click', () => {\n logoContainer.classList.toggle('active')\n })\n}\n\nlet current_ad_number = null\n\nfunction expand_page_contents() {\n const page_contents = document.querySelector('div.page-contents'); \n if (page_contents === null) {\n return;\n }\n page_contents.classList.add('no-carousel');\n}\n\nfunction no_more_ads() {\n const carousel = document.querySelector('.carousel');\n if (carousel !== null) {\n carousel.remove();\n }\n expand_page_contents();\n}\n\nfunction loadAd() {\n const params = new URLSearchParams();\n if (current_ad_number !== null) {\n params.append('n', \"\"+current_ad_number);\n }\n fetch('/next-ad.json?' + params).then((res) => {\n return res.json()\n }).then((res) => {\n current_ad_number = res.current_ad_number\n const ad = res.ad\n const must_continue = res.continue\n const carousel = document.querySelector('.carousel');\n if (must_continue === 0\n || carousel === null\n || carousel.offsetWidth === 0) {\n no_more_ads();\n return;\n }\n const a = _retrieveLinkCarousel(carousel)\n a.innerHTML = \"\"\n const image = document.createElement('img')\n const text_container = document.createElement('div')\n const text = document.createElement('h4')\n const promoted = document.createElement('p')\n\n promoted.classList.add('promoted-tag')\n promoted.innerText = \"Promocionado\"\n image.src = ad.img\n image.alt = \"\"\n text.innerText = ad.text\n a.href = ad.href\n\n a.append(image)\n text_container.append(promoted)\n text_container.append(text)\n a.append(text_container)\n\n window.setTimeout(() => {\n loadAd()\n }, ad.seconds * 1000)\n }).catch(() => {\n window.setTimeout(() => {\n loadAd()\n }, 1000)\n });\n}\n\nfunction _retrieveLinkCarousel(carousel) {\n const maybeA = carousel.querySelector('a')\n if (maybeA !== null) {\n return maybeA\n }\n const a = document.createElement('a')\n carousel.innerHTML = \"\"\n carousel.append(a)\n return a\n}\n\n\n//# sourceURL=webpack://BurguillosInfo/./js-src/index.js?"); /***/ }),