{"id":38636,"date":"2026-02-02T02:19:34","date_gmt":"2026-02-02T02:19:34","guid":{"rendered":"https:\/\/ecuadorlodges.info\/?page_id=38636"},"modified":"2026-02-02T04:17:36","modified_gmt":"2026-02-02T04:17:36","slug":"base-datos","status":"publish","type":"page","link":"https:\/\/ecuadorlodges.info\/es\/base-datos\/","title":{"rendered":"base-datos"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"38636\" class=\"elementor elementor-38636\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5e6e67b e-flex e-con-boxed e-con e-parent\" data-id=\"5e6e67b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c2b3d60 elementor-widget elementor-widget-shortcode\" data-id=\"c2b3d60\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\n  <div class=\"lodges-db\" id=\"lodgesDBApp\">\n    <div class=\"wrap\">\n      <h1>Base de datos de Lodges \u2014 Ecuador<\/h1>\n      <p>Base local (localStorage). Fotos y links como texto. Links se abren solo al hacer clic.<\/p>\n\n      <div class=\"grid\">\n        <!-- FORMULARIO -->\n        <section class=\"panel\">\n          <div class=\"panel-head\">\n            <b>Formulario Lodge<\/b>\n            <button class=\"ghost\" id=\"reset\" type=\"button\">Limpiar<\/button>\n          <\/div>\n\n          <div class=\"panel-body\">\n            <input type=\"hidden\" id=\"id\">\n\n            <label>Nombre<\/label>\n            <input id=\"nombre\" placeholder=\"Ej: Cuyabeno Lodge\">\n\n            <div class=\"row row-2\">\n              <div>\n                <label>Categor\u00eda<\/label>\n                <input id=\"categoria\" placeholder=\"Ej: Amazon\u00eda \/ Andes \/ Cloud Forest \/ Gal\u00e1pagos\">\n              <\/div>\n              <div>\n                <label>Tipo<\/label>\n                <input id=\"tipo\" placeholder=\"Ej: Rainforest lodge \/ Hacienda \/ Cruise\">\n              <\/div>\n            <\/div>\n\n            <label>Localizaci\u00f3n<\/label>\n            <input id=\"localizacion\" placeholder=\"Ej: Cuyabeno, Sucumb\u00edos\">\n\n            <label>Capacidad (campo libre)<\/label>\n            <input id=\"capacidad\" placeholder=\"Ej: 35 hu\u00e9spedes \/ 18 rooms \/ 10 caba\u00f1as\">\n\n            <label>Foto (URL \/ link)<\/label>\n            <input id=\"foto\" placeholder=\"https:\/\/...\/foto.jpg o \/wp-content\/uploads\/...jpg\">\n            <div class=\"hint\">No se carga imagen (solo se abre al hacer clic).<\/div>\n\n            <label>Actividades (separadas por coma)<\/label>\n            <textarea id=\"act\" placeholder=\"Ej: canoeing, birdwatching, night walk\"><\/textarea>\n\n            <label>D\u00edas de salida<\/label>\n            <input id=\"dias\" placeholder=\"Ej: Todos los d\u00edas \/ Lunes y Jueves\">\n\n            <label>Link del lodge<\/label>\n            <input id=\"link\" placeholder=\"https:\/\/tusitio.com\/lodge\/...\">\n\n            <div class=\"divider\"><\/div>\n\n            <label>Tours (m\u00faltiples)<\/label>\n            <div class=\"hint\">Ej: 4D\/3N, 5D\/4N. Precio opcional.<\/div>\n            <div class=\"tours\" id=\"toursBox\"><\/div>\n\n            <div class=\"btns\">\n              <button class=\"ok\" id=\"addTour\" type=\"button\">+ Agregar tour<\/button>\n            <\/div>\n\n            <div class=\"divider\"><\/div>\n\n            <div class=\"btns\">\n              <button class=\"primary\" id=\"save\" type=\"button\">Guardar<\/button>\n              <button class=\"warn\" id=\"update\" type=\"button\" style=\"display:none\">Actualizar<\/button>\n              <button class=\"bad\" id=\"del\" type=\"button\" style=\"display:none\">Eliminar<\/button>\n            <\/div>\n\n            <div class=\"divider\"><\/div>\n\n            <label>Exportar \/ Importar<\/label>\n            <div class=\"btns\">\n              <button class=\"ghost\" id=\"export\" type=\"button\">Exportar JSON<\/button>\n              <button class=\"ghost\" id=\"importBtn\" type=\"button\">Importar JSON<\/button>\n              <button class=\"ghost\" id=\"wipe\" type=\"button\">Borrar TODO<\/button>\n            <\/div>\n            <input id=\"importFile\" type=\"file\" accept=\"application\/json\" style=\"display:none\">\n            <div class=\"hint\"><b>Importar<\/b> reemplaza la base actual por el archivo JSON.<\/div>\n          <\/div>\n        <\/section>\n\n        <!-- LISTADO -->\n        <section class=\"panel\">\n          <div class=\"panel-head\">\n            <b>Lodges<\/b>\n            <span id=\"count\" style=\"font-size:12px;color:var(--muted)\"><\/span>\n          <\/div>\n\n          <div class=\"panel-body\" style=\"padding:14px;border-bottom:1px solid var(--line);background:rgba(0,0,0,.10)\">\n            <div class=\"filters\">\n              <div>\n                <label>Buscar (nombre \/ ubicaci\u00f3n \/ tipo \/ actividades \/ tours)<\/label>\n                <input id=\"q\" placeholder=\"Ej: cuyabeno, birdwatching, 4D\/3N...\">\n              <\/div>\n              <div>\n                <label>Filtrar por categor\u00eda<\/label>\n                <select id=\"fCat\"><option value=\"\">Todas<\/option><\/select>\n              <\/div>\n              <div>\n                <label>Filtrar por tipo<\/label>\n                <select id=\"fTipo\"><option value=\"\">Todos<\/option><\/select>\n              <\/div>\n            <\/div>\n            <div class=\"stats\" id=\"stats\"><\/div>\n          <\/div>\n\n          <div class=\"cards\" id=\"cards\"><\/div>\n        <\/section>\n      <\/div>\n    <\/div>\n\n    <div class=\"toast\" id=\"toast\"><\/div>\n  <\/div>\n\n  <style>\n  .lodges-db{\n    --bg:#0f172a;--panel:#111c36;--muted:#9aa4b2;--text:#e5e7eb;--line:rgba(255,255,255,.10);\n    --accent:#D34600;--radius:16px;--font:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;\n    font-family:var(--font);background:var(--bg);color:var(--text);padding:24px 0 60px;\n  }\n  .lodges-db *{box-sizing:border-box}\n  .lodges-db .wrap{max-width:1200px;margin:0 auto;padding:0 16px}\n  .lodges-db h1{margin:0 0 6px}\n  .lodges-db p{margin:0;color:var(--muted);font-size:13px;line-height:1.4}\n  .lodges-db .grid{display:grid;grid-template-columns:420px 1fr;gap:16px;margin-top:16px}\n  @media(max-width:900px){.lodges-db .grid{grid-template-columns:1fr}}\n  .lodges-db .panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}\n  .lodges-db .panel-head{padding:12px 14px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;gap:10px}\n  .lodges-db .panel-body{padding:14px}\n  .lodges-db label{display:block;font-size:12px;color:var(--muted);margin:10px 0 6px}\n  .lodges-db input,.lodges-db textarea,.lodges-db select{\n    width:100%;padding:10px;border-radius:10px;border:1px solid var(--line);\n    background:#0b1226;color:var(--text);outline:none\n  }\n  .lodges-db textarea{min-height:70px;resize:vertical}\n  .lodges-db .row{display:grid;gap:10px}\n  .lodges-db .row-2{grid-template-columns:1fr 1fr}\n  @media(max-width:600px){.lodges-db .row-2{grid-template-columns:1fr}}\n  .lodges-db .hint{margin-top:6px;font-size:11px;color:var(--muted)}\n  .lodges-db button{\n    border:1px solid var(--line);background:#1f2937;color:#fff;padding:9px 12px;border-radius:999px;\n    cursor:pointer;font-size:12px;font-weight:800\n  }\n  .lodges-db button:hover{filter:brightness(1.05)}\n  .lodges-db .primary{background:var(--accent)}\n  .lodges-db .ok{background:rgba(34,197,94,.22)}\n  .lodges-db .warn{background:rgba(245,158,11,.22)}\n  .lodges-db .bad{background:rgba(239,68,68,.22)}\n  .lodges-db .ghost{background:transparent}\n  .lodges-db .btns{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}\n  .lodges-db .divider{height:1px;background:var(--line);margin:12px 0}\n  .lodges-db .tours{display:flex;flex-direction:column;gap:10px;padding:10px;border:1px dashed rgba(255,255,255,.16);border-radius:14px;background:rgba(0,0,0,.12)}\n  .lodges-db .tour-line{display:grid;grid-template-columns:1.2fr .6fr .5fr .5fr auto;gap:8px;align-items:center}\n  .lodges-db .tour-line input{padding:9px;border-radius:10px}\n  .lodges-db .tour-line .del{padding:9px 10px;border-radius:10px;background:rgba(239,68,68,.18);border:1px solid rgba(239,68,68,.35);font-weight:900}\n  @media(max-width:720px){.lodges-db .tour-line{grid-template-columns:1fr 1fr}.lodges-db .tour-line .del{grid-column:1\/-1}}\n  .lodges-db .filters{display:grid;grid-template-columns:1.2fr .8fr .8fr;gap:10px;align-items:end}\n  @media(max-width:900px){.lodges-db .filters{grid-template-columns:1fr}}\n  .lodges-db .stats{margin-top:10px;display:flex;gap:8px;flex-wrap:wrap;color:var(--muted);font-size:12px}\n  .lodges-db .pill{padding:7px 10px;border-radius:999px;border:1px solid var(--line);background:rgba(255,255,255,.06)}\n  .lodges-db .cards{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;padding:14px}\n  @media(max-width:1000px){.lodges-db .cards{grid-template-columns:repeat(2,1fr)}}\n  @media(max-width:600px){.lodges-db .cards{grid-template-columns:1fr}}\n  .lodges-db .card{border:1px solid var(--line);border-radius:14px;padding:12px;background:#0b1226;display:flex;flex-direction:column;gap:8px}\n  .lodges-db .card h3{margin:0;font-size:15px;letter-spacing:.2px}\n  .lodges-db .meta{font-size:12px;color:var(--muted);line-height:1.5}\n  .lodges-db .acts,.lodges-db .toursList{margin:6px 0 0;padding-left:18px;color:var(--text);font-size:12px;line-height:1.45}\n  .lodges-db .acts li,.lodges-db .toursList li{margin:2px 0}\n  .lodges-db .actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:6px}\n  .lodges-db .toast{position:fixed;right:16px;bottom:16px;background:#000c;padding:12px 14px;border-radius:12px;opacity:0;transform:translateY(6px);transition:.2s;border:1px solid var(--line);max-width:520px;white-space:pre-wrap;z-index:999999}\n  .lodges-db .toast.show{opacity:1;transform:translateY(0)}\n  <\/style>\n\n  <script>\n  (function(){\n    function init(){\n      var root = document.getElementById(\"lodgesDBApp\");\n      if(!root) return;\n\n      var KEY = \"ecuador_lodges_db_v4\";\n      var OLD_KEYS = [\"ecuador_lodges_db_v2\",\"ecuador_lodges_db_v3\",\"ecuador_lodges_no_foto\"];\n\n      function $(id){ return root.querySelector(\"#\"+id); }\n      function toast(msg){\n        var o = $(\"toast\"); if(!o) return;\n        o.textContent = String(msg||\"\"); o.classList.add(\"show\");\n        clearTimeout(o._t); o._t = setTimeout(function(){ o.classList.remove(\"show\"); }, 2200);\n      }\n      function escapeHtml(str){\n        str = String(str==null?\"\":str);\n        return str.replace(\/&\/g,\"&amp;\").replace(\/<\/g,\"&lt;\").replace(\/>\/g,\"&gt;\")\n                  .replace(\/\"\/g,\"&quot;\").replace(\/'\/g,\"&#039;\");\n      }\n      function norm(s){\n        s = (s||\"\").toString().toLowerCase();\n        if(s.normalize){ s = s.normalize(\"NFD\").replace(\/[\\u0300-\\u036f]\/g,\"\"); }\n        return s;\n      }\n      function uniqueSorted(arr){\n        var seen={}, out=[];\n        for(var i=0;i<arr.length;i++){\n          var v=(arr[i]||\"\").trim();\n          if(v && !seen[v]){ seen[v]=1; out.push(v); }\n        }\n        out.sort(function(a,b){ return a.localeCompare(b,\"es\"); });\n        return out;\n      }\n      function uid(){ return \"lod_\" + Math.random().toString(16).slice(2) + Date.now().toString(16); }\n\n      function resolveToSafeHttpUrl(raw){\n        raw = (raw||\"\").trim(); if(!raw) return \"\";\n        try{\n          var u = new URL(raw, window.location.href);\n          if(u.protocol===\"http:\"||u.protocol===\"https:\") return u.toString();\n          return \"\";\n        }catch(e){ return \"\"; }\n      }\n      function openLink(raw){\n        var url = resolveToSafeHttpUrl(raw);\n        if(!url) return toast(\"Link inv\u00e1lido o vac\u00edo.\");\n        window.open(url,\"_blank\",\"noopener\");\n      }\n\n      function normalizeItem(x){\n        x = x || {};\n        var cap = (x.capacidad!=null ? String(x.capacidad).trim() : \"\");\n        if(!cap){\n          var parts=[];\n          if(x.h) parts.push(x.h+\" hu\u00e9spedes\");\n          if(x.hab) parts.push(x.hab+\" hab\");\n          if(x.cab) parts.push(x.cab+\" cab\");\n          cap = parts.join(\" \/ \");\n        }\n        var acts=[];\n        if(Array.isArray(x.actividades)) acts=x.actividades;\n        else if(Array.isArray(x.act)) acts=x.act;\n        else if(typeof x.act===\"string\") acts=x.act.split(\",\").map(function(s){return s.trim();}).filter(Boolean);\n\n        var tours=[];\n        if(Array.isArray(x.tours)){\n          for(var i=0;i<x.tours.length;i++){\n            var t=x.tours[i]||{};\n            var one={nombre:String(t.nombre||\"\").trim(),precio:Number(t.precio||0),dias:Number(t.dias||0),noches:Number(t.noches||0)};\n            if(one.nombre||one.precio||one.dias||one.noches) tours.push(one);\n          }\n        }\n\n        return {\n          id:x.id||uid(),\n          nombre:String(x.nombre||\"\").trim(),\n          categoria:String(x.categoria||\"\").trim(),\n          tipo:String(x.tipo||\"\").trim(),\n          localizacion:String(x.localizacion||\"\").trim(),\n          capacidad:String(cap||\"\").trim(),\n          foto:String(x.foto||x.photo||\"\").trim(),\n          actividades:acts.map(function(s){return String(s).trim();}).filter(Boolean),\n          dias:String(x.dias||x.diasSalida||\"\").trim(),\n          link:String(x.link||\"\").trim(),\n          tours:tours\n        };\n      }\n\n      function loadDB(){\n        var raw = localStorage.getItem(KEY);\n        if(raw){\n          try{\n            var data = JSON.parse(raw);\n            if(Array.isArray(data)) return data.map(normalizeItem).filter(function(x){return x.nombre;});\n          }catch(e){}\n        }\n        for(var k=0;k<OLD_KEYS.length;k++){\n          var oldRaw = localStorage.getItem(OLD_KEYS[k]);\n          if(oldRaw){\n            try{\n              var oldData = JSON.parse(oldRaw);\n              if(Array.isArray(oldData)){\n                var migrated = oldData.map(normalizeItem).filter(function(x){return x.nombre;});\n                localStorage.setItem(KEY, JSON.stringify(migrated));\n                return migrated;\n              }\n            }catch(e){}\n          }\n        }\n        localStorage.setItem(KEY, JSON.stringify([]));\n        return [];\n      }\n\n      var db = loadDB();\n      function saveDB(){ localStorage.setItem(KEY, JSON.stringify(db)); }\n\n      var toursBox = $(\"toursBox\");\n      function makeTourLine(t){\n        t=t||{nombre:\"\",precio:\"\",dias:\"\",noches:\"\"};\n        var line=document.createElement(\"div\");\n        line.className=\"tour-line\";\n        line.innerHTML=\n          '<input type=\"text\" class=\"tNombre\" placeholder=\"Nombre (ej: 4D\/3N)\" value=\"'+escapeHtml(t.nombre||\"\")+'\">'+\n          '<input type=\"number\" class=\"tPrecio\" min=\"0\" placeholder=\"Precio\" value=\"'+escapeHtml(t.precio||\"\")+'\">'+\n          '<input type=\"number\" class=\"tDias\" min=\"0\" placeholder=\"D\u00edas\" value=\"'+escapeHtml(t.dias||\"\")+'\">'+\n          '<input type=\"number\" class=\"tNoches\" min=\"0\" placeholder=\"Noches\" value=\"'+escapeHtml(t.noches||\"\")+'\">'+\n          '<button type=\"button\" class=\"del\">Quitar<\/button>';\n        line.querySelector(\".del\").onclick=function(){ line.remove(); };\n        return line;\n      }\n      function ensureOneTour(){ if(toursBox && !toursBox.children.length) toursBox.appendChild(makeTourLine()); }\n      $(\"addTour\").onclick=function(){ toursBox.appendChild(makeTourLine()); };\n\n      function readToursFromUI(){\n        var lines=[].slice.call(toursBox.querySelectorAll(\".tour-line\"));\n        var out=[];\n        for(var i=0;i<lines.length;i++){\n          var line=lines[i];\n          var nombre=(line.querySelector(\".tNombre\").value||\"\").trim();\n          var precio=Number(line.querySelector(\".tPrecio\").value||0);\n          var dias=Number(line.querySelector(\".tDias\").value||0);\n          var noches=Number(line.querySelector(\".tNoches\").value||0);\n          if(!nombre && !precio && !dias && !noches) continue;\n          out.push({nombre:nombre,precio:precio,dias:dias,noches:noches});\n        }\n        return out;\n      }\n\n      function resetForm(){\n        $(\"id\").value=\"\";\n        [\"nombre\",\"categoria\",\"tipo\",\"localizacion\",\"capacidad\",\"foto\",\"act\",\"dias\",\"link\"].forEach(function(i){ $(i).value=\"\"; });\n        toursBox.innerHTML=\"\";\n        ensureOneTour();\n        $(\"save\").style.display=\"inline-block\";\n        $(\"update\").style.display=\"none\";\n        $(\"del\").style.display=\"none\";\n      }\n      $(\"reset\").onclick=resetForm;\n\n      function readForm(){\n        return {\n          nombre:$(\"nombre\").value.trim(),\n          categoria:$(\"categoria\").value.trim(),\n          tipo:$(\"tipo\").value.trim(),\n          localizacion:$(\"localizacion\").value.trim(),\n          capacidad:$(\"capacidad\").value.trim(),\n          foto:$(\"foto\").value.trim(),\n          actividades:$(\"act\").value.split(\",\").map(function(s){return s.trim();}).filter(Boolean),\n          dias:$(\"dias\").value.trim(),\n          link:$(\"link\").value.trim(),\n          tours:readToursFromUI()\n        };\n      }\n      function validate(o){ return !o.nombre ? \"Falta el nombre.\" : \"\"; }\n\n      $(\"save\").onclick=function(){\n        var data=readForm();\n        var err=validate(data);\n        if(err) return toast(err);\n        data.id=uid();\n        db.unshift(normalizeItem(data));\n        saveDB(); resetForm(); rebuildAll(); toast(\"Guardado\");\n      };\n\n      $(\"update\").onclick=function(){\n        var id=$(\"id\").value;\n        if(!id) return toast(\"No hay lodge seleccionado.\");\n        var data=readForm();\n        var err=validate(data);\n        if(err) return toast(err);\n        for(var i=0;i<db.length;i++){\n          if(db[i].id===id){ data.id=id; db[i]=normalizeItem(data); break; }\n        }\n        saveDB(); resetForm(); rebuildAll(); toast(\"Actualizado\");\n      };\n\n      $(\"del\").onclick=function(){\n        var id=$(\"id\").value;\n        if(!id) return toast(\"No hay lodge seleccionado.\");\n        var name=\"este lodge\";\n        for(var i=0;i<db.length;i++){ if(db[i].id===id){ name=db[i].nombre||name; break; } }\n        if(!confirm('\u00bfEliminar \"'+name+'\"?')) return;\n        db=db.filter(function(x){ return x.id!==id; });\n        saveDB(); resetForm(); rebuildAll(); toast(\"Eliminado\");\n      };\n\n      function loadToForm(l){\n        $(\"id\").value=l.id;\n        $(\"nombre\").value=l.nombre||\"\";\n        $(\"categoria\").value=l.categoria||\"\";\n        $(\"tipo\").value=l.tipo||\"\";\n        $(\"localizacion\").value=l.localizacion||\"\";\n        $(\"capacidad\").value=l.capacidad||\"\";\n        $(\"foto\").value=l.foto||\"\";\n        $(\"act\").value=(l.actividades||[]).join(\", \");\n        $(\"dias\").value=l.dias||\"\";\n        $(\"link\").value=l.link||\"\";\n\n        toursBox.innerHTML=\"\";\n        var list=(l.tours&&l.tours.length)?l.tours:[{nombre:\"\",precio:\"\",dias:\"\",noches:\"\"}];\n        for(var i=0;i<list.length;i++) toursBox.appendChild(makeTourLine(list[i]));\n        ensureOneTour();\n\n        $(\"save\").style.display=\"none\";\n        $(\"update\").style.display=\"inline-block\";\n        $(\"del\").style.display=\"inline-block\";\n        toast(\"Cargado para editar\");\n      }\n\n      $(\"export\").onclick=function(){\n        var blob=new Blob([JSON.stringify(db,null,2)],{type:\"application\/json\"});\n        var url=URL.createObjectURL(blob);\n        var a=document.createElement(\"a\");\n        a.href=url; a.download=\"ecuador-lodges-db.json\"; a.click();\n        URL.revokeObjectURL(url);\n        toast(\"JSON exportado\");\n      };\n\n      $(\"importBtn\").onclick=function(){ $(\"importFile\").click(); };\n      $(\"importFile\").addEventListener(\"change\", function(e){\n        var f=e.target.files && e.target.files[0];\n        if(!f) return;\n        var reader=new FileReader();\n        reader.onload=function(){\n          try{\n            var data=JSON.parse(reader.result);\n            if(!Array.isArray(data)) throw new Error(\"JSON inv\u00e1lido (no es arreglo).\");\n            db=data.map(normalizeItem).filter(function(x){return x.nombre;});\n            saveDB(); resetForm(); rebuildAll(); toast(\"JSON importado\");\n          }catch(err){\n            toast(\"Error importando: \" + (err && err.message ? err.message : \"archivo inv\u00e1lido\"));\n          }finally{ $(\"importFile\").value=\"\"; }\n        };\n        reader.readAsText(f);\n      });\n\n      $(\"wipe\").onclick=function(){\n        if(!confirm(\"\u00bfBorrar TODA la base? (No se puede deshacer)\")) return;\n        localStorage.setItem(KEY, JSON.stringify([]));\n        db=[]; resetForm(); rebuildAll(); toast(\"Base vac\u00eda\");\n      };\n\n      var cards=$(\"cards\"), count=$(\"count\"), stats=$(\"stats\"), q=$(\"q\"), fCat=$(\"fCat\"), fTipo=$(\"fTipo\");\n\n      function rebuildFilterOptions(){\n        var cats=uniqueSorted(db.map(function(x){return (x.categoria||\"\").trim();}).filter(Boolean));\n        var tipos=uniqueSorted(db.map(function(x){return (x.tipo||\"\").trim();}).filter(Boolean));\n        var keepCat=fCat.value, keepTipo=fTipo.value;\n        fCat.innerHTML='<option value=\"\">Todas<\/option>'+cats.map(function(c){return '<option>'+escapeHtml(c)+'<\/option>';}).join(\"\");\n        fTipo.innerHTML='<option value=\"\">Todos<\/option>'+tipos.map(function(t){return '<option>'+escapeHtml(t)+'<\/option>';}).join(\"\");\n        if(cats.indexOf(keepCat)!==-1) fCat.value=keepCat;\n        if(tipos.indexOf(keepTipo)!==-1) fTipo.value=keepTipo;\n      }\n\n      function matchItem(l){\n        var text=norm(q.value.trim());\n        var cat=(fCat.value||\"\").trim();\n        var tipo=(fTipo.value||\"\").trim();\n        if(cat && (l.categoria||\"\").trim()!==cat) return false;\n        if(tipo && (l.tipo||\"\").trim()!==tipo) return false;\n        if(!text) return true;\n        var hay=[l.nombre,l.categoria,l.tipo,l.localizacion,l.capacidad,(l.actividades||[]).join(\" \"),\n          (l.tours||[]).map(function(t){return [t.nombre,t.dias,t.noches,t.precio].join(\" \");}).join(\" \"),\n          l.dias].join(\" | \");\n        return norm(hay).indexOf(text)!==-1;\n      }\n\n      function getNumericCapacity(capStr){\n        var m=String(capStr||\"\").match(\/(\\d{1,6})\/);\n        return m ? Number(m[1]) : null;\n      }\n\n      function renderStats(filtered){\n        var total=db.length, shown=filtered.length;\n        var cats={}, tipos={}, nums=[];\n        for(var i=0;i<filtered.length;i++){\n          var c=(filtered[i].categoria||\"\").trim();\n          var t=(filtered[i].tipo||\"\").trim();\n          if(c) cats[c]=1; if(t) tipos[t]=1;\n          var n=getNumericCapacity(filtered[i].capacidad);\n          if(typeof n===\"number\" && !isNaN(n)) nums.push(n);\n        }\n        var sumCap=nums.reduce(function(a,b){return a+b;},0);\n        stats.innerHTML=\n          '<div class=\"pill\"><b>'+shown+'<\/b> mostrados \/ <b>'+total+'<\/b> total<\/div>'+\n          '<div class=\"pill\">Categor\u00edas: <b>'+Object.keys(cats).length+'<\/b><\/div>'+\n          '<div class=\"pill\">Tipos: <b>'+Object.keys(tipos).length+'<\/b><\/div>'+\n          '<div class=\"pill\">\u03a3 Capacidad (solo num\u00e9rica): <b>'+sumCap+'<\/b> <span style=\"opacity:.8\">('+nums.length+' items)<\/span><\/div>';\n      }\n\n      function renderCards(){\n        var filtered=db.filter(matchItem);\n        count.textContent=filtered.length+\" \/ \"+db.length;\n        renderStats(filtered);\n\n        cards.innerHTML=\"\";\n        if(!filtered.length){\n          cards.innerHTML='<div class=\"meta\" style=\"padding:10px;color:var(--muted)\">No hay resultados.<\/div>';\n          return;\n        }\n\n        filtered.forEach(function(l){\n          var d=document.createElement(\"div\");\n          d.className=\"card\";\n          var acts=l.actividades||[], tours=l.tours||[];\n\n          var actsHtml = acts.length ? '<ul class=\"acts\">'+acts.map(function(a){return '<li>'+escapeHtml(a)+'<\/li>';}).join(\"\")+'<\/ul>' : '<div class=\"meta\">Actividades: \u2014<\/div>';\n          var toursHtml = tours.length ? '<ul class=\"toursList\">'+tours.map(function(t){\n            var label=escapeHtml(t.nombre||\"Tour\")+\" \u00b7 \"+(t.dias||0)+\"D\/\"+(t.noches||0)+\"N\";\n            if(t.precio) label+=\" \u00b7 $\"+Math.round(t.precio);\n            return '<li>'+label+'<\/li>';\n          }).join(\"\")+'<\/ul>' : '<div class=\"meta\">Tours: \u2014<\/div>';\n\n          d.innerHTML=\n            '<h3>'+escapeHtml(l.nombre)+'<\/h3>'+\n            '<div class=\"meta\">'+\n              '<b>Categor\u00eda:<\/b> '+escapeHtml(l.categoria||\"\u2014\")+'<br>'+\n              '<b>Tipo:<\/b> '+escapeHtml(l.tipo||\"\u2014\")+'<br>'+\n              '<b>Localizaci\u00f3n:<\/b> '+escapeHtml(l.localizacion||\"\u2014\")+'<br>'+\n              '<b>Capacidad:<\/b> '+escapeHtml(l.capacidad||\"\u2014\")+'<br>'+\n              '<b>Salidas:<\/b> '+escapeHtml(l.dias||\"\u2014\")+\n            '<\/div>'+\n            '<div><div class=\"meta\"><b>Actividades:<\/b><\/div>'+actsHtml+'<\/div>'+\n            '<div><div class=\"meta\"><b>Tours:<\/b><\/div>'+toursHtml+'<\/div>'+\n            '<div class=\"actions\">'+\n              '<button class=\"warn btnEdit\" type=\"button\">Editar<\/button>'+\n              (l.link ? '<button class=\"ok btnOpenLodge\" type=\"button\">Abrir lodge<\/button>' : '')+\n              (l.foto ? '<button class=\"ghost btnOpenFoto\" type=\"button\">Abrir foto<\/button>' : '')+\n            '<\/div>';\n\n          d.querySelector(\".btnEdit\").onclick=function(){ loadToForm(l); };\n\n          var b1=d.querySelector(\".btnOpenLodge\");\n          if(b1) b1.onclick=function(){ openLink(l.link); };\n          var b2=d.querySelector(\".btnOpenFoto\");\n          if(b2) b2.onclick=function(){ openLink(l.foto); };\n\n          cards.appendChild(d);\n        });\n      }\n\n      function rebuildAll(){ rebuildFilterOptions(); renderCards(); }\n\n      q.addEventListener(\"input\", renderCards);\n      fCat.addEventListener(\"change\", renderCards);\n      fTipo.addEventListener(\"change\", renderCards);\n\n      resetForm(); rebuildAll(); toast(\"Base lista\");\n    }\n\n    if(document.readyState===\"loading\") document.addEventListener(\"DOMContentLoaded\", init);\n    else init();\n  })();\n  <\/script>\n\n  <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"_joinchat":[],"footnotes":""},"categories":[],"tags":[],"class_list":["post-38636","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>base-datos - Lodges Ecuador<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ecuadorlodges.info\/es\/base-datos\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"base-datos - Lodges Ecuador\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ecuadorlodges.info\/es\/base-datos\/\" \/>\n<meta property=\"og:site_name\" content=\"Lodges Ecuador\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/LodgesinEcuador\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-02T04:17:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ecuadorlodges.info\/wp-content\/uploads\/2022\/09\/CanoaTrip002.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1929\" \/>\n\t<meta property=\"og:image:height\" content=\"1286\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ecuadorlodges.info\\\/base-datos\\\/\",\"url\":\"https:\\\/\\\/ecuadorlodges.info\\\/base-datos\\\/\",\"name\":\"base-datos - Lodges Ecuador\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ecuadorlodges.info\\\/#website\"},\"datePublished\":\"2026-02-02T02:19:34+00:00\",\"dateModified\":\"2026-02-02T04:17:36+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/ecuadorlodges.info\\\/base-datos\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/ecuadorlodges.info\\\/base-datos\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/ecuadorlodges.info\\\/base-datos\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/ecuadorlodges.info\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"base-datos\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/ecuadorlodges.info\\\/#website\",\"url\":\"https:\\\/\\\/ecuadorlodges.info\\\/\",\"name\":\"Lodges Ecuador\",\"description\":\"The best places to relax around Ecuador\",\"publisher\":{\"@id\":\"https:\\\/\\\/ecuadorlodges.info\\\/#organization\"},\"alternateName\":\"Responsible Travel\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/ecuadorlodges.info\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/ecuadorlodges.info\\\/#organization\",\"name\":\"Lodges Ecuador\",\"url\":\"https:\\\/\\\/ecuadorlodges.info\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/ecuadorlodges.info\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/ecuadorlodges.info\\\/wp-content\\\/uploads\\\/2024\\\/10\\\/cropped-logo-lodges-ecuador.webp\",\"contentUrl\":\"https:\\\/\\\/ecuadorlodges.info\\\/wp-content\\\/uploads\\\/2024\\\/10\\\/cropped-logo-lodges-ecuador.webp\",\"width\":400,\"height\":105,\"caption\":\"Lodges Ecuador\"},\"image\":{\"@id\":\"https:\\\/\\\/ecuadorlodges.info\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/LodgesinEcuador\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"base-datos - Lodges Ecuador","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ecuadorlodges.info\/es\/base-datos\/","og_locale":"es_ES","og_type":"article","og_title":"base-datos - Lodges Ecuador","og_url":"https:\/\/ecuadorlodges.info\/es\/base-datos\/","og_site_name":"Lodges Ecuador","article_publisher":"https:\/\/www.facebook.com\/LodgesinEcuador","article_modified_time":"2026-02-02T04:17:36+00:00","og_image":[{"width":1929,"height":1286,"url":"https:\/\/ecuadorlodges.info\/wp-content\/uploads\/2022\/09\/CanoaTrip002.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/ecuadorlodges.info\/base-datos\/","url":"https:\/\/ecuadorlodges.info\/base-datos\/","name":"base-datos - Lodges Ecuador","isPartOf":{"@id":"https:\/\/ecuadorlodges.info\/#website"},"datePublished":"2026-02-02T02:19:34+00:00","dateModified":"2026-02-02T04:17:36+00:00","breadcrumb":{"@id":"https:\/\/ecuadorlodges.info\/base-datos\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ecuadorlodges.info\/base-datos\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/ecuadorlodges.info\/base-datos\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ecuadorlodges.info\/"},{"@type":"ListItem","position":2,"name":"base-datos"}]},{"@type":"WebSite","@id":"https:\/\/ecuadorlodges.info\/#website","url":"https:\/\/ecuadorlodges.info\/","name":"Lodges Ecuador","description":"The best places to relax around Ecuador","publisher":{"@id":"https:\/\/ecuadorlodges.info\/#organization"},"alternateName":"Responsible Travel","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ecuadorlodges.info\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/ecuadorlodges.info\/#organization","name":"Lodges Ecuador","url":"https:\/\/ecuadorlodges.info\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/ecuadorlodges.info\/#\/schema\/logo\/image\/","url":"https:\/\/ecuadorlodges.info\/wp-content\/uploads\/2024\/10\/cropped-logo-lodges-ecuador.webp","contentUrl":"https:\/\/ecuadorlodges.info\/wp-content\/uploads\/2024\/10\/cropped-logo-lodges-ecuador.webp","width":400,"height":105,"caption":"Lodges Ecuador"},"image":{"@id":"https:\/\/ecuadorlodges.info\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/LodgesinEcuador"]}]}},"_links":{"self":[{"href":"https:\/\/ecuadorlodges.info\/es\/wp-json\/wp\/v2\/pages\/38636","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ecuadorlodges.info\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ecuadorlodges.info\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ecuadorlodges.info\/es\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/ecuadorlodges.info\/es\/wp-json\/wp\/v2\/comments?post=38636"}],"version-history":[{"count":10,"href":"https:\/\/ecuadorlodges.info\/es\/wp-json\/wp\/v2\/pages\/38636\/revisions"}],"predecessor-version":[{"id":38648,"href":"https:\/\/ecuadorlodges.info\/es\/wp-json\/wp\/v2\/pages\/38636\/revisions\/38648"}],"wp:attachment":[{"href":"https:\/\/ecuadorlodges.info\/es\/wp-json\/wp\/v2\/media?parent=38636"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ecuadorlodges.info\/es\/wp-json\/wp\/v2\/categories?post=38636"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ecuadorlodges.info\/es\/wp-json\/wp\/v2\/tags?post=38636"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}