From 1f73a7070ff2df9f7006246bd5651ca8f9c82992 Mon Sep 17 00:00:00 2001
From: Face <69168154+face-hh@users.noreply.github.com>
Date: Tue, 22 Jul 2025 15:34:42 +0300
Subject: [PATCH] p, pre, br, b, img, separator, i, u, small, mark, code tags
---
Assets/Icons/23x23-empty.svg | 2 +
.../Icons/23x23-empty.svg.import | 11 +-
{Icons => Assets/Icons}/arrow-left.svg | 0
{Icons => Assets/Icons}/arrow-left.svg.import | 6 +-
{Icons => Assets/Icons}/arrow-right.svg | 0
.../Icons}/arrow-right.svg.import | 6 +-
{Icons => Assets/Icons}/chevron-down.svg | 0
.../Icons}/chevron-down.svg.import | 6 +-
Assets/Icons/loader-circle.svg | 1 +
Assets/Icons/loader-circle.svg.import | 37 +++++
{Icons => Assets/Icons}/plus.svg | 0
{Icons => Assets/Icons}/plus.svg.import | 6 +-
{Icons => Assets/Icons}/rotate-cw.svg | 0
{Icons => Assets/Icons}/rotate-cw.svg.import | 6 +-
{Icons => Assets/Icons}/search.svg | 0
{Icons => Assets/Icons}/search.svg.import | 6 +-
{Icons => Assets/Icons}/x.svg | 0
{Icons => Assets/Icons}/x.svg.import | 6 +-
README.md | 7 +
Ref/methods.gd | 2 +-
Scenes/Styles/BrowserText.tres | 32 ++++
Scenes/Tab.tscn | 19 ++-
Scenes/Tags/bold.tscn | 23 +++
Scenes/Tags/br.tscn | 10 ++
Scenes/Tags/code.tscn | 22 +++
Scenes/Tags/h1.tscn | 0
Scenes/Tags/img.tscn | 10 ++
Scenes/Tags/italic.tscn | 22 +++
Scenes/Tags/mark.tscn | 22 +++
Scenes/Tags/p.tscn | 22 +++
Scenes/Tags/pre.tscn | 22 +++
Scenes/Tags/separator.tscn | 8 +
Scenes/Tags/small.tscn | 22 +++
Scenes/Tags/underline.tscn | 22 +++
Scenes/main.tscn | 31 ++--
Scripts/B9/HTMLParser.gd | 16 ++
Scripts/Network.gd | 61 ++++++++
Scripts/Network.gd.uid | 1 +
Scripts/Tab.gd | 8 +
Scripts/TabContainer.gd | 6 +
Scripts/Tags/bold.gd | 5 +
Scripts/Tags/bold.gd.uid | 1 +
Scripts/Tags/br.gd | 4 +
Scripts/Tags/br.gd.uid | 1 +
Scripts/Tags/code.gd | 5 +
Scripts/Tags/code.gd.uid | 1 +
Scripts/Tags/img.gd | 11 ++
Scripts/Tags/img.gd.uid | 1 +
Scripts/Tags/italic.gd | 5 +
Scripts/Tags/italic.gd.uid | 1 +
Scripts/Tags/mark.gd | 5 +
Scripts/Tags/mark.gd.uid | 1 +
Scripts/Tags/p.gd | 5 +
Scripts/Tags/p.gd.uid | 1 +
Scripts/Tags/pre.gd | 5 +
Scripts/Tags/pre.gd.uid | 1 +
Scripts/Tags/separator.gd | 26 ++++
Scripts/Tags/separator.gd.uid | 1 +
Scripts/Tags/small.gd | 5 +
Scripts/Tags/small.gd.uid | 1 +
Scripts/Tags/underline.gd | 5 +
Scripts/Tags/underline.gd.uid | 1 +
Scripts/main.gd | 123 +++++++++++++++-
Scripts/youtube.png | Bin 2202 -> 0 bytes
godotgif/LICENSE.txt | 21 +++
godotgif/README.md | 139 ++++++++++++++++++
.../libgodotgif.macos.template_debug | Bin 0 -> 745432 bytes
.../libgodotgif.macos.template_release | Bin 0 -> 745096 bytes
...godotgif.windows.template_debug.x86_32.dll | Bin 0 -> 431616 bytes
...godotgif.windows.template_debug.x86_64.dll | Bin 0 -> 516608 bytes
...dotgif.windows.template_release.x86_32.dll | Bin 0 -> 398336 bytes
...dotgif.windows.template_release.x86_64.dll | Bin 0 -> 459776 bytes
...ibgodotgif.android.template_debug.arm64.so | Bin 0 -> 1182776 bytes
...godotgif.android.template_release.arm64.so | Bin 0 -> 1103152 bytes
...libgodotgif.linux.template_debug.x86_32.so | Bin 0 -> 1579968 bytes
...libgodotgif.linux.template_debug.x86_64.so | Bin 0 -> 1433568 bytes
...bgodotgif.linux.template_release.x86_32.so | Bin 0 -> 1533536 bytes
...bgodotgif.linux.template_release.x86_64.so | Bin 0 -> 1374848 bytes
...godotgif.windows.template_debug.x86_64.dll | Bin 0 -> 516608 bytes
godotgif/godotgif.gdextension | 23 +++
godotgif/godotgif.gdextension.uid | 1 +
project.godot | 9 ++
82 files changed, 841 insertions(+), 48 deletions(-)
create mode 100644 Assets/Icons/23x23-empty.svg
rename Scripts/youtube.png.import => Assets/Icons/23x23-empty.svg.import (60%)
rename {Icons => Assets/Icons}/arrow-left.svg (100%)
rename {Icons => Assets/Icons}/arrow-left.svg.import (74%)
rename {Icons => Assets/Icons}/arrow-right.svg (100%)
rename {Icons => Assets/Icons}/arrow-right.svg.import (74%)
rename {Icons => Assets/Icons}/chevron-down.svg (100%)
rename {Icons => Assets/Icons}/chevron-down.svg.import (74%)
create mode 100644 Assets/Icons/loader-circle.svg
create mode 100644 Assets/Icons/loader-circle.svg.import
rename {Icons => Assets/Icons}/plus.svg (100%)
rename {Icons => Assets/Icons}/plus.svg.import (76%)
rename {Icons => Assets/Icons}/rotate-cw.svg (100%)
rename {Icons => Assets/Icons}/rotate-cw.svg.import (75%)
rename {Icons => Assets/Icons}/search.svg (100%)
rename {Icons => Assets/Icons}/search.svg.import (75%)
rename {Icons => Assets/Icons}/x.svg (100%)
rename {Icons => Assets/Icons}/x.svg.import (77%)
create mode 100644 README.md
create mode 100644 Scenes/Styles/BrowserText.tres
create mode 100644 Scenes/Tags/bold.tscn
create mode 100644 Scenes/Tags/br.tscn
create mode 100644 Scenes/Tags/code.tscn
create mode 100644 Scenes/Tags/h1.tscn
create mode 100644 Scenes/Tags/img.tscn
create mode 100644 Scenes/Tags/italic.tscn
create mode 100644 Scenes/Tags/mark.tscn
create mode 100644 Scenes/Tags/p.tscn
create mode 100644 Scenes/Tags/pre.tscn
create mode 100644 Scenes/Tags/separator.tscn
create mode 100644 Scenes/Tags/small.tscn
create mode 100644 Scenes/Tags/underline.tscn
create mode 100644 Scripts/Network.gd
create mode 100644 Scripts/Network.gd.uid
create mode 100644 Scripts/Tags/bold.gd
create mode 100644 Scripts/Tags/bold.gd.uid
create mode 100644 Scripts/Tags/br.gd
create mode 100644 Scripts/Tags/br.gd.uid
create mode 100644 Scripts/Tags/code.gd
create mode 100644 Scripts/Tags/code.gd.uid
create mode 100644 Scripts/Tags/img.gd
create mode 100644 Scripts/Tags/img.gd.uid
create mode 100644 Scripts/Tags/italic.gd
create mode 100644 Scripts/Tags/italic.gd.uid
create mode 100644 Scripts/Tags/mark.gd
create mode 100644 Scripts/Tags/mark.gd.uid
create mode 100644 Scripts/Tags/p.gd
create mode 100644 Scripts/Tags/p.gd.uid
create mode 100644 Scripts/Tags/pre.gd
create mode 100644 Scripts/Tags/pre.gd.uid
create mode 100644 Scripts/Tags/separator.gd
create mode 100644 Scripts/Tags/separator.gd.uid
create mode 100644 Scripts/Tags/small.gd
create mode 100644 Scripts/Tags/small.gd.uid
create mode 100644 Scripts/Tags/underline.gd
create mode 100644 Scripts/Tags/underline.gd.uid
delete mode 100644 Scripts/youtube.png
create mode 100644 godotgif/LICENSE.txt
create mode 100644 godotgif/README.md
create mode 100644 godotgif/bin/godotgif.macos.template_debug.framework/libgodotgif.macos.template_debug
create mode 100644 godotgif/bin/godotgif.macos.template_release.framework/libgodotgif.macos.template_release
create mode 100644 godotgif/bin/godotgif.windows.template_debug.x86_32.dll
create mode 100644 godotgif/bin/godotgif.windows.template_debug.x86_64.dll
create mode 100644 godotgif/bin/godotgif.windows.template_release.x86_32.dll
create mode 100644 godotgif/bin/godotgif.windows.template_release.x86_64.dll
create mode 100644 godotgif/bin/libgodotgif.android.template_debug.arm64.so
create mode 100644 godotgif/bin/libgodotgif.android.template_release.arm64.so
create mode 100644 godotgif/bin/libgodotgif.linux.template_debug.x86_32.so
create mode 100644 godotgif/bin/libgodotgif.linux.template_debug.x86_64.so
create mode 100644 godotgif/bin/libgodotgif.linux.template_release.x86_32.so
create mode 100644 godotgif/bin/libgodotgif.linux.template_release.x86_64.so
create mode 100644 godotgif/bin/~godotgif.windows.template_debug.x86_64.dll
create mode 100644 godotgif/godotgif.gdextension
create mode 100644 godotgif/godotgif.gdextension.uid
diff --git a/Assets/Icons/23x23-empty.svg b/Assets/Icons/23x23-empty.svg
new file mode 100644
index 0000000..585211f
--- /dev/null
+++ b/Assets/Icons/23x23-empty.svg
@@ -0,0 +1,2 @@
+
\ No newline at end of file
diff --git a/Scripts/youtube.png.import b/Assets/Icons/23x23-empty.svg.import
similarity index 60%
rename from Scripts/youtube.png.import
rename to Assets/Icons/23x23-empty.svg.import
index 82be867..3e79677 100644
--- a/Scripts/youtube.png.import
+++ b/Assets/Icons/23x23-empty.svg.import
@@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
-uid="uid://dioe63fr47oq7"
-path="res://.godot/imported/youtube.png-5feacc6342e9a438cbbd6a63702ea1ce.ctex"
+uid="uid://dglkjumm1q4lo"
+path="res://.godot/imported/23x23-empty.svg-f79aa182e01c658978086a2615b5cbce.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Scripts/youtube.png"
-dest_files=["res://.godot/imported/youtube.png-5feacc6342e9a438cbbd6a63702ea1ce.ctex"]
+source_file="res://Assets/Icons/23x23-empty.svg"
+dest_files=["res://.godot/imported/23x23-empty.svg-f79aa182e01c658978086a2615b5cbce.ctex"]
[params]
@@ -32,3 +32,6 @@ process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/arrow-left.svg b/Assets/Icons/arrow-left.svg
similarity index 100%
rename from Icons/arrow-left.svg
rename to Assets/Icons/arrow-left.svg
diff --git a/Icons/arrow-left.svg.import b/Assets/Icons/arrow-left.svg.import
similarity index 74%
rename from Icons/arrow-left.svg.import
rename to Assets/Icons/arrow-left.svg.import
index 855fcba..6033883 100644
--- a/Icons/arrow-left.svg.import
+++ b/Assets/Icons/arrow-left.svg.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bp42ccs2nmbmw"
-path="res://.godot/imported/arrow-left.svg-6665bd65bdc7655f58ffd2c77101e033.ctex"
+path="res://.godot/imported/arrow-left.svg-5f99da4595c3d8d0d08c3c956ebfe3c3.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Icons/arrow-left.svg"
-dest_files=["res://.godot/imported/arrow-left.svg-6665bd65bdc7655f58ffd2c77101e033.ctex"]
+source_file="res://Assets/Icons/arrow-left.svg"
+dest_files=["res://.godot/imported/arrow-left.svg-5f99da4595c3d8d0d08c3c956ebfe3c3.ctex"]
[params]
diff --git a/Icons/arrow-right.svg b/Assets/Icons/arrow-right.svg
similarity index 100%
rename from Icons/arrow-right.svg
rename to Assets/Icons/arrow-right.svg
diff --git a/Icons/arrow-right.svg.import b/Assets/Icons/arrow-right.svg.import
similarity index 74%
rename from Icons/arrow-right.svg.import
rename to Assets/Icons/arrow-right.svg.import
index 9eae9b6..c33c38a 100644
--- a/Icons/arrow-right.svg.import
+++ b/Assets/Icons/arrow-right.svg.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dyyylow47qd0k"
-path="res://.godot/imported/arrow-right.svg-952a316afcd4823b2076bf76a665b17d.ctex"
+path="res://.godot/imported/arrow-right.svg-c769bf30dd1a5a6c76e989455e94e01b.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Icons/arrow-right.svg"
-dest_files=["res://.godot/imported/arrow-right.svg-952a316afcd4823b2076bf76a665b17d.ctex"]
+source_file="res://Assets/Icons/arrow-right.svg"
+dest_files=["res://.godot/imported/arrow-right.svg-c769bf30dd1a5a6c76e989455e94e01b.ctex"]
[params]
diff --git a/Icons/chevron-down.svg b/Assets/Icons/chevron-down.svg
similarity index 100%
rename from Icons/chevron-down.svg
rename to Assets/Icons/chevron-down.svg
diff --git a/Icons/chevron-down.svg.import b/Assets/Icons/chevron-down.svg.import
similarity index 74%
rename from Icons/chevron-down.svg.import
rename to Assets/Icons/chevron-down.svg.import
index 03bf3d4..c005fa6 100644
--- a/Icons/chevron-down.svg.import
+++ b/Assets/Icons/chevron-down.svg.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://df1m4j7uxi63v"
-path="res://.godot/imported/chevron-down.svg-484378157f0927346bbcbdbf4232b051.ctex"
+path="res://.godot/imported/chevron-down.svg-549b6fd6d6d40e9ebd832012d163f272.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Icons/chevron-down.svg"
-dest_files=["res://.godot/imported/chevron-down.svg-484378157f0927346bbcbdbf4232b051.ctex"]
+source_file="res://Assets/Icons/chevron-down.svg"
+dest_files=["res://.godot/imported/chevron-down.svg-549b6fd6d6d40e9ebd832012d163f272.ctex"]
[params]
diff --git a/Assets/Icons/loader-circle.svg b/Assets/Icons/loader-circle.svg
new file mode 100644
index 0000000..b53caf3
--- /dev/null
+++ b/Assets/Icons/loader-circle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Assets/Icons/loader-circle.svg.import b/Assets/Icons/loader-circle.svg.import
new file mode 100644
index 0000000..c6d6026
--- /dev/null
+++ b/Assets/Icons/loader-circle.svg.import
@@ -0,0 +1,37 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cttplkybt1dxv"
+path="res://.godot/imported/loader-circle.svg-c17ccf4fea88a610c3708518f9137af7.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://Assets/Icons/loader-circle.svg"
+dest_files=["res://.godot/imported/loader-circle.svg-c17ccf4fea88a610c3708518f9137af7.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/Icons/plus.svg b/Assets/Icons/plus.svg
similarity index 100%
rename from Icons/plus.svg
rename to Assets/Icons/plus.svg
diff --git a/Icons/plus.svg.import b/Assets/Icons/plus.svg.import
similarity index 76%
rename from Icons/plus.svg.import
rename to Assets/Icons/plus.svg.import
index 87d39b8..30cfacf 100644
--- a/Icons/plus.svg.import
+++ b/Assets/Icons/plus.svg.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cehbtwq6gq0cn"
-path="res://.godot/imported/plus.svg-dfcf01023e04ffbd2a1c50b2672d981c.ctex"
+path="res://.godot/imported/plus.svg-f4b3570cb7fae700c6a08ebce6d60d56.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Icons/plus.svg"
-dest_files=["res://.godot/imported/plus.svg-dfcf01023e04ffbd2a1c50b2672d981c.ctex"]
+source_file="res://Assets/Icons/plus.svg"
+dest_files=["res://.godot/imported/plus.svg-f4b3570cb7fae700c6a08ebce6d60d56.ctex"]
[params]
diff --git a/Icons/rotate-cw.svg b/Assets/Icons/rotate-cw.svg
similarity index 100%
rename from Icons/rotate-cw.svg
rename to Assets/Icons/rotate-cw.svg
diff --git a/Icons/rotate-cw.svg.import b/Assets/Icons/rotate-cw.svg.import
similarity index 75%
rename from Icons/rotate-cw.svg.import
rename to Assets/Icons/rotate-cw.svg.import
index bdc56f8..c29ffcd 100644
--- a/Icons/rotate-cw.svg.import
+++ b/Assets/Icons/rotate-cw.svg.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cu4hjoba6etf"
-path="res://.godot/imported/rotate-cw.svg-868e19f6bcf83d62897eb2ac44a0b471.ctex"
+path="res://.godot/imported/rotate-cw.svg-dc1ce1f9471720aef7c52da0114941eb.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Icons/rotate-cw.svg"
-dest_files=["res://.godot/imported/rotate-cw.svg-868e19f6bcf83d62897eb2ac44a0b471.ctex"]
+source_file="res://Assets/Icons/rotate-cw.svg"
+dest_files=["res://.godot/imported/rotate-cw.svg-dc1ce1f9471720aef7c52da0114941eb.ctex"]
[params]
diff --git a/Icons/search.svg b/Assets/Icons/search.svg
similarity index 100%
rename from Icons/search.svg
rename to Assets/Icons/search.svg
diff --git a/Icons/search.svg.import b/Assets/Icons/search.svg.import
similarity index 75%
rename from Icons/search.svg.import
rename to Assets/Icons/search.svg.import
index 1d4d79a..0328218 100644
--- a/Icons/search.svg.import
+++ b/Assets/Icons/search.svg.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bf0vx7qwo28k6"
-path="res://.godot/imported/search.svg-597dbc74e85ee7dfea046ab610b3d4ad.ctex"
+path="res://.godot/imported/search.svg-1a2b06368a6d95d720ef3acf028b44e6.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Icons/search.svg"
-dest_files=["res://.godot/imported/search.svg-597dbc74e85ee7dfea046ab610b3d4ad.ctex"]
+source_file="res://Assets/Icons/search.svg"
+dest_files=["res://.godot/imported/search.svg-1a2b06368a6d95d720ef3acf028b44e6.ctex"]
[params]
diff --git a/Icons/x.svg b/Assets/Icons/x.svg
similarity index 100%
rename from Icons/x.svg
rename to Assets/Icons/x.svg
diff --git a/Icons/x.svg.import b/Assets/Icons/x.svg.import
similarity index 77%
rename from Icons/x.svg.import
rename to Assets/Icons/x.svg.import
index 757408a..521d0ae 100644
--- a/Icons/x.svg.import
+++ b/Assets/Icons/x.svg.import
@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://gq8g7t4s3ryg"
-path="res://.godot/imported/x.svg-4402340e2f725e924f2e7d83afde3bea.ctex"
+path="res://.godot/imported/x.svg-0cde62f4f4d7229f6d4217f24c8f641d.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://Icons/x.svg"
-dest_files=["res://.godot/imported/x.svg-4402340e2f725e924f2e7d83afde3bea.ctex"]
+source_file="res://Assets/Icons/x.svg"
+dest_files=["res://.godot/imported/x.svg-0cde62f4f4d7229f6d4217f24c8f641d.ctex"]
[params]
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8ca1494
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+TODO:
+1. Write a new **selection system**. Godot's built-in `RichTextLabel` selection is limited by the node's boundaries. In normal web, holding click and dragging your mouse across the screen will select text across multiple nodes. Godot doesn't have a "set_selected_text" property, despite having one for "get_selected_text".
+2. **Right-click Dropdown** for basic text operations (Copy, Paste, Cut). Download options for images
+3. **Select-all CTRL+A shortcut**
+4. **Scrolling** in the website container
+5. **Store** tab containers so switching tabs won't erase previous tab.
+6. **GIF** support
\ No newline at end of file
diff --git a/Ref/methods.gd b/Ref/methods.gd
index 1ef10f8..701b587 100644
--- a/Ref/methods.gd
+++ b/Ref/methods.gd
@@ -69,4 +69,4 @@ func _log_element_tree(element: HTMLParser.HTMLElement, depth: int):
_log_result(element_info)
for child in element.children:
- _log_element_tree(child, depth + 1)
\ No newline at end of file
+ _log_element_tree(child, depth + 1)
diff --git a/Scenes/Styles/BrowserText.tres b/Scenes/Styles/BrowserText.tres
new file mode 100644
index 0000000..4580c8a
--- /dev/null
+++ b/Scenes/Styles/BrowserText.tres
@@ -0,0 +1,32 @@
+[gd_resource type="Theme" load_steps=7 format=3 uid="uid://bn6rbmdy60lhr"]
+
+[sub_resource type="SystemFont" id="SystemFont_jecr6"]
+font_names = PackedStringArray("Serif")
+font_weight = 700
+
+[sub_resource type="SystemFont" id="SystemFont_75mhk"]
+font_names = PackedStringArray("Serif")
+font_italic = true
+font_weight = 700
+
+[sub_resource type="SystemFont" id="SystemFont_3k2jb"]
+font_names = PackedStringArray("Serif")
+font_italic = true
+
+[sub_resource type="SystemFont" id="SystemFont_u0shw"]
+font_names = PackedStringArray("Monospace")
+
+[sub_resource type="SystemFont" id="SystemFont_g4dwp"]
+font_names = PackedStringArray("Serif")
+
+[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_jecr6"]
+
+[resource]
+RichTextLabel/colors/font_selected_color = Color(1, 1, 1, 1)
+RichTextLabel/colors/selection_color = Color(0.313726, 0.403922, 0.8, 1)
+RichTextLabel/fonts/bold_font = SubResource("SystemFont_jecr6")
+RichTextLabel/fonts/bold_italics_font = SubResource("SystemFont_75mhk")
+RichTextLabel/fonts/italics_font = SubResource("SystemFont_3k2jb")
+RichTextLabel/fonts/mono_font = SubResource("SystemFont_u0shw")
+RichTextLabel/fonts/normal_font = SubResource("SystemFont_g4dwp")
+RichTextLabel/styles/focus = SubResource("StyleBoxEmpty_jecr6")
diff --git a/Scenes/Tab.tscn b/Scenes/Tab.tscn
index 178a919..b97d65f 100644
--- a/Scenes/Tab.tscn
+++ b/Scenes/Tab.tscn
@@ -1,11 +1,12 @@
-[gd_scene load_steps=11 format=3 uid="uid://sqhcxhcre081"]
+[gd_scene load_steps=12 format=3 uid="uid://sqhcxhcre081"]
[ext_resource type="Script" uid="uid://crpnnfqm3k5xv" path="res://Scripts/Tab.gd" id="1_q3baj"]
-[ext_resource type="Texture2D" uid="uid://gq8g7t4s3ryg" path="res://Icons/x.svg" id="2_pisds"]
+[ext_resource type="Texture2D" uid="uid://gq8g7t4s3ryg" path="res://Assets/Icons/x.svg" id="2_pisds"]
[ext_resource type="StyleBox" uid="uid://fd1nftmqox32" path="res://Scenes/Styles/TabHoverDefault.tres" id="3_kjcxk"]
[ext_resource type="Texture2D" uid="uid://c7u7a1u1v04bx" path="res://Scenes/Styles/TabGradientDefault.tres" id="3_q3baj"]
[ext_resource type="StyleBox" uid="uid://bx3sgro1ageff" path="res://Scenes/Styles/TabDefault.tres" id="4_ib6pj"]
-[ext_resource type="Texture2D" uid="uid://dioe63fr47oq7" path="res://Scripts/youtube.png" id="6_bdsd2"]
+[ext_resource type="Texture2D" uid="uid://dglkjumm1q4lo" path="res://Assets/Icons/23x23-empty.svg" id="5_ib6pj"]
+[ext_resource type="Texture2D" uid="uid://70k6bw18rsri" path="res://icon.svg" id="6_ib6pj"]
[ext_resource type="StyleBox" uid="uid://dn8exdnk8tjce" path="res://Scenes/Styles/CloseButtonHover.tres" id="6_pisds"]
[ext_resource type="StyleBox" uid="uid://dn6r16retee3l" path="res://Scenes/Styles/CloseButtonNormal.tres" id="7_1ohlo"]
@@ -45,10 +46,20 @@ theme_override_styles/pressed = ExtResource("3_kjcxk")
theme_override_styles/normal = ExtResource("4_ib6pj")
action_mode = 0
text = "(2) YouTube - STOP PLAYING WITH ME BITCHES FR"
-icon = ExtResource("6_bdsd2")
+icon = ExtResource("5_ib6pj")
alignment = 0
text_overrun_behavior = 3
+[node name="Icon" type="TextureRect" parent="."]
+custom_minimum_size = Vector2(23, 23)
+layout_mode = 0
+offset_left = 8.0
+offset_top = 13.0
+offset_right = 31.0
+offset_bottom = 36.0
+texture = ExtResource("6_ib6pj")
+expand_mode = 1
+
[node name="CloseButton" type="Button" parent="."]
z_index = 2
custom_minimum_size = Vector2(34, 34)
diff --git a/Scenes/Tags/bold.tscn b/Scenes/Tags/bold.tscn
new file mode 100644
index 0000000..2101c2c
--- /dev/null
+++ b/Scenes/Tags/bold.tscn
@@ -0,0 +1,23 @@
+[gd_scene load_steps=3 format=3 uid="uid://ijrbim6j8e36"]
+
+[ext_resource type="Script" uid="uid://chdftsciuecfk" path="res://Scripts/Tags/bold.gd" id="1_04sgx"]
+[ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="1_mtsji"]
+
+[node name="BOLD" type="VBoxContainer"]
+anchors_preset = 10
+anchor_right = 1.0
+grow_horizontal = 2
+theme = ExtResource("1_mtsji")
+script = ExtResource("1_04sgx")
+
+[node name="RichTextLabel" type="RichTextLabel" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+focus_mode = 2
+mouse_default_cursor_shape = 1
+theme = ExtResource("1_mtsji")
+theme_override_colors/default_color = Color(0, 0, 0, 1)
+bbcode_enabled = true
+text = "What the sigma"
+fit_content = true
+selection_enabled = true
diff --git a/Scenes/Tags/br.tscn b/Scenes/Tags/br.tscn
new file mode 100644
index 0000000..1d9f528
--- /dev/null
+++ b/Scenes/Tags/br.tscn
@@ -0,0 +1,10 @@
+[gd_scene load_steps=2 format=3 uid="uid://dmnpful5xhtrk"]
+
+[ext_resource type="Script" uid="uid://csd2kcqixac65" path="res://Scripts/Tags/br.gd" id="1_7hb8m"]
+
+[node name="BR" type="Control"]
+layout_mode = 3
+anchors_preset = 10
+anchor_right = 1.0
+grow_horizontal = 2
+script = ExtResource("1_7hb8m")
diff --git a/Scenes/Tags/code.tscn b/Scenes/Tags/code.tscn
new file mode 100644
index 0000000..5e2cab9
--- /dev/null
+++ b/Scenes/Tags/code.tscn
@@ -0,0 +1,22 @@
+[gd_scene load_steps=3 format=3 uid="uid://i5otagppegeo"]
+
+[ext_resource type="Script" uid="uid://c3dnmqsnj0akr" path="res://Scripts/Tags/code.gd" id="1_g4dwp"]
+[ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="2_u0shw"]
+
+[node name="CODE" type="VBoxContainer"]
+anchors_preset = 10
+anchor_right = 1.0
+grow_horizontal = 2
+script = ExtResource("1_g4dwp")
+
+[node name="RichTextLabel" type="RichTextLabel" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+focus_mode = 2
+mouse_default_cursor_shape = 1
+theme = ExtResource("2_u0shw")
+theme_override_colors/default_color = Color(0, 0, 0, 1)
+bbcode_enabled = true
+text = "What the sigma"
+fit_content = true
+selection_enabled = true
diff --git a/Scenes/Tags/h1.tscn b/Scenes/Tags/h1.tscn
new file mode 100644
index 0000000..e69de29
diff --git a/Scenes/Tags/img.tscn b/Scenes/Tags/img.tscn
new file mode 100644
index 0000000..7092cb6
--- /dev/null
+++ b/Scenes/Tags/img.tscn
@@ -0,0 +1,10 @@
+[gd_scene load_steps=2 format=3 uid="uid://b5rpke43iqfkt"]
+
+[ext_resource type="Script" uid="uid://dgakysfyq773t" path="res://Scripts/Tags/img.gd" id="1_clm6l"]
+
+[node name="TextureRect" type="TextureRect"]
+size_flags_horizontal = 0
+size_flags_vertical = 0
+expand_mode = 1
+stretch_mode = 2
+script = ExtResource("1_clm6l")
diff --git a/Scenes/Tags/italic.tscn b/Scenes/Tags/italic.tscn
new file mode 100644
index 0000000..0de7c4f
--- /dev/null
+++ b/Scenes/Tags/italic.tscn
@@ -0,0 +1,22 @@
+[gd_scene load_steps=3 format=3 uid="uid://bdw0ahhesgnvr"]
+
+[ext_resource type="Script" uid="uid://bamty87whxwxi" path="res://Scripts/Tags/italic.gd" id="1_ch1cm"]
+[ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="1_vh1cg"]
+
+[node name="ITALIC" type="VBoxContainer"]
+anchors_preset = 10
+anchor_right = 1.0
+grow_horizontal = 2
+theme = ExtResource("1_vh1cg")
+script = ExtResource("1_ch1cm")
+
+[node name="RichTextLabel" type="RichTextLabel" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+focus_mode = 2
+mouse_default_cursor_shape = 1
+theme_override_colors/default_color = Color(0, 0, 0, 1)
+bbcode_enabled = true
+text = "What the sigma"
+fit_content = true
+selection_enabled = true
diff --git a/Scenes/Tags/mark.tscn b/Scenes/Tags/mark.tscn
new file mode 100644
index 0000000..f59d724
--- /dev/null
+++ b/Scenes/Tags/mark.tscn
@@ -0,0 +1,22 @@
+[gd_scene load_steps=3 format=3 uid="uid://dlj64k35igexw"]
+
+[ext_resource type="Script" uid="uid://c2i8dwyyuufff" path="res://Scripts/Tags/mark.gd" id="1_j8rvb"]
+[ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="1_jr508"]
+
+[node name="MARK" type="VBoxContainer"]
+anchors_preset = 10
+anchor_right = 1.0
+grow_horizontal = 2
+theme = ExtResource("1_jr508")
+script = ExtResource("1_j8rvb")
+
+[node name="RichTextLabel" type="RichTextLabel" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+focus_mode = 2
+mouse_default_cursor_shape = 1
+theme_override_colors/default_color = Color(0, 0, 0, 1)
+bbcode_enabled = true
+text = "What the sigma"
+fit_content = true
+selection_enabled = true
diff --git a/Scenes/Tags/p.tscn b/Scenes/Tags/p.tscn
new file mode 100644
index 0000000..576101c
--- /dev/null
+++ b/Scenes/Tags/p.tscn
@@ -0,0 +1,22 @@
+[gd_scene load_steps=3 format=3 uid="uid://fr6lovy4ikok"]
+
+[ext_resource type="Script" uid="uid://cg6kjvlx3an1j" path="res://Scripts/Tags/p.gd" id="1_pnbfg"]
+[ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="2_1glvj"]
+
+[node name="P" type="VBoxContainer"]
+anchors_preset = 10
+anchor_right = 1.0
+grow_horizontal = 2
+script = ExtResource("1_pnbfg")
+
+[node name="RichTextLabel" type="RichTextLabel" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+focus_mode = 2
+mouse_default_cursor_shape = 1
+theme = ExtResource("2_1glvj")
+theme_override_colors/default_color = Color(0, 0, 0, 1)
+bbcode_enabled = true
+text = "What the sigma"
+fit_content = true
+selection_enabled = true
diff --git a/Scenes/Tags/pre.tscn b/Scenes/Tags/pre.tscn
new file mode 100644
index 0000000..d352134
--- /dev/null
+++ b/Scenes/Tags/pre.tscn
@@ -0,0 +1,22 @@
+[gd_scene load_steps=3 format=3 uid="uid://byt2tvxanciuk"]
+
+[ext_resource type="Script" uid="uid://8mam5rvtx72x" path="res://Scripts/Tags/pre.gd" id="1_7hb8m"]
+[ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="1_xp1ft"]
+
+[node name="PRE" type="VBoxContainer"]
+anchors_preset = 10
+anchor_right = 1.0
+grow_horizontal = 2
+theme = ExtResource("1_xp1ft")
+script = ExtResource("1_7hb8m")
+
+[node name="RichTextLabel" type="RichTextLabel" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+focus_mode = 2
+mouse_default_cursor_shape = 1
+theme_override_colors/default_color = Color(0, 0, 0, 1)
+bbcode_enabled = true
+text = "What the sigma"
+fit_content = true
+selection_enabled = true
diff --git a/Scenes/Tags/separator.tscn b/Scenes/Tags/separator.tscn
new file mode 100644
index 0000000..c8d7f71
--- /dev/null
+++ b/Scenes/Tags/separator.tscn
@@ -0,0 +1,8 @@
+[gd_scene load_steps=2 format=3 uid="uid://drfl5d5o2cudk"]
+
+[ext_resource type="Script" uid="uid://rol353cupbbf" path="res://Scripts/Tags/separator.gd" id="1_pu577"]
+
+[node name="Separator" type="Control"]
+layout_mode = 3
+anchors_preset = 0
+script = ExtResource("1_pu577")
diff --git a/Scenes/Tags/small.tscn b/Scenes/Tags/small.tscn
new file mode 100644
index 0000000..03a490a
--- /dev/null
+++ b/Scenes/Tags/small.tscn
@@ -0,0 +1,22 @@
+[gd_scene load_steps=3 format=3 uid="uid://btiiex1eu1krs"]
+
+[ext_resource type="Script" uid="uid://xr7n1lat501x" path="res://Scripts/Tags/small.gd" id="1_5vt6h"]
+[ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="1_yi3vu"]
+
+[node name="SMALL" type="VBoxContainer"]
+anchors_preset = 10
+anchor_right = 1.0
+grow_horizontal = 2
+theme = ExtResource("1_yi3vu")
+script = ExtResource("1_5vt6h")
+
+[node name="RichTextLabel" type="RichTextLabel" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+focus_mode = 2
+mouse_default_cursor_shape = 1
+theme_override_colors/default_color = Color(0, 0, 0, 1)
+bbcode_enabled = true
+text = "What the sigma"
+fit_content = true
+selection_enabled = true
diff --git a/Scenes/Tags/underline.tscn b/Scenes/Tags/underline.tscn
new file mode 100644
index 0000000..dfaa164
--- /dev/null
+++ b/Scenes/Tags/underline.tscn
@@ -0,0 +1,22 @@
+[gd_scene load_steps=3 format=3 uid="uid://br7ys1wgsp5om"]
+
+[ext_resource type="Script" uid="uid://x0hphtm8kf12" path="res://Scripts/Tags/underline.gd" id="1_7hb8m"]
+[ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="1_xp1ft"]
+
+[node name="UNDERLINE" type="VBoxContainer"]
+anchors_preset = 10
+anchor_right = 1.0
+grow_horizontal = 2
+theme = ExtResource("1_xp1ft")
+script = ExtResource("1_7hb8m")
+
+[node name="RichTextLabel" type="RichTextLabel" parent="."]
+layout_mode = 2
+size_flags_horizontal = 3
+focus_mode = 2
+mouse_default_cursor_shape = 1
+theme_override_colors/default_color = Color(0, 0, 0, 1)
+bbcode_enabled = true
+text = "What the sigma"
+fit_content = true
+selection_enabled = true
diff --git a/Scenes/main.tscn b/Scenes/main.tscn
index 797da50..3b6b536 100644
--- a/Scenes/main.tscn
+++ b/Scenes/main.tscn
@@ -1,14 +1,14 @@
-[gd_scene load_steps=22 format=3 uid="uid://bytm7bt2s4ak8"]
+[gd_scene load_steps=23 format=3 uid="uid://bytm7bt2s4ak8"]
[ext_resource type="Script" uid="uid://bg5iqnwic1rio" path="res://Scripts/main.gd" id="1_8q3xr"]
-[ext_resource type="Texture2D" uid="uid://df1m4j7uxi63v" path="res://Icons/chevron-down.svg" id="2_6bp64"]
+[ext_resource type="Texture2D" uid="uid://df1m4j7uxi63v" path="res://Assets/Icons/chevron-down.svg" id="2_6bp64"]
[ext_resource type="Script" uid="uid://cy0c74thgjwok" path="res://Scripts/TabContainer.gd" id="2_hptm8"]
-[ext_resource type="Texture2D" uid="uid://bf0vx7qwo28k6" path="res://Icons/search.svg" id="3_8gbba"]
-[ext_resource type="Texture2D" uid="uid://bp42ccs2nmbmw" path="res://Icons/arrow-left.svg" id="3_21xkr"]
-[ext_resource type="Texture2D" uid="uid://dyyylow47qd0k" path="res://Icons/arrow-right.svg" id="4_6bp64"]
+[ext_resource type="Texture2D" uid="uid://bf0vx7qwo28k6" path="res://Assets/Icons/search.svg" id="3_8gbba"]
+[ext_resource type="Texture2D" uid="uid://bp42ccs2nmbmw" path="res://Assets/Icons/arrow-left.svg" id="3_21xkr"]
+[ext_resource type="Texture2D" uid="uid://dyyylow47qd0k" path="res://Assets/Icons/arrow-right.svg" id="4_6bp64"]
[ext_resource type="PackedScene" uid="uid://sqhcxhcre081" path="res://Scenes/Tab.tscn" id="4_344ge"]
-[ext_resource type="Texture2D" uid="uid://cu4hjoba6etf" path="res://Icons/rotate-cw.svg" id="5_344ge"]
-[ext_resource type="Texture2D" uid="uid://cehbtwq6gq0cn" path="res://Icons/plus.svg" id="5_ynf5e"]
+[ext_resource type="Texture2D" uid="uid://cu4hjoba6etf" path="res://Assets/Icons/rotate-cw.svg" id="5_344ge"]
+[ext_resource type="Texture2D" uid="uid://cehbtwq6gq0cn" path="res://Assets/Icons/plus.svg" id="5_ynf5e"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_344ge"]
@@ -61,13 +61,16 @@ expand_margin_left = 40.0
LineEdit/styles/focus = SubResource("StyleBoxEmpty_8gbba")
LineEdit/styles/normal = SubResource("StyleBoxFlat_8gbba")
+[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_white"]
+bg_color = Color(1, 1, 1, 1)
+
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_6iyac"]
bg_color = Color(0.105882, 0.105882, 0.105882, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_21xkr"]
bg_color = Color(0.168627, 0.168627, 0.168627, 1)
-[node name="Control" type="Control"]
+[node name="Main" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@@ -187,17 +190,23 @@ stretch_mode = 5
custom_minimum_size = Vector2(0, 5)
layout_mode = 2
-[node name="BottomContainer" type="Control" parent="VBoxContainer"]
+[node name="WebsiteContainer" type="VBoxContainer" parent="VBoxContainer"]
+unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
+theme_override_constants/separation = 22
-[node name="ColorRect2" type="ColorRect" parent="VBoxContainer/BottomContainer"]
+[node name="WebsiteBackground" type="Panel" parent="."]
+z_index = -1
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
+offset_top = 125.0
grow_horizontal = 2
grow_vertical = 2
+mouse_filter = 2
+theme_override_styles/panel = SubResource("StyleBoxFlat_white")
[node name="Panel" type="Panel" parent="."]
z_index = -5
@@ -212,7 +221,7 @@ theme_override_styles/panel = SubResource("StyleBoxFlat_6iyac")
z_index = -6
layout_mode = 2
offset_right = 1920.0
-offset_bottom = 117.0
+offset_bottom = 125.0
mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_21xkr")
diff --git a/Scripts/B9/HTMLParser.gd b/Scripts/B9/HTMLParser.gd
index 7964c18..447dac6 100644
--- a/Scripts/B9/HTMLParser.gd
+++ b/Scripts/B9/HTMLParser.gd
@@ -23,6 +23,18 @@ class HTMLElement:
func get_id() -> String:
return get_attribute("id")
+
+ func get_collapsed_text() -> String:
+ # Collapse whitespace: replace multiple spaces, tabs, newlines with single space
+ var collapsed = text_content.strip_edges()
+ # Replace multiple whitespace characters with single space
+ var regex = RegEx.new()
+ regex.compile("\\s+")
+ return regex.sub(collapsed, " ", true)
+
+ func get_preserved_text() -> String:
+ # For pre tags - preserve all whitespace
+ return text_content
class ParseResult:
var root: HTMLElement
@@ -149,6 +161,10 @@ func get_title() -> String:
var title_element = find_first("title")
return title_element.text_content if title_element != null else ""
+func get_icon() -> String:
+ var icon_element = find_first("icon")
+ return icon_element.get_attribute("src")
+
func get_meta_content(name_: String) -> String:
var meta_elements = find_all("meta", "name")
for element in meta_elements:
diff --git a/Scripts/Network.gd b/Scripts/Network.gd
new file mode 100644
index 0000000..d0882c4
--- /dev/null
+++ b/Scripts/Network.gd
@@ -0,0 +1,61 @@
+extends Node
+
+func fetch_image(url: String) -> ImageTexture:
+ var http_request = HTTPRequest.new()
+ add_child(http_request)
+
+ var error = http_request.request(url)
+ if error != OK:
+ print("Error making HTTP request: ", error)
+ http_request.queue_free()
+ return null
+
+ var response = await http_request.request_completed
+
+ var result = response[0] # HTTPClient.Result
+ var response_code = response[1] # int
+ var headers = response[2] # PackedStringArray
+ var body = response[3] # PackedByteArray
+
+ http_request.queue_free()
+
+ if result != HTTPRequest.RESULT_SUCCESS or response_code != 200:
+ print("Failed to fetch image. Result: ", result, " Response code: ", response_code)
+ return null
+
+ # Get content type from headers
+ var content_type = ""
+ for header in headers:
+ if header.to_lower().begins_with("content-type:"):
+ content_type = header.split(":")[1].strip_edges().to_lower()
+ break
+
+ var image: Image = Image.new()
+ var load_error
+
+ # Load image based on content type
+ if content_type.contains("png") or url.to_lower().ends_with(".png"):
+ load_error = image.load_png_from_buffer(body)
+ elif content_type.contains("jpeg") or content_type.contains("jpg") or url.to_lower().ends_with(".jpg") or url.to_lower().ends_with(".jpeg"):
+ load_error = image.load_jpg_from_buffer(body)
+ elif content_type.contains("webp") or url.to_lower().ends_with(".webp"):
+ load_error = image.load_webp_from_buffer(body)
+ elif content_type.contains("bmp"):
+ load_error = image.load_bmp_from_buffer(body)
+ elif content_type.contains("tga"):
+ load_error = image.load_tga_from_buffer(body)
+ else:
+ print("Unknown or missing content-type. Attempting bruteforce converting across PNG, JPG and WebP...")
+ load_error = image.load_png_from_buffer(body)
+ if load_error != OK:
+ load_error = image.load_jpg_from_buffer(body)
+ if load_error != OK:
+ load_error = image.load_webp_from_buffer(body)
+
+ if load_error != OK:
+ print("Failed to load image from buffer. Content-Type: ", content_type, " Error: ", load_error)
+ return null
+
+ var texture = ImageTexture.create_from_image(image)
+
+ return texture
diff --git a/Scripts/Network.gd.uid b/Scripts/Network.gd.uid
new file mode 100644
index 0000000..44bfee9
--- /dev/null
+++ b/Scripts/Network.gd.uid
@@ -0,0 +1 @@
+uid://bbfpng3opsnyp
diff --git a/Scripts/Tab.gd b/Scripts/Tab.gd
index 4e9ba1d..49ebbd2 100644
--- a/Scripts/Tab.gd
+++ b/Scripts/Tab.gd
@@ -7,6 +7,7 @@ signal tab_closed
@onready var gradient_texture: TextureRect = $GradientTexture
@onready var button: Button = $Button
@onready var close_button: Button = $CloseButton
+@onready var icon: TextureRect = $Icon
const TAB_GRADIENT: GradientTexture2D = preload("res://Scenes/Styles/TabGradient.tres")
const TAB_GRADIENT_DEFAULT: GradientTexture2D = preload("res://Scenes/Styles/TabGradientDefault.tres")
@@ -36,6 +37,13 @@ func _process(_delta):
else:
close_button.add_theme_stylebox_override("normal", CLOSE_BUTTON_NORMAL)
+func set_title(title: String) -> void:
+ button.text = title
+
+func set_icon(new_icon: Texture) -> void:
+ icon.texture = new_icon
+ icon.rotation = 0
+
func _on_button_mouse_entered() -> void:
mouse_over_tab = true
if is_active: return
diff --git a/Scripts/TabContainer.gd b/Scripts/TabContainer.gd
index 876461a..82f388f 100644
--- a/Scripts/TabContainer.gd
+++ b/Scripts/TabContainer.gd
@@ -1,8 +1,11 @@
+class_name TabManager
extends HFlowContainer
var tabs: Array[Tab] = []
var active_tab := 0
+@onready var main: Main = $"../.."
+
const TAB = preload("res://Scenes/Tab.tscn")
const TAB_NORMAL: StyleBoxFlat = preload("res://Scenes/Styles/TabNormal.tres")
@@ -79,6 +82,9 @@ func create_tab() -> void:
h_box_container.add_child(tab)
set_active_tab(index)
+
+ # WARNING: temporary
+ main.render()
func _input(event: InputEvent) -> void:
if Input.is_action_just_pressed("NewTab"):
diff --git a/Scripts/Tags/bold.gd b/Scripts/Tags/bold.gd
new file mode 100644
index 0000000..b7c7403
--- /dev/null
+++ b/Scripts/Tags/bold.gd
@@ -0,0 +1,5 @@
+extends VBoxContainer
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ var label: RichTextLabel = $RichTextLabel
+ label.text = "[font_size=24][b]%s[/b][/font_size]" % element.get_collapsed_text()
diff --git a/Scripts/Tags/bold.gd.uid b/Scripts/Tags/bold.gd.uid
new file mode 100644
index 0000000..9fb8059
--- /dev/null
+++ b/Scripts/Tags/bold.gd.uid
@@ -0,0 +1 @@
+uid://chdftsciuecfk
diff --git a/Scripts/Tags/br.gd b/Scripts/Tags/br.gd
new file mode 100644
index 0000000..74b39c1
--- /dev/null
+++ b/Scripts/Tags/br.gd
@@ -0,0 +1,4 @@
+extends Control
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ custom_minimum_size.y = 24
diff --git a/Scripts/Tags/br.gd.uid b/Scripts/Tags/br.gd.uid
new file mode 100644
index 0000000..f137bb5
--- /dev/null
+++ b/Scripts/Tags/br.gd.uid
@@ -0,0 +1 @@
+uid://csd2kcqixac65
diff --git a/Scripts/Tags/code.gd b/Scripts/Tags/code.gd
new file mode 100644
index 0000000..670d888
--- /dev/null
+++ b/Scripts/Tags/code.gd
@@ -0,0 +1,5 @@
+extends VBoxContainer
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ var label: RichTextLabel = $RichTextLabel
+ label.text = "[font_size=20][code]%s[/code][/font_size]" % element.get_collapsed_text()
diff --git a/Scripts/Tags/code.gd.uid b/Scripts/Tags/code.gd.uid
new file mode 100644
index 0000000..2d000d1
--- /dev/null
+++ b/Scripts/Tags/code.gd.uid
@@ -0,0 +1 @@
+uid://c3dnmqsnj0akr
diff --git a/Scripts/Tags/img.gd b/Scripts/Tags/img.gd
new file mode 100644
index 0000000..f89b735
--- /dev/null
+++ b/Scripts/Tags/img.gd
@@ -0,0 +1,11 @@
+extends TextureRect
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ var src = element.get_attribute("src")
+ if !src: return print("Ignoring tag without \"src\" attribute.")
+
+ texture = await Network.fetch_image(src)
+
+ var texture_size = texture.get_size()
+ custom_minimum_size = texture_size
+ size = texture_size
diff --git a/Scripts/Tags/img.gd.uid b/Scripts/Tags/img.gd.uid
new file mode 100644
index 0000000..2a7471f
--- /dev/null
+++ b/Scripts/Tags/img.gd.uid
@@ -0,0 +1 @@
+uid://dgakysfyq773t
diff --git a/Scripts/Tags/italic.gd b/Scripts/Tags/italic.gd
new file mode 100644
index 0000000..68f5577
--- /dev/null
+++ b/Scripts/Tags/italic.gd
@@ -0,0 +1,5 @@
+extends VBoxContainer
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ var label: RichTextLabel = $RichTextLabel
+ label.text = "[font_size=24][i]%s[/i][/font_size]" % element.get_collapsed_text()
diff --git a/Scripts/Tags/italic.gd.uid b/Scripts/Tags/italic.gd.uid
new file mode 100644
index 0000000..ca360bd
--- /dev/null
+++ b/Scripts/Tags/italic.gd.uid
@@ -0,0 +1 @@
+uid://bamty87whxwxi
diff --git a/Scripts/Tags/mark.gd b/Scripts/Tags/mark.gd
new file mode 100644
index 0000000..c6e3e1c
--- /dev/null
+++ b/Scripts/Tags/mark.gd
@@ -0,0 +1,5 @@
+extends VBoxContainer
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ var label: RichTextLabel = $RichTextLabel
+ label.text = "[font_size=24][bgcolor=#FFFF00]%s[/bgcolor][/font_size]" % element.get_collapsed_text()
diff --git a/Scripts/Tags/mark.gd.uid b/Scripts/Tags/mark.gd.uid
new file mode 100644
index 0000000..57a6073
--- /dev/null
+++ b/Scripts/Tags/mark.gd.uid
@@ -0,0 +1 @@
+uid://c2i8dwyyuufff
diff --git a/Scripts/Tags/p.gd b/Scripts/Tags/p.gd
new file mode 100644
index 0000000..1b83ded
--- /dev/null
+++ b/Scripts/Tags/p.gd
@@ -0,0 +1,5 @@
+extends Control
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ var label: RichTextLabel = $RichTextLabel
+ label.text = "[font_size=24]%s[/font_size]" % element.get_collapsed_text()
diff --git a/Scripts/Tags/p.gd.uid b/Scripts/Tags/p.gd.uid
new file mode 100644
index 0000000..31a189f
--- /dev/null
+++ b/Scripts/Tags/p.gd.uid
@@ -0,0 +1 @@
+uid://cg6kjvlx3an1j
diff --git a/Scripts/Tags/pre.gd b/Scripts/Tags/pre.gd
new file mode 100644
index 0000000..9da741e
--- /dev/null
+++ b/Scripts/Tags/pre.gd
@@ -0,0 +1,5 @@
+extends VBoxContainer
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ var label: RichTextLabel = $RichTextLabel
+ label.text = "[font_size=20][code]%s[/code][/font_size]" % element.get_preserved_text()
diff --git a/Scripts/Tags/pre.gd.uid b/Scripts/Tags/pre.gd.uid
new file mode 100644
index 0000000..da86787
--- /dev/null
+++ b/Scripts/Tags/pre.gd.uid
@@ -0,0 +1 @@
+uid://8mam5rvtx72x
diff --git a/Scripts/Tags/separator.gd b/Scripts/Tags/separator.gd
new file mode 100644
index 0000000..b2da732
--- /dev/null
+++ b/Scripts/Tags/separator.gd
@@ -0,0 +1,26 @@
+extends Control
+
+var separator_node: Separator
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ var direction = element.get_attribute("direction")
+
+ if direction == "vertical":
+ separator_node = VSeparator.new()
+ separator_node.size_flags_vertical = Control.SIZE_EXPAND_FILL
+ separator_node.custom_minimum_size.x = 2
+ separator_node.layout_mode = 1
+ separator_node.anchors_preset = Control.PRESET_LEFT_WIDE
+ else:
+ separator_node = HSeparator.new()
+ separator_node.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ separator_node.custom_minimum_size.y = 2
+ separator_node.layout_mode = 1
+ separator_node.anchors_preset = Control.PRESET_FULL_RECT
+
+ add_child(separator_node)
+
+ # Make the parent control also expand to fill available space
+ size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ if direction == "vertical":
+ size_flags_vertical = Control.SIZE_EXPAND_FILL
diff --git a/Scripts/Tags/separator.gd.uid b/Scripts/Tags/separator.gd.uid
new file mode 100644
index 0000000..892cffe
--- /dev/null
+++ b/Scripts/Tags/separator.gd.uid
@@ -0,0 +1 @@
+uid://rol353cupbbf
diff --git a/Scripts/Tags/small.gd b/Scripts/Tags/small.gd
new file mode 100644
index 0000000..4dd1ad4
--- /dev/null
+++ b/Scripts/Tags/small.gd
@@ -0,0 +1,5 @@
+extends VBoxContainer
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ var label: RichTextLabel = $RichTextLabel
+ label.text = "[font_size=18]%s[/font_size]" % element.get_collapsed_text()
diff --git a/Scripts/Tags/small.gd.uid b/Scripts/Tags/small.gd.uid
new file mode 100644
index 0000000..74fc901
--- /dev/null
+++ b/Scripts/Tags/small.gd.uid
@@ -0,0 +1 @@
+uid://xr7n1lat501x
diff --git a/Scripts/Tags/underline.gd b/Scripts/Tags/underline.gd
new file mode 100644
index 0000000..e3726ea
--- /dev/null
+++ b/Scripts/Tags/underline.gd
@@ -0,0 +1,5 @@
+extends VBoxContainer
+
+func init(element: HTMLParser.HTMLElement) -> void:
+ var label: RichTextLabel = $RichTextLabel
+ label.text = "[font_size=24][u]%s[/u][/font_size]" % element.get_collapsed_text()
diff --git a/Scripts/Tags/underline.gd.uid b/Scripts/Tags/underline.gd.uid
new file mode 100644
index 0000000..9e71dc7
--- /dev/null
+++ b/Scripts/Tags/underline.gd.uid
@@ -0,0 +1 @@
+uid://x0hphtm8kf12
diff --git a/Scripts/main.gd b/Scripts/main.gd
index 3f605f0..e050d00 100644
--- a/Scripts/main.gd
+++ b/Scripts/main.gd
@@ -1,12 +1,32 @@
+class_name Main
extends Control
-func _ready():
- render()
+@onready var website_container: Control = %WebsiteContainer
+@onready var tab_container: TabManager = $VBoxContainer/TabContainer
+const LOADER_CIRCLE = preload("res://Assets/Icons/loader-circle.svg")
+
+var loading_tween: Tween
+
+const P = preload("res://Scenes/Tags/p.tscn")
+const IMG = preload("res://Scenes/Tags/img.tscn")
+const SEPARATOR = preload("res://Scenes/Tags/separator.tscn")
+const BOLD = preload("res://Scenes/Tags/bold.tscn")
+const ITALIC = preload("res://Scenes/Tags/italic.tscn")
+const UNDERLINE = preload("res://Scenes/Tags/underline.tscn")
+const SMALL = preload("res://Scenes/Tags/small.tscn")
+const MARK = preload("res://Scenes/Tags/mark.tscn")
+const CODE = preload("res://Scenes/Tags/code.tscn")
+const PRE = preload("res://Scenes/Tags/pre.tscn")
+const BR = preload("res://Scenes/Tags/br.tscn")
func render():
+ # Clear existing content
+ for child in website_container.get_children():
+ child.queue_free()
+
var html_bytes = "
Hey there! this is a test
+ This is bold + This is italic + This is underline + this is small + this is marked +this is code
+
+ +Text in a pre element +is displayed in a fixed-width +font, and it preserves +both spaces and +line breaks +- +
+
+
(zz zvw<{oJJcv6!EqP?2Hgz*t*A zU1l+=QH6=A8SQes31v7-AQT$HXY=n_g(z#2PvUzqzJnJOw#gUShnP4C&3#l1Vzlz& z(;~#Mv!M?SI~xOLg<~uMW$f}@lF}#2D)+^N(8VTCiITj1VyK7I##af%vC524gFrLA z3K~gqE@r=>K=pVax9lJFa+7yss!i0(tv_%E%PU5 2|Ud|y{=g>1VU zvR-a%(Z*=VEi~meCG~U}YauDQA}6ARB!?j5&0S<8M2^-nqTP>%8`jW Z)>C9O&5%jb7ufL;Bp=S7 zRkj$c#TE{YQtZ|j$%?U*5H?CbRzDnsI%?bG@g;Wo1f+`=Rnpe8hQqN*U+AbO74xkU zd)^UeLr+J^l~zJp`aZys8wCNkEcFXGL*fFC(FqvC z+PPMc*$#6!sxswnhfdpEZTBD#jQ(n)j&Pj4M)R~QxgqB%`jdk+XdGj&0S39t2%h5Z zSExh0ff$*8f%c!@KFT=}Z YeumoTVTF{yz!-;7#)7Ax7e1H1>zf{oK0zCQ#i6zbc>mz3HNb|?mQ6+ zv2=&PQ_?r&CL2LEb0PUzq#XF!bWAQZhuFvDX`LVb+%vm~KjD6ofkOHlx8CWm7t$ z;Yx{YlrEvtW@hitQ>9W;h2wUby*ZADs^YK-9P+4AYBqGJ<17SC&nc?3%jaMxu`=-N zC!|4DB(*sbwRTf3pD#UJflRq)Ab-$YqSCzoR-)PcGv)GzkJmN4PJUPHUk85>`Xl<+ z@2H(k?#=txs+Ix$YY~#@P9|ud=wHb@c>k)UWkkz^b^Yt1w`%TR?H>;6Ul(a=7X7Q` zEYZJS7|Q!s>=qij0{hqZD5CFQe@52OzxrIUe_1Yjy}tf6JIdF;@;d7K*P8FI*1s0q z44FCZ3g} $zq1SoqqmY!h&(Vso>_Q__=&i@gMxsyt z*?|g96XRTu@9>>3M$4QxViv(5CuZKd;JbQxiS-)BqtmAPmID2x^6O@SOep=IAc$r4 z;!0oATqym`7-~Sm=SYI&W>5(sPl=`@S7d!HBYJ+CPU%OyUbE77gWv-u6(iYCLg{bG z5la8^V_e7`!E3P6??Ms1($~JR2Bly9NR>$?#?wWeR8E_sECuX!G`~;t=ZM}zGm8?h z*Zd8eG>Mlw)tN; SLicY|>7vF{rx-LKtmZr7P_gkruE?;P zNRj_pkLpdRcz`m;7ed^~d PX`Ed} D_BXR~h`H5XV zW>v!D(9W}g#4i77b0xoYA4#YZ3KIvy?7TgZ#(Ef8^@s6tE%FeW8=Z>sEOC*ru= zfTA*0{?#V`0 x3yk)$O#;T(`;f$Nx)LSC_{zScks &*KH^mFuuNj12ru- z+Bav3@wMASq!PyOKwj|pI(2&B`1*mdhVk{};H!?WJum4ji%vMEin)=-*N#}C_$~KQ z>-}=CethlO7=mloJz#uoi9ED$7g*tBS(Mcwj*=f9L_zfF?P7c_OCTvGUy24i#l`q~ z2r>Qms kIKEbJ+|v?dPkehvb@s&45OM|k{oP#)1JlC)?J`OvNWatj7LvEm z-+hLR3OFNt{_fU)C#AcRzuQ11T*-Iaf!38^=0W5*1XcarmOnz!yn6pOcrG9|tEZ d n|~dHMU1vwvO8ZI{i33_iFl4N+n#$4LBzW z^#wyo2y|_u>PIw~s-hpW*VIT)eRg{QJv#k(glhHiIj{?fF?kLaf9NkR9z-rfpre7k zdM;2uG=CxAM{^nD1syhJYOEc4GqK$2?O*O3Yt7kM4u@T=&6QaJ1+ke@E37%a4GxRl zH6{WUk*5jvtE|Q0acDcTXRO$@v-j*grL9%z6-Rd2VfI!CA3XPR!$mkh{*G0SH_B5i zw8u4vL};A8nj{fM;}rpR@!PNJcy=3WgB5hZcy>R5>ie(XL#mA}T=>3hcPy_gc?32_ zAgkd#h?EiNWEBLGem11K{YMxV9qW;C;b;os#~=!X_Yo6f6l?b^*Nocuz&3WGIn}XC za JQr`B~+4kc?U)iCEAW> !tNi>w!})JQ9BjPJ$G^8O=l^X#{~?0^{(}GSRQ>@0 z{`a6Xn}c}G{A1zg=O47|_;+yr-`_$s6~gK4mq8VOV$Je6sa(4}K&>VZ!RAwty{Zq5 zGle{eqvf~y<#8jIM=sb9`Y;4%)WP`$8<)qt%|ag20YUOWX-4rH<>9dC _siqR z6fTbi-~1(gI0^4^Rewjd`p^&5sr)Ajwq(?$@jsRG-<~*F-qFXuNfdk)WUKspdASSy z1pk{<{s960-8T^bh}X oG* z#PuSyhT3xF9k}c}2^ww_G^7R6z tth~y6u?61oYwsTmmlGc~^p8I0 z^!f ^L<$-b0%>4PP lw-L}3uTdXTvH9ZDhX&xwuMc01=lYO!nrQl$`^RT+=wFL| zQ2zk6TK_;4@~~3#2zl(}y*0T#arAUszdS_2Y_K8ZaWj^s(1@=sTpk1033=QF2 VZL?Ms+migqdk@wc*_QcU> zc=R;=5C!wVhLA@+EK9-p2dP{hDQks1Ist;@5e8_A*C>y;WSu-tKd+a^{3p0Pj(+u* z#*4Rr<68I^^Xb?xh>se^i-y1J`zOYWyMg=4^Jy%Va3znx?hC{@oClFIf~w=iDBOkA z*}H F^~p!{CG9vMW|mN5CsD( zz61`@KbG^}n%o{A*dWxP>4PXp+f70rDzOlR1YW(H>qD19p$|6;n%p6Prg)9|& mP_h9z~=sLLQ5FZ%uAb9QAGGmxm}g zm88zc&y!f*K^`xdxjbUm2zk^41oaOCpebIXJi_nP$z$6Ly*wOaxjfQ9(_ffRrvt~e z@GtaHT0(r(&_B-nrq@UGkJi9_<^Exy67c^e5&H>d9z>2qP_=(pj#kq@3O=im9{B$P z=+X6$7s(m!>mS)Ix$IXbavE0gAo3^z9SyAbNHzV#%Uun$9#2G+IyiM#p%1S-&N*w3 z53D b%h$pq+vi}Sl6QJQ!9z_0xKt}`n`cO6caM`a9hypkS zvRARr;=MDuJwC8@s6o>QQP4r0a(&oR&h=qTGS>&gH$opyHYa?^?mq!d@f!8v2(~qR z`tZdxy*@lRlIz0)bm6}+J`4elYuAVPkBN^O^kKU@NFPFh`^x%ICcIj$!4<^WiU*Na z1iH3R1>E+RYV={@M>Wz@pY;i#N2d>uQ?0)7Vc1Pv_HSY11T?(KgUAgCbTqIJ$^!I( z?;k$M?<`p53u0sc!4H9eUt8D>M_NxHSThN3OggAihgXP=C1ZPTffh!QYtl6>f~~oe zc2uX}ocjg#CE^m_?1tYNaD8Hm`@|w<;HUih#GC5(NyPsWM2by3lyDg%`1lxRlQV|d z q_ZEKYgIpWA>bT5i}*(#z+ zF+ROmaM#na+nFxTYvDr0W8xGGRQE1mVYfBoivJPzk=r2+ {eFaR zKYE}|wwK!FjaGT9Ro-Eh&q?wn)(k_TRdEipDrs<`Z;<%*`yUp$+$!%er+J;FtOCTK zpFpkXh$_hN9qkqVS*u(k$v;Xmyzf(oNy _K=Avze_IFZyH+wHh-LRA5D9YXN1l&$0$7gz&MXI3Hm zkiIC!5$_9@ds<4JqpF@^gl0#8OV*?b^$JsNEhx9mm2l!bi6-Gba7#ND+t@e1^1ksP zuP*wxuc&XFXZspcvE+>?&ExK3Y~Qe-k;{kcs`{>-7n8`7uNXJHCy2u#2BlU~g( _oe4Fuehk(3;?>jH>|-n+%LIHutI(I$_)=_{2hl @mIk-@%t4`Om$>FaI3GHF Rmwy)Z9MNPt`8VNmKgHHieUMlaetPUUTY_|u{F@_-wsN`rP5gTm`42`VI{9y+ zgIzAje;A4*GM_y}aGLyYc;^c8-`DUe^3TKpYdTuK{-3@MV9u!so7~7;Tq_I`F&FoZ zAj!DzM~AS`-qv?k`7(}k#S~C>YKKBe84w|LG)YB&gjv7+_#^RWGcEZgHK}Ymp&`Zg zp}7%gB-xoQ$qO>6hs&->2*6c78~(FsPBs`3oE3LGCMmb$%WO7Ae94E ~4sGlw;)qPJcf8oFa 6=TKQ z{ *S`fIg8O&!%iJ{G6_6kUmi&s-idADO#->U0*Yfi5? zLyBp^MmknUBKcy!5Z^^e)f0s~5d1wSbFn3Yz^wd4CWilxoIT^WmsIS}#YM0l0zD}V zN8g&z<3j-c`&Im}5&p&!S1%%-4sTH{1WgC3BG_!94vTRraVf?txybC@Nw-rpN*5C* zB?}FCfZ2!~P@hULO4ed=UUAl;FmhhdsY*aa&Y*P%KUIX|f{RfPDcDjr5QoYj&JW)b z;?xGXM12E28^s%_ian*xFPLxF>D%Tp6&VJ)Dvd%i#E_2R{}ek5eyvJsT!ez_OnmIe z`BmZ*XQ-d#=K-;1Lhp#|$!VViW9Fb2{A8);M&J9z$6+B#y~!J!&SCowL}E%~6X>j# zVk~~s&tZ2A;W0W6F{}R0_j?jV5ZU+^82e`+BlWz<${lF0S?nnj89e^`Jwf*VNVN*t zLiT?2`EG{iYMBiOAmXK?{@|zrDY;6OG@(-d~6KU$pl#X=IeE+WVQjLe==cNllQd zv73>Az5n(}pS}MQqUh}0-Y+L|guUOkix}yDAgUDOtT!|PR&Ve32NsrG&u8y SG((%8;{PwU z_ix#CHG3b1!M|YdH^4b_&ED@0y$H7VTMNZe?R}|k_4dAM-;8=qC`dK-O>e$CqS-h5 z`J^W7n-nq5srKbsd OV+-@bXXwhu&S z-}FFP8k7!FebCn)MhcI!tw;yiH@%SMvu`@{?^W!ZOjM$?Z`>dgW851o8^sZs&!!Tb zX5ZZM53O%iV_#mn;VSc^X5SoH=xc!gDf?z721>A3z%mgDuy0-vU-G$q^BVLS#b&d= z?WD*R?3;lA)7dw}2@q4=!+^V*ee)CHz6Sf|Q zX1ED zXPv9GpCs&?h59)(M#YHEWUkr1x$_LwE9{%)AO-dfb%7e~n{C^L_?n??pnXGNs(rJV zP2=nt_n%g=lR@&3K!0WXX0nQ(&zD!UZx;L1A&u5!ntcQH5SCa8VN$Yi<>UZ+lE^`$ zk0cnfd0;m;V~h6qW`96MzI~R6RcHTva6<~Vm`!>d{Y^1$S`gSk0Sma-YG2vDi4U@G zo>P%s!M-V^p=A9yy?uirt}@WR!Nn3`-#p4`_uDt>jg$4eeH<2m!&SVoRSvmV5F8e= zIj9939-r^$knEfIK>MaX-)~9~L1cHN^!Cl(@3?*QH>_i>VBh4bRS5g$3G8wB?3<)f z)I?<8JVc8uoqcnvEsfv8zB!EeU$k#3Xk-kuZ)nNJ7V-)YuI7oJYJ%H0cOe1$X3bHb zee(&Tntc=1j)rx91>MqKjP$<|Rf=)Z-!%bNZ{JJ+7M5=G**AlbhJBL(n~>&<_In@! zS8_ffb44e;E9{&0D39E31WR#Y-*iAM$X?-wOipF!)Yxi0oA^>dtePzF6Y}$!et%}@ z)Nz6S%;(~W2G}=K5YgK=8J97=UctUuhy63ZeUorXpL!KNUsyYrsc%)Wc7piv`8UH; zK>G@Mkr|eo&(&GQKJxhwtMzx@vgK;_PbQ=Tt^bSu&gXHX+h_kkZ>rcoLa{XaC#-t= zCtmnFNBvDG5QYWlg$ *`K652{8hO{GA1W3G{a^ zYE2zU_&Z-iJjmbq!X w^LKW` zmmqtzWh-h1;qPpSxMp8svLTTfE)s<1@1!oPvqwpuT6w=c8cDsfiofjxF7i`s0M!S? z9{@4gqrH(1vPVCO)!CzOBT 5IYM-rJ0M`X ze8O-=duHYd@-Eor?`?{myl(wfTx7}QRD_e)jsLQPx!4>*@^Qn%se0XPa8U7KF1162 zmEP;=7{Og`t8^|mcWM$NmmAc8Ty83kcWC(|^M{!vdD%d6x5*3Wjv;zjHk6F9O`PF{ z?4XD&Wjhh!uQe c6eO3N zDR%+KF(pC={R%;gr;W&w`#~Uvg#tsOzz}N3l%zOgp3a1CFG_N~$(?O5dG6y##=`}4 ziY%cKKth(#BQ#%+GrKI8t9bW_*?l_lTo#=Nkm|68bw{sXNILZ;FSm*l;r+pyu|e|y z@-n 9VX&fQiPlpA!mil*)Eq+d$SY>f^46H%_Jc&TZ$0+mCZh&h+<56 z$*)=T?hNUQ&Qf9ZD#QH#75+Y1&WQl~n4Eu?6kpHw8^ d*8~< z+yS@%6kN>#_<4yC@E?$Spn)9V0K5gLI9jrdlLg)@TgHP`#QB8yik9&ll#tiqo-Myw z$@LXfQ%`|w3=Tcju^7c2i(+@=6#D~f1QNShhn@)19E$`l@C`r-G>Ff!xW}88uXijC zAVO8c`wW$Zx_LyN>R7yOi_a`2$6`A-HHK=I`W=fG&JiBtz!&}PU1jH_)t_Mj_NLn2 z!T!X$Dvm4I+Zf4DvG>kWtH7UVRUV9sQX+6WI25cFRx!NcKNN=dA*hF>_ziE>vDohi zABTnDFqN08;#iCp98Qq^99H94T!`HvOm-rOT!ob0@E%^s4eyvsVTP*yD|(#|Zy@^4 z6NIZZ3H#fFZ4aOQz2aeNDYCzJ(c(mBe@|>i^Odl_GZ6oa_V;cYy{oamV; M-4`Nhrf1lg~JK*O( z!ss9kohR6dGz5DXMj4+Ue*i(Q KW^vcu55ppc$vR!e =p+D>~@9 zLf$0cXV7?o_D6t&ZZAIj?2lDQ0PmIUkKJno;#fj_Mf;;3q4V1xq_0=EKb`@4nu3dH zK2y ~d1UTRLER*cCkV#p`1^E&Z*~S$ z yN?(@+#%H61F3W zA!;|RS*GHw9n6;~@M=>MCFM~pgN&0YC11e9fH<5fZ!~*%k>z#^&Z@Cp%b*iTv;dx- zRG};St2GGZ;;x(6+TStl%j-O$UH3uPcC#CRoF^3Hni-n7%AEDYw27@?@$}Z;2+Wn7 z3bNP~#OaJy8df~$$nnTSO|RU@34+t0$p+N#O6Ko-x}vRf$=*26dI$`mgn{Dj#sDXO z9hm=ZE4PS3(_yA1mm$GSybi}nq$6-|h8<4gIM?G_y1SwrZQ{Eh0{CTm_{9Xj6-6Kd zf-fQXcLn@Q9KIkJK1&ZjiQwn@;TPf_6Uz|r4|4d-V0eojK9S%D_~8fRUKnd5;G1*! z#9;VHJ-mV7O@8=z+%sf{6FL7!ws8JW1@ZqAva$XV@+(1tZAB54{|bVCSHOS5;R}M{ z-_*m;Blx*~_>vOhU%)#!d}c8GC_VgOf*;_AUx<6etc`&0#o-f!;cwH!(>s97 -B zU%=1j@R`Bzd3yLvf*;_A-@S$S7x0g9_{3m%yB Pm8D7R^V) gI6u0B4bp j z*PVwPqAI}`2+Z1R?_Zpy(n_&U(>7- z Kv!mQZuNc!%%Z8?7!pX>Pzxr;P@Yk)s`R=`IE!-oN$jHj!>zpuiVqOP2E;r{wV zpBw!REyb?_KT3tCQ@J_oLN$0#2R!j7gp%js55%DLD_IY !|oR?|96R2FZ^{n)&%ce@D&tyUJ^&kL=L-+o5px7hQB<$ z${l7nZMwy>@U&@&ar0S9JW^ V-qB@xw|;w{;X*1Ld9RfffyUADLo zS&D^kAKlRL1Ue+#_@+F#3^cvOQ9bDIL8xWm_=k>jYshY^Vv;iIz#mLwPli2S3MsO> zdd;zBIJ@BRXDEAxg&Dl-%stcZcy0^dAXtwl!`&;ODAtTL6gd>C*x$?f!|TZM(Fxj8 zV$sNQTDEC6&R-kkO&Go4%2{g4{Thtfl#~i y$My|P#-L&t#BN{q8o_4sg)n29-Aw2F|r=Vf3Q4V zhH%3`gs&rOAiMW73?Vt|W5Eh;Ii653dk}%pt) DeTgSr~Sp yGD^QNcIyQiW*1 zE6fpG2kD?h3zmg8fZfyx%}R<%D+w?*aXX0|)^Q=T0b#1b=M4 H!klr|I zk-pG$$5qIkiNVE8V=Wr#g6Ob^QXvB+%+p@WS3B}% tr)A3f6(v&fG~~?nG`Z_GAW~%pO7U!@O3^@6 zhG)|~tAYCkUPXE#ElFoDr`AfYC2GBqYVF2r-J{m}HPwoOrw)Wbr=#%AJ(Uz&WmskG z_dX#8_hlMoUCBqiwE9R`!-L2p2v&{+n2N6l@CjgdXKF=P@<42Xp?o?IBA-V9LxQ)2 z3K9+w_dD pQVpi?!10%Xjfr8g)Kg6rp!OPq3!wtmve9pHZfA6P?IyOx%Pl zqlHyE?5Kn6+*e_ABB0np`e49IUNQ8}=Ltek1`C3(>Yjp~17+SVj_jNPG>pB;$l^ z t$>g0n^(gtocwSPcsPS1@Y}^ z@$Dn}wgBIRRHz#h68EviRs4&R(l<75TV_XGjDiw$lai#0>FsD-Qy;XKlwSPputy}h zCp-To*dHimYz|ayP<$V@HEgcvVVsQQF@hR)nKC0SL=6o$G|mh(-_K5c2t5H!S{14z zH+a46TVI>yE!Ys?Cl2mZoyJgtJ#+%qm3D-cqpQ+YLQX$_p)wV(wBG_3F>=}#Tgs@d zgo#(ird;4pe|Ayp_M|CUM?AL_TlV`4?PvW(A^e^Ix5v8{dTv*;$~<98)_%4Yh8hIk z3cP^`BZ8p5H}iuKLjfs2Sk#u;{Jj_MujTt2v795^Y~xJHyI9uO)N?G@(mBqGQbP?e zw2Lh}h$M|N{5lcm7Y_it()P1IkNS9i5Xytem3Z!sBH%ez1L9`wem3Jg=Na$fb9Oxa zg1!$G-*5D@+le^cUBNl+fu;qgHz5e(^wmXvPN87xJxJgB-S3~qekP9VXl-chJW&iw z;L@gy!Q*(CJ>LMYba|ixb}6j_@K~NLuH2OO9O5=PYhkMF`~)xIl}k#WSet8X1zH;~ z=P_$emcihV>@Fvs&hvVjYxbYD7 xm8(Qbe2q2V!M zAU0aaGj{Qd5bF5NFj(Xh0_x(8m+*@17*6s%RusMqn_%z)F6B*lk#+x)P$akExd|U$ zgv7JZZzNe8Vbk6xJvqo+sLQ vYDTg$fLjDx%@@} zdBvtJq1@yw >P+?GyQDT=wsseV7uZUK)U;n9{Dyu89dpQ1F^4P> zYD06#QjGkIH~Z!g#d!D$t)X^1O?)6t@%2RZ)z5l=N{#*TZ50PC??K71lu$kqK907q zDH+$)Kl9N)zxuE0pKCq~?w`vx>HFuBp1gm4h5niE>z~|AjYg--PQ1rSy^h+NOEmvu zj_!6cQ$3y0C_iHp4UJ;uL1ZGejSIZ04O8^bpuPoXHt+WZm_4C*P&(eX>fq%}wQsGa zFIwLU5!6%Psx0yKEybAhxYkmo&U>qNDfPimkaw3L@1yfXWuyfuo69&8!OC1t zRxbQ0Q51ZN3|6}<6F;j_IDG=|Zx~7KN?e?^=y-TPrB^R&(p`>T16;TE63W@&Q!d^5 zR>eZ(-pE;|tqHnHMt>M~t#TIR<8>I>S7?hfW>Zw(h% wA=nYkkXl&+jOav~De)d8L8e6BKGT9iL?U!{Ef72-MEM*K zA{UViQ~WKx>uu}=Z1BxjkXLNp`OK#B? 1YC44?D)f?B*~P|baPs-N&1(E{n~Xg4Bo{~ 3n D=bJ?b{7_2c+rfd4cn} zt!GbDPJ6;6ru1LfOCND9ghzl+>1J;lUWV(s4a oe!pvX%<;RcKNcWDc%EajySysY**SzIqP84 zJQ-IpWipO=HK(q1fXN?n5&VRn+*~zlrmyG2=2~=Pm^GPjHQSW&rCkfPuIa{73{7<2 z@suQ2S`~ECoMKG%8|!1UXLACLX>eLR!YM40a*CqxgOi>~n1xF5d!hx7E@HfgR}>Ib z#WuD;1HuxLGzul6;Ix3+MA+qaU|9xR?jOJiYN`*K8fgIC{I%dW&XB;PDJfV<5gI#W zYlfC=f|e9XN|Y_>qREwmPpPuE1Gzn<3p?RalX8xSIc~MerB*1hHKatka1g&FD*Tz& zVnPM+ZL;E^kS%Ge^EX?E%~DQf*yLo`bW(?%@CJoTAwPo6F7V$<#pY51Kv<@R U?heGOfe#eoQu>-Gayw>81gzap(XHmaQrYiQIr)yWH`o- zm19xXy@8%)b|p6zpG6RPlu*4$pBIVG7qO3tnnVz}kv@|)x?jNO!12R3UJN8R_5||e zyQFf_`AW(qZyhHVd3ZIUw#|jPB9H9ra%;|A2FLw&*L3v9Bj}H}u0?;0rv3=uI>{4F zTnt@oH{~{~(wh|VC^LM(6>&c ^>FB;ry1XtAY)fQkF1FTr_j~0 z&{2rR@g#OJXjP%=sZGv=1JLW}MLv@znAW0F+ltw(9ZkPcR_|6vEPVa_io@HH%=#(M zwdJ$nj(&2lcI=(^u%?Ei4(7>0mIk+oO}^dCCu#Rn!s%fWEgZx5StE}iAg4#1U!6?< zfYT!tg$cd*Q} Xs1>F!K?4A_57(8I?Q`~W|^ z^giu>3HZ7kJ~0^n^5?qx%aLFvKYYw0+W&&T6ZP-FH|+mz3#xyE9=?F!x1tEzfcAfP z6a2dZ{tXUa5Df3q!)FuxTtEEc#l*jWAIae}gW=Qk@Djlf@WW?*Nc;= hJJ3Q4bby8 zehfBsmK$fO{CrL@u4LZ84O)ljgb+SW4|e`#4mMQ<`;NdA<1l~q&PG6EC9$X!xYxBJ z>bKGymE4jVupZ)MR(#7nz%9a%2bP;-5kmsm@eWr9`zZ>dk3C6TA7DGSaQK6t0iNRS z8Nz+Mkr1vz1|j6XsN`z#u0S|ZMVKQH{&|ukT%aP%5eR1yJjLCW0^ysK@uZ5d6(4?E zJSz}}?iUnx69_*R2vb#r-2}pPf~UCq2oMJQN7UbUSB#w=6AdQx(J=zL=uBmcM^X)> z0M-+F1<3y=Xy?EE#GGSA!{0`=E5;!>D+C36btR$W$H5fiwnqhSD1&o=)(q>=*#Cg^ zFqWjCA!d*uo3`PHmOm2NPXpbnI#6oJY<$u%xPOISune3M$A|s|Z$TVA5gv&aovENJ z;nE%oTTsfDpDH~O5=iIf9XBM{=gBq-%9c k;Ge88moerMFkI7ni0c-D z8U6eGr#pZm{qKuZd7r ^gJ>bQ^k21{`Ljvnf-8$ z^x*ej0_f4bhxiE9iX(Rd@xaYo_Hzz%8eBYxT!uhL1ABEY{0I8qOCo*v$gdBGf&uGL zpFWI^=A6yI2UZI;p!?A8my8hwCt|l+=)-4NDMAAG{7OM|*%+Y@TQ+f;%mhvG8uej4 zp26|y!^`n{eYk^bzcGt82C)#*zmZ7|9&o;h Xgzc)1>KE|1dDLLRFD0V$aYn&LIe<10Lx 4zxz>@iIqb6)52 zXwSGj3P%Zfd |R!8v&bKCqn|{qhh6Cmz-0G5s|zk0!^tJeH0W@^}jnBoBh7c#ZOykIf99evD|V zmq&O#E{}7V8TEbTD!<=Q4>+!ce=&aUeh>`TG=Ap%9n9#*&o8j>yYl!sk4m_bw;dq% z6Mp1D &S^4gCcTc0q$PkOuY; zYOgYWzVFuuM8Uu&nqGuHwBx-sc?LePjqCmTAPSD9QJT-E6Bcp_)ILf |#g=s*@W5}yq9v2RCdCVIw eu=zJ<{5qUv43_f{T1pT|JE?JI>ar;0}f-7}!)k1o! z-XZCka=)ZQXRd@rNJ{du7%J*Y9*p%k)FX|X?k>u-x$*|W5M*<1q~eh+AEM$?jO1EH zUs;nw#O$hAir&rc%Bd4ol% zNj$J*^8-y(%#x2&B>5nGA>svy7a+bA8(FmFL94a$e+p)L2xj&msZll_EsGNM)Dl>R z;#0zfd@AuK(F;9b5^sLvCM?esgUo5C>>oK-k*$$!Q-+JPY&M7&jZD8J`y-Q9rm25Y zE4Y%&qz DUw_?u2{dunl3WQwEf=j!4A2ZnIuEYn69-Zp5Zp*KOtt zXU#b4ri9$9gp-%jl>0WsV^iYs`^Ki+zawtN6OdpyuN+P3X`}joU0FEzwTw5N0SxCB zIy3CbcsRd*bBw?~M1(D=+_9HPik8|4$X?J$pFLztDx2I98wj>Kzeq*ySjP>VDoHN& zM01kl(m?&SB~>`y_Q3zQAqG1gIJ5C4S33Dk(l6-VSA2mJy@#9lF3N=NRnRvqcei3= zUvg!}Q2YUSG+-j`KzSS9z_j(85=Dy*uEXR4xV;SBF=u0hO`a0rX$Z`;o>RZG(Oq!R zIgfhAY_8ZF^X@|x$f7PYJMVrZlsxK0v-2LHx{LD$(|7z~jQa=Gj5j#x104$Fsj(vU zrbtZ^DV*=2l61HYCGR8Ulk>7g>H(3OEmCPBHBY4Q!@*Q?p-43qseGjPTi =YLXmo3q)J3;S5Nd$Ij A18Q n4{Sx-gz=eL~3hX@13-S-HTwWyAx$RMWg;o?mARiOMBhCb2wu|OCn z5UzSe(D<=HxRDT2+ {rz2P^B+N?RD7g>z ziOx8lk?<@!-?C1`F~2^ER^{n Rw-u2wm>12YqM7(M7DdZ& z@I!KalTAaDvYZF5S7sx{W^tHr7K$%CaJ`aGU!KGlt1@dT;*y*rg5BJu=l9PC-&YGx z(?xpPk!gXAWqt^tR!(M=!PyF1ZxJvcqSD>V!_X?&3#uhfOYx1YsPuLIqX-?y0pm(Y z;z6VZ0gfU(hkzeu!R{J+U?yz1jq|7;yDC&{BJra?Gx)*5j@-Ufe{b|=_T_B)h4bnD z-%maS2d)*b5rb3GW`0g_HR!7Po_#QX!D((EJV;)j6m+l6lIUJ^?uc&WJ xj(dVB-xHJU!@d_m+vNI>G zj?~k>+ZiPsOS(fl-WBS3j_UUNwflxA?$Nj_Bhh!no9484hv(MB4|cPU!3p{aQChZ4 z&@>n{Z43*6Y(7(=dj|h-b`I+Htp`Y+ygndSjL-UO#Hc#*A7WH}i=>L*Cqfbi({dU| z FTZ(ouK3AN1m7}Q%kdWlizYdjLkUcr%Y8czDt zuLjj2YD4t3ryY?j#sLQy8UQTpH_TXS7{!uiyxFS1g840wraZ zRB}CG`*soMMn_+&IZQiMMbk?w$QVL+jh0QVh(5(Q!GcnJ>SDUz!5G4CdEN_JSO=6N zVUx)V_BwI;5>BlZ!ajv{A25#PRYr&4x+zg|YB?A74FpedcN-G+?}+K&=TqNHfnV2N zf?tN9m$4z1NVJ<(8HxdCA0%4nm<+QNr$$TZvMUVO6@CL2XIXYj9ZIAXegk%`)C$K| z$bc=8LI6?(3l9ctk=}qUv98e!SiFH=VJ$k9XvHf?Q|sAW8D49vv!2fGt!N9Yd{#<2 zFu67T$V45Oxn#m3-gTRF0b}A0PaTS1IAfM~@KY3u0Y)r3FeK#yv`y)P!x*OAnY>l$ zz>1~7)0X!~yuFI? R6 zPokJFq@>-GZz9&}?BVunV@?w6SJhumg}?ONNW{sdlvsqrbvT_nzJzaIvA#H*&U>CPJpZvc{8arOkQd$IQ!(__ZUH8_2Syb7t+E;`kd zR3Vw}sW5*_OE?LF!)aaDJzgoV*lEPi*?8)*wm9!k;-;f4P%mrJ{-+zMcYA&%I`GL| z3lUR}0smTw^Sr{$`mkR)H=dSVx4B=Tf;v96kHjh%9CA;rpV&eaBtp}CgckkLTWYmc zs#8p?nx4-lO0P|+i+<%A4c*3COfH2oLa9ro75-HjG+a|^x Mb%038vM5@D6=dD5(|d!TO*!B5@TE>DfRR}TM$PI#e6GVW doJg28thP<=V)fn=^92leI_eRxGq}-Nav@={ zpTMSlL1Rz0mZsSd8y@IxW^Om)upCP^6(Meb1K89w8h=Pu~Y^wTKtJ}WuF61-4$`Kg~r(A(^Af%Keh8qbUvgwd RhmbaEX{i zQf0+o9<<^wrtYJy_$z8!@%si$=oXIXoWhD9LsK2AtFKpTRpe=JOZuG#$`V^05+ole zOK4S%9qu17P$F)=a2~sN3SN2-FR>}L>@-d;0t e-X*$v9 zh*K%k#!CYEm}WR&u1kxpFM|;^q-v1#$!IqDqK?vve?s~>E^Q@?6)nL&hS$?7@N(e`m+j9gu=yY zNGmf+&lX|dOeFe_rGEy~KN9_uNdLssKQY$gStTe*e|FbuLdN$0z$=Jl+Y!O9ro_{f zBWmm0g@96!IgtE?=pVx W`6wK1?wCRW@>h3j7)aa-FiCTlu=IYJ9x!V3;I9J~fEBi0a)z5sw zXC*L+xjJ2&tMRz&F@_aA&DA9Vb2a#{GFLCW%3N)!X0HAawyq%bf8$)8@v$nEDsy%E zzcp9e$#e~vtOr?L7EIP@VzPGXC+oZZ<;mKDi4e23rTW?0KmPk%4_BF=r+*YUKaWNF zTIS~zg1bIH|GzgsH#}c;e#ZTopJ3tfUtM|#6EYs!*oeVYE` j4oR<9& U zLx6qOJWh}~8Q91(c5)Hb!)ZDMD_nozT4yiO85Hs++PJ;oWpSumlKYVJhcEFjvgi4b zy^(y1lF~1NZfXP>u#~0Wva-sBR_sU#1J)J-3#-~KE30pDgcX0G6^kP)t&ZyR)lsV= ztOK0w+%v(jl=R2sCUixn4$NE_vKffe(gPIYQuTSqFzy}-ljNIW%VN$k< 3W@@|z{RlsUA<;}wfHx5|>XT{`3L|C1R-2NP+A|&I|Io>mwYPfKL<9Fu6WWc~X z2<_F-Di1-lF&vtkMP-hAd=*8AiaebNc?Z5w`hz =;F&^NaLZW-)||`m7+76t@EBP0 ze!7~+;Co!XyrLBX=Y#MVM8acWPdf2*H#bg1Lr2fp<+J#a6FUz69(*?p2H9!5?6%9t zur~t>#SXckwCRQ4(AcIN?4tX;2RCT;l?Ots-s-B!ZE&-XTAwMx`5htTZEIBuNk|>E z`&_nGn`reD0vCzq^Rl)2J-{h|dtdIvoIkGW6lj4T{{!;x*qL|Gt^MsH?}6P_Y8A!@ z7@pDwqY{LJam6nmoPG?D4+*C##YAe6I}}9IGcWjEyrL7h<@3G0)mcBq=&5DMM^F8e zFE!J#)I8(C<9TPSN#~}L6T()9X{$}Xvy3I!cHx#YUpR+r%XF!v*KXYBFy)>=(}+tg zrrg66cUj0KSBl#g=9M6sM$i(~KSw{qXPRHsrO0Ahe%@kAJ#ANdYp^s-^IubxH=BvB zhEkg}bg{jT&TjJGa{rz!$xZ7`EQSSn_$5`o7(S=YFDULDAtn9p#B+zmu&~aN>xp$= zhsA_S3Jt&|M254adjdSCf$OcVg`C3N2l0j0S~i59`eKoNj%az89x1^%ULjoPzMsz3 z`#*I3JH9$k$Wpy0q|rYEEv?G@YAr2XLkjeS>_j=Ar8NK;{hkoreDWXhhfJgGG81jt zVBOj;%7$&TYx0L&(+LRc3eDFBB`vX{TUn`Jaes)lRiUSY9WDpV*@ZrT2;$t{!i_dM z`+x)-B4&8 #3*u6Qu$_$P^WZPh- zyB9xMS%BM&OYN?SQFgh~j}MpS;J-e_atq0psD~3xZ6&3vRmO$d^UgzfV59lHa<4K_ ziAVL__d_}HV2=C;o;D%B&F^@_zmTrO
(6LFhnqVlIsP&&jKUZ7rU_eLQyq zz~iMGRbE7^DfbfmlkR@_5ajV=4Njo11m2&<4kCu$?dlT-IWwXRcuNkNh<#qXvtG*z zKbe@`8smB(x9x0C>ImGLiuT4G- zOR%ZkmDLnNWa(?jtzv=D;748WiI`_q>O!~5aEH>-8e^yAdWx5eMmZdXfm78M2Saz0 z6Iei(V8? X)6HUS=wC#d@ZYN!f_j`G6TKiBzp(6z@3V&v(Nc3h~zsF;HgD` zKJho`1b-eA>^r+MJ<6Wc157y2l3PDlCauIJRQYFH&n#F%9ch4?>a$Pr4gnY9TO>p{ zdL8ir0(`Mr`MK$g6>iSPk(_yl@aeZEWK%AUggR)?QJd_6u0g*JFlux%y;G<-ID|aY zOB_T$he)9;=UHecram;(F?NoGk#x`*A2f;*92KK)bv=i0e-dx IV9v9iwLYGz;b#{djsg7m_H!lNH=f@@Q@= z-8?C0ZOle BSH9*%suKhOY`d^Znq;WH_M|NN}n zs9ch7kmUQ2Pv0Uu(}2Zcl;ka*J0xWgK NKW z)d0;XDB-jOmoG8f-RFd$6^o>FXUAx~p;KFE;k^`hO>4@Y!i0@w6hG+T#vv;p(A{@^ z@BwnZ%9r@wFWZXm*mgs+ bSLO@F$^w(B!-U5A@aEJTH1Fb_lTIqUw`)~M@ zG>83zf%6xS(dzH t`u&eyg&6?f|jU%M>y2ss^s0m(bYcTS2eqD`*<8Xa%j>M|}Mpk380V zVetBS9u^)NVzGiAvZBTnbRSU{t)M^lwD*mFw4N91=Wf78>*vp2{a4n{M*uBdUq4@8 zKhuu7Zk_g@T0g%8YyRI}KfgWyziIt^;BAfC|FQM+mw&&$e*SM;Kc9zl=zr__dB@)Z z*Uzhwu4bpA%KG^gg41>?uCJeQp5Xtb^>gay|J&Bj+xAykKM#}?tPm$gSUdb+ExH^A zXDikj 5yA1Ytly33&&s}VP)<+ar4O>vV+#+%qV%Vjtp@1I?>M+4inmfMVXg1ToPiyV`V3B z69cRBHgtyqH%%PV_;OHZFXt3j;2H&9lYxnSo+Sec#hlEBA4ycm!p4K(PheSrr;l(h z9NrNJ_ptcaUpeamdz{Vxi~!F%PZ7bl!0r#++HhC6s22w!g9l`1V6k<~0It~7eY7`~ z4Th`yK46SR{@yNcFw1zF3NPVUu)3kuzH!G*;$$YcmwUifh(*j!W&%-oQmZa4Lmv1P zZ|BL=8rg8Foilrq4Vy(-8L>Ij8r652aZkR4Z~RoU+5|@%EeBXHfYIL1R}?D7@oF{n zJY-UpwXU(h?sGH3K>izkBv &f8#1FXsLwx41Q_w$2euZ!@OBprKQ z1&QGB?p!2ssC6mv^<5qab0swS1oGv-Wr}t@&5jPG+~_c#JE{;ZL}!Z+rjtCzFNQ-3 zr)%#ULSKu*c$p`m|x^reY{kr!_oO2C%Nt~0V=Z$erb~W3Eci+Ra=2&UaC9EQN^me{n85&qM~6 g5nUn=pD4_ 2iymozMUi%IWd-s`|ktR z{)n1I+y}h$;eY#mz|wJonI3eh%9XGJN$oyhI!S4{@xWM7VzekxjHK>9U?K_EWn7UN zcptEca~0VD+5dms2P{X^{ZHQqeD7(ldz)bWYuC^G_W{@JBJ~sZ0sDMM@fPb*zS{eM zZ5G2o(BB7qjbrBb1=%3Xs{itRz&&t=O1}Gm`$TFiMjq(U&muKRq V3e=Q>YmtM^8j><@ ^iPmKC4aL|xkS^va#-@#^(yQGE+&2n?{^mR}ZK(GF*B}oAz;3DzbJRR+ z4`6zzvxtJ|cW{k@X0UmHLGJ4WPjT%&;ER;;jEYdb4>&;}d;th)QtK@c7C>Y`cpngw zjnrEpyqDl9uH6S5Hxe1~Dnj)>pdERjF!3#IV*7qDr*V`(S=m~kJdw+3Y)=>{uH6Sb zMj1aLgAPxq_W?Hxl!xaD8ebO(8wrG;st8{f2p17N#l?NVHxUc6|7bo5zE2jMzWRN- z(ceQgG40iOpKcF!$03IqI1m6eJBJkR)7^^H%9}8m(tWzHd;i*fx{Uki+`aBT-OGny z9|zs1n*h50-TQRU))(sem+sS9@CbjE`*ela&Z>H!?&9?7?$gajSu*3_c#gv3?2dOu zpScyG?>^nZC?c(<`*cg5zlQsCZ*UaoKK%Fls<}`1C^$i1AoFn^C?%RAK-2$W@7?2L zy1M`I+=jTsP(s`)T8g5iObJpV2{R-vRTb3~4XSk~DO!X^+DxZ|wzPWjR4-b+D5|cd zO(Z0=H11Rpt;-ofluF`K^Lwwo_C9lFq_^+$yq?b=&(G@>=gfYu_1=5!z0W>-ud~iR z{65{|Qv0^|>DnQ0kAM7;0ro4nD~CNnBT&jCR;S5?Q*?w`6LApl%~hr8iZditC4`o} zh4<#dX{LpV{Psdx``~k4dD?dtJjj=C!3~9Xo!){I5$CwZ*JB4N?V~w#xum>>Y2~~4 zjb67wtUXG#i37#8=MuYgg+AYiuf2(ohwgKvOXsd6%t`h6B=zdQc;Brq3U}N4Ziw`7 zT83gcrE%ogY|6s4ltx#)-9}bn{$1k)87JOu+YA9zQ0XvHK|LUQ3a6-#B%wlYwiVSD z2@lHz40qY>X@JA`Ls1Jb;PQAFFr9LeUphnDM_|zwAq^GsDGD@Cuv$LG?3>Cp^kGpU zhw(xc# 5m*qGs>5qM{f6{vbN{3vXdMdo5ZdNQ{!?VRP=zamq#kEs&OHtt_hLnMbhL5sov ziTx|Oq3Qmw=c~WbCj*?Jb?tOT`|e+1#)lQveD$>~I&WADYt?e+t5cTv%va9|W}dHp zbm4z$zFLPqE#o_1-T4?_6Ihj@s!c7E=$cmZ)daET3t2~Vp+BFmz62V-)Ee59$yn~w zM+&!_rXtBOX>Cl4VP|NM7e$l$Y+}(xEIY7?#gt&a0l!_0c6FFWRHB^!YSLN(IccHK z@%*j5*yEw$6G)?LoU+5{eYB4lgC7< %>C?GuiYQIgd2BMJO_79in6Q90p2D;m z4|H*tfH$TNQ?7bT+$U_3vIA3oN(^-F>durkD35SS*&VADlyMx=K>4UF 2T z#C&x?*MBx&UDLy7zWVc_+vls_pj`j%e0669?wS8+zPjjKIrG)(Xr9~WtG!ano3EaF zljnx#C(#l6KP=|UWd@G=e6@`z+8@nV-BbU@eD%CZSyxCdxN`P?fF*LiS~!Kvl!!9P z{U4 Dk~fm2K@cGLP$%vV!FM8Y C*W>p07T2 z;E(33D>0nXys)*%!gPs7SIk$*L5cb5aD10b&R45K0MnLcC<7++G+%ugr>LM6LWSn5 z1FDLI4`l+)S4WaQzW0V&fC1fsXggA2jAy=j@DZe)Mw* T%*d)!P4{g)5v6AK#zMu!AMoOAlOw-ScCY)(jGtFI+CiL>) z`?aQ$W(m{WDQPm9rk)qgk)EP%o@ScflE(GW %3^RIAPRurl}lEb{yaMz_??-X&3N;K^g-_f(EmwJN=N8m_^}> zcl(Ho9+rviRK9x%m-CO4c&76*K2L_pbTh$dsfFH3BuhD;y2OS3zsx*!S_&Nu2M*Gw zb5~!X9Q7 ?O!xpL#7V+O znebI6Op}CFm~bu=Hk5=_n6RWD^y%EykO@yy!fzAU -vv9ceK698J+-@-s|WJWrUMDG8rp!r`P( z=dL0q>_-VhCE=Y+_&F24DG8f0;lG%$gCuOqgw;u(&Rr)#s5Qfx?oSiXFV%if`)GT5 zhbinPN-6HMn)nEh_yB~vA6`W`K}(k-Pw`apl_ybphw0o6mZp9FD`C7~@1K@Ej%IND zeAI`3gVeCcdGUu!{^^oGg85%6pMSWApPnu6LrLBJn&T7P*zrVcO3U%kzV_iu&> 00Kr*#7>W32VS=q-;9I{86TUBb{~-CXuO5XaShSgq_7$aC{Ja*JO!y{ zaX-+%l9Zzz9m7vB%CR4jAj irxJKC9MlhK^tTT)utFZ 8@8@{%VdeKXL;Ezx3p%UB3q1G? zqUoD5RTI=eR!8DQ(Lka(wBgCrKvU5? lOG$3@ z`Gi%O@SM1{kpe5$mOzK<@+!EHUmuwtg~w3a8MheH8ez&S-Zw&An$`a6H`8fZu{X(8 z2}keo!C=qmczcF;n+5OgI7}ByJ@)t?>V}v8toAL_;IF5hlVD#;1&oxbvu%#{w5{QC zZPpWHQVL%2!KY!hiSidV#GScVo4gzmOOCNku*-4M0yLdA2YzeWRkfyeI>(Dwu=UM$ zunnKafFB9AUPeu5_h9i)&^Hz~|8 IY77vL2kER8B^^~q0Q(%K{PJ;5=e zNjP%Lq}*y6a$BG2$*tw>xovombL%H_Yp!xTqpbifa?8Z)5hAx05Jhg=1^LM3$ZRQ0 zS`1SbpqVqR4pCc>#s^&Sep!OO3@_)p2hO% oErCRF8!aywq zRY=#W2}iWY<0af4s=Y@WLVdJ0qh)*lJ^#O?V*meX>=a3}UFrYNqm3gy{(oK`Et-PN zz2jAOuYv{6kmBEg82$e*QY}gUKhFQl{{Jv(Oc(aO8@_S zA))VIoe3eVs4Ky2FaN(t4tW9#qW=;9Kbr3U-2cyunz~|5aGU>sEp aFc3NF45>;s=ZAyN$~&ws*iksvWfMb z$Vm%L=Bc^#|KEtA%ioem+2KBL^Z~lKqaIGDL+AxRu#^A)2^!m?jzd eLMq@(Oc=<7?|@MF|C!K9`Y+*J`Ttu{!W2m;{r}aOum&E6gOL3H zOu6cLQAV4j?7)=gx`TnvmH)p5QHD!O>Hn|5lzXuhpfaApoebs;Wx_J|Em6iZ!-df< zBBXQa|Hqm4eAn0C@B90&<5kvuf)4km{(tcd+)^kGA#pg6{~w1<4`LP|_J3~n5B>l5 z`TGCAEyw?la{b%>|BKu+|C#@PZ+ZTIG*3DH|HsPp|6@CBnlPM4$P`Tw=FX;LsWt;g zkN;m3?GOF`L;sHd|AMmakNp3z1Q}DjO5qSLQzFVF{r^(?cK<)}zRmwXtQ(C$B3`8j zPRakDK!Xsuw_m w)5K-B_a pl)Pnc$36xkknL((*T?(@Ui7n0^4ruh~kRGLJldDM&M38s0OX=0@__vEts z1GFb4%?Si@!Ki7H<_V^0;zd)RY2uisp`_XROpCX)a7nY6X(A-eSf(i=|D9ep``d`R zxrI3}j4F{vt!Q`Yymmy~{ZDB9ndTfs$f#$S=2I^kC)2EFnqo v0gMim}Vl=lu4Qq H0`};-1iBiS};wvktRse%m59h z3l jIlX7@Y %Y95|&EBe=*?;O!$x_9L0nuo)v`CB;hC~e2Vnx+%=pD6Dgsu zBwWaZ7AEwUgrQ70j|rPe!cZm*BYiq|4PwHIlyGY>oBR?Jp6Vn_UNwqM&TTEKHi`)k zma@sY(1FQ$kk#nimB57SC}D*poXv! @Qr|DEKHS}F=DazhR6d-iHKM#H4g1UZ;hrY=u z2572Cnj)rgPczbd!8C_Eictbn2Qh*Qnl+N9CDY_Wgi1rZPop$BUNlcK%_~e}Gt!Ke zG^eJbzz)-r(`=%+F7Zs$a9utDZEf%%uHY)<8gVx4Di|$QMnDVKWh2gKF>yIVBd&6b zHG&R0>0P8x=dRr%Vn3<|B?L=Ce z i*aT%ORGj zoV9v=2v=mah?3cn$ZGZ~$k47UN$x^}KN&Blk;5``1DV1*yVtWiu+PnI%@szK^DFI8 z!@H%pPezm!U4e@<*7H83D1+E-1^c#b$nvmYuf>kqN1zbfM3zRo56J>Xi@giM |29ZM+x9ex_( zck>~H8L E|7-tUd$EuU9h@Zkp7`9E=Y6xj?@{+-|J}ZY zVmy5q^5y#P)=cv8-`y*i*?)H?`+v%RH)t1)>^}ax`y=?8kp8=5{Dh43-#Nu{BBX@w zr+@ChyWAF69r^Ft>HfPDNHX~EhVy#sg(0Fzed2d#yvt3ht-=2Ow1zyIg9L}^!())f zJ?hUtLN^{cX#@N69aj49-a;BifhQlMG3ta?|8BatqZUq}Lul&@e9Nv69i-kz`gE@R zcMT~aND@l_os9`=gOCci^DaRc!-PMb=SA+$K7#OA8|c%y?!TjiHAtX2fb!oV4J8c2 z6KfE{e>aFJFO3&vv`fmVOnL4;FwnX3-%TgVVUkk%@0Ky;WYjU0@g638mkB#c!h4u7 zlJx1E{ddiA_Mi6Ol`NtOz@NNt_7t98qYBoHr$a~ve!+jY83#Rn_qCe;%zt;Ko{#_T zF6<2H`@Y#NlZ=$af*&mjh1l2e|PGn=ou!J5Slr{5WoA#r@H^{>t-JR zUGXd4{=2?l)gD0B(tnpGa Mrm}Z+7&BsjB zmTA1=cR!ajO_*j^3pQ#N(=70!8OAg&$iOJC_}!6`=GbUq)C-a(lW89HqN&R??=y{8 z{O+BS=5?m&Drsc=?tNY~d+Uq38NxJP@w O2@NpC3!)6`-b zulU^sk|vmGR!f?Xm?qzgCYEV-K?Zf>6~AkfG}%vzx_MgCtYVslUNpaBafoZ-1*Y+e z-wlv7&oa&3l4cXr4Dq5_$247;#w&jJYkIXB{iYq${M3x=CYNdM@uHc)G-Z&1QC{)8 zDU#+qg3EB_FOoF7nWlt%T6z^XXPVVa;}yT#TGA}z7`4auLr=`2Zj0Y-2W_oh51yFF z_}!s`(b8%Fv|v(UT~T?1iOU&!`4^r#6~<9nqORNneL7e1yFXLH4kXY_N5=0~W5S~k zG2whB3}(XjB;kA}e4q5`T*dFcLJ89(p^V?%f;7w ;dcbG7g3BQnp?=ay?(x-D3zxyvr$dH6Ges?F*VDcN1us0LtQt+BHG)WTnX2Qow zpUzeMZUQB=mxMBYcRCaHkc8Lk2$QEUVO2?ZJw})uLi%*B;&*R0LBcOcAd_YMZgVEQ z+K)~CgbD9r!mm$q9e%=un@OL}Rs8N}l<=w~l<~WVkOq@Kl!S>)xF=bd{In!YWWq6| zPv #APFln;cO ! zNT1F*e)mb7dB^AZ#6u<)fK=RPjs8A8ez&d&Un|x2bVg Ic zCzkzCE`K--q4~qcD4wcLV*Z^{+K2zWXq{j8-~G+_-D!gHFXMM3WI0@&gq_{XFGpRJ z<1gZOgMIDwj^Ew5Q`(Co>hnj8;XDR&JhY78UENK$*W KmDiUcW-^K zdVV?ayYF?N2J*!3HXbT|>+!p<%oOc{OXT+W-DLtR){Z^Sb!q7++HRiAPsMY3#qSP% zP_FO(-{W`hGuZQY;&;D6;E^YOca{9b@w;En@QL5eei^oKsJS*WiOxBG_ee$9<{iH~ z3X6YQS>CF|<{yN(X#I=Yka;*Y#P1FvKY>Y0ar(sX4lv|a`j{uTF}LSdb_eISK;|}D z<#tB909s@G?gfY b$YDxP4asFTS|Ico~#z_DF6Zon7|IzZ8PM@jI5@XohAMn%Y|A!Ek*fyB$<^LDS zA+)ag--zFxji&oQ_y6+}Yp|HY`^N9~wX?IBqAT{zp!0?gL%w|f|6mMF#`xWP1+(=3 zfAYWO|6faMR3HC;uey9qNdJE;{Dh41|BESoNJ%&n|J?sy8G7XZAApU* 9&yWEB|2BQ(`;++H7m$-SumexcrT;$}X_!eD(TWH& z>H1aZ;*MH4hz_Bx5Af8yK6H@UgY@ZK`Ts4H5F`nu|Njmqd<%p$t=U;w5XLa!Py40+ z{{caGwGQ-m;#~Rv$5O%?BxHE}|NW4L686XAa}bjMpD8arBFbo&lvA1VUSgng<^O+$ z5{602?uZP4XK_4JmY|NQjQ23%yG+ rNJKL=$NtEqqD|Np2w|38|i9REK8`mmj|J*GKk7@M)DZFTy# zN)yNm|NnhFLCAfWj-}dW96kR3tyHu>^#8a2JN|z`fh*?^{r|8884LeEN-F&Sh_vGP z-HX{=H@Ex$+tF-4R>nt2|9^fh8i9oW{|lUw|Nkx=gnRqu4$(7ADj_rzPcOvIY_#9p zBXDuc{pLE?F!=xR%9?TijwivYJ%FsG|KBQdu@qpDLv`mzQ$c6c^a0|syJL^^|3eEaL z85GYee%G>|ZC}w}%=gAi8X3P^K&~#G#uX&2?94P?@w*q-G0iBZX(nl8{O(&`H19Lb zZ#6_|yyAC1mNbo+rVt_&3n$}uM|jZ;VVV_8;}yR Zqm}V5y zc*XD5l{Bv~%|nt##_ygZ7nWW(y8=bsG-4XB_}#r?5^+N7#WYnUjf~&@+>7P~ra4?) z)QwmCu0zrUGEFW-sBUEZZi*L8SEhM|X}schV C6V4`mI#=<# z6DZ+9NhsrY 24ZAlo!gl$Nl&Q<*Gos@8)HJdEscW=;!kWNdwBwXV! z>aZ0PZu^c+UIQJ};c>`nbgtrecTvJSl2FF)e#(UROTs6Z@MwZCIYkma!GuoIr*jp* zJA)E>OF|jHJD3Sic4CujFyTu~c()|1!Gv8%pUzeMZc9qI-il3@@w>rHxIhwS`3aLF znQ-q;HaQDAFu4dDP-%3|@w;1b<{Q78g=bB2{KH_s2?}&2oTOMmr{&oMqESPig|m7Q zGU%b}jS;h*zT`3M%Xl$LOp!D)ez&U^%|$nHM|EQwulU_7_#8J~3uBn3m87}Kr3v(+ z`Iu?0RTZVN8B6oIq-g>gOyiGjWE0DY-`xpq?ah{4!7_gLW5H-?6A3MpWhm!!xVPv6 zlXh?g4}}hlc!~7sT*dEBrv$4cl<~WdFyZlzOjwNxUu42?Nmz{uBT1jmRs3#qN+`XT zODN-aO-$&Ngj;Tj3VnbHf5_(&Zh;O;s8xYJopb!|w>bNc#P4Qq0KK?x8vU=v_}w1& z@a*u`-J%r+Nd+I5`+X=7O|98K`d9J0-D!z&d;IQaHv-UY_4wTnYm?Np>Im`G<98d! zQgvAP5Yhv`jPbkYE@Gnp-;CdFae-Ev|5p6&ne%k9Y{#7G-;3Yn`7kd2q>6O$rv!+t zmHOd_me!p5UCKrDqiNS}xwQe4L{DoEEXg$*peNoK`b~}cVWi*Hqu=p5^lP&I%?hO7 z+*khslJ)!x@k4Vr)AJ9;i(J~ii6Z}8p|1h-%73j v%Y>(S3A{nuFkWud>^SAV8a ze u;nSpRdOzuZ@UiBW$6>8E-050m}?)=v@o zqkZ*98ub%NzpF=oc_8#_vVIq#-`rQfwNXEu^xaK$`= ^XP{Kll`o}Q0R~L)lW5+e>9c9t4Ci;B>P!E zUX;JNuYQzKzb)yzo9Om$c$DlPC+x2!^fiE9_M43QWmNueJ^GnL$bQ!UNtA!Nul_D1 z>-{H-^wT{0iI0)}tpB0VAMLBZ$f%!5`dvNx&6CJ})*mbMoBQe~8TI>-zWZ+7{<6o( z{;|UT_Cj9+=w*LXqkb6af9uiDA4>MK{>?zq{s8%(a_xxc$$00&^x109&CO}~4Nqh7 z%%~6}E&OC{cy~H_sQmEL>@M6KLvsVuRhnmDrzeMLjMVqJ*L6pZ`uqz|5^q4Mj6~^c z-Rw}hmvHG%YN~y33HNe*T9&@Do$A8&ntSJ<0_6AW BI{p$Ey-c}WhL|Yw8N&x=s7;mmzDkbG))oh5ytNZ^}V9z7BScbD8x$BZ=PGI ze4M6sR9 `GeaT(t?^%_^{k-sb)jMRYK?o zm{#kX^iG<^PCo4A8b!TuCc-S-D1QsQ{Dtv=Jdk}x(WzTohfSQ2K{5Dj_6p?63VKrZ z&x>SiXN;|8TjZ^j&gfXFA@TNhMJ=d{#l_(Qa-nvBSGPI>QJ7yaY3B-nl=!+I(Jd+t zpggrLEE|H%HbD>{IH~T2qUq}ATnFU%d<=ae44bs!t6({(kezOPF>m#qG@7C&*j- C?GuBb2r2I5YHbHGjY1=>}=C8?3J2 z(+vu!F1Q 5rxTokd8h*Q65ff*st#1As;A}XBH~)y>=9AdBG32B=`Zs7w*2}a zEIE1+rLrI9>n2C6hv@mWp+9}{8P_HEr>|)d)ukac{YOwOg`A@X65VI{7gRwZCsjh| z2t3NryU+bIRQDN&=Q*D4a}HOF>^^2NQumn}CA!b-bKpzQsxG@wHszNmZdBCtmy1Ll z1)^J^!GmNWslltUJ*v&MgAM4~o=X>{SYP=*Kl!Wc`=83I`dyC8M0@VSZS|}0j|m@g zJH7!6ct82Qcu#+FTAU=`@^*Qz`^Ak *us)Ld*intnV8F*3q;1nf|T!rYCRo_qt(Du}!(devZ z$Gwd9n45#67XJfooA_>}SnXcN>$aaA#A2$#^#BaCc^Gr(rC}OKHqdZdTT7yNWqIqt z)|+|SW9MkhvFyY%2b2x_;34zNnpi(OLx+nJr(!QYjOJ&w!gE9wh;q+H{&>jm?q`Jy zY!y#A=mVI$Yf%ToetCA>N`FLYTHg%ti$+1 C!=QY{UiX|C}e>eK7` fB{R$MCL>R`;%g?B1Y!q&>a40dG zmYkw8$szKR*ojnJAYS%T|HodG0ap7VcfVjNnVKQb1Ly7XzT=O&-otQtzOxJ&is@(} z8qhqKt_pO1RM_59sxb51Hz>tv`5HgfNU$D}cPK2aW8xhht&SmxNHcv&zp&40brcA_ z8IBw3sP|GQt#cF<_|XtN&rycX(3j~+racc`EC81U9?KO4L>$G1a9HaFa`D4qa(~E$ zEAJ+-r#A6KwL-D9H8`ic|3FLu@vy!+(vVXah6fagp8r$F$Nm2S(QNjw Qz4<;HRpeH$+CJwpfdK>gQGZRet@H9`V%A5Xul; z I%kTR~SIg zd>#4+kgV(Hvrfz>& z5!wHku>X5tNv^{Hz3ks&)L%vVD?R!e-bdBaS%0C>U+k-&Vbq^S`V&0*8}JgZ7Q_0F z3H?N0{RE?aH_~t8(a*$EPzz-JCPF{VS3lIKA58kicj)#fVkxfW3=#I9|5exz(98Z~ zNY?vL0e)yJJ^IamCHq+ zk^QV6EA+#B^_yNcls^nVwBj1N{fpzU4#~lOjkp$W3jM Kb`e+fhD;X1N72gi)3AYIeuspAR_fUTA?4q`Y!`ZawP)v(w~WBU4J5eXl)=O z^@DBD4`ls^f#LcG=%pWrWL>`_erUzjb^XJnpEFq4-$3Xe2I!?9V$}B|{god5<-N&% z)<1Pg*zc>q#i+lE^e1@q^GnHo)?Ww=_5 #dx;GwRZ zn&ZB6;uqM!{+yseH0dkV# v6#lgOQs2jqbJ q1JU;F4G|Gn=)ot@HYL5kig#4SrBT!FspHP!uv4$_ZPDK;X>Qp{X z(=U|I-|(lUA2rq=+$dj?gZEF{a{);>qxRzA1KM+sID}lo;r8}Cu-DL@f5)HJF~rj! z|7v~hi*tYZV}IJ{tMJ@m?9lybFXFS(9)H@78Aeyi+s9QM3xC=|nxg+Rf7&N+kqR0i zt`N2LH5y6lQWe&%GYz^xqmu4V+kl@~pd6uQ6b_NJ_eDa1N(dc*=N!62r12Q#5cwA# z{CXTBM^1>YNB*>157DVx8`Vnm!u22O{ ^j{b^qy4PEModSb??HG@T{ zx}`0}d^++Io-a0o4pQ$ReL81 JtNT$cg}g-#B)U)H+f+dzuc(C3T6k!pcb}i(@u!$er=?*NWA}OMnBIN91tWEz zX7`Hj)AkVf)MBwzo75lqdHiYb9~N~a{b^sl!G$busqg|yYxIZs`b&JTXW!rdR9^XS z&fqf9TK;%j{VM!R!mHel`>tn|d=$warL~k#dl~Q7pS{i%f%~;)ewFIc@;aWG$eV`t zj!+l=w8lW`mR*-Zxg4g+Qt@_wT907w`ZM~I@X{X55-fVI1;}YR(eCXbGXK2=Wj+!< znzLFXWR7uT7225mH52zybDz}~i@++&X_m~Vq^pNXavZdT|EY(R91lrwlmF=#bQ>%n zY19cjKs?1-b=*d&`vlXG+){U9PD2TYa5q3b*bNyh^v>WkBq-kyPX^C>GFUH&i?x-a z7;f!j9KqMqU|Ou;(@k3>`L>9-D@#{H&h@-=9wQ}RgQPSq*pqXV%-JGyZcRDES+#bc z@KvII+}dCY)^UzRt)A6(6$o7VEw9JhPil|;#HL*q8M(EcLR^-#M0*a&Vh(ppTlxqU z!L8*B$x>}toah*X7phAOJ}d5eR-@0VSp_k9_4pfAe_hm!`u`!~_ZnXm-UZLFv?{mb z EPN4QE zxuRPf={e=*ALw+P!OeLt0QwMme-9z0+FLk+HdN3GDy@T{6 +XB95in7;!wS zCFAIE%Z@yt-!RE7`#4rb>W0a#<$79oj|jPCI~zny&%9#j;_R07dQ~zu(6~PH^}qW5 z#!PD$+*|tkFAG1kVssn1e$@7%zH@q$%~2l$gZ~4d*ZOafQ9qOPS9 Nhp&hmn38kA6pT;Rmw*%|a@Fn6Lf?B f2<{pCNB z{jC46&` grX{b^XbXo0NXKW3Kh{YbyqPq*KSrK6T(6ZW4vA=)3H zm;DEjtk+*YerPK_`eDb(e%Ak7=r8uwUt-i>K>8Cr`WorSuzrfrPxRFvY1B_7{Wc!` z4cJaX3uOH+LO;w`zqL_6ob-#`0jmFJVvi6l$13a(68eV$df9*4sDGIBS9 bE8R z;#<1?`42!pr>C&Lme4;8(93?4QNQds+3(R`+=1+8{hxrr|K+Q{3(0!_$s+v;9{tgg zWIyYFDD)G3^=BIMpGf6zWD8DKCOVf1l17()vJmMTPhIM5qnIKkt-g>I!0XN7NcSXrVflX zubX)c_l9gOD7~ M0fV$|*s z`3I(ahB`qA3Phd@)8^E{iCnz7b|E#^er@*2inp@A1&QCjvxqf;o8;} tDTlW^AWhWDuRW$)xU?L7i;wTx+twEj=&L7MW{yQe2X;o<0yW#}ZF9rF-Sx1GG zrbrV}`dIrVen|fqKOYAIUzuOgS)cW@zP{)u9#;Qmv;Qut;G1cX)^ZUrPF-g#9vX4- z=;26SA(NBoxw1WGVxC_xq~q 7y3pA(_eY|Fpy?NFUijiL z*jTiSNPfbza}wN-BW17-8H|Qh(F)~HmGKo~_h`QMDo5w_5EoxjGCir47aw-jPQ~)7 zbQAS2>gE2aUC{8w>1B;mdZd?iPU(|g)++Upyg=$tVo_RjkGz c=r&$dk$#B$D@YHjcs{thYZ#5PXmFM!X|!VsuGG!w`a? zP563x>O;t0YF6VAQeO!4r6FW57nM-$t!r`!xq)A3_PzF)=EnX^!%=}R7ghl38ZIz! z^-)|anG0{+w({lL?akHLmG0r%ZQu%EuGA+{rrq|Kwnm-~C=-@62K!RGLF{{bOnajk zA{|oqlNdK3@)))Ot9EcE N}(OvIHGw|{QdwEos)7?a$)z16%j-)8UIG2Zdq zMA>lWxmYdGwEvK&)Gj!q{AA&XTN`KKbR}T)iB3OLQH*b~_FvVIm{|in_Ly#BNNj@= zV;D@yh~CV@-~|kW`;9eaMt)dP$w8~A_U!}Ylv1jvKywCS&4ejX? >Dhuwta Q)L zIBWyi3VD0a2BXZySy!UXX+4`q=k*K^sE#XTPF`YTs%pzTC~orW#-q`)k^n!~O?(^z zC7^N5bqVL9)=QzJiZu(xDrbBaYxsD_R9u)9f>WzOn(plpS*~Ak$k>}2=oo;8-)eL8 z>1b_{ZL|032$Mh`nLU|=;mIfATpZ9E8rI8x_UwqP^lSd+47#3#{kHU39sSH1@8UPw z@N7|Cy`^Xz+ Q3$9X$!gu&WAdUc+Je~2A<8> zn{sb-=AcB}=ms0R$~?h!%Uw{kNY+P0R?!`zm27!EJECA*QW0jumrptIUdHikbi8B2 z#DwIL%_FjGb8foL=wI_IRwU18X`CaeYP2J+x;^flI7e!D#L>8nQ|7r?%cDNc^S;M1 z+8Nu#?d;`_%r|$>cMkSXzt(8-eZ8GQt*oX*m>VBiW`1D@ZbCL^P$Qf3 QOUhYI6kA06=aRf zN!?r&h{;LhKC`pfM3bDPT$?jPbWqx-EO{#)Tr9Uad*aitakGI?VQ{*Ngv6 Ajdx5hgX3VJ$%=EOxFHqV=g+i&!oG6B}KC0~liHW6`-TB~C12f>%NF(&gX%OH%U zuId=U #fKFbH+=s4#vdVFULh5A7!2pdMEq< zW^$@=Nn-7X(zl~%IY`(<40FIsJ^m|EEf{PP3LITF#zvkn&!ekc!HWcZh~Zc4*CCL$ z&XtB#`&Q&<-H0=|OA!l(JU_+S+eIa@Z$-TWro=@^oYh}chds~Ozfqo)4u-O%wX!A~ z$}y`xmmw|Gn(Uqb_M!m$bzAap(eB*n%!L-}inip`T68`Tbrx&i>nT?BoSV0Vo#AK` zTk_3lXG#-)o4w4IT^Q~&KEy`;IID|nu=dvEy>Ym{La7nrGGC4o{oS1x?O3>ot`GNi zn}0s?=OU)&y0Xz3=3Mtf#hRUKac;{l3y;ZMC 81VC~+-C zDRGJDSI1?1mJ>E*#ye}(i%&idYZk=WPbEa2M17vbXm`? A$UX!|qi;|93BB5&AJ9zFnb@3~8nXprqZb>Dy7p+*_%iTT74o z)Sk_L&6a+$FuEkmKgEK&ztdWJ(CWXNDCb%tVJ@A$Y@s)=4g4|Yw5k=a;Q!c))#F?2 zi1+_4KJo`+`=``h5N%%9zN*!|1NVkTR(DRujucaT ER%h=*n|-G(`y6U@ zD{e&LQ))%*aAk_lBXlR>v}h}gj<+AQrk}ZGbEdWJi`$}YP8Qu9B6eU%Fg=eo_oxM; zR)eV)C)5fi+Y9Kw{43_PK?V4)uc-a_U{U)I2aDSGNL+#hK6{>ry3fWMXZx+xRo2oY z@%A60OSbx_bg|lZqn_ja&y-)!6GGiscpK^)Em_qJ*|b=5bz6&EEBg7|(`9bAYcT%v zSq}}sS{NTl@?Fk7ibz=s=awtFX1F!s`GRpp*A}zXv(fg7NToR3E>u-&6?fJ%CDPK) zi}_GWf!8W7ScbC0Ipul2L-QFbPl;Tcsg+nL<&GJXXFZv6XVFYK6*lHolk-X)uI662 zn nI9$3tq6m z (TwixdRgt&uJJ5bz{d0mBUEdb6PdjL)gG%Rtt2btIR@V9pl z-hf-8yQG4DN|1S7k3f6(sv?V|96g@49~Sf!V7wcpqoztvo9Jhrn 4|% zh^r-l^uFl4iW4AG)YR(eNsFMAHdGz&BMcqqjYtGeh>8e?5_;O(0EqoH98sa5(lTYz zY#hJF6$8ftD^bqMO(EWCQ1(U-gols%B+X|rmkLWSt2)a}eTOe(7w_tD1yik7n0q=; z6RC4%VuEwzV2mLH6N@^Dcq ZBD}kop{sse_}p#|;i3^T|$EH$jxz)=JNy z?#G(mygn$p@g;j8&6yw(X5Dv@%!zK1&`R_lzImsGJ16@`+cBANq&A4WJflYXwJK>< z{Y#M4z@1IAQeI!^OLTRKx)zGXnXx~+e@J&voH~-42{AEcmGNB58S)0zMRKi;R{xzz z?w|2enQ17ZR_OSwJpM}__sQcCC=y;QkJV)QoAS7wjuBZTazZAR$YXF-R=ram+sR`O zc^oc}v*@^B3aSiWVsgKOzYp=3f l$Z&Fk*+gAGx!| zRlo0NVl>4@UY~Ix+TJH9dV7yxFda>4(A!yS1cpPp_k97DqAE1>EyfvqG4Xc1f+C&K zYQ2MjFPx0vAO%NSb!`lU=@!JV(j?(mj>jHl?|^>sjt6PfjN|)adRM<$O|d_<4KIgl zEuaI}LYU3*pfx$r>I~|JzdT!H-sHj}#4jOYg#`G{#(q&>hk{ppCf|SQesUMzfvuEr z?eyou{nGjp-NsWWaUMP4!gWu@X4eGyhspZ40K Rg zOx7dwrhJv)m>Nc2=DN5~RM&< 1o$}ui%!4@@gjF6db!B85~<=XBh_D2d(rc$Ip-I^a;w8Mb&?7Y zIc$Y1=s`Sou% an&M!Op;v+?G!v&`@%Ab3Cse>V zzs|qt0eG#0@nk=*B8|P4ZQ>Ae5C?2gS%w2l+Jtw@aNO}U-tSuu4!pXEVqBW2q7V+7 zGwRn8H>mB_Ik{9yy`S3bcpl R_C^3t}Ci{csYUemyAl*;q%zp5n)iz^PMQ&sP^2 zjqM3H%J`qf734xFKY~i4J_I9--3R|70zmfQ04q1Phn21_4Qbv%-WpRI%FP+ofQ3I| z;SZ&7Q&A;Z?gAHHZ*ZGm2;tm{^s*k=32kz@Br+1J8=R+*VT{D+$XbPrW@L ZLjW2! )*ku)92R>)yS zHtNVqg%mP!MMst>L}MhPsw#m)A(t2#sw2}C@;f7M>d2D{F~Na?jG-M=0M;a-lDI;5SBt#*t8M&Y%H}Yj&TNsHz;60bXrI08_Ch5o_ zg~TzkLPxeKB!Q8$I j-Nn&KMj?7ocNJbXv$V`QdV`Ptxj8RA` zBNg!q3Fk9dAu|~nq9Z*OlEKIl9kD3H$;eS1xmzKN7-?2R Bknv|*UK0= zq$3v;vVxJ;cyWnKeN-W98L{ig4ux!C QMk=_cq%E(C_iB!n%j6~q&MP_TJ5EDIib4Jb4 zkx+$%FtSfa0u>U {3W;MrzhkI$tZq!pLwP z`9vX6jI7j=Hxv@b$PFFIP)GtJL&8)(Qxr0gk@Y$