From 2f19a7c07761673102c98220175511f8b96a42bf Mon Sep 17 00:00:00 2001 From: FrankZamora Date: Thu, 27 Nov 2025 14:34:52 -0600 Subject: [PATCH] Fase 4.1: Bootstrap Icons subset (94% reduccion) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Optimizacion PageSpeed: - Original: 211 KB (2050 iconos) - Subset: 13 KB (104 iconos usados) - Ahorro: 198 KB (94% reduccion) Cambios: - Creado script create-icons-subset.py para generar subsets - Generado bootstrap-icons-subset.min.css (4.5 KB) - Generado bootstrap-icons-subset.woff2 (8.7 KB) - Agregado font-display:swap (elimina bloqueo de 420ms) - Actualizado enqueue-scripts.php para usar subset 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- Assets/Vendor/bootstrap-icons-subset.css | 127 ++++++++ Assets/Vendor/bootstrap-icons-subset.min.css | 1 + Assets/Vendor/create-icons-subset.py | 281 ++++++++++++++++++ .../Vendor/fonts/bootstrap-icons-subset.woff | Bin 0 -> 10520 bytes .../Vendor/fonts/bootstrap-icons-subset.woff2 | Bin 0 -> 8888 bytes Inc/enqueue-scripts.php | 7 +- 6 files changed, 413 insertions(+), 3 deletions(-) create mode 100644 Assets/Vendor/bootstrap-icons-subset.css create mode 100644 Assets/Vendor/bootstrap-icons-subset.min.css create mode 100644 Assets/Vendor/create-icons-subset.py create mode 100644 Assets/Vendor/fonts/bootstrap-icons-subset.woff create mode 100644 Assets/Vendor/fonts/bootstrap-icons-subset.woff2 diff --git a/Assets/Vendor/bootstrap-icons-subset.css b/Assets/Vendor/bootstrap-icons-subset.css new file mode 100644 index 00000000..20b2090d --- /dev/null +++ b/Assets/Vendor/bootstrap-icons-subset.css @@ -0,0 +1,127 @@ +/*! + * Bootstrap Icons Subset - ROI Theme + * 104 iconos de 2050 originales (5.1%) + * Generado automaticamente - NO EDITAR + */ +@font-face{ + font-display:swap; + font-family:bootstrap-icons; + src:url("fonts/bootstrap-icons-subset.woff2") format("woff2"), + url("fonts/bootstrap-icons-subset.woff") format("woff") +} +.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{ + display:inline-block; + font-family:bootstrap-icons!important; + font-style:normal; + font-weight:400!important; + font-variant:normal; + text-transform:none; + line-height:1; + vertical-align:-.125em; + -webkit-font-smoothing:antialiased; + -moz-osx-font-smoothing:grayscale +} +.bi-arrow-counterclockwise::before{content:"\f117"} +.bi-arrow-down-circle::before{content:"\f119"} +.bi-arrow-right::before{content:"\f138"} +.bi-arrow-up::before{content:"\f148"} +.bi-arrows-angle-expand::before{content:"\f14a"} +.bi-arrows-expand::before{content:"\f14c"} +.bi-arrows-fullscreen::before{content:"\f14d"} +.bi-arrows-move::before{content:"\f14e"} +.bi-arrows-vertical::before{content:"\f698"} +.bi-aspect-ratio::before{content:"\f150"} +.bi-badge-ad::before{content:"\f161"} +.bi-bar-chart::before{content:"\f17e"} +.bi-bootstrap::before{content:"\f1a8"} +.bi-bounding-box::before{content:"\f1b6"} +.bi-box-arrow-up-right::before{content:"\f1c5"} +.bi-c-circle::before{content:"\f7db"} +.bi-calendar-check::before{content:"\f1e2"} +.bi-calendar3::before{content:"\f214"} +.bi-card-image::before{content:"\f226"} +.bi-card-text::before{content:"\f228"} +.bi-chat-dots::before{content:"\f24a"} +.bi-chat-dots-fill::before{content:"\f249"} +.bi-chat-quote::before{content:"\f255"} +.bi-chat-text::before{content:"\f267"} +.bi-check-circle::before{content:"\f26b"} +.bi-chevron-down::before{content:"\f282"} +.bi-clock::before{content:"\f293"} +.bi-code::before{content:"\f2c8"} +.bi-code-slash::before{content:"\f2c6"} +.bi-cursor::before{content:"\f2e3"} +.bi-display::before{content:"\f302"} +.bi-envelope::before{content:"\f32f"} +.bi-envelope-fill::before{content:"\f32c"} +.bi-envelope-paper::before{content:"\f73d"} +.bi-exclamation-octagon::before{content:"\f337"} +.bi-exclamation-triangle::before{content:"\f33b"} +.bi-eye::before{content:"\f341"} +.bi-facebook::before{content:"\f344"} +.bi-file-earmark-text::before{content:"\f38b"} +.bi-file-text::before{content:"\f3b9"} +.bi-filetype-css::before{content:"\f742"} +.bi-filetype-js::before{content:"\f74c"} +.bi-folder-fill::before{content:"\f3d1"} +.bi-fonts::before{content:"\f3da"} +.bi-gear::before{content:"\f3e5"} +.bi-geo-alt-fill::before{content:"\f3e7"} +.bi-globe::before{content:"\f3ee"} +.bi-graph-up::before{content:"\f3f2"} +.bi-grid::before{content:"\f3fc"} +.bi-grid-3x3-gap::before{content:"\f3f9"} +.bi-hand-index::before{content:"\f403"} +.bi-hourglass::before{content:"\f421"} +.bi-hourglass-split::before{content:"\f41f"} +.bi-image::before{content:"\f42a"} +.bi-info-circle::before{content:"\f431"} +.bi-input-cursor::before{content:"\f436"} +.bi-input-cursor-text::before{content:"\f435"} +.bi-instagram::before{content:"\f437"} +.bi-key::before{content:"\f44f"} +.bi-layout-sidebar::before{content:"\f45f"} +.bi-layout-text-window-reverse::before{content:"\f463"} +.bi-lightning::before{content:"\f46f"} +.bi-lightning-charge-fill::before{content:"\f46c"} +.bi-link::before{content:"\f471"} +.bi-link-45deg::before{content:"\f470"} +.bi-linkedin::before{content:"\f472"} +.bi-list::before{content:"\f479"} +.bi-list-nested::before{content:"\f474"} +.bi-list-ol::before{content:"\f475"} +.bi-list-ul::before{content:"\f478"} +.bi-magic::before{content:"\f675"} +.bi-megaphone::before{content:"\f484"} +.bi-megaphone-fill::before{content:"\f483"} +.bi-menu-button-wide::before{content:"\f489"} +.bi-mouse::before{content:"\f499"} +.bi-palette::before{content:"\f4b1"} +.bi-person::before{content:"\f4e1"} +.bi-person-lines-fill::before{content:"\f4db"} +.bi-phone::before{content:"\f4e7"} +.bi-pin::before{content:"\f4ed"} +.bi-power::before{content:"\f4ff"} +.bi-send-fill::before{content:"\f6b9"} +.bi-share::before{content:"\f52e"} +.bi-shield-check::before{content:"\f52f"} +.bi-shield-lock::before{content:"\f538"} +.bi-shield-x::before{content:"\f53e"} +.bi-slash-circle::before{content:"\f567"} +.bi-sliders::before{content:"\f56b"} +.bi-square::before{content:"\f584"} +.bi-star::before{content:"\f588"} +.bi-star-fill::before{content:"\f586"} +.bi-stars::before{content:"\f589"} +.bi-tablet::before{content:"\f5ae"} +.bi-tag::before{content:"\f5b0"} +.bi-tags::before{content:"\f5b2"} +.bi-telephone-fill::before{content:"\f5b4"} +.bi-text-center::before{content:"\f5c4"} +.bi-text-paragraph::before{content:"\f5c8"} +.bi-three-dots::before{content:"\f5d4"} +.bi-toggle-on::before{content:"\f5d6"} +.bi-twitter-x::before{content:"\f8db"} +.bi-type::before{content:"\f5f7"} +.bi-whatsapp::before{content:"\f618"} +.bi-x-circle::before{content:"\f623"} \ No newline at end of file diff --git a/Assets/Vendor/bootstrap-icons-subset.min.css b/Assets/Vendor/bootstrap-icons-subset.min.css new file mode 100644 index 00000000..34e56388 --- /dev/null +++ b/Assets/Vendor/bootstrap-icons-subset.min.css @@ -0,0 +1 @@ +@font-face{font-display:swap;font-family:bootstrap-icons;src:url("fonts/bootstrap-icons-subset.woff2") format("woff2"),url("fonts/bootstrap-icons-subset.woff") format("woff")}.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{display:inline-block;font-family:bootstrap-icons!important;font-style:normal;font-weight:400!important;font-variant:normal;text-transform:none;line-height:1;vertical-align:-.125em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.bi-arrow-counterclockwise::before{content:"\f117"}.bi-arrow-down-circle::before{content:"\f119"}.bi-arrow-right::before{content:"\f138"}.bi-arrow-up::before{content:"\f148"}.bi-arrows-angle-expand::before{content:"\f14a"}.bi-arrows-expand::before{content:"\f14c"}.bi-arrows-fullscreen::before{content:"\f14d"}.bi-arrows-move::before{content:"\f14e"}.bi-arrows-vertical::before{content:"\f698"}.bi-aspect-ratio::before{content:"\f150"}.bi-badge-ad::before{content:"\f161"}.bi-bar-chart::before{content:"\f17e"}.bi-bootstrap::before{content:"\f1a8"}.bi-bounding-box::before{content:"\f1b6"}.bi-box-arrow-up-right::before{content:"\f1c5"}.bi-c-circle::before{content:"\f7db"}.bi-calendar-check::before{content:"\f1e2"}.bi-calendar3::before{content:"\f214"}.bi-card-image::before{content:"\f226"}.bi-card-text::before{content:"\f228"}.bi-chat-dots::before{content:"\f24a"}.bi-chat-dots-fill::before{content:"\f249"}.bi-chat-quote::before{content:"\f255"}.bi-chat-text::before{content:"\f267"}.bi-check-circle::before{content:"\f26b"}.bi-chevron-down::before{content:"\f282"}.bi-clock::before{content:"\f293"}.bi-code::before{content:"\f2c8"}.bi-code-slash::before{content:"\f2c6"}.bi-cursor::before{content:"\f2e3"}.bi-display::before{content:"\f302"}.bi-envelope::before{content:"\f32f"}.bi-envelope-fill::before{content:"\f32c"}.bi-envelope-paper::before{content:"\f73d"}.bi-exclamation-octagon::before{content:"\f337"}.bi-exclamation-triangle::before{content:"\f33b"}.bi-eye::before{content:"\f341"}.bi-facebook::before{content:"\f344"}.bi-file-earmark-text::before{content:"\f38b"}.bi-file-text::before{content:"\f3b9"}.bi-filetype-css::before{content:"\f742"}.bi-filetype-js::before{content:"\f74c"}.bi-folder-fill::before{content:"\f3d1"}.bi-fonts::before{content:"\f3da"}.bi-gear::before{content:"\f3e5"}.bi-geo-alt-fill::before{content:"\f3e7"}.bi-globe::before{content:"\f3ee"}.bi-graph-up::before{content:"\f3f2"}.bi-grid::before{content:"\f3fc"}.bi-grid-3x3-gap::before{content:"\f3f9"}.bi-hand-index::before{content:"\f403"}.bi-hourglass::before{content:"\f421"}.bi-hourglass-split::before{content:"\f41f"}.bi-image::before{content:"\f42a"}.bi-info-circle::before{content:"\f431"}.bi-input-cursor::before{content:"\f436"}.bi-input-cursor-text::before{content:"\f435"}.bi-instagram::before{content:"\f437"}.bi-key::before{content:"\f44f"}.bi-layout-sidebar::before{content:"\f45f"}.bi-layout-text-window-reverse::before{content:"\f463"}.bi-lightning::before{content:"\f46f"}.bi-lightning-charge-fill::before{content:"\f46c"}.bi-link::before{content:"\f471"}.bi-link-45deg::before{content:"\f470"}.bi-linkedin::before{content:"\f472"}.bi-list::before{content:"\f479"}.bi-list-nested::before{content:"\f474"}.bi-list-ol::before{content:"\f475"}.bi-list-ul::before{content:"\f478"}.bi-magic::before{content:"\f675"}.bi-megaphone::before{content:"\f484"}.bi-megaphone-fill::before{content:"\f483"}.bi-menu-button-wide::before{content:"\f489"}.bi-mouse::before{content:"\f499"}.bi-palette::before{content:"\f4b1"}.bi-person::before{content:"\f4e1"}.bi-person-lines-fill::before{content:"\f4db"}.bi-phone::before{content:"\f4e7"}.bi-pin::before{content:"\f4ed"}.bi-power::before{content:"\f4ff"}.bi-send-fill::before{content:"\f6b9"}.bi-share::before{content:"\f52e"}.bi-shield-check::before{content:"\f52f"}.bi-shield-lock::before{content:"\f538"}.bi-shield-x::before{content:"\f53e"}.bi-slash-circle::before{content:"\f567"}.bi-sliders::before{content:"\f56b"}.bi-square::before{content:"\f584"}.bi-star::before{content:"\f588"}.bi-star-fill::before{content:"\f586"}.bi-stars::before{content:"\f589"}.bi-tablet::before{content:"\f5ae"}.bi-tag::before{content:"\f5b0"}.bi-tags::before{content:"\f5b2"}.bi-telephone-fill::before{content:"\f5b4"}.bi-text-center::before{content:"\f5c4"}.bi-text-paragraph::before{content:"\f5c8"}.bi-three-dots::before{content:"\f5d4"}.bi-toggle-on::before{content:"\f5d6"}.bi-twitter-x::before{content:"\f8db"}.bi-type::before{content:"\f5f7"}.bi-whatsapp::before{content:"\f618"}.bi-x-circle::before{content:"\f623"} \ No newline at end of file diff --git a/Assets/Vendor/create-icons-subset.py b/Assets/Vendor/create-icons-subset.py new file mode 100644 index 00000000..c41f2328 --- /dev/null +++ b/Assets/Vendor/create-icons-subset.py @@ -0,0 +1,281 @@ +#!/usr/bin/env python3 +""" +Bootstrap Icons Subset Generator +Genera CSS y fuente optimizados solo con los iconos usados en roi-theme +""" + +import re +import subprocess +import os + +# Directorio base +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + +# Iconos usados en roi-theme (extraidos con grep) +USED_ICONS = [ + "bi-arrow-counterclockwise", + "bi-arrow-down-circle", + "bi-arrow-right", + "bi-arrows-angle-expand", + "bi-arrows-expand", + "bi-arrows-fullscreen", + "bi-arrows-move", + "bi-arrows-vertical", + "bi-arrow-up", + "bi-aspect-ratio", + "bi-badge-ad", + "bi-bar-chart", + "bi-bootstrap", + "bi-bounding-box", + "bi-box-arrow-up-right", + "bi-calendar3", + "bi-calendar-check", + "bi-card-image", + "bi-card-text", + "bi-c-circle", + "bi-chat-dots", + "bi-chat-dots-fill", + "bi-chat-quote", + "bi-chat-text", + "bi-check-circle", + "bi-chevron-down", + "bi-clock", + "bi-code", + "bi-code-slash", + "bi-cursor", + "bi-display", + "bi-envelope", + "bi-envelope-fill", + "bi-envelope-paper", + "bi-exclamation-octagon", + "bi-exclamation-triangle", + "bi-eye", + "bi-facebook", + "bi-file-earmark-text", + "bi-file-text", + "bi-filetype-css", + "bi-filetype-js", + "bi-folder-fill", + "bi-fonts", + "bi-gear", + "bi-geo-alt-fill", + "bi-globe", + "bi-graph-up", + "bi-grid", + "bi-grid-3x3-gap", + "bi-hand-index", + "bi-hourglass", + "bi-hourglass-split", + "bi-image", + "bi-info-circle", + "bi-input-cursor", + "bi-input-cursor-text", + "bi-instagram", + "bi-key", + "bi-layout-sidebar", + "bi-layout-text-window-reverse", + "bi-lightning", + "bi-lightning-charge-fill", + "bi-link", + "bi-link-45deg", + "bi-linkedin", + "bi-list", + "bi-list-nested", + "bi-list-ol", + "bi-list-ul", + "bi-magic", + "bi-megaphone", + "bi-megaphone-fill", + "bi-menu-button-wide", + "bi-mouse", + "bi-palette", + "bi-person", + "bi-person-lines-fill", + "bi-phone", + "bi-pin", + "bi-power", + "bi-send-fill", + "bi-share", + "bi-shield-check", + "bi-shield-lock", + "bi-shield-x", + "bi-slash-circle", + "bi-sliders", + "bi-square", + "bi-star", + "bi-star-fill", + "bi-stars", + "bi-tablet", + "bi-tag", + "bi-tags", + "bi-telephone-fill", + "bi-text-center", + "bi-text-paragraph", + "bi-three-dots", + "bi-toggle-on", + "bi-twitter-x", + "bi-type", + "bi-whatsapp", + "bi-x-circle", +] + +def read_original_css(): + """Lee el CSS original de Bootstrap Icons""" + css_path = os.path.join(BASE_DIR, "bootstrap-icons.min.css") + with open(css_path, "r", encoding="utf-8") as f: + return f.read() + +def extract_unicode_codes(css_content, icons): + """Extrae los codigos unicode de los iconos usados""" + codes = {} + for icon in icons: + # Buscar .bi-nombre::before{content:"\XXXX"} + pattern = rf'\.{re.escape(icon)}::before\{{content:"\\([a-f0-9]+)"\}}' + match = re.search(pattern, css_content, re.IGNORECASE) + if match: + codes[icon] = match.group(1) + else: + print(f"WARNING: No se encontro codigo para {icon}") + return codes + +def generate_subset_css(codes): + """Genera el CSS subset con solo los iconos usados""" + css_lines = [] + + # Header + css_lines.append("/*!") + css_lines.append(" * Bootstrap Icons Subset - ROI Theme") + css_lines.append(f" * {len(codes)} iconos de 2050 originales ({len(codes)/2050*100:.1f}%)") + css_lines.append(" * Generado automaticamente - NO EDITAR") + css_lines.append(" */") + + # @font-face con font-display: swap + css_lines.append('@font-face{') + css_lines.append(' font-display:swap;') + css_lines.append(' font-family:bootstrap-icons;') + css_lines.append(' src:url("fonts/bootstrap-icons-subset.woff2") format("woff2"),') + css_lines.append(' url("fonts/bootstrap-icons-subset.woff") format("woff")') + css_lines.append('}') + + # Estilos base para .bi + css_lines.append('.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{') + css_lines.append(' display:inline-block;') + css_lines.append(' font-family:bootstrap-icons!important;') + css_lines.append(' font-style:normal;') + css_lines.append(' font-weight:400!important;') + css_lines.append(' font-variant:normal;') + css_lines.append(' text-transform:none;') + css_lines.append(' line-height:1;') + css_lines.append(' vertical-align:-.125em;') + css_lines.append(' -webkit-font-smoothing:antialiased;') + css_lines.append(' -moz-osx-font-smoothing:grayscale') + css_lines.append('}') + + # Reglas para cada icono + for icon, code in sorted(codes.items()): + css_lines.append(f'.{icon}::before{{content:"\\{code}"}}') + + return '\n'.join(css_lines) + +def generate_minified_css(codes): + """Genera CSS minificado""" + parts = [] + + # @font-face + parts.append('@font-face{font-display:swap;font-family:bootstrap-icons;src:url("fonts/bootstrap-icons-subset.woff2") format("woff2"),url("fonts/bootstrap-icons-subset.woff") format("woff")}') + + # Estilos base + parts.append('.bi::before,[class*=" bi-"]::before,[class^=bi-]::before{display:inline-block;font-family:bootstrap-icons!important;font-style:normal;font-weight:400!important;font-variant:normal;text-transform:none;line-height:1;vertical-align:-.125em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}') + + # Iconos + icon_rules = [f'.{icon}::before{{content:"\\{code}"}}' for icon, code in sorted(codes.items())] + parts.append(''.join(icon_rules)) + + return ''.join(parts) + +def create_font_subset(codes): + """Crea subset de la fuente usando pyftsubset""" + # Crear archivo con unicodes + unicodes = ','.join([f'U+{code}' for code in codes.values()]) + + # Paths + woff2_src = os.path.join(BASE_DIR, "fonts", "bootstrap-icons.woff2") + woff2_dst = os.path.join(BASE_DIR, "fonts", "bootstrap-icons-subset.woff2") + woff_src = os.path.join(BASE_DIR, "fonts", "bootstrap-icons.woff") + woff_dst = os.path.join(BASE_DIR, "fonts", "bootstrap-icons-subset.woff") + + # Crear subset woff2 + print(f"Creando subset woff2 con {len(codes)} glyphs...") + cmd_woff2 = [ + "pyftsubset", + woff2_src, + f"--unicodes={unicodes}", + f"--output-file={woff2_dst}", + "--flavor=woff2" + ] + subprocess.run(cmd_woff2, check=True) + + # Crear subset woff + print(f"Creando subset woff con {len(codes)} glyphs...") + cmd_woff = [ + "pyftsubset", + woff_src, + f"--unicodes={unicodes}", + f"--output-file={woff_dst}", + "--flavor=woff" + ] + subprocess.run(cmd_woff, check=True) + + # Mostrar tamanos + orig_size = os.path.getsize(woff2_src) / 1024 + new_size = os.path.getsize(woff2_dst) / 1024 + print(f"woff2: {orig_size:.1f} KB -> {new_size:.1f} KB ({(1-new_size/orig_size)*100:.1f}% reduccion)") + +def main(): + print("=== Bootstrap Icons Subset Generator ===\n") + + # 1. Leer CSS original + print("1. Leyendo CSS original...") + css_content = read_original_css() + + # 2. Extraer codigos unicode + print(f"2. Extrayendo codigos de {len(USED_ICONS)} iconos...") + codes = extract_unicode_codes(css_content, USED_ICONS) + print(f" Encontrados: {len(codes)} iconos") + + # 3. Generar CSS subset + print("3. Generando CSS subset...") + subset_css = generate_subset_css(codes) + css_path = os.path.join(BASE_DIR, "bootstrap-icons-subset.css") + with open(css_path, "w", encoding="utf-8") as f: + f.write(subset_css) + print(f" Guardado: bootstrap-icons-subset.css") + + # 4. Generar CSS minificado + print("4. Generando CSS minificado...") + min_css = generate_minified_css(codes) + min_path = os.path.join(BASE_DIR, "bootstrap-icons-subset.min.css") + with open(min_path, "w", encoding="utf-8") as f: + f.write(min_css) + orig_css_size = os.path.getsize(os.path.join(BASE_DIR, "bootstrap-icons.min.css")) / 1024 + new_css_size = os.path.getsize(min_path) / 1024 + print(f" CSS: {orig_css_size:.1f} KB -> {new_css_size:.1f} KB ({(1-new_css_size/orig_css_size)*100:.1f}% reduccion)") + + # 5. Crear font subset + print("5. Creando font subset...") + try: + create_font_subset(codes) + except Exception as e: + print(f" ERROR: {e}") + print(" Intenta ejecutar: pip install fonttools brotli") + return + + print("\n=== COMPLETADO ===") + print("Archivos generados:") + print(" - bootstrap-icons-subset.css (legible)") + print(" - bootstrap-icons-subset.min.css (minificado)") + print(" - fonts/bootstrap-icons-subset.woff2") + print(" - fonts/bootstrap-icons-subset.woff") + +if __name__ == "__main__": + main() diff --git a/Assets/Vendor/fonts/bootstrap-icons-subset.woff b/Assets/Vendor/fonts/bootstrap-icons-subset.woff new file mode 100644 index 0000000000000000000000000000000000000000..19dd685fde5c5d80167ca5ab878a345e31daf223 GIT binary patch literal 10520 zcmY*+u;o{_Z5v&-ZL7<+ZQC}xY@^HQvTfV8rv5u~A12n?nP=}687DJWoTszh zAfUG&XWVAi9;QDW5&$5%0RSYI>{}|y%}or90RXc9>aqO? zjjDWp^B?hNt;P?>`vEDiJrJ_Fjq^`^a?&5p{DUPR^6y7$JENaGGRz;o@E^wRHcD*_ z+<)Fn`trjGen1G64`gL)U}N&LXYU`b_k(!w6oOQHJ16HKZR3X{{Fes+2LRl&i@mMl zafdxtoS&VaJI&n8%#K{IZLeLAZJ%{l$ZYN05Nf$`We^Ed38@nE1(ZRP(ve9slYv%C zj1>_oV_WVJ_mhovj7wEo5+kMTwN1h*R1%TDMof;xslmt&+oU4)r~~*9f~8Vu*v9y^ zk<+iwGkiAjC?$9{9%cATO5e|~KYc)AEN_Ih8;S-s|5$WALf=XxJ+;dc7nRM>&5_2` zH7Y(wP);S3b+EVUhI47rEtAP$lBTU+*rg35MP*kjwhz7Jyp8U&c6(cjrA61T4Tulk z2_G*@oC6mcC!F0t)Eb{vTOEWSnUh^ocD8B|oog8vN?PLYipDKu8XHCRT4LioW~P(D zQQm%@uNT44@j)df9m|tf5Ed6V%4h2+4W4i8j4vQsCt=-Cz_xd`#>Ys@(bJj@q)w$e zPd%okVGbK`WHyq;l)0od6Id$OmBd^@xnGO9;caOJe=eWltdo{6g4BEuLZxRuQe85; zFGuvuyyi~H_mZvvE*Z|DYKreI_=B+=x*xBokj2k8W6=BX!ilfQX~n{LJWps?VodF| zf?g3VIb1=)37?) z3e4cZdq$#5;hT1#y6@qsDp9m&8y2P|BrF#V5CNJ7`r z1093)wz7Htn_!n1TX4Rs4ND{^3fyD%ySe@;tGZS$CzwLSu~#sA7iL^&o&?9v_R%Fh zAp8fA+1gdS`8ms90VQDkmkzA)$a7Cmo(D+H%8FJSNyc0~F8rl$T48v{b_A}O#;;%U z-H!aVOU#-+DCTIdJ1edx?NN-FRPiIV@OfM885N<)O9|z{-&7*_%6V0$EAGJ(lgmdt zxUMX4JJ_uq!qMjsV&)MesUxVhh-=WZTn=3JQP~m>tP`AW+1b>lOon@J>)P8YgqD3* zc2SC=otFntqukrQ;#-Js?1-}Yz2b1Q{builTCykuXws9RthE*t&EhOJSxx({Bne#{ zr-P@F>*t%g+}3W13>L^4a|%)zT}Xlk&Ac0X=!#lAR!fua_1bnF%v;m%A%S+D$s$Mw z^sLr2cE2%-ZN}HZQAsgGzqEW&4{Ii-bUU7`8%HC-S`}D|p2sqiJ%*iWhwEk6Jto+m zcA#hjDO=N`B*G8%#Z5RIN}gD%t1T&ZE|Ti1zxoeQSN*_UT)+pIEq5{qQ;Z+K_V!Xd zKc(=t)rXs}klGYk2igs#T{_HH)Y;tJ?6$jgB-o8MQlD5muMF!gR{r(Rv9ZJ;{7pr8 z;3{oy&I>{V4i2zk<R~ zRa(5SY-}dY`^Fe7YJ>1wEhbQ}yv0ZVET4ghE)gw7U~nhVE%?s8@j1 zk2;6fUyN7+thD&g1C*MCU(P8(PkXm%2SY_v0XB)4S7a*K3L66;TbEYZH7lAK$ zsl%CPSMVH^M7k~&VxFGkd(NcY3C6p@7)MSFr@Wq7^B}Z_45$+MQN#a9yq+=iFzDv! zVZc*bo>p@Qm1BUoLq0X61aBF^jSK-t7UD)px|Ez#qm>K=@&CqU!|1d3 zHe|Ea(pjC?O+hqAturpyd!P>nwaCZOciZ^MR*av%Uy)d09oW9ldKmoPTc2Y&wALOx`^VBp=JSk}HxNEp!6eUwRVY;bW*4yAM@e*)ZjM1}&M1~k&qu6THH8lGto zhScFI=!}^;iJz(X#E0mTac+Dk9>Si^Dl~O@jPN)84rgHlNEj}HUFbjirge}F{5nd) zOH4T}k;^SHqqY!dBNr;;=P`rI_x)leR5%WKg?w-dt}GUWS45wf^83>%q2GN8TA>(%322HT&WBctF zZ!eL*-_k0@4t= z(cO|=T(6Oa9oqwS4sC%ipN9DvJYl_MJdHw&xX}%LQpXU30Maxo?}X;%zm5&1>m*X%)eTj{Gwn zasfxJ`G5rx(JvKye;Jr<-xhP%JG4$vqO!P)6I;gw5o`$rWf)m9P5BD-C0Y>xV<-;L zicn6XWQ{j;o;4m*K0AC-u8@{|tEggd1@^&yfHg8JyR}ME-8)M>yNIRU2G!XGeG^%M z_cs;C8rgpg2u+*c0v^>9J+UpKN8^$5cCqV0dQ()H(=Wk0lzpW@Y5r!*%#iPftX%6A zH#Mg>Z^VvRfKqBU!xFcz0>yVv;B2~$M)Vu}9vC@*}_;+Hf^`PYb{y;V(qruFtz5`>M9WfCD-0rhMil|D<$tS-EsHD z!zU4zBo{PX=~b2jxS5!X)LRF4X;g#&8TvD>5LKOYAEK|OJ?qkURzNIispa=z|LXbh z+wk7el(1doc|TDzd4`us+uRQK+u|q;0y!|IMY!=9Ah%@x zqlnQyGy5HBj2;sWbl5LYcAzP52u0+>dmRk}l$S_;?Om~rT;VyX3jd3B)D_J!^EK7p zM|4i_06p?xZ}_i~%?=IU8VS1LKY8;RHi(w~aJP>jG-wQ0UctyOpSgp($6ibj(#Z}L zRv($MFpJY=A*S&QSC*_Z+|%Z90at2v#^06#RW}G8`ftA$k=naNU4E;_oTg*PUKexW znNJ8?fPQ3FF>(m~(t{nxIjl>+w-J^acyjtJyww=f@jX2rrs&a#8{#4F_R;q_9GH>u zHZf5wWKy7{Fo=&)qipX~Vw1($y3^LuRf~TlyncVv5990lPB^8MXMxu68yYPJwksIw z!XuwtMWX7$nT7vYqD-c;MW&xF5}Fz^?(8;1tWc>%o7+AIErS-f*4N|pg6V@kR~L!k zcjeRsQv1movlRgnO)0Zy0>D5kYYtryf;Z|;6E?dZ#0U;Gid2~+l-~65F4x7B3YRbAL}r%*B@jeNL2^YNu3{jtcgWuRMxy|gqa669S&0~TGhNT zM)x0V_vaUfx1J&ZcmoK)iQAXpRuqO49|-cV%~^IJk)m8YW721OH1x~xI&)y}pQD_TJqg_=E`lCdii4 z7T@rHL&QU4dlC@Uq*@>zfR~`GB~)+9!V|;uT`QnZxK1LX6nK_Y!QwDGvN#Z_wa%!Z zeRRB+NT^u%yiq-g<&mmN+fhC9M+UJNE~0ceXsXTVd!SjKpYG;gKb+yBP>MC7dCkcQMQ5EI9&Cq8-u& zj=UKV{37f9Qt2=vl|8iWPxHQH&bc{4JCB?3_}B)Vi*6Mv%{93fY1(rFaMdbAf4R({ z4(3{fz9y=tTiG=qL+erzpzm2W|E|t7MO8OLH>JiwdkM+1#MP;7sko^ukmYJhg2{KA z4uI7HuPlPgoU+(?$7rT#HfuU=MzHu*0MA|0kpC>)f}))m@6ehCxr$OQ?N>EZ9RK$ z*jPu!N45lWzPHacjg|(+{y+*mH2Y^MCWJCzmd@K2TC8;hWI^+YG?ga;9dr=lNeuk9 z2dOdj(5qy3GLK4Bu^dglSyTCTN@c@Rw3xYtlg3ka;Nj!dl}9zwwbKJr`#R$HJp7-z z1!%te&aABG=ysF7m0L(&h%BA)*89b}_A*EeXWRJqNWNLLI#FPy_V;Z`(Bp4Z%q(#N z(5UDcKGxM)@c`xO&Cl_j+JaANBLr;&kudHYJfB=7j%vjXYJglgV*y38-b{^UPuXYU z)A-tOvwHKiWye}tlV7n93d=de>A##HqIgB#HFdpf_@Uw5gBK1|#adoI-Lfz6&cc|0 ztcx|d{->L-I*zrrIg+y+cRfEp2j#)htKZs+2CRl~fmSEe_~2`E>-k@rK6VZmV{fu9 zSm1}TChE8>)}#%(J-pt-5aLcg<_t?;M*+6pmt{S_YmIIY{MaxSr>kiX)Te>HPxsKp z-)DML@w3U-gy?K=s-ll~arwC?%2x=GV%LASvGA?@5>|<5`~oS6br8lz^#_?Y`W7e- zJr2rljG(`rq|NV)Xg|t`5EE)RYDI_*sfp+_WOy3>tvtn9=)7!=Y}LSt^Yvb+w%Gd| zhiA3e(3z~7--CBalHXw&u$DJx>3QCpFhuPXBm-Y85nf;rJ#<7lE<7uA6q+tw%m8eT zV`7964nX~#!BQU0A9aRU+R}%mO9v%Y*w>dzl6}LppSNS3iBx_LR3}rOjP8f5~Aj`)}L5v0)HrFy$UQP?=JdMh@V^9~ zo)7VK!Zf+b$z>DfD+!UMvpf4y8jP=%xMFo7T(=JgkX#X3#|sWw0Q-AZY>vJ)Bs>bU zds^{xWVVTJyjlg}pk;DdyM^@zKv*i5q+PWsq?dsgy6gTPyw7|NKQ>Y6`IXC#G<9x< zG(3{_M44@dQ)s{SI?@yIseo#|pH!&71*h-&mOiC8rzYUo)#1jc7T6fGKyJBijF`l= zA?@cK0=$Y8hY^!4*CroTetm3j_etO+2{rE~mCt8?zC15+4ynX>8U56>M^Ii{xGbB1 zm&0ceiW0v2n{-Get~XQO@j{k?EQzy`CK z2bfL&EWr!C>tC*J)ycWmo0xLi(J*n3P?T5S#JVFf3}y&&vK zfFlKlGG4`J_9PhEIz+#s6_wV}wYQCgqHRa1C6eOSKA!za;B6Iz`n~-s??f;{k?(e@ zlvp1YKEpV@L@=5>YO`X!C)MN)#Vk|G`D%glAV!Z7ikGsjvB0xJ~D0{!nCsq}0Pk>_Xb zV<&0jV173q6R(?DWZ8Kbt`rS@tt)l^o?NWDb0)RU3AiFf;m&OIDK#<78tya%$O|ML zx0&E(pCXuCPFfdBhB9b1)k7zzdloZrEP?G6>Ti@#c|iO1x~t`G$JH9NZ`X-3R5@{YXclSy$H2XE@S_+y>(~b z4)M~+Lw#yV&?wNFzPc$ah*!%O|GQiHXOg@v+3?H@>$MAsxwHcSe98$^NYCU=>Uo zhW4p)?QXsI$D$-q3D24|+CjaUB;V{q+cYU?3m5KAe1Kz|6Clef=~H)xlJY9_Z( zpTfG=cMjfu)@zB!jf>U+x4sV(;(~9(-az*BCe~6RGHfC@D4wcT0n+H~YvHi!`EdYO z9E@r_$RsAcd~AY);U!j`jcB1YmhwLUSdprc#%}?Xg9NGRXS~fDS~KElNxn( zwGmLo=ASj1WG{nijjE94x$%@a%U4a0=474FZ8_XgM>-7u!p{6|$n{}KoPCQl*$iEK2m&~Z2+s@r=ICr^1taJrgPklglwFo*Vu*zOSdq1VZ1IRo7?KWc(w$R^#4 z7CI@=a1w)~i8}L_FT&SoWcZ;r&YZ@XG_b&^lQ|rXyTV`Kr23wsT8o~M=hT?R{_)MA zyyycP(9R2_D6oFS|8l7>wT$ian)TusKNMr~j8rf~Q6{xBBX9>0wTlTVL_}!DMRAF? z-RsqDCQ;J&uvuZ3e{pqRqxvi}oaB{YwkN)s#};hG2JB3#xDa@56!il&v5R>rTeOy$ z{HrTf<*Jwcn^2M!&XPj9A#KE6`p07i?YOXe^i|fqz(AZ?ep;jji@|o~?}>Y|u>663 zbCv+Llj4Jm#__-QkR};vY>|pe%(-#R)QqH8d4$oXDGnH%{42U5{=);Yxz12g(}{#R z$__$Ilj`kHZfUZTxY?72mcZ3b!OUsZ@q}PIrhYosca7(T;Ry0FVW3J@}0`TQ)yI`426Be3(0;D zL?CugDUpOWkzjnVKz=A!OZbCYcR2=nnHL~wacw01hq~S8jGD*^8KZ;ZO(5`fEB|_- zR)Mn-Xo*pBpDz1mT&+c^-35};eyK&+5)oTp6Pp4Fsg4dk+Umc5`~Skw&2`$-kE}*n z(Ky9s+xA{i-))o1?wE+W%eT`16+bcub(CfkNVP#}7?W{${>6Dnz%_~cc5=>j5>hK} zESG+P?Xq%;Ah^8UO%FAz$F7?Dz|9ZbTm;7Px58$}ExXS>71DI5}Ik4`CNLNDh)+o!!F=qL zny@&@)PfyZ)N3D&%IINkQRb%)(pTqxCoE3bi%~M3EwN0GCPjW^l3{Puk$96a*FWKC z)Xk_0)S>e>jq*U(bUF6U)IlW9dGmE1UYW(@NNZu=>|`K zr3CpmtiFz^S#^qDPlX286sFmBH(86Vo>SP>$PAW!{)k{}3_(9gQkbChLLL_2jW|EK zcrPnzif-99I5t-;pL1!i5b%VY!93u~SNg@f`m(Ev#>&EyF{!Fc06Ce0B=ZUq;D;ty zh_XI2n~)QPz6Mec5x-JGu{zeut21*#B0ubumOsaPV~^hHp*(&AhjS6@xMcwg&7tCn zM)6R}?B&g7c)MnBTEBt>o|<_ZMpDosnx(b=72bG;y5&pb@P2Pdc1AlGFkfQLW?u^} z7vQ{bIj4gzl~>dp$+hgGms!diP~UHoH@-$8P`LI|>wl-ub&1&W3Z5q|_(;f=+i3I* zzSiVz3mrTNoMET!C-9C(u@c6>Ku#SrO5tNHwW*{eQNk-BBC36C=!BGE6KchuG1=dI zZygBtWfI}<)Nxx z<3nM(omb+L1stnNvBu9YQmrHi9d!_0r8_PXlsbw;23#+Pb?v;+JWw+R8dY08ICr{Xid}9bH=dxx1X}D?8pTsTquRvifY#yO3m< z?ib(9?(RS$Z4b=G_OYVmqsOG7>UG~N-9gY2T?+SwT_y5ThwMoHPA?&^8g>5xqwgxv z1IKkWUk7RtM`y(rRhsB*RS-~Uz#wBWz_k5(%gwK*wvKyN6a>nnu}27kz}OU!k+i96 zIGxElRVM0@G;VSlr5d&tzWCILzSFzwdU7pjK0)}~ z{C$(B==th2uDeom0vEb<;gYDDs_EZopXhIf)x%y-wyX8~rOLSHg}>cV*Xwv(9JVpr zj}e#;QEpn(Hd|OQD?hKR*_;q{I$#C2n^jRM@o361*62x_y|={hiLOmf&vr>tvEMVk^|cK0Fb zx!m8z_ZYSOJx&cDwWX4WX+3Wr_qD#SpL(BpAl_x>{0iUPf`MC65#KgI`~~9e@t1UD zIf)PF`(oJM;9eHRb;{wbd(|+9a<2%I9GkSW@h>L)5z@u_Tun|jS}>kCIDQY}J)b9q z9k0ic$_{;wJj*Z`e*!^1rxcDg!Cv$qo{tR>ERI|mQ@hH1oOM14K#`kEbwLVoFCU>( z08|QOix|iwU5f4H-dI%txsk#bATmlbYDrL)q(?eUyH1oR)3hmiw1MFYm$sq2^2xiB zfxtD>YG+a?iAN1&?C3M_eHM(YWdFaR+YT$JL2F!Q+GiV010&HogbqS3e?o5Og5oGJ z2KwiMq*J#1CYf7DY0TnOgAOFhJ*(b;vXmHNC=&{%F~MkJ8GOV_we3lsiU@1)GTMt; zj2PSX*3Y`LS{5X33HcVU0CoCnb2y7Z`OYB7)dz?mGQQT%cNIW6DQoJR+Z+w0HbpmyQ9YTD< z7{U(1BO(T(PNHXG4&qqiArg2Jb&^1mI+7_;B+@j}^Z)U60RaHgy#cj)2t1Df7$DmJ zj_FNS=l{R+_v`mQkR;H5J}XE7@PF!m-Y6sepI9&u0Q&xB-uW4f#)L(_zJ*UhB0u`f z;Q6#5SKqz~M%cjfQ2NI zm>eJ&0bTz;H5TXOB^DGBA#Rp!SFW-=uA36@NQooE&Cm7eB?1+Vql_WNoFn2HW;7Cm zJ0+5X(N_who{sSqwWLJU(ujr2$|ktlFpY-{FG8;;C$7~IZKA>`&k)@$LtlMs^9Cr3 ziKWWTUy%>B8)l?Q?hm^w>cK zwy)%0VZI^=o(U+0aHu3%Riq!Af~ICEyZ%tUNqD@;PXzVI{2JX$+YtZAoFOfLjID=rdr# zwT7$@3^6>DsZ&!uMs?oS-fc!Ds(&Y&y>R61%=?Y7f0AFntN;BpKE6Ws$X@t<7r@2JB+X9&@9 zV5T1iC05f%g=T*S4< z5BfReu}V5L%m}-SD2lVS-7dCe3FkpxaWj^O{LWCkqEEz>faW}?5t7Ufk#7A@lF9BQ zS+bkmG^%7%C@qoz!J0r;VnBtE1shmshldh5u(am`Y-jywuwC;iiM4>GzM^9JTxDy`511p3@}BcC)U;A7wKVo5Y@AsL0ZiT+4{V-h9D0JC zf0*rgp8r!-*E;%%!!luh}vTLxy?FJm+Pu4roGUEkjeY*!f%h7}G3}@!y?V-wcTo zRJ@2|F?9cOKmY)c0uzV_Lg$nMFOb(QXj}rc00IC&DELT+f@HxiAV%j3cx;WtbKNc= z2h(m`2*e^lR#;fgRf20nnm;}lBv0d!f;%;0$2|)U>nj5 zg%81hao3Q0X!=m$(1M|LLmflshHek_4=aaF!|}uJVScz~_~qf|;oZY`hW|Y*;v0l) zNF$5!IB>F+i#*~pp71?S8Rp^ju&>TU$C~8~=UHK$4K}&bR=2p{lYVZW-}|ef(y}$F znqIE8jcw^zCpy)cZuRea`l#RM9Q`!SzPY$3?wnn)Kfgc!lk3ASIO?X>WSsPR8(m?` zA=SM*QZ}z}KkdieUDrBy$^4Jn!R=VpX3o7d{_pB9z1JH(*<;<;%`GY4@!Z8<$dw=S zZTjN7i@xRMt~CgBEGIG~CIz@Qx7{L;^S>_Z=T-`igIlm~5au`gMnM`P%QhW}#m zAwB#*$2rDPj_^7M*vSs+nF046zol>geS6>ESC?U5Kj0v0F?#G1?D2)K9}xM!fx=IO zP&Y);m;)YN*ej0cJ z<}3#TBAxYQ*V$E?p~Lj@XT-)DeUrwLW}HY}39eQLlOEi)i#IOIZU>MGbENytY<2!MwOtjBDlHfRw@=&(e0s_zedl|i*c zN!CZJVn;RD(U_>)&ly#CJIwJyMxnH3GYtlvkQ7h3)_LB1Hel?_=wCn>%BhA=>72Q1 zm@D_w_x>n9zLrvqo;>?k`RkW|{{HzWfF_dDUehxnDg9Y+i5VKL$N$rRb~~q8%Z-tl zXgvUDqxG6T2#!CROtj>*G6~~{(IiJ@&_s9}4Sy8bs9b{3Yh*GkbA{IlI)Dy}5-=?S z5@Tn3L`Wf5B~~;MeO8d32myS;1?>@JG&y=^v@Pp~4e>FGc6KQ;1OR#mBZDTV#aVem z9cULYD{_b>cTo(MW^op?C`DX&%d#+Oc1TKJ%z7i2N=8e)>y8-t3vOuD``KR@sGAv_z8sOW7LNTU?6=V z?u(!WKtLeERnDd2LisW%R6`qi9xJA&v%YjR=ep_*Rbj4PvY=|ySciDp%Y26HI)vsE z?B+Fq;zR{a?zdlVOo?_LO)jeu1NTW1K+=?OMd4CZO%xP$IQkh>+f|M=?%XvEEsS}XQMKPd*|7YJQC zPmI76vr-Q>cmr6Ra!Ay0vh_R3{-bnz~*W&3Xn^OBspIV>q+`0;umr5OtXpabMt~W(qqW@P}|6XWuO#sd&LRBRp`Rv+2sq+2RG({opuQkbf8^SPeQY*{|h2@*hm7LHg^TIz(O z6rj?s11}@+&M!<^Khmm-eH;W?p{!SRxSb5>F~%lh{s0(xYM}-GQ8a6SB52SNPY?mA zB(f6-c>=Xt;xSD_=qvPOv1llU1b~SmN(OqwOkRlHys)DNd)h!`iEic)@iU=}5C<9} z43r)dL?|*Rp;Mzrj?{unwICpe4fxeSr0Mqv2KqTuVK*njS4Wa%kuTN|iRg_;7_*2_ z^gy9yoYE8@OixNh=P-{5yK$gc+1X6b=dP+uS>895o9me^?bwP5@t(0b$|((gBJ)9q zLt-%IJmpD_r+|~37G69}WHCe><#2+#Ms_usA-sTuy02)>-zz-4!HWKgm7Wqv!Ag;6 z30EX|Q(Z`jO5xI~F60z;zD)&kYUb1yv` z^nq}aZ1-fhah+vvWIIjbEw*NA&nQj)1iB;8Jt=R9?@N4FDiLBa5)|w3nN#D+7-%+H zlDllOuA2qX7>xmXwJ!YxI$i^Sfig+4cXy#Z8O;Dsmt78lK<^%E%4Upx@sd!s$s<6| z8Xq zF)d#MV@#8gQ3)nEo;bXN%_I<%%^LucwIKngv_UuqERs0$tW93czI}5v%b(TH4d&yw z+&j~%c)>hBEGKVY$F32^VL%6Z!RLNNMz$Fzama>dDHUn@j+{Ue`c(`2?y6pU&wa3A z*57Zt@j&MzWJ^;)v+>Q3aH5@{N!we-$p3Gcq5R#i@59cXU3=?;rGzn0j?!<_c9CVV z++K_Mrwu`%&8oWV>VusEz=vt!axW>S77H3kDz+#a0E8hKNE%O~h9X>cpz*SENKq-a50tY&ohI>goMwFpo2p7bdieB8M zVjF^xK#sErTwa$Hm)AuhY$(%4^C{#kdsS^80!JYw*4?=w4>nIXQXjf_eOd46X>oMP zV(dJ%rZhO-rmIDpGD+XokbNsaL7ge1lEk zvC`}PHsd-W322~m31dL#c8GL_k#2g4!^k?j1EGrpO~Eysk%V!(Hz{!xLLXo#%tnj7 z`{(#+3-e)|B;&Q`o}In<_WSG4q)7hjJ(V&fu0+&0rdoYtzP{_GdS^b!XKynRh)g4Y zE+X~$rOb~e<@PkwF;!8-3rM`e{;2NBi!0A{=AH2FO{bJEVzupsosmtNZ`-5qxFh36 z2=t}x&+eYJ{m4#O*D9_7SnM^i^`+*=G%IE z@6qhG%{}j(7j!bfG@mWzJNq`z7l(dwJjE#n$n$&85R`VN$1WA+^-!8HJ~fl;1>hRa z(PBx@>?KyaR3Ev@Vya=QLX*Rnf?1wrw|wBLN6A(x0_-&l(flEyHqb-Laj3k1QBG9s z;jM%@JrXoI>}O=zTedZp>}WLnSgLsDs;`AW8})VX$wK{NjI4QpR!Ur%CYoW|L^4D) z*u6-3;XH92IIOTXrAMRERBiy!Zk5P30~+^Uz`AsiDnotXQWc)(RhX$s!x--uf`zez z(5@g6TM_Q3F+CFkS@z9Hek_Ho0craY`}?Eg(-(XwImE@%E-@F$@Z*Unq3py=j{?i9 zUdN2}NX@Lm7@sE~VBcT2q}!`k-|b@|Q6`Yeu#`AMmk!|r+tNvil*B{5LXicWMidiS zLu$G%sDm+3Zuvdzs;RqB?_ucZ5kT|0uw8a|8!OEh3A^_`T3gVcdNqmj1-i5p<;s+P z(zXsEw8x=ZwWfiBKfo2q3HS)9k6j)&=58cpdM_y=MUPTs7FJ`m%iBV~Ym8;t?*m*!)$LB%LSDVM{@bPR?oB82& z@)zR0hf{Da2#ZB7S+FBs!tjo0zn{Zt(~CzLLgQT9?j-o|I)CRt@S0MGbewpC_1^Ka zfW^7M2Eb3m;EB-_gG2`r!l)c5@+9P7hcW79{}>6K&<4GDVWp*2^5uHn&>MKoy%0Fd zwwbnR4D}Jl`t;fNqrRLaBpEu4W=P4$YJpt6Or0z+-J#H72_ZeGI4G0I4i-$ugQy(^ z@jgUiLW-x_rGxD6^`af1fV<3SGnO@*T1;iVeWpG-9yg`<`f$fzk53RXTM&sJKxJ9Z zxXBklwgorJ(+tYpj_`k}NW+lu&|Y**^j zRpae8-S;&>(~f5aWtg$N+~hN1ztLxujA_#F({47{w9N9;Xn)qNTyW?|$cxqzgR(9n zgf1CLtQGNyTaATI*ySkTc(+VwMR`?z>GSsOWf70qz5DW@7dfFWzKU&fMVy9F$1B2O zWLlxZQo{fb2#~p*PXpiK=)i)CsVpJ`V2ZeX_pcJS>3s;{ohC-huZaIdJs`6eNR`$9{!N zmdI zUQwvvI7(NjlSu=s3j*XwA1=m-$dBzO)Dc3wZ83Y3d=wGbg@-;f^7RTN`3++ak8uL>m?lR#&3aDhl>iz{G2r&Uk8?N^{Nw`>}nTKxdv@ArEbg@ zSVdhD{^>Ji40FYOg_&S`VpJOEd$K?BfUyO19Xb`0(8Pw2_cSK%+4eqMFf0E&W$Zvf1e>R84%3zsRcbBGP}kab?7%G5Uc3+6D~epaZ>3h?jb~vaWQ&Tv zCe3ve6x98Txh|mqWl->82$qX&jnYP&7_&nj@eu403xEKu{|ulmyr*O<_YixOZ7ee_ zfP_);w9NO^h#_hJ6>u2D98`PD$XIju5i!|yzrHH#K42KGJo5s$Vim-YbX z?AL9t&vt?y>&d5&9s>fCag;qmH4v0He){tsyiTu-rhkyWOb^pD6cn{Lyi?D4l=pLpVt^!i{!?>?x(zV zBSFecr^ZHRh$En^*H{VPR3fr672cVRD%{Jo>J17fY?+O!_k$U|qieWxWXx3|qX7H( z)V{+o%sl;+Nk$UJ8mAMW14(cCnx!gfRr=ewWnF_G0)gp4}+%WI|FXU6%e1CjDfIOd?zIF>`wnCM01-v7{**t5-5&IUK7f z#EYzWanYfoRvS@!o4P#r$6=!RA2vop+_Cx85Zb?vE)tSIIyhve?ahQd)5ML1Dwi0lDB%gX|jI3FnL*5{B zBya6D;%$gAz8)O^9q^$HU*6lo^*vwx3qULX(arf>FaomR$Ip5#yT4%^CYbYG;>KZL$>}W zPQ{0DVt!q$>Go}teelU3*DmatX0plhi(I>K?%aj;#d4BsP1AZ7-co~44#tVk4->R+ z-ppa^KWCz1zDb#s@=Z(>^Z9y=Q}{F>4W!DMgZ34`Ll0&=pPHRwpS0FhI&q%Hfw%;} zHZQeAYfGckY}%65cHrql`RRQ4GRHXA^Ng(RrLMJ;^z#~~;AvWahdqMp(+>P3E91Fq zT!Wp4|GAZ#z#(;c-Hd?v#8OrERC*>sG7}!oB&&v4oGq?q5liNlvGa>@+Fi{^STL=e z_5n9$GMch_r+afd;VP4d5DFxH!DYTb?`=#eMwvS{3O3wP}V9-#2S)hDa{T7&~iUIKyNn zx@}lKHlnFb`wP)A!jN^#>PW`DTypFcdk0+G$ak z-K9j&thkd5Xa0ev!`lnWFcAlpiH(gBD#+m+BtLdo3Z*rbAuUYL`Iuy!1y#h$T8raf z)JDs!`FIeyQ4r5(@=2a@Y`2>pIn^p?kp;GuxUUf$bl#74I-h&x{fU7;De<45S6|k8 zwU?_u|EKq{U5mmJV+Zq|Hj+ZGkZgRKH)!^l>HebPmqD>giwDRcd4Swss#IBW6LT$z zhV;aAgF9@^zasv%CQNlN@g8Uo|AFYgvpSaTWRV~ot_{a>%+fpk#1HO5)n79!Ru?ua zF(Txsr|)*sh@usKMX$w_OHTZbg46-i76hZs1_R@aWLbA#01u!prFE&O)@3y^!N^I- z!?Hf3*ofB(kIDp@ef)s{Vux4u0;sDb&Q$FT#^BZ+$?8=4k=;yp;9KYfj}vt&p>FYH z%x(3*p)2(GdI)L^qFhk{EM;OV@-Vld`2)77*mzjhByovyQd`2-$*>fv^GbaVah`}f zKzl|LfCk-@0LeWh^q%>-k(*LBsrD0J zi0*5?RDMytzW`@c7bV1T(v>njrdvaO&^QY)DL6S96c@MTThi!hO1oNoTU5fRuXMZ1(U3t)*D|3I-1lL;+&uGk_Hm&yRX zS+Q4|X*moSsR1c?%p$go5^>^zapsI~Zd_Dpd1%>=26fV;pgZHBKqIQb{^;$Fy3 z@_XWCY2-xga!W#+rOMKlU|FG?M`&V-5;MNI?g}>071%9@BJ`VL8NY_nl;X)OV(*Eu z+*?D4Mv5;LNY~W#)E$gGCqj)7(d}-SzP8dWZXEmMH~*N1LXsy<^qxFJz8UCfV{Q}L!4P$F@4O~=S@?xlBYY9BUP$+5 z0RH>Lpk`1jvLx&E!^K=o-zejENU~Z6G~|4s0kY1r$OBu3cJaXIyT+{`B}%{``BQ~` zfAIdpxIqR#WkJBkeEnk%80H0q2(#T%zdL(n}MZ%)xC~V#7Ial~A zb55@dL(7ZAw;&Jmdm*uwcfXE^{Gy7P3khj5lZ2&X<7&bJ{`By})PIqDEHCFI*Zm&a z9ciO?P|1$Hvm+TZO5<@W+ooosqBRaxm#L$5jCi}9DYTE3ZwYEM;baXQ;c!QTPM5toT`1dUbuY;CrE zRjt4yE*J0S6m_&0Y}2;TE!F=Qez5LMLG%>G)b4z6UpX~;ig0IQw#<$&;%LCzaElZQGU!K*hFgGr@ChE3M~noTa*U_4q^ak+tI{PL#5aT6-GC zM1=L)*Ji(ZCxFM`fjh4bt?D;&BagmbeS2Miim>*syWEcIW%u zRnT!^V|LV*+SuA&(JK1kv>R*H(S=#Y_otH-Rroo17uwIG+ z9ZKzIp=XKY_2woxMJyLjflY01J0l%mA5F%)|NG<4r5{SPczGS-5$kkX-cGRaUUrt! zwWfzfw9h95Uyl%cj1hwv&;Sj1>rvVs-JZ!N#x&Wl^QQ%wVz-V=)Pyk57BGTb>tnYb z#YrvM9E)+Yi8h(r%-A3eFfHEkhyXexT)6XC7RZ$pZN%iIj!D*}`Ll`mLL*_UV{?eY zBi;!TX?=j+CdgpQiQzxbf%Z^1E>T!TcY*zk}mFuvJO)qFV2lU zVdLyjo^lb}x)nGnk}b~QUr`VNRu{a!HG)f3?^8R!bS~Jkpx=AwLR63q-sy3N`+VW< zX>~#1cI^DMK`wvNt#$h#C=ie0K=;Jk1V#bT5(%|=X;<3DL>hADq8L!siW`ROgru-mvqe3P5IpWtaxn9$1*uX?O zWPhvv8^%&Z8h8!r>{!xyPsb2ely_WOEWkU+5^|9eM*kq(b z>)AQ(r6NVf3f4jWR=I-~DtG}6gv?<^CqkGNaE3h1;!IAkEy&GmslJZ=l`o;kYGZ}U zuTaoKbP9!+N7-Q2pI;vzc(E>Y+wH5XA4UcXSvQ(1bVNDBA?jE0^YA9Ev8%cyz;tCJ8uFRDo?M$vjoUI&8jfUvxiT@(VZ z;x_^vU6|^C%`+%NMRwI;347#n6F% Subset: 13 KB (104 iconos) = 94% reduccion wp_enqueue_style( 'bootstrap-icons', - get_template_directory_uri() . '/Assets/Vendor/bootstrap-icons.min.css', + get_template_directory_uri() . '/Assets/Vendor/bootstrap-icons-subset.min.css', array('roi-bootstrap'), - '1.11.3', + ROI_VERSION, 'all' );