From 1d4ae5f520916dd94f0f993fa45f4bc5a98e506a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 14:14:53 +0000 Subject: [PATCH] deploy: 5549494f6720c0fc81dee7cbee1cb2bf97f83c71 --- 404.html | 6 +- .../postcondition-ambiguity/index.html | 8 +- .../algorithms-and-correctness/index.html | 8 +- .../index.html | 8 +- algorithms/category/graphs/index.html | 8 +- algorithms/category/hash-tables/index.html | 8 +- .../category/paths-in-graphs/index.html | 26 +++ algorithms/category/recursion/index.html | 8 +- .../category/red-black-trees/index.html | 8 +- algorithms/graphs/bfs-tree/index.html | 8 +- .../graphs/iterative-and-iterators/index.html | 8 +- algorithms/hash-tables/breaking/index.html | 8 +- .../breaking/mitigations/index.html | 8 +- .../hash-tables/breaking/python/index.html | 8 +- algorithms/index.html | 8 +- algorithms/paths/bf-to-astar/astar/index.html | 104 ++++++++++ algorithms/paths/bf-to-astar/bf/index.html | 184 ++++++++++++++++++ .../paths/bf-to-astar/dijkstra/index.html | 145 ++++++++++++++ algorithms/paths/bf-to-astar/index.html | 64 ++++++ algorithms/rb-trees/applications/index.html | 8 +- algorithms/rb-trees/rules/index.html | 8 +- algorithms/recursion/karel/index.html | 8 +- .../recursion/karel/solution/index.html | 10 +- .../bottom-up-dp/index.html | 8 +- .../pyramid-slide-down/greedy/index.html | 8 +- .../recursion/pyramid-slide-down/index.html | 8 +- .../pyramid-slide-down/naive/index.html | 8 +- .../pyramid-slide-down/top-down-dp/index.html | 10 +- algorithms/tags/a-star/index.html | 24 +++ algorithms/tags/applications/index.html | 6 +- algorithms/tags/astar/index.html | 24 +++ algorithms/tags/backtracking/index.html | 6 +- algorithms/tags/balanced-trees/index.html | 6 +- algorithms/tags/bellman-ford/index.html | 26 +++ algorithms/tags/bfs/index.html | 6 +- algorithms/tags/bottom-up-dp/index.html | 6 +- algorithms/tags/brute-force/index.html | 26 +++ algorithms/tags/c/index.html | 6 +- algorithms/tags/cpp/index.html | 15 +- algorithms/tags/csharp/index.html | 6 +- algorithms/tags/dijkstra/index.html | 25 +++ algorithms/tags/dynamic-array/index.html | 6 +- .../tags/dynamic-programming/index.html | 15 +- algorithms/tags/exponential/index.html | 6 +- algorithms/tags/graphs/index.html | 6 +- algorithms/tags/greedy/index.html | 12 +- algorithms/tags/hash-tables/index.html | 6 +- algorithms/tags/index.html | 6 +- algorithms/tags/iterative/index.html | 6 +- algorithms/tags/iterators/index.html | 6 +- algorithms/tags/java/index.html | 6 +- algorithms/tags/karel/index.html | 6 +- algorithms/tags/postconditions/index.html | 6 +- algorithms/tags/python/index.html | 6 +- algorithms/tags/recursion/index.html | 6 +- algorithms/tags/red-black-trees/index.html | 6 +- algorithms/tags/solution/index.html | 6 +- algorithms/tags/sorting/index.html | 6 +- algorithms/tags/testing/index.html | 6 +- algorithms/tags/time-complexity/index.html | 6 +- algorithms/tags/top-down-dp/index.html | 6 +- algorithms/time-complexity/extend/index.html | 8 +- ...-meme-405d6b8dcc7aec5846fef402abfa8317.jpg | Bin 0 -> 86026 bytes assets/js/08dfa3a2.0462ec4c.js | 1 + assets/js/1535ede8.102142f5.js | 1 + assets/js/1535ede8.aa3b4147.js | 1 - assets/js/2af5d0a7.928c2eb4.js | 1 + assets/js/2fcf0558.14a64e69.js | 1 - assets/js/2fcf0558.a6f753b6.js | 1 + assets/js/354a7b72.257f6430.js | 1 - assets/js/354a7b72.becd0640.js | 1 + assets/js/3adcbc3a.481c535c.js | 1 + assets/js/3d92ba6e.e64b02a7.js | 1 + assets/js/493c0536.6ae62548.js | 1 + assets/js/520f8175.85515c7b.js | 1 - assets/js/520f8175.d9b4c84f.js | 1 + assets/js/595c7293.6c273bef.js | 1 + assets/js/595c7293.b89891f3.js | 1 - assets/js/5c15401e.e4b1c753.js | 1 + assets/js/698e2076.0fda5cee.js | 1 + ...cbca1.6248e0be.js => 6e3cbca1.5d0620d6.js} | 2 +- assets/js/7052c0bc.54d577f1.js | 1 + assets/js/7052c0bc.6b9d4e57.js | 1 - assets/js/794ef108.5b256546.js | 1 + assets/js/794ef108.9378da0c.js | 1 - assets/js/84d1e0d8.a5a56acc.js | 1 - assets/js/84d1e0d8.e078634a.js | 1 + assets/js/97a42631.7eff63e9.js | 1 + assets/js/97a42631.dd58f185.js | 1 - assets/js/a2ba8888.ab09cb54.js | 1 + assets/js/b1288602.2a7bb9cd.js | 1 + assets/js/b1288602.9422d997.js | 1 - assets/js/b8cbf382.6ba7c9a6.js | 1 - assets/js/b8cbf382.e3b79fad.js | 1 + assets/js/c4c4056e.3de7285f.js | 1 + assets/js/d05e838c.3caaf7e6.js | 1 + assets/js/d05e838c.ee3d8fcc.js | 1 - assets/js/dd841e73.afb9a531.js | 1 - assets/js/dd841e73.c1ec5d72.js | 1 + assets/js/df078f58.4f109cb4.js | 1 + assets/js/main.2a166133.js | 2 + ...CENSE.txt => main.2a166133.js.LICENSE.txt} | 0 assets/js/main.3450d297.js | 2 - assets/js/runtime~main.65095f6f.js | 1 + assets/js/runtime~main.81d405e9.js | 1 - blog/2023/08/02/copr/index.html | 6 +- blog/aoc-2022/1st-week/index.html | 6 +- blog/aoc-2022/2nd-week/index.html | 6 +- blog/aoc-2022/3rd-week/index.html | 6 +- blog/aoc-2022/4th-week/index.html | 6 +- blog/aoc-2022/intro/index.html | 6 +- blog/archive/index.html | 6 +- blog/index.html | 6 +- blog/leetcode/sort-diagonally/index.html | 6 +- blog/tags/admin/index.html | 6 +- blog/tags/advent-of-code-2022/index.html | 6 +- blog/tags/advent-of-code/index.html | 6 +- blog/tags/copr/index.html | 6 +- blog/tags/cpp/index.html | 6 +- blog/tags/index.html | 6 +- blog/tags/iterators/index.html | 6 +- blog/tags/leetcode/index.html | 6 +- blog/tags/red-hat/index.html | 6 +- blog/tags/rust/index.html | 6 +- blog/tags/vps/index.html | 6 +- blog/tags/🏭/index.html | 6 +- c/bonuses/seminar-03/index.html | 6 +- c/bonuses/seminar-04/index.html | 6 +- c/bonuses/seminar-05-06/index.html | 6 +- c/bonuses/seminar-08/index.html | 6 +- c/bonuses/seminar-10/index.html | 6 +- c/category/bonuses/index.html | 6 +- c/category/practice-exams/index.html | 6 +- c/index.html | 6 +- c/mr/index.html | 6 +- c/pexam/cams/index.html | 6 +- c/pexam/garbage_collect/index.html | 6 +- contributions/index.html | 6 +- cpp/category/exceptions-and-raii/index.html | 6 +- cpp/environment/index.html | 6 +- .../placeholders/index.html | 6 +- cpp/index.html | 6 +- .../graphs/iterative-and-iterators.tar.bz2 | Bin 1945 -> 1941 bytes .../graphs/iterative-and-iterators.tar.gz | Bin 1935 -> 1932 bytes files/algorithms/paths/bf-to-astar.tar.bz2 | Bin 0 -> 3161 bytes files/algorithms/paths/bf-to-astar.tar.gz | Bin 0 -> 2993 bytes files/algorithms/paths/bf-to-astar/.archive | 0 files/algorithms/paths/bf-to-astar/astar.hpp | 59 ++++++ files/algorithms/paths/bf-to-astar/bf.hpp | 136 +++++++++++++ .../algorithms/paths/bf-to-astar/dijkstra.hpp | 58 ++++++ files/algorithms/paths/bf-to-astar/graph.hpp | 108 ++++++++++ files/algorithms/paths/bf-to-astar/main.cpp | 50 +++++ files/algorithms/paths/bf-to-astar/makefile | 8 + files/algorithms/recursion/karel-1.tar.bz2 | Bin 5897 -> 5882 bytes files/algorithms/recursion/karel-1.tar.gz | Bin 6581 -> 6581 bytes .../recursion/pyramid-slide-down.tar.bz2 | Bin 1548 -> 1547 bytes .../recursion/pyramid-slide-down.tar.gz | Bin 1423 -> 1421 bytes .../algorithms/time-complexity/extend.tar.bz2 | Bin 4080 -> 4081 bytes .../algorithms/time-complexity/extend.tar.gz | Bin 3912 -> 3911 bytes files/c/bonuses/03.tar.bz2 | Bin 2652 -> 2640 bytes files/c/bonuses/03.tar.gz | Bin 2336 -> 2338 bytes files/c/bonuses/04.tar.bz2 | Bin 2533 -> 2538 bytes files/c/bonuses/04.tar.gz | Bin 2500 -> 2499 bytes files/c/bonuses/05-06.tar.bz2 | Bin 3641 -> 3645 bytes files/c/bonuses/05-06.tar.gz | Bin 3487 -> 3486 bytes files/c/bonuses/08.tar.bz2 | Bin 73546 -> 73527 bytes files/c/bonuses/08.tar.gz | Bin 106232 -> 106229 bytes files/c/bonuses/10.tar.bz2 | Bin 234863 -> 234814 bytes files/c/bonuses/10.tar.gz | Bin 230118 -> 230122 bytes ib002/category/paths-in-graphs/index.html | 11 ++ ib002/paths/bf-to-astar/astar/index.html | 11 ++ ib002/paths/bf-to-astar/bf/index.html | 11 ++ ib002/paths/bf-to-astar/dijkstra/index.html | 11 ++ ib002/paths/bf-to-astar/index.html | 11 ++ ib002/tags/a-star/index.html | 11 ++ ib002/tags/astar/index.html | 11 ++ ib002/tags/bellman-ford/index.html | 11 ++ ib002/tags/brute-force/index.html | 11 ++ ib002/tags/dijkstra/index.html | 11 ++ .../paths/bf-to-astar/bellman-ford-meme.jpg | Bin 0 -> 37548 bytes .../paths/bf-to-astar/dijkstra-meme.jpg | Bin 0 -> 86026 bytes index.html | 6 +- search/index.html | 6 +- sitemap.xml | 2 +- talks/index.html | 6 +- 185 files changed, 1524 insertions(+), 325 deletions(-) create mode 100644 algorithms/category/paths-in-graphs/index.html create mode 100644 algorithms/paths/bf-to-astar/astar/index.html create mode 100644 algorithms/paths/bf-to-astar/bf/index.html create mode 100644 algorithms/paths/bf-to-astar/dijkstra/index.html create mode 100644 algorithms/paths/bf-to-astar/index.html create mode 100644 algorithms/tags/a-star/index.html create mode 100644 algorithms/tags/astar/index.html create mode 100644 algorithms/tags/bellman-ford/index.html create mode 100644 algorithms/tags/brute-force/index.html create mode 100644 algorithms/tags/dijkstra/index.html create mode 100644 assets/images/dijkstra-meme-405d6b8dcc7aec5846fef402abfa8317.jpg create mode 100644 assets/js/08dfa3a2.0462ec4c.js create mode 100644 assets/js/1535ede8.102142f5.js delete mode 100644 assets/js/1535ede8.aa3b4147.js create mode 100644 assets/js/2af5d0a7.928c2eb4.js delete mode 100644 assets/js/2fcf0558.14a64e69.js create mode 100644 assets/js/2fcf0558.a6f753b6.js delete mode 100644 assets/js/354a7b72.257f6430.js create mode 100644 assets/js/354a7b72.becd0640.js create mode 100644 assets/js/3adcbc3a.481c535c.js create mode 100644 assets/js/3d92ba6e.e64b02a7.js create mode 100644 assets/js/493c0536.6ae62548.js delete mode 100644 assets/js/520f8175.85515c7b.js create mode 100644 assets/js/520f8175.d9b4c84f.js create mode 100644 assets/js/595c7293.6c273bef.js delete mode 100644 assets/js/595c7293.b89891f3.js create mode 100644 assets/js/5c15401e.e4b1c753.js create mode 100644 assets/js/698e2076.0fda5cee.js rename assets/js/{6e3cbca1.6248e0be.js => 6e3cbca1.5d0620d6.js} (57%) create mode 100644 assets/js/7052c0bc.54d577f1.js delete mode 100644 assets/js/7052c0bc.6b9d4e57.js create mode 100644 assets/js/794ef108.5b256546.js delete mode 100644 assets/js/794ef108.9378da0c.js delete mode 100644 assets/js/84d1e0d8.a5a56acc.js create mode 100644 assets/js/84d1e0d8.e078634a.js create mode 100644 assets/js/97a42631.7eff63e9.js delete mode 100644 assets/js/97a42631.dd58f185.js create mode 100644 assets/js/a2ba8888.ab09cb54.js create mode 100644 assets/js/b1288602.2a7bb9cd.js delete mode 100644 assets/js/b1288602.9422d997.js delete mode 100644 assets/js/b8cbf382.6ba7c9a6.js create mode 100644 assets/js/b8cbf382.e3b79fad.js create mode 100644 assets/js/c4c4056e.3de7285f.js create mode 100644 assets/js/d05e838c.3caaf7e6.js delete mode 100644 assets/js/d05e838c.ee3d8fcc.js delete mode 100644 assets/js/dd841e73.afb9a531.js create mode 100644 assets/js/dd841e73.c1ec5d72.js create mode 100644 assets/js/df078f58.4f109cb4.js create mode 100644 assets/js/main.2a166133.js rename assets/js/{main.3450d297.js.LICENSE.txt => main.2a166133.js.LICENSE.txt} (100%) delete mode 100644 assets/js/main.3450d297.js create mode 100644 assets/js/runtime~main.65095f6f.js delete mode 100644 assets/js/runtime~main.81d405e9.js create mode 100644 files/algorithms/paths/bf-to-astar.tar.bz2 create mode 100644 files/algorithms/paths/bf-to-astar.tar.gz create mode 100644 files/algorithms/paths/bf-to-astar/.archive create mode 100644 files/algorithms/paths/bf-to-astar/astar.hpp create mode 100644 files/algorithms/paths/bf-to-astar/bf.hpp create mode 100644 files/algorithms/paths/bf-to-astar/dijkstra.hpp create mode 100644 files/algorithms/paths/bf-to-astar/graph.hpp create mode 100644 files/algorithms/paths/bf-to-astar/main.cpp create mode 100644 files/algorithms/paths/bf-to-astar/makefile create mode 100644 ib002/category/paths-in-graphs/index.html create mode 100644 ib002/paths/bf-to-astar/astar/index.html create mode 100644 ib002/paths/bf-to-astar/bf/index.html create mode 100644 ib002/paths/bf-to-astar/dijkstra/index.html create mode 100644 ib002/paths/bf-to-astar/index.html create mode 100644 ib002/tags/a-star/index.html create mode 100644 ib002/tags/astar/index.html create mode 100644 ib002/tags/bellman-ford/index.html create mode 100644 ib002/tags/brute-force/index.html create mode 100644 ib002/tags/dijkstra/index.html create mode 100644 img/algorithms/paths/bf-to-astar/bellman-ford-meme.jpg create mode 100644 img/algorithms/paths/bf-to-astar/dijkstra-meme.jpg diff --git a/404.html b/404.html index eef186e..7094698 100644 --- a/404.html +++ b/404.html @@ -14,10 +14,10 @@ - - + + -
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

\ No newline at end of file diff --git a/algorithms/algorithms-correctness/postcondition-ambiguity/index.html b/algorithms/algorithms-correctness/postcondition-ambiguity/index.html index ec12c39..f68c46e 100644 --- a/algorithms/algorithms-correctness/postcondition-ambiguity/index.html +++ b/algorithms/algorithms-correctness/postcondition-ambiguity/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Vague postconditions and proving correctness of algorithms

Introduction

+

Vague postconditions and proving correctness of algorithms

Introduction

Source code used later on.

Implementation of select sort from the exercises

To implement select sort from the exercises and make it as easy to read as possible, I have implemented maximum function that returns index of the biggest element from the first nn elements.

@@ -123,6 +123,6 @@ This means hypothesis is randomly creating lists of integers and passing them to
% pytest -v test_sort.py
=================================== test session starts ====================================
platform linux -- Python 3.6.8, pytest-3.8.2, py-1.7.0, pluggy-0.13.1 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/xfocko/git/xfocko/ib002/postcondition-ambiguity, inifile:
plugins: hypothesis-5.16.1
collected 4 items

test_sort.py::test_select_sort[select_sort-check_vague_postcondition] PASSED [ 25%]
test_sort.py::test_select_sort[select_sort-check_postcondition] PASSED [ 50%]
test_sort.py::test_select_sort[broken_select_sort-check_vague_postcondition] PASSED [ 75%]
test_sort.py::test_select_sort[broken_select_sort-check_postcondition] FAILED [100%]

========================================= FAILURES =========================================
_________________ test_select_sort[broken_select_sort-check_postcondition] _________________

sorting_function = <function broken_select_sort at 0x7fac179308c8>
postcondition = <function check_postcondition at 0x7fac1786d1e0>

@given(lists(integers()))
> @settings(max_examples=1000)
@pytest.mark.parametrize(
"postcondition", [check_vague_postcondition, check_postcondition]
)
@pytest.mark.parametrize("sorting_function", [select_sort, broken_select_sort])
def test_select_sort(sorting_function, postcondition, numbers):

test_sort.py:132:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
test_sort.py:139: in test_select_sort
postcondition(numbers, result)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

original_arr = [0, 0], arr = [0, 1]

def check_postcondition(original_arr, arr):
if not arr:
return

# check ordering
for x, y in zip(arr, itertools.islice(arr, 1, len(arr))):
assert x <= y

# get counts from original list
original_counts = {}
for value in original_arr:
original_counts[value] = 1 + original_counts.get(value, 0)

# get counts from resulting list
counts = {}
for value in arr:
counts[value] = 1 + counts.get(value, 0)

# if arr is permutation of original_arr then all counts must be the same
> assert counts == original_counts
E assert {0: 1, 1: 1} == {0: 2}
E Differing items:
E {0: 1} != {0: 2}
E Left contains more items:
E {1: 1}
E Full diff:
E - {0: 1, 1: 1}
E + {0: 2}

test_sort.py:128: AssertionError
----------------------------------- Captured stdout call -----------------------------------
Falsifying example: test_select_sort(
sorting_function=<function test_sort.broken_select_sort>,
postcondition=<function test_sort.check_postcondition>,
numbers=[0, 0],
)
============================ 1 failed, 3 passed in 6.84 seconds ============================

We can clearly see that our broken select sort has passed the vague postcondition, but the explicit one was not satisfied.

Summary

-

For proving the correctness of the algorithm it is better to be explicit than prove that algorithm is correct even though it is not. Being explicit also allows you to test smaller chunks of code better.

+

For proving the correctness of the algorithm it is better to be explicit than prove that algorithm is correct even though it is not. Being explicit also allows you to test smaller chunks of code better.

\ No newline at end of file diff --git a/algorithms/category/algorithms-and-correctness/index.html b/algorithms/category/algorithms-and-correctness/index.html index 4558784..773cfcc 100644 --- a/algorithms/category/algorithms-and-correctness/index.html +++ b/algorithms/category/algorithms-and-correctness/index.html @@ -18,14 +18,14 @@ correctness. - - + + -
Skip to main content

Algorithms and Correctness

Materials related to basic ideas behind algorithms and proofs of their +

+

\ No newline at end of file diff --git a/algorithms/category/asymptotic-notation-and-time-complexity/index.html b/algorithms/category/asymptotic-notation-and-time-complexity/index.html index 82fe879..d6d0535 100644 --- a/algorithms/category/asymptotic-notation-and-time-complexity/index.html +++ b/algorithms/category/asymptotic-notation-and-time-complexity/index.html @@ -16,13 +16,13 @@ - - + + -
Skip to main content

Asymptotic Notation and Time Complexity

Materials related to asymptotic notation and time complexity. +

+

\ No newline at end of file diff --git a/algorithms/category/graphs/index.html b/algorithms/category/graphs/index.html index 8046b6f..104f057 100644 --- a/algorithms/category/graphs/index.html +++ b/algorithms/category/graphs/index.html @@ -16,15 +16,15 @@ - - + + -
Skip to main content

Graphs

Materials related to basic graph algorithms and graph problems. +

+

\ No newline at end of file diff --git a/algorithms/category/hash-tables/index.html b/algorithms/category/hash-tables/index.html index 9778ff9..45ebdbf 100644 --- a/algorithms/category/hash-tables/index.html +++ b/algorithms/category/hash-tables/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content
+
Skip to main content
\ No newline at end of file diff --git a/algorithms/category/paths-in-graphs/index.html b/algorithms/category/paths-in-graphs/index.html new file mode 100644 index 0000000..69636ae --- /dev/null +++ b/algorithms/category/paths-in-graphs/index.html @@ -0,0 +1,26 @@ + + + + + +Paths in Graphs | mf + + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/algorithms/category/recursion/index.html b/algorithms/category/recursion/index.html index a74b162..2e77fe6 100644 --- a/algorithms/category/recursion/index.html +++ b/algorithms/category/recursion/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content
+
Skip to main content
\ No newline at end of file diff --git a/algorithms/category/red-black-trees/index.html b/algorithms/category/red-black-trees/index.html index 8f73daf..ccd4a1a 100644 --- a/algorithms/category/red-black-trees/index.html +++ b/algorithms/category/red-black-trees/index.html @@ -16,15 +16,15 @@ - - + + -
Skip to main content

Red-Black Trees

Materials related to red-black trees. +

+

\ No newline at end of file diff --git a/algorithms/graphs/bfs-tree/index.html b/algorithms/graphs/bfs-tree/index.html index 342fab2..252fbac 100644 --- a/algorithms/graphs/bfs-tree/index.html +++ b/algorithms/graphs/bfs-tree/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Distance boundaries from BFS tree on undirected graphs

Introduction

+

Distance boundaries from BFS tree on undirected graphs

Introduction

As we have talked on the seminar, if we construct from some vertex uu BFS tree on an undirected graph, we can obtain:

  • lower bound of length of the shortest path between 2 vertices from the height difference
  • @@ -49,6 +49,6 @@

    Oops, we have gotten a new BFS tree, that has a height difference of 1.

    -
    tip

    Try to think about a way this can be generalized for shortening of minimal length 3 to minimal length 2 ;)

+
tip

Try to think about a way this can be generalized for shortening of minimal length 3 to minimal length 2 ;)

\ No newline at end of file diff --git a/algorithms/graphs/iterative-and-iterators/index.html b/algorithms/graphs/iterative-and-iterators/index.html index 0d61cbf..bdc66ba 100644 --- a/algorithms/graphs/iterative-and-iterators/index.html +++ b/algorithms/graphs/iterative-and-iterators/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Iterative algorithms via iterators

Introduction

+

Iterative algorithms via iterators

Introduction

@@ -44,6 +44,6 @@

Closer explanation of the iterator shenanigans follows. In the beginning, either start or when pushing new vertex, we are pushing an iterator that points just before the first successor. When populating lastVertex and successors in the while-loop, we take the element from the top of the stack. MoveNext returns true if there is an element, i.e. successor in this case. If it returns false we have nothing to do and we pop the vertex from the stack (also set finishing time and color). If we have successor we check if it has been already visited or not. If has not, we set discovery time and color accordingly, also we add it to stack.

Implementation

In case you want to play around with the code. At the beginning there is a link to the C# implementation that can be used. It has a basic representation of graph and includes BFS/DFS implementation in classes.

-

In Program.cs you can also find a method that returns graph we used on the seminar.

+

In Program.cs you can also find a method that returns graph we used on the seminar.

\ No newline at end of file diff --git a/algorithms/hash-tables/breaking/index.html b/algorithms/hash-tables/breaking/index.html index 6a423bf..976322c 100644 --- a/algorithms/hash-tables/breaking/index.html +++ b/algorithms/hash-tables/breaking/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Breaking Hash Table

We will try to break a hash table and discuss possible ways how to prevent such +

+
\ No newline at end of file diff --git a/algorithms/hash-tables/breaking/mitigations/index.html b/algorithms/hash-tables/breaking/mitigations/index.html index 37ded35..aea5a93 100644 --- a/algorithms/hash-tables/breaking/mitigations/index.html +++ b/algorithms/hash-tables/breaking/mitigations/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Possible Mitigations

There are multiple ways the issues created above can be mitigated. Still we can +

Possible Mitigations

There are multiple ways the issues created above can be mitigated. Still we can only make it better, we cannot guarantee the ideal time complexity…

For the sake of simplicity (and referencing an article by Neal Wu on the same topic; in references below) I will use the C++ to describe the mitigations.

@@ -80,6 +80,6 @@ implemented, the tree may be ordered by just the hash.

  1. Neal Wu. Blowing up unordered_map, and how to stop getting hacked on it.
  2. -
+
\ No newline at end of file diff --git a/algorithms/hash-tables/breaking/python/index.html b/algorithms/hash-tables/breaking/python/index.html index c9b6b37..bd5d99e 100644 --- a/algorithms/hash-tables/breaking/python/index.html +++ b/algorithms/hash-tables/breaking/python/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Breaking the Hash Table in Python

+

Breaking the Hash Table in Python

Our language of choice for bringing the worst out of the hash table is Python.

Let's start by talking about the hash function and why we've chosen Python for this. Hash function for integers in Python is simply identity, as you might've @@ -137,6 +137,6 @@ will collide).

Arbitrary-sized integers, they can get as big as your memory allows.

-
+
\ No newline at end of file diff --git a/algorithms/index.html b/algorithms/index.html index 58a9f0b..a250af1 100644 --- a/algorithms/index.html +++ b/algorithms/index.html @@ -14,15 +14,15 @@ - - + + -
Skip to main content

Introduction

In this part you can find “random” additional materials I have written over the +

Introduction

In this part you can find “random” additional materials I have written over the course of teaching Algorithms and data structures I.

It is a various mix of stuff that may have been produced as a follow-up on some question asked at the seminar or spontanously.

If you have some ideas for posts, please do not hesitate to submit them as issues -in the linked GitLab.

+in the linked GitLab.

\ No newline at end of file diff --git a/algorithms/paths/bf-to-astar/astar/index.html b/algorithms/paths/bf-to-astar/astar/index.html new file mode 100644 index 0000000..fa4d367 --- /dev/null +++ b/algorithms/paths/bf-to-astar/astar/index.html @@ -0,0 +1,104 @@ + + + + + +A* algorithm | mf + + + + + + + + + + + + + + +
Skip to main content

A* algorithm

Intro

+

Let's start by the recap of what we've achieved so far:

+
    +
  1. We have implemented a naïve brute-force algorithm that tries to relax paths +as long as there are any paths to be relaxed.
  2. +
  3. Then we have fixed an issue caused by negative loops that can result in +a non-terminating run of our brute-force method. At this moment we have made +some small arguments why are bounding is enough and doesn't prevent any +shortest path to not be discovered.
  4. +
  5. Finally we have converted our bounded brute-force algorithm into the +Bellman-Ford algorithm.
  6. +
  7. We have mentioned the worst-case time complexity of our bounded naïve +approach and also the Bellman-Ford algorithm. Our worst-case depended on the +fact that we assumed the worst possible ordering of the relaxations. However +we could also try to relax in the most ideal ordering which could result in a +faster algorithm and that's how we got to the Dijkstra's algorithm.
  8. +
+

Now the question is, could we improve the Dijkstra's algorithm to get even +better results? And the answer is maybe!

+

Dijkstra's algorithm chooses the next cheapest vertex for relaxing. This is good +as long as there is no additional information. However, imagine a roadmap of +some country. If you're in the middle of the map and you want to go south, it +doesn't make much sense for you to go to the north (in the opposite direction), +but a little bit might make sense, so that you can switch to highway and go much +faster.

+

The important question here is how to influence the algorithm, so that it does +choose the path that makes more sense rather than the one that costs the +least.

+

A* description

+

The A* algorithm can be considered a modification of Dijkstra's algorithm. The +cost is still the same, we cannot change it, right? However when we pick the +vertices from the heap, we can influence the order by some heuristic. In this +case, we introduce a function that can suggest how feasible the vertex is.

+

Roadmap heuristic

+

Let's have a look at the heuristic we could use for the roadmap example. There +are roads (the edges) and towns (the vertices). Cost could be an average time to +travel the road. What heuristic could we use to influence our algorithm to +choose a better ordering of the vertices when relaxing?

+

In the former example we've said that it doesn't make much sense to go in the +opposite direction than our goal is… We could choose the distance from our goal +as the heuristic, e.g. right now we're 100 km away from our goal, using this +road makes us 50 km away and using the other road we will be 200 km away.

+

Heuristic for our map

+

Our map is a bit simpler, but we can use a very similar principle. We will use +the Manhattan distance, which is defined in a following way:

+xaxb+yayb\vert x_a - x_b \vert + \vert y_a - y_b \vert +

Since we cannot move in diagonals, it makes sense to maintain the distance in +the actual steps from the goal.

+

Passing the heuristic

+

In our case, when we're using C++, we can just template the function that will +calculate the shortest path and pass the heuristic as a parameter.

+

Implementation

+

Actual implementation is very easy once we have the Dijkstra's algorithm:

+
auto astar(const graph& g, const vertex_t& source, const auto& h)
-> std::vector<std::vector<int>> {
// make sure that ‹source› exists
assert(g.has(source));

// initialize the distances
std::vector<std::vector<int>> distances(
g.height(), std::vector(g.width(), graph::unreachable()));

// initialize the visited
std::vector<std::vector<bool>> visited(g.height(),
std::vector(g.width(), false));

// ‹source› destination denotes the beginning where the cost is 0
auto [sx, sy] = source;
distances[sy][sx] = 0;

pqueue_t priority_queue{std::make_pair(0 + h(source), source)};
std::optional<pqueue_item_t> item{};
while ((item = popq(priority_queue))) {
auto [cost, u] = *item;
auto [x, y] = u;

// we have already found the shortest path
if (visited[y][x]) {
continue;
}
visited[y][x] = true;

for (const auto& [dx, dy] : DIRECTIONS) {
auto v = std::make_pair(x + dx, y + dy);
auto cost = g.cost(u, v);

// if we can move to the cell and it's better, relax¹ it and update queue
if (cost != graph::unreachable() &&
distances[y][x] + cost < distances[y + dy][x + dx]) {
distances[y + dy][x + dx] = distances[y][x] + cost;
pushq(priority_queue,
std::make_pair(distances[y + dy][x + dx] + h(v), v));
}
}
}

return distances;
}
+

Running on our map

+

For this algorithm I will also show the example of a call:

+
distances = astar(g, std::make_pair(1, 9), [](const auto& u) {
auto [x, y] = u;
return std::abs(1 - x) + std::abs(7 - y);
});
std::cout << "[A*] Cost: " << distances[7][1] << "\n";
+

First argument to the function is the graph itself. Second argument is the +source vertex where we start. And finally the lambda returns +Manhattan distance to the goal.

+

And we get the following result:

+
Normal cost: 1
Vortex cost: 5
Graph:
#############
#..#..*.*.**#
##***.....**#
#..########.#
#...###...#.#
#..#...##.#.#
#..#.*.#..#.#
#D...#....#.#
########*.*.#
#S..........#
#############
[Finite BF] Cost: 22
[Bellman-Ford] Cost: 22
[Dijkstra] Cost: 22
[A*] Cost: 22
+

Comparison

+

Now you may wonder how does it compare to the previous algorithms. Supposedly it +should be faster. Let's add counters and debugging output when we update +distance to our goal. And now if we run our code, we get the following output:

+
Normal cost: 1
Vortex cost: 5
Graph:
#############
#..#..*.*.**#
##***.....**#
#..########.#
#...###...#.#
#..#...##.#.#
#..#.*.#..#.#
#D...#....#.#
########*.*.#
#S..........#
#############
Relaxing path to goal in 40. relaxation
Relaxing path to goal in 68. relaxation
Relaxing path to goal in 89. relaxation
[Finite BF] Cost: 22
Relaxing path to goal in 40. relaxation
Relaxing path to goal in 68. relaxation
Relaxing path to goal in 89. relaxation
[Bellman-Ford] Cost: 22
Relaxing path to goal in 41. iteration
[Dijkstra] Cost: 22
Relaxing path to goal in 31. iteration
[A*] Cost: 22
+

From the output we can easily deduce that for both brute-force and Bellman-Ford, +which are in our case identical, we actually relax three times and for the last +time in the 89th iteration.

+

Dijkstra's algorithm manages to find the shortest path to our goal already in +the 41st iteration.

+

And finally after introducing some heuristic, we could find the shortest path +in the 31st iteration.

+
danger

Please keep in mind that choosing bad heuristic can actually lead to worse +results than using no heuristic at all.

+

Summary

+

And there we have it. We have made our way from the brute-force algorithm all +the way to more optimal ones. Hopefully we could notice how the small +improvements of the already existing algorithms made them much better.

+ + \ No newline at end of file diff --git a/algorithms/paths/bf-to-astar/bf/index.html b/algorithms/paths/bf-to-astar/bf/index.html new file mode 100644 index 0000000..bb90723 --- /dev/null +++ b/algorithms/paths/bf-to-astar/bf/index.html @@ -0,0 +1,184 @@ + + + + + +BF | mf + + + + + + + + + + + + + + +
Skip to main content

BF

Basic idea

+

We will ease in with our own algorithm to find the shortest path. We will +start by thinking about the ways we can achieve that. If we didn't have the * +cells, we could've easily run a BFS1 and be done with it. Maybe it is a good +place to start, or isn't, there is only one way to find out though.

+

How does the BFS work? We know the vertex where we start and we know the +vertex we want to find the shortest path to. Given this knowledge we +incrementally visit all of our neighbours and we do that over and over until the +destination is found2. Could we leverage this somehow?

+

Naïve approach

+

Well, we could probably start with all vertices being unreachable (having the +highest possible price) and try to improve what we've gotten so far until there +are no improvements. That sounds fine, we shall implement this. Since we are +going on repeat, we will name this function bf() as in brute-force, cause it +is trying to find it the hard way:

+
const static std::vector<vertex_t> DIRECTIONS =
std::vector{std::make_pair(0, 1), std::make_pair(0, -1),
std::make_pair(1, 0), std::make_pair(-1, 0)};

auto bf(const graph& g, const vertex_t& source, const vertex_t& destination)
-> int {
// ‹source› must be within the bounds
assert(g.has(source));

// ‹destination› must be within the bounds
assert(g.has(destination));

// we need to initialize the distances
std::vector<std::vector<int>> distances(
g.height(), std::vector(g.width(), graph::unreachable()));

// ‹source› destination denotes the beginning where the cost is 0
auto [sx, sy] = source;
distances[sy][sx] = 0;

// now we need to improve the paths as long as possible
bool improvement_found;
do {
// reset the flag at the beginning
improvement_found = false;

// go through all of the vertices
for (int y = 0; y < g.height(); ++y) {
for (int x = 0; x < g.width(); ++x) {
// skip the cells we cannot reach
if (distances[y][x] == graph::unreachable()) {
continue;
}

// go through the neighbours
auto u = std::make_pair(x, y);
for (const auto& [dx, dy] : DIRECTIONS) {
auto v = std::make_pair(x + dx, y + dy);
auto cost = g.cost(u, v);

// if we can move to the cell and it's better, relax¹ it
if (cost != graph::unreachable() &&
distances[y][x] + cost < distances[y + dy][x + dx]) {
distances[y + dy][x + dx] = distances[y][x] + cost;
improvement_found = true;
}
}
}
}
} while (improvement_found);

return distances[destination.second][destination.first];
}
+
Relaxation

I have made a brief mention of the relaxation in the comment in the code. You've +been probably thought that relaxation of an edge means that you found +a better solution to the problem.

In general it is an approximation technique that reduces the problem of +finding the path u → x1 → … → xn → v to subproblems +u → x1, x1 → x2, …, xn → v such that the sum of the costs of each step is +minimal.

+

Correctness

+

Is our solution correct? It appears to be correct… We have rather complicated +map and our algorithm has finished in an instant with the following output:

+
Normal cost: 1
Vortex cost: 5
Graph:
#############
#..#..*.*.**#
##***.....**#
#..########.#
#...###...#.#
#..#...##.#.#
#..#.*.#..#.#
#D...#....#.#
########*.*.#
#S..........#
#############
Cost: 22
+

If you have a better look at the map, you will realize that the cost 22 is the +one path skipping the * cells, since they cost more than going around.

+

We can play around a bit with it. The * cells can be even vortices that pull +you in with a negative price and let you propel yourself out 😉 Let's +change their cost to -1 then. Let's check what's the fastest path to the cell.

+
Normal cost: 1
Vortex cost: -1
Graph:
#############
#..#..*.*.**#
##***.....**#
#..########.#
#...###...#.#
#..#...##.#.#
#..#.*.#..#.#
#D...#....#.#
########*.*.#
#S..........#
#############
+

And we're somehow stuck… The issue comes from the fact that spinning around in +the vortices allows us to lower the cost infinitely. That's why after each +iteration there is still a possibility to lower the cost, hence the algorithm +doesn't finish. What can we do about this?

+
tip

This algorithm is correct as long as there are no negative loops, i.e. ways how +to lower the cost infinitely. Therefore we can also just lay a precondition that +requires no negative loops to be present.

+

Fixing the infinite loop

+

Our issue lies in the fact that we can endlessly lower the cost. Such thing must +surely happen in some kind of a loop. We could probably track the relaxations +and once we spot repeating patterns, we know we can safely terminate with some +results at least.

+

This approach will not even work on our 2D map, let alone any graph. Problem is +that the negative loops lower the cost in each iteration and that results +in lowering of the costs to the cells that are reachable from the said loops. +That's why this problem is relatively hard to tackle, it's not that easy to spot +the repeating patterns algorithmically.

+

On the other hand, we can approach this from the different perspective. Let's +assume the worst-case scenario (generalized for any graph):

+
+

Let KnK_n be complete graph. Let PP be the shortest path from v1v_1 to vnv_n +such that PP has n1n - 1 edges, i.e. the shortest path between the two chosen +vertices visits all vertices (not necessarily in order) and has the lowest +cost.

+

In such scenario assume the worst-case ordering of the relaxations (only one +helpful relaxation per iteration). In this case, in each iteration we find +the next edge on our path PP as the last. This means that we need +V1\vert V \vert - 1 iterations to find the shortest path PP.

+

Because we have laid PP as the shortest path from v1v_1 to vnv_n and it +visits all vertices, its prefixes are the shortest paths from v1v_1 to any +other vertex in our graph.

+

Therefore, we can safely assume that any relaxation after V1\vert V \vert - 1 +iterations, is the effect of a negative loop in the graph.

+
+

How can we leverage this? We will go through the edges only as many times as +cells we have. Let's adjust the code to fix the looping:

+
auto bf_finite(const graph& g, const vertex_t& source,
const vertex_t& destination) -> int {
// ‹source› must be within the bounds
assert(g.has(source));

// ‹destination› must be within the bounds
assert(g.has(destination));

// we need to initialize the distances
std::vector<std::vector<int>> distances(
g.height(), std::vector(g.width(), graph::unreachable()));

// ‹source› destination denotes the beginning where the cost is 0
auto [sx, sy] = source;
distances[sy][sx] = 0;

// now we only iterate as many times as cells that we have
for (int i = g.height() * g.width(); i > 0; --i) {
// go through all of the vertices
for (int y = 0; y < g.height(); ++y) {
for (int x = 0; x < g.width(); ++x) {
// skip the cells we cannot reach
if (distances[y][x] == graph::unreachable()) {
continue;
}

// go through the neighbours
auto u = std::make_pair(x, y);
for (const auto& [dx, dy] : DIRECTIONS) {
auto v = std::make_pair(x + dx, y + dy);
auto cost = g.cost(u, v);

// if we can move to the cell and it's better, relax¹ it
if (cost != graph::unreachable() &&
distances[y][x] + cost < distances[y + dy][x + dx]) {
distances[y + dy][x + dx] = distances[y][x] + cost;
}
}
}
}
}

return distances[destination.second][destination.first];
}
+

And we get the following result:

+
Normal cost: 1
Vortex cost: -1
Graph:
#############
#..#..*.*.**#
##***.....**#
#..########.#
#...###...#.#
#..#...##.#.#
#..#.*.#..#.#
#D...#....#.#
########*.*.#
#S..........#
#############
Cost: -236
+

The negative cost means that there is a way to propel ourselves via some +vortices. Let's adjust the cost of vortices back to the original 5 and check +whether our modified algorithm works as it did before. And it surely does yield +the 22 as before.

+
Refactoring

You can definitely notice some deep nesting in our code, to counter this +phenomenon I will convert the looping over x and y to one variable that can +be decomposed to x and y. It is a very common practice when working with 2D +arrays/lists to represent them as 1D. In our case:

i : 0 → width * height - 1
x = i % width
y = i / width
+

Bellman-Ford

+

If you have ever attended any Algorithms course that had path-finding in its +syllabus, you probably feel like you've seen the algorithm above before3… And +yes, the first algorithm I have proposed is a very dumb version of the +Bellman-Ford algorithm, it's dumb, because it loops 😉 After our “looping” +prevention we got to the point that is almost the Bellman-Ford with the one +exception that it doesn't report whether there are any negative cycles, it just +ends.

+

Let's have a look at a proper implementation of the Bellman-Ford algorithm:

+
auto bellman_ford(const graph& g, const vertex_t& source)
-> std::vector<std::vector<int>> {
// ‹source› must be within the bounds
assert(g.has(source));

// we need to initialize the distances
std::vector<std::vector<int>> distances(
g.height(), std::vector(g.width(), graph::unreachable()));

// ‹source› destination denotes the beginning where the cost is 0
auto [sx, sy] = source;
distances[sy][sx] = 0;

// now we only iterate as many times as cells that we have
for (int i = g.height() * g.width(); i > 0; --i) {
// go through all of the vertices
for (int v = g.height() * g.width() - 1; v >= 0; --v) {
int y = v / g.width();
int x = v % g.width();

// skip the cells we cannot reach
if (distances[y][x] == graph::unreachable()) {
continue;
}

// go through the neighbours
auto u = std::make_pair(x, y);
for (const auto& [dx, dy] : DIRECTIONS) {
auto v = std::make_pair(x + dx, y + dy);
auto cost = g.cost(u, v);

// if we can move to the cell and it's better, relax¹ it
if (cost != graph::unreachable() &&
distances[y][x] + cost < distances[y + dy][x + dx]) {
distances[y + dy][x + dx] = distances[y][x] + cost;
}
}
}
}

// now we check for the negative loops
bool relaxed = false;
for (int v = g.height() * g.width() - 1; !relaxed && v >= 0; --v) {
int y = v / g.width();
int x = v % g.width();

// skip the cells we cannot reach
if (distances[y][x] == graph::unreachable()) {
continue;
}

// go through the neighbours
auto u = std::make_pair(x, y);
for (const auto& [dx, dy] : DIRECTIONS) {
auto v = std::make_pair(x + dx, y + dy);
auto cost = g.cost(u, v);

// if we can move to the cell and it's better, relax¹ it
if (cost != graph::unreachable() &&
distances[y][x] + cost < distances[y + dy][x + dx]) {
relaxed = true;
std::cerr << "Found a negative loop\n";
break;
}
}
}

return distances;
}
+

And if we run it with our negative cost of entering vortices:

+
[Bellman-Ford] Found a negative loop
[Bellman-Ford] Cost: -240
+

On the Bellman-Ford

+

You might be surprised that we have managed to iterate from a brute-force method +that mindlessly tries to find a better path until there are no better paths left +all the way to the Bellman-Ford algorithm.

+

I always say that Bellman-Ford is a smart brute-force. BF is also an algorithm +that leverages dynamic programming. You might wonder how can it utilize DP if +it is “technically” a brute-force technique. Table with the shortest distances +is the thing that makes it DP.

+
+

I might not know the shortest path yet, but I do remember all of other paths, +and I can improve them, if possible.

+
+

That's where the beauty of both dynamic programming and relaxing gets merged +together and does its magic.

+

Proof of the correctness of the BF is done via induction to the number of +iterations. I would suggest to try to prove the correctness yourself and +possibly look it up, if necessary.

+

Also the correctness of the BF relies on the conclusion we've made when fixing +the infinite-loop on our naïve BF solution.

+

Time complexity

+

Let's have a short look at the time complexities of the presented algorithms:

+
    +
  1. +

    naïve approach: given that there are no negative loops, we are bound by the +worst-case ordering of the relaxations which results in

    +O(VE)\mathcal{O}(\vert V \vert \cdot \vert E \vert) +
  2. +
  3. +

    our naïve approach with the fixed count of iterations instead of the +do-while loop results in the same worst-case time complexity:

    +Θ(VE)\Theta(\vert V \vert \cdot \vert E \vert) +
  4. +
  5. +

    and finally the well-known Bellman-Ford's algorithm time complexity:

    +Θ(VE)\Theta(\vert V \vert \cdot \vert E \vert) +
  6. +
+

Small refactor

+

Since we are literally copy-pasting the body of the loops just for the sake of +relaxing, we can factor that part out into a separate function:

+
static auto _check_vertex(const graph& g,
std::vector<std::vector<int>>& distances, int v,
bool check_only = false) -> bool {
bool improvement_found = false;

// unpack the vertex coordinates
int y = v / g.width();
int x = v % g.width();

// skip the cells we cannot reach
if (distances[y][x] == graph::unreachable()) {
return false;
}

// go through the neighbours
auto u = std::make_pair(x, y);
for (const auto& [dx, dy] : DIRECTIONS) {
auto v = std::make_pair(x + dx, y + dy);
auto cost = g.cost(u, v);

// if we can move to the cell and it's better, relax¹ it
if (cost != graph::unreachable() &&
distances[y][x] + cost < distances[y + dy][x + dx]) {
if (check_only) {
return true;
}

distances[y + dy][x + dx] = distances[y][x] + cost;
improvement_found = true;
}
}

return improvement_found;
}
+

This function can be also used for checking the negative loops at the end of the +BF by using the check_only parameter to signal that we just want to know if +there would be any edge relaxed instead of performing the relaxation itself.

+

Then we can also see the differences between the specific versions of our +path-finding algorithms in a clear way:

+
auto bf(const graph& g, const vertex_t& source, const vertex_t& destination)
-> int {
// ‹source› must be within the bounds
assert(g.has(source));

// ‹destination› must be within the bounds
assert(g.has(destination));

// we need to initialize the distances
std::vector<std::vector<int>> distances(
g.height(), std::vector(g.width(), graph::unreachable()));

// ‹source› destination denotes the beginning where the cost is 0
auto [sx, sy] = source;
distances[sy][sx] = 0;

// now we need to improve the paths as long as possible
bool improvement_found;
do {
// reset the flag at the beginning
improvement_found = false;

// go through all of the vertices
for (int v = g.height() * g.width() - 1; v >= 0; --v) {
improvement_found = _check_vertex(g, distances, v) || improvement_found;
}
} while (improvement_found);

return distances[destination.second][destination.first];
}

auto bf_finite(const graph& g, const vertex_t& source,
const vertex_t& destination) -> int {
// ‹source› must be within the bounds
assert(g.has(source));

// ‹destination› must be within the bounds
assert(g.has(destination));

// we need to initialize the distances
std::vector<std::vector<int>> distances(
g.height(), std::vector(g.width(), graph::unreachable()));

// ‹source› destination denotes the beginning where the cost is 0
auto [sx, sy] = source;
distances[sy][sx] = 0;

// now we only iterate as many times as cells that we have
for (int i = g.height() * g.width(); i > 0; --i) {
// go through all of the vertices
for (int v = g.height() * g.width() - 1; v >= 0; --v) {
_check_vertex(g, distances, v);
}
}

return distances[destination.second][destination.first];
}

auto bellman_ford(const graph& g, const vertex_t& source)
-> std::vector<std::vector<int>> {
// ‹source› must be within the bounds
assert(g.has(source));

// we need to initialize the distances
std::vector<std::vector<int>> distances(
g.height(), std::vector(g.width(), graph::unreachable()));

// ‹source› destination denotes the beginning where the cost is 0
auto [sx, sy] = source;
distances[sy][sx] = 0;

// now we only iterate as many times as cells that we have
for (int i = g.height() * g.width(); i > 0; --i) {
// go through all of the vertices
for (int v = g.height() * g.width() - 1; v >= 0; --v) {
_check_vertex(g, distances, v);
}
}

// now we check for the negative loops
for (int v = g.height() * g.width() - 1; v >= 0; --v) {
if (_check_vertex(g, distances, v, true)) {
std::cerr << "[Bellman-Ford] Found a negative loop\n";
break;
}
}

return distances;
}

+
+
tip

You might've noticed that I've been using abbreviation BF interchangeably for +both Bellman-Ford and brute-force. If you think about the way Bellman-Ford +algorithm works, you should realize that in the worst case it's updating the +shortest path till there no shorter path exists, so in a sense, you could really +consider it a brute-force algorithm.

+

Footnotes

+
    +
  1. +

    Breadth-first search

    +
  2. +
  3. +

    Of course, there are some technicalities like keeping track of the visited +vertices to not taint the shortest path by already visited vertices.

    +
  4. +
  5. +

    or at least you should, LOL

    +
  6. +
+
+ + \ No newline at end of file diff --git a/algorithms/paths/bf-to-astar/dijkstra/index.html b/algorithms/paths/bf-to-astar/dijkstra/index.html new file mode 100644 index 0000000..c15a994 --- /dev/null +++ b/algorithms/paths/bf-to-astar/dijkstra/index.html @@ -0,0 +1,145 @@ + + + + + +Dijkstra's algorithm | mf + + + + + + + + + + + + + + +
Skip to main content

Dijkstra's algorithm

Intro

+

Let's rewind back to the small argument in the previous post about the fact that +we can safely bound the amount of iterations with relaxations being done.

+

We have said that assuming the worst-case scenario (bad order of relaxations) we +need at most V1\vert V \vert - 1 iterations over all edges. We've used that +to our advantage to bound the iterations instead of the do-while loop that +was a risk given the possibility of the infinite loop (when negative loops are +present in the graph).

+
tip

We could've possibly used both boolean flag to denote that some relaxation has +happened and the upper bound of iterations, for some graphs that would result in +faster termination.

Using only the upper bound we try to relax edges even though we can't.

+

Now the question arises, could we leverage this somehow in a different way? What +if we used it to improve the algorithm instead of just bounding the iterations? +Would that be even possible?

+

Yes, it would! And that's when Dijkstra's algorithm comes in.

+

Dijkstra's algorithm

+

I'll start with a well-known meme about Dijkstra's algorithm: +Dijkstra&#39;s algorithm meme

+

And then follow up on that with the actual backstory from Dijkstra himself:

+
+

What is the shortest way to travel from Rotterdam to Groningen, in general: +from given city to given city. It is the algorithm for the shortest path, +which I designed in about twenty minutes. One morning I was shopping in +Amsterdam with my young fiancée, and tired, we sat down on the café terrace to +drink a cup of coffee and I was just thinking about whether I could do this, +and I then designed the algorithm for the shortest path. As I said, it was +a twenty-minute invention. In fact, it was published in '59, three years +later. The publication is still readable, it is, in fact, quite nice. One of +the reasons that it is so nice was that I designed it without pencil and +paper. I learned later that one of the advantages of designing without pencil +and paper is that you are almost forced to avoid all avoidable complexities. +Eventually, that algorithm became to my great amazement, one of the +cornerstones of my fame.

+

— Edsger Dijkstra, in an interview with Philip L. Frana, Communications of the +ACM, 2001

+
+
Precondition

As our own naïve algorithm, Dijkstra's algorithm has a precondition that places +a requirement of no edges with negative weights in the graph. This +precondition is required because of the nature of the algorithm that requires +monotonically non-decreasing changes in the costs of shortest paths.

+

Short description

+

Let's have a brief look at the pseudocode taken from the Wikipedia:

+
function Dijkstra(Graph, source):
for each vertex v in Graph.Vertices:
dist[v] ← INFINITY
prev[v] ← UNDEFINED
add v to Q
dist[source] ← 0

while Q is not empty:
u ← vertex in Q with min dist[u]
remove u from Q

for each neighbor v of u still in Q:
alt ← dist[u] + Graph.Edges(u, v)
if alt < dist[v]:
dist[v] ← alt
prev[v] ← u

return dist[], prev[]
+

Dijkstra's algorithm works in such way that it always tries to find the shortest +paths from a vertex to which it already has a shortest path. This may result in +finding the shortest path to another vertex, or at least some path, till further +relaxation.

+

Given that we need to always choose the cheapest vertex, we can use a min +heap to our advantage which can further improve the time complexity of the +algorithm.

+

Used techniques

+

This algorithm leverages the dynamic programming technique that has already +been mentioned with regards to the Bellman-Ford algorithm and also greedy +technique. Let's talk about them both!

+

Dynamic programming technique comes from the fact that we are continuously +building on top of the shortest paths that we have found so far. We slowly build +the shortest paths from the given source vertex to all other vertices that are +reachable.

+

Greedy technique is utilized in such way that Dijkstra's algorithm always +improves the shortest paths from the vertex that is the closest, i.e. it tries +extending the shortest path to some vertex by appending an edge, such extended +path may (or may not) be the shortest path to another vertex.

+
Greedy algorithms

Greedy algorithms are algorithms that choose the most optimal action +at the moment.

+

The reason why the algorithm requires no edges with negative weights comes from +the fact that it's greedy. By laying the requirement of non-negative weights in +the graph we are guaranteed that at any given moment of processing outgoing +edges from a vertex, we already have a shortest path to the given vertex. This +means that either this is the shortest path, or there is some other vertex that +may have a higher cost, but the outgoing edge compensates for it.

+

Implementation

+

Firstly we need to have some priority queue wrappers. C++ itself offers +functions that can be used for maintaining max heaps. They also have generalized +version with any ordering, in our case we need reverse ordering, because we need +the min heap.

+
using pqueue_item_t = std::pair<int, vertex_t>;
using pqueue_t = std::vector<pqueue_item_t>;

auto pushq(pqueue_t& q, pqueue_item_t v) -> void {
q.push_back(v);
std::push_heap(q.begin(), q.end(), std::greater<>{});
}

auto popq(pqueue_t& q) -> std::optional<pqueue_item_t> {
if (q.empty()) {
return {};
}

std::pop_heap(q.begin(), q.end(), std::greater<>{});
pqueue_item_t top = q.back();
q.pop_back();

return std::make_optional(top);
}
+

And now we can finally move to the actual implementation of the Dijkstra's +algorithm:

+
auto dijkstra(const graph& g, const vertex_t& source)
-> std::vector<std::vector<int>> {
// make sure that ‹source› exists
assert(g.has(source));

// initialize the distances
std::vector<std::vector<int>> distances(
g.height(), std::vector(g.width(), graph::unreachable()));

// initialize the visited
std::vector<std::vector<bool>> visited(g.height(),
std::vector(g.width(), false));

// ‹source› destination denotes the beginning where the cost is 0
auto [sx, sy] = source;
distances[sy][sx] = 0;

pqueue_t priority_queue{std::make_pair(0, source)};
std::optional<pqueue_item_t> item{};
while ((item = popq(priority_queue))) {
auto [cost, u] = *item;
auto [x, y] = u;

// we have already found the shortest path
if (visited[y][x]) {
continue;
}
visited[y][x] = true;

for (const auto& [dx, dy] : DIRECTIONS) {
auto v = std::make_pair(x + dx, y + dy);
auto cost = g.cost(u, v);

// if we can move to the cell and it's better, relax¹ it and update queue
if (cost != graph::unreachable() &&
distances[y][x] + cost < distances[y + dy][x + dx]) {
distances[y + dy][x + dx] = distances[y][x] + cost;
pushq(priority_queue, std::make_pair(distances[y + dy][x + dx], v));
}
}
}

return distances;
}
+

Time complexity

+

The time complexity of Dijkstra's algorithm differs based on the backing data +structure.

+

The original implementation doesn't leverage the heap which results in +repetitive look up of the “closest” vertex, hence we get the following +worst-case time complexity in the Bachmann-Landau notation:

+Θ(V2)\Theta(\vert V \vert^2) +

If we turn our attention to the backing data structure, we always want the +“cheapest” vertex, that's why we can use the min heap, given that we use +Fibonacci heap we can achieve the following amortized time complexity:

+O(E+VlogV)\mathcal{O}(\vert E \vert + \vert V \vert \cdot \log{\vert V \vert}) +
Fibonacci heap

Fibonacci heap is known as the heap that provides Θ(1)\Theta(1) amortized +insertion and O(logn)\mathcal{O}(\log{n}) amortized removal of the top (either +min or max).

+

Running the Dijkstra

+

Let's run our code:

+
Normal cost: 1
Vortex cost: 5
Graph:
#############
#..#..*.*.**#
##***.....**#
#..########.#
#...###...#.#
#..#...##.#.#
#..#.*.#..#.#
#D...#....#.#
########*.*.#
#S..........#
#############
[Finite BF] Cost: 22
[Bellman-Ford] Cost: 22
[Dijkstra] Cost: 22
+

OK, so it seems to be working just fine. Now the question arises:

+
+

What happens when we have negative weights in our graph?

+
+

Busting the myth about looping Dijkstra

+

One of the very common misconception about Dijkstra's algorithm is that it loops +infinitely when you have negative weights or loops in the graph. Well, if we use +our propelling vortices, not only we have the negative weights, but also the +negative loops. Let's run our code! Our first naïve approach was actually +looping:

+
Normal cost: 1
Vortex cost: -1
Graph:
#############
#..#..*.*.**#
##***.....**#
#..########.#
#...###...#.#
#..#...##.#.#
#..#.*.#..#.#
#D...#....#.#
########*.*.#
#S..........#
#############
[Finite BF] Cost: -240
[Bellman-Ford] Found a negative loop
[Bellman-Ford] Cost: -240
[Dijkstra] Cost: 14
+

Well, it definitely doesn't loop. How much does 14 make sense is a different +matter.

+
Variations

There are multiple variations of the Dijkstra's algorithm. You can implement +it in such way that with negative weights or loops it loops infinitely, but it +can be countered. In our case we keep the track of the vertices that already got +a shortest path established via the visited, that's how even multiple entries +for one vertex in the heap are not an issue.

+

Summary

+

Now we have an algorithm for finding the shortest path that is faster than our +original naïve brute-force or Bellman-Ford. However we need to keep in mind its +requirement of no negative weights for correct functioning.

+

You can also see how we used our thought process of figuring out the worst-case +time complexity for the naïve or Bellman-Ford algorithm to improve the original +path-finding algorithms.

+ + \ No newline at end of file diff --git a/algorithms/paths/bf-to-astar/index.html b/algorithms/paths/bf-to-astar/index.html new file mode 100644 index 0000000..e748a91 --- /dev/null +++ b/algorithms/paths/bf-to-astar/index.html @@ -0,0 +1,64 @@ + + + + + +From BF to A* | mf + + + + + + + + + + + + + + +
Skip to main content

From BF to A*

Intro

+

We will delve into the details and ideas of the most common path-finding +algorithms. For the purpose of demonstrating some “features” of the improved +algorithms, we will use a 2D map with some rules that will allow us to show cons +and pros of the shown algorithms.

+

Let's have a look at the example map:

+
#############
#..#..*.*.**#
##***.....**#
#..########.#
#...###...#.#
#..#...##.#.#
#..#.*.#..#.#
#....#....#.#
########*.*.#
#...........#
#############
+

We can see three different kinds of cells:

+
    +
  1. # which represent walls, that cannot be entered at all
  2. +
  3. * which represent vortices that can be entered at the cost of 5 coins
  4. +
  5. . which represent normal cells that can be entered for 1 coin (which is the +base price of moving around the map)
  6. +
+

Let's dissect a specific position on the map to get a better grasp of the rules:

+
 .
#S*
.
+

We are standing in the cell marked with S and we have the following options

+
    +
  • move to the north (.) with the cost of 1 coin,
  • +
  • move to the west (#) is not allowed because of the wall,
  • +
  • move to the east (*) is allowed with the cost of 5 coins, and finally
  • +
  • move to the south (.) with the cost of 1 coin.
  • +
+
info

Further on I will follow the same scheme for marking cells with an addition of +D to denote the destination to which we will be finding the shortest path.

+

Boilerplate

+

For working with this map I have prepared a basic structure for the graph in C++ +that will abstract some of the internal workings of our map, namely:

+
    +
  • remembers the costs of moving around
  • +
  • provides a simple function that returns price for moving directly between +two positions on the map
  • +
  • allows us to print the map out, just in case we'd need some adjustments to be +made
  • +
+

We can see the graph header here:

+
#ifndef _GRAPH_HPP
#define _GRAPH_HPP

#include <cmath>
#include <limits>
#include <ostream>
#include <utility>
#include <vector>

using vertex_t = std::pair<int, int>;

struct graph {
graph(const std::vector<std::vector<char>>& map)
: map(map),
_height(static_cast<int>(map.size())),
_width(map.empty() ? 0 : static_cast<int>(map[0].size())) {}

static auto unreachable() -> int { return UNREACHABLE; }
static auto normal_cost() -> int { return NORMAL_COST; }
static auto vortex_cost() -> int { return VORTEX_COST; }

auto cost(const vertex_t& u, const vertex_t& v) const -> int {
auto [ux, uy] = u;
auto [vx, vy] = v;

auto hd = std::abs(ux - vx) + std::abs(uy - vy);
switch (hd) {
// ‹u = v›; staying on the same cell
case 0:
return 0;
// ‹u› and ‹v› are neighbours
case 1:
break;
// ‹u› and ‹v› are not neighbouring cells
default:
return UNREACHABLE;
}

// boundary check
if (vy < 0 || vy >= _height || vx < 0 || vx >= _width) {
return UNREACHABLE;
}

switch (map[vy][vx]) {
case '#':
return UNREACHABLE;
case '*':
return VORTEX_COST;
default:
return NORMAL_COST;
}
}

auto width() const -> int { return _width; }
auto height() const -> int { return _height; }
auto has(const vertex_t& v) const -> bool {
auto [x, y] = v;
return (0 <= y && y < _height) && (0 <= x && x < _width);
}

friend std::ostream& operator<<(std::ostream& os, const graph& g);

private:
std::vector<std::vector<char>> map;
int _height, _width;

const static int UNREACHABLE = std::numeric_limits<int>::max();
// XXX: modify here to change the price of entering the vortex
const static int VORTEX_COST = 5;
const static int NORMAL_COST = 1;
};

std::ostream& operator<<(std::ostream& os, const graph& g) {
for (const auto& row : g.map) {
for (const char cell : row) {
os << cell;
}
os << "\n";
}

return os;
}

#endif /* _GRAPH_HPP */
+
Source code

You can find all the source code referenced in this series +here.

+

Let's finally start with some algorithms!

+ + \ No newline at end of file diff --git a/algorithms/rb-trees/applications/index.html b/algorithms/rb-trees/applications/index.html index 4c6a3e3..3e642c5 100644 --- a/algorithms/rb-trees/applications/index.html +++ b/algorithms/rb-trees/applications/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Použití červeno-černých stromů

Použití

+

Použití červeno-černých stromů

Použití

Červeno-černé stromy jsou celkem oblíbené pro implementaci ADT množiny nebo slovníku za předpokladu, že nad vkládanými klíči existuje uspořádání. Jazyky níže implementují dané datové struktury v 2 variantách a to:

+
\ No newline at end of file diff --git a/algorithms/rb-trees/rules/index.html b/algorithms/rb-trees/rules/index.html index 08b14ed..3e3323f 100644 --- a/algorithms/rb-trees/rules/index.html +++ b/algorithms/rb-trees/rules/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

On the rules of the red-black tree

Introduction

+

On the rules of the red-black tree

Introduction

Have you ever thought about the red-black tree rules in more depth? Why are they formulated the way they are? How come they keep the tree balanced? Let's go through each of the red-black tree rules and try to change, break and contemplate about @@ -191,6 +191,6 @@ complexity for the operations, but having more relaxed rules.

red nodes still exist

-
+
\ No newline at end of file diff --git a/algorithms/recursion/karel/index.html b/algorithms/recursion/karel/index.html index 669d838..6843fe2 100644 --- a/algorithms/recursion/karel/index.html +++ b/algorithms/recursion/karel/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Recursion and backtracking with Robot Karel

\ No newline at end of file diff --git a/algorithms/recursion/karel/solution/index.html b/algorithms/recursion/karel/solution/index.html index 4920b54..62fe2ff 100644 --- a/algorithms/recursion/karel/solution/index.html +++ b/algorithms/recursion/karel/solution/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Solving the maze problem

+

Solving the maze problem

We will go through the given problem the same way as I have suggested in the previous post.

Summary of the problem

@@ -93,7 +93,7 @@ successful in finding the exit. However there is one precondition of our solution that we haven't spoken about.

We are silently expecting the maze not to have any loops. Example of such maze can be the maze666.kw:

-
┌─────────┬─┐
│. . . . .│.│
│ ┌─────┐ │ │
│.│. . .│.│.│
│ │ │ │ │ │
│.│.│. . .│.│
│ │ │ └─┤
│.│.│. . . 1│
│ │ │ │ ┌─┤
│.│. . .│.│.│
│ └─────┘ │ │
│. > . . .│.│
└─────────┴─┘
+
┌─────────┬─┐
│. . . . .│.│
│ ┌─────┐ │ │
│.│. . .│.│.│
│ │ │ │ │ │
│.│.│. . .│.│
│ │ │ └─┤
│.│.│. . . 1│
│ │ │ │ ┌─┤
│.│. . .│.│.│
│ └─────┘ │ │
│. > . . .│.│
└─────────┴─┘

If you try running our solution on this map, Karel just loops and never finds the solution. Let's have a look at the loop he gets stuck in:

┌─────────┬─┐
│* * * * *│.│
│ ┌─────┐ │ │
│*│* * *│*│.│
│ │ │ │ │ │
│*│*│. * *│.│
│ │ │ └─┤
│*│*│. * * 1│
│ │ │ │ ┌─┤
│*│* * *│*│.│
│ └─────┘ │ │
│* * * * *│.│
└─────────┴─┘
@@ -115,6 +115,6 @@ we need to be careful not to confuse the exit with already visi

which is usually very easy matter

-
+
\ No newline at end of file diff --git a/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html b/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html index a308f4f..b9ab384 100644 --- a/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html +++ b/algorithms/recursion/pyramid-slide-down/bottom-up-dp/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Bottom-up dynamic programming

+

Bottom-up dynamic programming

If you try to think in depth about the top-down DP solution, you might notice that the core of it stands on caching the calculations that have been already done on the lower “levels” of the pyramid. Our bottom-up implementation will be @@ -77,6 +77,6 @@ successor and represents the way we can enhance the existing implementation.

one was not correct, thus the quotes

-
+
\ No newline at end of file diff --git a/algorithms/recursion/pyramid-slide-down/greedy/index.html b/algorithms/recursion/pyramid-slide-down/greedy/index.html index 484167d..c6a1612 100644 --- a/algorithms/recursion/pyramid-slide-down/greedy/index.html +++ b/algorithms/recursion/pyramid-slide-down/greedy/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Greedy solution

We will try to optimize it a bit. Let's start with a relatively simple greedy +

Greedy solution

We will try to optimize it a bit. Let's start with a relatively simple greedy approach.

Greedy algorithms

Greedy algorithms can be described as algorithms that decide the action on the optimal option at the moment.

@@ -56,6 +56,6 @@ we choose it.

Our final sum is: 1 + 3 + 7 + 11 + 16 = 38, but in the bottom left cell we have a 99 that is bigger than our whole sum.

-
tip

Dijkstra's algorithm is a greedy algorithm too, try to think why it is correct.

+
tip

Dijkstra's algorithm is a greedy algorithm too, try to think why it is correct.

\ No newline at end of file diff --git a/algorithms/recursion/pyramid-slide-down/index.html b/algorithms/recursion/pyramid-slide-down/index.html index 5f3334c..05a0b58 100644 --- a/algorithms/recursion/pyramid-slide-down/index.html +++ b/algorithms/recursion/pyramid-slide-down/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Introduction to dynamic programming

In this series we will try to solve one problem in different ways.

+

Introduction to dynamic programming

In this series we will try to solve one problem in different ways.

Problem

The problem we are going to solve is one of CodeWars katas and is called Pyramid Slide Down.

@@ -48,6 +48,6 @@ other differences will lie only in the solutions of the problem. You can see the

cause why not, right!?

-
+
\ No newline at end of file diff --git a/algorithms/recursion/pyramid-slide-down/naive/index.html b/algorithms/recursion/pyramid-slide-down/naive/index.html index 7fc10f1..835fcce 100644 --- a/algorithms/recursion/pyramid-slide-down/naive/index.html +++ b/algorithms/recursion/pyramid-slide-down/naive/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Naïve solution

Our naïve solution consists of trying out all the possible slides and finding +

Naïve solution

Our naïve solution consists of trying out all the possible slides and finding the one with maximum sum.

public static int longestSlideDown(int[][] pyramid, int row, int col) {
if (row >= pyramid.length || col < 0 || col >= pyramid[row].length) {
// BASE: We have gotten out of bounds, there's no reasonable value to
// return, so we just return the ‹MIN_VALUE› to ensure that it cannot
// be maximum.
return Integer.MIN_VALUE;
}

if (row == pyramid.length - 1) {
// BASE: Bottom of the pyramid, we just return the value, there's
// nowhere to slide anymore.
return pyramid[row][col];
}

// Otherwise we account for the current position and return maximum of the
// available “slides”.
return pyramid[row][col] + Math.max(
longestSlideDown(pyramid, row + 1, col),
longestSlideDown(pyramid, row + 1, col + 1));
}

public static int longestSlideDown(int[][] pyramid) {
// We start the slide in the top cell of the pyramid.
return longestSlideDown(pyramid, 0, 0);
}

As you can see, we have 2 overloads:

@@ -73,6 +73,6 @@ therefore we can just sum the ones.
warning

It would've been more complicated to get an exact result. In the equation above we are assuming that the width of the pyramid is bound by the height.

-

Hopefully we can agree that this is not the best we can do. 😉

+

Hopefully we can agree that this is not the best we can do. 😉

\ No newline at end of file diff --git a/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html b/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html index a1977ae..787c161 100644 --- a/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html +++ b/algorithms/recursion/pyramid-slide-down/top-down-dp/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Top-down dynamic programming

+

Top-down dynamic programming

Top-down dynamic programming is probably the most common approach, since (at least looks like) is the easiest to implement. The whole point is avoiding the unnecessary computations that we have already done.

@@ -60,7 +60,7 @@ the pyramid:

is done only once.

For each calculation we take 2 values from the cache and insert one value. Because we have chosen TreeMap, these 3 operations have logarithmic time -complexity and therefore this step is equivalent to 3log2n3 \cdot \log_2{n}.

+complexity and therefore this step is equivalent to 3log2n3 \cdot \log_2{n}.

However for the sake of simplicity, we are going to account only for the insertion, the reason is rather simple, if we include the 2 retrievals here, it will be interleaved with the next step, therefore it is easier to keep the @@ -132,6 +132,6 @@ complexity of this approach. I'll give you a hint:

-
+
\ No newline at end of file diff --git a/algorithms/tags/a-star/index.html b/algorithms/tags/a-star/index.html new file mode 100644 index 0000000..431fa40 --- /dev/null +++ b/algorithms/tags/a-star/index.html @@ -0,0 +1,24 @@ + + + + + +One doc tagged with "a star" | mf + + + + + + + + + + + + + + +
Skip to main content

One doc tagged with "a star"

View All Tags

From BF to A*

Figuring out shortest-path problem from the BF to the A* algorithm. +

+ + \ No newline at end of file diff --git a/algorithms/tags/applications/index.html b/algorithms/tags/applications/index.html index 1eb82d9..e29794e 100644 --- a/algorithms/tags/applications/index.html +++ b/algorithms/tags/applications/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "applications"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/astar/index.html b/algorithms/tags/astar/index.html new file mode 100644 index 0000000..b7983e7 --- /dev/null +++ b/algorithms/tags/astar/index.html @@ -0,0 +1,24 @@ + + + + + +One doc tagged with "astar" | mf + + + + + + + + + + + + + + +
Skip to main content

One doc tagged with "astar"

View All Tags

A* algorithm

Moving from Dijkstra's algorithm into the A* algorithm. +

+ + \ No newline at end of file diff --git a/algorithms/tags/backtracking/index.html b/algorithms/tags/backtracking/index.html index 5355e4c..8d61ace 100644 --- a/algorithms/tags/backtracking/index.html +++ b/algorithms/tags/backtracking/index.html @@ -14,12 +14,12 @@ - - + +
Skip to main content

2 docs tagged with "backtracking"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/balanced-trees/index.html b/algorithms/tags/balanced-trees/index.html index dc2b102..01a8d3f 100644 --- a/algorithms/tags/balanced-trees/index.html +++ b/algorithms/tags/balanced-trees/index.html @@ -14,12 +14,12 @@ - - + +
Skip to main content

2 docs tagged with "balanced trees"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/bellman-ford/index.html b/algorithms/tags/bellman-ford/index.html new file mode 100644 index 0000000..7e12f68 --- /dev/null +++ b/algorithms/tags/bellman-ford/index.html @@ -0,0 +1,26 @@ + + + + + +2 docs tagged with "bellman ford" | mf + + + + + + + + + + + + + + +
Skip to main content

2 docs tagged with "bellman ford"

View All Tags

BF

Solving the shortest path problem with a naïve approach that turns into +something. +

From BF to A*

Figuring out shortest-path problem from the BF to the A* algorithm. +

+ + \ No newline at end of file diff --git a/algorithms/tags/bfs/index.html b/algorithms/tags/bfs/index.html index 1729b95..2421be4 100644 --- a/algorithms/tags/bfs/index.html +++ b/algorithms/tags/bfs/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "bfs"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/bottom-up-dp/index.html b/algorithms/tags/bottom-up-dp/index.html index fd9eabe..c7e9e7a 100644 --- a/algorithms/tags/bottom-up-dp/index.html +++ b/algorithms/tags/bottom-up-dp/index.html @@ -14,12 +14,12 @@ - - + +
Skip to main content

2 docs tagged with "bottom-up-dp"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/brute-force/index.html b/algorithms/tags/brute-force/index.html new file mode 100644 index 0000000..ee453c9 --- /dev/null +++ b/algorithms/tags/brute-force/index.html @@ -0,0 +1,26 @@ + + + + + +2 docs tagged with "brute force" | mf + + + + + + + + + + + + + + +
Skip to main content

2 docs tagged with "brute force"

View All Tags

BF

Solving the shortest path problem with a naïve approach that turns into +something. +

From BF to A*

Figuring out shortest-path problem from the BF to the A* algorithm. +

+ + \ No newline at end of file diff --git a/algorithms/tags/c/index.html b/algorithms/tags/c/index.html index ae5036c..0a2aef2 100644 --- a/algorithms/tags/c/index.html +++ b/algorithms/tags/c/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "c"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/cpp/index.html b/algorithms/tags/cpp/index.html index a0ff871..805e190 100644 --- a/algorithms/tags/cpp/index.html +++ b/algorithms/tags/cpp/index.html @@ -3,7 +3,7 @@ -3 docs tagged with "cpp" | mf +7 docs tagged with "cpp" | mf @@ -14,13 +14,18 @@ - - + + -
Skip to main content

3 docs tagged with "cpp"

View All Tags

Breaking Hash Table

How to get the linear time complexity in a hash table. +

7 docs tagged with "cpp"

View All Tags

A* algorithm

Moving from Dijkstra's algorithm into the A* algorithm. +

BF

Solving the shortest path problem with a naïve approach that turns into +something. +

Breaking Python

Actually getting the worst-case time complexity in Python. +

From BF to A*

Figuring out shortest-path problem from the BF to the A* algorithm.

+

\ No newline at end of file diff --git a/algorithms/tags/csharp/index.html b/algorithms/tags/csharp/index.html index e4edbdf..b180c87 100644 --- a/algorithms/tags/csharp/index.html +++ b/algorithms/tags/csharp/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "csharp"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/dijkstra/index.html b/algorithms/tags/dijkstra/index.html new file mode 100644 index 0000000..0def4d2 --- /dev/null +++ b/algorithms/tags/dijkstra/index.html @@ -0,0 +1,25 @@ + + + + + +2 docs tagged with "dijkstra" | mf + + + + + + + + + + + + + + +
Skip to main content

2 docs tagged with "dijkstra"

View All Tags

From BF to A*

Figuring out shortest-path problem from the BF to the A* algorithm. +

+ + \ No newline at end of file diff --git a/algorithms/tags/dynamic-array/index.html b/algorithms/tags/dynamic-array/index.html index 9befe75..a616811 100644 --- a/algorithms/tags/dynamic-array/index.html +++ b/algorithms/tags/dynamic-array/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "dynamic array"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/dynamic-programming/index.html b/algorithms/tags/dynamic-programming/index.html index efeff20..446f06b 100644 --- a/algorithms/tags/dynamic-programming/index.html +++ b/algorithms/tags/dynamic-programming/index.html @@ -3,7 +3,7 @@ -3 docs tagged with "dynamic-programming" | mf +7 docs tagged with "dynamic programming" | mf @@ -14,13 +14,18 @@ - - + + -
Skip to main content

3 docs tagged with "dynamic-programming"

View All Tags

Bottom-up DP solution

Bottom-up DP solution of the Pyramid Slide Down. +

7 docs tagged with "dynamic programming"

View All Tags

A* algorithm

Moving from Dijkstra's algorithm into the A* algorithm. +

BF

Solving the shortest path problem with a naïve approach that turns into +something. +

From BF to A*

Figuring out shortest-path problem from the BF to the A* algorithm.

+

\ No newline at end of file diff --git a/algorithms/tags/exponential/index.html b/algorithms/tags/exponential/index.html index 0d385fa..e93b067 100644 --- a/algorithms/tags/exponential/index.html +++ b/algorithms/tags/exponential/index.html @@ -14,12 +14,12 @@ - - + +
Skip to main content

2 docs tagged with "exponential"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/graphs/index.html b/algorithms/tags/graphs/index.html index 8cb6070..482900a 100644 --- a/algorithms/tags/graphs/index.html +++ b/algorithms/tags/graphs/index.html @@ -14,12 +14,12 @@ - - + +
Skip to main content

2 docs tagged with "graphs"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/greedy/index.html b/algorithms/tags/greedy/index.html index 4e713d1..1a5424f 100644 --- a/algorithms/tags/greedy/index.html +++ b/algorithms/tags/greedy/index.html @@ -3,7 +3,7 @@ -2 docs tagged with "greedy" | mf +4 docs tagged with "greedy" | mf @@ -14,12 +14,14 @@ - - + + -
Skip to main content

2 docs tagged with "greedy"

View All Tags

Greedy solution

Greedy solution of the Pyramid Slide Down. +

4 docs tagged with "greedy"

View All Tags

From BF to A*

Figuring out shortest-path problem from the BF to the A* algorithm. +

+

\ No newline at end of file diff --git a/algorithms/tags/hash-tables/index.html b/algorithms/tags/hash-tables/index.html index 1a969d3..99f15c9 100644 --- a/algorithms/tags/hash-tables/index.html +++ b/algorithms/tags/hash-tables/index.html @@ -14,13 +14,13 @@ - - + +
Skip to main content

3 docs tagged with "hash-tables"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/index.html b/algorithms/tags/index.html index 5e539eb..ad8f329 100644 --- a/algorithms/tags/index.html +++ b/algorithms/tags/index.html @@ -14,10 +14,10 @@ - - + + -
Skip to main content
+
Skip to main content
\ No newline at end of file diff --git a/algorithms/tags/iterative/index.html b/algorithms/tags/iterative/index.html index 93c9d5a..46cff49 100644 --- a/algorithms/tags/iterative/index.html +++ b/algorithms/tags/iterative/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "iterative"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/iterators/index.html b/algorithms/tags/iterators/index.html index d72a7c3..1432ba3 100644 --- a/algorithms/tags/iterators/index.html +++ b/algorithms/tags/iterators/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "iterators"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/java/index.html b/algorithms/tags/java/index.html index 46e5757..12c8f47 100644 --- a/algorithms/tags/java/index.html +++ b/algorithms/tags/java/index.html @@ -14,8 +14,8 @@ - - + +
Skip to main content

5 docs tagged with "java"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/karel/index.html b/algorithms/tags/karel/index.html index 23e0eac..73e4fc0 100644 --- a/algorithms/tags/karel/index.html +++ b/algorithms/tags/karel/index.html @@ -14,12 +14,12 @@ - - + +
Skip to main content

2 docs tagged with "karel"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/postconditions/index.html b/algorithms/tags/postconditions/index.html index a788cec..3a803ed 100644 --- a/algorithms/tags/postconditions/index.html +++ b/algorithms/tags/postconditions/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "postconditions"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/python/index.html b/algorithms/tags/python/index.html index 508f8f4..a25e9a1 100644 --- a/algorithms/tags/python/index.html +++ b/algorithms/tags/python/index.html @@ -14,8 +14,8 @@ - - + +
Skip to main content

7 docs tagged with "python"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/recursion/index.html b/algorithms/tags/recursion/index.html index 17763ca..9044d56 100644 --- a/algorithms/tags/recursion/index.html +++ b/algorithms/tags/recursion/index.html @@ -14,8 +14,8 @@ - - + +
Skip to main content

5 docs tagged with "recursion"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/red-black-trees/index.html b/algorithms/tags/red-black-trees/index.html index 43c041b..fa05a57 100644 --- a/algorithms/tags/red-black-trees/index.html +++ b/algorithms/tags/red-black-trees/index.html @@ -14,12 +14,12 @@ - - + +
Skip to main content

2 docs tagged with "red-black trees"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/solution/index.html b/algorithms/tags/solution/index.html index b5e1ec2..8923f0a 100644 --- a/algorithms/tags/solution/index.html +++ b/algorithms/tags/solution/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "solution"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/sorting/index.html b/algorithms/tags/sorting/index.html index 22f85bc..4c8828d 100644 --- a/algorithms/tags/sorting/index.html +++ b/algorithms/tags/sorting/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "sorting"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/testing/index.html b/algorithms/tags/testing/index.html index 58a2e9b..1fee8ab 100644 --- a/algorithms/tags/testing/index.html +++ b/algorithms/tags/testing/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "testing"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/time-complexity/index.html b/algorithms/tags/time-complexity/index.html index 3bcedef..1335d14 100644 --- a/algorithms/tags/time-complexity/index.html +++ b/algorithms/tags/time-complexity/index.html @@ -14,11 +14,11 @@ - - + +
Skip to main content

One doc tagged with "time complexity"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/tags/top-down-dp/index.html b/algorithms/tags/top-down-dp/index.html index 90d9b30..3f1e22c 100644 --- a/algorithms/tags/top-down-dp/index.html +++ b/algorithms/tags/top-down-dp/index.html @@ -14,12 +14,12 @@ - - + +
Skip to main content

2 docs tagged with "top-down-dp"

View All Tags
+

\ No newline at end of file diff --git a/algorithms/time-complexity/extend/index.html b/algorithms/time-complexity/extend/index.html index f2dc4ad..6ff6278 100644 --- a/algorithms/time-complexity/extend/index.html +++ b/algorithms/time-complexity/extend/index.html @@ -16,11 +16,11 @@ - - + + -
Skip to main content

Time complexity of ‹extend›

Introduction

+

Time complexity of ‹extend›

Introduction

Each year there is a lot of confusion regarding time complexity of the extend operation on the lists in Python. I will introduce two specific examples from previous year and also will try to explain it on one of the possible implementations of extend operation.

Technicalities

At the beginning we should clear some of the “myths” regarding extending of the lists. There is a common misunderstanding regarding differences between a += b, a.extend(b) and a + b.

@@ -90,6 +90,6 @@ elements from b.

If we have a look at the extend implementation in this dynamic array example:

void dynamic_array_extend(struct dynamic_array_t *arr, struct dynamic_array_t *src)
{
if (arr == NULL || src == NULL)
{
return;
}

for (size_t i = 0; i < src->count; i++)
{
dynamic_array_push_back(arr, dynamic_array_at(src, i));
}
}

Apart from checking edge cases, we can notice that we run for-loop over the elements from the other array and add them one-by-one to the arr. Time complexity of this operation is time dependant on the src array.

-

In this specific implementation, you could also resize the memory allocated for the array in one go and copy whole src array in one go. However even if you did so, it would be still dependant on the size of the src array. Cause you still need to copy count(src)elementSize(src)\texttt{count}(src) \cdot \texttt{elementSize}(src) bytes. From that we can assume that for specific instance of array the elementSize(src)\texttt{elementSize}(src) is fixed, therefore we consider it a constant. That way we are getting O(count(src))\mathcal{O}(\texttt{count}(src)) as a time complexity of our extend operation.

+

In this specific implementation, you could also resize the memory allocated for the array in one go and copy whole src array in one go. However even if you did so, it would be still dependant on the size of the src array. Cause you still need to copy count(src)elementSize(src)\texttt{count}(src) \cdot \texttt{elementSize}(src) bytes. From that we can assume that for specific instance of array the elementSize(src)\texttt{elementSize}(src) is fixed, therefore we consider it a constant. That way we are getting O(count(src))\mathcal{O}(\texttt{count}(src)) as a time complexity of our extend operation.

\ No newline at end of file diff --git a/assets/images/dijkstra-meme-405d6b8dcc7aec5846fef402abfa8317.jpg b/assets/images/dijkstra-meme-405d6b8dcc7aec5846fef402abfa8317.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ee512ee369273fdedf211be59acedbf92235d8c2 GIT binary patch literal 86026 zcmdqIWmsIzvM@S8Ai)ycCAeF#;O_43?(Q1gCAhmYxVr}T!7T(IG`MrgyYGAUId|{7 z&-4BLx@T5**Q!n*HwTJ0OlPu4D>q~7-*RH z?_oZ`A;H1H!os0_{DgpniH3!RiH3oJgHJ|?gG+*kf$^F4GYL5b6*Uz$Asr(fB_kOn z73Ciy5bxi=hx-7B3I~TuiGzVd`G1^V`vAxvAVE+)P!PlbNMr~oWQf-R04@Lm009jF z_-_dY0`eX7d#JaYIB#tHmHv4b0ut&S4D{;?009aD0Eq;J1OPyQKLd*R|B3Ry)zESm ztcbM~{bW6+`^P{)Z#xF7%gE#dnZ;1*NzU)9a-tM@XL`7?lB+vjKuo$z9$hzdj}7hL z*YqAsUjF}?IK04cJ=3meyv>p$iaEe=7hN6zC@rC1Lyh~yJhOF*{^JXc zHD$)ajN@O~9)OWThxvyxj{pF9B9 zWSXZQ7K@E5It~n7beNp9Dd9IxiyB$O;d@i*HY4=bdg@YVdmBUgta}A=&<8;UatM>0 zN)qkF4gS*yD7-GGQVs^{J4ZManbNMAD?vvVBc97LWAPDA+jPMW)F{r%;2R?uHKR@3!c^^WVPHRT?7` zlZhNU|5%jrE-Tw1?B*_Rs6hd>P|AZ1v@x(}A6TUfP%MbOqG@<%C_}V_!-p45m4T9E z7h^}3WHl^$OD*dZ6B%5`Q6fKkDl6BT431W7dIi|3p;Gt9nv69SD(TE^zauOI-wr_K zTiyhFJiP+6-T65~u#+Y^LlSqCmN8&4({@a<@$6a;#h+qf#N97^d+|8-ekmN-I)BHV zq@meZvu#|pc0|lgvz_#De$+LyN#fw0RkQG8Jkq?tEjlp7o%X(c_g-YiF-CSz+%&ZH2LKdP z5Oh7}L}6_D5?eIivVww$2s&EPLa;e{?jH#(6D$G%;HKdc0RS4wL?8g#96+teM2Q9f zsQRnEJrAMz2Ma<|wFn(eS+hk;GeY?f;2+8SHjx8nm9PL?EbZt$XlSywah5-(R=rRk zZ2#d_fSqaF*3@mlSJ3HW&S;Tv8FUQ3%b3YP{0Mna7S@$zNK5 zB}2EG#7gRHxyw?-IQ8YTm@EjkrY@SotY#vPAH!@9C%#Cv!PI?`)i$fZMa1Zj&ML`R z-EncF%s@dym3N`ueoW7{(#$ei)tQ>i53z_z+Z{G04H4>X8~N;bGV-;O9>djrG9S`y zbfCzj=Who7DlI?-J+xHH!*CSQ~V+?Kmp+VlHFmxQ$AbK@NhCEQ7#Yb`{GC68FK{eAh;|G^IA zYA}^104}iz1UC)PrqV=%rbYvrD=0|W0aV9AbBaW$}+vwdt>95S8F=Q+9;9C)H15 zcSUZyi-vfoypCrX-tFY8eh_qWcBP-tjLELm7Fhd#@bmvR8t_7?N8$??!EB;U9#ylc z%eu^lBebTHo)<4ULn0e5CB<|mFgNJ1r=o87$J~Ye$rA2qT{6Fhk}<|gkitL_+stbYx*w7FotXy^Vgl_C?FzO3wrC2qg_<66@HUxx}|c_iys4la;EKQKy`*bPkC zcjm<6NP+965M;_}LBcLp77o7#Vq8@dA7%bryh3c*O#}xZvm@}jfvBCL6Bk0bb@hoH zUjYiEZ1|s*P``xIUL3IyIq~=J>xhfaZ?8;j#EEC^j!Wb4EKB<4exX?oQ#-DeA)PzTf*ZoppRc zdp<&99UQzj3dM{Jo3?}e|3c;80N`i@BcgO|K;;Iz0S#r6{%Fby3Xo~s43qXqeQgJ&aqe7J;WZw&uS^`FDler_|z{w2z@_85&e(xm7(Q zF`%j!{hb=#HV<{y89o*-7XYWsf?F*QjSirahirf=SCB6fLC2`VO6TA~)ScY2v84Q? z#3QKxD*XSZ`_J+Xo(uTvz5j!;kRUG|Kdz`5a)wyPu_rMzMV+X~)D-=lqng}&cOV?8 zCQXs9fo;C&=RXPj|JM**369MhQANaDJ?5jKzZ0QPtyf57WQHx!b}Gn(fNP7356oS$ zdtLscwEj&V!W@83`PP6?Oe%u=rYYZQBUwtVshwLUSPoZ8T_j>t_MfF5rh9VfH))}h zt6ojiF7~nl?P%O`;UY?<4G%0|rsk}Uv6=@i0wPKwZ=0W2W~_O4iuUM}k#W)je(PkR z`vabOyyp*Aukpu^G$*tL#P}&F<2ud;rn={HK6^&NWu_xfMlG{fQng<^PPhIZ@xLqI zoG8eo-12~OxETe>;FRgX;SLSW1)vH6Z%U+hXOg6jdaZk1vwYuZr*avzV8j21Cp2`$ z-2Xup!b+=>6v!I#TMmjSHV)_Ho8s(Vw?4p9bSX~>YXp!BOf9xt!JH|P8Pmzuu8TZa zv=&THu!Yj7qlS`eJN_Z`PIGZecx z0VO^ZnxytAw#FjK*`_esqw!tdb#|ovjZR7@8$S(XL<*@q*y(G5!CPjTnMoIXcc<8o znH};$=O{ret4jHz_DFoCaLO!wnTkt#rlsQCyz9-; zb;=h_5v#)dT5Cr=-yC*Ky8L-O@x=2C(=c21=nq z<47_csNI)7jydY%5{Ks-H7E3quA0vB>SCbQhe8N+hTN$pV=>Wm5tUCv(e|RbH;XM` z(2(}w6;OOGWW`iA<~r9wqL-Kb(WW7J2Wdi2v~03$rc}h9f`yxi2eJ?S%T?Kg6GdRo zj%=wABPRwE^88hA>E*ieH=`@f%p(_?JiHiZ%goy^R*IP6e8^eC7bV=O$CiS(kCJgw zy8ay5eeRg6_RuY@>hoqr&Dmg81Z^00TD)D=kn+;}KrLI=A2$(DNI$0SxSi&PM2>b3 zw!Mp)Yojqm17uq*!K-gR2ZUX0bF{}o(ia+x=^-(vXAcmPHnCIIl=o!RF4q?;8E^fA zNeeo5=l!PZ{TZuqYu(&{6=}!&^;u^ckHorV{EjKMk(mDPUbfET=BlDfC*GJg8BL?p z_uqMPn46VKTgA#itZ^f}E@wv{;+C7{cYjJXTt$gpXEz2w{+Hhbbr59`BWW!^3l#tKj;2GP^_%7D6dvC@+y7$#gvo~;fgv_P|a!tEZ z)6-+ai$;AYT8he{?7ZvyB8e1u;YhFcmIb@rDw@@eM8fu_(8!{`;r#YPOp^=2VV0}t zkf)^^R(gzQyqZo8y#ZJP37}=)Jhb}bZK;!g*_7er*o4jN)Z;wtNAo-?L<85u1~OR| zP7j@`o7OA`mbZyC|G#Dw%9;Z5JMIe^!cC4+WXxE;J+u2845hKz>bRac^q&8hq z-+W&ZqAprUzbr81rXkNU5goMmYsdZ3{nP{4R?rsC%WZIHrk~bMN51o8@y?Urx_6Rs z2l*bNXkpJi`(E=TJfR@@(Pco)tm7&wy<*CQ|1ak+_$`!GkO%y!i}3%Yz99ede6=Ez zBBhS6c&eHX-sVlN6@;tLx=KV)7$|C|2`tm&(%0IZUeJkYrYlpSR87j$oDE(GBqT2M z<1(sbbBXmN$gn}bv*Y&Z@Z`2_+NR`3D>d4I5Riv>3ldbDK>ssH`>R*LU+b)AvfsIo zznfp%N~)c(2GDE^>DD6t&24noDv{C_u}hmK8Ter$bl4ujg4>Q|wV@d|B&8>=Asc2D zUMbt%jz|f$-yk^Mecfh0Nr$(J%v!p}BRfjEF9afc?&K3cz|a)Ua2E!~Lz9{kU9kwj zh;WYO@lAc1#Jq~#q-cuJG1_$i&_9kKU1NxC8G#jI0ytm94K@c@JxjO!H2bqHh4E|G zaQ2abXLP_f4Xe1H&?v|j0J&N!KfuDP@g|+OW|6L#(nn==IC}#+yJsil@SG2zp}m&h zA0|`vGVjcp9X*}r_iaXh-~6t|1-6U^%ec(IE;>h{uHa6)ypvjW^7vMj_K0`HsrB8d z%yp46>b_lk`P1>`E3{?u%}yd>RQ>;b7@3 zDyfmCEDcO@noEfB_d-lliJ5d1XW5`etYP*O7$Ryz^AS!82dYYjwPcHUpFNF+a1-Gq z+=*alCN!$rF;J-T=WM)x^WaB4+G_G;5 zzrjOL@^x)YG*aaY(iunT{E=}Vd;$~R#!JL!6q)97D|=(;hUyfay1Q^d5=+N+?0 zqZv_mGsT|0W_%sYg#@4**9z*Cte3yD<{?RmgcJ9LS2+ACZpR(B@lmO2>fxkIl=D9C zD8)y&OqrfPwyn|TMi0&Z%FAgnO|pq&xvdieI}xk+e;a|xt&|7jOr9Wx%J#OJ1j*>55wbkf{1YhrC~{@ZvPSFHmJ3-?j- z=mwo7X-zrWrXFlTy9sBoH@#qF_s)&PmD}jT5@(I)eDThf(&{&RB1_6CO!jkQaXXG5+1mW-AVDG*E`GX&CSq zCw3({g~l58dzw{gKYl-;Pc5!*KX2@wU?e`iC^i;pltSlXfN#p72Ci6PbxaKQ)-2JK;jYtDwe|hJWKVsWfhs(*o5_ea73I@5Tg2^UbnW`e znSo#}CnFIPYV~oq^J9q*TR&A@=XnrCVk>MR^eorA+DZy$F-}3lS0HrfGa+IY# zp!1IyRBQWWTi2yXI?3YgNC2_{KqH{}w!^Bze|d#-lJq`fHdr7w4xl2S38hj0HYJb^ z==p*D#KEB4Qb2jY?mq&gzZCG1U99D7ED~ zJ@oOB*VM_5E$JvR`^a`P^A8t)zYHoL0B>O;02(s)4JiL#aTf%C>09vl^9=@gQ}c-( za-QF(->T@jtS~Oaj&c-pu5v=lm(T z>ZWkugIcErnlU@Wt(ww+p3G#nrob#Pv0+z2B3nJNn%Jv11Hf>9K0kv4p~m{mYq-~t zz396J%wIF`2WpTJcX2w%WUWP9X$D9+A313`rmHV4=E z*1QRN!-y2i({2(%doX9n-sq~#-wvDPI5|C>ok214+q^bewF^{oLxeUH_{@*TO4mX6 zAkq%-FqD+A4!2XFP^q@5hL4hlnmic2Gvl7qbS8 zAi;0r+O!u3&5#h&8?h%g5dxlh9hp<~hCbL2b_TmpQBUC$SXii2W{PS(lZ<+3tXxz<1UUK_cwJrK2!%OB1o zuzEvRR+_=|V=2F4zlB|(AQ#ON1ynFN$6WOs^flCO>L8`;6L|MDI`VE~Mlz_M zl^f0=G@j=^uiWH@uLR{9Usw_&$0PNF*$Gn!j^d2xo!t2zMw+hCHGG-p$Tr?6_*AE5C!) zXXobv8I@c$8Cc<4B8O+!)l>6%O#F*q1td;#r6e zkqb<&?nm2chKZ?15?t7TUu1CX1duLTHq1K3<~6AxWyr}HsOi&)!{0iIOU;3{-z4c8 z(yEREWMhtKtC8(xp(k9F>o_f&f4$6>JF)v}c^?ORGBl)B|CI4m(sV<;rC5^|My6J1 z&27t6GhnkRst}ev1y`V~NX;W97o$!EQ&tYPioY-jw1A5n9-nD=I5DUC0Yy1QSZgJ;r4B%(8}S#;hI=`Ww{B%H-GBfXYnL;aT;p zN!!}T7$;891J1~_7(8p|b6lsMbFz%7A8-aUu7+g9tbHqEZ(=f=Gw^u`^%rI7)YieH zn5(Addml8?dNgdylxgCH7tp?xbb@uPzkY5eKj|#XtV`{rQh)f`L!=e@0x=reK2gPk zFDkky=iDG{Ja=~;(9;sN~>@_>~D zWK?QFGIIFj@W2t4!W3)`kJqJRIz*tUyP;_Wyw;&F&=#CN!aA-}{X9^^@2!3OSXhbz zedY4?3T1S!Eg(!OSGD{#hUPCZwC~zowvanu#I>#ca&P%qLiA0$xjT)Qr&S_+ zw}+|w@*P-f?INEunX9q7R=n`V&9IYCuK=pKW%)%4;;VHYo5n^^S|kKMq=ctj@pcnW zvCVu2B@otmbPS)jm@l)?ii6R)&IItZt*6YK1soMiE-aFeEmx<}VOd1ue*uDcgp#2X zrWmS9IJ3xxG6M1o$Ja8t8|wnV#?IH&+$Jn!RELEJ6Az_LB%)qS4$iaW%HH4*38OhO zlemMnq5OdCTcc7HloD_P$|B4cLkvm--{Qw6DFqk4dBu~O%>@lGlczcl$D^3ikhgDY z^CP>ozcgQdD^mk}N28fSW+1~XugCb2?gqafZOU^WN415Ro0$fQ=~bEGy@rcto43`y zZ`O87I)I{pNAVS4XEf72=I#=Ea<|!N{R+q^OOH8ncIf~qThSG9 zagY`P_JQfkQw#>lqZ~LsRN@-80)NkaXE1akju?qzi_xt!FxN%A0GmDlcyD zVQW@;>sn1Q!I_gk=ddl!kp5P@;;?L}JL!<>6=3yqN82*t>u{haX!%Z^Lq7H zQ^zZqL7q8I3M3?R(ekbMv^BD(Jkl~TWrS&oxP$8E$B*j-E_BxTqHOXv>saFZ5-;2H z^V!crf*a5v$|d*8etfB0uGETz7aX~8)5@HW5SgB$54KjZh#Q%Qa?2nQ7weTiYtm8a zfNHt@g+6>}wK%8_pqB`9ubBIazHM&5u$mH&3+xutW)A<f0fHk=%Pl_<|2$B8|^F)l(>wI$X_}71|g$Q1!6E{s5K_EgOc>OJBnx=EEu-DxK3B z4D${W$Q0?+BNn5KNe7chBs{hTm}l4da;(TB4*SEZc4#8LFP=Af-gwF2a6<<}Kx*Vl zSNo%t*Eu)^;>2Clv`lsaO5dmI7_ z6qOlmW@#MSwgp7nvVpo%V9u91f6cFbefrA1Q$;D`8m4FhE^rqH_Vy4xX772e@#Y2n zX1|u(uNKo#sCZI;I_e!Mz2R6UlC;U&@EWnvG?Cs@jYrRXMy>aQ>FP>5{xwOuBrJDI90N6 z75wAM%gChLXvg`baii1O&S%4}OPDIJ;N+q#O5%R%BF^JmWV>q4j{;7q_8v-`NbQlM_^T@5Pj%E|E9oAi0)I()R;%*fqjz!y$n- z)}uxC?TTpChV-ECm`l9z5Q#s!eTy2DtXHcrmLAYOY;-cBE-OmQAT?99*XKweCj9vI zP2$TxEY3OFH_~5qHw~@^fZ@e7qAhXp+Mse*>+bzjK$c4@1I)Od8>8B6^Zu$Vyz$`f z>!>g0D0~IiW|vm4fZoYGy5O|AUqxRYvKw!GB&F22I1Fg3-rsWuRrF^mff`C{+MI4| z4g5alpM%@Az$SV8r%8ubF-ekzytmJxg4vg)jeT518G8&el#2<)jziWbG0EXZLRki~ z_Y)hFb7VPo@w1WQ3WtN#KVnq|RPmd=dE;LJ^lmb9Yhc}YTbIy_EY4^QIjB1qOwOuH z?MkxJHn@TJrPo3qT|OS2R_KmAkuvaNX)&TZ-_1a^)f%d*j!oHuZ~ajw8h*I@5P|H>--8hzcRj| zP)9LfU3JbI8oL<)Bm9uwWz|vrnZ86GOQAk=<)a#rADbg2I?Pc`>o8wF`_oB`Scg1t z!3W!mR4W|jOed*AfUFgm@#2YGl1q^iI`qSMuA{89vnO3LFx-=qz4aP06 zQA}}Z54($mQGzd31mAwm0iuD$-gW$aLRZ(&;c+YFHB-Gh!IoM$DoGqfUM z38#T01iVTI#rxXat%p=;bQh{a`nal(WqYI9*U&E6!aQHoI`u@az*%6=w68}}Szjyc zj0Q92KsCQC*&3Y{9qOCw6x2p!U96>dw}lrOObjzhVf7dvlvOLpp)_zXR;T%xdiual z6(_3(F=6nxGYiCm#|i(CV<)&ceJ01icOqJHhOX$Pk{B zSvVYjfpTYC8(+!I@23lr=1{xtX1|Xc_^nK+1Wfp?yRq!+tEVS7!mf{oT<$NvlbaSj zR{ho-l3)q~A*;P2%+sft&3rAT;rnc8GNpoejKIjiR^;mujtiKrM>Gt;@ z+}YB>SA_!>F5Z55%V%FDjG6Lz4|ded)D9O4@5?4&Z`Z}TQDUm4;0CRkPdwX8r*9+B z`@WVN1Sjt+ygdA-BvY+?{#4x2EoS%BX#mpeyg8c$R$K3U!S+@z*MQt80fIDtziiH` zhEIV@UjYthL%$bhJ3rrfvS$CDC#=63Sa6g>qA&J)SvC)ksVwY+H)47ADu@;Rg$15? z1uVBo-NfKO$k$DuXmVv{dy=c4TwoEo@a7Ib4*M=JH$CFF}Zy3vq~ zIl78H&6U~}liNR&Q4X&VA~MM}fSp^_NoE;)rV60>rNMdxs(`_zWl`HGmFQe~SnX8?6Bp~!6y*X+PQBY`8GEw} zT*7*zvg8uvmAvV-S*Vh!6^#Vh@KH6;NXa;d#(Lugsp8y}=_I;`mLg91XHr23-W9g5HI#2~E7& zR#kg`Ohwu^vC;>RCP?*VXOYfgUQbc3Y1L1~sB{pr=WuHIA)9OaYOs6R)4_n{#veX1 z*QSVjB_T?rO;&=V(_(eB`{M8wu*OmGCFXSDyU6&V;$U6f@sq_Xz|q`<`i!q{%mHD3 zdiygjr}o?vLt`L*k08O_UkO+(|Q0-Z>kVWs^!tu53{slPjVyYq`mBWGaN%j#@%(4oRL zU#MT(Z;UEm7GPf8GO8MOdsB`wT#oEv^-2fVD?l$T>{({&5x}>#_70b;u-cCIo1V-M z;SsfAoAzTDw+oNW+I=6HvEwd%wEOWOY{oeajX<8pgZgP4zC0OXOaU7k8KKFL)aCIi zE0kFx-2mn&{45!lG!YfA(GDZw6HBmHWd^mLhP~g)En%W6qztxpv7UFvr*-ILk>o`^ ziJ+W~dIJ<0^OhziJf~5RkN4=2w^k^(b)kWQr)R5Ctzako_T;s-w>Jdp1wTN9*^@Wn z$c5ol{}m9*_2%7djxef{A#Beiu{-e`hYCEM8gsI%_P=2}_&u7jG|cN{O?f$Ux^fv` zIx!aM<4RW#N+|_KANtF>V7A}fBd@ahJ?hC9(NR{NSjNhbD{NYNuPTQ{TuY11v-4RT z^6eC)5#I2YJa@mjH`d^sl{T}R?4swDSHN%QoXd5kM>QGWx$ejPYl8K=;~6%j+yNZ5 zSwyoApY%wSLIM4VHn?DqDb=2mWoG1$^huay#^2Yz%qBzmp&6?_v09_)B7DvD%x5p_ z1%vwV=obJMXb#K4f@w@1WJh9>{%K5zrs|4-hNL67tC-e>jc<_$)Duie63>o+F5M$S#%RQaX}K zMS9N7Z2x=DKb>&-eX^w&7vuJi;W+q|9ro1a-%5nv3W@J=0H0K-_Aq~>HA_s>2b1zx zNi9>MUVShr$VM5eF!u^z>S3Nc@OWMjG4XqfFEaEH@q8~>jRATnIrpd=R5jh9?dCmQ zaeyX|3cH@^=w0SZQ(Ed^3l1{Qp!3jy-~9gEQP-P))L<~!031whg?}ENy*7-?BTW`0 zGulTf>hdeIgrx3`yO!dZzoww(TBp3COt~NUM8uHxBwn=87LFpy;w3Y8=~yQG{%{5g zi#YTZaAOoD*c(#8ee0hMQI3Y@jY37I&+knBjgfdn9m(_rCb`|e2zgwoS$gEZUgPF64dzzq+og*!O#E2SBp)08?(KBI^0z&00v=)o})5Z`Iyg{?tp zo>R=b?TwN0zY;V^^}R!7nfa6$Q^m`84mDLCIHs0Tvn?X=GG&`gH{MQQC!8=`^633( z#4xOJv_{HYz)|RZ(a)E)IV}n+n0Jzz{jB%!$sCZ3`8^FL3PukF>PfpOFP~(<+i2Z! z!%SW^kP_vIiN(s_bs#nydH8>U*mo*uHXyAo&?w@+X*ZS+l&Q(yd=?eRgG;7e&#!lh zo-+EvVD&|?T&ng2{t#x)($C&)C&-l{%3a%~L(KmWZGZbTIQYo#_SSFu?Ac}SN1Q-I zo}>)K+ZK@G`|5s-Z%9%?@X;+~++3I4wzShr-LYK=_SNsi_I=%U;V~$dH@|xdbQt`+ ze>XvI2d_z^yjoy%e%pWPc3u$Jz4Z1|S?U!!0>pX|5!B6`Y~2}kY)eVM3q^UsqTIl< zEyvkrh;sAY6Lf!!;!mX8fj(I;d%BkRRSjrrGo*?vm@#@9>K_`FYk-AW6kzn*pFXDa zW4UUfGnFVVD8R`4+$y!?PrQxt3+<4hbooUzI>IM>51!RGovB)fBF5LuKUmd?qB)XD zmn9|26SDfO^Ry&HKTfsgRa~9f>!}V=|DvL=SfDC`Ku>8%yBx;-^l;SB13}EH-A6=T zg|s$urqpStkQ+Co#Y<{!p*22QOjhm3gA!H`sa@g_C^K1_e4ULJU&Vh0+elCjJ6H^4 z>>;!FP_5K(sgTMP%xIg%?4&}Hkm_i%wpv@hB}@|aK2U}>8>=_$(aO0pxkhHc|4~xp zYHH0NvS|BG%T0~5OS*SqS9vg*LtzXRGFAPS10m1S`Y@6qnwD`4P_$$#y8{b^TKU*d zwNR+9NJ&a`lX$D7iDKB8u0GaN#Tw9Atul`*It~4-XM^!$1pO$lR!i#8zxIbA3Gc6n z-?Wco#_|gQ^s*}@Mcbj;u&GzT>_wn6wNZIlgX6RAdq$P+8Rd&WB6)cZn)flgRa^Bl zC@em|EgNoxSNb@6;@6NHnA-6-SPj!X~w51E*Nm2SVwqz$w zzvVNe12h97&?~3wOzH(27HN~2>eQ$#iE-o`<_ic{qr-$;?(`;<^%!HlOJEf{Y!7je*81a3-Y~3c`2u*DlHxF z4O>nrbvFsZQH*6;XV3Ev!ys;L#GESPoGFg>1FxWHr%j)w2M1@?WdEEm`C@f{!Ysl; zL@{shsSyVlu)?f3R(N|@t19GUUI;JS)nMh9-IkxEZCOrpZR?}jmE`O(t}}TcD>(SbUmB=2xo9A$I7ws7MiQuDPZr$X#Lau()l5 zXIp9&uVo#POP-`(3ltB!;_3BWemeKdd6KSG8M;<*OpaU}>IQH2@p0z2ish!M8&Ymn zD10sdA)VAgY^g+QmcOIEuwPi#%KNQKg7tbs`S$z&OhYPNeXDF z=OuwtzKnUtdp?mS6=`-3${9E;GA&==8`XG!zjzSF&e~t#kXj}B8AW(aY)g_Ue_z{W+C6r%?QHB74=RZb73H2ZEHe4B6{KGY!J7A+fHb;Cem?SqwUQHd~)jM`kg}Lv<_C;%_tkclrI$k zN)hOs3}}TMPC3arZRYf6H$PPUIqJJRtxNCc@U53%_WY$?fm8A+VlU9WX`D_;Zx&}t zAVTUMrq##(j@q4v_u<7Gmca5+$cKyD6*A5#+izhpvJrYW1KRk(D#D^daGY_9t9^>5 zeoCZlH;MN0Ai^;`AQ9_;?|s3n+f1jFWKT#~YO2oYT27hYho{r=2Zn{PiyoXU6-!x0 zF|pJa+Ega1560PI<$a}!1iXYNf$Hqi^zoMaFr!2epXSPmGHKM-o9cdB*U+k*n(f%zi66LNcqLsozPKl@LHJjPF-dC3$Fjbqg&1^7$`dRV6h(%57j>QMJfT{zJwG@+!gHs6En!eejg}aoSRR6z zB((027y%6(=nCqLJr+3BW7V3Ng)UZt_9w-}{?IaF0od;Ye8oc6#;CGPBC4OKqUKcg zla#7S{s2~1BLzU}#;1Q__P&be|g72w7&#^KX9e>FF_z#>pRN6Jn&qB)V=T@sbACj zKVrAG-ugSHbB)(A@(~QjD5SSJFf!XHn$R4Jq1p#SeHQ1bj~2`=fNDQr97x5??Ay;- zgU0y5SDc;+8LE>9HDN^0Y)=z~=dZL7dt~%9w0%7N_OHm_+f19un!Rm6&l;p4>#)rWBCwyp9jqyAWH!#BzB6JgIPt%Zoqudz1ol4dQEU zxr4jrjAoVjS8r_7iu0)tL`5B-M+Egx{u5H0DLkTnvoz?)9XvhHelRY5tp&m;MLB4y z9L&fNWa9K1=?c{th!E$2!u3BTT_a9SowymkI?-_cxo%t#!kilGHEfxQ@+`z+(_64QW09!p{I%hah+hx2rZQ zHPdDd>nNGldsBU|^k&zk>j0faDDqpx6*7n^T2Mlwb02BpfB4Q9m-_JftUq1r#tG~v zX_YS_`rulu2$_;gQeF!XL?^I}SSh_r`4%xahk$LWsJ8N3ZsW>kRU~6|6-IUf6QMVx zu`>`NM~hLnPC^ah&Dh{S6rofL|9X%33*MJKHG$@jdW3{_qB;HE(;8c83TM( zPPS~EG{2cYI|={|m(?*zMYM({5op~5(-WLtbALQ|vOGn0PYDC6>u>Cet2XK77np;M z(Vh=esbAC`LeODNAxPE%L1-=ij8C6f55f)s9jt}a=KZmk?3$`i&@>x4n| zUL2oKFemlN=WR~|?QoU{Qw5!Y~WxfI~MY%593-gOZ{f|Z-t`y~si*!-6TEDAs@am|KI&yWn zUg=~@K71w9aAU=xl2%8crliaeTq)oc;DHhSfw026G9A#u^0XiAcUfDuOT6N%yl)!! z4*!->&{HOYW_Qu_=o|;tR;Qcp%Q`ce%cFl-z3O6C)ta6ny#n|?LdK40ZYBZy=DCOl zND$Y^wR+??bVQI^pq=1XwzwQC_fty_q+iLON}uxGs^YiMO9kuVJwrX~E{mK`bW;?Z z*BFEQJi_Qhf+1ZQIdgPh{$LKN1mL5l*0HL*SL;_QKm3HX74jx8>{f|R4}RO zOQ5lOX#c;u|QUW}L0|!;e&Pli>tH*(xXW z8m%PIqE6Q^-@Hcb7eVfhNetI+#LycZ?Zn`-!# zhSDR`lN&tHhv1TZ<@clsG&g5Wmn-?kznx<|s3zoN8cCE^uk7BO%^7rRYQMck!_B$F z`&}*c@Xf#mU6vD8VaU?=V=FWY3lmx=3{S57`3m9`z@$gFb(Ismi#1h1nBq&)6Uk*i z=4_E!r~9^%+Nt`LzMla;J`9&g*$;RKl*;)CpUyjqV5hqpb8VIE-#4@qSi22WN2*>! z)Rs#dn1+p}+&IQopL)g-$bPpQRet>K=}@4cUuCDvOThynnO!#(>o;GrGoOa9%APPf zm4K5ia{UU3+jkF3ecLY*{i8~J#(|tng}2qZ zXQ(9J!Phz^r+IX95Yg)C!d83{Ju@Om!@Oo5tvM*8qDob>sufZCq)d?dPD^myuh4q` z6(B6}S&>dOF1eo9pcDtwtRr=hxRAm4#2_m5c>87fQ>X(ilmB@n; zd=`Vp0?e(F34F6T9ukpz^1KI)cwt)kz{Pwa`p{O>p5E4H8$z{ppk>=ntd0cX^{JEh zY8jp7cvb|Vk3;w875d*du8Z_M3>}M#%J4VR2UPj~AJ*P7D6Xb!8zs2AyA1B006~Mh zW^foJfx!vx?(Pr>Hs}nR!GZ-15ZomYJh(gLK65|M`<_#Es=j~URM+m=J>5NB-Mx3O zb@jDY%m1fOpp6IT>Ij(rUri!=p2V77uZ+x)?DgpffA$O$)b{wS^ynypuN0tNE+g7W zl6ujOh2I;hY^|aKj06M=IGoy6_Ucp0IjqhSNo)K65KGoxpZeYW)%&Qk?NEI#sJa+S}!o=8Hpu z;g;Mv-%*d6+V}N7zMc{a?EyADKeAPV1;&#`e)I_>$2g1-v^dg+aP`%Pwn49Om$JX8T=0?wtAL1fd z3L^7Pk0J%p?J|j9Ry(O!$GrMwhmSV;dJ40C%m{spa1}r!!;ff<(=C{XKoXZw z2E(Cq{qclD^ftm~y-Q471BKCqHj7zQF7q@yyjPU5VgXVOXPnTkKSQ7$4E$z2`Et`a zKVAbDPMvSP zTtEMEeP@Q)vxJv^O5;K^xs(WloK*-~aD1!9`3H&eA0(+M*m1TMCi{q5dXJ|5T=9|0 zg=5WSJU%FUny%#V-Bc#4Ny4%(qsOdtzikKgpar?r2fP$-9;7K!1a}4@VgG})-vv7F zP_K6(ZuDPZZrrrSAAG?sg{wb;=oA?qhaYx=rC)SnGYv@1XgU6v1W6fgqW`XK@RKyF z7gXKHKVA<$-u){@ z`~HI@Q}^eOj`wAu^&B+T3t_kZaGQ-i4kr57v{`+}Fgp5Lr zO2{N2tHUUWMj|AfTKpd}ID$7W^Xea@&{%oGNG8nx(?zDweiL{Ja&k`kYQ#32AujC6 zeWw}_4`dGz-wra>Y!Z_)B?js5%@f;#1{26*2lC>Jz-~@e=6>SXNqs(Z+ZC4vk0+v< z5#Mntd9uU|c&sw7zKG3`XzwRi0IQ;pNY2G^xOiex3&j(3j0J6%O+XVgqf1TDAiSUJ zJoSE8V`ypd2@O-3=l)Fcgt3wGs)Vtse5!bQT<^55&i9?SSTB0GH>D^13xHi2#{(|~ zCpVmPhhEf9CTvwiY+q0>9{=KeO?3 zr&X6E`@4Dw=}u~_+I{q*GdAJV82Ua3S`7-||3WbE7Pm$e!8FaT5F~$QGqxkVr!%OU z`}2};e2y19uU4eg{o1Z(vnYO;x@+RgrBcY8O!vlr2Lc%x2^}#Cuh9N?Adrbr5CnZD z0Y+IJK{-?*tI+=r1oD3eB2tp46WTO({%^SK!Qp8d`~L+5+VrtBo&yo;tNo1qEFaP* z;zyf)s|v~!Tu&4Aap=hRCx|Et_HiVVh|P%fP7^)XPCWB;o{59TW;ysu+^=mhVm15-E2#>kOx4Ucy;jF!_Jj!zDXJ7bUC;xXQ z>jG6bDK2tq)+oqyvqG;}xn_v~J7!!=Kvxw~`Dl zpP^xXw5TS+%VR>N^A40G5GPhZp8dd1$vUhyp{xJS%^{&bGAgzsr!}aylK9Uqku#In zBgGGeKOy0NH$Opp5W}m6Fu_1L0z-KF!azeuMgNaE1_}}pDlwBFiJUGWv$Z=ZBa2X2 zBbtD)yhmDztezFzK6ZdH_Qr?={wK9)8U+*h_{+s3&(PYt8&`$?KrtY{28WCtgzb2NXO!G z;!TFTCUS^4JC`vA7R$FUQV3mrx*XH-xz*8SZ|spf5Fya4N*4d&xiC*>?~c0mw&g4 z!&O|FqkUm~4*4~y+xghiQB;_=*$_SRdSNwQ_#(IIP&U}WL-0BQ>@3!cNlRKr@Tu`Ah?VicN6-AI zF0b@6sc);&eD~m#=ZcBS0oUC(3FBv`+7o4O0c6qEr^_KQWj=nQHTpw#E<;nMAW@0@ z=;>&JfSFd^;E@cXUz5e`T3$t}qy!TAl%>|zZm#|VEJ1ZP4@UG%XM1e(VHP2`q|>mN zhQFC3Pjw$d1R1KTeF^$gVPP(rmQ*Yn`@!-BcrkXj3f8ktCU%Wvt;fu<*p9}NeNU!K+Qm3^I``45QH zs*A}*PcD4!NsK}J?UJ(~0Z+FbK!NkSEqA}76&J61g+ao_?zO5%KB3XTL3ek3ca>fB zp(IPb(#I93B-xeQF7hJ$%wmlA_cKo;v?u>sgSWRq%A-rb#4^kWs0fAWP zmsb`Oc0c{-2yE1uPGRn#m0QSGq1IeIeT_F%Lnsnia%DZZ2AW(m4u4qqqIZN(1>|HY zbh}`Q;*|JwBP<$9lVQANH8$s+%pKL<&|}h8CGcHmXrb#lC`!|ih!|UXowBL655)IBpp(p%agLQ9%EfP|C zWL4nRFB~f*C0+a_s}V4m@x>Q=%;y6W8d6Cj;2Fz5NGnl8egtdiIfOgPR61U}if%`P zf4s@W*zB#bKue>oi98Rut9HPF?UB%)Qi_c{NLu zDuqp<((Z`n@57uYibD!t$0EIDN2};y3V0`m_4qZ;ijj+n zPGSE2o5NjJtrt-KhhVSNpOIHBEfC)ywvt5e^A#~FCB_B~ZQu{n>H1cj<`Av>HhQw- zf=+Qd?p2kN9-l&6;+mFT`k>ald4H6NaCZa2m1}By_%*4p3M7STrg@-$xUWf-`2u|# zV!}xwb9!~cB9Jb3hsHxo*w`}kxZqH3U`aj7YIwE3`o}nAa#oE9qfPAW68hN?B;Lw} z=yg3lyZ{GMarGnPcQrIt1QO9=i5cw4D+{u|k*+yee1Nu1I7}U2OUnE^9^Jde27)Xm z>IrwhugpV{B0AT>#u#aa2h4eI!(?)er=JWL!1Swt*37@y+t=)FQ8X# ziWkrXuIMGpFJSqiTQ@LXbcp`~`?lhaRgE}X(}f(JSMf!I9imx7U+%g9#=gluty~jB zW6r9zA5alLz4kgkZf7K*ZpbnnF!~61Pfr$y{~C<3&K~qpUb0mT^{TcIX)S-0)#w6x z(O|nqw0pGKGq#NT?X}a_WFIC+h9vQAvX~z3l!ZnY65+SK&xfiPyaRS~W#ABM`5vpc zhnv#0wRAYCcv9dKVol8>g6~O$H0yIs%D9fpKJL*2(`Z&@Tj74%a{g?vuc;`Hal>B8cNyv zn-!bc7i|`~*V0;zJ5`o?yEqCh?eBwnRpnFa;s-hJ0{yZn2l8HxJG<&e-Zdo{bOwmD z@CN5Q>*1?}EHqMXl#51bC3KDRSSnkS3y4g@?bvR~AKo*N*Rr_@)yn~YYJB$ve8frn|}{GK8BO1vGSflp+Ea^@`St1m9+pF2|-hT}h(9eq#clkOfn%%o!k)a3bnJA!1IIFfP z*#qOI)l{9H>;u8Bna_tGGO^ff(f>jErmq0$Pw)P8PgU=xS*7&l16}LE1XKjMyk4bf zNMK=Xp=_YHD%Y!J#RK|Hk*@wXzr2|gNX)3^^P#xp=ho*#9M7JK?3eeudOw&_;y|vh zDDTrLm&2&jbgWoTYk^<5u0IxE=gBsD@OtWvF^&S@QCb@+@^(}yK0{^60HUwv$9Zpb z=+J~-qiJn5tWi$C>N-&exDC}Kpo$YcEUZl?3157};r^<`5*h;+pN3-x=4jEtZ5?g` zZUw50JJ`exJ(kHR4`-V@>#1nfXO~gc7cfOXMjTt{^+ExSq&onwHANp7$PCXslc$v? z)!3F-+1KRhz;d=dsJ8`j)CnVKV1+8UAI~xml_ias+V_z2g-iEYJL`d3$Wg7@68+YM zOX@xQ#<(0Ws$?SSr^Qxpeb*K2G+JvPHN30b?j^J6X&B2TsdDe2V|u4NTAt|AH+S&@fO)w_k@YPd6f4eTtJ-Wf?rtvRdZ8Me zZ>`2`Zv%b8n$PcCldSDDYa%zG}?E2Zz3HNqP(b$V=yV+&I_mGkc(nnPQF3aJmX4uxaD(QCx5OXnNArk z>u!w=tUbUL@$WXr80w-Sd=@v7T%h;WvQxLbf-;<@N_z<Xc0a zL$3OAhQaWR?o)2GFdeFI!W&`Up)4&J%doTT$ z)iQ(+2EN$~cw{iS>@midP45abDVM1lavRGP^5HVbA+lgnusZkRfFv+t0OMO#B=!;ywznf!9Wh#}bB^6hdTg zkM`vjHG~V6K2-^_bfIvd&*yWa|8@6NqSQHuoq1bd04xMur)Ev8T=28vVguH1Y_RTN zFOFE~{V!mwU*$pUY<<$+|?_)9MP_TNwU?up_?;Jm%OL|%wuig>N46IDs2|y zhUo;}P}RvDg`Uq_Co zu7MpJRvn#y`a@D@%TDjCPvG{1YyTjLl@@MlKw3{2uS$KDE%!u^OBCNa4m*y2Z%t#= znq3HeBIY5b{vW502 z`tcJSU}J{_)&?*&OW#4y@Ny5GoXw;$2Iw3~06v096ef*x`jm21aPfuG??W!7y(!dK zlub$BunXntXpzSPZjMoiC=r!Px%>3wuFu;eCBdP4y#C0tkbI8IrV|^8kaUe=lG|^y z(s;F!%u_te2v_EhvCN7XA=K@$DScoOLF3250R0*A2hE|DT0HJmC9Fdc(ISp-{UEOs zfuDRao9d+UKj4U-e)fxRixK=A~7MmhaN2MsZvLG5va0p&fs@`4F zv&F51+5g_?O?RjW6Ka31-U;KG?6Un#EX5s_NqGXM?m=FEHW@+{er)iQhKsWJ*AbNV zv-)a~W}?Y?`#=18Wb%2K)Q^9o(wdzMHeY6=EFuxxV9CENIUc-;KcVPrNGHTLCHuMR zS~oUk<-UD%&>i7yD#e)PMMMEGt*`74yqbx9*W~B*YWd5VG|yai`HSS-qg~{Zlpbaex3bfw zowwo#^6t0E#r1{mkQTdcun|jwQ`~79Fnir-S~=-ZFd=!WeYV}1OI3Wde73U~nR-Ph z0?mG4!<^qS(Z-rhNcN8V@?p;Hg|!m)c%f@q^UK@kTa8~lKRejJqD~(mSzZjLL zc4cgt$T+|~Ip4tUJ9>WzmnTwZ_LN>?pq;*03@;oiKonv(6;S5b*Zi>EzHZgelf?yx zyk#Z(hpuO=7`qv=X0F|q=0{>L;XFEtvxR|GEB1cnC?^CaawCC4`JO}LC&f2Ix&@5m9*epHwO`G(Zy7dXVkAWjw)=f1#* zl|=E(;i8&ZqMoE{*U>f+O-B}`0v>ZIBmGn7*;0B<+S1R!^r~v-(MZhd@vg(7!gsQH z^S~u@sah0M%TgMSn34Pwk)DpRBJ>m$Mo3jJ+=K<86&r<`gm)_%#eQ>wBNcW(Ls)=N zb+ENn@Z0!*kUF-y5q7CP&2tE7vk`dB_VewAq!Eb6mZ_V(np)Q@#gx7k`ZkoD<#Db& z2F=&~prpT6qwI8JAO>WzQx9g{%)r)ySSDzza|paI(l zf@+t`!7|atPT)h0Y%rJmS$SntOjM9-S{h>dJ$Ce>ol$iGMfQifu?)@1r9H zX8EHynm=TaqsNYHdiQ&_o*X-i0ni(@RO4o@G)~IzP3rPjpd6 z|1QswHpFLRT!hz~pU{m@?k-Ct>>+Rca%dzDrxqe}XsGsJW$M}3S4%t8l_e8N=QJDs zQiw%ro;5U|y*@SY>7s&!Nzdf*!603cft-qep-e-XA*QZkv1(qY)vWtdjURUU=rZ-= ztrUyWn%`ns3vD+2$@dw^5U3xEMi!5ImsN8dMC$0Vrr&!kcLScyjK0A2&Q4vZIRL!GIY#jwjH*d=md~v($|Vh(F7idQiRE9&&TK^1^j!dwYU5r zE^)@q68*a9FH-6}%D+wv^yJ&XzztbPj*)gnqppIbLnQlkGgM5Q#e-Wp#=JtRR}Am#?}F~#toRAnY`t&+U%jrC$fAo+-~Y=KOl3m zeZKs&)}TR5OBxq?FNOl;JEBCQ!A0&>&MN7~0W>zPND1BTTy{3B3Pw zJe54ILKmN|5!SN|O5veF_ck)7}GK0d1qz-z~I}FPb2*%P6x0V|-?*U;HNCV2A_E zZ_#%ZQ3i-T6KR(zxEtj7^N^;5xm+c)#Tl=2P$@DDa&zSP5x1z{{Ef4TfV6q8%-uxP z^~qF(V!2iA+=5#_)6!*aIPbz&@#7Zjmm4f`t}yK*jogn=pv$mhI;gifmFEriH7$KS z);By?or$(^TVCh(sev&YG2IK1rJpX`Q3Z|}xJ?(&3FU_`f|UO zx(x&nA^{=6E-+E7Lr`?XX?hHtF>^gjW3u9#Kd@!n^`(g|VFSB8@XuCx<^_7Y-|R?i zgCLM(QO)V6O(H-fm%JXU;CMHf1x5;fb zvuRzB^h)xXiwdK&hTup$vG7OgT_{Ty56?2t)H1HhN@#D()G~=@pU{+_`+eDk9%Tkh z$*qYBSg6gV;pf@V*aN1Al$*`VvHPR)3-vpA~9 z^guIi7=$anvYn+GZS30syz7Bsl|CuLdzkcsSft9;&rIf0*gLUE69zVS#p~s_jzWS9 z?}s${7U16mlBO66MNS_`14`$tGxVv-u7hb5yON@mxkhP8U`j`KdD;g$zqd~nFz3!J z!f1$)JUyMO-4d6xl6$hR(`4U5zp@T)zteJZa@fu>Nd9hG*RvtOg7p5IKbwk;DN5bk zNQB398ti%>*c)_eS*YZPg=TH;nmzX7U^fVQ`-Q2Cd6(!yWXe@%UFv(int#IWyRu(s zMx}$WZv*)SemO=CI|6`@n-0O|+CB3j&uD zS?HED59=itW0z38XK62xc==dq3>j(07Htz$qDn*Z8q+FJQSLI{yaXy<493z^afi(jt`{vVjsDTHzgIki> zt8O zikAqux>-mu52{NUO$FD^EYhw6!`USYHOU7-o^QXRX2AUEg~ogOA*NXIP4w@X+j1X# z7k2BSbCQUq&FhV5yj7(j*e|PIU0g%5pTG%oZhutP*Txm&`m<&hyHw6js{nIL*}9n@ zr6ygd(4#U57GQjwYJr-#0*SWpB=Hgua>-wiNYy@NltUOATr{dks9kTlet&6NgD<*Z zT9C~Wu$d-4 z0o!M#wwWGs*Y(AFMm93@W*PyD%s8+hg{!3ZCOt=9s>zPuKS-y4A_q)mRlDrtdR>2s z_1KKFcff~Y3HcP0IJ5VjOtRnIY0bw*E9&;QlV9D)HzR5FUj5|>GgsimabIZuz0>$I zYmsoB9dM9Uqcj+lBiO~+hr}%2K>ePCIxLlF^l{FWV7ai}Nc;z4>J(F-?w`g}=5#0- zh;`O3)sBWR>229rP$n*g!K~M5w^`5pfh?1`Nh0UfjJzKbi5FKg(NphtXWEh%EZ|NE zD-*t~;kahj8sLB(Hp7;g_(K3wE)rlIe6J_$^4(P@F!<9(q5;LO`{M%doX=WnPob)q zU}U1`sG}gI3sQ>}cl3FtO@$9drHV2!r|26vR0f$f@n2kW5Se>-&Cg)!81il1s0w5H zJXG!s43i5_{8Pifzfd9A*QtooGwE+hF8;s3R)R))YDrQ%SrV! z4KFT^GJVp9GQ+z|87glJ@cxPl0S=G1dihO$5Pa2JF=BFmbuT{i6hgdiaJITZcH8tf za}7;gGDGQ2j!@yCeg6P<2@+oicD~CW5RbBgzvaL@i+sz6jY7%_3iC%jrRhK6y&F1Q zx2g9O(8dIgUDX4m&jqGx*kZ_YON|BbfuD}CV$FJ;H;u!EiJr!_&a2US;)~vh8j*{x zea7Suq5fCBM@WZB*)1l^U_02q5w|TY{r|iBpTz%-P8WZ{vb#@$R{oQ_`@{*}v@mAM z>jc01-yHv~z6o>oBM63E7_FI*^&-7nz$Y)jFR48 zT_*E1Q@kS^HaL%-si(Uxi}H2DY%^lq?cJMY)M$4-uM^9HZ-4a0dbe+blNM zq;125iko7@9@8u3G-E%Ynq?tQrJ^j-tOic z7%;<)fT%K5xGkgI=;}r_YpsBdY9%SFx&xN;^kn%BwTK0f5 z)N#{4=qWxchS-0JG};HR=ZmmqPoZcIS(lGj~Gep$NYE9aPB=XC&Whtz;V za10l57XUqBD38ZUIZ5@e%g{eaMBV0jHvQ1q6L)70)%eX)d%D5(8-k=s>p^SHku|*U zb@W_}NATFjs-2Wy*6zz0cv0IRf(`QZ(m+!swDGhz4nX(k(t>9N#Wd&$tY)0%!oZGv z=|FGGUavhmbk6FSHgFJ0jEt^zRNAXPW)y+x1OT2jFY70ICPE+#LtHY#Iu8Ve;yKq) z<;}leLnx~{Cnrh}3ijmFmO-d*EO z&@v2$PnG)P3CZz{gl1;Gj1%BV?CP9XHj1D>=CQ1A3I#D>=w_KjZ#R z9%*H))eXNmN}0VXlBNXsdRFMDXQQHy!4B^Gxg{;;xqntHvZ$qlns_)c0#m4+bbBz{ zWw43+Tv}VzJ`5^pUWNRf^%wD=EVKH#uWs;K)3=7eo5%iKVX(J>bhq%QK&Y1+}$OZ?9aA9{_j+!xi)Y1*y6?m$7Em}SF!JV3Sm1y{kMsE z7EQN09^QJ1*H+rZzn?kXc8ZvhwX>9^-gC5^m!1nU(ts=P;>_zfHde%qN^?IR+r2$< zc65r&ZV4|V=EUs)AN~xeuJV;l@!Vtaimmmv~B_avKHyEBY{0ez2t2S zRZa@Z4;kfFnY|>dDEwmo<7 z8>V`zLYBj|dr4OAo^l!gB=QeZroo$jf8MCxRsUO8bjv6Oa#So<46}$Vr5Lwj>h@@% zz?xAcda`w$z`>yWV0maS(e{7-2>unuoEVa6RMnFTBU0{tzg)S)wM@P)-#sp~OIE{q zk3DS=i1u%ZZ^Z;>rBFTz!%(=-9D}Ja2OG3>L(gn;$oXMPrPq+=)swVpro=UZiG`1# zois%0oVX)AFU4+0HFYLg&C@za?sXNKJkCmdU!%5^k(^oK`Dw|Pw5gUD{l-Y~?ZTSh z>@bfXmDfx@S@MHsa>v80k20>9o@@QCS_%>NcqX{M5SdXTouaF~$`ywN3#q}Gx}2Er zy#k1vTiK2W{qbRzQC}o#ylxfy71M2G8feudl(0xFFv@izf7H`GljzHJwQ=SMbxV2o zJPQv+5)J2@>U5RMR6ZWp$_qXt0C0_Hw9Mgy{SOzk&=PvjGW&m!KqWsW7SngblTQm4 z9PI2f1jHMbJSuaY~QGMH6^4Z(THZkU#7J8m^&s8gWubkHZ^z5rlQ)!iF%LVwFWGxrHK_SM1pKPlQjs!l896HJanDY7~ zrsDIZhF54Z^w>N%oaStMe&M+Owa;OGT^? zycc1V_UmhdM6_YC2eN9Lsz-7rig+{eRHR}HWrXnPy!wgc4=8*weGy;dNsm8L0kCPn ziB{Cq= zi>^7zrNgFmyDrL4)C9G~dFGBy#P%Y6r&mVE=R6a)T~TlZS2BoxPto<@Rrx8+`29Ld z78UA`QIXktH4qT9m+taY31`;p5B9reD!D>lq?@)zwiL{nqkUq|vd$;!MFv!Giha!u zyz}}c)S<$DuCOJ zyKh%LOJ4Hwe7#Zl*XyWZJ8LA>$nRXNb{3-Y8jk^<#V5t`22L zbQL08nH)SCux^6n*z4diRG7}jlS%Sh>|Q$SXC{FL2^oYyx7osa<8N!SkfiPlsU9_2 zDM1<>yVI3I+o(`KzF)i=uZ3{Bk_~403*RN+kT$Rm{l1*}A_d~ad^^2xjVmBx_Ii@r z?7FI8`aUkh>dk>(F-Awx;idRou)##*SSHX;jDq&MSRdU`Bb3P5;|A`|8n!OX^v2(z zB8w_ph{c{yKmEG;QrUsB5$8RyVj7cf%+c{3ChJc_vJM=Rd8yz;TW>}d2JelT+^@Dj zPDwZJ9LfY}Vf?>=f+vQ>4#1alV)|iz)Om6)?aEAP+2q$pqDhN&Knx0J-YZamd zB6nIglVN$cEWM-*5pXaNN@$IeO5kwn;xrqrb#JV@{)1JKnDslhE$;{*R4cAV>qo{9 zxAsL1bMy5C9QfG!T$-O^PGx>zA`28G$ zLPWRfy3+Gk?!^(GfnerSi}@{7XG>r#1{FWLuR(9vCzpx&hGw(TNSRQ6llxu z;#C%Ze~2{v+Qa&S7=;PxsO3>_Gl-vp1+5*Y@<{za_|5Mz_sLEDug$9cMhyaOZ-Pmi z-Q%d_Cf+|95G#uu*WL0w3G}EvY7BT3aV1>OG;pE|sTv*wDZ12?u18S6f7J;n(;v-d ziA@*vm2>JgypD9{iF~&}eOA2Qo%pUuAs7GU)Tpr$dP$p(gtfl1KrEd2IZ@vHX@hG( znI(rvJ(Hvh2E3rnwzI?WbTP&DUE3mS+S?qde~W-=9aj3DUw_(f7Y$Poi8oO~jaY9j z1X)j$r0HZiMvaR<3>wQ++ZueR+7J8( z2JAiyXsn4N*c8cwDISlPGnJpW?1+^#zpY?fTpvFRcqkWR40WgYv1JHHG#jzGi^PvG zHDG8C+OsK8>fUPBeBqjCa!1!+XI?BH7>vt^MVgiI34-aTe>h#`h+X2fS~s>O7Ajco z#N&}t-jW?GKgv#=Y9|_Dj5V#4G+2|CsK?(@=rao1lle`1VOc<2qN>3>o+P2#ZgwInq|VC2*ns0FofhKR>>I zmnfjY-dt@5n}pG-N4T#;waW@r1=}a9s%$eA2xB8`7ez$|O$Ei_*Y&CtTXticjsuqB zt>XSs8F9Wz3nzLTaVL0_{w0|kBFtmEdX!fdNS{&_Te;7yAo%j>5x%CG1 zJL=O1ADQ7?RRbu-S?ka1xc6}tlaizB$xivf_ftRP^Vb?Y5HcLmmHo`ErRl z4Lr1^7~{PPHlz>Sj&4CSSus${gVB&v&&t)~B~6+i3B;MpHhtb z_XBTRH~Sx?F;s$BI97B(gd2bH{d;`P9uwO)6Cf;B_)J;mh7dBEd%z<4Z;zfVb?}pd zrzSxNr}&1AHc>mS9N^49P04xy53?Vz6azWYD9Eh}NIFbp%X}o$9QH4w z^JoW5vA<@tn>yP!VRd~GzAqn2;k#kK3o_1o^0IoC9gu?8OG0Ef>5@A7IkQC^8w6p-s?rUF^*f)E6^Y7J#YCPcHC~M+BNeIAB)qJjj z7mRl(C*`4-<_WILjQag4Uct`OF{?OUDG^yXS!o`b$5o_4U})j_;I+ym3$f5gOwrsj zrmk4$BjWLa^jS2NiURD9yHQ(i!oa09o#fZHS+U)pqp(QH=E4a~GGb!<$YuNnzg9IV zuzXF(eYO8C79d!6R$R@LKmbV0?t;Os0Wq;I1El)_&Kl5YPQs-KJ=GjB-2m(`yqBgu zjMOS>j-9aqyN0Jneakr1IOcGXuGcXHfLfyFrd0*aK2=tILMHU=#i59*RvkZm8Dtx3 z!S_Kt9DvjjdON;u=CbkVtalYZG~v<)_FQtf`uvjDbt3UjyzX-Eh^Y#6@-6vIFd~>z zdvGgq@MbEu6##ll?Uyu;5>tQ2#6HZU=di%Uo839AAb72a37O5w!X?}I^o!>s^n8S5 zDHShikoR{Q(aQqZ(HRax9sP|i#pSOG70B7wTvO+iUOB!qm!e1OwY+XTM!k-Mg#o$vUA4nu!d@lo$Ab zV{nPpmKAVJ!A5jBaTIXuKYqSOzFTR<=tFYgU<1sRNKTwFCe+Zcw%2}IbUqoHT<6w1 zSwhh~B1i@{1f=QT5_V~0Oa?zplsE~=u)w5BE{mD9x?if&VKOTH%?c!6Kf zsud*AC{5Ra=|K%U{Hw?tk@#Qhtg_sWod9Bph0P|O>TRx-Ee&VO4K;^f{$g5miEmDY#ELHin7G1Iaz#j1kDK~ zFs;&racW&;z~9U^ti(mFnn)%UDhrWC8Jd(>D44!W8?x!zef-groP|%X;!z{;^DlBm z-!KND=w)l6{4)yUCYlxX0FiD+v=LgIRb}VbK5+8IC{{aiMH8JncK;Y+HC@{@`72(| zES`;9bO?ucN$C&vHv+)hz#m(fqrlILE8B(EYt`7ytwVbdRVE=7twc+8Bfu~|IO?Ya zjS*$XU0dR*gheATN;YWKvM3z-JeZ`K7gVl+D(S>;sf^TPuNs2l_!(*&!A!IZ0cB&p zPT(eg|3{M|$I=$vm1Y(T4bFZe8W+p{^#ce)*S}wi8xGPG;%(s#%Op$#)v0lfG-)HZ^lw7{Xrd^{3@IJ}`waHa7Th1)G za6083qZrVB^gzWWH~^mO4X$Nf!UH(k5*c6RMlFlo$S4yg+9xPA*8d7|xX_$1uILg9O?}iISzHbo18zGx z^xa@k0dr`uDD4pQgF13fV+@l|iztYQqg$$7#me`VfA4 zX%akM{c6+x)XZmPf4r==rq>RcG&H7;17v-;P0H4vH@-+jLV05%@gF~&ZrtjyAdNn9 zNLu7-)HIdZIeqgl#t>`}M>Sj|VU!6N%EpyhAqw(Fff1+| zJLqV;*yHA7Eq}AeRp)h3c@n6~tj}&T+oWuWtbCVZ33I_l`|0BR^R`wZTxZRf!P3%H zTjwXm3K1w!()H!Lj~LkjdBed4Bz>WWzbbA@)r-9|eD~9V*38}{OSbsN%fTUVj8Z1n zsF|&YA)-Eux!OwYGsk+ybPfu z>VQ-pP7vaC$6L(q=xY0@itq%~CCrsII_P!$8(g$_yb$?Dt2Y0+_4wy8sh23vfC|GKtOSRvMdiJN(Eg64n^{V1T$mh%!-3$!*c0aVG1-TK3Mf4LkvRTHEKo~Tk`YG#rWgzIfr{{LJWS-%ESWl{{8`Na=n-pQ zCOMj^SHf|Fs!zV~P;OpJ9!G3!-$8$MHkZ zzDNHk0>Y+pV43{xM^*Z%e$3|eNDQ>yj?&22DX>S0gzuc=n4JZ<>NE;b z*|E5Qo(%qwL?cI}iVh+s%K84jrLs!S)|*$W=AWQV9M)3{Z~0hsxq+87@25NMl7t$V z5wh0w;O0eg|J%!;*Y=p60=?IS@$Qp-fN&u90ekjty3$DX z=?oj!aV;iSW!{lK8f&ITFZHnd(&uuZ*+Iok#KbP#+ViJHW6T?z1NC}MJSBnSpwbq* zdpt)0z~(0<1;{!q*?B*Rt685MaZ@xyWyZt5O98^&U zfcp0O<<={Z*05+SI$oS~Ql1wZ>1py$eN>s0^B{PDHM7dNfmwka*_DzaTRd84`+Y>0 zbs;rEVnXW;&=?qJ+*`GTwZOP$I9w&ByO_EEh*?Qs zcYXjzY%X2Wd890q&r|ZkP5=0VZ~WL~kEUjAV{!Y29@lg}MWWNVLTFznV)l49s}iy; zbeE~gUf{4T%*;~)k6FYmQIxDHw+eA|eWKJq`Yrgxl59eF-1!V>UMc1iRkv^G>+k`G z$nYjDer^#3YF}NKnYTQSm(%3bM#M)5l|5`K2XCmBe zDffb)GyNi`IZ;m+5L&}AQY95CQmRYCSy`LNDr9~Yb<)KX$du{aot65IherJEdoe5B~|;+LqZuc_g~K{s{G9C+YB&a`8L1R^uSP^I7#W#8dux()0Ru07NB`J&gM zE=n2UH7xvvlSv|hOsVNA7f0`M6(7!EoPs!E*1Pf~l$&+^5Db+Q#(huYLKlzS`%hIv zmd$s8l5`%pb*io;#-*|7E06gTjAn~Hk`@Ugn7lt1aXE0nrdhSe6gLPK_$%AHP6rg_ zQyjiW>=Eo;)AfEB2r!^TBS_`5GFLMN%lOrjT^dgILv!?gmh}H2?W=?0YQ8oHm%-hG z2N~SmUBaM)JHg!v&fp$g65M4VxD(tG+(IC@1-D>%ci!Lk)o$%STf4P2HCV-ykG;GKL}JPtFf7wc?4ksYz;~z3hU-&7rJIQfw1% zzvQ^a9EeF2G}ubnCBUwvV31{JcCv4ek{A1i9`W4Qw;aVZA&s8mUso9OF%3?*PO77V z&y34WX*t-HYC_KBcX0y@r$30D28z&P4^jVxdrHBaBs}cAXcA{oJH&7Nma_}0)-Bs@kKH}!mKYVlja1;m8XBB7>c=YnDMNBQ;S;g|OBJTtbNXk~lM(hGKSX z)v}ns!rYJ<*{Qqo&$M~BZ)C`uoEK>$aG1WfS&maU{e>rr(9msN={mjf&i{G+(Q+OZ zA@+m8t^blh2`>v6-*>! z(xFICvR{gRuweg7|K@Ro{FR<}O`7`BW&a%)9-KkM{n!l}41X`D z_0RXFPrNmW^=|z0;oYk!oS%C*bfI<(3KD08!;>Q2o)YxqiQ>A(2jIbRQy3Ejzrt~X z9amMYHeiu1nL6L#`{qh!zY*s~C-w>V{ftw4?q8C(IN^0==^Ieavew2Rb4|MvK0!PB zhw22UG*XU7vxlejwsZCNnVp`Rd0acid*;KO`Eu-%>>jxXgYs(W%!R0^CN=wa4Ei5Q z#kgdDeW*QS{0C6y^j~E^k!xUI z2d?*j+5V#}G`-I@1|88Tz51zZ~t8 z4m&oquITPgw@djkITz(rxw5S*V?IlvH^;;`JwPkXE#vM?eK6VDh0OtbJOS>mWyg-~ zuW9d`9#rV2);-C;SHhpky?^T1rE8>{|Jg&C%+%ZUX zZ^Ux>y-=amH$TKY#wRbJy0~<))E%rhg)pG#J3(ir7 z@k%c<=xGg}GJ^hTpf1`mA6<(1Aph|_S8c7GJ~7jt10Ut-WYZ_PL&$y9`W&Z~=w=hu zZ%f!8%rUWkTq1y0c5~HDMTFw8yb-;##<>!=69UCMdJprEh$Ti=W@b%H9{`fe1;j+H zX{XKxRZ{$fWLQO%PpFTQ7gi3*88!WSKm|2qPFsd-5R2Cd)qxHi$oIYb!&X#>t@9iR zq&31sfu0o?pJ8%Wb&LfLl(Fa^#^lN`z*c&dA{9s?f@r4okndMB*4+D3d;sgWqj>@W z1w&-iLl(G3L!%4IMPGr&g(`q_wE{)W^F3q7QH218Hf;o_v_OdbJU-|>&(*2SaI)8y z+?3Ji6jigS;%7XmW!Rta_;f`O5~8Qs^ViUMm)PHnOl0IwW#{j7?wA2$(GSa|$v;=e*$)-s zKi!{T03X503SEU9sy|<*nm9w*Vif@Cj3gvM+OK?)9yWKTat z3{BSQ{T93^6t96?7c@U_3XrqcIb}Hd9;@nMhj*BavHZ~;so!#1HCJ^YleF$LpidMR zW8JF$vrMZQra0ZH=yX()Fy7U??}l$UYPH-R5Cbi&jOde5CmmnkYx`+eyXBvUMQtAHa+9X`Q zZcX;Cw4S4S*zbnoC5v3))>nT!oAx@Jy#G?HK4~rD8r+zK2 zkIPxwVkhV{x-YatLhR{m+WIeGyM9pvJs}PK-_9(Xya+2S)>(h`7>d5A^wLAtrMx4n zDtHjd+l6{T(>U%N#bO3XtlOLS6}~C@4|U4@g(zBx;TDqpL@$XITL84%JL>f9uG^JB z`<zfHY0BjZhg_--%M;1TxHz~C-FG#1HPRs;~@SN24$q3r!l=Dj2^@=A7 zX^e|}Y@AoAo&)%K@gKl*U~+bwrDNJ^)rl+$(zt%WQWV2ax$>8H^>7O(cMZq3LrLG( zUc{>qiYRbvaCDoP2Ll%hQjo{>cL(yezY~sZOq2Irw%wM)&S6ckj5BRUG6zPR-s|hD zs&#d-ma~$EwU_F`U3T7r3c}tK>jD2t^Ddu-dJm?=Qm5j&ze#V=?Y}=)G;jaV z{(qK<)?cjMhO{F%#~)Gpu8y^HckOMGSLAxRvryxjv!u8Db%lmRhnT`r&jRHT3r6ZR zcxT9CV{cBs!R8U}N0r>J zxjU%t*2@XE*U9nKqO314huVy<>fI*G46S?+l2YEmGhbo?a)7OUXBaxx3A>YWb4n6Q_bncas6b;WG%(ARoR?>k{xBqy zPYtNRD0{%y+cldEp`qQ}ebcKoY;eY9y{iq4D=4)kd7has=aZdNp()4JY{kD%Q`G!C zEjoY2J+B1J2gMW$s`GUurtUenz-nj^j8ovQ7&h5-zwz$MPfH^7Dted){Tn3J{kPVe zng+*)9^8^t_&yvD)wfpd z*lrfVM8yjv{XppS=QCva%_VLPXc?eGFycNYjkZPofoxI_RF9LRN*w zCl)e>Ln@0Xb|7?9_eGJx9liBJmSsD!ntJ8C3#Suf+(;q|#+hgMA%tWb(V{D@z$N&U zlsejhEb~n!+203TuF)kD0%dJ(jy&~WXWKdm=-E6><_VTp#83~4W=3(r3zvE;ynP0) zW=Wx51tC(j} zfTpjR5W*^PEu&2~#N50bZwZM4++3MM434!GXzKL8-bG-dxxZ`adx zK1{T$LN8CqOD&u=Iv3RF(Zdo)O9jp~EHbxsA?VXyk-==X{-d({kq3V>hDU7@IMV0$ z+Y8YvOv-o;gW3F5lNr?EufMQa*4SzZY^YpRI+LCvdD-`1gk#8fQltuB zw(U$KR7R3qu0{Rz391=pwR3DMTO0K0aC|;~{MZU=c0d=&6#esAw|n#JC->eTsinCB zjC@c6TC`42fjX&QG)=JOCUIMHTQZBddiejSnlg_S8CzC$zAv?MQ{lH7;@!wSfhUA9 z{pa(VPhAya)hh1V^Vi+6=dqZ4vjN4Das~~Kr};6mW)>JVG~ZH<@v~(Y>*0>mJKa^2 zB&9-2%!vKByUjP()s>mN?*S~Aq?<4}DP7>7(!3eYVb_wSvC(ED0oYV%Tmzi-cQ55Z z>f-KUg5lJOwzJ6hcSZ zLu1u^?{!0$)}1-ibM)vP$bo2{toL_9uswBy$i2AiV=C|^$Ql|x{p@>~k&4ki*2Wlg zkg*o5lH518S#H?`xaV*DP`eOl$SZ1|wzW9(w%eU`n{+yi@R<;0W0{7#OgUNY4Q3K9 z!HZ5P+a&xH9GaxICu!Y$sEUyN%(7zMzi{%ON$ni=cTm9KWqZP?A_Ja>zhg0R63S%rAq~z|-4ey6ml_peI?GCLHJWPCA`ztWW!6;Oycm6Ob zek2#2IqgPBqW#boWAr4Bfn&|Gdd{T{Kj?TM?Nc0;97J`P$mLEF;I%og>(e+nPIHbr z9sB{Oas|Sa8NG4tMZD*mQb+jX2r>bik1|zn(D+)Cu@`$UDsES+?Lw8^g8Fw`Yh;F| z8Nik!6WOXshqP_x{!UkQ;se6^89|EK`ZRh;1w94Id(LfMmhEh9Z2II{#0Y006-^{w zv^zm#lYLn>4hXU!uK?Y&$!qsvbZ4?87ly|(5}si@LSUaDq|86qS@1JFTW?l z@Q5pETmiLTErW+NDfi)|!6;05hV~)6bJ6I@tTNmtjdqtUt9LR|TOm3vo*xU2fJ$M| znzqR-^UMYv7HS~cr3)*0Uhl(B10ya*=&)zitot4sOQ%}0cX-?0ujka_$xz&E!rWpq zr&I?7HXor~+TX&jbES95eMD~?%X0Wku*IH_AsF;|CiC35zI|C$`x#Bz2Mdht{ozC^ zZ)MTj3*9@?-IoE6Ual_Rk_FY}BT1_t&KlM9SthUji13i`5Sr?6XjSO42@=Y5dv1JlVt=W>!eZ;XAqk85WS))==n|%DY z=(6Of&g~LTh*;BeapT_t67<=j%;5&sP31!>j0Jpe2n`tc%t|7$&iL)LD=y&jvK%MM z1-2<4a&Pt*PTK0iM_uX-3nNk}lJWWNu30R%gPnL`?2F(g1{}e*-0x3XNYavJ|1O}$ z^jHf*U7wdbaw2HV^eJ$;R)xKQ^%v^#z4J1ni&4P$vw!s{6w`WGgBZ*nZiwM=)+^+~ zpCG5ii8HQHOdg@NLN+?L<|dhx-Mn+Lb(a>Zzy zVhglp$EWptU(0x?-ON&}dKR9qN@F6I+EU z6qUX*b`{*L$QPa(IJ_Il(M$LW?dXP%7Wyx4A!U$^aN4HMeOWZ)Q4pYNE_I#9vR<*_ z(=S+4TLx_J-q981G?E+%-0Q($tm0(0w~!vw+wZ^ZT&Xb8xxR$%^EOJxTy&R>hG}9; zZ7%tppXv_u!glJiK_q3}TnPG7qb-!ZSykHZ%jF9{3C*6fuOadyHDnI3c$(e!i%wv! zg0pnHsqe}S2^D4`>rtSXXu%4t=+Tws49&9r^>wWwIF(%{5!4x{^7B%iJbt?De(e0$ z?&a-j5hbWmeW=y&d(Dz?%3$!nYfB>zJO3d(7HE!X=N0fqUuxJtnfhi=ussuJ)l1R= zKhYvmd5>mo0@F%vI~NDSq;O*U;P|8zby`Srtvg_9mNmI#C) z)LSEzMWSr7DroU;UqK%Yy)0rcL3_J2Y>Lh}`3?%0?HDFyp})GRj%FhSD(0RAZRq2Q zV`KJ2j7gkxe9Ik1-kx2Z$O-wE4+m9?Bjj@Cl9+*Nd0eASOc&qs@{E-SjWh`2zid%X zMoBE56iiDYgxO8C+YRx~LzDL?&3cR{xTKt$fCVM|)wTPmx8N8p0;{0o>hg-zV6(Jg z55iXRU)+K4imMF6+}*%EtM8LZY0;+He1!uTlNg=)Tn+YBcdfXKlM}mqi@~VzT9G>~^U4<=J!QVWX3eF{Vcy`d$-?dn<_c{u^>tV>eVTc!qGp%whJU=c?|Edhy>0rv2 zeDpI#k~Y1KQ(`$>4zNmfknz1lioXwq7S@1}sskzJfdC_6fzKWsNwcZIp3fsl9Kk(0 zz(<)lWR5w!A2nGN5p)l0#jup!3zIzq^TWEo@PIc-Mf1kFr)|J+Oup_P9TWN+lI&|=YBCQ>*6n6TeJZS_1O=|5MYdu^2N=e~-Gp`@<=Ke_eBbdzt zUK)~F6pdqe*51gS93bAqqpC3Qa+2jg0KnO=?R-|WzE^R!Ndd7>@4w#*CgTA&@Pk>b zc9PVTi*3}BIJ70{zZ#l+L4Z|5PDqbSl(OZh6u#O;8R(Vt=d`m zAvul?Giav^+6vJSWA_d~RjPJ{{YhC#(;qr22!K?-LrBX$ZB8rdex`8Po*Gv1Dw6Vd zfW(ZjBwt<5;)*TfCJ}%zntH%2g-5PsyHoH z0{Be1*aLR{rhL8J6q{BZA1u=^`jr!G(-!PY1iPdYbh^Un(qVOOquqqbYU1dvtmR*C zW|7^d3QTT!1lQufEgd7`z}K-`hc&4;#V$rbyolqXhhq2Z#Ai5(Gu+eZJVlpr!w^0e zA3}1OlaP~(^^=dHy4~0JOFPGq- z>EEDjg7Zt%zrv%-KWgBH7x7{Z-XL=YVY8?)$|aPa=t8Yorkw+w^wFC~@la51QDJ>E zd_#1CeOYx7%eqe&`{2^&0e~ZNI=8UrmPcF5^%#*SL-Knq$G5+RXRN4E!+_T%R`GZj zZ~eW^*D4^h%4-_g^*lV|RkID{(&UW|i*hUs#dR;pGa;EaT7ct|Q2Xs@sa^{wK@vj- zH0KnLzZvS)SnzD;(t!M9{S0v>*QZszU5iZyqf~|atc7pcaX+o6g7U<9o9b_yH`cR6 zWLs1@Dtk>J>qnug+uLxcJnwZo)HV?k>azwNv5O{~YwP&U_KR2)U!MZNvEIxZaoTiz zC$1OG!*t=%zicFcDK6ES%@6K@MpRn{nPmwp>YBz_s*v&)4mMimy}6u;DQqjT%u#bm z8)>{M$0_&Zh?UTMZG>`aA4(RAoT?Go0PO)30eTk(i5sCLN+NyU$hawWjQjL|OWRcL zC3oOJVlp*?!SL_fLG!~}pIveu!HLCKIF)IOa8HhHnjFxp^bM^8{yl>La-yNGy_6lC zPZxxT06;`UKte=8hVxSYOPGuRz^CJp0b6?Dh0~@LH*Iqd&Rt4tSzNjQH)Ae>6x|n+1|xEQ@(A_WmnQu&qF%Ch@fsi@%N29tsXqL=vJ&yC%+h;rY>W4jkc*sm+ibyi zSZR*F#*xl_pW^Wp!8AuU(R%JO6{gH8jWANKIJ-j!f5DfcwRJ>Y+L8jEDnBGQcrb}Q zXi|r{Zb+zz-BtZ{+v)*@@_lJeCJITm=1Sy4#;cVxQTsG1Q1;*l?tvsFn?hvXaWa!l z8NO`GA^5YaOj<)9ZN^WeW3x!Iv=P|j;4-*~3SWlWvspi>(w$<-cRqb-=w#2Ik;#ry z6X4^Bv|p_CCAl`&Cdvr|#o@Tx{*!R)Ko5BYriKW|L3P&+nVvlg2kgm~Hi114sT6H5 zn+@@9x+$J1OKFV{F1f&||FUSWfEsS7;mRU{sn@D~X%o+~@iJoIA4@6wwK_7wks>fT z1ut>CwZulLf%)@wk9_o==UZ+k02>ERCv-n8t!XyL2*b9wp?u2y#IM?>!OHPGH-m=} zaQ11~{S9H+Df0P_QEB@(bSTQLiMlmGZdyk%?6A$sqRwXeFV*Z}Q>>$o_GQ}yn2HL? zQdjNET!;!LEhaWLIkcJmUMkl7B@a+WiY7fWv(6*rxy8E#0Cg=~9LFuz`jkC?%>#3w zI9ok*CbI%$#8~c;Nvf zL}oQJb=XveMF18|q!jg^nY7-xActcFgVQREK@9{`qnIW{&~-DKMWkhAW+HtSHoZ<` z!J`MO{r7qDR`>PHju_yByZZ{yhd2P9Gg&JCQTr{lg;)CE=$5J+s?T(MKnKiJU9pZ; zn(JuNG7Hh_F4w20Md;A$=@+RyRESJC*zo|DY|RT*hT~AI&ynMv1 zhld6`J>h)z{}w|lZmO@UnOBR4w_~@i=0_%-p8He(01QHFnEQD7QHa$sd4J=9;%2tH-t65y(dOg#Pno3%jN?o3UI~TqA-1GsbU|t1%~wO76CMh zBGUKY30`%IeB+VoWN;k~Ea+;U&>=6}Nynq$r7K8POIDplTP;wWt_c+dyQ{KbLu@Ed@uu=$#Vml$B)|f4kudbKp<{k-V=Z80?bo%3>~Ql%K`N z{y{#QIkyHHs>3n6SCjdwKxOi7*}k>b6~Y~_=1=vZWZP&StpB^Qj`%l_BA6j^=Qon+ z2c@=h_lB-ymwC?7gzDi&14o_y>17QG0;Y6~PcE9Uy_ee*^JQLtr`zN?^9*A$DQ%Id8-!8Imr*6*@@ z2Om*6^vNUCkkr{!M70lP7)-O9#sX%x!pQRNouzo!g-8XpQY>kV#jV#R?A==H_h$R) zr_{8=2btrKRef!-`Adbx6+RzbwK zOs1n3O6>FKImp^=x2Rhg#Tj$m#>1qUta>3hwhLI0PbeQb!|eT1aqA?se~akN%X31> z_vadN;~>(3Euu=Sj#poP^f-|Sv9S7iTndm1+-Fv-`BJ}w6TR|H$a9RoA^>V>e1`m7K7Ct#ysE9 z_fa6GU*eVdrYYFYVzqImfIFqi+U$HmCd)!&0EPLOPkaO*-0g(tu&>&n79hk@E*!yR z(MXt}MOKkKCgJi`3^LFB2UR zvFk}P<}sB&NQU;Tex#(6zUXu;HdhOUqkI5CHpypL;}a2WT-ediNqOOXIX39H0-z{G z9%uN=K1pebzB4x{lE86fSvu^#8H#RP=RWecDfwJHLzx%yr@ zb(5`{1;?BbxghXbC{1(9a}ZCQb$TiAzR+Lo+}5m!<-L%egnDt(R}K^xEnA z;%zBoO=B(6>LSxDrZ|^Fu`Rg1zr+8k1FTrn(c;l5>iV{H=rM{6Gx@m!!tmLd6v(GT zjcrRaJKh+*wwIqXkZ*BZ7SiXy4bb17J#s&62_&ZPbgw)U&iGK_S~E)5G8E`N7K@C- zud^g>#{@_&WWs!!Qm5j3Ae+)i4Z8#H2yliQA0-p0azF-eHk{K3e`$yO0}w`lWUgwh zekj?sBUPo3+|r800`OD4E0WyPzZsi}de>|T_X$KSH2 zJ4>#MbZD)XX7No zrB$}JBF9M7Ib+4=Gt^z>{fRe?rVHH1&tqv7Qw3n33$*d%g=d`Dn)|xO2@(uPRoV9> z{XIqX(ralmC!j@&0Fa8=f^rsYDVUDfJ(QPWC$)MaEru$D{O^R5q~Kpw2C`ix ztBVb;E$E(g=VEOhk5cw$8X;fps>8cPB|W1UwW2*Db8PcegVXzzfNiJ^y~ME4pJ}&}voWm-tnq9)Bp0xxcsk zhv^p?XS>rG9&9qspW-HieVKE*u6_AYa&%oDu=rMNut_rerv5tJRpTaMI3KTPbL8@w zxkFPeP6ChvdB0U$e@B)cN9RpkKa|U(i3mv0Lkhg^pIs!bbUN3L_U^>+Rf{l9>`tWP z*UGd462^q8F`c7y8_x_Y=sGV+sK)yvv5*EuH*w74W{{8<%?7E@V#r>Hy_ZIqtzk9` zSy0a%<^~T78}o0|Ot235^Y`Xj(U&ZWq2VFe*KQT3q2r4=BuKG3A^gg4n9=@m>P#F~ zj1Ow08pYiF%qaWL8%w4_(_pEdt>|LCK68jEXoKydVzFu`dkO80TpUx_ZHzu(pst!8(Eo+ZQF6* z1cIAvSId6uZ`@Q_f{}_#T&Yx7tAiFvtPHK+_&e#ba@~S*hw_WiTKb*~voog!nF(cm zD!q_>6$GvVZ*AvtYKvG)L|a3#Q4@Fd+MkRkVn|yH#~L4V!qFF zYH0!a#8AW9Hh!rvp_-sn$NxLBRrfT#t)|yt)1lF7ls=#k{ZUT&PJ8QZ&Klbfd-GUG znAViIdDXU?)~_`!fGA%4Xf6J^416C|e73N}0n*a*v$J(nK>TqNr2_>bti`Gps)*z3 z`DAK$8Q`fJ)DW9&RE5pAG0y4N z;-ZvlA4+vdWrL;!`*yWrky#Zl^ft3FM=$S018QE#y8D;fN$`mUtiKv9jffsACud^5K z@Ufw|$}2u3^|(b=!2F)EH5k!UHK~G-HcH#OjfF%nb(J8%Fu?*?lu@K95G>CbmgI| zj_!J1yMMW*5?-KyQ>)H)y+{eVm6|U)2TR0I{M9~6O9L*kpl>>L4^&-Pw2wzr?@R8Qz)mkJaSyhxo5pHBl58GCk@dY zHqY8++ZZwu%q9pOb+#;7WCLNT>Yq-_jG9bPIbEC_0`5-?F{TJ0_ijRD*$Tyw{*VX> z>FN|kSglF7sh|QT*izwM6}KKR_|?x9Rfo1l)h9u|0V4t@W)i|1r$%h>zDIwMg;>{2 zQoSK5o>;%dFXh0>q>+K;kt%_oe)58zy-I@!G*_FgpM#~DrU#J;@c2kb&^4f)A{U%A z7%N+Zy>NHyRi9r>)Ydf7?;zhT2RJ4Y52u`bW4|p^0yO%vOj}f3Oc{d~hPY+AJKS!4 zfYo`(-82uWU7?6iFQ-5_Hnwt(n7kQMv>t8KF68|>En;LWWp6%{YLv`1Y^^Da7JOkc z(zofFVDbT34cB$X3JF$45dQrNe?_JUEziZyl+GR7)GaoWW!?RWLQobqKfK7Dpnbg| zN{YT8gyW}!&!^>eV0~T$v@|UkR*XjZr1NNbbQFXvM{NtOfuQIFY)Dv>G5GX)VS;i2 zdqtvCMoeT}g(J$GSVp>MTrd>J!IGzTy!leyt3eUV)SB(-TFniyA*03h9SC9f@;`t@ zfSYV@snn6>QF@xCFb8fcx~*~h=XC&mUaq>;4xvimp?FE}mjR=@D2yl_y)r}><=>?D zF+?}T1Ifp(k)vkWr`&S07x~B>Jt@2ij19f-w(zBOS1K~KQjxvM9By(vtVoR_M&liL zC5wDys*Kt2j()shwf%O)ByjySoKz+pfOHIsHEl7i-3xRWxzA!$oIrPO4ld#>%Q`21 zi2X7iF!wz8r^Sv6IiTvRyBU7AY56Bx?WL^Vg@E|V#AswrWR%Du$*Kg+DM!*U|JdOq z_Swy1)oZ6?LElZELXF#;tzily(<#X2608}QL8esXX(pBa8V9`IIZcf-tUPHSrRg>I z+sZkYmBiozD4$9nn2;}i*QM=9fR!3{9KTJ4aSMZ+-n*4xJ?`l)lD zg{ckuWq=zPC8uw$>q=#?#2ihDJ!^h}cr{QHpoT^URCR=G!8( zD|~@xEQ^mR#=te}-pP<6cAUmpW47d<1}#=nN2CsT?am(nkhg0(zM7RN8B1(WnoEJTEh$#1}_{OO#C5OKNWhJSQaLDvzN% zBf~M(^_7@2+eedGBSSGbdY_J(iT2vY8*}X~9sU z^aC5yE>|Hzd&UXBF-;Jul59F+p0_|-&7WM}8)|pb+gqHUz6m8oPXOAo4LG+xkxko` zSXwX^$}gZi(YzqhN38(n3WaFs$Li3YF3X!CJ!c-NZdJ&SusI}UUGNux7YExu(Pov? z4FR0!aTZ~@om{!u@wh6C07KWJ-3v3poo2eX1;*?$tTePNd(sD1&@*ZHe#}l#JyyahQz$L} z4SNB+eRo98j>unM$<@A7oE;l>WCYTumtGv)JFW0HoGs6UUx^>E!{f-gxu}S-52zzRQuDnDs4?=czx9x2>Q*Znv?7 z<1=_z$0>C^D>Y~e_~J{wOj}2v|9hZ5wtvSnYyGc5|E-&EH&)nHM^k`1iWf2CVef~X zYX!c%Yj(mvk(*UCV+wK7k76OzEIlEzWpBYlU)>AFOeHN0CFKHO9+y7ka+_h#8a`yZ z*cUbmAXYKui%4LDG5I5X4i`-9A_u$()gm|>1&$nx1nYH~R|Tx3>@&tqfm!G_troBQ z2;*vG_s{xK0M0SxHNI$m8ISOYXbR+4$i@v@5zUR%9gIV9_18_6d4*+yw2M)dzy4fi zzdbE+jAYmkG`*@|m=pR4G7&ZI`M$r%!_FCxS^ z!5|E=b@hfDb8;~Ci^PG(S1cAAA>kh1Vmujs_?ir#dARIR$pOX-hvK3|h%4CB|^P zS&jUh;m#WDb)9mP(}OxgT;mG`|=Nwd$1Gch$vk?7-f)H(}9>D_}3)ZLmYpfh<7W1o=AxO9S<3tjs#h z@TYqt{%-9Tw!><*k}Vhc5U}=nSbxUX9R=-{Q{oc{F_pfnpbW^A^uai9d6LD4&C#7k z7q6pb&T$jNYaCNxL$qf|&rtOO(bt+R$5LU)WP}VuE5lrZNubmO7T^<=(5+5g*GGrg zQNGO21fh+9NEv&eQQv8QU5QOMA{trf3CPsZkZu|YnGMiSdL!PL4KnC4vMK~SlSV9*l($jSibwBI23WO>S^+A zbCe`Jf7L2Qs2SuZL%nAg%;8QGWJ1823%g!6@2}v$&FfSN8WLK<6|oMi!mWC(a2WKs z4VlFV9~srgW2#eo!|3>u%8eor*)vo{un=y<1h8=)K{+sohU2j9+W?BFWEgDG+En5% zfd_cTH5p-o3<_Jqku}^X*yPl_Gqq^Pn1ghSWpjo-)5SH*}FDSLmZQh`wcLNO1Rh zmOX+w;~*gX#^<_#41dNmqQZvC=5>GF9-zO`>nGgZI;Q;b5#M+%K@}*xw=0ry#`@4$&q%73UdMp-jrqxRx1oi=u{~R4syE$dVkVG?xsIg$NzX7C zcVCp0W_o<{4nOzKC%Qn@9zDr)qswqyP`(6-h;})z!~pWaKF?*d%{QFYfBQ+-k(jVN z$m>V09_~Z?6PJy8bip*?TVuSZkKig;U4z5TpL6q(kc`{g{^JmN^6jhqSUwfksC~$AD(Y0XoCLq@% zB7x=(8_j~hm>;sp(^B40w&PqHA=|Y^z8zhhS=7ut~KUMV(@r`omtGVXF#cB^Q^pZS9 ztqjTS0(x)wZ+bVAlHF^q0= zc#HwuuW4^NUgyYB$m3l~{p8DWoBhG9thpTo9nsykP^7wH_f|Gs(4tzaaso6(OlyD> ze{|$trWMb<6U}eLaH%rwvvB4->seXX{-dILdKdFbSapJ^%Rj5vxcoL4^plC#ZqatV zu}Lbe$W@|%t7ib%e1+!q51{#=rnechzQMw3)R?(mi88_xVFGFB^E!3;AMn?@tlaeA zh|^8Vzi;jPo4#6mL7uhb*{rLkiE7PzzKO(k8tzDN3+dM-SOzDPIrgQ(r@N@&GeA!V z7j58ZxlQ;rO;qC@-rSmfR;^jZpq_h50_YZk#$|qbNEi1$sBiB3kr+20QM}9e#RoK% zV6dN6j(RIO8%h8yaji3!RHlfgVJr60=!P}tv5{pD!t)nuF_0Yb#)I(N*-EN>F|@{B z8RA09T48!S5TGn&qvO&;r>dni_?yq=VzoJ**GcHyVzpVu2jc(UF2EnCvi@n?zt&tg zkZ z_{I+2r%Zo;ll$pEJ$Ck1yAClsEUA%ybYj zW014`9XAq9>bqrgyICFmT!~)S|AZy8@yiic%KU1Gl?A#?r$%0snY1Df8hM~!Cd>MQ zIpIxSN!lq{6Se2hyH3n`w|8`r4{R8URoxek;epN{TYpGTOT~QkFKm1j!oY|p=V$~` zj*-*utgTUA?-{V)>xz}CSAS@ux{xDSmR+B*^gOGGXsI*TcdV7hc9yVpNz*Lr%JPcy z|3`$ve-FRy3mUr{Gug3F*vVFi?X?>(Sb{v;kRUq5KE)V$fmVkrUy^z&SVd3Ch* zNQ2DUjRT)x~sia!;wA2jri=Rfk^eLmt z>UXYq?!rj?M50x~Xh~?^E`-dLlFb#(&00z7HL&_v>TS}i;uloQnGc)pNaxsyTJ4km z2&#@}qxdr0Ua%`adRxR(sM}RMC!zJl($9EuL0R+#F`7hqUHAaiiDCry!n;bWsPBqB$9L@KWP-EsF{er{z z&KEtKDB{N{H-I2I5>s)Xy!^kx%C1&BMWDWBvMKZHFEipgEk?KqT`Lz^xX~F$ zR;>p1zFaUJSNc9;!gqVdsG`i7UNn1CP8g!6cxdz6GQ`?Jis1niG}qLo0uqj7(+-8T zmD#b<6orxlMwBL*Y6~_NHId+A&hn`{2R#L&E_%jBJ0%JlJGYla=#s#Xg_GjfF?k!? z@H_)lNzXXYT0`yUwe!z&-tT@t1*9^#rnfb@5vLcDF_ht;dD8dGRQ?feVU0UtIK}io{Bnw$ zpx2NYjtuG|V!M?0D!HD)1H^{FS+dg=D` z_*L#T5D|fj0rL+hq8MSB){$YPIGQFCaRZqeOJB~@;8vKpL2aYFEWUMsUAH1}eYyn2 zu$DB~XKDw5Fe`JfC}vtYku`c~smwQPvbG~qPnFHK0G2(4^_$j{1H^P4i)xXS(bcc zn4zOSLl~$yFSJYiD!m}nHF|KA!16xIt7AI@^^1!DM%)?d7M zzKI^B9+xHqiC$;ZPm4In9(;?y6Z4x~zAE|1LV5D2?D^b%;G>RWQGh2E#f0za9?py6 zH3+{WCR37^kgcBeh!yp9y}FxPdXdYT-yT6>H8acT(;jC`S!m`xRrnaMsKVZpHJssn z>uA9%X|}*zYRZw_bT3`DZB+&o_FdYPtHgJMitB5P*D_-qS1R9z@TgXtF3dRIgQzCCJ&?3o0wfa*$@2$q@gq_{ zWx^@ zeKUCBfd=(=LJ;$e6YW>2=x^cn$=uhwscp5z*6I(b>&B=7-2t_)0;U7Xzy72TqzxgB z`-7$Nn`NIwK9#HL^a`Z5zjrFpw#cyLhUE~uit3G0qPCn>+P(BTHetgo?R-zLh1FZ^ zsFQl%GCFR>~WU@cQ=L*`od@&D~634?W@d`y;r3 zK0+k8jHL7a#cMFCqveDrf}GEm3{q0)?fsg$AtQops}A9E%;Glu;jEECF%H0v;RV@ue6R>ey0q*q|g$&X=VV1No!b8;VwdtSy; z&%oMi7pP(d;%6dHH3|w_`JkjXsAaOCzm1Dk+p>IQE9sU`+rfpJt4j~#T;&8^V^(4i} zBNs5N;}DEgpwQG^WKm2Xm`PD;^!}0=%JNG7mo0fVJdVP{}dxk03}Vrl1j zlsHZx3M(hM7@+j+RkAU@?Ku(l<-!%E+UlONX1l>#dA7eB*MT$0z%aXFL$KYv{2Vv? z;hX{&#tpX*W-5b_bKO-n+FT4q9KA(=Dcrg?-f5BKHufo4mcQNiVf0V`m_QTnogp-@ zu6CA84wxj-FZGfw9DRWZfg9LX6yRENv3lWq_*&!*=hVeQO8eg1{*oe92VUTMb!_?1 z3Ss>tF0>nU&|OB}!TwF5$U6Iy|-bsr0;}{CD~9zMl_{(4FBI+8~`k`HPh9 zAt(%YVK5=i?WVL3?TTf+fyKunUy6_Y0>_xBjF|bzeSf;V0$C`!ejmF#YA||c`Y3sy_huXL59W@O$k{=UHS=b_f zj-Hy^>Iy+fmyXkmzj<%vl`lWwIGjEKp(RWvyy=0Xvc%h?c9&g6u|1?)%O%?3pp!0lwOR_OA_!s8|HjRvyM>TQx zbWotn&jghlq^W?i<7O}=)-185$JDTB*m_6v45vL~Y}@Ou_ND3LwJ9Kf`b@2K%u7oi z>yfyz(vB3vEdJN8cxxD0t*loCva@#K<1*~GOU7CsVwaE8=~987aK8l+UAbMk=dZue z;luMjxg^a86sTcSea0g^FYpufk|M%_6a1) z!pL(u+RBwgrWnpiHl*hBEk?`fQ&Esh41mmMwAt+U!T{H6wZSx3t70lA*~U)Fb`eeh zW?w@F+3TzpHs*4!iM+aw6wGBH|GGNR!C z*4z&0gK1_dAE1AK&?xgT_iDy6c?ScQZv6y~rLdpAJpDrKVd88liZlpM2TUKjCmZt2= z^ca5@&PZ5E$?(DB*L(Xt6j=d4I5`Kpw# zPq!rI{y@B_8S{70r7rSpg~2|y!zkxwSKzFwntGEGCf7hGs4YfD_GmO94DPnZ0DHe< ztiwYTiA!>Uln@cqpb04{z-tbx_t6tOxA%NY424CMquFWqmdZdcoFblG*KZmSVWa z((Thb+JwL{=b8d*{qtqx(+V;EL3RD#yfp@;dLCglX>H)j^Qt?~61lGWe+bhT{x*i`M9P zLNMHp)Pg5&*tyI6ARH|#KbmqU^YIBeM8MBd`I-Y&#U zT!$a}vUyi4i38X&?R!zJ&(`kyqsQKoRF`{W z%l8&cQqMF@mJvOoL6<=J3eq5*Mj%Rm5ovispZ-27-En%=?Gy)qxjCtyi|hqZAUsqU zcCZ)?xF+~f#0v9EJ9hhw;hJA&a<42kIRz=r)8cG-lurK%fT4PY%s4X4*`$B;JMh&@$ z)*QM+qIONHG1z70G&YFNGY%94s7b z?LhP}<99b_QW`^^{&bn3xyIw!2?;kR*WY$zUuS8-E@2!}2(t)p;L$9djd&HQ#o@Y2IIB|Du>G*|AKZ|E;8$2LDHnn4eWt#`2!yWW6 zJQfE`WpM!6Z^Sn`L2(Q`MtX*7)s|b`;qvPO!;&4L%pX)tQq-3{Dt5zsl&pM|=T3ye zM2TpO)=gp6N!;(KP4&>0z~!e`FwN?cp5n`WbTv+$o7YZkAXb@_6bX?3k%0HOlklya zIq!psA{~s?&vC?>j*fCEnHtTZ>HNQ{N)k%6+@!rqs4W-f#nXjdvOC1OXki(VP4`Z% zs1+ zFh6AuxTW0FoshVa{A2{v6-?rBhKCdDrSF`NqR2|;YXYpcz@7{_`MSJX#J|GeG-PKz zCMX3q1P=L(s-&i!5Z-#51@$R?vqNtLC3t!PuBcT{>7#^87`g~QqHzDF~2LL`qTxXmR1L7enri08GP}|PM?H$ z6S#$T$3YcIJog>e;y58fHLyl5+uN4-?!Ex(GUmN3TLzc<5JgI?o{PB;g^{HioCj0} z^a8N^r_oSu$88bUzCNSywwA-L{#GWur)5I08&qXNVycIv+jK_o0<5p7ZerLK0Q)Vd z+r*lYF}ryW$<-JW-r?6BOjp@jucNK5GRd03TLe}DW*G(=mn`@KjqkLi7Zvciddp>( z^E!HVV-6`(Y8Qn4nCWzRS^pA2`U_rNScq^Gn=NjiI>M{wo5>{y>iQtGYwUthDFuC?ZIxm z3FBh<{puiD!(8=UuC?}9i(>E=X4^s-9U-zPBO``G-Zv*izP5iYbgrOk=#%_e$rce# zi8AcXkLhDvw^5Qg;-9;{DJG7$xqM}?`%*podc1K~2YFd(BKE2@hKMbKP0mM#0OyK1 zST^VwKnp=i)T>P~;l)4WTq>=g4dp9qaLkUw|xKYEn)HaRUINrzU_ciz9@Q934A(aC`N` zJWN;2)A95w`3Vqa_vYi%+-DCmR&<_kV*jK9I2VJ>I$z|Bk-3AgGZJvRmf#2bqAAv{lL5Nb-!sfS@o_leme_n8Ub!Nz z<=E?%+Z1gM;R>4YZ;8Y>A?sTp z{_-hDy44GD@HG><$I$RQGpb~lFi%zKG9#_S-orR@_!dDPmH9hGmir@_DXCRJLeGw= zHLu_35~nPsWg~2KSVOmaEsH$5k$nB^uH|AiIiZ9aq~=_%XwL%bZg8An)&6z*IUUvXWIr?x)gg<^ZepR4c?E*E}ML}hRrGb%&=p}X8BvD zo4Ro(Fp&aPYV*ogNF-o-t-u}oDQgk@QcxgwYkHU@mM6p9pm1H&^1aQW%@tFid%)H5 zr>L@A)vaBoZIgKGa1OL}*c+@|{$(}xn3+obEqu9}N!pbrN{TraNsEKvKA*S(T24)% zyYm59?v<>`d&%fDS~`rX-E62M6K0OQ}&}+L+#$>4`C|k-lo?~ zki9nX`5HC#2+)EXzdQ zz|_5YuPxE<*>-jsDKGF}IN2JLWq^_%n02Mky)oXZs&-*H5;b9}RG}Z_uU+$VU5E}3 z`X=XKxJ_rk84#93)YOa?i?BI58kqaKC_bgcj}dL}GbPJ4@Q_KE8W+TtmvDqZSo*e50FuLZ-$$ zoCYFyhu7p>9}W!DwSl}BPp33)hs!$M-v{ZZgTE) z;bPfhD^6(J0QB;dR;m)pg=%3@z3%-np`;-1=s16Qo6dnT+M1TeRQ$u7kegA=d?6R0 zUArui!97?#$QKk5ry9gqsDO*+>R$(oUlbNe_HdmLtD1;>npUhS`zg`%M=#1Sia6Q2 z09ubtEdtyKbUP50B!!(21{}mFD$7V_?pux4=7D$Y^Ni;WeNT5}TgzxHA#Vpcal=T{ z+w)8?4VnR3MWc*L#upL}i}d8G6jDTHJyJ#6oOGFc(y=&l!}*P$YP))fG%_R=!WkdtK{PMC4MZ?hJg_ z#4p&OcNM!>DSO!DbjxY~rSYD8Q5aLx!pDa1FPGlPD@ZthW{;oSiU< zbvNbdeQchxC@KEn)5&VXr_ZK{xI*;4zFP^Ha-?N}qr4Jwb!?cDAJci2Utq8>&- z=t3RAWtCqZkY;EWnQ6S`cx5JaoAG`M(+o0b(-dj!#QExo;~8;NW zEKT{D#@|_9dc&^YBg~YgX`^3_&6{4Zo4=g1XYb#2uU$bf&xewjQtzOkh{!4Fn;zAx zmqW3(^SEqo?t;~bbi%W`t905{yCo;2E*T-k3>M=MTbCU%uLLp7ujodQd0tgM)P$4I z74OKB^$>5|$}eTF6C$N4Pl+M68S9r>^1f4#h$kpfRPOsEgX~(6z=fDyjlf*buc?v( z23`{R>n^FX_%aYj8!#TnM6PlJ3k+s0Dspjflnrt0VfN?S+L3BR^Y|`GN^vQY!Z95QoOf@%UlS^+STMKPPR~@soA0p~up#RalIM z;=#2Utgpg^R39sCH(daFC0n^J5Yw=)E{i_M7I5&Zba&lqJ@k%-9^XQrV{9_{9%aPb z+F|6X*`!8f-vg|sSXo(dOowML=JQ$d7x~fSa9y<`diw-@Hl&|35WTRv`n#8cKDdEi zsr}U?J<%=?)U8IZx&9Wv8Yy;E6)^JnB|Cc@wmQZb5z23jt<;F{J*|Psl$|E%+#4r) zgMYmd!j#lo=w!*nh<&mo{SQFj)+N%>&M@ym7Nf$V1=XMZ8ZAdfH5E?Zn7oT-1N1qi z4+?$|_Cbw%ls8ucYG5`3Gs3+uL_-)D>ER@}`O4Y#?;%r9L< zn=@(ZJIaqSU-mDZZb`{FGgVFh&|2XDs5{&vtg|L$?4pi9t@O3xYgY4GwdeW#aPVAB zMkpd>zz+v)%hATDC%8OhY93L0rGCJg$!aovWL>K1^#it+s0lBm)<|Z~{aHw?mcjQ& z{9%B6wDkeK^Y#xQ=LOB*sTw>#Fzv_hP3lroX;-;>54yM(&0C*N&gC>bolp`f8R?i3 zoFO7!$GB`(lBg{Bl1cy5omy^;p#u0R7>2scRIJnmLDz-;0jM1CDY05%dw$%f;$yAk z>f3zsn5vpxX|Zo<-~g>)B{yzn7_v8~$FKBr%VOdCqz8ADgW?3AB7i_YRx`f}P^%hH zw@M_|?t7n*^K;db#@Z4;6gasCkgLgiQ;V{{=W(AOr;DXoLoWa@5l!d|m&T>d=`mN(p{wb-1 zr7{2>)n)!dLUXwRsryy3aQ+{FBWI^0S%7CJk0VB?M-_3<&wXC9=A!484Lf6NDFv-uK19SLgt+s=60(g1XbH`0kO!dMmgHzLm!EV z9s|Pl1>|R@*T1>8Cz^_y*0a`(b{Br9&cYsQjn}_i&1SVqnVm6WR3z-0Zv6<(Qi&a` zAAH#STYQQ!L!+phCD^v%b$*4YoCP^WspAZ1L|-L@n|K|3)rusE!i3fKenqx0^UI4G z7iR{SEQ#V5Fk+k>;QLXRN>OK6*GuJWmKSoX*Xf)lFU3^L8I9WY%Jpw#Dq$j-)2Qd9 zep|L&b8Q{+D5xa8vRkyc_b=9qD(Bq4#&=^n`xaY)Ajn~SkRad9Chd|iyg7<)Vyevw zva!JlU&cBOMg6%Ml0oBgfx21N-i9l=EKPWp{``dhfTL8c4!?g$u%|U+A$Rmv z>puX(M;EbZ7BBpo{kmqZt37uQU;hYc~N$KTu1NRl)qnb#}ch^#!IjIRh6#fo?% z^2D5t!P>1^;m3~so?NJXav=oJs%Nz1j~pVm+U1hRt>gA8`erI;PyW$}K2aw^yl(Qj z^-aUklF+ml6CSkQo|A?F+Kv68AvG+$Az-yF04H>nj{Np~uv9HvA-@Zo8~^a0BHwEw z{1}+{@g?Z@1-8;Fj8E;nxyJ_jZzG1EU32&T^ODP|yw8cH#xYbTJ|ujB<9nF$ zulQO}tyCJo76gC5((4#rc*{^dGThR<1iLFjLJRDOtjq^~0xVMWwlo7i&oY(1=_o!X zA-}zuG#H_G!%>Zs{~!x858D=~-xT`A>$%mL_a$G>(Jm6a;F>b;Y3a~Vz9b7bH+$Es z;3a~uf$`-tOlVzy_d$c*$+r^m4&qZ0Ueh&Gd!yVpBGt@X0`24~e4TZzHia1PO-JRa zsuDJEwSS&t71h+7!}KS}`r=DOyg#dWwwoGU3DgGEt9)atFzrl(PHz`Et(+l0goiOl zEJ8f$)z`_ES*PQud#;2 z!u{w+-e&4q#5UF?6-!kBCus<7r0U=$g?NHCh)TMWtM0{%Bf8d6poT2gbDzKt&2_ z^iDPpIfns61;*Pkz-t?-QsXo2&_NAjbHB$pxqG3{S}F0gghA->a%FEK+%^Ksqu?b{ z9`MXiY$U-qDhKa4Lt+-(j5jawmKFy>SUe+?mys;8aiUjn0e)vo$8?Pr9!ApHyfbgj zWb?%5%N&364fztQU4Ml+q~h_sfbeG*#z{QTy2RTrl)qnM5v&CMp4X`JQ2qQY52JDt zecA-n4f;59eB97T_O4&{V&8!*=Fo3tdXTsT({*{-%%<)w0<2YkA}vH2m1tNa=KW(`_Rp{yxI0adw9pN3Q1D(4j4=x?G!nt+R0kAquv z=;(GszIA;T>_MC^y9lo-dH3GmXPU<`_TPmzD{GZQ91P#nfP=-&Xm_xo%3XeA9%UOs z<+trIe3LBmZn`qy=?M*Bjh$)lTCV%=6z*?jtFi{+8{&#{9TO1F4tBo#S%&Wp>IO4r z{RP}CjI%5fv*t*JLqXareqqfkHk^80KtJw_Xa}LeF_{XAn1UWRv+v5HPMMg>BWX@# z6oeXlrBq&Mt>KO&kuM-DLt@d)j}8`wxU%AjW*bHvF@COzQ*!yH~UhTl^P^WF}U+sZtsn+klw$q;`bbhHg9C+-fw`t z&aRh_V^2p{V_DR8mTjy2R&ANCH?>PmXpToxh~_LlkbTYr-o$Cd@-FvYTPfSiLh)Z2 zMAE>{@R+ENO+4-g((&*iVA1b|KALdM42TN7US>K)|FewiQ{s!?JQ z2%ctS1F`dR!lM|OK4)=YVvjwPThXc)Zx>J#Xe%kNid?rvECRLZ%lTprM5HcHYqg+SR&NC#xB-v zdSf6$kj+93^68UY&s z=Dv0%ZK8MJZ04?ikJP+y+FVljQUqKMh{xb1S~xj1nAy@NH4{?CPMNskE8L(&VAm*22rHtfu#zFaaYQKa-Z<(`Qcz35`12tu|8jPq}lQdQd_Cu z%_H;6t3fS*Ru50_#K2eG4)v2+6i8|bRd#A$jDG;ad*AOA6~CJfgzZh{qBX&~%z!$w zunddd(gm~@qu|OPRmK66uO4OS0}g+b8h_%Jf4^Yr{|E2_=Coign4Jz<;pv~FNg#J= zIf5<)xxFSKd;WRTB6WW8VeB48qkQL8)SQ8Boxv9-R5k!mG_<}=T%^XVtSUzY0jwqL zO)KpUnfQ^96a+tWZ;o=suU*6Zv^hh^VB=@m>|KQ&H2Exn=SiX8)lNX}FQ!@M+}_mT z`y>yo4IaA_hnBs4pLKPVjiG#>v3;uPYODu_1N8`2AS>Rp$u}jBWB6^oy47{;^^;GM zRxl`&2usjUd-jNwOB`Wtu_n$YHC#~n1q-&s@a4oIX5ltz9zIn@6>zp;IGnndwLq1i zNa%0)ZAh!Em40-%e82TF?%p@%`C*bOy4oEdRRU#@zmE_~u0Fv@YLtAlO*%fQ*@y~! zA^6>1n}&~vh;P<0u1}6{+|hKDTfjK;ML^=c^@J`t?Dd&|55I~wb>4zxN_ej*=$3bG z2}Q{rsB9TgmthJ(1s74OGj0R}N$6-q3pZ?9J|PBVt{)>|Q8p^o@H};xXsK+q{M$EJ z$@ck$Bzmrwxmp&?&5aUREUwEu%YSYUto1sdKKVjUO6~S~;o>r`0#jw?0Upsh((fL= zSKCwGA73|$8;!4nrp$bwZx-iQ^AmlB?z|5`3HekINuunA>|P;V9w2=eF*U@fl-U{Ja1(T9!sZ)l{-j^yKIpH#pj#0f@ z2FOhSfeIeY#}C3dc_S}e1Da|--OAY}6kGikwoKvNqdUpa6UVpkR()mZ7h6BMGB1A% zm-wglVt*~cFD|+o^t;(bSO8x=Cigu;;{#3;X6V+^Om2M*>TBp{nx}gBUiW$!Y#h7A zx;zIJ6VCl|U{p`XE{<-N{9C1P^a%^hj%f_3T1Q3#cW7yiCM?KqkQgs(u(YCX=?a_( z^o9o3%Gu<@(eBj@qYl@zJ62bNBA!y)$##@KR<^3ae7nT6IL5w)3SI(?!1gf5HBowR zT$kKtSLmc`tpXn`0O9k9HX4=ZY$^5`IFVjtH$=oV^ejzO^!LTzty+gcc!84^j!xG- zJR0~1&*#n$ltU-B;%&4u4Wd(}dhA$+Nbb`o-w&w9XrxJ%5l)CKuKCrYV1Em*Rs60o zE6Q0VVuI|Nr`2bmUb7%ePXuA}#l6<8*?GfB9bJtthCq}zBek@$0W$8%g}jy+yiJeD2RNXJNXpLIbD1)kHJv5fJqB<{=Aj3Sp?IjVR! z7dOOpV7`LyPXGWGC2(i!_Kx?DU%zk{kKFe4#Py6s7KKu{mVh*G=&a@}(q)Z#!Vhc}Jp{M{0G%@xH9qI{8SHlB;lk$DV#pOdnWjLT2E?O7ZRhlmY5HXatMVhCKS z^Ui&|*SkNmi_6|x8m(L9an_3)TFsT%hJzF z4YyOT&(MUK%x1#%)q0p3%@={XymJ1D%&~zp^p$kql}y(NN|*|iQ>yvoPve(Ndu8KK zw0phzwp^Z{y8$udYC;dTx)@%Qh>(p|)zpLzSW`bsx2AETCnl@StqSSOG~?T=>dn+M z4~5g)7DcF5T~rN(VbtX8p$OZ<^n2_DGAFpNjZ}M5ZRZj<&6;(w*ly!)vNlU<7HU4^ z#nC>+LuhR{;>Ob-_Wl^dG-{{r8Qa~n#A3G@593#H{K)N>F!aTQhsZu!d)A~B=Syi! z!r2_((Bm1F2)bc7chJN`R}=d+%OMvQmpsl-);-mcda?>mNu`@vkjjW@yT6&7ZB+Z#bl_itV2w16s?ZziC6_)*2^;3Rv;HKR(xPeV z0+#XTshFz{ra|L<*vam!$qMFK=f9+H;=h|cr)csNcpJQU-`6z_KG*};B0ccryY|21 zAGBEBfKe?&A`%s=-N$R7+D%#-o)nY>@i!+hA@JA8*fn8ioYc^kn82H}r}vqhJLKNyKNW z@LKwA<0~n4CBI)K6q%f68=S1_RaKQO)vvRzKox7vl0BT0WB^;Z*ce>^Et!N9L-}ns zj298d@M(ld7LT6a?tIXRp9JUeK(Cjzx+F#2Mk!b$ssv!ycattG6hHHn(tu=Yveut8 zpo;}TU0W3?yhdNUtKlUIj;`X^>jAmEm#6$S7wu|=jT ze4d*zVYbDA0MOT1e&>blJY5H>E;j7Qc(bkfx~k5JV!qD zBgrnK`Lf0)W!nsR^+bYX44A0syy(Cr5l~!2FMO02gX1WhzMgePAAk|Ib;;bsm6v%V z!x^nkZJpH|0|2HVmtT9t2<1Z;qCOIjab+v-gl-xq_HZlSbYi(D$#aqJ$gt7_jslIR zgA|6~?dcO~3gTR^DQ!uf(`OuMmj|1wc-&^sHcKSaQZeDIumaqkGL^@UkG0||zm+F> z;1%>T&xAGq=-0MA7~@z1>|X3@qm;jOZ;DzU`=#-kn8kz2XErE#i$3WGI8%W=QYvN% za^G5xh8xoRYJB2~e`wNNb>~!N)>}5|ExryC>xviXobWU4+dN0Fq#bW!7gDOigJO1S zt9V3+Gh_MzGL^1AU4t~q>0aD}qvFqP@k@`=okE*q&8VKOG ze#kD#EbvcYPFgGZxb_5TK+YuVVLO36A4v&F@kJ%vtpt?)x1^{VoOs}Q zJl4;*Ch+-)%U}I$6$Qz~spgddbKQB?w2n8e%!WKDH=<&lQ?m-bJ< z{f%vu)daWT-Kk`=-a*A-+|D6|AW| zSvB8^D2j^Ql!|c#?Xv(3t$X)|BDoo5SOB3OPvBR1Ex_exCYi3^I-PrK_UyhF*4`~U z)6nzzs{t6=N_n^UZ^HP)tM~{%%4%wQm$EJWbdSZIObJO#m;EShQ-4u zSzkiR63vd!y@lC9WxE&C@t^(yFqM3n;;ozPZbZU{lIq+lCdZ$_1Ixt;m>3;q4Ic;Z zkj%)GI05M2caas?SbPZlTk6zDB`@N~zrM0cj=2{5jf>tq+!y&A==k-CS@3r+Gc&*Q zu1$)DrH5f5{mn>>jk#{)A+v%>BX9Vw!VmWKit1yjC2J!`P+Qw3XhnYJb#(Ff*LP}A z?8u|*F!{``jr>{n1A~4v*24wMcz|wh~W-iMA;Zz(m`UCquL|GD{!y2^1>R2Ul64tVSiziq+c%oX<91En-ZDqg~OjHYxdvHp0cTmE5 z2HFH;33mXKW7BGr0Ez%u+Hs8DNS2Fn7R+*}H!0Cw?*Bd972fARB6p|%5*GX?5^OU` z779eeKv0_8TM1++O^G25F#8NtBoXA348Hh}gs52w>p0qrIOt_4H{}?(X&Ud6gv>Ak zDiWVAqM49V@h>8v!A3~`WHAYDoy0?pGomvRnPj}21z+MaqMnHQD3C3VbD&Fw4)fUD zC{0n+40J?86h#CbA%^Y}gLaceQQ>z4Y#L!~8Xk;7Th|H&K>GC0!Ga;q9&nD|D{I%O8BSY?g-U73%$#C z9G#r;a)j}3A^+R;d{zPz322V|A6)VOg}HeUv=z$OGW!1u_;!}o2aV*d%-!|>7XAVJ z1Niv|>gVq4&k@o`cM*^~a{Ucp^q;25fBy&HG3zCon@7-BqB|aq{&$1@M`qKaC^Uae zLq}Ahn559O2`EYd+N2KNnPFT^{tvLfg`0$;(2%Mnm&3FdZzNi$@oZwi#R%|uJS|FDKn_=e1zVJI{J#UE(A_T_wD_kZ{l%j&3tIex zaO=OKy?Z*1MhkA8h3=|zP)9{~F^x(*+!nYC`kGe~tfNZy_U3B+ym9 zApIW&{tqM=l|>W)f**8GB*E4{1$2xx{x{(BNwD`Uk=Hm>=tRP29E@f@bO9Fct`ex} zzy10DWu0A3iA7D(#RSOZ6N-=|iIHj1okr0-=Rfc>ki{7^1w{X(y+fj1f=8}KKN3zR z|FHO@rYvNdMNbA(B~-D55Iq7`sBxsm@nlY%Nh}gWM)1KL8Z;x`ShXY)i|9_MF1o7@ znVSYH%t-7eNtBL}r2Q$+dEFh_ixGP5215A(iC{ueDYII?%{W-( z?U8~8bTOINbA%D1z07wMUnUz2X05KRf!P_{&*ox+aX=wAT=i~COp1P>~_r0 zIpt!AL=IC!?M@%H)POaZv)PDWp|(P=tdXk+L6(+*{n%FztcAy-zAH`-_ds0r&!K8G z474*@Z5*XL(yk&xW~3kb2?MFq`_)QL9uvLnNWZR2>+g`0!LxZ*E`1U1{UC}Abby<^ z3N7goG!yA+^$FNKmYvabO->+0 z9N%fH-;>Z>=(DL(y@h1z*8wzrILOiSs5|;#+|8x#K0vf@p8uc^;xBic=OHVIP^LTZx?bSn-LK*3)PQQQ!yfEhA3Zb(LY6 zHReUTqp+|2#|YeR4Kk3>w;UT<+N25QHbQ!qKrd7mU>1u%N>-8HH<+DY_q|XC^zp<) z;gUWWZ=I8VmO3Ync!e+f>6Y4CO3ZK7PDF!0@qizi?HzR5;3nC)F3Gk(_VstE_he%f zMeN}WFdn|xYq8!nd(65`i@Tw!vodVck-)zT|e!=gitK~>`Bp*+Qe%yV5rZYbo0PO$? z3kwI$Y5(FxG#?7dk)fR+g`!;`v7lWbZJ*0pUcfyO|8|0e=1BB0|0Pzuh}2NF7K2;Q zDTH1q0#I9jsHGw&!2+hymB|JoPuYgYBOhCb5rsc>)aMVYjxi$mn8?BF=zO^2ddMJk z%_&RYK6qojJ}A5-DR{|&_$Ux|PHBqm#pSAXO`{V~@JY)dVkrf|rJ5oh2G2Udlizs* z0U(@8f+9*%R8Fw?@U`3}A3>dRg&9Uzgxxu*>*GReM2ItVYlyUj8%xV6K0HjRIkuH1 z1|q&qRz}lm5r?yQZb#T8=JE{#(v($#=cIrn=Mnd7(8t8Qa6P-G-HXTs9;gc`+7hN8 zPqAWr!W%s=n_;uS^4TY_>+%Ya^OO^&HkLIq9qk<0b}bO{IV93nvwl z*80!?GaDB0Q4>DG%utR(*rUGE*##P){| zpG`KE5E2L>K)?`+As~jPfT)|$18V3+)PR79Eff{|CIkpY2?&Ua8mcrE5WHBfhKPz- zE-ET|(F=%**sxyP_51RBXWn`L`t9tTo!Ob)nRDjMoX_X^e4gjwq14(>!16PH0p;YPV%fOLyevq!Cmnzi`&q3h_0K z=u5|iM(c#vaL0ILXjvyPt)ix`9OE}!-${J0Nlq^ta7^TPuf9^n;F#aIB_+@MAMm~v zWtRMWl$GJ=(P1=dDMqz>iUKGig~~H{r8MvIjoFwKQ3so4=N;^Jd%T@_PoG>jpKRgK zu^O+dcpJ>=14_YAFU zQI0cKS9H$D>O`JiiZAnz)&gboQD$MPAM@m7Y7$B1_}|6|@UjPQ27BUqh)l&F!|^HX z%k%e}<$%A-~1oZ}vw#n#m@PI$*G~-{= zm?9v{EG+khSJ=fQLYo>p)=sU*TlV=nM)%Fhzs+M|j~SA`x`{R@RZnwl2)2 zz1k&(zb*RFs*M-u-;^o)nUxj+fKEuw9VPBVJ%TXQl)aCctc(cgEP zj})9;qSdyL-xS-N&u9&+5N)Wfe~mihxQZn=-q?gqT;@)nYHjK`u18d)Asrd*T4c3Y zKf6}t{k{$mvphRwP~>F_^yV#<<4b(_IkhE%l=u%z;dG8<6WG+B zRsuS#lE+m|v#)EpyaRqHNESv@-_}7m3;h1MH zqlTm`R1zj`FiF31nF(#9sF&ZC*rvLG7cnoT{=P~*u(r*xeyK2!E-~7iw>y}x$JU*QQ8Y4doovc~}YoYz8Qttq>ckZKX< zH9KBJ`-7ao(!kju-ghWQdB9jOO}ZtosWxR)ne0fv>fhS)k6HsJoTwA3luCSoon!=@ z{od?oeJ2Ku{j;A+2sB7woqMw3-XKsUdV~pu}&Obuq=ly$@65Bn? zc~S@GxtnP9^!zSSCT`Z%YOPheGZ7&>^ar6Q1PoKNKc{?OczwEy?4bDv=03xI+m3sb zG>9f%z`hOi{7Anh_HbWL{S1T8DS5!mSjk&64@*5Q6cH&^@+hJ+!={XJ?wO|8 z3Gd%BMVJq12W1T6rqA%eqiE>Aa49%rd*?Z9ahPm-WR%4AaV8TU`clYy4Bi68*`5gD zFR5r#4zP9hJN4o!<wA!yPgvY1hPm)B6~XWyz%pBm zAFSk1{#(*Ffkp<&saNfd)tr0x_DSyU_1!*4$xkxEsF{nn>xKKFoVZh_YPTwsWtur1 zfHs%PSJdfW9_^7wo;v80=RxF|S>BBg^o+}<2Gd>tt}7arCpa{h8I zvfa+Q2{m0U96rNbUZ~v>rAZ9BUX8)nY%nkI5j6rMuzR%am!=r=i6@zO3h%Ekn>HNi z55~N?%Ibg)i)qjC4k?s;HvuD7inUvpxq}B5)yl#M4hIlm@-f`nWn+p04KL zUc`L32m``j@AX;i6Te9JrB8^$<&AA!Mg^{hilz)wKMPYs^him-YNG!3D?a$*qqbE} zBCuzXsWq#*fyMj;OM9CwoCW`Jd^`;G<17CMC`QlV-=O3#5b$OcP@tYE8%M~U)8xnB zR?P9;B@Ypm<}HagAL^84+bQ?NWVhdZ=})!@T<;tl8S>%Z|Abm2?ELDvUM>^K!m@cnFnN&MDE^t`YXbU$m9m@37J zSMUdq5zf5$bb-lF4c&B{BJ*g-$`Ks+4)VhAc=)Q)4$%128Iv}-ZCxQzZ1mD8HWd9bhg>D+tJN4BT4LSC_p7!i)iscnfmqS`GC zC$in3FqN~Ft@Phey-b08VLw9;9T+#gJx2ysw(7;>e4fuE3v;fMIV-Em6s>E~U!4-MQdnBo(Sol<94I$AU6&|Jif2ibg!?^3;eTX}kmt7hWu$cLYVMO3^~-;q zlWXVY(Ruf$Qz;1xCj~t?=vcyVw3U%xi^VG*1$`Y@i`r-QI^pMBQ?cBk-m^lJ6r6lwu0M?-bnDJfU~OS4LTGa#Y6hsha{2)d2XkTxd1KybxS)bcM7&yc zTD}AArEjg;nlvXPtA`Z7sp{LWxiYF{Pkjtm#<1SQ;YnSV&8Z<}$X1R{O=IW6y?RxV zuA~ThM3x)vCMiL>38GBdH=G9&TiyE->}|z!%9>8}aGpy&OfERMWc4nsBJo5@0J>+t z2V6;)*%0Aj%xf8WE2g_&dXHvStA4AUH}8#LUN$jQa1gZ~OTejQt0R!1uuFRxlicCm zr5p+8K)LNrBQ(zNXJZ4jQD)rkx}Uiw3sB!5assZ8y~z7%D~R%6TtA^R5qD`ed_1G1 z?m5yF^gd$D%IV6#<9uw0X9W4pIOtp+f;iVoR_`~UklUVF>C+a#YjY+KYp9I-+(oaX zIqnAmBumZ_>#ZC(4KR`*&LB=01&et{7l!+#Iueb~l!szw=>JH;OW~?uot|`OouiKg z_;#MqorZhN!;r74s+Ac3Jh?$by0gY=>y{bi#ctBPUxEAEf3#dD=+Tt&K|x)c>xB=! zO+3rdpqY|rw!*Sao8yVQC@PC0GnmgOdcT*_ur{4F2jdIgZqAm?`ETuS(ZPp(S7JSS z7b&d#5<=YBrd@uB9i+hN_pey$%jyCL*6-svpDa|ngclUoRXq{cDbV?4SIfn2)3m1R zRy@`s>0@iwsl+@mrFV3!bBbT{5?D;${BhxjnEL$= zMVh@+cE?w<@^LG9e~4vU(j-!ws?Q$$AssACt=!p8z&HiQ+xN|mOfS0Abp0gGOFp{L zBaUI-1=C)Trf?7<=@PadX>ZqiC)CHfSIJxRU1(wI+qp3)XLM=a+MUBcObshQzh1Ej zj-{0yauyEEQ_ikp%G9~nJ=~yz{&W%#wo3bP+^0TOj@zEL2-FrprUc6NWUKmb3}n_2 z34@cyI3>AWn#OcvQfJ@F!7+&Q(?p&6)9T++LX$CEOInF@5naDMi-La{YIvubb&%pE zoD{%~Jb|H8C?7?QU9uHcL+b?&vi}032Fthj>)(Ln4sGonPj>j`R=GFo5T08c&ycd0 zmKro;V(eBnx;0N5#)jr%G#vHXmq4Ypu~(aTi85Qz2+J1wDjpuiQu|u_eDtn1NC8nX zQ;`I2qzatQ`86x%s=k$?59Pd6fk?+0&($^P|A#t#(&sCB{UzJ{B$z8=;NdLM-hQz% zfWx6KCc1flaq$)`8d|_enfKpL6rNE!^!-2B%Br?LID;}cmdvr3^;edSSg>ecXOL{! zk2~zZ7^!ZCGnnLltCVRFBIZc{WmxH|BCj8MWh;s&$f%KUPVC$=Y=H- z8vfcNy6kJsf{Wix72e(ud5`E@Vv%o@=Iv}bCZ zufjl~vmOySX?oI-yhP!9^=l}g4HlxNIfH$rtAJkwFzlWE3;gT@xnF9-!K8^YWHMrSPRqSfq|h{aCP4RhGCW&mW(}B7-NGGhN~Oq zrHE>WGQk!PEI95}YWQeCL0+5D7ET%qs=i}WV>cWr{;#m1PZSqKvL6)FQYXWE4;6f= zk#=I1(Q&;?XVZ8zMI?^jc00YlJ;z`8wqVyIFjCHmt(7in2z zj5%b{yC=&L2{B=m8}-3GleD}LyugEG=$V`C`_A)`2PO89o-4!K7cECOsYolV0iscC z=3X~mfZLGKR1U>!_2Ts(B4W5`XbN^xSLhpTbMZ6TGRiG$P$VUvSYx6u36Fi>JhESJ zm7lA)T}+!^S6I6V(Wt5RHxM*3WtkQent6lZWeA)SpR-j7vLE=*$OYemx&Mw2Xsc%Rn=FQ)+-9eYyjJWevsD z3JjDIVd9q5a5YF69X3lY>w^7f4nL$%(UcythtV2+5<4v3YIAZJR}?<4=`n0p{PeUr$4hpIaA{&kYyL z&79rOO)=mb!Fd=FpJX53a#WMQLW6*w%N*FL??vYOm>M9GV1+2%Ydk>( z56N7xVF^q`G&)UjvU+S0C}O#r&|TgE)NiDMMp@-DOt5Pjs`KyM(O=ackW`clz7Wr@ z92Mbu`Floy)s%du#c%Z#Z5MG1Hz`Q`(Y2-&?fMpu4{`jCppK)di!b+`)(&r4Du~Hj zZzk!J4|&t}xBBXZl#X9^E&EC{52y5*Lpyq)y(-sFp&a&ULt7_yB@Ny@_5)dTzYNJJ zJNqutL@BEsojodC6k{|&`UovAb&ynGcA?KKcc>$W zvLH8(NKBEV7`gNaM?9Ukp`+u!_Q3Eq|9*J(I?A4yHO<8fa@5<81hc{1P7hM66kN%- zZc(KuM_J53TV)$K8E+7sVqMvBQEL&?)xgFSGSkB9TPc%q%PRvr|CCc^5yiXA@3~|9Xu~4RzJ**Ls4WaBdF%rZnvdBq3$D`` zwNaa;ScT;Cg~KL?F&HUg_svSKArpzY(y#-ZN{ip$z3H*emn-?4jfrdft|Mo9IW%6X zj%U3vRWK2_Zf_ylzj3zOV-a*R>*4G-btcmSDKWH+mbySdS`NoY@Ws!0b-~t>x%0U2 z;`)$mF!BoqKaTnnv9sniUDd{_((7~Lvwi`~8RY>ix$y!Wd=45#y^d;1tbR%kj)We6 zX!fLc*vK0#8yO`eF8j@-0g!%;ojy}Nn;HM_cV=bA?bsWhYaGADywqKrc|Jd;$9`UY z`u}~s__uY(|NYbd|F2pg8|&L&{6C;zFPoCWw?ri{hwvzo%IcSLjSzTU1=YJ9%)6Cp zb@VRA46G>}C1h#cs-T($8jZK255(dFUe$CW=}pp;0AQaC_eks|HBYIG zDg(dvrYZ-z_K+*CR!?xE^o~h$@jOx=G`p!`)N9X>0Y3ibS524}Gwixmd9v$xRD-jssVK5N31hCHkBTm_X4LK*sX*4ulk0MdEYEYi=59pY?J4 zR=sj@ttBn|rg6qxiW|K#+_e|pnR?*f=g>6AcM++chp!Tqz@+tg$=!(4VzLVXeNZ&g zfWUv3;U=?f2LBbCzu@Tk)}r|8805{T;wv~@0wT2@AsqnI!(o9h) zyhQLI7K`pg89kmz{_qUl;eyLjZ?z#N@S|_JnE0&`!VE4y(8vumxHhGRuqSTL&W^3< z`qVxvtWe^V&)beS5S}!`(WV<`8qX|pIwBm^u`p6b{v$j=5Ol0pw{cXxC$%PoQbEIL z)_P%qOWD=p95E7FCP!xla9rfmv4}mVY9py;xL)Oi-$pNgm0T#7&qlbw?8YbS`Q~*w zbf}5QB`YF0rAio$MEl(78ZxL(>2yHH)}5s+&13BN+jEkpvUg5?kTid*ARqBMr@%U@ zI6()=&m#QVjq&$3x0~j`w`;5~`e11>$xPl;jWp*fC%zfKyw_v+<>)dTcxaukCr@(= zr=m<{=dyk*w_=`^)<KgeIvAa+|vLfuYC&xmrZ@BT~gj4?$%|F z)jcuAheE>#A?FfK+pd}{^E5+uv?{R$UjrhGGkg7@|Xanc3`xeICB7^jOKuF6N+SXTOY`A99a~od`g2 zYo9=JGngYYZ$sKh)A;os$8K(sevv!_Z=pVD@62*Dhag{X7}eRMPdC zs=RS!aPTtb9R~E@+@+Xw4F3t8(~JKNhyMO-;KIt8)&KXz!YeWA-GKdJucOtg3lQ}3 z5y+T*9Wdez#}DT{fir8f(8yI<0N#H=-rIop-w*&W%ihh5v2!ad5Y*Y*7=0duoF4(S z>n~RPaonWG>hJFAbGZ~V|BNpNLQmxHrsOlr%)oQqWWwi`4C5|^vN2<&S-vSQSBsHg zrbk6@hz;NVi52B^xRC8FD&-3LrwBH!W@T!;n)dT*zm~muzM0eUH;o3KAKy_nXmSri zCmnr-DSx7LKX#N!4$Zj!$2MA4a_Rk|6DlZKj^VPF z7PACA>rJ^Lv<>TqB;{o3p%Lt5o(f5T|21oLvfPS>|%RPP`{fB#nHA#Yaf zOx&{vdnp?L8Vq>t3J0NlOj&K%HxL>q!*a_rlrjU_vs^6WX?m*<6<5;y9DdG)I7sQ@AvQh z&f{u&i9^Q3dA*rVOJ`4Pr<7fGYEvuU^lrlv^eaarP80>!_8My!IVKEaa*%>ucu!23 zZ0{A=*EWD`W(gv)9t3k6X1}@?NbGy-f10CkBQDwEkqq*J>#f);(iBhMJx|Sh_F*v+ zGUTTp7&thE`r3!;Y|DJXZ{M&m`LzXY;WW$>Wj(DSbt%=RX+?{gX5CoP9^ZY})ZSp{ zw6Aq__PK|}w*J)v410w3p$T`!;GB|^1}`UeKiL>>^gIzFM7n#ZC%5LV@clQ&Qchg0 z7<<7C-@iiP({!cCc))4;0+7|aM?@AxOlh_R&t}vz<)l8xE0%TT2^gX&*4`{#R1+9G zxTB{Gxv5^uaz{Lj?|?%bcB6C%#Y{f7H1?w~ycK6h2-qPXyi24!NS~H5iqfEE7q9Y7 zk547$^aE>Jab#7T2hI-ItLlZ?6Y|_8U^Cug6aX6|%xPdIdQE(U8vYNosZkJ64jahr zq%~Rv@#F12FUvpCqcKX$PuiKdI(ax!+5ozLt&SYnO}O zd3p+$N%C(hg?FIZgWmXs?H-cYAuIdOyyj8R@Y;iySfHvjglO*vYh%=ra#vUyi>s)7 z@o#G5s43ep+ml###9-+(MUo^ltk1uUnA{-!-s@-3g4Cp!FD%B|dA$)681>i-^f{Bx z@a`o7QtcB2`}EFiBwtCRNQF9D&$7C9rV&*c%OTG=F@a~x(P*rCW}}Ss)-gx-aIvwVAe%7^|s|C?>A1#kABhQ zP$mqRAECDaeum=ij7f8#sfB!XAYQeGCZO9${^htC#}G_OS@6SiT=34AZ#(X|!p}Iy zC6&?az>1$EWTT`|T0$ST^t+GBug^)i@|mv1WuHDcsFUpm zgU9E?$RBUxKbo~x;9mR>WYl)k4F#nc2_R$TOW1nftx^8unzhD*Pu%_?>_J)zH2<)nIcaDh&ZG2CxiwZR1Ks{O;^{PxB4^tCf?hlOC2IPY0}L=>~ByIBqlbi4coLCB?RjE%tB)DNcv+qT(~IM0z1=R__4qe=S1 z1Hi8_fX4T9m#00}4Y=iRSMKI?QyuF=Xik=IXPQIzMVXNGTe$gP%SH+nJR zN3lGxR|w*v2n&saHQ%mDj1jf*;wUw*0vlLRyysGv05!=)a+BtyYJs+=#)M%@7db(` z@wJL_J+N#bjYv%0O4K{3B7k*G%SMn<{lZc6tyF$mDWtt*?YkbE-j4@*tI6}`hz5D- zm$CY&$!1jyAgfQPvp@*`x3!u#uQhm9Inw<8b076_zi)(QdG<3olDg!7Ad6V*6trI+ zP#(7Cjxno6j(yC-m@##d%3hHm%!L@Txo{rLK6lT{bh4tWKU@f(p>Q;u3yKZq*ANEM zHsA|yI7-ek>dGZaZUtia$oe>bIRn|u)yHBCJ#Q>Vvx+!16qTsPF#@^R2-?E3E0(|* zDCbq6L{HU^%@w^{L_<5V!Sp12?d1bXh`xDQ==(|E^Vc4-8<1;Xjulkuxu+65jjxy{ zDHCpUoC5;R5u3*BuKMCx7so!>kcWe=<1G6|_eONZxLWeciQ`i(nnWwj-At@aZ}k?t zf<VT&- z)YrLdbxv+Z_d-@oGrJ6Xh88r*&9Y@I9q0$mI#8$!tvUBT2*muUh+71`?Ij0bQ#?r( z&2>uY$|f&fxUox6R?mrzv1_H2ITNTbG!t2{fI{4g@WLc2^(nji`A7|>#MJ(ML+@D^ z*N%zT2hAVG7k$@?rdLbxE9QJ(z2fwO9hVN@dh*}OEZg!&RUY*d^Lc#sffs5 z0G|!aj%H&l5r8=c2z$<8(3ymZ<5=6|?+sEVV$|whY)Ch1I$d8FsW+3{G*SY$MjGv? zBA#(NL>{zRA)}YoH0&gwp#4bMC^3n7TB(f7>)$q|Es|mAy#5yG5a~UKY1m_%QtBfN z_ZjcQDQVT?Cv>TmL0gsS2vJhg=1x6t-O$7E3aC9>jA4(hG;HTa=2glP`*HlMq1hCL zPgTbbGX_)b`D0o^daSq>l+;uzO(y;Qa=6g5`xN0m^4ChyF3bkyUK-{RQ+&J3HslEQ zWNnI-;=Y$E&geGx!|ArdVC307XsrM6Cjzh0RCjy^_6UzErgrxc)G{k19x9%YYT-yhusCtcR<>Wj7_tK zv9+wplnZGz&&tw*)5*_!*b8Tcsb_~?&?nf`js&G$?yZ_7t-qoJ+v~$Lp{EVQ}2D1r2Frfq3MnnF6L9kK|oX zb~m2Ygkityk5xRN;izhL}S6;jMStXoTB<@m)}-`l&jLp<#}2U#>SnLhKH*A z|Jg=%9^LyaQW86t>1zaKg&=dlt;@;<;Ke5S02qJmxHH(j5cwgktVfcEr~>@JcagQC z@ao`57)XQG;~^6`D;mpV?*FnG7gVJ6e9$gU78_#SvrlP za~ZK&PiZI<(g)LMxkwVK6eGsp-;!g&!;vP?oNS936`Fdk_dkzxQ&&JF@`C0W3m2g> zNkB2S1rWw>t%kAvfHjO;f;0JS;)}uU^ZZ?{!c2=hUSJ9zb%drSPP*KM6Z8c!JTqQI zL6pB(nx)qp>MJe^pZXY6ALT#p$L&XRw+p2W*{;|P40BWf_W9N1Si3K#fubw!4) zNqHUHOGw%}JHT@=#P4g2$A@)s$C`b6yrO^{rLDWHcy@|*@|fFix-l~^xjYcl@Cz1& z!CB4*KH265+cHrD3MlY_t~i`Sg2}S zDs9)@NmsYEHPu4C{$FQeERo;O7z%RKJx$?;NR_*H8WR7t)k+HgnzXEeUk^*ipH=Hw zlI=~q1PLVLLGUEW90q1NYiw4uy#Xryz*+Om> ztz$vyuv)%aOVJt@Vl32hkSSE1kE#R6s^%g9dZnMteZwy4#@ zPdJN!PTO)6-7!gQ5I_`66?a?bj^XD?`mVnARYo&-MR@tP^*HRg%}HTfR@n+!1SyV2 z?G2+39NcE@3Wepc-OW0cfkP6z5VqkUqg(1Dl%%w{DP9;JXn*pWV;DGA_r61Hp|XGC zY=v^NNN=&QNBnZ%KBQ?`0d+QXa7oKJp$bCBfcF=9?I3rq-T%N3GiqvZaXu2#levMK zJKDVJ9fGrnZ_+zSf4-uq#pkMJy#Ogf8vpRA%*?`Wr0&$#E~m>gc^x@Q^ZUqJ zI;dAeVOe?RhjBppUAEO{h&zF+97GIdXQ%7t|NGg{7;eIiex=yw(S@{{6_o_%z~!XQ zgg|WZpfnr-#0lU}35;4Kg zV-Sq4<4Q%(a&8kN{YL0j?u>TYzQ-JF#a*|2x;Y*5huPr?DF&leduxn6YeJa`Nsf^* z&GZ}oY5Pht>965Q;J*XBKYNU zz{YKuIyj=fyTPwfbm6kh5#SM{Q;ssxbqx8Z^BqxrjoEa+yPoFHKz}1t+@8uzUzVlp z1(y55g&eg*gXjPa^X7|hGb3co*;EKtu6XKcTv3B-YN~hJ?8l4$IOVN@hdNODwd=VL znYlgqI;`07J6`P(Z@4M@Hl^K>674lbD!LVq@E+f$E)o?O&DM^G3~ z<+s>K!#H2G8tH`NIx(#!^-O!@(HeG9y^Gf2FVB(dASb*Rr+!DMG_3rm^5vb|+3E=+ zybKM`!kn*Vyf{`R{M*bgeW~@~tKxA+l!Mu8X8nQC&+&c`J|BnC6w18FO%3hE^txnH z5^}@Yw6{?|LSP`^2I9)uv>9X}_)IC=CM&!$RUPz<%&4mEJwjuQ7zV_pGOhkKbj255 zZZj^C=x=p7R3~3>P|vK<;))iJ+P5N*WWgUU*X81UviJFEP=1UvF)$`#mMmElvd;xJ zc3P{?`jDr(R7F?vTWT9~Zk7t-v4cI%NMvYU2iZlkJl{_T>+o9pJVe^!XD50;j*gQT z^ch2!-SthCUT=kn^3rfg6XsPvdLqn4pL=YQKrZ~78o3-WT>-29`SEZy-7 z;F={E65z3;2E&;}TychjG2Z8p_zdP?`>lk?qbyvU*Fjb6)enK`u}Q9*T(4kz=Qj1< zsHJcJnZYsCD?Bln(A512iD~%pk<)j}+T+g$$hpDfOGQD<_8?F7n#C&@TE04tPUfH` z-m`S`RgARac*VPWQM&7fEp(d*?QtZyaC6JEuoIBOw^|0k2-fB`a&8-mBznbsg+b^M zXJaNM&lX?%!tm8Ny?Fwi&CJFv`#6L60F3x`M^fN59MdimwpjY*IK@6VxHvvv-83P2 zvBD6)^}Anm;L8I>?Za8Tv(MXUCz#zFZsDm>0hIBCM*bFPRT}ITkr12jqY6!4(I0?j z_8zyrA{6lKT)j8<9pMsj#Zt_D%i_G1DY?;YlD0O}+imS_noZ2hp_=ayPsyn}md7@3 zE$j+b#}|Rp2>0z91=*amnrgQA`$~P3{x#u-2$Szb42nzxn9QL_oXLQN>NxeY7d)I)4%>an4ED2bx|DF?KzI~DbR%`kQU&vka~zS)>=N|`V* zVby&kilikRigXGVh)a1;glT*mIIbqzA#3)*X>&ZBBIAzOV|EPrmic70a%*P7vj#%F z(^}V)mx~{CHS7b}cxl8@T0;EL2cQX2@^z<*v+<2Hc|Sl*sEyZ6Vne;tOTKoqJD-)N z!?Snsqd9s{Q(~keueVZjIA$Z~;@l6S=b5m#u&r-T+WoZiP`s0y%i4*vrVu{+jw95} zX&Ar$L6kh$6<3A1u&`pDH2s{F^l|RtOE?kdzr3EAx#R^bc}V1#?>`|h^tz?XsXw%> zGD7TENAfN67Z-DTw&Jb?MgKvT6feXo3~QO%Zjt2P=%5$y+#k$j?9 z5ho;grHV#^^pe)HBPEB1qYV9UB76HlBP^X3-oT zpdaOBYgjrl#e9ywPzdu1z9OPoPZnpHjR&Y|mfrF^SgfyYdrS<8^)bvUYx3gOIz^Jl51BPTdGsWpr%F)M4wI6`qZ5d3cfJWMBF|ud%+#XJs>4?v*Yk0RCr01~ zvnr5&+^6*72`;YX1`}`JoSD(0RZZOIcdpGkh^tX#`rP#9oaAjmt<_W~j~Hp07hiW= z&OV#`4oD!Dfoj=$%pdCpMFGLpJEhcR6w#&|_VZ=o!q&U4ZJw&>#tRZ8H9J>>I6wu^ zYCXH@;x|Ksd|7x)Ui2>{NpQM$sePrgGB|(08B0gO{GXGy_&lqXCyhHCno@~ZHj~wf zm?x)_dD(!&YDov|)^=bw+N&R68{&h=NYAv`q>@WF{8K_{q^6595HJ@<3+!GaU(w`f z7p#sY7S^BM{4}tbT`swibjRs9vrk|Ych+j-aXE>u_M49r^rSruNcgl;Q|`Bo!}Bwj z)|V=9f#_(UG{n0O>2 zAEo4cDLgCg%3mN%;Ph9pVh#C9oh{?Vk81$d*v)q&1()(}THC}UByWKbg+n-Z4K0sP zucF`d#fzc=>I+OQ@QNHC}H>tddqL;wUs(N&5F-2Wgegv z&aQ{28nlZlPar-Ul9m`|^bXX7oX-hWECb`7HHWh(y7}66<$UszwB$_8o(-wJsl;X; zQ4)*f16kRtbkx{B6cXkxycRM?zU(Sm1%9+!B=jh@)_=YW&Du(PVLa=0NQK-;MABx_ z1ugZc;XiktK_kJVm~+p3
?&?GbZAq`gW<6F||JNGQdu}=Jq_qEmafD1aLufwTtfCoY#3cB0)qAuf7Fs+R59=P)IQy6pvJij`QP9SJJPNk~0ox3!>hlzg~Vck@hs z=%ArMI+>%;&-y&9IPI8(<5&nk_r}wP>;e`XE#sM$cNOBbi+tVdp*e5jVJ6zsb{r9& z*#ZcNmuW$%(g@27W5^`MdZxn*M-)1849itt@bm8$U@;O6Vord{S z6wJG1Nw*d@7#GlSnNglWNQZZ;p=oYY{l>HQ#ioni0$25BdD? zm;V#pT*a?%7VsA1`c&PRzereo-EwKuqDsM&;HLN9whUpW4u5SN(7?Vh!>X$|d08-L zxmE|gtc6i*_;u(*tPJEo2Oz}8Y#%3NG_3G|@B|jmzH`Gt#->*^8=JMd6rd%&0`*J> z-#V8je$A`}s7>xac!|+mo_zp}D;x2#z3#}l^Qtt`tlkhVD=HeH4Y~xEhZGnY%QKXo ztM_rcNttoMre-g+@^z^+(~5D*1g+Ln|0wQ8n{b|TJ)IufYq$GQ67>T4ZJAY7#~d;g zt2vr$5H&X<;~#uWL!XrVFy{ zwbt8@hD^*v3Zll+@*!(mIfi-6#*|VPM@4_%fUq_@8_5?^SN77%d0riX87`yUY2=)W zl3cou)55{8F36w*$j%X-XN$I`do2gvZnYkOs(t0g?Bel-LU1I6qxa!_VL!4xVzY{d zed!@fX=CGl($h@LGOlk9LV|{7;q!7${cfkMZ`(X)WF(wJ{?Zg)6~f@Man;Iu$Q-9N zA^Dh)73AE6=fp&AYDMOKP5Hjl#&g|V!Q|d6ecJ}~me725%~rBO;hflS?Lxogf0>S; zk;WYKi44n)8XrVomyPzlw%wP5TsZD#MJj}zaN;%d9s3n`(ycaqWIHAqLMGF0Sb507 zme|GOYHisfj#SO0D3K}1O~t)OEt1Jy+}20qM`J`E*C)|uPXkar2+bB8KS*zJJV^YW zz0Sii%kDFzG{G36%Z`Rx9e(AT`-swGEIthT`Bc0mREphPZ_pAd%jAVo*YzKr-4#?C zBQBvZEaD2bblA{dIMLwG(Cx5V3wbB5(N3p~h4cIT~F&+yC}dU736isUo*KemSEVUsrDGY`)PP)sxWkp!@c^bHV#?p%s!G zlrOHF$jp%)+Lw}G^!+h)6v}PMA^nMUn2J?y5f^Slc`wBFq(S`S3Ld9?D4^C^CpnoX zF6~*3*qO@C-LWNGwU6c&%kP>rXS8GDkE$m7S#VMh=gft_`#8S#_nze)B+Tc(SlyJg za&F~h&*%SvY&tTq>AL|@^Rm!H4BT;R@%k6TWa<>Pms4K;?k`vbb>ZN+WMSp^c-q<- z3eyuD^vR)|iNn1iRm~pGTbh{D)XH=?k16B1FrNFBQh(*Gp3rD|LX{H1dMcaQot~rb zHhN!jo|As}W&?MH@5CL3y3MR%msZfEv4Z8HF@7!ylh+Vju0?NNicq^xRA^<4xq$L} z@<6@K#W}0$ES&Kw7v_hM6w)Vze1YuHai~$fnP^(i75N?N6+HCjtP0zp;)gvl^tt|~ zM$a`e(LWwnAgAxXk&LDhV&|%#o3BnKUC>G z#vA+qpX-4xQHYD#0LZpa0d3lzqcfo!_h4%Fcr57(IFTAk7vDuPbl4Alq!F ze|)aB@?-S6p*i+0|BQ1rbAK#`*omxCs4K0nuJGK2EEBsHqs82rLln*6|2ZYdqb8}W z!vXTBq=z3m)b&ZJN!<+0X=mF);C5#kJF2t8%Nk-4>0PD3%~Xu@7hoc!6%DL5r4qTX z0}HSL+wrcfEoJ-V(ZILe8lW+j3G~BSqH#CneNp5bbzxKMe zXJ?v;1bpL=l(s@Vw>+WA2ql|~t2ot+vnqmT?vlJ1*5$HYOHf;t1rJ_Y zLJuOvx|}^8hSyrYU|3``IJI6U%4nPAdN{M1gjaIF8M2E~>eZGfK66tF_g1mK;Z8OH zxsPnus@1oXvvZGi-gLl`=AXu?7z@RrQf#^5zSdL>I;W7RwM_Ge8iL99FuNi|q%wt; z2=ye8Z4LSukWnbNQMC^t$=R@??${t3#PGyLN}n-~h;of*drPbOjN4@ws-S+rZ&2Kz zots=x2ozDTvvD<7qg`f|)T1t2iF5ki-jws%oJl!p&i>HeKV#&s&M_Z$gEBckZRcHF zdjFduux$SpN^EbN=$~K)>xkMdJc!Mt&zm5C4}*bOiEj)apaZCUn;@QtoDqc$#xg2R z9cjsib<=P1r(GT&9I?T!q4 za^)8Wvac*;rdS};z<1GwsmqXs54b|SIln-~h)%(H6IFj?K-dfCW_IExKvHZBBzj;T zx{7A$sHew#v879Ax)40C_$fRrpXnppaYG=&{`F*`a*#{(%_k5SHTyz$VmeG7l?K0~ zX+-i*>x_9Z_iu`%SpNdx65CN4vuyh&sW1&Ln}fbzL|Fw443X)it7eITSUbi{_15og z`3{a{fKmZY!Dk_h6HYKMsTsH;>Ladv#RRw)sFE{VJy$TP2;kUmx*Mgn3w z0xI((1H}KDIWqy+Rak+25}lNQN& zx%RTiW?<~8(9h?uD~kMg^`Wgp;fVxtPZ8y|$rv04PLCZ*HN38-ny9Y`Q+tf=#TVM3 zJFfZ{k|H-IY}pe7FO~-}oP9lV2kpclnSYfH5!dICd;i6)`~xM(YRhjiFs>LTMx>A`%NpvH_p~2Kt(wc_Z8a#Zv3|VtP_^IS z^C?E8;}n(85EvhoY{qYFstd1#BBJ5H2I!!sN#T?u`12RbzOEGWZDV~jzy6l{Z`9<2 z29T-W0Qqr~>mh!wf5C3mct{0JNsO$%863quV8vIQ;jMPx-;v$a5b^x!RG2jI4?Nz04BDK2bu#vFNjT_6{k3PGMD*Za(@vd|^!>J;zI*yny-ZO- zROhxRPl`jLnvZ3%>*H1P^;?Xpd4O2_0 zp952W7xqOLjGQOvK*uFrgP|4ac(5XO^E>7y>2q@|&WW7{9ptYuDzCn?G02I;!(gNB znNV%Kte$Y6&=E^Uh&XgIuE?p7tZF$lE=7!F^y*Q}Y;WC*N;h77Yd`YPw%#xxzR!Gn zwA7GAPGXDjhcq8284e!7LPCUWPi3?X)^@Xl356%|8ZrH*Lwggl{nA#!S&uarF8;$S zzulg;x3Co2`D}SCfwy6Ce}c1YSt?#0?|hL@jA&ru;kd$!vd#$;X|rlBpGoHK#r8+D z>O&w4;;I6N`dZ?_vbA4y_KyXJ^SaK_@F#0sV@#7AgbVLJ=050ETKFb5Nmd1?@^J6} z2YQ3ZS-CXZm2*?a8=gq$E?@EAkT^!j7`=GC+ z@~?t-DNTjFMZ+8;-fcUIE~B|CqRM9Aom+A5v}y=Sqr6i!_T7qwZ;>gkp6p9`6l-D6 zB7M$3a@R>Hvn06rBWGxj)ZlB;tTy%`ZcH10CO*`)U3i)Co81B?$pG)6i(V z;W-4Ivu>0EGw?gi)|Gwd7!yF<{3;A}jfy@r_uKyysQ_00!~hvHbPpa%CZURoLJDR| zy9~jQd1eJ=46Jd2tVjjMLVMt+DT z3-wBsEB;nM48SSVsO~9puGmc&2^V!M)olC{a.exports=JSON.parse('{"label":"astar","permalink":"/algorithms/tags/astar","allTagsPath":"/algorithms/tags","count":1,"items":[{"id":"paths/2024-01-01-bf-to-astar/astar","title":"A* algorithm","description":"Moving from Dijkstra\'s algorithm into the A* algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar/astar"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/1535ede8.102142f5.js b/assets/js/1535ede8.102142f5.js new file mode 100644 index 0000000..94b5cab --- /dev/null +++ b/assets/js/1535ede8.102142f5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[5376],{44969:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(85893),i=t(11151);const r={id:"seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n"},o=void 0,a={id:"bonuses/seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n",source:"@site/c/bonuses/10.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-10",permalink:"/c/bonuses/seminar-10",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/10.md",tags:[],version:"current",lastUpdatedAt:1704291155,formattedLastUpdatedAt:"Jan 3, 2024",frontMatter:{id:"seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n"},sidebar:"autogeneratedBar",previous:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"},next:{title:"Practice Exams",permalink:"/c/category/practice-exams"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Project",id:"project",level:2},{value:"Summary of the gameplay",id:"summary-of-the-gameplay",level:3},{value:"Suggested workflow",id:"suggested-workflow",level:2},{value:"Tasks",id:"tasks",level:2},{value:"Dictionary",id:"dictionary",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/10.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you are given almost finished project - The Hangman Game. Your\ntask is to try the game, in case you find any bugs point them out and cover as\nmuch of the game as possible with tests."}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2 K\u20a1."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Item"}),(0,s.jsx)(n.th,{children:"Bonus"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Fixing bugs from failing tests"}),(0,s.jsx)(n.td,{children:"0.25"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"word_guessed"})}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Hidden bug"}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Extending tests, undetectable bugs or evil bug"}),(0,s.jsx)(n.td,{children:"0.37"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Refactor"}),(0,s.jsx)(n.td,{children:"0.38"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"project",children:"Project"}),"\n",(0,s.jsxs)(n.p,{children:["Project consists of 2 source files - ",(0,s.jsx)(n.code,{children:"hangman.c"})," and ",(0,s.jsx)(n.code,{children:"main.c"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main.c"})," is quite short and concise, there is nothing for you to do."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"hangman.c"})," contains implementation of the game. In case you feel lost, consult\nthe documentation in ",(0,s.jsx)(n.code,{children:"hangman.h"})," that represents an interface that can be used\nfor implementing the game."]}),"\n",(0,s.jsxs)(n.p,{children:["Apart from those sources this project is a bit more complicated. ",(0,s.jsx)(n.em,{children:"Game loop"})," is\nrealised via single encapsulated function that complicates the testing. Because\nof that, there are 2 kinds of tests:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Unit tests"})," - that are present in ",(0,s.jsx)(n.code,{children:"test_hangman.c"})," and can be run via:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-unit\n"})}),"\n",(0,s.jsx)(n.p,{children:"They cover majorly functions that can be tested easily via testing framework."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Functional tests"})," - same as in ",(0,s.jsx)(n.code,{children:"seminar-08"})," and are focused on testing the\nprogram as whole. Basic smoke test is already included in ",(0,s.jsx)(n.code,{children:"usage"})," test case."]}),"\n",(0,s.jsx)(n.p,{children:"They can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-functional\n"})}),"\n",(0,s.jsxs)(n.p,{children:["When testing ",(0,s.jsx)(n.code,{children:"hangman"})," function (the game loop), it is suggested to create\nfunctional tests."]}),"\n",(0,s.jsx)(n.p,{children:"When submitting the files for review, please leave out functional tests that\nwere given as a part of the assignment, so that it is easier to navigate, I\nwill drag the common files myself. :)"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Whole test suite can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check\n"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"summary-of-the-gameplay",children:"Summary of the gameplay"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Secret word gets chosen from the file that's path is given as an argument."}),"\n",(0,s.jsx)(n.li,{children:"You get 8 guesses."}),"\n",(0,s.jsx)(n.li,{children:"Invalid characters don't count."}),"\n",(0,s.jsx)(n.li,{children:"Already guessed characters don't count, even if not included in the secret."}),"\n",(0,s.jsxs)(n.li,{children:["You can guess the whole word at once","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"If you get it right, you won, game ends."}),"\n",(0,s.jsx)(n.li,{children:"If you don't get it right, you get to see the secret, game ends."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"In case of end of input, game finishes via force."}),"\n",(0,s.jsx)(n.li,{children:"In case of invalid input, no guesses are subtracted, game carries on."}),"\n",(0,s.jsx)(n.li,{children:"Letters and words are not case sensitive."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"suggested-workflow",children:"Suggested workflow"}),"\n",(0,s.jsxs)(n.p,{children:["As we have talked about on the seminar, I suggest you to follow\n",(0,s.jsx)(n.em,{children:"Test-Driven Development"}),"\nin this case."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"TDD workflow",src:t(27420).Z+"",width:"2814",height:"1652"})}),"\n",(0,s.jsx)(n.p,{children:"In our current scenario we are already in the stage of refactoring and fixing the\nbugs. Therefore try to follow this succession of steps:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Try to reproduce the bug."}),"\n",(0,s.jsx)(n.li,{children:"Create a test that proves the presence of the bug."}),"\n",(0,s.jsx)(n.li,{children:"Fix the bug."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are submitting the bonus via GitLab, it is helpful to commit tests\nbefore commiting the fixes, so that it is apparent that the bug is manifested.\nExample of ",(0,s.jsx)(n.code,{children:"git log"})," (notice that the first line represents latest commit):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"feat: Implement fizz_buzzer\ntest: Add tests for fizz_buzzer\nfix: Fix NULL-check in print_name\ntest: Add test for NULL in print_name\n"})}),"\n",(0,s.jsx)(n.h2,{id:"tasks",children:"Tasks"}),"\n",(0,s.jsx)(n.p,{children:"As to your tasks, there are multiple things wrong in this project."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'There are 2 "bugs" that cannot be detected via tests, i.e. they are not bugs\nthat affect functionality of the game.'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["There is one evil bug in ",(0,s.jsx)(n.code,{children:"get_word"}),". It is not required to be fixed ;) Assign\nit the lowest priority."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"There are some tests failing. Please try to figure it out, so you have green\ntests for the rest :)"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["We have gotten a bug report for ",(0,s.jsx)(n.code,{children:"word_guessed"}),", all we got is"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["doesn't work when there are too many ",(0,s.jsx)(n.code,{children:"a"}),"s"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Please try to replicate the bug and create a tests, so we don't get any\nregression later on."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"One hidden bug :) Closely non-specified, we cannot reproduce it and we were\ndrunk while playing the game, so we don't remember a thing. :/"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Try to cover as much code via the tests as possible. We are not going to look\nat the metrics, but DRY is violated a lot, so as a last task try to remove as\nmuch of the duplicit code as possible."}),"\n",(0,s.jsx)(n.p,{children:"Tests should help you a lot in case there are some regressions."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsxs)(n.p,{children:["In case you wonder why there are always 3 same words in the file with words, it\nis because of the ",(0,s.jsx)(n.code,{children:"get_word"})," bug. It is not a bug that can be easily fixed, so\nit is a not requirement at all and you can still get all points for the bonus ;)"]}),"\n",(0,s.jsx)(n.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Functional_testing",children:"Functional tests"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Smoke_testing_%28software%29",children:"Smoke test"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Don%27t_repeat_yourself",children:"DRY"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},27420:(e,n,t)=>{t.d(n,{Z:()=>s});const s=t.p+"assets/images/tdd_lifecycle-327ad9ee0ed8318ed11e19a28e02b2cc.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>o});var s=t(67294);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1535ede8.aa3b4147.js b/assets/js/1535ede8.aa3b4147.js deleted file mode 100644 index 253b5de..0000000 --- a/assets/js/1535ede8.aa3b4147.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[5376],{44969:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(85893),i=t(11151);const r={id:"seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n"},o=void 0,a={id:"bonuses/seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n",source:"@site/c/bonuses/10.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-10",permalink:"/c/bonuses/seminar-10",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/10.md",tags:[],version:"current",lastUpdatedAt:1703979877,formattedLastUpdatedAt:"Dec 30, 2023",frontMatter:{id:"seminar-10",title:"10th seminar",description:"Finding bugs in a hangman.\n"},sidebar:"autogeneratedBar",previous:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"},next:{title:"Practice Exams",permalink:"/c/category/practice-exams"}},c={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Project",id:"project",level:2},{value:"Summary of the gameplay",id:"summary-of-the-gameplay",level:3},{value:"Suggested workflow",id:"suggested-workflow",level:2},{value:"Tasks",id:"tasks",level:2},{value:"Dictionary",id:"dictionary",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/10.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you are given almost finished project - The Hangman Game. Your\ntask is to try the game, in case you find any bugs point them out and cover as\nmuch of the game as possible with tests."}),"\n",(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2 K\u20a1."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Item"}),(0,s.jsx)(n.th,{children:"Bonus"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Fixing bugs from failing tests"}),(0,s.jsx)(n.td,{children:"0.25"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"word_guessed"})}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Hidden bug"}),(0,s.jsx)(n.td,{children:"0.50"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Extending tests, undetectable bugs or evil bug"}),(0,s.jsx)(n.td,{children:"0.37"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Refactor"}),(0,s.jsx)(n.td,{children:"0.38"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"project",children:"Project"}),"\n",(0,s.jsxs)(n.p,{children:["Project consists of 2 source files - ",(0,s.jsx)(n.code,{children:"hangman.c"})," and ",(0,s.jsx)(n.code,{children:"main.c"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main.c"})," is quite short and concise, there is nothing for you to do."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"hangman.c"})," contains implementation of the game. In case you feel lost, consult\nthe documentation in ",(0,s.jsx)(n.code,{children:"hangman.h"})," that represents an interface that can be used\nfor implementing the game."]}),"\n",(0,s.jsxs)(n.p,{children:["Apart from those sources this project is a bit more complicated. ",(0,s.jsx)(n.em,{children:"Game loop"})," is\nrealised via single encapsulated function that complicates the testing. Because\nof that, there are 2 kinds of tests:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Unit tests"})," - that are present in ",(0,s.jsx)(n.code,{children:"test_hangman.c"})," and can be run via:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-unit\n"})}),"\n",(0,s.jsx)(n.p,{children:"They cover majorly functions that can be tested easily via testing framework."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Functional tests"})," - same as in ",(0,s.jsx)(n.code,{children:"seminar-08"})," and are focused on testing the\nprogram as whole. Basic smoke test is already included in ",(0,s.jsx)(n.code,{children:"usage"})," test case."]}),"\n",(0,s.jsx)(n.p,{children:"They can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check-functional\n"})}),"\n",(0,s.jsxs)(n.p,{children:["When testing ",(0,s.jsx)(n.code,{children:"hangman"})," function (the game loop), it is suggested to create\nfunctional tests."]}),"\n",(0,s.jsx)(n.p,{children:"When submitting the files for review, please leave out functional tests that\nwere given as a part of the assignment, so that it is easier to navigate, I\nwill drag the common files myself. :)"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Whole test suite can be run via:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$ make check\n"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"summary-of-the-gameplay",children:"Summary of the gameplay"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Secret word gets chosen from the file that's path is given as an argument."}),"\n",(0,s.jsx)(n.li,{children:"You get 8 guesses."}),"\n",(0,s.jsx)(n.li,{children:"Invalid characters don't count."}),"\n",(0,s.jsx)(n.li,{children:"Already guessed characters don't count, even if not included in the secret."}),"\n",(0,s.jsxs)(n.li,{children:["You can guess the whole word at once","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"If you get it right, you won, game ends."}),"\n",(0,s.jsx)(n.li,{children:"If you don't get it right, you get to see the secret, game ends."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"In case of end of input, game finishes via force."}),"\n",(0,s.jsx)(n.li,{children:"In case of invalid input, no guesses are subtracted, game carries on."}),"\n",(0,s.jsx)(n.li,{children:"Letters and words are not case sensitive."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"suggested-workflow",children:"Suggested workflow"}),"\n",(0,s.jsxs)(n.p,{children:["As we have talked about on the seminar, I suggest you to follow\n",(0,s.jsx)(n.em,{children:"Test-Driven Development"}),"\nin this case."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"TDD workflow",src:t(27420).Z+"",width:"2814",height:"1652"})}),"\n",(0,s.jsx)(n.p,{children:"In our current scenario we are already in the stage of refactoring and fixing the\nbugs. Therefore try to follow this succession of steps:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Try to reproduce the bug."}),"\n",(0,s.jsx)(n.li,{children:"Create a test that proves the presence of the bug."}),"\n",(0,s.jsx)(n.li,{children:"Fix the bug."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are submitting the bonus via GitLab, it is helpful to commit tests\nbefore commiting the fixes, so that it is apparent that the bug is manifested.\nExample of ",(0,s.jsx)(n.code,{children:"git log"})," (notice that the first line represents latest commit):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"feat: Implement fizz_buzzer\ntest: Add tests for fizz_buzzer\nfix: Fix NULL-check in print_name\ntest: Add test for NULL in print_name\n"})}),"\n",(0,s.jsx)(n.h2,{id:"tasks",children:"Tasks"}),"\n",(0,s.jsx)(n.p,{children:"As to your tasks, there are multiple things wrong in this project."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'There are 2 "bugs" that cannot be detected via tests, i.e. they are not bugs\nthat affect functionality of the game.'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["There is one evil bug in ",(0,s.jsx)(n.code,{children:"get_word"}),". It is not required to be fixed ;) Assign\nit the lowest priority."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"There are some tests failing. Please try to figure it out, so you have green\ntests for the rest :)"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["We have gotten a bug report for ",(0,s.jsx)(n.code,{children:"word_guessed"}),", all we got is"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["doesn't work when there are too many ",(0,s.jsx)(n.code,{children:"a"}),"s"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Please try to replicate the bug and create a tests, so we don't get any\nregression later on."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"One hidden bug :) Closely non-specified, we cannot reproduce it and we were\ndrunk while playing the game, so we don't remember a thing. :/"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Try to cover as much code via the tests as possible. We are not going to look\nat the metrics, but DRY is violated a lot, so as a last task try to remove as\nmuch of the duplicit code as possible."}),"\n",(0,s.jsx)(n.p,{children:"Tests should help you a lot in case there are some regressions."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsxs)(n.p,{children:["In case you wonder why there are always 3 same words in the file with words, it\nis because of the ",(0,s.jsx)(n.code,{children:"get_word"})," bug. It is not a bug that can be easily fixed, so\nit is a not requirement at all and you can still get all points for the bonus ;)"]}),"\n",(0,s.jsx)(n.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Functional_testing",children:"Functional tests"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Smoke_testing_%28software%29",children:"Smoke test"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Don%27t_repeat_yourself",children:"DRY"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},27420:(e,n,t)=>{t.d(n,{Z:()=>s});const s=t.p+"assets/images/tdd_lifecycle-327ad9ee0ed8318ed11e19a28e02b2cc.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>o});var s=t(67294);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2af5d0a7.928c2eb4.js b/assets/js/2af5d0a7.928c2eb4.js new file mode 100644 index 0000000..e52b9f8 --- /dev/null +++ b/assets/js/2af5d0a7.928c2eb4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[3979],{53703:t=>{t.exports=JSON.parse('{"label":"a star","permalink":"/algorithms/tags/a-star","allTagsPath":"/algorithms/tags","count":1,"items":[{"id":"paths/2024-01-01-bf-to-astar/index","title":"From BF to A*","description":"Figuring out shortest-path problem from the BF to the A* algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/2fcf0558.14a64e69.js b/assets/js/2fcf0558.14a64e69.js deleted file mode 100644 index 0e1b478..0000000 --- a/assets/js/2fcf0558.14a64e69.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[4638],{69470:e=>{e.exports=JSON.parse('{"title":"Hash Tables","description":"Materials related to hash tables.\\n","slug":"/category/hash-tables","permalink":"/algorithms/category/hash-tables","navigation":{"previous":{"title":"Distance boundaries from BFS tree on undirected graphs","permalink":"/algorithms/graphs/bfs-tree"},"next":{"title":"Breaking Hash Table","permalink":"/algorithms/hash-tables/breaking"}}}')}}]); \ No newline at end of file diff --git a/assets/js/2fcf0558.a6f753b6.js b/assets/js/2fcf0558.a6f753b6.js new file mode 100644 index 0000000..a0ab6bc --- /dev/null +++ b/assets/js/2fcf0558.a6f753b6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[4638],{69470:a=>{a.exports=JSON.parse('{"title":"Hash Tables","description":"Materials related to hash tables.\\n","slug":"/category/hash-tables","permalink":"/algorithms/category/hash-tables","navigation":{"previous":{"title":"A* algorithm","permalink":"/algorithms/paths/bf-to-astar/astar"},"next":{"title":"Breaking Hash Table","permalink":"/algorithms/hash-tables/breaking"}}}')}}]); \ No newline at end of file diff --git a/assets/js/354a7b72.257f6430.js b/assets/js/354a7b72.257f6430.js deleted file mode 100644 index cdd441d..0000000 --- a/assets/js/354a7b72.257f6430.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[9414],{46617:(I,i,l)=>{l.r(i),l.d(i,{assets:()=>j,contentTitle:()=>g,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>Z});var s=l(85893),m=l(11151);const a={id:"bfs-tree",title:"Distance boundaries from BFS tree on undirected graphs",description:"Short explanation of distance boundaries deduced from a BFS tree.\n",tags:["graphs","bfs"],last_update:{date:new Date("2022-04-30T00:00:00.000Z")}},g=void 0,c={id:"graphs/bfs-tree",title:"Distance boundaries from BFS tree on undirected graphs",description:"Short explanation of distance boundaries deduced from a BFS tree.\n",source:"@site/algorithms/10-graphs/2022-04-30-bfs-tree.md",sourceDirName:"10-graphs",slug:"/graphs/bfs-tree",permalink:"/algorithms/graphs/bfs-tree",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/10-graphs/2022-04-30-bfs-tree.md",tags:[{label:"graphs",permalink:"/algorithms/tags/graphs"},{label:"bfs",permalink:"/algorithms/tags/bfs"}],version:"current",lastUpdatedAt:1651276800,formattedLastUpdatedAt:"Apr 30, 2022",frontMatter:{id:"bfs-tree",title:"Distance boundaries from BFS tree on undirected graphs",description:"Short explanation of distance boundaries deduced from a BFS tree.\n",tags:["graphs","bfs"],last_update:{date:"2022-04-30T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"Iterative algorithms via iterators",permalink:"/algorithms/graphs/iterative-and-iterators"},next:{title:"Hash Tables",permalink:"/algorithms/category/hash-tables"}},j={},Z=[{value:"Introduction",id:"introduction",level:2},{value:"Lower bound",id:"lower-bound",level:2},{value:"Proof by contradiction",id:"proof-by-contradiction",level:2}];function n(I){const i={admonition:"admonition",annotation:"annotation",em:"em",h2:"h2",img:"img",li:"li",math:"math",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",p:"p",semantics:"semantics",span:"span",strong:"strong",ul:"ul",...(0,m.a)(),...I.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(i.p,{children:["As we have talked on the seminar, if we construct from some vertex ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"u"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"u"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.4306em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"u"})]})})]})," BFS tree on an undirected graph, we can obtain:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["lower bound of length of the shortest path between 2 vertices from the ",(0,s.jsx)(i.em,{children:"height difference"})]}),"\n",(0,s.jsxs)(i.li,{children:["upper bound of length of the shortest path between 2 vertices from the ",(0,s.jsx)(i.em,{children:"path through the root"})]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"lower-bound",children:"Lower bound"}),"\n",(0,s.jsx)(i.p,{children:"Consider the following graph:"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.img,{src:l(79968).Z+"#gh-light-mode-only",width:"252",height:"539"}),"\n",(0,s.jsx)(i.img,{src:l(21949).Z+"#gh-dark-mode-only",width:"252",height:"539"})]}),"\n",(0,s.jsxs)(i.p,{children:["We run BFS from the vertex ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"a"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"a"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.4306em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"a"})]})})]})," and obtain the following BFS tree:"]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.img,{src:l(62843).Z+"#gh-light-mode-only",width:"275",height:"347"}),"\n",(0,s.jsx)(i.img,{src:l(43770).Z+"#gh-dark-mode-only",width:"275",height:"347"})]}),"\n",(0,s.jsxs)(i.p,{children:["Let's consider pair of vertices ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"e"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"e"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.4306em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"e"})]})})]})," and ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"h"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"h"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6944em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"h"})]})})]}),". For them we can safely lay, from the BFS tree, following properties:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["lower bound: ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"2"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"2"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"2"})]})})]})]}),"\n",(0,s.jsxs)(i.li,{children:["upper bound: ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"4"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"4"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"4"})]})})]})]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["By having a look at the graph we started from, we can see that we have a path \u2039",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsxs)(i.mrow,{children:[(0,s.jsx)(i.mi,{children:"e"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"j"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"h"})]}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"e, j, h"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"e"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",style:{marginRight:"0.05724em"},children:"j"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"h"})]})})]}),"\u203a that has a length 2. Apart from that we can also notice there is another path from ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"e"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"e"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.4306em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"e"})]})})]})," to ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"h"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"h"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6944em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"h"})]})})]})," and that is \u2039",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsxs)(i.mrow,{children:[(0,s.jsx)(i.mi,{children:"e"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"a"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"c"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"i"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"d"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"h"})]}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"e, a, c, i, d, h"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"e"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"a"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"c"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"i"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"d"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"h"})]})})]}),"\u203a. And that path has a length of ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"5"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"5"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"5"})]})})]}),". Doesn't this break our statements at the beginning? (",(0,s.jsx)(i.em,{children:"I'm leaving that as an exercise ;)"}),")"]}),"\n",(0,s.jsx)(i.h2,{id:"proof-by-contradiction",children:"Proof by contradiction"}),"\n",(0,s.jsxs)(i.p,{children:["Let's keep the same graph, but break the lower bound, i.e. I have gotten a lower bound ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"2"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"2"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"2"})]})})]}),", but \u201cthere must be a shorter path\u201d! ;)"]}),"\n",(0,s.jsxs)(i.p,{children:["Now the more important question, is there a shorter path in that graph? The answer is no, there's no shorter path than the one with length ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"2"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"2"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"2"})]})})]}),". So what can we do about it? We'll add an edge to have a shorter path. Now we have gotten a lower bound of ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"2"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"2"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"2"})]})})]}),", which means the only shorter path we can construct has ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"1"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"1"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"1"})]})})]})," edge and that is \u2039",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsxs)(i.mrow,{children:[(0,s.jsx)(i.mi,{children:"e"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"h"})]}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"e, h"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"e"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"h"})]})})]}),"\u203a (no intermediary vertices). Let's do this!"]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.img,{src:l(40050).Z+"#gh-light-mode-only",width:"252",height:"539"}),"\n",(0,s.jsx)(i.img,{src:l(7619).Z+"#gh-dark-mode-only",width:"252",height:"539"})]}),"\n",(0,s.jsx)(i.p,{children:"Okay, so we have a graph that breaks the rule we have laid. However, we need to run BFS to obtain the new BFS tree, since we have changed the graph."}),"\n",(0,s.jsxs)(i.admonition,{type:"tip",children:[(0,s.jsxs)(i.p,{children:["Do we need to run BFS after ",(0,s.jsx)(i.strong,{children:"every"})," change?"]}),(0,s.jsx)(i.p,{children:"\xadI am leaving that as an exercise ;)"})]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.img,{src:l(9248).Z+"#gh-light-mode-only",width:"371",height:"347"}),"\n",(0,s.jsx)(i.img,{src:l(31350).Z+"#gh-dark-mode-only",width:"371",height:"347"})]}),"\n",(0,s.jsx)(i.p,{children:"Oops, we have gotten a new BFS tree, that has a height difference of 1."}),"\n",(0,s.jsx)(i.admonition,{type:"tip",children:(0,s.jsx)(i.p,{children:"Try to think about a way this can be generalized for shortening of minimal length 3 to minimal length 2 ;)"})})]})}function d(I={}){const{wrapper:i}={...(0,m.a)(),...I.components};return i?(0,s.jsx)(i,{...I,children:(0,s.jsx)(n,{...I})}):n(I)}},21949:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMTg5cHQiIGhlaWdodD0iNDA0cHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMTg5LjAwIDQwNC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCA0MDApIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0iIzFiMWIxZCIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgcG9pbnRzPSItNCw0IC00LC00MDAgMTg1LC00MDAgMTg1LDQgLTQsNCIvPgo8IS0tIGEgLS0+CjxnIGlkPSJub2RlMSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMjYiIGN5PSItMzc4IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxMjYiIHk9Ii0zNzQuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9Ijk5IiBjeT0iLTMwNiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0zMDIuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5jPC90ZXh0Pgo8L2c+CjwhLS0gYSYjNDU7JiM0NTtjIC0tPgo8ZyBpZD0iZWRnZTEiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmEmIzQ1OyYjNDU7YzwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xMTkuNiwtMzYwLjQxQzExNS4zNiwtMzQ5LjQxIDEwOS44MSwtMzM1LjAzIDEwNS41NCwtMzIzLjk2Ii8+CjwvZz4KPCEtLSBlIC0tPgo8ZyBpZD0ibm9kZTMiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmU8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTU0IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTU0IiB5PSItMTU4LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ZTwvdGV4dD4KPC9nPgo8IS0tIGEmIzQ1OyYjNDU7ZSAtLT4KPGcgaWQ9ImVkZ2UyIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmIzQ1O2U8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTI5LjE0LC0zNTkuODVDMTMwLjk4LC0zNDkuNDkgMTMzLjI3LC0zMzYuMDEgMTM1LC0zMjQgMTQyLjQ5LC0yNzEuOSAxNDkuMTgsLTIxMC4wMSAxNTIuMjQsLTE4MC40MyIvPgo8L2c+CjwhLS0gaSAtLT4KPGcgaWQ9Im5vZGU0IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5pPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9IjI3IiBjeT0iLTIzNCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjciIHk9Ii0yMzAuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtpIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik04NC40MywtMjkwLjgzQzcyLjAyLC0yNzguNzcgNTQuMjcsLTI2MS41MSA0MS44LC0yNDkuMzgiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSI5OSIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyYjNDU7YiAtLT4KPGcgaWQ9ImVkZ2U0IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5jJiM0NTsmIzQ1O2I8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNOTksLTI4Ny43Qzk5LC0yNzYuODUgOTksLTI2Mi45MiA5OSwtMjUyLjEiLz4KPC9nPgo8IS0tIGogLS0+CjxnIGlkPSJub2RlNiIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ajwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMjYiIGN5PSItMTgiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjEyNiIgeT0iLTE0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ajwvdGV4dD4KPC9nPgo8IS0tIGUmIzQ1OyYjNDU7aiAtLT4KPGcgaWQ9ImVkZ2U1IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5lJiM0NTsmIzQ1O2o8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTUwLjYyLC0xNDMuODdDMTQ1LjI0LC0xMTYuNTggMTM0Ljc4LC02My41MiAxMjkuMzksLTM2LjE5Ii8+CjwvZz4KPCEtLSBkIC0tPgo8ZyBpZD0ibm9kZTciIGNsYXNzPSJub2RlIj4KPHRpdGxlPmQ8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMzYiIGN5PSItMTYyIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIzNiIgeT0iLTE1OC4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmQ8L3RleHQ+CjwvZz4KPCEtLSBpJiM0NTsmIzQ1O2QgLS0+CjxnIGlkPSJlZGdlNiIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aSYjNDU7JiM0NTtkPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTI5LjE4LC0yMTYuMDVDMzAuNTcsLTIwNS4yMSAzMi4zOCwtMTkxLjE4IDMzLjc4LC0xODAuMjgiLz4KPC9nPgo8IS0tIGggLS0+CjxnIGlkPSJub2RlOCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSI5OSIgY3k9Ii05MCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmg8L3RleHQ+CjwvZz4KPCEtLSBiJiM0NTsmIzQ1O2ggLS0+CjxnIGlkPSJlZGdlNyIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YiYjNDU7JiM0NTtoPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTk5LC0yMTUuODdDOTksLTE4OC41OCA5OSwtMTM1LjUyIDk5LC0xMDguMTkiLz4KPC9nPgo8IS0tIGQmIzQ1OyYjNDU7aCAtLT4KPGcgaWQ9ImVkZ2U4IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5kJiM0NTsmIzQ1O2g8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNNDkuMzYsLTE0Ni4xNUM2MC4wNSwtMTM0LjI4IDc0Ljk3LC0xMTcuNyA4NS42NiwtMTA1LjgyIi8+CjwvZz4KPCEtLSBoJiM0NTsmIzQ1O2ogLS0+CjxnIGlkPSJlZGdlOSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aCYjNDU7JiM0NTtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTEwNS40LC03Mi40MUMxMDkuNjQsLTYxLjQxIDExNS4xOSwtNDcuMDMgMTE5LjQ2LC0zNS45NiIvPgo8L2c+CjwvZz4KPC9zdmc+Cg=="},79968:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMTg5cHQiIGhlaWdodD0iNDA0cHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMTg5LjAwIDQwNC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCA0MDApIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0id2hpdGUiIHN0cm9rZT0idHJhbnNwYXJlbnQiIHBvaW50cz0iLTQsNCAtNCwtNDAwIDE4NSwtNDAwIDE4NSw0IC00LDQiLz4KPCEtLSBhIC0tPgo8ZyBpZD0ibm9kZTEiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmE8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMTI2IiBjeT0iLTM3OCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTI2IiB5PSItMzc0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTMwNiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0zMDIuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmM8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmIzQ1O2MgLS0+CjxnIGlkPSJlZGdlMSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7JiM0NTtjPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTExOS42LC0zNjAuNDFDMTE1LjM2LC0zNDkuNDEgMTA5LjgxLC0zMzUuMDMgMTA1LjU0LC0zMjMuOTYiLz4KPC9nPgo8IS0tIGUgLS0+CjxnIGlkPSJub2RlMyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNTQiIGN5PSItMTYyIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNTQiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmU8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmIzQ1O2UgLS0+CjxnIGlkPSJlZGdlMiIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7JiM0NTtlPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTEyOS4xNCwtMzU5Ljg1QzEzMC45OCwtMzQ5LjQ5IDEzMy4yNywtMzM2LjAxIDEzNSwtMzI0IDE0Mi40OSwtMjcxLjkgMTQ5LjE4LC0yMTAuMDEgMTUyLjI0LC0xODAuNDMiLz4KPC9nPgo8IS0tIGkgLS0+CjxnIGlkPSJub2RlNCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIyNyIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjI3IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtpIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik04NC40MywtMjkwLjgzQzcyLjAyLC0yNzguNzcgNTQuMjcsLTI2MS41MSA0MS44LC0yNDkuMzgiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI5OSIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5iPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtiIC0tPgo8ZyBpZD0iZWRnZTQiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7YjwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik05OSwtMjg3LjdDOTksLTI3Ni44NSA5OSwtMjYyLjkyIDk5LC0yNTIuMSIvPgo8L2c+CjwhLS0gaiAtLT4KPGcgaWQ9Im5vZGU2IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5qPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjEyNiIgY3k9Ii0xOCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTI2IiB5PSItMTQuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmo8L3RleHQ+CjwvZz4KPCEtLSBlJiM0NTsmIzQ1O2ogLS0+CjxnIGlkPSJlZGdlNSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZSYjNDU7JiM0NTtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTE1MC42MiwtMTQzLjg3QzE0NS4yNCwtMTE2LjU4IDEzNC43OCwtNjMuNTIgMTI5LjM5LC0zNi4xOSIvPgo8L2c+CjwhLS0gZCAtLT4KPGcgaWQ9Im5vZGU3IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5kPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjM2IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMzYiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmQ8L3RleHQ+CjwvZz4KPCEtLSBpJiM0NTsmIzQ1O2QgLS0+CjxnIGlkPSJlZGdlNiIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aSYjNDU7JiM0NTtkPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTI5LjE4LC0yMTYuMDVDMzAuNTcsLTIwNS4yMSAzMi4zOCwtMTkxLjE4IDMzLjc4LC0xODAuMjgiLz4KPC9nPgo8IS0tIGggLS0+CjxnIGlkPSJub2RlOCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI5OSIgY3k9Ii05MCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCI+aDwvdGV4dD4KPC9nPgo8IS0tIGImIzQ1OyYjNDU7aCAtLT4KPGcgaWQ9ImVkZ2U3IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5iJiM0NTsmIzQ1O2g8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNOTksLTIxNS44N0M5OSwtMTg4LjU4IDk5LC0xMzUuNTIgOTksLTEwOC4xOSIvPgo8L2c+CjwhLS0gZCYjNDU7JiM0NTtoIC0tPgo8ZyBpZD0iZWRnZTgiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmQmIzQ1OyYjNDU7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik00OS4zNiwtMTQ2LjE1QzYwLjA1LC0xMzQuMjggNzQuOTcsLTExNy43IDg1LjY2LC0xMDUuODIiLz4KPC9nPgo8IS0tIGgmIzQ1OyYjNDU7aiAtLT4KPGcgaWQ9ImVkZ2U5IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5oJiM0NTsmIzQ1O2o8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNMTA1LjQsLTcyLjQxQzEwOS42NCwtNjEuNDEgMTE1LjE5LC00Ny4wMyAxMTkuNDYsLTM1Ljk2Ii8+CjwvZz4KPC9nPgo8L3N2Zz4K"},7619:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMTg5cHQiIGhlaWdodD0iNDA0cHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMTg5LjAwIDQwNC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCA0MDApIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0iIzFiMWIxZCIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgcG9pbnRzPSItNCw0IC00LC00MDAgMTg1LC00MDAgMTg1LDQgLTQsNCIvPgo8IS0tIGEgLS0+CjxnIGlkPSJub2RlMSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMjYiIGN5PSItMzc4IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxMjYiIHk9Ii0zNzQuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9Ijk5IiBjeT0iLTMwNiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0zMDIuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5jPC90ZXh0Pgo8L2c+CjwhLS0gYSYjNDU7JiM0NTtjIC0tPgo8ZyBpZD0iZWRnZTEiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmEmIzQ1OyYjNDU7YzwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xMTkuNiwtMzYwLjQxQzExNS4zNiwtMzQ5LjQxIDEwOS44MSwtMzM1LjAzIDEwNS41NCwtMzIzLjk2Ii8+CjwvZz4KPCEtLSBlIC0tPgo8ZyBpZD0ibm9kZTMiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmU8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTU0IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTU0IiB5PSItMTU4LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ZTwvdGV4dD4KPC9nPgo8IS0tIGEmIzQ1OyYjNDU7ZSAtLT4KPGcgaWQ9ImVkZ2UyIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmIzQ1O2U8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTI5LjE0LC0zNTkuODVDMTMwLjk4LC0zNDkuNDkgMTMzLjI3LC0zMzYuMDEgMTM1LC0zMjQgMTQyLjQ5LC0yNzEuOSAxNDkuMTgsLTIxMC4wMSAxNTIuMjQsLTE4MC40MyIvPgo8L2c+CjwhLS0gaSAtLT4KPGcgaWQ9Im5vZGU0IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5pPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9IjI3IiBjeT0iLTIzNCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjciIHk9Ii0yMzAuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtpIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik04NC40MywtMjkwLjgzQzcyLjAyLC0yNzguNzcgNTQuMjcsLTI2MS41MSA0MS44LC0yNDkuMzgiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSI5OSIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyYjNDU7YiAtLT4KPGcgaWQ9ImVkZ2U0IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5jJiM0NTsmIzQ1O2I8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNOTksLTI4Ny43Qzk5LC0yNzYuODUgOTksLTI2Mi45MiA5OSwtMjUyLjEiLz4KPC9nPgo8IS0tIGogLS0+CjxnIGlkPSJub2RlNiIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ajwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMjYiIGN5PSItMTgiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjEyNiIgeT0iLTE0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ajwvdGV4dD4KPC9nPgo8IS0tIGUmIzQ1OyYjNDU7aiAtLT4KPGcgaWQ9ImVkZ2U1IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5lJiM0NTsmIzQ1O2o8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTUwLjYyLC0xNDMuODdDMTQ1LjI0LC0xMTYuNTggMTM0Ljc4LC02My41MiAxMjkuMzksLTM2LjE5Ii8+CjwvZz4KPCEtLSBoIC0tPgo8ZyBpZD0ibm9kZTciIGNsYXNzPSJub2RlIj4KPHRpdGxlPmg8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iOTkiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItODYuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5oPC90ZXh0Pgo8L2c+CjwhLS0gZSYjNDU7JiM0NTtoIC0tPgo8ZyBpZD0iZWRnZTYiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmUmIzQ1OyYjNDU7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xNDIuMDcsLTE0NS44MUMxMzIuODQsLTEzNC4wNyAxMjAuMTMsLTExNy44OSAxMTAuOTEsLTEwNi4xNiIvPgo8L2c+CjwhLS0gZCAtLT4KPGcgaWQ9Im5vZGU4IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5kPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9IjM1IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMzUiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5kPC90ZXh0Pgo8L2c+CjwhLS0gaSYjNDU7JiM0NTtkIC0tPgo8ZyBpZD0iZWRnZTciIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmkmIzQ1OyYjNDU7ZDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0yOC45OCwtMjE1LjdDMzAuMjIsLTIwNC44NSAzMS44MSwtMTkwLjkyIDMzLjA1LC0xODAuMSIvPgo8L2c+CjwhLS0gYiYjNDU7JiM0NTtoIC0tPgo8ZyBpZD0iZWRnZTgiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmImIzQ1OyYjNDU7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik05OSwtMjE1Ljg3Qzk5LC0xODguNTggOTksLTEzNS41MiA5OSwtMTA4LjE5Ii8+CjwvZz4KPCEtLSBoJiM0NTsmIzQ1O2ogLS0+CjxnIGlkPSJlZGdlMTAiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmgmIzQ1OyYjNDU7ajwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xMDUuNCwtNzIuNDFDMTA5LjY0LC02MS40MSAxMTUuMTksLTQ3LjAzIDExOS40NiwtMzUuOTYiLz4KPC9nPgo8IS0tIGQmIzQ1OyYjNDU7aCAtLT4KPGcgaWQ9ImVkZ2U5IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5kJiM0NTsmIzQ1O2g8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNNDguNTcsLTE0Ni4xNUM1OS40MywtMTM0LjI4IDc0LjU5LC0xMTcuNyA4NS40NSwtMTA1LjgyIi8+CjwvZz4KPC9nPgo8L3N2Zz4K"},40050:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMTg5cHQiIGhlaWdodD0iNDA0cHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMTg5LjAwIDQwNC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCA0MDApIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0id2hpdGUiIHN0cm9rZT0idHJhbnNwYXJlbnQiIHBvaW50cz0iLTQsNCAtNCwtNDAwIDE4NSwtNDAwIDE4NSw0IC00LDQiLz4KPCEtLSBhIC0tPgo8ZyBpZD0ibm9kZTEiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmE8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMTI2IiBjeT0iLTM3OCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTI2IiB5PSItMzc0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTMwNiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0zMDIuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmM8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmIzQ1O2MgLS0+CjxnIGlkPSJlZGdlMSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7JiM0NTtjPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTExOS42LC0zNjAuNDFDMTE1LjM2LC0zNDkuNDEgMTA5LjgxLC0zMzUuMDMgMTA1LjU0LC0zMjMuOTYiLz4KPC9nPgo8IS0tIGUgLS0+CjxnIGlkPSJub2RlMyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNTQiIGN5PSItMTYyIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNTQiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmU8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmIzQ1O2UgLS0+CjxnIGlkPSJlZGdlMiIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7JiM0NTtlPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTEyOS4xNCwtMzU5Ljg1QzEzMC45OCwtMzQ5LjQ5IDEzMy4yNywtMzM2LjAxIDEzNSwtMzI0IDE0Mi40OSwtMjcxLjkgMTQ5LjE4LC0yMTAuMDEgMTUyLjI0LC0xODAuNDMiLz4KPC9nPgo8IS0tIGkgLS0+CjxnIGlkPSJub2RlNCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIyNyIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjI3IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtpIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik04NC40MywtMjkwLjgzQzcyLjAyLC0yNzguNzcgNTQuMjcsLTI2MS41MSA0MS44LC0yNDkuMzgiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI5OSIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5iPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtiIC0tPgo8ZyBpZD0iZWRnZTQiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7YjwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik05OSwtMjg3LjdDOTksLTI3Ni44NSA5OSwtMjYyLjkyIDk5LC0yNTIuMSIvPgo8L2c+CjwhLS0gaiAtLT4KPGcgaWQ9Im5vZGU2IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5qPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjEyNiIgY3k9Ii0xOCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTI2IiB5PSItMTQuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmo8L3RleHQ+CjwvZz4KPCEtLSBlJiM0NTsmIzQ1O2ogLS0+CjxnIGlkPSJlZGdlNSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZSYjNDU7JiM0NTtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTE1MC42MiwtMTQzLjg3QzE0NS4yNCwtMTE2LjU4IDEzNC43OCwtNjMuNTIgMTI5LjM5LC0zNi4xOSIvPgo8L2c+CjwhLS0gaCAtLT4KPGcgaWQ9Im5vZGU3IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5oPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSI5OSIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5oPC90ZXh0Pgo8L2c+CjwhLS0gZSYjNDU7JiM0NTtoIC0tPgo8ZyBpZD0iZWRnZTYiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmUmIzQ1OyYjNDU7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xNDIuMDcsLTE0NS44MUMxMzIuODQsLTEzNC4wNyAxMjAuMTMsLTExNy44OSAxMTAuOTEsLTEwNi4xNiIvPgo8L2c+CjwhLS0gZCAtLT4KPGcgaWQ9Im5vZGU4IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5kPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjM1IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMzUiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmQ8L3RleHQ+CjwvZz4KPCEtLSBpJiM0NTsmIzQ1O2QgLS0+CjxnIGlkPSJlZGdlNyIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aSYjNDU7JiM0NTtkPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTI4Ljk4LC0yMTUuN0MzMC4yMiwtMjA0Ljg1IDMxLjgxLC0xOTAuOTIgMzMuMDUsLTE4MC4xIi8+CjwvZz4KPCEtLSBiJiM0NTsmIzQ1O2ggLS0+CjxnIGlkPSJlZGdlOCIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YiYjNDU7JiM0NTtoPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTk5LC0yMTUuODdDOTksLTE4OC41OCA5OSwtMTM1LjUyIDk5LC0xMDguMTkiLz4KPC9nPgo8IS0tIGgmIzQ1OyYjNDU7aiAtLT4KPGcgaWQ9ImVkZ2UxMCIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aCYjNDU7JiM0NTtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTEwNS40LC03Mi40MUMxMDkuNjQsLTYxLjQxIDExNS4xOSwtNDcuMDMgMTE5LjQ2LC0zNS45NiIvPgo8L2c+CjwhLS0gZCYjNDU7JiM0NTtoIC0tPgo8ZyBpZD0iZWRnZTkiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmQmIzQ1OyYjNDU7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik00OC41NywtMTQ2LjE1QzU5LjQzLC0xMzQuMjggNzQuNTksLTExNy43IDg1LjQ1LC0xMDUuODIiLz4KPC9nPgo8L2c+Cjwvc3ZnPgo="},43770:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMjA2cHQiIGhlaWdodD0iMjYwcHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMjA2LjAwIDI2MC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCAyNTYpIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0iIzFiMWIxZCIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgcG9pbnRzPSItNCw0IC00LC0yNTYgMjAyLC0yNTYgMjAyLDQgLTQsNCIvPgo8IS0tIGEgLS0+CjxnIGlkPSJub2RlMSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMzUiIGN5PSItMjM0IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxMzUiIHk9Ii0yMzAuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9Ijk5IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5jPC90ZXh0Pgo8L2c+CjwhLS0gYSYjNDU7Jmd0O2MgLS0+CjxnIGlkPSJlZGdlMSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7Jmd0O2M8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTI2LjY1LC0yMTYuNzZDMTIyLjI5LC0yMDguMjggMTE2Ljg1LC0xOTcuNzEgMTExLjk2LC0xODguMiIvPgo8cG9seWdvbiBmaWxsPSJ0cmFuc3BhcmVudCIgc3Ryb2tlPSJ3aGl0ZSIgcG9pbnRzPSIxMTQuOTksLTE4Ni40NCAxMDcuMywtMTc5LjE1IDEwOC43NywtMTg5LjY0IDExNC45OSwtMTg2LjQ0Ii8+CjwvZz4KPCEtLSBlIC0tPgo8ZyBpZD0ibm9kZTMiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmU8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTcxIiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTcxIiB5PSItMTU4LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ZTwvdGV4dD4KPC9nPgo8IS0tIGEmIzQ1OyZndDtlIC0tPgo8ZyBpZD0iZWRnZTIiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmEmIzQ1OyZndDtlPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTE0My4zNSwtMjE2Ljc2QzE0Ny43MSwtMjA4LjI4IDE1My4xNSwtMTk3LjcxIDE1OC4wNCwtMTg4LjIiLz4KPHBvbHlnb24gZmlsbD0idHJhbnNwYXJlbnQiIHN0cm9rZT0id2hpdGUiIHBvaW50cz0iMTYxLjIzLC0xODkuNjQgMTYyLjcsLTE3OS4xNSAxNTUuMDEsLTE4Ni40NCAxNjEuMjMsLTE4OS42NCIvPgo8L2c+CjwhLS0gYiAtLT4KPGcgaWQ9Im5vZGU0IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5iPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9IjI3IiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIyNyIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyZndDtiIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyZndDtiPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTg0LjQzLC0xNDYuODNDNzQuMjUsLTEzNi45NCA2MC40OCwtMTIzLjU1IDQ4Ljk3LC0xMTIuMzYiLz4KPHBvbHlnb24gZmlsbD0idHJhbnNwYXJlbnQiIHN0cm9rZT0id2hpdGUiIHBvaW50cz0iNTEuNDEsLTEwOS44NSA0MS44LC0xMDUuMzggNDYuNTMsLTExNC44NyA1MS40MSwtMTA5Ljg1Ii8+CjwvZz4KPCEtLSBpIC0tPgo8ZyBpZD0ibm9kZTUiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmk8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iOTkiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItODYuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7Jmd0O2kgLS0+CjxnIGlkPSJlZGdlNCIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YyYjNDU7Jmd0O2k8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNOTksLTE0My43Qzk5LC0xMzUuOTggOTksLTEyNi43MSA5OSwtMTE4LjExIi8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjEwMi41LC0xMTguMSA5OSwtMTA4LjEgOTUuNSwtMTE4LjEgMTAyLjUsLTExOC4xIi8+CjwvZz4KPCEtLSBqIC0tPgo8ZyBpZD0ibm9kZTYiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmo8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTcxIiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNzEiIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmo8L3RleHQ+CjwvZz4KPCEtLSBlJiM0NTsmZ3Q7aiAtLT4KPGcgaWQ9ImVkZ2U1IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5lJiM0NTsmZ3Q7ajwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xNzEsLTE0My43QzE3MSwtMTM1Ljk4IDE3MSwtMTI2LjcxIDE3MSwtMTE4LjExIi8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjE3NC41LC0xMTguMSAxNzEsLTEwOC4xIDE2Ny41LC0xMTguMSAxNzQuNSwtMTE4LjEiLz4KPC9nPgo8IS0tIGggLS0+CjxnIGlkPSJub2RlNyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIyNyIgY3k9Ii0xOCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjciIHk9Ii0xNC4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmg8L3RleHQ+CjwvZz4KPCEtLSBiJiM0NTsmZ3Q7aCAtLT4KPGcgaWQ9ImVkZ2U2IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5iJiM0NTsmZ3Q7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0yNywtNzEuN0MyNywtNjMuOTggMjcsLTU0LjcxIDI3LC00Ni4xMSIvPgo8cG9seWdvbiBmaWxsPSJ0cmFuc3BhcmVudCIgc3Ryb2tlPSJ3aGl0ZSIgcG9pbnRzPSIzMC41LC00Ni4xIDI3LC0zNi4xIDIzLjUsLTQ2LjEgMzAuNSwtNDYuMSIvPgo8L2c+CjwhLS0gZCAtLT4KPGcgaWQ9Im5vZGU4IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5kPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9Ijk5IiBjeT0iLTE4IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSI5OSIgeT0iLTE0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ZDwvdGV4dD4KPC9nPgo8IS0tIGkmIzQ1OyZndDtkIC0tPgo8ZyBpZD0iZWRnZTciIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmkmIzQ1OyZndDtkPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTk5LC03MS43Qzk5LC02My45OCA5OSwtNTQuNzEgOTksLTQ2LjExIi8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjEwMi41LC00Ni4xIDk5LC0zNi4xIDk1LjUsLTQ2LjEgMTAyLjUsLTQ2LjEiLz4KPC9nPgo8L2c+Cjwvc3ZnPgo="},62843:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMjA2cHQiIGhlaWdodD0iMjYwcHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMjA2LjAwIDI2MC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCAyNTYpIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0id2hpdGUiIHN0cm9rZT0idHJhbnNwYXJlbnQiIHBvaW50cz0iLTQsNCAtNCwtMjU2IDIwMiwtMjU2IDIwMiw0IC00LDQiLz4KPCEtLSBhIC0tPgo8ZyBpZD0ibm9kZTEiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmE8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMTM1IiBjeT0iLTIzNCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTM1IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmM8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmZ3Q7YyAtLT4KPGcgaWQ9ImVkZ2UxIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmZ3Q7YzwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xMjYuNjUsLTIxNi43NkMxMjIuMjksLTIwOC4yOCAxMTYuODUsLTE5Ny43MSAxMTEuOTYsLTE4OC4yIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjExNC45OSwtMTg2LjQ0IDEwNy4zLC0xNzkuMTUgMTA4Ljc3LC0xODkuNjQgMTE0Ljk5LC0xODYuNDQiLz4KPC9nPgo8IS0tIGUgLS0+CjxnIGlkPSJub2RlMyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNzEiIGN5PSItMTYyIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNzEiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmU8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmZ3Q7ZSAtLT4KPGcgaWQ9ImVkZ2UyIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmZ3Q7ZTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xNDMuMzUsLTIxNi43NkMxNDcuNzEsLTIwOC4yOCAxNTMuMTUsLTE5Ny43MSAxNTguMDQsLTE4OC4yIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjE2MS4yMywtMTg5LjY0IDE2Mi43LC0xNzkuMTUgMTU1LjAxLC0xODYuNDQgMTYxLjIzLC0xODkuNjQiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIyNyIgY3k9Ii05MCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjciIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyZndDtiIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyZndDtiPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTg0LjQzLC0xNDYuODNDNzQuMjUsLTEzNi45NCA2MC40OCwtMTIzLjU1IDQ4Ljk3LC0xMTIuMzYiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iNTEuNDEsLTEwOS44NSA0MS44LC0xMDUuMzggNDYuNTMsLTExNC44NyA1MS40MSwtMTA5Ljg1Ii8+CjwvZz4KPCEtLSBpIC0tPgo8ZyBpZD0ibm9kZTUiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmk8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iOTkiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItODYuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmk8L3RleHQ+CjwvZz4KPCEtLSBjJiM0NTsmZ3Q7aSAtLT4KPGcgaWQ9ImVkZ2U0IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5jJiM0NTsmZ3Q7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik05OSwtMTQzLjdDOTksLTEzNS45OCA5OSwtMTI2LjcxIDk5LC0xMTguMTEiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iMTAyLjUsLTExOC4xIDk5LC0xMDguMSA5NS41LC0xMTguMSAxMDIuNSwtMTE4LjEiLz4KPC9nPgo8IS0tIGogLS0+CjxnIGlkPSJub2RlNiIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ajwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNzEiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjE3MSIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5qPC90ZXh0Pgo8L2c+CjwhLS0gZSYjNDU7Jmd0O2ogLS0+CjxnIGlkPSJlZGdlNSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZSYjNDU7Jmd0O2o8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNMTcxLC0xNDMuN0MxNzEsLTEzNS45OCAxNzEsLTEyNi43MSAxNzEsLTExOC4xMSIvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgcG9pbnRzPSIxNzQuNSwtMTE4LjEgMTcxLC0xMDguMSAxNjcuNSwtMTE4LjEgMTc0LjUsLTExOC4xIi8+CjwvZz4KPCEtLSBoIC0tPgo8ZyBpZD0ibm9kZTciIGNsYXNzPSJub2RlIj4KPHRpdGxlPmg8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMjciIGN5PSItMTgiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjI3IiB5PSItMTQuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmg8L3RleHQ+CjwvZz4KPCEtLSBiJiM0NTsmZ3Q7aCAtLT4KPGcgaWQ9ImVkZ2U2IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5iJiM0NTsmZ3Q7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0yNywtNzEuN0MyNywtNjMuOTggMjcsLTU0LjcxIDI3LC00Ni4xMSIvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgcG9pbnRzPSIzMC41LC00Ni4xIDI3LC0zNi4xIDIzLjUsLTQ2LjEgMzAuNSwtNDYuMSIvPgo8L2c+CjwhLS0gZCAtLT4KPGcgaWQ9Im5vZGU4IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5kPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTE4IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSI5OSIgeT0iLTE0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5kPC90ZXh0Pgo8L2c+CjwhLS0gaSYjNDU7Jmd0O2QgLS0+CjxnIGlkPSJlZGdlNyIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aSYjNDU7Jmd0O2Q8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNOTksLTcxLjdDOTksLTYzLjk4IDk5LC01NC43MSA5OSwtNDYuMTEiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iMTAyLjUsLTQ2LjEgOTksLTM2LjEgOTUuNSwtNDYuMSAxMDIuNSwtNDYuMSIvPgo8L2c+CjwvZz4KPC9zdmc+Cg=="},31350:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMjc4cHQiIGhlaWdodD0iMjYwcHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMjc4LjAwIDI2MC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCAyNTYpIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0iIzFiMWIxZCIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgcG9pbnRzPSItNCw0IC00LC0yNTYgMjc0LC0yNTYgMjc0LDQgLTQsNCIvPgo8IS0tIGEgLS0+CjxnIGlkPSJub2RlMSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMzUiIGN5PSItMjM0IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxMzUiIHk9Ii0yMzAuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9Ijk5IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5jPC90ZXh0Pgo8L2c+CjwhLS0gYSYjNDU7Jmd0O2MgLS0+CjxnIGlkPSJlZGdlMSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7Jmd0O2M8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTI2LjY1LC0yMTYuNzZDMTIyLjI5LC0yMDguMjggMTE2Ljg1LC0xOTcuNzEgMTExLjk2LC0xODguMiIvPgo8cG9seWdvbiBmaWxsPSJ0cmFuc3BhcmVudCIgc3Ryb2tlPSJ3aGl0ZSIgcG9pbnRzPSIxMTQuOTksLTE4Ni40NCAxMDcuMywtMTc5LjE1IDEwOC43NywtMTg5LjY0IDExNC45OSwtMTg2LjQ0Ii8+CjwvZz4KPCEtLSBlIC0tPgo8ZyBpZD0ibm9kZTMiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmU8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTcxIiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTcxIiB5PSItMTU4LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ZTwvdGV4dD4KPC9nPgo8IS0tIGEmIzQ1OyZndDtlIC0tPgo8ZyBpZD0iZWRnZTIiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmEmIzQ1OyZndDtlPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTE0My4zNSwtMjE2Ljc2QzE0Ny43MSwtMjA4LjI4IDE1My4xNSwtMTk3LjcxIDE1OC4wNCwtMTg4LjIiLz4KPHBvbHlnb24gZmlsbD0idHJhbnNwYXJlbnQiIHN0cm9rZT0id2hpdGUiIHBvaW50cz0iMTYxLjIzLC0xODkuNjQgMTYyLjcsLTE3OS4xNSAxNTUuMDEsLTE4Ni40NCAxNjEuMjMsLTE4OS42NCIvPgo8L2c+CjwhLS0gYiAtLT4KPGcgaWQ9Im5vZGU0IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5iPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9IjI3IiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIyNyIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyZndDtiIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyZndDtiPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTg0LjQzLC0xNDYuODNDNzQuMjUsLTEzNi45NCA2MC40OCwtMTIzLjU1IDQ4Ljk3LC0xMTIuMzYiLz4KPHBvbHlnb24gZmlsbD0idHJhbnNwYXJlbnQiIHN0cm9rZT0id2hpdGUiIHBvaW50cz0iNTEuNDEsLTEwOS44NSA0MS44LC0xMDUuMzggNDYuNTMsLTExNC44NyA1MS40MSwtMTA5Ljg1Ii8+CjwvZz4KPCEtLSBpIC0tPgo8ZyBpZD0ibm9kZTUiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmk8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iOTkiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItODYuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7Jmd0O2kgLS0+CjxnIGlkPSJlZGdlNCIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YyYjNDU7Jmd0O2k8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNOTksLTE0My43Qzk5LC0xMzUuOTggOTksLTEyNi43MSA5OSwtMTE4LjExIi8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjEwMi41LC0xMTguMSA5OSwtMTA4LjEgOTUuNSwtMTE4LjEgMTAyLjUsLTExOC4xIi8+CjwvZz4KPCEtLSBoIC0tPgo8ZyBpZD0ibm9kZTYiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmg8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTcxIiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNzEiIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmg8L3RleHQ+CjwvZz4KPCEtLSBlJiM0NTsmZ3Q7aCAtLT4KPGcgaWQ9ImVkZ2U1IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5lJiM0NTsmZ3Q7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xNzEsLTE0My43QzE3MSwtMTM1Ljk4IDE3MSwtMTI2LjcxIDE3MSwtMTE4LjExIi8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjE3NC41LC0xMTguMSAxNzEsLTEwOC4xIDE2Ny41LC0xMTguMSAxNzQuNSwtMTE4LjEiLz4KPC9nPgo8IS0tIGogLS0+CjxnIGlkPSJub2RlNyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ajwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIyNDMiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjI0MyIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ajwvdGV4dD4KPC9nPgo8IS0tIGUmIzQ1OyZndDtqIC0tPgo8ZyBpZD0iZWRnZTYiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmUmIzQ1OyZndDtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTE4NS41NywtMTQ2LjgzQzE5NS43NSwtMTM2Ljk0IDIwOS41MiwtMTIzLjU1IDIyMS4wMywtMTEyLjM2Ii8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjIyMy40NywtMTE0Ljg3IDIyOC4yLC0xMDUuMzggMjE4LjU5LC0xMDkuODUgMjIzLjQ3LC0xMTQuODciLz4KPC9nPgo8IS0tIGQgLS0+CjxnIGlkPSJub2RlOCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSI5OSIgY3k9Ii0xOCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNC4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmQ8L3RleHQ+CjwvZz4KPCEtLSBpJiM0NTsmZ3Q7ZCAtLT4KPGcgaWQ9ImVkZ2U3IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5pJiM0NTsmZ3Q7ZDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik05OSwtNzEuN0M5OSwtNjMuOTggOTksLTU0LjcxIDk5LC00Ni4xMSIvPgo8cG9seWdvbiBmaWxsPSJ0cmFuc3BhcmVudCIgc3Ryb2tlPSJ3aGl0ZSIgcG9pbnRzPSIxMDIuNSwtNDYuMSA5OSwtMzYuMSA5NS41LC00Ni4xIDEwMi41LC00Ni4xIi8+CjwvZz4KPC9nPgo8L3N2Zz4K"},9248:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMjc4cHQiIGhlaWdodD0iMjYwcHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMjc4LjAwIDI2MC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCAyNTYpIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0id2hpdGUiIHN0cm9rZT0idHJhbnNwYXJlbnQiIHBvaW50cz0iLTQsNCAtNCwtMjU2IDI3NCwtMjU2IDI3NCw0IC00LDQiLz4KPCEtLSBhIC0tPgo8ZyBpZD0ibm9kZTEiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmE8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMTM1IiBjeT0iLTIzNCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTM1IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmM8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmZ3Q7YyAtLT4KPGcgaWQ9ImVkZ2UxIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmZ3Q7YzwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xMjYuNjUsLTIxNi43NkMxMjIuMjksLTIwOC4yOCAxMTYuODUsLTE5Ny43MSAxMTEuOTYsLTE4OC4yIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjExNC45OSwtMTg2LjQ0IDEwNy4zLC0xNzkuMTUgMTA4Ljc3LC0xODkuNjQgMTE0Ljk5LC0xODYuNDQiLz4KPC9nPgo8IS0tIGUgLS0+CjxnIGlkPSJub2RlMyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNzEiIGN5PSItMTYyIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNzEiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmU8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmZ3Q7ZSAtLT4KPGcgaWQ9ImVkZ2UyIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmZ3Q7ZTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xNDMuMzUsLTIxNi43NkMxNDcuNzEsLTIwOC4yOCAxNTMuMTUsLTE5Ny43MSAxNTguMDQsLTE4OC4yIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjE2MS4yMywtMTg5LjY0IDE2Mi43LC0xNzkuMTUgMTU1LjAxLC0xODYuNDQgMTYxLjIzLC0xODkuNjQiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIyNyIgY3k9Ii05MCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjciIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyZndDtiIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyZndDtiPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTg0LjQzLC0xNDYuODNDNzQuMjUsLTEzNi45NCA2MC40OCwtMTIzLjU1IDQ4Ljk3LC0xMTIuMzYiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iNTEuNDEsLTEwOS44NSA0MS44LC0xMDUuMzggNDYuNTMsLTExNC44NyA1MS40MSwtMTA5Ljg1Ii8+CjwvZz4KPCEtLSBpIC0tPgo8ZyBpZD0ibm9kZTUiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmk8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iOTkiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItODYuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmk8L3RleHQ+CjwvZz4KPCEtLSBjJiM0NTsmZ3Q7aSAtLT4KPGcgaWQ9ImVkZ2U0IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5jJiM0NTsmZ3Q7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik05OSwtMTQzLjdDOTksLTEzNS45OCA5OSwtMTI2LjcxIDk5LC0xMTguMTEiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iMTAyLjUsLTExOC4xIDk5LC0xMDguMSA5NS41LC0xMTguMSAxMDIuNSwtMTE4LjEiLz4KPC9nPgo8IS0tIGggLS0+CjxnIGlkPSJub2RlNiIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNzEiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjE3MSIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5oPC90ZXh0Pgo8L2c+CjwhLS0gZSYjNDU7Jmd0O2ggLS0+CjxnIGlkPSJlZGdlNSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZSYjNDU7Jmd0O2g8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNMTcxLC0xNDMuN0MxNzEsLTEzNS45OCAxNzEsLTEyNi43MSAxNzEsLTExOC4xMSIvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgcG9pbnRzPSIxNzQuNSwtMTE4LjEgMTcxLC0xMDguMSAxNjcuNSwtMTE4LjEgMTc0LjUsLTExOC4xIi8+CjwvZz4KPCEtLSBqIC0tPgo8ZyBpZD0ibm9kZTciIGNsYXNzPSJub2RlIj4KPHRpdGxlPmo8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMjQzIiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIyNDMiIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCI+ajwvdGV4dD4KPC9nPgo8IS0tIGUmIzQ1OyZndDtqIC0tPgo8ZyBpZD0iZWRnZTYiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmUmIzQ1OyZndDtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTE4NS41NywtMTQ2LjgzQzE5NS43NSwtMTM2Ljk0IDIwOS41MiwtMTIzLjU1IDIyMS4wMywtMTEyLjM2Ii8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjIyMy40NywtMTE0Ljg3IDIyOC4yLC0xMDUuMzggMjE4LjU5LC0xMDkuODUgMjIzLjQ3LC0xMTQuODciLz4KPC9nPgo8IS0tIGQgLS0+CjxnIGlkPSJub2RlOCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI5OSIgY3k9Ii0xOCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNC4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCI+ZDwvdGV4dD4KPC9nPgo8IS0tIGkmIzQ1OyZndDtkIC0tPgo8ZyBpZD0iZWRnZTciIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmkmIzQ1OyZndDtkPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTk5LC03MS43Qzk5LC02My45OCA5OSwtNTQuNzEgOTksLTQ2LjExIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjEwMi41LC00Ni4xIDk5LC0zNi4xIDk1LjUsLTQ2LjEgMTAyLjUsLTQ2LjEiLz4KPC9nPgo8L2c+Cjwvc3ZnPgo="},11151:(I,i,l)=>{l.d(i,{Z:()=>c,a:()=>g});var s=l(67294);const m={},a=s.createContext(m);function g(I){const i=s.useContext(a);return s.useMemo((function(){return"function"==typeof I?I(i):{...i,...I}}),[i,I])}function c(I){let i;return i=I.disableParentContext?"function"==typeof I.components?I.components(m):I.components||m:g(I.components),s.createElement(a.Provider,{value:i},I.children)}}}]); \ No newline at end of file diff --git a/assets/js/354a7b72.becd0640.js b/assets/js/354a7b72.becd0640.js new file mode 100644 index 0000000..e28a147 --- /dev/null +++ b/assets/js/354a7b72.becd0640.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[9414],{46617:(I,i,l)=>{l.r(i),l.d(i,{assets:()=>j,contentTitle:()=>g,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>Z});var s=l(85893),m=l(11151);const a={id:"bfs-tree",title:"Distance boundaries from BFS tree on undirected graphs",description:"Short explanation of distance boundaries deduced from a BFS tree.\n",tags:["graphs","bfs"],last_update:{date:new Date("2022-04-30T00:00:00.000Z")}},g=void 0,c={id:"graphs/bfs-tree",title:"Distance boundaries from BFS tree on undirected graphs",description:"Short explanation of distance boundaries deduced from a BFS tree.\n",source:"@site/algorithms/10-graphs/2022-04-30-bfs-tree.md",sourceDirName:"10-graphs",slug:"/graphs/bfs-tree",permalink:"/algorithms/graphs/bfs-tree",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/10-graphs/2022-04-30-bfs-tree.md",tags:[{label:"graphs",permalink:"/algorithms/tags/graphs"},{label:"bfs",permalink:"/algorithms/tags/bfs"}],version:"current",lastUpdatedAt:1651276800,formattedLastUpdatedAt:"Apr 30, 2022",frontMatter:{id:"bfs-tree",title:"Distance boundaries from BFS tree on undirected graphs",description:"Short explanation of distance boundaries deduced from a BFS tree.\n",tags:["graphs","bfs"],last_update:{date:"2022-04-30T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"Iterative algorithms via iterators",permalink:"/algorithms/graphs/iterative-and-iterators"},next:{title:"Paths in Graphs",permalink:"/algorithms/category/paths-in-graphs"}},j={},Z=[{value:"Introduction",id:"introduction",level:2},{value:"Lower bound",id:"lower-bound",level:2},{value:"Proof by contradiction",id:"proof-by-contradiction",level:2}];function n(I){const i={admonition:"admonition",annotation:"annotation",em:"em",h2:"h2",img:"img",li:"li",math:"math",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",p:"p",semantics:"semantics",span:"span",strong:"strong",ul:"ul",...(0,m.a)(),...I.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(i.p,{children:["As we have talked on the seminar, if we construct from some vertex ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"u"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"u"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.4306em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"u"})]})})]})," BFS tree on an undirected graph, we can obtain:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["lower bound of length of the shortest path between 2 vertices from the ",(0,s.jsx)(i.em,{children:"height difference"})]}),"\n",(0,s.jsxs)(i.li,{children:["upper bound of length of the shortest path between 2 vertices from the ",(0,s.jsx)(i.em,{children:"path through the root"})]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"lower-bound",children:"Lower bound"}),"\n",(0,s.jsx)(i.p,{children:"Consider the following graph:"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.img,{src:l(79968).Z+"#gh-light-mode-only",width:"252",height:"539"}),"\n",(0,s.jsx)(i.img,{src:l(21949).Z+"#gh-dark-mode-only",width:"252",height:"539"})]}),"\n",(0,s.jsxs)(i.p,{children:["We run BFS from the vertex ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"a"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"a"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.4306em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"a"})]})})]})," and obtain the following BFS tree:"]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.img,{src:l(62843).Z+"#gh-light-mode-only",width:"275",height:"347"}),"\n",(0,s.jsx)(i.img,{src:l(43770).Z+"#gh-dark-mode-only",width:"275",height:"347"})]}),"\n",(0,s.jsxs)(i.p,{children:["Let's consider pair of vertices ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"e"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"e"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.4306em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"e"})]})})]})," and ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"h"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"h"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6944em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"h"})]})})]}),". For them we can safely lay, from the BFS tree, following properties:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["lower bound: ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"2"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"2"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"2"})]})})]})]}),"\n",(0,s.jsxs)(i.li,{children:["upper bound: ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"4"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"4"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"4"})]})})]})]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["By having a look at the graph we started from, we can see that we have a path \u2039",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsxs)(i.mrow,{children:[(0,s.jsx)(i.mi,{children:"e"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"j"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"h"})]}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"e, j, h"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"e"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",style:{marginRight:"0.05724em"},children:"j"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"h"})]})})]}),"\u203a that has a length 2. Apart from that we can also notice there is another path from ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"e"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"e"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.4306em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"e"})]})})]})," to ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mi,{children:"h"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"h"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6944em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"h"})]})})]})," and that is \u2039",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsxs)(i.mrow,{children:[(0,s.jsx)(i.mi,{children:"e"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"a"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"c"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"i"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"d"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"h"})]}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"e, a, c, i, d, h"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"e"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"a"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"c"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"i"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"d"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"h"})]})})]}),"\u203a. And that path has a length of ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"5"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"5"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"5"})]})})]}),". Doesn't this break our statements at the beginning? (",(0,s.jsx)(i.em,{children:"I'm leaving that as an exercise ;)"}),")"]}),"\n",(0,s.jsx)(i.h2,{id:"proof-by-contradiction",children:"Proof by contradiction"}),"\n",(0,s.jsxs)(i.p,{children:["Let's keep the same graph, but break the lower bound, i.e. I have gotten a lower bound ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"2"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"2"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"2"})]})})]}),", but \u201cthere must be a shorter path\u201d! ;)"]}),"\n",(0,s.jsxs)(i.p,{children:["Now the more important question, is there a shorter path in that graph? The answer is no, there's no shorter path than the one with length ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"2"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"2"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"2"})]})})]}),". So what can we do about it? We'll add an edge to have a shorter path. Now we have gotten a lower bound of ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"2"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"2"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"2"})]})})]}),", which means the only shorter path we can construct has ",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsx)(i.mrow,{children:(0,s.jsx)(i.mn,{children:"1"})}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"1"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.6444em"}}),(0,s.jsx)(i.span,{className:"mord",children:"1"})]})})]})," edge and that is \u2039",(0,s.jsxs)(i.span,{className:"katex",children:[(0,s.jsx)(i.span,{className:"katex-mathml",children:(0,s.jsx)(i.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,s.jsxs)(i.semantics,{children:[(0,s.jsxs)(i.mrow,{children:[(0,s.jsx)(i.mi,{children:"e"}),(0,s.jsx)(i.mo,{separator:"true",children:","}),(0,s.jsx)(i.mi,{children:"h"})]}),(0,s.jsx)(i.annotation,{encoding:"application/x-tex",children:"e, h"})]})})}),(0,s.jsx)(i.span,{className:"katex-html","aria-hidden":"true",children:(0,s.jsxs)(i.span,{className:"base",children:[(0,s.jsx)(i.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"e"}),(0,s.jsx)(i.span,{className:"mpunct",children:","}),(0,s.jsx)(i.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.jsx)(i.span,{className:"mord mathnormal",children:"h"})]})})]}),"\u203a (no intermediary vertices). Let's do this!"]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.img,{src:l(40050).Z+"#gh-light-mode-only",width:"252",height:"539"}),"\n",(0,s.jsx)(i.img,{src:l(7619).Z+"#gh-dark-mode-only",width:"252",height:"539"})]}),"\n",(0,s.jsx)(i.p,{children:"Okay, so we have a graph that breaks the rule we have laid. However, we need to run BFS to obtain the new BFS tree, since we have changed the graph."}),"\n",(0,s.jsxs)(i.admonition,{type:"tip",children:[(0,s.jsxs)(i.p,{children:["Do we need to run BFS after ",(0,s.jsx)(i.strong,{children:"every"})," change?"]}),(0,s.jsx)(i.p,{children:"\xadI am leaving that as an exercise ;)"})]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.img,{src:l(9248).Z+"#gh-light-mode-only",width:"371",height:"347"}),"\n",(0,s.jsx)(i.img,{src:l(31350).Z+"#gh-dark-mode-only",width:"371",height:"347"})]}),"\n",(0,s.jsx)(i.p,{children:"Oops, we have gotten a new BFS tree, that has a height difference of 1."}),"\n",(0,s.jsx)(i.admonition,{type:"tip",children:(0,s.jsx)(i.p,{children:"Try to think about a way this can be generalized for shortening of minimal length 3 to minimal length 2 ;)"})})]})}function d(I={}){const{wrapper:i}={...(0,m.a)(),...I.components};return i?(0,s.jsx)(i,{...I,children:(0,s.jsx)(n,{...I})}):n(I)}},21949:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMTg5cHQiIGhlaWdodD0iNDA0cHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMTg5LjAwIDQwNC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCA0MDApIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0iIzFiMWIxZCIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgcG9pbnRzPSItNCw0IC00LC00MDAgMTg1LC00MDAgMTg1LDQgLTQsNCIvPgo8IS0tIGEgLS0+CjxnIGlkPSJub2RlMSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMjYiIGN5PSItMzc4IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxMjYiIHk9Ii0zNzQuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9Ijk5IiBjeT0iLTMwNiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0zMDIuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5jPC90ZXh0Pgo8L2c+CjwhLS0gYSYjNDU7JiM0NTtjIC0tPgo8ZyBpZD0iZWRnZTEiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmEmIzQ1OyYjNDU7YzwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xMTkuNiwtMzYwLjQxQzExNS4zNiwtMzQ5LjQxIDEwOS44MSwtMzM1LjAzIDEwNS41NCwtMzIzLjk2Ii8+CjwvZz4KPCEtLSBlIC0tPgo8ZyBpZD0ibm9kZTMiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmU8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTU0IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTU0IiB5PSItMTU4LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ZTwvdGV4dD4KPC9nPgo8IS0tIGEmIzQ1OyYjNDU7ZSAtLT4KPGcgaWQ9ImVkZ2UyIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmIzQ1O2U8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTI5LjE0LC0zNTkuODVDMTMwLjk4LC0zNDkuNDkgMTMzLjI3LC0zMzYuMDEgMTM1LC0zMjQgMTQyLjQ5LC0yNzEuOSAxNDkuMTgsLTIxMC4wMSAxNTIuMjQsLTE4MC40MyIvPgo8L2c+CjwhLS0gaSAtLT4KPGcgaWQ9Im5vZGU0IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5pPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9IjI3IiBjeT0iLTIzNCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjciIHk9Ii0yMzAuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtpIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik04NC40MywtMjkwLjgzQzcyLjAyLC0yNzguNzcgNTQuMjcsLTI2MS41MSA0MS44LC0yNDkuMzgiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSI5OSIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyYjNDU7YiAtLT4KPGcgaWQ9ImVkZ2U0IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5jJiM0NTsmIzQ1O2I8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNOTksLTI4Ny43Qzk5LC0yNzYuODUgOTksLTI2Mi45MiA5OSwtMjUyLjEiLz4KPC9nPgo8IS0tIGogLS0+CjxnIGlkPSJub2RlNiIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ajwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMjYiIGN5PSItMTgiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjEyNiIgeT0iLTE0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ajwvdGV4dD4KPC9nPgo8IS0tIGUmIzQ1OyYjNDU7aiAtLT4KPGcgaWQ9ImVkZ2U1IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5lJiM0NTsmIzQ1O2o8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTUwLjYyLC0xNDMuODdDMTQ1LjI0LC0xMTYuNTggMTM0Ljc4LC02My41MiAxMjkuMzksLTM2LjE5Ii8+CjwvZz4KPCEtLSBkIC0tPgo8ZyBpZD0ibm9kZTciIGNsYXNzPSJub2RlIj4KPHRpdGxlPmQ8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMzYiIGN5PSItMTYyIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIzNiIgeT0iLTE1OC4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmQ8L3RleHQ+CjwvZz4KPCEtLSBpJiM0NTsmIzQ1O2QgLS0+CjxnIGlkPSJlZGdlNiIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aSYjNDU7JiM0NTtkPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTI5LjE4LC0yMTYuMDVDMzAuNTcsLTIwNS4yMSAzMi4zOCwtMTkxLjE4IDMzLjc4LC0xODAuMjgiLz4KPC9nPgo8IS0tIGggLS0+CjxnIGlkPSJub2RlOCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSI5OSIgY3k9Ii05MCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmg8L3RleHQ+CjwvZz4KPCEtLSBiJiM0NTsmIzQ1O2ggLS0+CjxnIGlkPSJlZGdlNyIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YiYjNDU7JiM0NTtoPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTk5LC0yMTUuODdDOTksLTE4OC41OCA5OSwtMTM1LjUyIDk5LC0xMDguMTkiLz4KPC9nPgo8IS0tIGQmIzQ1OyYjNDU7aCAtLT4KPGcgaWQ9ImVkZ2U4IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5kJiM0NTsmIzQ1O2g8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNNDkuMzYsLTE0Ni4xNUM2MC4wNSwtMTM0LjI4IDc0Ljk3LC0xMTcuNyA4NS42NiwtMTA1LjgyIi8+CjwvZz4KPCEtLSBoJiM0NTsmIzQ1O2ogLS0+CjxnIGlkPSJlZGdlOSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aCYjNDU7JiM0NTtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTEwNS40LC03Mi40MUMxMDkuNjQsLTYxLjQxIDExNS4xOSwtNDcuMDMgMTE5LjQ2LC0zNS45NiIvPgo8L2c+CjwvZz4KPC9zdmc+Cg=="},79968:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMTg5cHQiIGhlaWdodD0iNDA0cHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMTg5LjAwIDQwNC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCA0MDApIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0id2hpdGUiIHN0cm9rZT0idHJhbnNwYXJlbnQiIHBvaW50cz0iLTQsNCAtNCwtNDAwIDE4NSwtNDAwIDE4NSw0IC00LDQiLz4KPCEtLSBhIC0tPgo8ZyBpZD0ibm9kZTEiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmE8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMTI2IiBjeT0iLTM3OCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTI2IiB5PSItMzc0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTMwNiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0zMDIuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmM8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmIzQ1O2MgLS0+CjxnIGlkPSJlZGdlMSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7JiM0NTtjPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTExOS42LC0zNjAuNDFDMTE1LjM2LC0zNDkuNDEgMTA5LjgxLC0zMzUuMDMgMTA1LjU0LC0zMjMuOTYiLz4KPC9nPgo8IS0tIGUgLS0+CjxnIGlkPSJub2RlMyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNTQiIGN5PSItMTYyIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNTQiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmU8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmIzQ1O2UgLS0+CjxnIGlkPSJlZGdlMiIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7JiM0NTtlPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTEyOS4xNCwtMzU5Ljg1QzEzMC45OCwtMzQ5LjQ5IDEzMy4yNywtMzM2LjAxIDEzNSwtMzI0IDE0Mi40OSwtMjcxLjkgMTQ5LjE4LC0yMTAuMDEgMTUyLjI0LC0xODAuNDMiLz4KPC9nPgo8IS0tIGkgLS0+CjxnIGlkPSJub2RlNCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIyNyIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjI3IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtpIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik04NC40MywtMjkwLjgzQzcyLjAyLC0yNzguNzcgNTQuMjcsLTI2MS41MSA0MS44LC0yNDkuMzgiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI5OSIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5iPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtiIC0tPgo8ZyBpZD0iZWRnZTQiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7YjwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik05OSwtMjg3LjdDOTksLTI3Ni44NSA5OSwtMjYyLjkyIDk5LC0yNTIuMSIvPgo8L2c+CjwhLS0gaiAtLT4KPGcgaWQ9Im5vZGU2IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5qPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjEyNiIgY3k9Ii0xOCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTI2IiB5PSItMTQuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmo8L3RleHQ+CjwvZz4KPCEtLSBlJiM0NTsmIzQ1O2ogLS0+CjxnIGlkPSJlZGdlNSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZSYjNDU7JiM0NTtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTE1MC42MiwtMTQzLjg3QzE0NS4yNCwtMTE2LjU4IDEzNC43OCwtNjMuNTIgMTI5LjM5LC0zNi4xOSIvPgo8L2c+CjwhLS0gZCAtLT4KPGcgaWQ9Im5vZGU3IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5kPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjM2IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMzYiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmQ8L3RleHQ+CjwvZz4KPCEtLSBpJiM0NTsmIzQ1O2QgLS0+CjxnIGlkPSJlZGdlNiIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aSYjNDU7JiM0NTtkPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTI5LjE4LC0yMTYuMDVDMzAuNTcsLTIwNS4yMSAzMi4zOCwtMTkxLjE4IDMzLjc4LC0xODAuMjgiLz4KPC9nPgo8IS0tIGggLS0+CjxnIGlkPSJub2RlOCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI5OSIgY3k9Ii05MCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCI+aDwvdGV4dD4KPC9nPgo8IS0tIGImIzQ1OyYjNDU7aCAtLT4KPGcgaWQ9ImVkZ2U3IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5iJiM0NTsmIzQ1O2g8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNOTksLTIxNS44N0M5OSwtMTg4LjU4IDk5LC0xMzUuNTIgOTksLTEwOC4xOSIvPgo8L2c+CjwhLS0gZCYjNDU7JiM0NTtoIC0tPgo8ZyBpZD0iZWRnZTgiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmQmIzQ1OyYjNDU7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik00OS4zNiwtMTQ2LjE1QzYwLjA1LC0xMzQuMjggNzQuOTcsLTExNy43IDg1LjY2LC0xMDUuODIiLz4KPC9nPgo8IS0tIGgmIzQ1OyYjNDU7aiAtLT4KPGcgaWQ9ImVkZ2U5IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5oJiM0NTsmIzQ1O2o8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNMTA1LjQsLTcyLjQxQzEwOS42NCwtNjEuNDEgMTE1LjE5LC00Ny4wMyAxMTkuNDYsLTM1Ljk2Ii8+CjwvZz4KPC9nPgo8L3N2Zz4K"},7619:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMTg5cHQiIGhlaWdodD0iNDA0cHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMTg5LjAwIDQwNC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCA0MDApIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0iIzFiMWIxZCIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgcG9pbnRzPSItNCw0IC00LC00MDAgMTg1LC00MDAgMTg1LDQgLTQsNCIvPgo8IS0tIGEgLS0+CjxnIGlkPSJub2RlMSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMjYiIGN5PSItMzc4IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxMjYiIHk9Ii0zNzQuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9Ijk5IiBjeT0iLTMwNiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0zMDIuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5jPC90ZXh0Pgo8L2c+CjwhLS0gYSYjNDU7JiM0NTtjIC0tPgo8ZyBpZD0iZWRnZTEiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmEmIzQ1OyYjNDU7YzwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xMTkuNiwtMzYwLjQxQzExNS4zNiwtMzQ5LjQxIDEwOS44MSwtMzM1LjAzIDEwNS41NCwtMzIzLjk2Ii8+CjwvZz4KPCEtLSBlIC0tPgo8ZyBpZD0ibm9kZTMiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmU8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTU0IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTU0IiB5PSItMTU4LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ZTwvdGV4dD4KPC9nPgo8IS0tIGEmIzQ1OyYjNDU7ZSAtLT4KPGcgaWQ9ImVkZ2UyIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmIzQ1O2U8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTI5LjE0LC0zNTkuODVDMTMwLjk4LC0zNDkuNDkgMTMzLjI3LC0zMzYuMDEgMTM1LC0zMjQgMTQyLjQ5LC0yNzEuOSAxNDkuMTgsLTIxMC4wMSAxNTIuMjQsLTE4MC40MyIvPgo8L2c+CjwhLS0gaSAtLT4KPGcgaWQ9Im5vZGU0IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5pPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9IjI3IiBjeT0iLTIzNCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjciIHk9Ii0yMzAuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtpIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik04NC40MywtMjkwLjgzQzcyLjAyLC0yNzguNzcgNTQuMjcsLTI2MS41MSA0MS44LC0yNDkuMzgiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSI5OSIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyYjNDU7YiAtLT4KPGcgaWQ9ImVkZ2U0IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5jJiM0NTsmIzQ1O2I8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNOTksLTI4Ny43Qzk5LC0yNzYuODUgOTksLTI2Mi45MiA5OSwtMjUyLjEiLz4KPC9nPgo8IS0tIGogLS0+CjxnIGlkPSJub2RlNiIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ajwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMjYiIGN5PSItMTgiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjEyNiIgeT0iLTE0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ajwvdGV4dD4KPC9nPgo8IS0tIGUmIzQ1OyYjNDU7aiAtLT4KPGcgaWQ9ImVkZ2U1IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5lJiM0NTsmIzQ1O2o8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTUwLjYyLC0xNDMuODdDMTQ1LjI0LC0xMTYuNTggMTM0Ljc4LC02My41MiAxMjkuMzksLTM2LjE5Ii8+CjwvZz4KPCEtLSBoIC0tPgo8ZyBpZD0ibm9kZTciIGNsYXNzPSJub2RlIj4KPHRpdGxlPmg8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iOTkiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItODYuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5oPC90ZXh0Pgo8L2c+CjwhLS0gZSYjNDU7JiM0NTtoIC0tPgo8ZyBpZD0iZWRnZTYiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmUmIzQ1OyYjNDU7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xNDIuMDcsLTE0NS44MUMxMzIuODQsLTEzNC4wNyAxMjAuMTMsLTExNy44OSAxMTAuOTEsLTEwNi4xNiIvPgo8L2c+CjwhLS0gZCAtLT4KPGcgaWQ9Im5vZGU4IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5kPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9IjM1IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMzUiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5kPC90ZXh0Pgo8L2c+CjwhLS0gaSYjNDU7JiM0NTtkIC0tPgo8ZyBpZD0iZWRnZTciIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmkmIzQ1OyYjNDU7ZDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0yOC45OCwtMjE1LjdDMzAuMjIsLTIwNC44NSAzMS44MSwtMTkwLjkyIDMzLjA1LC0xODAuMSIvPgo8L2c+CjwhLS0gYiYjNDU7JiM0NTtoIC0tPgo8ZyBpZD0iZWRnZTgiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmImIzQ1OyYjNDU7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik05OSwtMjE1Ljg3Qzk5LC0xODguNTggOTksLTEzNS41MiA5OSwtMTA4LjE5Ii8+CjwvZz4KPCEtLSBoJiM0NTsmIzQ1O2ogLS0+CjxnIGlkPSJlZGdlMTAiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmgmIzQ1OyYjNDU7ajwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xMDUuNCwtNzIuNDFDMTA5LjY0LC02MS40MSAxMTUuMTksLTQ3LjAzIDExOS40NiwtMzUuOTYiLz4KPC9nPgo8IS0tIGQmIzQ1OyYjNDU7aCAtLT4KPGcgaWQ9ImVkZ2U5IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5kJiM0NTsmIzQ1O2g8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNNDguNTcsLTE0Ni4xNUM1OS40MywtMTM0LjI4IDc0LjU5LC0xMTcuNyA4NS40NSwtMTA1LjgyIi8+CjwvZz4KPC9nPgo8L3N2Zz4K"},40050:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMTg5cHQiIGhlaWdodD0iNDA0cHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMTg5LjAwIDQwNC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCA0MDApIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0id2hpdGUiIHN0cm9rZT0idHJhbnNwYXJlbnQiIHBvaW50cz0iLTQsNCAtNCwtNDAwIDE4NSwtNDAwIDE4NSw0IC00LDQiLz4KPCEtLSBhIC0tPgo8ZyBpZD0ibm9kZTEiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmE8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMTI2IiBjeT0iLTM3OCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTI2IiB5PSItMzc0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTMwNiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0zMDIuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmM8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmIzQ1O2MgLS0+CjxnIGlkPSJlZGdlMSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7JiM0NTtjPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTExOS42LC0zNjAuNDFDMTE1LjM2LC0zNDkuNDEgMTA5LjgxLC0zMzUuMDMgMTA1LjU0LC0zMjMuOTYiLz4KPC9nPgo8IS0tIGUgLS0+CjxnIGlkPSJub2RlMyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNTQiIGN5PSItMTYyIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNTQiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmU8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmIzQ1O2UgLS0+CjxnIGlkPSJlZGdlMiIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7JiM0NTtlPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTEyOS4xNCwtMzU5Ljg1QzEzMC45OCwtMzQ5LjQ5IDEzMy4yNywtMzM2LjAxIDEzNSwtMzI0IDE0Mi40OSwtMjcxLjkgMTQ5LjE4LC0yMTAuMDEgMTUyLjI0LC0xODAuNDMiLz4KPC9nPgo8IS0tIGkgLS0+CjxnIGlkPSJub2RlNCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIyNyIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjI3IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtpIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik04NC40MywtMjkwLjgzQzcyLjAyLC0yNzguNzcgNTQuMjcsLTI2MS41MSA0MS44LC0yNDkuMzgiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI5OSIgY3k9Ii0yMzQiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5iPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7JiM0NTtiIC0tPgo8ZyBpZD0iZWRnZTQiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyYjNDU7YjwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik05OSwtMjg3LjdDOTksLTI3Ni44NSA5OSwtMjYyLjkyIDk5LC0yNTIuMSIvPgo8L2c+CjwhLS0gaiAtLT4KPGcgaWQ9Im5vZGU2IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5qPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjEyNiIgY3k9Ii0xOCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTI2IiB5PSItMTQuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmo8L3RleHQ+CjwvZz4KPCEtLSBlJiM0NTsmIzQ1O2ogLS0+CjxnIGlkPSJlZGdlNSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZSYjNDU7JiM0NTtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTE1MC42MiwtMTQzLjg3QzE0NS4yNCwtMTE2LjU4IDEzNC43OCwtNjMuNTIgMTI5LjM5LC0zNi4xOSIvPgo8L2c+CjwhLS0gaCAtLT4KPGcgaWQ9Im5vZGU3IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5oPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSI5OSIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5oPC90ZXh0Pgo8L2c+CjwhLS0gZSYjNDU7JiM0NTtoIC0tPgo8ZyBpZD0iZWRnZTYiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmUmIzQ1OyYjNDU7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xNDIuMDcsLTE0NS44MUMxMzIuODQsLTEzNC4wNyAxMjAuMTMsLTExNy44OSAxMTAuOTEsLTEwNi4xNiIvPgo8L2c+CjwhLS0gZCAtLT4KPGcgaWQ9Im5vZGU4IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5kPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjM1IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMzUiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmQ8L3RleHQ+CjwvZz4KPCEtLSBpJiM0NTsmIzQ1O2QgLS0+CjxnIGlkPSJlZGdlNyIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aSYjNDU7JiM0NTtkPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTI4Ljk4LC0yMTUuN0MzMC4yMiwtMjA0Ljg1IDMxLjgxLC0xOTAuOTIgMzMuMDUsLTE4MC4xIi8+CjwvZz4KPCEtLSBiJiM0NTsmIzQ1O2ggLS0+CjxnIGlkPSJlZGdlOCIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YiYjNDU7JiM0NTtoPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTk5LC0yMTUuODdDOTksLTE4OC41OCA5OSwtMTM1LjUyIDk5LC0xMDguMTkiLz4KPC9nPgo8IS0tIGgmIzQ1OyYjNDU7aiAtLT4KPGcgaWQ9ImVkZ2UxMCIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aCYjNDU7JiM0NTtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTEwNS40LC03Mi40MUMxMDkuNjQsLTYxLjQxIDExNS4xOSwtNDcuMDMgMTE5LjQ2LC0zNS45NiIvPgo8L2c+CjwhLS0gZCYjNDU7JiM0NTtoIC0tPgo8ZyBpZD0iZWRnZTkiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmQmIzQ1OyYjNDU7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik00OC41NywtMTQ2LjE1QzU5LjQzLC0xMzQuMjggNzQuNTksLTExNy43IDg1LjQ1LC0xMDUuODIiLz4KPC9nPgo8L2c+Cjwvc3ZnPgo="},43770:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMjA2cHQiIGhlaWdodD0iMjYwcHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMjA2LjAwIDI2MC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCAyNTYpIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0iIzFiMWIxZCIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgcG9pbnRzPSItNCw0IC00LC0yNTYgMjAyLC0yNTYgMjAyLDQgLTQsNCIvPgo8IS0tIGEgLS0+CjxnIGlkPSJub2RlMSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMzUiIGN5PSItMjM0IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxMzUiIHk9Ii0yMzAuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9Ijk5IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5jPC90ZXh0Pgo8L2c+CjwhLS0gYSYjNDU7Jmd0O2MgLS0+CjxnIGlkPSJlZGdlMSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7Jmd0O2M8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTI2LjY1LC0yMTYuNzZDMTIyLjI5LC0yMDguMjggMTE2Ljg1LC0xOTcuNzEgMTExLjk2LC0xODguMiIvPgo8cG9seWdvbiBmaWxsPSJ0cmFuc3BhcmVudCIgc3Ryb2tlPSJ3aGl0ZSIgcG9pbnRzPSIxMTQuOTksLTE4Ni40NCAxMDcuMywtMTc5LjE1IDEwOC43NywtMTg5LjY0IDExNC45OSwtMTg2LjQ0Ii8+CjwvZz4KPCEtLSBlIC0tPgo8ZyBpZD0ibm9kZTMiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmU8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTcxIiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTcxIiB5PSItMTU4LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ZTwvdGV4dD4KPC9nPgo8IS0tIGEmIzQ1OyZndDtlIC0tPgo8ZyBpZD0iZWRnZTIiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmEmIzQ1OyZndDtlPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTE0My4zNSwtMjE2Ljc2QzE0Ny43MSwtMjA4LjI4IDE1My4xNSwtMTk3LjcxIDE1OC4wNCwtMTg4LjIiLz4KPHBvbHlnb24gZmlsbD0idHJhbnNwYXJlbnQiIHN0cm9rZT0id2hpdGUiIHBvaW50cz0iMTYxLjIzLC0xODkuNjQgMTYyLjcsLTE3OS4xNSAxNTUuMDEsLTE4Ni40NCAxNjEuMjMsLTE4OS42NCIvPgo8L2c+CjwhLS0gYiAtLT4KPGcgaWQ9Im5vZGU0IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5iPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9IjI3IiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIyNyIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyZndDtiIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyZndDtiPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTg0LjQzLC0xNDYuODNDNzQuMjUsLTEzNi45NCA2MC40OCwtMTIzLjU1IDQ4Ljk3LC0xMTIuMzYiLz4KPHBvbHlnb24gZmlsbD0idHJhbnNwYXJlbnQiIHN0cm9rZT0id2hpdGUiIHBvaW50cz0iNTEuNDEsLTEwOS44NSA0MS44LC0xMDUuMzggNDYuNTMsLTExNC44NyA1MS40MSwtMTA5Ljg1Ii8+CjwvZz4KPCEtLSBpIC0tPgo8ZyBpZD0ibm9kZTUiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmk8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iOTkiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItODYuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7Jmd0O2kgLS0+CjxnIGlkPSJlZGdlNCIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YyYjNDU7Jmd0O2k8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNOTksLTE0My43Qzk5LC0xMzUuOTggOTksLTEyNi43MSA5OSwtMTE4LjExIi8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjEwMi41LC0xMTguMSA5OSwtMTA4LjEgOTUuNSwtMTE4LjEgMTAyLjUsLTExOC4xIi8+CjwvZz4KPCEtLSBqIC0tPgo8ZyBpZD0ibm9kZTYiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmo8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTcxIiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNzEiIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmo8L3RleHQ+CjwvZz4KPCEtLSBlJiM0NTsmZ3Q7aiAtLT4KPGcgaWQ9ImVkZ2U1IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5lJiM0NTsmZ3Q7ajwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xNzEsLTE0My43QzE3MSwtMTM1Ljk4IDE3MSwtMTI2LjcxIDE3MSwtMTE4LjExIi8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjE3NC41LC0xMTguMSAxNzEsLTEwOC4xIDE2Ny41LC0xMTguMSAxNzQuNSwtMTE4LjEiLz4KPC9nPgo8IS0tIGggLS0+CjxnIGlkPSJub2RlNyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIyNyIgY3k9Ii0xOCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjciIHk9Ii0xNC4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmg8L3RleHQ+CjwvZz4KPCEtLSBiJiM0NTsmZ3Q7aCAtLT4KPGcgaWQ9ImVkZ2U2IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5iJiM0NTsmZ3Q7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0yNywtNzEuN0MyNywtNjMuOTggMjcsLTU0LjcxIDI3LC00Ni4xMSIvPgo8cG9seWdvbiBmaWxsPSJ0cmFuc3BhcmVudCIgc3Ryb2tlPSJ3aGl0ZSIgcG9pbnRzPSIzMC41LC00Ni4xIDI3LC0zNi4xIDIzLjUsLTQ2LjEgMzAuNSwtNDYuMSIvPgo8L2c+CjwhLS0gZCAtLT4KPGcgaWQ9Im5vZGU4IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5kPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9Ijk5IiBjeT0iLTE4IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSI5OSIgeT0iLTE0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ZDwvdGV4dD4KPC9nPgo8IS0tIGkmIzQ1OyZndDtkIC0tPgo8ZyBpZD0iZWRnZTciIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmkmIzQ1OyZndDtkPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTk5LC03MS43Qzk5LC02My45OCA5OSwtNTQuNzEgOTksLTQ2LjExIi8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjEwMi41LC00Ni4xIDk5LC0zNi4xIDk1LjUsLTQ2LjEgMTAyLjUsLTQ2LjEiLz4KPC9nPgo8L2c+Cjwvc3ZnPgo="},62843:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMjA2cHQiIGhlaWdodD0iMjYwcHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMjA2LjAwIDI2MC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCAyNTYpIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0id2hpdGUiIHN0cm9rZT0idHJhbnNwYXJlbnQiIHBvaW50cz0iLTQsNCAtNCwtMjU2IDIwMiwtMjU2IDIwMiw0IC00LDQiLz4KPCEtLSBhIC0tPgo8ZyBpZD0ibm9kZTEiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmE8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMTM1IiBjeT0iLTIzNCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTM1IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmM8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmZ3Q7YyAtLT4KPGcgaWQ9ImVkZ2UxIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmZ3Q7YzwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xMjYuNjUsLTIxNi43NkMxMjIuMjksLTIwOC4yOCAxMTYuODUsLTE5Ny43MSAxMTEuOTYsLTE4OC4yIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjExNC45OSwtMTg2LjQ0IDEwNy4zLC0xNzkuMTUgMTA4Ljc3LC0xODkuNjQgMTE0Ljk5LC0xODYuNDQiLz4KPC9nPgo8IS0tIGUgLS0+CjxnIGlkPSJub2RlMyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNzEiIGN5PSItMTYyIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNzEiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmU8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmZ3Q7ZSAtLT4KPGcgaWQ9ImVkZ2UyIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmZ3Q7ZTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xNDMuMzUsLTIxNi43NkMxNDcuNzEsLTIwOC4yOCAxNTMuMTUsLTE5Ny43MSAxNTguMDQsLTE4OC4yIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjE2MS4yMywtMTg5LjY0IDE2Mi43LC0xNzkuMTUgMTU1LjAxLC0xODYuNDQgMTYxLjIzLC0xODkuNjQiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIyNyIgY3k9Ii05MCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjciIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyZndDtiIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyZndDtiPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTg0LjQzLC0xNDYuODNDNzQuMjUsLTEzNi45NCA2MC40OCwtMTIzLjU1IDQ4Ljk3LC0xMTIuMzYiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iNTEuNDEsLTEwOS44NSA0MS44LC0xMDUuMzggNDYuNTMsLTExNC44NyA1MS40MSwtMTA5Ljg1Ii8+CjwvZz4KPCEtLSBpIC0tPgo8ZyBpZD0ibm9kZTUiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmk8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iOTkiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItODYuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmk8L3RleHQ+CjwvZz4KPCEtLSBjJiM0NTsmZ3Q7aSAtLT4KPGcgaWQ9ImVkZ2U0IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5jJiM0NTsmZ3Q7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik05OSwtMTQzLjdDOTksLTEzNS45OCA5OSwtMTI2LjcxIDk5LC0xMTguMTEiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iMTAyLjUsLTExOC4xIDk5LC0xMDguMSA5NS41LC0xMTguMSAxMDIuNSwtMTE4LjEiLz4KPC9nPgo8IS0tIGogLS0+CjxnIGlkPSJub2RlNiIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ajwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNzEiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjE3MSIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5qPC90ZXh0Pgo8L2c+CjwhLS0gZSYjNDU7Jmd0O2ogLS0+CjxnIGlkPSJlZGdlNSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZSYjNDU7Jmd0O2o8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNMTcxLC0xNDMuN0MxNzEsLTEzNS45OCAxNzEsLTEyNi43MSAxNzEsLTExOC4xMSIvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgcG9pbnRzPSIxNzQuNSwtMTE4LjEgMTcxLC0xMDguMSAxNjcuNSwtMTE4LjEgMTc0LjUsLTExOC4xIi8+CjwvZz4KPCEtLSBoIC0tPgo8ZyBpZD0ibm9kZTciIGNsYXNzPSJub2RlIj4KPHRpdGxlPmg8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMjciIGN5PSItMTgiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjI3IiB5PSItMTQuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmg8L3RleHQ+CjwvZz4KPCEtLSBiJiM0NTsmZ3Q7aCAtLT4KPGcgaWQ9ImVkZ2U2IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5iJiM0NTsmZ3Q7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0yNywtNzEuN0MyNywtNjMuOTggMjcsLTU0LjcxIDI3LC00Ni4xMSIvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgcG9pbnRzPSIzMC41LC00Ni4xIDI3LC0zNi4xIDIzLjUsLTQ2LjEgMzAuNSwtNDYuMSIvPgo8L2c+CjwhLS0gZCAtLT4KPGcgaWQ9Im5vZGU4IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5kPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTE4IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSI5OSIgeT0iLTE0LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5kPC90ZXh0Pgo8L2c+CjwhLS0gaSYjNDU7Jmd0O2QgLS0+CjxnIGlkPSJlZGdlNyIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+aSYjNDU7Jmd0O2Q8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNOTksLTcxLjdDOTksLTYzLjk4IDk5LC01NC43MSA5OSwtNDYuMTEiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iMTAyLjUsLTQ2LjEgOTksLTM2LjEgOTUuNSwtNDYuMSAxMDIuNSwtNDYuMSIvPgo8L2c+CjwvZz4KPC9zdmc+Cg=="},31350:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMjc4cHQiIGhlaWdodD0iMjYwcHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMjc4LjAwIDI2MC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCAyNTYpIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0iIzFiMWIxZCIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgcG9pbnRzPSItNCw0IC00LC0yNTYgMjc0LC0yNTYgMjc0LDQgLTQsNCIvPgo8IS0tIGEgLS0+CjxnIGlkPSJub2RlMSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIxMzUiIGN5PSItMjM0IiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxMzUiIHk9Ii0yMzAuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9Ijk5IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5jPC90ZXh0Pgo8L2c+CjwhLS0gYSYjNDU7Jmd0O2MgLS0+CjxnIGlkPSJlZGdlMSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YSYjNDU7Jmd0O2M8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNMTI2LjY1LC0yMTYuNzZDMTIyLjI5LC0yMDguMjggMTE2Ljg1LC0xOTcuNzEgMTExLjk2LC0xODguMiIvPgo8cG9seWdvbiBmaWxsPSJ0cmFuc3BhcmVudCIgc3Ryb2tlPSJ3aGl0ZSIgcG9pbnRzPSIxMTQuOTksLTE4Ni40NCAxMDcuMywtMTc5LjE1IDEwOC43NywtMTg5LjY0IDExNC45OSwtMTg2LjQ0Ii8+CjwvZz4KPCEtLSBlIC0tPgo8ZyBpZD0ibm9kZTMiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmU8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTcxIiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTcxIiB5PSItMTU4LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ZTwvdGV4dD4KPC9nPgo8IS0tIGEmIzQ1OyZndDtlIC0tPgo8ZyBpZD0iZWRnZTIiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmEmIzQ1OyZndDtlPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTE0My4zNSwtMjE2Ljc2QzE0Ny43MSwtMjA4LjI4IDE1My4xNSwtMTk3LjcxIDE1OC4wNCwtMTg4LjIiLz4KPHBvbHlnb24gZmlsbD0idHJhbnNwYXJlbnQiIHN0cm9rZT0id2hpdGUiIHBvaW50cz0iMTYxLjIzLC0xODkuNjQgMTYyLjcsLTE3OS4xNSAxNTUuMDEsLTE4Ni40NCAxNjEuMjMsLTE4OS42NCIvPgo8L2c+CjwhLS0gYiAtLT4KPGcgaWQ9Im5vZGU0IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5iPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgY3g9IjI3IiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIyNyIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyZndDtiIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyZndDtiPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTg0LjQzLC0xNDYuODNDNzQuMjUsLTEzNi45NCA2MC40OCwtMTIzLjU1IDQ4Ljk3LC0xMTIuMzYiLz4KPHBvbHlnb24gZmlsbD0idHJhbnNwYXJlbnQiIHN0cm9rZT0id2hpdGUiIHBvaW50cz0iNTEuNDEsLTEwOS44NSA0MS44LC0xMDUuMzggNDYuNTMsLTExNC44NyA1MS40MSwtMTA5Ljg1Ii8+CjwvZz4KPCEtLSBpIC0tPgo8ZyBpZD0ibm9kZTUiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmk8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iOTkiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItODYuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiIGZpbGw9IndoaXRlIj5pPC90ZXh0Pgo8L2c+CjwhLS0gYyYjNDU7Jmd0O2kgLS0+CjxnIGlkPSJlZGdlNCIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+YyYjNDU7Jmd0O2k8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBkPSJNOTksLTE0My43Qzk5LC0xMzUuOTggOTksLTEyNi43MSA5OSwtMTE4LjExIi8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjEwMi41LC0xMTguMSA5OSwtMTA4LjEgOTUuNSwtMTE4LjEgMTAyLjUsLTExOC4xIi8+CjwvZz4KPCEtLSBoIC0tPgo8ZyBpZD0ibm9kZTYiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmg8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBjeD0iMTcxIiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNzEiIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmg8L3RleHQ+CjwvZz4KPCEtLSBlJiM0NTsmZ3Q7aCAtLT4KPGcgaWQ9ImVkZ2U1IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5lJiM0NTsmZ3Q7aDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik0xNzEsLTE0My43QzE3MSwtMTM1Ljk4IDE3MSwtMTI2LjcxIDE3MSwtMTE4LjExIi8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjE3NC41LC0xMTguMSAxNzEsLTEwOC4xIDE2Ny41LC0xMTguMSAxNzQuNSwtMTE4LjEiLz4KPC9nPgo8IS0tIGogLS0+CjxnIGlkPSJub2RlNyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ajwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSIyNDMiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjI0MyIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIiBmaWxsPSJ3aGl0ZSI+ajwvdGV4dD4KPC9nPgo8IS0tIGUmIzQ1OyZndDtqIC0tPgo8ZyBpZD0iZWRnZTYiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmUmIzQ1OyZndDtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJ3aGl0ZSIgZD0iTTE4NS41NywtMTQ2LjgzQzE5NS43NSwtMTM2Ljk0IDIwOS41MiwtMTIzLjU1IDIyMS4wMywtMTEyLjM2Ii8+Cjxwb2x5Z29uIGZpbGw9InRyYW5zcGFyZW50IiBzdHJva2U9IndoaXRlIiBwb2ludHM9IjIyMy40NywtMTE0Ljg3IDIyOC4yLC0xMDUuMzggMjE4LjU5LC0xMDkuODUgMjIzLjQ3LC0xMTQuODciLz4KPC9nPgo8IS0tIGQgLS0+CjxnIGlkPSJub2RlOCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGN4PSI5OSIgY3k9Ii0xOCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNC4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCIgZmlsbD0id2hpdGUiPmQ8L3RleHQ+CjwvZz4KPCEtLSBpJiM0NTsmZ3Q7ZCAtLT4KPGcgaWQ9ImVkZ2U3IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5pJiM0NTsmZ3Q7ZDwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIGQ9Ik05OSwtNzEuN0M5OSwtNjMuOTggOTksLTU0LjcxIDk5LC00Ni4xMSIvPgo8cG9seWdvbiBmaWxsPSJ0cmFuc3BhcmVudCIgc3Ryb2tlPSJ3aGl0ZSIgcG9pbnRzPSIxMDIuNSwtNDYuMSA5OSwtMzYuMSA5NS41LC00Ni4xIDEwMi41LC00Ni4xIi8+CjwvZz4KPC9nPgo8L3N2Zz4K"},9248:(I,i,l)=>{l.d(i,{Z:()=>s});const s="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDMuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiAlMyBQYWdlczogMSAtLT4KPHN2ZyB3aWR0aD0iMjc4cHQiIGhlaWdodD0iMjYwcHQiCiB2aWV3Qm94PSIwLjAwIDAuMDAgMjc4LjAwIDI2MC4wMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxnIGlkPSJncmFwaDAiIGNsYXNzPSJncmFwaCIgdHJhbnNmb3JtPSJzY2FsZSgxIDEpIHJvdGF0ZSgwKSB0cmFuc2xhdGUoNCAyNTYpIj4KPHRpdGxlPiUzPC90aXRsZT4KPHBvbHlnb24gZmlsbD0id2hpdGUiIHN0cm9rZT0idHJhbnNwYXJlbnQiIHBvaW50cz0iLTQsNCAtNCwtMjU2IDI3NCwtMjU2IDI3NCw0IC00LDQiLz4KPCEtLSBhIC0tPgo8ZyBpZD0ibm9kZTEiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmE8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMTM1IiBjeT0iLTIzNCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTM1IiB5PSItMjMwLjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5hPC90ZXh0Pgo8L2c+CjwhLS0gYyAtLT4KPGcgaWQ9Im5vZGUyIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5jPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9Ijk5IiBjeT0iLTE2MiIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmM8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmZ3Q7YyAtLT4KPGcgaWQ9ImVkZ2UxIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmZ3Q7YzwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xMjYuNjUsLTIxNi43NkMxMjIuMjksLTIwOC4yOCAxMTYuODUsLTE5Ny43MSAxMTEuOTYsLTE4OC4yIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjExNC45OSwtMTg2LjQ0IDEwNy4zLC0xNzkuMTUgMTA4Ljc3LC0xODkuNjQgMTE0Ljk5LC0xODYuNDQiLz4KPC9nPgo8IS0tIGUgLS0+CjxnIGlkPSJub2RlMyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNzEiIGN5PSItMTYyIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNzEiIHk9Ii0xNTguMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmU8L3RleHQ+CjwvZz4KPCEtLSBhJiM0NTsmZ3Q7ZSAtLT4KPGcgaWQ9ImVkZ2UyIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5hJiM0NTsmZ3Q7ZTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xNDMuMzUsLTIxNi43NkMxNDcuNzEsLTIwOC4yOCAxNTMuMTUsLTE5Ny43MSAxNTguMDQsLTE4OC4yIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjE2MS4yMywtMTg5LjY0IDE2Mi43LC0xNzkuMTUgMTU1LjAxLC0xODYuNDQgMTYxLjIzLC0xODkuNjQiLz4KPC9nPgo8IS0tIGIgLS0+CjxnIGlkPSJub2RlNCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+YjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIyNyIgY3k9Ii05MCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjciIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCI+YjwvdGV4dD4KPC9nPgo8IS0tIGMmIzQ1OyZndDtiIC0tPgo8ZyBpZD0iZWRnZTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmMmIzQ1OyZndDtiPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTg0LjQzLC0xNDYuODNDNzQuMjUsLTEzNi45NCA2MC40OCwtMTIzLjU1IDQ4Ljk3LC0xMTIuMzYiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iNTEuNDEsLTEwOS44NSA0MS44LC0xMDUuMzggNDYuNTMsLTExNC44NyA1MS40MSwtMTA5Ljg1Ii8+CjwvZz4KPCEtLSBpIC0tPgo8ZyBpZD0ibm9kZTUiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmk8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iOTkiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9Ijk5IiB5PSItODYuMyIgZm9udC1mYW1pbHk9IidDYXNjYWRpYSBDb2RlIFBMJywgJ0pldEJyYWlucyBNb25vJywgJ0lvc2V2a2EnLCAnRmlyYSBDb2RlJywgJ0hhY2snLCBtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTQuMDAiPmk8L3RleHQ+CjwvZz4KPCEtLSBjJiM0NTsmZ3Q7aSAtLT4KPGcgaWQ9ImVkZ2U0IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5jJiM0NTsmZ3Q7aTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik05OSwtMTQzLjdDOTksLTEzNS45OCA5OSwtMTI2LjcxIDk5LC0xMTguMTEiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iMTAyLjUsLTExOC4xIDk5LC0xMDguMSA5NS41LC0xMTguMSAxMDIuNSwtMTE4LjEiLz4KPC9nPgo8IS0tIGggLS0+CjxnIGlkPSJub2RlNiIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+aDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNzEiIGN5PSItOTAiIHJ4PSIyNyIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjE3MSIgeT0iLTg2LjMiIGZvbnQtZmFtaWx5PSInQ2FzY2FkaWEgQ29kZSBQTCcsICdKZXRCcmFpbnMgTW9ubycsICdJb3NldmthJywgJ0ZpcmEgQ29kZScsICdIYWNrJywgbW9ub3NwYWNlIiBmb250LXNpemU9IjE0LjAwIj5oPC90ZXh0Pgo8L2c+CjwhLS0gZSYjNDU7Jmd0O2ggLS0+CjxnIGlkPSJlZGdlNSIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZSYjNDU7Jmd0O2g8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNMTcxLC0xNDMuN0MxNzEsLTEzNS45OCAxNzEsLTEyNi43MSAxNzEsLTExOC4xMSIvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgcG9pbnRzPSIxNzQuNSwtMTE4LjEgMTcxLC0xMDguMSAxNjcuNSwtMTE4LjEgMTc0LjUsLTExOC4xIi8+CjwvZz4KPCEtLSBqIC0tPgo8ZyBpZD0ibm9kZTciIGNsYXNzPSJub2RlIj4KPHRpdGxlPmo8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMjQzIiBjeT0iLTkwIiByeD0iMjciIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIyNDMiIHk9Ii04Ni4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCI+ajwvdGV4dD4KPC9nPgo8IS0tIGUmIzQ1OyZndDtqIC0tPgo8ZyBpZD0iZWRnZTYiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmUmIzQ1OyZndDtqPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTE4NS41NywtMTQ2LjgzQzE5NS43NSwtMTM2Ljk0IDIwOS41MiwtMTIzLjU1IDIyMS4wMywtMTEyLjM2Ii8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjIyMy40NywtMTE0Ljg3IDIyOC4yLC0xMDUuMzggMjE4LjU5LC0xMDkuODUgMjIzLjQ3LC0xMTQuODciLz4KPC9nPgo8IS0tIGQgLS0+CjxnIGlkPSJub2RlOCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI5OSIgY3k9Ii0xOCIgcng9IjI3IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iOTkiIHk9Ii0xNC4zIiBmb250LWZhbWlseT0iJ0Nhc2NhZGlhIENvZGUgUEwnLCAnSmV0QnJhaW5zIE1vbm8nLCAnSW9zZXZrYScsICdGaXJhIENvZGUnLCAnSGFjaycsIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxNC4wMCI+ZDwvdGV4dD4KPC9nPgo8IS0tIGkmIzQ1OyZndDtkIC0tPgo8ZyBpZD0iZWRnZTciIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmkmIzQ1OyZndDtkPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTk5LC03MS43Qzk5LC02My45OCA5OSwtNTQuNzEgOTksLTQ2LjExIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjEwMi41LC00Ni4xIDk5LC0zNi4xIDk1LjUsLTQ2LjEgMTAyLjUsLTQ2LjEiLz4KPC9nPgo8L2c+Cjwvc3ZnPgo="},11151:(I,i,l)=>{l.d(i,{Z:()=>c,a:()=>g});var s=l(67294);const m={},a=s.createContext(m);function g(I){const i=s.useContext(a);return s.useMemo((function(){return"function"==typeof I?I(i):{...i,...I}}),[i,I])}function c(I){let i;return i=I.disableParentContext?"function"==typeof I.components?I.components(m):I.components||m:g(I.components),s.createElement(a.Provider,{value:i},I.children)}}}]); \ No newline at end of file diff --git a/assets/js/3adcbc3a.481c535c.js b/assets/js/3adcbc3a.481c535c.js new file mode 100644 index 0000000..7f13c48 --- /dev/null +++ b/assets/js/3adcbc3a.481c535c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[5701],{62535:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>h,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var t=n(85893),a=n(11151);const i={id:"bf",slug:"/paths/bf-to-astar/bf",title:"BF",description:"Solving the shortest path problem with a na\xefve approach that turns into\nsomething.\n",tags:["cpp","brute force","bellman ford","dynamic programming"],last_update:{date:new Date("2024-01-01T00:00:00.000Z")}},r=void 0,l={id:"paths/2024-01-01-bf-to-astar/bf",title:"BF",description:"Solving the shortest path problem with a na\xefve approach that turns into\nsomething.\n",source:"@site/algorithms/11-paths/2024-01-01-bf-to-astar/01-bf.md",sourceDirName:"11-paths/2024-01-01-bf-to-astar",slug:"/paths/bf-to-astar/bf",permalink:"/algorithms/paths/bf-to-astar/bf",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/11-paths/2024-01-01-bf-to-astar/01-bf.md",tags:[{label:"cpp",permalink:"/algorithms/tags/cpp"},{label:"brute force",permalink:"/algorithms/tags/brute-force"},{label:"bellman ford",permalink:"/algorithms/tags/bellman-ford"},{label:"dynamic programming",permalink:"/algorithms/tags/dynamic-programming"}],version:"current",lastUpdatedAt:1704067200,formattedLastUpdatedAt:"Jan 1, 2024",sidebarPosition:1,frontMatter:{id:"bf",slug:"/paths/bf-to-astar/bf",title:"BF",description:"Solving the shortest path problem with a na\xefve approach that turns into\nsomething.\n",tags:["cpp","brute force","bellman ford","dynamic programming"],last_update:{date:"2024-01-01T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"From BF to A*",permalink:"/algorithms/paths/bf-to-astar"},next:{title:"Dijkstra's algorithm",permalink:"/algorithms/paths/bf-to-astar/dijkstra"}},h={},c=[{value:"Basic idea",id:"basic-idea",level:2},{value:"Na\xefve approach",id:"na\xefve-approach",level:2},{value:"Correctness",id:"correctness",level:3},{value:"Fixing the infinite loop",id:"fixing-the-infinite-loop",level:3},{value:"Bellman-Ford",id:"bellman-ford",level:2},{value:"On the Bellman-Ford",id:"on-the-bellman-ford",level:3},{value:"Time complexity",id:"time-complexity",level:2},{value:"Small refactor",id:"small-refactor",level:2}];function o(e){const s={a:"a",admonition:"admonition",annotation:"annotation",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",hr:"hr",li:"li",math:"math",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",msub:"msub",ol:"ol",p:"p",pre:"pre",section:"section",semantics:"semantics",span:"span",strong:"strong",sup:"sup",...(0,a.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h2,{id:"basic-idea",children:"Basic idea"}),"\n",(0,t.jsxs)(s.p,{children:["We will ",(0,t.jsx)(s.em,{children:"ease in"})," with our own algorithm to find the shortest path. We will\nstart by thinking about the ways we can achieve that. If we didn't have the ",(0,t.jsx)(s.code,{children:"*"}),"\ncells, we could've easily run a BFS",(0,t.jsx)(s.sup,{children:(0,t.jsx)(s.a,{href:"#user-content-fn-1",id:"user-content-fnref-1","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"1"})})," and be done with it. Maybe it is a good\nplace to start, or isn't, there is only one way to find out though."]}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.em,{children:"How does the BFS work?"})," We know the vertex where we start and we know the\nvertex we want to find the shortest path to. Given this knowledge we\nincrementally visit all of our neighbours and we do that over and over until the\ndestination is found",(0,t.jsx)(s.sup,{children:(0,t.jsx)(s.a,{href:"#user-content-fn-2",id:"user-content-fnref-2","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"2"})}),". Could we leverage this somehow?"]}),"\n",(0,t.jsx)(s.h2,{id:"na\xefve-approach",children:"Na\xefve approach"}),"\n",(0,t.jsxs)(s.p,{children:["Well, we could probably start with all vertices being ",(0,t.jsx)(s.em,{children:"unreachable"})," (having the\nhighest possible price) and try to improve what we've gotten so far until there\nare no improvements. That sounds fine, we shall implement this. Since we are\ngoing on repeat, we will name this function ",(0,t.jsx)(s.code,{children:"bf()"})," as in ",(0,t.jsx)(s.em,{children:"brute-force"}),", cause it\nis trying to find it the hard way:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-cpp",children:"const static std::vector DIRECTIONS =\n std::vector{std::make_pair(0, 1), std::make_pair(0, -1),\n std::make_pair(1, 0), std::make_pair(-1, 0)};\n\nauto bf(const graph& g, const vertex_t& source, const vertex_t& destination)\n -> int {\n // \u2039source\u203a must be within the bounds\n assert(g.has(source));\n\n // \u2039destination\u203a must be within the bounds\n assert(g.has(destination));\n\n // we need to initialize the distances\n std::vector> distances(\n g.height(), std::vector(g.width(), graph::unreachable()));\n\n // \u2039source\u203a destination denotes the beginning where the cost is 0\n auto [sx, sy] = source;\n distances[sy][sx] = 0;\n\n // now we need to improve the paths as long as possible\n bool improvement_found;\n do {\n // reset the flag at the beginning\n improvement_found = false;\n\n // go through all of the vertices\n for (int y = 0; y < g.height(); ++y) {\n for (int x = 0; x < g.width(); ++x) {\n // skip the cells we cannot reach\n if (distances[y][x] == graph::unreachable()) {\n continue;\n }\n\n // go through the neighbours\n auto u = std::make_pair(x, y);\n for (const auto& [dx, dy] : DIRECTIONS) {\n auto v = std::make_pair(x + dx, y + dy);\n auto cost = g.cost(u, v);\n\n // if we can move to the cell and it's better, relax\xb9 it\n if (cost != graph::unreachable() &&\n distances[y][x] + cost < distances[y + dy][x + dx]) {\n distances[y + dy][x + dx] = distances[y][x] + cost;\n improvement_found = true;\n }\n }\n }\n }\n } while (improvement_found);\n\n return distances[destination.second][destination.first];\n}\n"})}),"\n",(0,t.jsxs)(s.admonition,{title:"Relaxation",type:"info",children:[(0,t.jsxs)(s.p,{children:["I have made a brief mention of the relaxation in the comment in the code. You've\nbeen probably thought that ",(0,t.jsx)(s.strong,{children:"relaxation of an edge"})," means that you found\na better solution to the problem."]}),(0,t.jsxs)(s.p,{children:["In general it is an approximation technique that ",(0,t.jsx)(s.em,{children:"reduces"})," the problem of\nfinding the path ",(0,t.jsx)(s.code,{children:"u \u2192 x1 \u2192 \u2026 \u2192 xn \u2192 v"})," to subproblems\n",(0,t.jsx)(s.code,{children:"u \u2192 x1, x1 \u2192 x2, \u2026, xn \u2192 v"})," such that the sum of the costs of each step is\n",(0,t.jsx)(s.strong,{children:"minimal"}),"."]})]}),"\n",(0,t.jsx)(s.h3,{id:"correctness",children:"Correctness"}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.em,{children:"Is our solution correct?"})," It appears to be correct\u2026 We have rather complicated\nmap and our algorithm has finished in an instant with the following output:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"Normal cost: 1\nVortex cost: 5\nGraph:\n#############\n#..#..*.*.**#\n##***.....**#\n#..########.#\n#...###...#.#\n#..#...##.#.#\n#..#.*.#..#.#\n#D...#....#.#\n########*.*.#\n#S..........#\n#############\nCost: 22\n"})}),"\n",(0,t.jsxs)(s.p,{children:["If you have a better look at the map, you will realize that the cost ",(0,t.jsx)(s.code,{children:"22"})," is the\none path skipping the ",(0,t.jsx)(s.code,{children:"*"})," cells, since they cost more than going around."]}),"\n",(0,t.jsxs)(s.p,{children:["We can play around a bit with it. The ",(0,t.jsx)(s.code,{children:"*"})," cells can be even vortices that pull\nyou in with a negative price and let you ",(0,t.jsx)(s.em,{children:"propel"})," yourself out ","\ud83d\ude09"," Let's\nchange their cost to ",(0,t.jsx)(s.code,{children:"-1"})," then. Let's check what's the fastest path to the cell."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"Normal cost: 1\nVortex cost: -1\nGraph:\n#############\n#..#..*.*.**#\n##***.....**#\n#..########.#\n#...###...#.#\n#..#...##.#.#\n#..#.*.#..#.#\n#D...#....#.#\n########*.*.#\n#S..........#\n#############\n"})}),"\n",(0,t.jsxs)(s.p,{children:["And we're somehow stuck\u2026 The issue comes from the fact that ",(0,t.jsx)(s.em,{children:"spinning around"})," in\nthe vortices allows us to lower the cost infinitely. That's why after each\niteration there is still a possibility to lower the cost, hence the algorithm\ndoesn't finish. ",(0,t.jsx)(s.em,{children:"What can we do about this?"})]}),"\n",(0,t.jsx)(s.admonition,{type:"tip",children:(0,t.jsx)(s.p,{children:"This algorithm is correct as long as there are no negative loops, i.e. ways how\nto lower the cost infinitely. Therefore we can also just lay a precondition that\nrequires no negative loops to be present."})}),"\n",(0,t.jsx)(s.h3,{id:"fixing-the-infinite-loop",children:"Fixing the infinite loop"}),"\n",(0,t.jsxs)(s.p,{children:["Our issue lies in the fact that we can endlessly lower the cost. Such thing must\nsurely happen in some kind of a loop. We could probably track the relaxations\nand once we spot repeating patterns, we know we can safely terminate with ",(0,t.jsx)(s.em,{children:"some"}),"\nresults at least."]}),"\n",(0,t.jsxs)(s.p,{children:["This approach will not even work on our 2D map, let alone any graph. Problem is\nthat the ",(0,t.jsx)(s.em,{children:"negative loops"})," lower the cost in ",(0,t.jsx)(s.strong,{children:"each"})," iteration and that results\nin lowering of the costs to the cells that are reachable from the said loops.\nThat's why this problem is relatively hard to tackle, it's not that easy to spot\nthe repeating patterns algorithmically."]}),"\n",(0,t.jsx)(s.p,{children:"On the other hand, we can approach this from the different perspective. Let's\nassume the worst-case scenario (generalized for any graph):"}),"\n",(0,t.jsxs)(s.blockquote,{children:["\n",(0,t.jsxs)(s.p,{children:["Let ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsxs)(s.msub,{children:[(0,t.jsx)(s.mi,{children:"K"}),(0,t.jsx)(s.mi,{children:"n"})]})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"K_n"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.8333em",verticalAlign:"-0.15em"}}),(0,t.jsxs)(s.span,{className:"mord",children:[(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.07153em"},children:"K"}),(0,t.jsx)(s.span,{className:"msupsub",children:(0,t.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,t.jsxs)(s.span,{className:"vlist-r",children:[(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.1514em"},children:(0,t.jsxs)(s.span,{style:{top:"-2.55em",marginLeft:"-0.0715em",marginRight:"0.05em"},children:[(0,t.jsx)(s.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(s.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(s.span,{className:"mord mathnormal mtight",children:"n"})})]})}),(0,t.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,t.jsx)(s.span,{className:"vlist-r",children:(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.15em"},children:(0,t.jsx)(s.span,{})})})]})})]})]})})]})," be complete graph. Let ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsx)(s.mi,{children:"P"})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"P"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.6833em"}}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"})]})})]})," be the shortest path from ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsxs)(s.msub,{children:[(0,t.jsx)(s.mi,{children:"v"}),(0,t.jsx)(s.mn,{children:"1"})]})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"v_1"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.5806em",verticalAlign:"-0.15em"}}),(0,t.jsxs)(s.span,{className:"mord",children:[(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"v"}),(0,t.jsx)(s.span,{className:"msupsub",children:(0,t.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,t.jsxs)(s.span,{className:"vlist-r",children:[(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.3011em"},children:(0,t.jsxs)(s.span,{style:{top:"-2.55em",marginLeft:"-0.0359em",marginRight:"0.05em"},children:[(0,t.jsx)(s.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(s.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(s.span,{className:"mord mtight",children:"1"})})]})}),(0,t.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,t.jsx)(s.span,{className:"vlist-r",children:(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.15em"},children:(0,t.jsx)(s.span,{})})})]})})]})]})})]})," to ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsxs)(s.msub,{children:[(0,t.jsx)(s.mi,{children:"v"}),(0,t.jsx)(s.mi,{children:"n"})]})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"v_n"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.5806em",verticalAlign:"-0.15em"}}),(0,t.jsxs)(s.span,{className:"mord",children:[(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"v"}),(0,t.jsx)(s.span,{className:"msupsub",children:(0,t.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,t.jsxs)(s.span,{className:"vlist-r",children:[(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.1514em"},children:(0,t.jsxs)(s.span,{style:{top:"-2.55em",marginLeft:"-0.0359em",marginRight:"0.05em"},children:[(0,t.jsx)(s.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(s.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(s.span,{className:"mord mathnormal mtight",children:"n"})})]})}),(0,t.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,t.jsx)(s.span,{className:"vlist-r",children:(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.15em"},children:(0,t.jsx)(s.span,{})})})]})})]})]})})]}),"\nsuch that ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsx)(s.mi,{children:"P"})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"P"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.6833em"}}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"})]})})]})," has ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsxs)(s.mrow,{children:[(0,t.jsx)(s.mi,{children:"n"}),(0,t.jsx)(s.mo,{children:"\u2212"}),(0,t.jsx)(s.mn,{children:"1"})]}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"n - 1"})]})})}),(0,t.jsxs)(s.span,{className:"katex-html","aria-hidden":"true",children:[(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.6667em",verticalAlign:"-0.0833em"}}),(0,t.jsx)(s.span,{className:"mord mathnormal",children:"n"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,t.jsx)(s.span,{className:"mbin",children:"\u2212"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.6444em"}}),(0,t.jsx)(s.span,{className:"mord",children:"1"})]})]})]})," edges, i.e. the shortest path between the two chosen\nvertices visits all vertices (not necessarily in order) and has the lowest\ncost."]}),"\n",(0,t.jsxs)(s.p,{children:["In such scenario assume the worst-case ordering of the relaxations (only one\n",(0,t.jsx)(s.em,{children:"helpful"})," relaxation per iteration). In this case, in each iteration we find\nthe next edge on our path ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsx)(s.mi,{children:"P"})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"P"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.6833em"}}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"})]})})]})," as the last. This means that we need\n",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsxs)(s.mrow,{children:[(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mi,{children:"V"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mo,{children:"\u2212"}),(0,t.jsx)(s.mn,{children:"1"})]}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"\\vert V \\vert - 1"})]})})}),(0,t.jsxs)(s.span,{className:"katex-html","aria-hidden":"true",children:[(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,t.jsx)(s.span,{className:"mbin",children:"\u2212"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.6444em"}}),(0,t.jsx)(s.span,{className:"mord",children:"1"})]})]})]})," iterations to find the shortest path ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsx)(s.mi,{children:"P"})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"P"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.6833em"}}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"})]})})]}),"."]}),"\n",(0,t.jsxs)(s.p,{children:["Because we have laid ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsx)(s.mi,{children:"P"})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"P"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.6833em"}}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"})]})})]})," as the shortest path from ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsxs)(s.msub,{children:[(0,t.jsx)(s.mi,{children:"v"}),(0,t.jsx)(s.mn,{children:"1"})]})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"v_1"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.5806em",verticalAlign:"-0.15em"}}),(0,t.jsxs)(s.span,{className:"mord",children:[(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"v"}),(0,t.jsx)(s.span,{className:"msupsub",children:(0,t.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,t.jsxs)(s.span,{className:"vlist-r",children:[(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.3011em"},children:(0,t.jsxs)(s.span,{style:{top:"-2.55em",marginLeft:"-0.0359em",marginRight:"0.05em"},children:[(0,t.jsx)(s.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(s.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(s.span,{className:"mord mtight",children:"1"})})]})}),(0,t.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,t.jsx)(s.span,{className:"vlist-r",children:(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.15em"},children:(0,t.jsx)(s.span,{})})})]})})]})]})})]})," to ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsxs)(s.msub,{children:[(0,t.jsx)(s.mi,{children:"v"}),(0,t.jsx)(s.mi,{children:"n"})]})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"v_n"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.5806em",verticalAlign:"-0.15em"}}),(0,t.jsxs)(s.span,{className:"mord",children:[(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"v"}),(0,t.jsx)(s.span,{className:"msupsub",children:(0,t.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,t.jsxs)(s.span,{className:"vlist-r",children:[(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.1514em"},children:(0,t.jsxs)(s.span,{style:{top:"-2.55em",marginLeft:"-0.0359em",marginRight:"0.05em"},children:[(0,t.jsx)(s.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(s.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(s.span,{className:"mord mathnormal mtight",children:"n"})})]})}),(0,t.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,t.jsx)(s.span,{className:"vlist-r",children:(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.15em"},children:(0,t.jsx)(s.span,{})})})]})})]})]})})]})," and it\nvisits all vertices, its prefixes are the shortest paths from ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsx)(s.mrow,{children:(0,t.jsxs)(s.msub,{children:[(0,t.jsx)(s.mi,{children:"v"}),(0,t.jsx)(s.mn,{children:"1"})]})}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"v_1"})]})})}),(0,t.jsx)(s.span,{className:"katex-html","aria-hidden":"true",children:(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.5806em",verticalAlign:"-0.15em"}}),(0,t.jsxs)(s.span,{className:"mord",children:[(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"v"}),(0,t.jsx)(s.span,{className:"msupsub",children:(0,t.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,t.jsxs)(s.span,{className:"vlist-r",children:[(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.3011em"},children:(0,t.jsxs)(s.span,{style:{top:"-2.55em",marginLeft:"-0.0359em",marginRight:"0.05em"},children:[(0,t.jsx)(s.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(s.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(s.span,{className:"mord mtight",children:"1"})})]})}),(0,t.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,t.jsx)(s.span,{className:"vlist-r",children:(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.15em"},children:(0,t.jsx)(s.span,{})})})]})})]})]})})]})," to any\nother vertex in our graph."]}),"\n",(0,t.jsxs)(s.p,{children:["Therefore, we can safely assume that any relaxation after ",(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsxs)(s.mrow,{children:[(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mi,{children:"V"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mo,{children:"\u2212"}),(0,t.jsx)(s.mn,{children:"1"})]}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"\\vert V \\vert - 1"})]})})}),(0,t.jsxs)(s.span,{className:"katex-html","aria-hidden":"true",children:[(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,t.jsx)(s.span,{className:"mbin",children:"\u2212"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"0.6444em"}}),(0,t.jsx)(s.span,{className:"mord",children:"1"})]})]})]}),"\niterations, is the effect of a negative loop in the graph."]}),"\n"]}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.em,{children:"How can we leverage this?"})," We will go through the edges only as many times as\ncells we have. Let's adjust the code to fix the looping:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-cpp",children:"auto bf_finite(const graph& g, const vertex_t& source,\n const vertex_t& destination) -> int {\n // \u2039source\u203a must be within the bounds\n assert(g.has(source));\n\n // \u2039destination\u203a must be within the bounds\n assert(g.has(destination));\n\n // we need to initialize the distances\n std::vector> distances(\n g.height(), std::vector(g.width(), graph::unreachable()));\n\n // \u2039source\u203a destination denotes the beginning where the cost is 0\n auto [sx, sy] = source;\n distances[sy][sx] = 0;\n\n // now we only iterate as many times as cells that we have\n for (int i = g.height() * g.width(); i > 0; --i) {\n // go through all of the vertices\n for (int y = 0; y < g.height(); ++y) {\n for (int x = 0; x < g.width(); ++x) {\n // skip the cells we cannot reach\n if (distances[y][x] == graph::unreachable()) {\n continue;\n }\n\n // go through the neighbours\n auto u = std::make_pair(x, y);\n for (const auto& [dx, dy] : DIRECTIONS) {\n auto v = std::make_pair(x + dx, y + dy);\n auto cost = g.cost(u, v);\n\n // if we can move to the cell and it's better, relax\xb9 it\n if (cost != graph::unreachable() &&\n distances[y][x] + cost < distances[y + dy][x + dx]) {\n distances[y + dy][x + dx] = distances[y][x] + cost;\n }\n }\n }\n }\n }\n\n return distances[destination.second][destination.first];\n}\n"})}),"\n",(0,t.jsx)(s.p,{children:"And we get the following result:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"Normal cost: 1\nVortex cost: -1\nGraph:\n#############\n#..#..*.*.**#\n##***.....**#\n#..########.#\n#...###...#.#\n#..#...##.#.#\n#..#.*.#..#.#\n#D...#....#.#\n########*.*.#\n#S..........#\n#############\nCost: -236\n"})}),"\n",(0,t.jsxs)(s.p,{children:["The negative cost means that there is a way to ",(0,t.jsx)(s.em,{children:"propel"})," ourselves via some\nvortices. Let's adjust the cost of ",(0,t.jsx)(s.em,{children:"vortices"})," back to the original ",(0,t.jsx)(s.code,{children:"5"})," and check\nwhether our modified algorithm works as it did before. And it surely does yield\nthe ",(0,t.jsx)(s.code,{children:"22"})," as before."]}),"\n",(0,t.jsxs)(s.admonition,{title:"Refactoring",type:"tip",children:[(0,t.jsxs)(s.p,{children:["You can definitely notice some ",(0,t.jsx)(s.em,{children:"deep nesting"})," in our code, to counter this\nphenomenon I will convert the looping over ",(0,t.jsx)(s.code,{children:"x"})," and ",(0,t.jsx)(s.code,{children:"y"})," to one variable that can\nbe decomposed to ",(0,t.jsx)(s.code,{children:"x"})," and ",(0,t.jsx)(s.code,{children:"y"}),". It is a very common practice when working with 2D\narrays/lists to represent them as 1D. In our case:"]}),(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"i : 0 \u2192 width * height - 1\nx = i % width\ny = i / width\n"})})]}),"\n",(0,t.jsx)(s.h2,{id:"bellman-ford",children:"Bellman-Ford"}),"\n",(0,t.jsxs)(s.p,{children:["If you have ever attended any Algorithms course that had path-finding in its\nsyllabus, you probably feel like you've seen the algorithm above before",(0,t.jsx)(s.sup,{children:(0,t.jsx)(s.a,{href:"#user-content-fn-3",id:"user-content-fnref-3","data-footnote-ref":!0,"aria-describedby":"footnote-label",children:"3"})}),"\u2026 And\nyes, the first algorithm I have proposed is a very dumb version of the\n",(0,t.jsx)(s.em,{children:"Bellman-Ford"})," algorithm, it's dumb, because it loops ","\ud83d\ude09"," After our \u201clooping\u201d\nprevention we got to the point that is almost the ",(0,t.jsx)(s.em,{children:"Bellman-Ford"})," with the one\nexception that it doesn't report whether there are any negative cycles, it just\nends."]}),"\n",(0,t.jsx)(s.p,{children:"Let's have a look at a proper implementation of the Bellman-Ford algorithm:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-cpp",children:"auto bellman_ford(const graph& g, const vertex_t& source)\n -> std::vector> {\n // \u2039source\u203a must be within the bounds\n assert(g.has(source));\n\n // we need to initialize the distances\n std::vector> distances(\n g.height(), std::vector(g.width(), graph::unreachable()));\n\n // \u2039source\u203a destination denotes the beginning where the cost is 0\n auto [sx, sy] = source;\n distances[sy][sx] = 0;\n\n // now we only iterate as many times as cells that we have\n for (int i = g.height() * g.width(); i > 0; --i) {\n // go through all of the vertices\n for (int v = g.height() * g.width() - 1; v >= 0; --v) {\n int y = v / g.width();\n int x = v % g.width();\n\n // skip the cells we cannot reach\n if (distances[y][x] == graph::unreachable()) {\n continue;\n }\n\n // go through the neighbours\n auto u = std::make_pair(x, y);\n for (const auto& [dx, dy] : DIRECTIONS) {\n auto v = std::make_pair(x + dx, y + dy);\n auto cost = g.cost(u, v);\n\n // if we can move to the cell and it's better, relax\xb9 it\n if (cost != graph::unreachable() &&\n distances[y][x] + cost < distances[y + dy][x + dx]) {\n distances[y + dy][x + dx] = distances[y][x] + cost;\n }\n }\n }\n }\n\n // now we check for the negative loops\n bool relaxed = false;\n for (int v = g.height() * g.width() - 1; !relaxed && v >= 0; --v) {\n int y = v / g.width();\n int x = v % g.width();\n\n // skip the cells we cannot reach\n if (distances[y][x] == graph::unreachable()) {\n continue;\n }\n\n // go through the neighbours\n auto u = std::make_pair(x, y);\n for (const auto& [dx, dy] : DIRECTIONS) {\n auto v = std::make_pair(x + dx, y + dy);\n auto cost = g.cost(u, v);\n\n // if we can move to the cell and it's better, relax\xb9 it\n if (cost != graph::unreachable() &&\n distances[y][x] + cost < distances[y + dy][x + dx]) {\n relaxed = true;\n std::cerr << \"Found a negative loop\\n\";\n break;\n }\n }\n }\n\n return distances;\n}\n"})}),"\n",(0,t.jsx)(s.p,{children:"And if we run it with our negative cost of entering vortices:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"[Bellman-Ford] Found a negative loop\n[Bellman-Ford] Cost: -240\n"})}),"\n",(0,t.jsx)(s.h3,{id:"on-the-bellman-ford",children:"On the Bellman-Ford"}),"\n",(0,t.jsx)(s.p,{children:"You might be surprised that we have managed to iterate from a brute-force method\nthat mindlessly tries to find a better path until there are no better paths left\nall the way to the Bellman-Ford algorithm."}),"\n",(0,t.jsxs)(s.p,{children:["I always say that Bellman-Ford is a ",(0,t.jsx)(s.em,{children:"smart"})," brute-force. BF is also an algorithm\nthat leverages ",(0,t.jsx)(s.em,{children:"dynamic programming"}),". You might wonder how can it utilize DP if\nit is \u201ctechnically\u201d a brute-force technique. Table with the shortest distances\nis the thing that makes it DP."]}),"\n",(0,t.jsxs)(s.blockquote,{children:["\n",(0,t.jsx)(s.p,{children:"I might not know the shortest path yet, but I do remember all of other paths,\nand I can improve them, if possible."}),"\n"]}),"\n",(0,t.jsxs)(s.p,{children:["That's where the beauty of both ",(0,t.jsx)(s.em,{children:"dynamic programming"})," and ",(0,t.jsx)(s.em,{children:"relaxing"})," gets merged\ntogether and does its magic."]}),"\n",(0,t.jsx)(s.p,{children:"Proof of the correctness of the BF is done via induction to the number of\niterations. I would suggest to try to prove the correctness yourself and\npossibly look it up, if necessary."}),"\n",(0,t.jsx)(s.p,{children:"Also the correctness of the BF relies on the conclusion we've made when fixing\nthe infinite-loop on our na\xefve BF solution."}),"\n",(0,t.jsx)(s.h2,{id:"time-complexity",children:"Time complexity"}),"\n",(0,t.jsx)(s.p,{children:"Let's have a short look at the time complexities of the presented algorithms:"}),"\n",(0,t.jsxs)(s.ol,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"na\xefve approach: given that there are no negative loops, we are bound by the\nworst-case ordering of the relaxations which results in"}),"\n",(0,t.jsx)(s.span,{className:"katex-display",children:(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsxs)(s.mrow,{children:[(0,t.jsx)(s.mi,{mathvariant:"script",children:"O"}),(0,t.jsx)(s.mo,{stretchy:"false",children:"("}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mi,{children:"V"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mo,{children:"\u22c5"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mi,{children:"E"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mo,{stretchy:"false",children:")"})]}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(\\vert V \\vert \\cdot \\vert E \\vert)"})]})})}),(0,t.jsxs)(s.span,{className:"katex-html","aria-hidden":"true",children:[(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsx)(s.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,t.jsx)(s.span,{className:"mopen",children:"("}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,t.jsx)(s.span,{className:"mbin",children:"\u22c5"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mclose",children:")"})]})]})]})}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsxs)(s.p,{children:["our na\xefve approach with the fixed count of iterations instead of the\n",(0,t.jsx)(s.code,{children:"do-while"})," loop results in the same worst-case time complexity:"]}),"\n",(0,t.jsx)(s.span,{className:"katex-display",children:(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsxs)(s.mrow,{children:[(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u0398"}),(0,t.jsx)(s.mo,{stretchy:"false",children:"("}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mi,{children:"V"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mo,{children:"\u22c5"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mi,{children:"E"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mo,{stretchy:"false",children:")"})]}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"\\Theta(\\vert V \\vert \\cdot \\vert E \\vert)"})]})})}),(0,t.jsxs)(s.span,{className:"katex-html","aria-hidden":"true",children:[(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsx)(s.span,{className:"mord",children:"\u0398"}),(0,t.jsx)(s.span,{className:"mopen",children:"("}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,t.jsx)(s.span,{className:"mbin",children:"\u22c5"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mclose",children:")"})]})]})]})}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"and finally the well-known Bellman-Ford's algorithm time complexity:"}),"\n",(0,t.jsx)(s.span,{className:"katex-display",children:(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsxs)(s.mrow,{children:[(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u0398"}),(0,t.jsx)(s.mo,{stretchy:"false",children:"("}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mi,{children:"V"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mo,{children:"\u22c5"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mi,{children:"E"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mo,{stretchy:"false",children:")"})]}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"\\Theta(\\vert V \\vert \\cdot \\vert E \\vert)"})]})})}),(0,t.jsxs)(s.span,{className:"katex-html","aria-hidden":"true",children:[(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsx)(s.span,{className:"mord",children:"\u0398"}),(0,t.jsx)(s.span,{className:"mopen",children:"("}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,t.jsx)(s.span,{className:"mbin",children:"\u22c5"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mclose",children:")"})]})]})]})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"small-refactor",children:"Small refactor"}),"\n",(0,t.jsx)(s.p,{children:"Since we are literally copy-pasting the body of the loops just for the sake of\nrelaxing, we can factor that part out into a separate function:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-cpp",children:"static auto _check_vertex(const graph& g,\n std::vector>& distances, int v,\n bool check_only = false) -> bool {\n bool improvement_found = false;\n\n // unpack the vertex coordinates\n int y = v / g.width();\n int x = v % g.width();\n\n // skip the cells we cannot reach\n if (distances[y][x] == graph::unreachable()) {\n return false;\n }\n\n // go through the neighbours\n auto u = std::make_pair(x, y);\n for (const auto& [dx, dy] : DIRECTIONS) {\n auto v = std::make_pair(x + dx, y + dy);\n auto cost = g.cost(u, v);\n\n // if we can move to the cell and it's better, relax\xb9 it\n if (cost != graph::unreachable() &&\n distances[y][x] + cost < distances[y + dy][x + dx]) {\n if (check_only) {\n return true;\n }\n\n distances[y + dy][x + dx] = distances[y][x] + cost;\n improvement_found = true;\n }\n }\n\n return improvement_found;\n}\n"})}),"\n",(0,t.jsxs)(s.p,{children:["This function can be also used for checking the negative loops at the end of the\nBF by using the ",(0,t.jsx)(s.code,{children:"check_only"})," parameter to signal that we just want to know if\nthere would be any edge relaxed instead of performing the relaxation itself."]}),"\n",(0,t.jsx)(s.p,{children:"Then we can also see the differences between the specific versions of our\npath-finding algorithms in a clear way:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-cpp",children:'auto bf(const graph& g, const vertex_t& source, const vertex_t& destination)\n -> int {\n // \u2039source\u203a must be within the bounds\n assert(g.has(source));\n\n // \u2039destination\u203a must be within the bounds\n assert(g.has(destination));\n\n // we need to initialize the distances\n std::vector> distances(\n g.height(), std::vector(g.width(), graph::unreachable()));\n\n // \u2039source\u203a destination denotes the beginning where the cost is 0\n auto [sx, sy] = source;\n distances[sy][sx] = 0;\n\n // now we need to improve the paths as long as possible\n bool improvement_found;\n do {\n // reset the flag at the beginning\n improvement_found = false;\n\n // go through all of the vertices\n for (int v = g.height() * g.width() - 1; v >= 0; --v) {\n improvement_found = _check_vertex(g, distances, v) || improvement_found;\n }\n } while (improvement_found);\n\n return distances[destination.second][destination.first];\n}\n\nauto bf_finite(const graph& g, const vertex_t& source,\n const vertex_t& destination) -> int {\n // \u2039source\u203a must be within the bounds\n assert(g.has(source));\n\n // \u2039destination\u203a must be within the bounds\n assert(g.has(destination));\n\n // we need to initialize the distances\n std::vector> distances(\n g.height(), std::vector(g.width(), graph::unreachable()));\n\n // \u2039source\u203a destination denotes the beginning where the cost is 0\n auto [sx, sy] = source;\n distances[sy][sx] = 0;\n\n // now we only iterate as many times as cells that we have\n for (int i = g.height() * g.width(); i > 0; --i) {\n // go through all of the vertices\n for (int v = g.height() * g.width() - 1; v >= 0; --v) {\n _check_vertex(g, distances, v);\n }\n }\n\n return distances[destination.second][destination.first];\n}\n\nauto bellman_ford(const graph& g, const vertex_t& source)\n -> std::vector> {\n // \u2039source\u203a must be within the bounds\n assert(g.has(source));\n\n // we need to initialize the distances\n std::vector> distances(\n g.height(), std::vector(g.width(), graph::unreachable()));\n\n // \u2039source\u203a destination denotes the beginning where the cost is 0\n auto [sx, sy] = source;\n distances[sy][sx] = 0;\n\n // now we only iterate as many times as cells that we have\n for (int i = g.height() * g.width(); i > 0; --i) {\n // go through all of the vertices\n for (int v = g.height() * g.width() - 1; v >= 0; --v) {\n _check_vertex(g, distances, v);\n }\n }\n\n // now we check for the negative loops\n for (int v = g.height() * g.width() - 1; v >= 0; --v) {\n if (_check_vertex(g, distances, v, true)) {\n std::cerr << "[Bellman-Ford] Found a negative loop\\n";\n break;\n }\n }\n\n return distances;\n}\n\n'})}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsx)(s.admonition,{type:"tip",children:(0,t.jsxs)(s.p,{children:["You might've noticed that I've been using abbreviation ",(0,t.jsx)(s.em,{children:"BF"})," interchangeably for\nboth ",(0,t.jsx)(s.em,{children:"Bellman-Ford"})," and ",(0,t.jsx)(s.em,{children:"brute-force"}),". If you think about the way Bellman-Ford\nalgorithm works, you should realize that in the worst case it's updating the\nshortest path till there no shorter path exists, so in a sense, you could really\nconsider it a brute-force algorithm."]})}),"\n",(0,t.jsxs)(s.section,{"data-footnotes":!0,className:"footnotes",children:[(0,t.jsx)(s.h2,{className:"sr-only",id:"footnote-label",children:"Footnotes"}),"\n",(0,t.jsxs)(s.ol,{children:["\n",(0,t.jsxs)(s.li,{id:"user-content-fn-1",children:["\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"https://en.wikipedia.org/wiki/Breadth-first_search",children:"Breadth-first search"})," ",(0,t.jsx)(s.a,{href:"#user-content-fnref-1","data-footnote-backref":"","aria-label":"Back to reference 1",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{id:"user-content-fn-2",children:["\n",(0,t.jsxs)(s.p,{children:["Of course, there are some technicalities like keeping track of the visited\nvertices to not taint the shortest path by already visited vertices. ",(0,t.jsx)(s.a,{href:"#user-content-fnref-2","data-footnote-backref":"","aria-label":"Back to reference 2",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n",(0,t.jsxs)(s.li,{id:"user-content-fn-3",children:["\n",(0,t.jsxs)(s.p,{children:["or at least you should, LOL ",(0,t.jsx)(s.a,{href:"#user-content-fnref-3","data-footnote-backref":"","aria-label":"Back to reference 3",className:"data-footnote-backref",children:"\u21a9"})]}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:s}={...(0,a.a)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},11151:(e,s,n)=>{n.d(s,{Z:()=>l,a:()=>r});var t=n(67294);const a={},i=t.createContext(a);function r(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3d92ba6e.e64b02a7.js b/assets/js/3d92ba6e.e64b02a7.js new file mode 100644 index 0000000..a4d26af --- /dev/null +++ b/assets/js/3d92ba6e.e64b02a7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[8236],{77778:t=>{t.exports=JSON.parse('{"label":"dijkstra","permalink":"/algorithms/tags/dijkstra","allTagsPath":"/algorithms/tags","count":2,"items":[{"id":"paths/2024-01-01-bf-to-astar/dijkstra","title":"Dijkstra\'s algorithm","description":"Moving from Bellman-Ford into the Dijsktra\'s algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar/dijkstra"},{"id":"paths/2024-01-01-bf-to-astar/index","title":"From BF to A*","description":"Figuring out shortest-path problem from the BF to the A* algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/493c0536.6ae62548.js b/assets/js/493c0536.6ae62548.js new file mode 100644 index 0000000..462ba79 --- /dev/null +++ b/assets/js/493c0536.6ae62548.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[7292],{45594:(e,s,a)=>{a.r(s),a.d(s,{assets:()=>o,contentTitle:()=>r,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>h});var t=a(85893),n=a(11151);const i={id:"astar",slug:"/paths/bf-to-astar/astar",title:"A* algorithm",description:"Moving from Dijkstra's algorithm into the A* algorithm.\n",tags:["cpp","dynamic programming","astar"],last_update:{date:new Date("2024-01-03T00:00:00.000Z")}},r=void 0,l={id:"paths/2024-01-01-bf-to-astar/astar",title:"A* algorithm",description:"Moving from Dijkstra's algorithm into the A* algorithm.\n",source:"@site/algorithms/11-paths/2024-01-01-bf-to-astar/03-astar.md",sourceDirName:"11-paths/2024-01-01-bf-to-astar",slug:"/paths/bf-to-astar/astar",permalink:"/algorithms/paths/bf-to-astar/astar",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/11-paths/2024-01-01-bf-to-astar/03-astar.md",tags:[{label:"cpp",permalink:"/algorithms/tags/cpp"},{label:"dynamic programming",permalink:"/algorithms/tags/dynamic-programming"},{label:"astar",permalink:"/algorithms/tags/astar"}],version:"current",lastUpdatedAt:170424e4,formattedLastUpdatedAt:"Jan 3, 2024",sidebarPosition:3,frontMatter:{id:"astar",slug:"/paths/bf-to-astar/astar",title:"A* algorithm",description:"Moving from Dijkstra's algorithm into the A* algorithm.\n",tags:["cpp","dynamic programming","astar"],last_update:{date:"2024-01-03T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"Dijkstra's algorithm",permalink:"/algorithms/paths/bf-to-astar/dijkstra"},next:{title:"Hash Tables",permalink:"/algorithms/category/hash-tables"}},o={},h=[{value:"Intro",id:"intro",level:2},{value:"A* description",id:"a-description",level:2},{value:"Roadmap heuristic",id:"roadmap-heuristic",level:2},{value:"Heuristic for our map",id:"heuristic-for-our-map",level:2},{value:"Passing the heuristic",id:"passing-the-heuristic",level:2},{value:"Implementation",id:"implementation",level:2},{value:"Running on our map",id:"running-on-our-map",level:2},{value:"Comparison",id:"comparison",level:2},{value:"Summary",id:"summary",level:2}];function c(e){const s={admonition:"admonition",annotation:"annotation",code:"code",em:"em",h2:"h2",li:"li",math:"math",mi:"mi",mo:"mo",mrow:"mrow",msub:"msub",ol:"ol",p:"p",pre:"pre",semantics:"semantics",span:"span",...(0,n.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h2,{id:"intro",children:"Intro"}),"\n",(0,t.jsx)(s.p,{children:"Let's start by the recap of what we've achieved so far:"}),"\n",(0,t.jsxs)(s.ol,{children:["\n",(0,t.jsx)(s.li,{children:"We have implemented a na\xefve brute-force algorithm that tries to relax paths\nas long as there are any paths to be relaxed."}),"\n",(0,t.jsxs)(s.li,{children:["Then we have fixed an issue caused by negative loops that can result in\na non-terminating run of our brute-force method. At this moment we have made\nsome small arguments why are bounding is enough and doesn't prevent any\nshortest path to ",(0,t.jsx)(s.em,{children:"not be"})," discovered."]}),"\n",(0,t.jsx)(s.li,{children:"Finally we have converted our bounded brute-force algorithm into the\nBellman-Ford algorithm."}),"\n",(0,t.jsx)(s.li,{children:"We have mentioned the worst-case time complexity of our bounded na\xefve\napproach and also the Bellman-Ford algorithm. Our worst-case depended on the\nfact that we assumed the worst possible ordering of the relaxations. However\nwe could also try to relax in the most ideal ordering which could result in a\nfaster algorithm and that's how we got to the Dijkstra's algorithm."}),"\n"]}),"\n",(0,t.jsxs)(s.p,{children:["Now the question is, could we improve the Dijkstra's algorithm to get even\nbetter results? And the answer is ",(0,t.jsx)(s.em,{children:"maybe"}),"!"]}),"\n",(0,t.jsx)(s.p,{children:"Dijkstra's algorithm chooses the next cheapest vertex for relaxing. This is good\nas long as there is no additional information. However, imagine a roadmap of\nsome country. If you're in the middle of the map and you want to go south, it\ndoesn't make much sense for you to go to the north (in the opposite direction),\nbut a little bit might make sense, so that you can switch to highway and go much\nfaster."}),"\n",(0,t.jsxs)(s.p,{children:["The important question here is how to ",(0,t.jsx)(s.em,{children:"influence"})," the algorithm, so that it does\nchoose the path that ",(0,t.jsx)(s.em,{children:"makes more sense"})," rather than the one that costs the\nleast."]}),"\n",(0,t.jsx)(s.h2,{id:"a-description",children:"A* description"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.em,{children:"A* algorithm"})," can be considered a modification of Dijkstra's algorithm. The\ncost is still the same, we cannot change it, right? However when we pick the\nvertices from the heap, we can influence the order by some ",(0,t.jsx)(s.em,{children:"heuristic"}),". In this\ncase, we introduce a function that can suggest how feasible the vertex is."]}),"\n",(0,t.jsx)(s.h2,{id:"roadmap-heuristic",children:"Roadmap heuristic"}),"\n",(0,t.jsx)(s.p,{children:"Let's have a look at the heuristic we could use for the roadmap example. There\nare roads (the edges) and towns (the vertices). Cost could be an average time to\ntravel the road. What heuristic could we use to influence our algorithm to\nchoose a better ordering of the vertices when relaxing?"}),"\n",(0,t.jsx)(s.p,{children:"In the former example we've said that it doesn't make much sense to go in the\nopposite direction than our goal is\u2026 We could choose the distance from our goal\nas the heuristic, e.g. right now we're 100 km away from our goal, using this\nroad makes us 50 km away and using the other road we will be 200 km away."}),"\n",(0,t.jsx)(s.h2,{id:"heuristic-for-our-map",children:"Heuristic for our map"}),"\n",(0,t.jsxs)(s.p,{children:["Our map is a bit simpler, but we can use a very similar principle. We will use\nthe ",(0,t.jsx)(s.em,{children:"Manhattan distance"}),", which is defined in a following way:"]}),"\n",(0,t.jsx)(s.span,{className:"katex-display",children:(0,t.jsxs)(s.span,{className:"katex",children:[(0,t.jsx)(s.span,{className:"katex-mathml",children:(0,t.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,t.jsxs)(s.semantics,{children:[(0,t.jsxs)(s.mrow,{children:[(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsxs)(s.msub,{children:[(0,t.jsx)(s.mi,{children:"x"}),(0,t.jsx)(s.mi,{children:"a"})]}),(0,t.jsx)(s.mo,{children:"\u2212"}),(0,t.jsxs)(s.msub,{children:[(0,t.jsx)(s.mi,{children:"x"}),(0,t.jsx)(s.mi,{children:"b"})]}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsx)(s.mo,{children:"+"}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"}),(0,t.jsxs)(s.msub,{children:[(0,t.jsx)(s.mi,{children:"y"}),(0,t.jsx)(s.mi,{children:"a"})]}),(0,t.jsx)(s.mo,{children:"\u2212"}),(0,t.jsxs)(s.msub,{children:[(0,t.jsx)(s.mi,{children:"y"}),(0,t.jsx)(s.mi,{children:"b"})]}),(0,t.jsx)(s.mi,{mathvariant:"normal",children:"\u2223"})]}),(0,t.jsx)(s.annotation,{encoding:"application/x-tex",children:"\\vert x_a - x_b \\vert + \\vert y_a - y_b \\vert"})]})})}),(0,t.jsxs)(s.span,{className:"katex-html","aria-hidden":"true",children:[(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsxs)(s.span,{className:"mord",children:[(0,t.jsx)(s.span,{className:"mord mathnormal",children:"x"}),(0,t.jsx)(s.span,{className:"msupsub",children:(0,t.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,t.jsxs)(s.span,{className:"vlist-r",children:[(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.1514em"},children:(0,t.jsxs)(s.span,{style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"},children:[(0,t.jsx)(s.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(s.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(s.span,{className:"mord mathnormal mtight",children:"a"})})]})}),(0,t.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,t.jsx)(s.span,{className:"vlist-r",children:(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.15em"},children:(0,t.jsx)(s.span,{})})})]})})]}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,t.jsx)(s.span,{className:"mbin",children:"\u2212"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsxs)(s.span,{className:"mord",children:[(0,t.jsx)(s.span,{className:"mord mathnormal",children:"x"}),(0,t.jsx)(s.span,{className:"msupsub",children:(0,t.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,t.jsxs)(s.span,{className:"vlist-r",children:[(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.3361em"},children:(0,t.jsxs)(s.span,{style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"},children:[(0,t.jsx)(s.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(s.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(s.span,{className:"mord mathnormal mtight",children:"b"})})]})}),(0,t.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,t.jsx)(s.span,{className:"vlist-r",children:(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.15em"},children:(0,t.jsx)(s.span,{})})})]})})]}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,t.jsx)(s.span,{className:"mbin",children:"+"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"}),(0,t.jsxs)(s.span,{className:"mord",children:[(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,t.jsx)(s.span,{className:"msupsub",children:(0,t.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,t.jsxs)(s.span,{className:"vlist-r",children:[(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.1514em"},children:(0,t.jsxs)(s.span,{style:{top:"-2.55em",marginLeft:"-0.0359em",marginRight:"0.05em"},children:[(0,t.jsx)(s.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(s.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(s.span,{className:"mord mathnormal mtight",children:"a"})})]})}),(0,t.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,t.jsx)(s.span,{className:"vlist-r",children:(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.15em"},children:(0,t.jsx)(s.span,{})})})]})})]}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,t.jsx)(s.span,{className:"mbin",children:"\u2212"}),(0,t.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,t.jsxs)(s.span,{className:"base",children:[(0,t.jsx)(s.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,t.jsxs)(s.span,{className:"mord",children:[(0,t.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,t.jsx)(s.span,{className:"msupsub",children:(0,t.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,t.jsxs)(s.span,{className:"vlist-r",children:[(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.3361em"},children:(0,t.jsxs)(s.span,{style:{top:"-2.55em",marginLeft:"-0.0359em",marginRight:"0.05em"},children:[(0,t.jsx)(s.span,{className:"pstrut",style:{height:"2.7em"}}),(0,t.jsx)(s.span,{className:"sizing reset-size6 size3 mtight",children:(0,t.jsx)(s.span,{className:"mord mathnormal mtight",children:"b"})})]})}),(0,t.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,t.jsx)(s.span,{className:"vlist-r",children:(0,t.jsx)(s.span,{className:"vlist",style:{height:"0.15em"},children:(0,t.jsx)(s.span,{})})})]})})]}),(0,t.jsx)(s.span,{className:"mord",children:"\u2223"})]})]})]})}),"\n",(0,t.jsx)(s.p,{children:"Since we cannot move in diagonals, it makes sense to maintain the distance in\nthe actual steps from the goal."}),"\n",(0,t.jsx)(s.h2,{id:"passing-the-heuristic",children:"Passing the heuristic"}),"\n",(0,t.jsx)(s.p,{children:"In our case, when we're using C++, we can just template the function that will\ncalculate the shortest path and pass the heuristic as a parameter."}),"\n",(0,t.jsx)(s.h2,{id:"implementation",children:"Implementation"}),"\n",(0,t.jsx)(s.p,{children:"Actual implementation is very easy once we have the Dijkstra's algorithm:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-cpp",children:"auto astar(const graph& g, const vertex_t& source, const auto& h)\n -> std::vector> {\n // make sure that \u2039source\u203a exists\n assert(g.has(source));\n\n // initialize the distances\n std::vector> distances(\n g.height(), std::vector(g.width(), graph::unreachable()));\n\n // initialize the visited\n std::vector> visited(g.height(),\n std::vector(g.width(), false));\n\n // \u2039source\u203a destination denotes the beginning where the cost is 0\n auto [sx, sy] = source;\n distances[sy][sx] = 0;\n\n pqueue_t priority_queue{std::make_pair(0 + h(source), source)};\n std::optional item{};\n while ((item = popq(priority_queue))) {\n auto [cost, u] = *item;\n auto [x, y] = u;\n\n // we have already found the shortest path\n if (visited[y][x]) {\n continue;\n }\n visited[y][x] = true;\n\n for (const auto& [dx, dy] : DIRECTIONS) {\n auto v = std::make_pair(x + dx, y + dy);\n auto cost = g.cost(u, v);\n\n // if we can move to the cell and it's better, relax\xb9 it and update queue\n if (cost != graph::unreachable() &&\n distances[y][x] + cost < distances[y + dy][x + dx]) {\n distances[y + dy][x + dx] = distances[y][x] + cost;\n pushq(priority_queue,\n std::make_pair(distances[y + dy][x + dx] + h(v), v));\n }\n }\n }\n\n return distances;\n}\n"})}),"\n",(0,t.jsx)(s.h2,{id:"running-on-our-map",children:"Running on our map"}),"\n",(0,t.jsx)(s.p,{children:"For this algorithm I will also show the example of a call:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-cpp",children:'distances = astar(g, std::make_pair(1, 9), [](const auto& u) {\n auto [x, y] = u;\n return std::abs(1 - x) + std::abs(7 - y);\n});\nstd::cout << "[A*] Cost: " << distances[7][1] << "\\n";\n'})}),"\n",(0,t.jsxs)(s.p,{children:["First argument to the function is the graph itself. Second argument is the\nsource vertex where we start. And finally the lambda returns\n",(0,t.jsx)(s.em,{children:"Manhattan distance"})," to the goal."]}),"\n",(0,t.jsx)(s.p,{children:"And we get the following result:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"Normal cost: 1\nVortex cost: 5\nGraph:\n#############\n#..#..*.*.**#\n##***.....**#\n#..########.#\n#...###...#.#\n#..#...##.#.#\n#..#.*.#..#.#\n#D...#....#.#\n########*.*.#\n#S..........#\n#############\n[Finite BF] Cost: 22\n[Bellman-Ford] Cost: 22\n[Dijkstra] Cost: 22\n[A*] Cost: 22\n"})}),"\n",(0,t.jsx)(s.h2,{id:"comparison",children:"Comparison"}),"\n",(0,t.jsx)(s.p,{children:"Now you may wonder how does it compare to the previous algorithms. Supposedly it\nshould be faster. Let's add counters and debugging output when we update\ndistance to our goal. And now if we run our code, we get the following output:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{children:"Normal cost: 1\nVortex cost: 5\nGraph:\n#############\n#..#..*.*.**#\n##***.....**#\n#..########.#\n#...###...#.#\n#..#...##.#.#\n#..#.*.#..#.#\n#D...#....#.#\n########*.*.#\n#S..........#\n#############\nRelaxing path to goal in 40. relaxation\nRelaxing path to goal in 68. relaxation\nRelaxing path to goal in 89. relaxation\n[Finite BF] Cost: 22\nRelaxing path to goal in 40. relaxation\nRelaxing path to goal in 68. relaxation\nRelaxing path to goal in 89. relaxation\n[Bellman-Ford] Cost: 22\nRelaxing path to goal in 41. iteration\n[Dijkstra] Cost: 22\nRelaxing path to goal in 31. iteration\n[A*] Cost: 22\n"})}),"\n",(0,t.jsx)(s.p,{children:"From the output we can easily deduce that for both brute-force and Bellman-Ford,\nwhich are in our case identical, we actually relax three times and for the last\ntime in the 89th iteration."}),"\n",(0,t.jsx)(s.p,{children:"Dijkstra's algorithm manages to find the shortest path to our goal already in\nthe 41st iteration."}),"\n",(0,t.jsx)(s.p,{children:"And finally after introducing some heuristic, we could find the shortest path\nin the 31st iteration."}),"\n",(0,t.jsx)(s.admonition,{type:"danger",children:(0,t.jsx)(s.p,{children:"Please keep in mind that choosing bad heuristic can actually lead to worse\nresults than using no heuristic at all."})}),"\n",(0,t.jsx)(s.h2,{id:"summary",children:"Summary"}),"\n",(0,t.jsx)(s.p,{children:"And there we have it. We have made our way from the brute-force algorithm all\nthe way to more optimal ones. Hopefully we could notice how the small\nimprovements of the already existing algorithms made them much better."})]})}function m(e={}){const{wrapper:s}={...(0,n.a)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},11151:(e,s,a)=>{a.d(s,{Z:()=>l,a:()=>r});var t=a(67294);const n={},i=t.createContext(n);function r(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/520f8175.85515c7b.js b/assets/js/520f8175.85515c7b.js deleted file mode 100644 index ea4aa7a..0000000 --- a/assets/js/520f8175.85515c7b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[8058],{24353:t=>{t.exports=JSON.parse('{"label":"cpp","permalink":"/algorithms/tags/cpp","allTagsPath":"/algorithms/tags","count":3,"items":[{"id":"hash-tables/2023-11-28-breaking/breaking","title":"Breaking Hash Table","description":"How to get the linear time complexity in a hash table.\\n","permalink":"/algorithms/hash-tables/breaking"},{"id":"hash-tables/2023-11-28-breaking/python","title":"Breaking Python","description":"Actually getting the worst-case time complexity in Python.\\n","permalink":"/algorithms/hash-tables/breaking/python"},{"id":"hash-tables/2023-11-28-breaking/mitigations","title":"Possible Mitigations","description":"Talking about the ways how to prevent the attacks on the hash table.\\n","permalink":"/algorithms/hash-tables/breaking/mitigations"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/520f8175.d9b4c84f.js b/assets/js/520f8175.d9b4c84f.js new file mode 100644 index 0000000..f450147 --- /dev/null +++ b/assets/js/520f8175.d9b4c84f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[8058],{24353:t=>{t.exports=JSON.parse('{"label":"cpp","permalink":"/algorithms/tags/cpp","allTagsPath":"/algorithms/tags","count":7,"items":[{"id":"paths/2024-01-01-bf-to-astar/astar","title":"A* algorithm","description":"Moving from Dijkstra\'s algorithm into the A* algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar/astar"},{"id":"paths/2024-01-01-bf-to-astar/bf","title":"BF","description":"Solving the shortest path problem with a na\xefve approach that turns into\\nsomething.\\n","permalink":"/algorithms/paths/bf-to-astar/bf"},{"id":"hash-tables/2023-11-28-breaking/breaking","title":"Breaking Hash Table","description":"How to get the linear time complexity in a hash table.\\n","permalink":"/algorithms/hash-tables/breaking"},{"id":"hash-tables/2023-11-28-breaking/python","title":"Breaking Python","description":"Actually getting the worst-case time complexity in Python.\\n","permalink":"/algorithms/hash-tables/breaking/python"},{"id":"paths/2024-01-01-bf-to-astar/dijkstra","title":"Dijkstra\'s algorithm","description":"Moving from Bellman-Ford into the Dijsktra\'s algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar/dijkstra"},{"id":"paths/2024-01-01-bf-to-astar/index","title":"From BF to A*","description":"Figuring out shortest-path problem from the BF to the A* algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar"},{"id":"hash-tables/2023-11-28-breaking/mitigations","title":"Possible Mitigations","description":"Talking about the ways how to prevent the attacks on the hash table.\\n","permalink":"/algorithms/hash-tables/breaking/mitigations"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/595c7293.6c273bef.js b/assets/js/595c7293.6c273bef.js new file mode 100644 index 0000000..497ea2d --- /dev/null +++ b/assets/js/595c7293.6c273bef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[5634],{58396:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var i=t(85893),s=t(11151);const r={id:"seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n"},o="8th seminar bonus assignment",c={id:"bonuses/seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n",source:"@site/c/bonuses/08.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-08",permalink:"/c/bonuses/seminar-08",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/08.md",tags:[],version:"current",lastUpdatedAt:1704291155,formattedLastUpdatedAt:"Jan 3, 2024",frontMatter:{id:"seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n"},sidebar:"autogeneratedBar",previous:{title:"5th and 6th seminar",permalink:"/c/bonuses/seminar-05-06"},next:{title:"10th seminar",permalink:"/c/bonuses/seminar-10"}},a={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Warning",id:"warning",level:2},{value:"Testing",id:"testing",level:2},{value:"Task no. 1: Counting (0.75 K\u20a1)",id:"task-no-1-counting-075-k",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Bonus part (0.75 K\u20a1)",id:"bonus-part-075-k",level:3},{value:"Task no. 2: Weird trees (1 K\u20a1)",id:"task-no-2-weird-trees-1-k",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"8th-seminar-bonus-assignment",children:"8th seminar bonus assignment"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"pathname:///files/c/bonuses/08.tar.gz",children:"Source"})}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"In this bonus you can implement two tasks, one of them has a bonus part with generic\nsolution."}),"\n",(0,i.jsx)(n.p,{children:"One is focused on counting ananas or in case of generic version any substring in\nthe file, but with a restriction on the function you use."}),"\n",(0,i.jsx)(n.p,{children:"Other one has a more algorithmic spirit."}),"\n",(0,i.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,i.jsx)(n.h2,{id:"warning",children:"Warning"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"DO NOT COMMIT test data"})," to your own git repository, since the tests include\nfiles that exceed 10MB by themselves. Even if they are on separate branch, they\ntake up the space."]}),"\n",(0,i.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,i.jsxs)(n.p,{children:["For testing you are provided with python script (requires ",(0,i.jsx)(n.code,{children:"click"})," to be installed:\n",(0,i.jsx)(n.code,{children:"pip3 install --user click"}),") and ",(0,i.jsx)(n.code,{children:"Makefile"})," that provides following targets:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting-bonus"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests with bonus implemented"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check"})," - runs both ",(0,i.jsx)(n.code,{children:"counting"})," and ",(0,i.jsx)(n.code,{children:"counting-bonus"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"clean"})," - removes output files from the test runs"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-1-counting-075-k",children:"Task no. 1: Counting (0.75 K\u20a1)"}),"\n",(0,i.jsx)(n.p,{children:"Your first task is to make smallish program that counts occurences of specific\n(or given) word from file and writes the number to other file."}),"\n",(0,i.jsx)(n.p,{children:"Usage of the program is:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Usage: ./counting [string-to-be-counted]\n"})}),"\n",(0,i.jsx)(n.p,{children:"Arguments that are passed to the program represent:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we count the words"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we output the count"]}),"\n",(0,i.jsxs)(n.li,{children:["(optional argument) ",(0,i.jsx)(n.code,{children:"[string-to-be-counted]"})," - in case you implement bonus,\notherwise we default to word ",(0,i.jsx)(n.code,{children:"ananas"})," ;)"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"In skeleton you are given 3 empty, but documented, functions to implement."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_anything"})," - function accepts input file and substring to be counted in\nthe file, returns the count."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_ananas"})," - same as ",(0,i.jsx)(n.code,{children:"count_anything"}),", but specialized for ananases, the\ndefault implementation from the skeleton expects you to implement ",(0,i.jsx)(n.code,{children:"count_anything"}),"\nand therefore it just calls the other function."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"write_number"})," - function that writes the number to the file, why would you\nneed the function is explained later :)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsxs)(n.p,{children:["For manipulation with the files you are only allowed to use ",(0,i.jsx)(n.code,{children:"fopen"}),", ",(0,i.jsx)(n.code,{children:"fclose"}),",\n",(0,i.jsx)(n.code,{children:"fgetc"})," and ",(0,i.jsx)(n.code,{children:"fputc"}),". Functions like ",(0,i.jsx)(n.code,{children:"fprintf"})," (except for ",(0,i.jsx)(n.code,{children:"stderr"})," or logging) and\n",(0,i.jsx)(n.code,{children:"fscanf"})," are ",(0,i.jsx)(n.strong,{children:"forbidden"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"In case you struggle and want to use one of those functions, the solution will be\npenalized by 50% of points."}),"\n",(0,i.jsx)(n.h3,{id:"bonus-part-075-k",children:"Bonus part (0.75 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["Bonus part of this assignment is to implement ",(0,i.jsx)(n.code,{children:"count_anything"})," rather than ",(0,i.jsx)(n.code,{children:"count_ananas"}),"."]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Smaller hint: This task does not need dynamic allocation :) You just need one\ngood helper function and the right idea ;)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-2-weird-trees-1-k",children:"Task no. 2: Weird trees (1 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["In this task we are crossing our paths with ",(0,i.jsx)(n.em,{children:"algorithms and data structures"}),".\nYour task is to write a program that constructs tree from the file that is given\nas an argument and pretty-prints it."]}),"\n",(0,i.jsxs)(n.p,{children:["Input file consists of lines, that include ",(0,i.jsx)(n.code,{children:"key"})," and ",(0,i.jsx)(n.code,{children:"rank"})," in form ",(0,i.jsx)(n.code,{children:"key;rank"}),"\nor ",(0,i.jsx)(n.code,{children:"nil"}),". Why would we have ",(0,i.jsx)(n.code,{children:"nil"})," in a file? The file represents pre-order iteration\nthrough the tree. Leaves never have rank different than 0, so you can safely assume\n2 non-existing ",(0,i.jsx)(n.code,{children:"nil"}),"s in the input after you read such node ;)"]}),"\n",(0,i.jsxs)("table",{children:[(0,i.jsxs)("tr",{children:[(0,i.jsx)("th",{children:"Example input file"}),(0,i.jsx)("th",{children:"Tree it represents"})]}),(0,i.jsxs)("tr",{children:[(0,i.jsx)("td",{children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8;4\n5;3\n3;2\n2;1\n1;0\nnil\n4;0\n7;1\n6;0\nnil\n11;2\n10;1\n9;0\nnil\n12;0\n"})})}),(0,i.jsx)("td",{children:(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"tree",src:t(30073).Z+"",width:"633",height:"684"})})})]})]}),"\n",(0,i.jsxs)(n.p,{children:["In this task you are only provided with different trees in the ",(0,i.jsx)(n.code,{children:"test-trees"})," directory.\nImplementation and format of the pretty-print is totally up to you. :)"]}),"\n",(0,i.jsx)(n.p,{children:"Example of mine for the tree above:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8 (rank = 4)\n+-- 5 (rank = 3)\n| +-- 3 (rank = 2)\n| | +-- 2 (rank = 1)\n| | | +-- 1 (rank = 0)\n| | +-- 4 (rank = 0)\n| +-- 7 (rank = 1)\n| +-- 6 (rank = 0)\n+-- 11 (rank = 2)\n +-- 10 (rank = 1)\n | +-- 9 (rank = 0)\n +-- 12 (rank = 0)\n"})}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Can you find out what are those trees? :)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,i.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,i.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},30073:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/tree-c9e37f87f9095c00fad33ea034485ce6.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>o});var i=t(67294);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/595c7293.b89891f3.js b/assets/js/595c7293.b89891f3.js deleted file mode 100644 index 356d538..0000000 --- a/assets/js/595c7293.b89891f3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[5634],{58396:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var i=t(85893),s=t(11151);const r={id:"seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n"},o="8th seminar bonus assignment",c={id:"bonuses/seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n",source:"@site/c/bonuses/08.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-08",permalink:"/c/bonuses/seminar-08",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/08.md",tags:[],version:"current",lastUpdatedAt:1703979877,formattedLastUpdatedAt:"Dec 30, 2023",frontMatter:{id:"seminar-08",title:"8th seminar",description:"Manipulating with files only char-by-char and a magic tree.\n"},sidebar:"autogeneratedBar",previous:{title:"5th and 6th seminar",permalink:"/c/bonuses/seminar-05-06"},next:{title:"10th seminar",permalink:"/c/bonuses/seminar-10"}},a={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Warning",id:"warning",level:2},{value:"Testing",id:"testing",level:2},{value:"Task no. 1: Counting (0.75 K\u20a1)",id:"task-no-1-counting-075-k",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Bonus part (0.75 K\u20a1)",id:"bonus-part-075-k",level:3},{value:"Task no. 2: Weird trees (1 K\u20a1)",id:"task-no-2-weird-trees-1-k",level:2},{value:"Submitting",id:"submitting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"8th-seminar-bonus-assignment",children:"8th seminar bonus assignment"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"pathname:///files/c/bonuses/08.tar.gz",children:"Source"})}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.p,{children:"In this bonus you can implement two tasks, one of them has a bonus part with generic\nsolution."}),"\n",(0,i.jsx)(n.p,{children:"One is focused on counting ananas or in case of generic version any substring in\nthe file, but with a restriction on the function you use."}),"\n",(0,i.jsx)(n.p,{children:"Other one has a more algorithmic spirit."}),"\n",(0,i.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,i.jsx)(n.h2,{id:"warning",children:"Warning"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"DO NOT COMMIT test data"})," to your own git repository, since the tests include\nfiles that exceed 10MB by themselves. Even if they are on separate branch, they\ntake up the space."]}),"\n",(0,i.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,i.jsxs)(n.p,{children:["For testing you are provided with python script (requires ",(0,i.jsx)(n.code,{children:"click"})," to be installed:\n",(0,i.jsx)(n.code,{children:"pip3 install --user click"}),") and ",(0,i.jsx)(n.code,{children:"Makefile"})," that provides following targets:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check-counting-bonus"})," - runs the ",(0,i.jsx)(n.code,{children:"counting"})," tests with bonus implemented"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"check"})," - runs both ",(0,i.jsx)(n.code,{children:"counting"})," and ",(0,i.jsx)(n.code,{children:"counting-bonus"})," tests"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"clean"})," - removes output files from the test runs"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-1-counting-075-k",children:"Task no. 1: Counting (0.75 K\u20a1)"}),"\n",(0,i.jsx)(n.p,{children:"Your first task is to make smallish program that counts occurences of specific\n(or given) word from file and writes the number to other file."}),"\n",(0,i.jsx)(n.p,{children:"Usage of the program is:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Usage: ./counting [string-to-be-counted]\n"})}),"\n",(0,i.jsx)(n.p,{children:"Arguments that are passed to the program represent:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we count the words"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:""})," - path to the file where we output the count"]}),"\n",(0,i.jsxs)(n.li,{children:["(optional argument) ",(0,i.jsx)(n.code,{children:"[string-to-be-counted]"})," - in case you implement bonus,\notherwise we default to word ",(0,i.jsx)(n.code,{children:"ananas"})," ;)"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"In skeleton you are given 3 empty, but documented, functions to implement."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_anything"})," - function accepts input file and substring to be counted in\nthe file, returns the count."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"count_ananas"})," - same as ",(0,i.jsx)(n.code,{children:"count_anything"}),", but specialized for ananases, the\ndefault implementation from the skeleton expects you to implement ",(0,i.jsx)(n.code,{children:"count_anything"}),"\nand therefore it just calls the other function."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"write_number"})," - function that writes the number to the file, why would you\nneed the function is explained later :)"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsxs)(n.p,{children:["For manipulation with the files you are only allowed to use ",(0,i.jsx)(n.code,{children:"fopen"}),", ",(0,i.jsx)(n.code,{children:"fclose"}),",\n",(0,i.jsx)(n.code,{children:"fgetc"})," and ",(0,i.jsx)(n.code,{children:"fputc"}),". Functions like ",(0,i.jsx)(n.code,{children:"fprintf"})," (except for ",(0,i.jsx)(n.code,{children:"stderr"})," or logging) and\n",(0,i.jsx)(n.code,{children:"fscanf"})," are ",(0,i.jsx)(n.strong,{children:"forbidden"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"In case you struggle and want to use one of those functions, the solution will be\npenalized by 50% of points."}),"\n",(0,i.jsx)(n.h3,{id:"bonus-part-075-k",children:"Bonus part (0.75 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["Bonus part of this assignment is to implement ",(0,i.jsx)(n.code,{children:"count_anything"})," rather than ",(0,i.jsx)(n.code,{children:"count_ananas"}),"."]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Smaller hint: This task does not need dynamic allocation :) You just need one\ngood helper function and the right idea ;)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"task-no-2-weird-trees-1-k",children:"Task no. 2: Weird trees (1 K\u20a1)"}),"\n",(0,i.jsxs)(n.p,{children:["In this task we are crossing our paths with ",(0,i.jsx)(n.em,{children:"algorithms and data structures"}),".\nYour task is to write a program that constructs tree from the file that is given\nas an argument and pretty-prints it."]}),"\n",(0,i.jsxs)(n.p,{children:["Input file consists of lines, that include ",(0,i.jsx)(n.code,{children:"key"})," and ",(0,i.jsx)(n.code,{children:"rank"})," in form ",(0,i.jsx)(n.code,{children:"key;rank"}),"\nor ",(0,i.jsx)(n.code,{children:"nil"}),". Why would we have ",(0,i.jsx)(n.code,{children:"nil"})," in a file? The file represents pre-order iteration\nthrough the tree. Leaves never have rank different than 0, so you can safely assume\n2 non-existing ",(0,i.jsx)(n.code,{children:"nil"}),"s in the input after you read such node ;)"]}),"\n",(0,i.jsxs)("table",{children:[(0,i.jsxs)("tr",{children:[(0,i.jsx)("th",{children:"Example input file"}),(0,i.jsx)("th",{children:"Tree it represents"})]}),(0,i.jsxs)("tr",{children:[(0,i.jsx)("td",{children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8;4\n5;3\n3;2\n2;1\n1;0\nnil\n4;0\n7;1\n6;0\nnil\n11;2\n10;1\n9;0\nnil\n12;0\n"})})}),(0,i.jsx)("td",{children:(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"tree",src:t(30073).Z+"",width:"633",height:"684"})})})]})]}),"\n",(0,i.jsxs)(n.p,{children:["In this task you are only provided with different trees in the ",(0,i.jsx)(n.code,{children:"test-trees"})," directory.\nImplementation and format of the pretty-print is totally up to you. :)"]}),"\n",(0,i.jsx)(n.p,{children:"Example of mine for the tree above:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8 (rank = 4)\n+-- 5 (rank = 3)\n| +-- 3 (rank = 2)\n| | +-- 2 (rank = 1)\n| | | +-- 1 (rank = 0)\n| | +-- 4 (rank = 0)\n| +-- 7 (rank = 1)\n| +-- 6 (rank = 0)\n+-- 11 (rank = 2)\n +-- 10 (rank = 1)\n | +-- 9 (rank = 0)\n +-- 12 (rank = 0)\n"})}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"Can you find out what are those trees? :)"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,i.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,i.jsx)(n.hr,{})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},30073:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/tree-c9e37f87f9095c00fad33ea034485ce6.png"},11151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>o});var i=t(67294);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c15401e.e4b1c753.js b/assets/js/5c15401e.e4b1c753.js new file mode 100644 index 0000000..5706ff4 --- /dev/null +++ b/assets/js/5c15401e.e4b1c753.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[9579],{43761:t=>{t.exports=JSON.parse('{"label":"bellman ford","permalink":"/algorithms/tags/bellman-ford","allTagsPath":"/algorithms/tags","count":2,"items":[{"id":"paths/2024-01-01-bf-to-astar/bf","title":"BF","description":"Solving the shortest path problem with a na\xefve approach that turns into\\nsomething.\\n","permalink":"/algorithms/paths/bf-to-astar/bf"},{"id":"paths/2024-01-01-bf-to-astar/index","title":"From BF to A*","description":"Figuring out shortest-path problem from the BF to the A* algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/698e2076.0fda5cee.js b/assets/js/698e2076.0fda5cee.js new file mode 100644 index 0000000..34c75bd --- /dev/null +++ b/assets/js/698e2076.0fda5cee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[3713],{38961:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>h,contentTitle:()=>r,default:()=>c,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var n=s(85893),a=s(11151);const i={id:"dijkstra",slug:"/paths/bf-to-astar/dijkstra",title:"Dijkstra's algorithm",description:"Moving from Bellman-Ford into the Dijsktra's algorithm.\n",tags:["cpp","dynamic programming","greedy","dijkstra"],last_update:{date:new Date("2024-01-03T00:00:00.000Z")}},r=void 0,o={id:"paths/2024-01-01-bf-to-astar/dijkstra",title:"Dijkstra's algorithm",description:"Moving from Bellman-Ford into the Dijsktra's algorithm.\n",source:"@site/algorithms/11-paths/2024-01-01-bf-to-astar/02-dijkstra.md",sourceDirName:"11-paths/2024-01-01-bf-to-astar",slug:"/paths/bf-to-astar/dijkstra",permalink:"/algorithms/paths/bf-to-astar/dijkstra",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/11-paths/2024-01-01-bf-to-astar/02-dijkstra.md",tags:[{label:"cpp",permalink:"/algorithms/tags/cpp"},{label:"dynamic programming",permalink:"/algorithms/tags/dynamic-programming"},{label:"greedy",permalink:"/algorithms/tags/greedy"},{label:"dijkstra",permalink:"/algorithms/tags/dijkstra"}],version:"current",lastUpdatedAt:170424e4,formattedLastUpdatedAt:"Jan 3, 2024",sidebarPosition:2,frontMatter:{id:"dijkstra",slug:"/paths/bf-to-astar/dijkstra",title:"Dijkstra's algorithm",description:"Moving from Bellman-Ford into the Dijsktra's algorithm.\n",tags:["cpp","dynamic programming","greedy","dijkstra"],last_update:{date:"2024-01-03T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"BF",permalink:"/algorithms/paths/bf-to-astar/bf"},next:{title:"A* algorithm",permalink:"/algorithms/paths/bf-to-astar/astar"}},h={},l=[{value:"Intro",id:"intro",level:2},{value:"Dijkstra's algorithm",id:"dijkstras-algorithm",level:2},{value:"Short description",id:"short-description",level:2},{value:"Used techniques",id:"used-techniques",level:2},{value:"Implementation",id:"implementation",level:2},{value:"Time complexity",id:"time-complexity",level:2},{value:"Running the Dijkstra",id:"running-the-dijkstra",level:2},{value:"Busting the myth about looping Dijkstra",id:"busting-the-myth-about-looping-dijkstra",level:2},{value:"Summary",id:"summary",level:2}];function m(e){const t={admonition:"admonition",annotation:"annotation",blockquote:"blockquote",code:"code",em:"em",h2:"h2",img:"img",math:"math",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",msup:"msup",p:"p",pre:"pre",semantics:"semantics",span:"span",strong:"strong",...(0,a.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h2,{id:"intro",children:"Intro"}),"\n",(0,n.jsx)(t.p,{children:"Let's rewind back to the small argument in the previous post about the fact that\nwe can safely bound the amount of iterations with relaxations being done."}),"\n",(0,n.jsxs)(t.p,{children:["We have said that assuming the worst-case scenario (bad order of relaxations) we\n",(0,n.jsx)(t.strong,{children:"need"})," at most ",(0,n.jsxs)(t.span,{className:"katex",children:[(0,n.jsx)(t.span,{className:"katex-mathml",children:(0,n.jsx)(t.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(t.semantics,{children:[(0,n.jsxs)(t.mrow,{children:[(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u2223"}),(0,n.jsx)(t.mi,{children:"V"}),(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u2223"}),(0,n.jsx)(t.mo,{children:"\u2212"}),(0,n.jsx)(t.mn,{children:"1"})]}),(0,n.jsx)(t.annotation,{encoding:"application/x-tex",children:"\\vert V \\vert - 1"})]})})}),(0,n.jsxs)(t.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(t.span,{className:"base",children:[(0,n.jsx)(t.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,n.jsx)(t.span,{className:"mord",children:"\u2223"}),(0,n.jsx)(t.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,n.jsx)(t.span,{className:"mord",children:"\u2223"}),(0,n.jsx)(t.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(t.span,{className:"mbin",children:"\u2212"}),(0,n.jsx)(t.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,n.jsxs)(t.span,{className:"base",children:[(0,n.jsx)(t.span,{className:"strut",style:{height:"0.6444em"}}),(0,n.jsx)(t.span,{className:"mord",children:"1"})]})]})]})," iterations over all edges. We've used that\nto our advantage to ",(0,n.jsx)(t.em,{children:"bound"})," the iterations instead of the ",(0,n.jsx)(t.code,{children:"do-while"})," loop that\nwas a risk given the possibility of the infinite loop (when negative loops are\npresent in the graph)."]}),"\n",(0,n.jsxs)(t.admonition,{type:"tip",children:[(0,n.jsxs)(t.p,{children:["We could've possibly used both ",(0,n.jsx)(t.em,{children:"boolean flag"})," to denote that some relaxation has\nhappened and the upper bound of iterations, for some graphs that would result in\nfaster termination."]}),(0,n.jsx)(t.p,{children:"Using only the upper bound we try to relax edges even though we can't."})]}),"\n",(0,n.jsx)(t.p,{children:"Now the question arises, could we leverage this somehow in a different way? What\nif we used it to improve the algorithm instead of just bounding the iterations?\nWould that be even possible?"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Yes, it would!"})," And that's when ",(0,n.jsx)(t.em,{children:"Dijkstra's algorithm"})," comes in."]}),"\n",(0,n.jsx)(t.h2,{id:"dijkstras-algorithm",children:"Dijkstra's algorithm"}),"\n",(0,n.jsxs)(t.p,{children:["I'll start with a well-known meme about Dijkstra's algorithm:\n",(0,n.jsx)(t.img,{alt:"Dijkstra's algorithm meme",src:s(3260).Z+"",width:"960",height:"724"})]}),"\n",(0,n.jsx)(t.p,{children:"And then follow up on that with the actual backstory from Dijkstra himself:"}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsx)(t.p,{children:"What is the shortest way to travel from Rotterdam to Groningen, in general:\nfrom given city to given city. It is the algorithm for the shortest path,\nwhich I designed in about twenty minutes. One morning I was shopping in\nAmsterdam with my young fianc\xe9e, and tired, we sat down on the caf\xe9 terrace to\ndrink a cup of coffee and I was just thinking about whether I could do this,\nand I then designed the algorithm for the shortest path. As I said, it was\na twenty-minute invention. In fact, it was published in '59, three years\nlater. The publication is still readable, it is, in fact, quite nice. One of\nthe reasons that it is so nice was that I designed it without pencil and\npaper. I learned later that one of the advantages of designing without pencil\nand paper is that you are almost forced to avoid all avoidable complexities.\nEventually, that algorithm became to my great amazement, one of the\ncornerstones of my fame."}),"\n",(0,n.jsx)(t.p,{children:"\u2014 Edsger Dijkstra, in an interview with Philip L. Frana, Communications of the\nACM, 2001"}),"\n"]}),"\n",(0,n.jsx)(t.admonition,{title:"Precondition",type:"caution",children:(0,n.jsxs)(t.p,{children:["As our own na\xefve algorithm, Dijkstra's algorithm has a precondition that places\na requirement of ",(0,n.jsx)(t.em,{children:"no edges with negative weights"})," in the graph. This\nprecondition is required because of the nature of the algorithm that requires\nmonotonically non-decreasing changes in the costs of shortest paths."]})}),"\n",(0,n.jsx)(t.h2,{id:"short-description",children:"Short description"}),"\n",(0,n.jsx)(t.p,{children:"Let's have a brief look at the pseudocode taken from the Wikipedia:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"function Dijkstra(Graph, source):\n for each vertex v in Graph.Vertices:\n dist[v] \u2190 INFINITY\n prev[v] \u2190 UNDEFINED\n add v to Q\n dist[source] \u2190 0\n\n while Q is not empty:\n u \u2190 vertex in Q with min dist[u]\n remove u from Q\n\n for each neighbor v of u still in Q:\n alt \u2190 dist[u] + Graph.Edges(u, v)\n if alt < dist[v]:\n dist[v] \u2190 alt\n prev[v] \u2190 u\n\n return dist[], prev[]\n"})}),"\n",(0,n.jsx)(t.p,{children:"Dijkstra's algorithm works in such way that it always tries to find the shortest\npaths from a vertex to which it already has a shortest path. This may result in\nfinding the shortest path to another vertex, or at least some path, till further\nrelaxation."}),"\n",(0,n.jsxs)(t.p,{children:["Given that we need to ",(0,n.jsx)(t.strong,{children:"always"})," choose the ",(0,n.jsx)(t.em,{children:"cheapest"})," vertex, we can use a min\nheap to our advantage which can further improve the time complexity of the\nalgorithm."]}),"\n",(0,n.jsx)(t.h2,{id:"used-techniques",children:"Used techniques"}),"\n",(0,n.jsxs)(t.p,{children:["This algorithm leverages the ",(0,n.jsx)(t.em,{children:"dynamic programming"})," technique that has already\nbeen mentioned with regards to the ",(0,n.jsx)(t.em,{children:"Bellman-Ford"})," algorithm and also ",(0,n.jsx)(t.em,{children:"greedy"}),"\ntechnique. Let's talk about them both!"]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Dynamic programming"})," technique comes from the fact that we are continuously\nbuilding on top of the shortest paths that we have found so far. We slowly build\nthe shortest paths from the given source vertex to all other vertices that are\nreachable."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Greedy"})," technique is utilized in such way that Dijkstra's algorithm always\nimproves the shortest paths from the vertex that is the closest, i.e. it tries\nextending the shortest path to some vertex by appending an edge, such extended\npath may (or may not) be the shortest path to another vertex."]}),"\n",(0,n.jsx)(t.admonition,{title:"Greedy algorithms",type:"tip",children:(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Greedy algorithms"})," are algorithms that choose the most optimal action\n",(0,n.jsx)(t.strong,{children:"at the moment"}),"."]})}),"\n",(0,n.jsx)(t.p,{children:"The reason why the algorithm requires no edges with negative weights comes from\nthe fact that it's greedy. By laying the requirement of non-negative weights in\nthe graph we are guaranteed that at any given moment of processing outgoing\nedges from a vertex, we already have a shortest path to the given vertex. This\nmeans that either this is the shortest path, or there is some other vertex that\nmay have a higher cost, but the outgoing edge compensates for it."}),"\n",(0,n.jsx)(t.h2,{id:"implementation",children:"Implementation"}),"\n",(0,n.jsx)(t.p,{children:"Firstly we need to have some priority queue wrappers. C++ itself offers\nfunctions that can be used for maintaining max heaps. They also have generalized\nversion with any ordering, in our case we need reverse ordering, because we need\nthe min heap."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-cpp",children:"using pqueue_item_t = std::pair;\nusing pqueue_t = std::vector;\n\nauto pushq(pqueue_t& q, pqueue_item_t v) -> void {\n q.push_back(v);\n std::push_heap(q.begin(), q.end(), std::greater<>{});\n}\n\nauto popq(pqueue_t& q) -> std::optional {\n if (q.empty()) {\n return {};\n }\n\n std::pop_heap(q.begin(), q.end(), std::greater<>{});\n pqueue_item_t top = q.back();\n q.pop_back();\n\n return std::make_optional(top);\n}\n"})}),"\n",(0,n.jsx)(t.p,{children:"And now we can finally move to the actual implementation of the Dijkstra's\nalgorithm:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-cpp",children:"auto dijkstra(const graph& g, const vertex_t& source)\n -> std::vector> {\n // make sure that \u2039source\u203a exists\n assert(g.has(source));\n\n // initialize the distances\n std::vector> distances(\n g.height(), std::vector(g.width(), graph::unreachable()));\n\n // initialize the visited\n std::vector> visited(g.height(),\n std::vector(g.width(), false));\n\n // \u2039source\u203a destination denotes the beginning where the cost is 0\n auto [sx, sy] = source;\n distances[sy][sx] = 0;\n\n pqueue_t priority_queue{std::make_pair(0, source)};\n std::optional item{};\n while ((item = popq(priority_queue))) {\n auto [cost, u] = *item;\n auto [x, y] = u;\n\n // we have already found the shortest path\n if (visited[y][x]) {\n continue;\n }\n visited[y][x] = true;\n\n for (const auto& [dx, dy] : DIRECTIONS) {\n auto v = std::make_pair(x + dx, y + dy);\n auto cost = g.cost(u, v);\n\n // if we can move to the cell and it's better, relax\xb9 it and update queue\n if (cost != graph::unreachable() &&\n distances[y][x] + cost < distances[y + dy][x + dx]) {\n distances[y + dy][x + dx] = distances[y][x] + cost;\n pushq(priority_queue, std::make_pair(distances[y + dy][x + dx], v));\n }\n }\n }\n\n return distances;\n}\n"})}),"\n",(0,n.jsx)(t.h2,{id:"time-complexity",children:"Time complexity"}),"\n",(0,n.jsx)(t.p,{children:"The time complexity of Dijkstra's algorithm differs based on the backing data\nstructure."}),"\n",(0,n.jsxs)(t.p,{children:["The original implementation doesn't leverage the heap which results in\nrepetitive ",(0,n.jsx)(t.em,{children:"look up"})," of the \u201cclosest\u201d vertex, hence we get the following\nworst-case time complexity in the ",(0,n.jsx)(t.em,{children:"Bachmann-Landau"})," notation:"]}),"\n",(0,n.jsx)(t.span,{className:"katex-display",children:(0,n.jsxs)(t.span,{className:"katex",children:[(0,n.jsx)(t.span,{className:"katex-mathml",children:(0,n.jsx)(t.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(t.semantics,{children:[(0,n.jsxs)(t.mrow,{children:[(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u0398"}),(0,n.jsx)(t.mo,{stretchy:"false",children:"("}),(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u2223"}),(0,n.jsx)(t.mi,{children:"V"}),(0,n.jsxs)(t.msup,{children:[(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u2223"}),(0,n.jsx)(t.mn,{children:"2"})]}),(0,n.jsx)(t.mo,{stretchy:"false",children:")"})]}),(0,n.jsx)(t.annotation,{encoding:"application/x-tex",children:"\\Theta(\\vert V \\vert^2)"})]})})}),(0,n.jsx)(t.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(t.span,{className:"base",children:[(0,n.jsx)(t.span,{className:"strut",style:{height:"1.1141em",verticalAlign:"-0.25em"}}),(0,n.jsx)(t.span,{className:"mord",children:"\u0398"}),(0,n.jsx)(t.span,{className:"mopen",children:"("}),(0,n.jsx)(t.span,{className:"mord",children:"\u2223"}),(0,n.jsx)(t.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,n.jsxs)(t.span,{className:"mord",children:[(0,n.jsx)(t.span,{className:"mord",children:"\u2223"}),(0,n.jsx)(t.span,{className:"msupsub",children:(0,n.jsx)(t.span,{className:"vlist-t",children:(0,n.jsx)(t.span,{className:"vlist-r",children:(0,n.jsx)(t.span,{className:"vlist",style:{height:"0.8641em"},children:(0,n.jsxs)(t.span,{style:{top:"-3.113em",marginRight:"0.05em"},children:[(0,n.jsx)(t.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(t.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(t.span,{className:"mord mtight",children:"2"})})]})})})})})]}),(0,n.jsx)(t.span,{className:"mclose",children:")"})]})})]})}),"\n",(0,n.jsx)(t.p,{children:"If we turn our attention to the backing data structure, we always want the\n\u201ccheapest\u201d vertex, that's why we can use the min heap, given that we use\nFibonacci heap we can achieve the following amortized time complexity:"}),"\n",(0,n.jsx)(t.span,{className:"katex-display",children:(0,n.jsxs)(t.span,{className:"katex",children:[(0,n.jsx)(t.span,{className:"katex-mathml",children:(0,n.jsx)(t.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(t.semantics,{children:[(0,n.jsxs)(t.mrow,{children:[(0,n.jsx)(t.mi,{mathvariant:"script",children:"O"}),(0,n.jsx)(t.mo,{stretchy:"false",children:"("}),(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u2223"}),(0,n.jsx)(t.mi,{children:"E"}),(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u2223"}),(0,n.jsx)(t.mo,{children:"+"}),(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u2223"}),(0,n.jsx)(t.mi,{children:"V"}),(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u2223"}),(0,n.jsx)(t.mo,{children:"\u22c5"}),(0,n.jsx)(t.mi,{children:"log"}),(0,n.jsx)(t.mo,{children:"\u2061"}),(0,n.jsxs)(t.mrow,{children:[(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u2223"}),(0,n.jsx)(t.mi,{children:"V"}),(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u2223"})]}),(0,n.jsx)(t.mo,{stretchy:"false",children:")"})]}),(0,n.jsx)(t.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(\\vert E \\vert + \\vert V \\vert \\cdot \\log{\\vert V \\vert})"})]})})}),(0,n.jsxs)(t.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(t.span,{className:"base",children:[(0,n.jsx)(t.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,n.jsx)(t.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,n.jsx)(t.span,{className:"mopen",children:"("}),(0,n.jsx)(t.span,{className:"mord",children:"\u2223"}),(0,n.jsx)(t.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(t.span,{className:"mord",children:"\u2223"}),(0,n.jsx)(t.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(t.span,{className:"mbin",children:"+"}),(0,n.jsx)(t.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,n.jsxs)(t.span,{className:"base",children:[(0,n.jsx)(t.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,n.jsx)(t.span,{className:"mord",children:"\u2223"}),(0,n.jsx)(t.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,n.jsx)(t.span,{className:"mord",children:"\u2223"}),(0,n.jsx)(t.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(t.span,{className:"mbin",children:"\u22c5"}),(0,n.jsx)(t.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,n.jsxs)(t.span,{className:"base",children:[(0,n.jsx)(t.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,n.jsxs)(t.span,{className:"mop",children:["lo",(0,n.jsx)(t.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,n.jsx)(t.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,n.jsxs)(t.span,{className:"mord",children:[(0,n.jsx)(t.span,{className:"mord",children:"\u2223"}),(0,n.jsx)(t.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,n.jsx)(t.span,{className:"mord",children:"\u2223"})]}),(0,n.jsx)(t.span,{className:"mclose",children:")"})]})]})]})}),"\n",(0,n.jsx)(t.admonition,{title:"Fibonacci heap",type:"tip",children:(0,n.jsxs)(t.p,{children:["Fibonacci heap is known as the heap that provides ",(0,n.jsxs)(t.span,{className:"katex",children:[(0,n.jsx)(t.span,{className:"katex-mathml",children:(0,n.jsx)(t.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(t.semantics,{children:[(0,n.jsxs)(t.mrow,{children:[(0,n.jsx)(t.mi,{mathvariant:"normal",children:"\u0398"}),(0,n.jsx)(t.mo,{stretchy:"false",children:"("}),(0,n.jsx)(t.mn,{children:"1"}),(0,n.jsx)(t.mo,{stretchy:"false",children:")"})]}),(0,n.jsx)(t.annotation,{encoding:"application/x-tex",children:"\\Theta(1)"})]})})}),(0,n.jsx)(t.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(t.span,{className:"base",children:[(0,n.jsx)(t.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,n.jsx)(t.span,{className:"mord",children:"\u0398"}),(0,n.jsx)(t.span,{className:"mopen",children:"("}),(0,n.jsx)(t.span,{className:"mord",children:"1"}),(0,n.jsx)(t.span,{className:"mclose",children:")"})]})})]})," ",(0,n.jsx)(t.strong,{children:"amortized"}),"\ninsertion and ",(0,n.jsxs)(t.span,{className:"katex",children:[(0,n.jsx)(t.span,{className:"katex-mathml",children:(0,n.jsx)(t.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(t.semantics,{children:[(0,n.jsxs)(t.mrow,{children:[(0,n.jsx)(t.mi,{mathvariant:"script",children:"O"}),(0,n.jsx)(t.mo,{stretchy:"false",children:"("}),(0,n.jsx)(t.mi,{children:"log"}),(0,n.jsx)(t.mo,{children:"\u2061"}),(0,n.jsx)(t.mi,{children:"n"}),(0,n.jsx)(t.mo,{stretchy:"false",children:")"})]}),(0,n.jsx)(t.annotation,{encoding:"application/x-tex",children:"\\mathcal{O}(\\log{n})"})]})})}),(0,n.jsx)(t.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(t.span,{className:"base",children:[(0,n.jsx)(t.span,{className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,n.jsx)(t.span,{className:"mord mathcal",style:{marginRight:"0.02778em"},children:"O"}),(0,n.jsx)(t.span,{className:"mopen",children:"("}),(0,n.jsxs)(t.span,{className:"mop",children:["lo",(0,n.jsx)(t.span,{style:{marginRight:"0.01389em"},children:"g"})]}),(0,n.jsx)(t.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,n.jsx)(t.span,{className:"mord",children:(0,n.jsx)(t.span,{className:"mord mathnormal",children:"n"})}),(0,n.jsx)(t.span,{className:"mclose",children:")"})]})})]})," ",(0,n.jsx)(t.strong,{children:"amortized"})," removal of the top (either\nmin or max)."]})}),"\n",(0,n.jsx)(t.h2,{id:"running-the-dijkstra",children:"Running the Dijkstra"}),"\n",(0,n.jsx)(t.p,{children:"Let's run our code:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Normal cost: 1\nVortex cost: 5\nGraph:\n#############\n#..#..*.*.**#\n##***.....**#\n#..########.#\n#...###...#.#\n#..#...##.#.#\n#..#.*.#..#.#\n#D...#....#.#\n########*.*.#\n#S..........#\n#############\n[Finite BF] Cost: 22\n[Bellman-Ford] Cost: 22\n[Dijkstra] Cost: 22\n"})}),"\n",(0,n.jsx)(t.p,{children:"OK, so it seems to be working just fine. Now the question arises:"}),"\n",(0,n.jsxs)(t.blockquote,{children:["\n",(0,n.jsx)(t.p,{children:"What happens when we have negative weights in our graph?"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"busting-the-myth-about-looping-dijkstra",children:"Busting the myth about looping Dijkstra"}),"\n",(0,n.jsxs)(t.p,{children:["One of the very common misconception about Dijkstra's algorithm is that it loops\ninfinitely when you have negative weights or loops in the graph. Well, if we use\nour ",(0,n.jsx)(t.em,{children:"propelling vortices"}),", not only we have the negative weights, but also the\nnegative loops. Let's run our code! Our first na\xefve approach was actually\nlooping:"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Normal cost: 1\nVortex cost: -1\nGraph:\n#############\n#..#..*.*.**#\n##***.....**#\n#..########.#\n#...###...#.#\n#..#...##.#.#\n#..#.*.#..#.#\n#D...#....#.#\n########*.*.#\n#S..........#\n#############\n[Finite BF] Cost: -240\n[Bellman-Ford] Found a negative loop\n[Bellman-Ford] Cost: -240\n[Dijkstra] Cost: 14\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Well, it definitely doesn't loop. How much does ",(0,n.jsx)(t.code,{children:"14"})," make sense is a different\nmatter."]}),"\n",(0,n.jsx)(t.admonition,{title:"Variations",type:"info",children:(0,n.jsxs)(t.p,{children:["There are multiple variations of the Dijkstra's algorithm. You ",(0,n.jsx)(t.strong,{children:"can"})," implement\nit in such way that with negative weights or loops it loops infinitely, but it\ncan be countered. In our case we keep the track of the vertices that already got\na shortest path established via the ",(0,n.jsx)(t.code,{children:"visited"}),", that's how even multiple entries\nfor one vertex in the heap are not an issue."]})}),"\n",(0,n.jsx)(t.h2,{id:"summary",children:"Summary"}),"\n",(0,n.jsx)(t.p,{children:"Now we have an algorithm for finding the shortest path that is faster than our\noriginal na\xefve brute-force or Bellman-Ford. However we need to keep in mind its\nrequirement of no negative weights for correct functioning."}),"\n",(0,n.jsx)(t.p,{children:"You can also see how we used our thought process of figuring out the worst-case\ntime complexity for the na\xefve or Bellman-Ford algorithm to improve the original\npath-finding algorithms."})]})}function c(e={}){const{wrapper:t}={...(0,a.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(m,{...e})}):m(e)}},3260:(e,t,s)=>{s.d(t,{Z:()=>n});const n=s.p+"assets/images/dijkstra-meme-405d6b8dcc7aec5846fef402abfa8317.jpg"},11151:(e,t,s)=>{s.d(t,{Z:()=>o,a:()=>r});var n=s(67294);const a={},i=n.createContext(a);function r(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6e3cbca1.6248e0be.js b/assets/js/6e3cbca1.5d0620d6.js similarity index 57% rename from assets/js/6e3cbca1.6248e0be.js rename to assets/js/6e3cbca1.5d0620d6.js index 4b245a5..ca932f0 100644 --- a/assets/js/6e3cbca1.6248e0be.js +++ b/assets/js/6e3cbca1.5d0620d6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[3276],{29538:e=>{e.exports=JSON.parse('{"pluginId":"algorithms","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"autogeneratedBar":[{"type":"link","label":"Introduction","href":"/algorithms/","docId":"algorithms-intro","unlisted":false},{"type":"category","label":"Algorithms and Correctness","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Vague postconditions and proving correctness of algorithms","href":"/algorithms/algorithms-correctness/postcondition-ambiguity","docId":"algorithms-correctness/postcondition-ambiguity","unlisted":false}],"href":"/algorithms/category/algorithms-and-correctness"},{"type":"category","label":"Asymptotic Notation and Time Complexity","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Time complexity of \u2039extend\u203a","href":"/algorithms/time-complexity/extend","docId":"time-complexity/extend","unlisted":false}],"href":"/algorithms/category/asymptotic-notation-and-time-complexity"},{"type":"category","label":"Recursion","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Recursion and backtracking with Robot Karel","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Solution to the problem","href":"/algorithms/recursion/karel/solution","docId":"recursion/2022-11-29-karel/solution","unlisted":false}],"href":"/algorithms/recursion/karel"},{"type":"category","label":"Introduction to dynamic programming","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Na\xefve solution","href":"/algorithms/recursion/pyramid-slide-down/naive","docId":"recursion/2023-08-17-pyramid-slide-down/naive","unlisted":false},{"type":"link","label":"Greedy solution","href":"/algorithms/recursion/pyramid-slide-down/greedy","docId":"recursion/2023-08-17-pyramid-slide-down/greedy","unlisted":false},{"type":"link","label":"Top-down DP solution","href":"/algorithms/recursion/pyramid-slide-down/top-down-dp","docId":"recursion/2023-08-17-pyramid-slide-down/top-down-dp","unlisted":false},{"type":"link","label":"Bottom-up DP solution","href":"/algorithms/recursion/pyramid-slide-down/bottom-up-dp","docId":"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp","unlisted":false}],"href":"/algorithms/recursion/pyramid-slide-down"}],"href":"/algorithms/category/recursion"},{"type":"category","label":"Red-Black Trees","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f","href":"/algorithms/rb-trees/applications","docId":"rb-trees/applications","unlisted":false},{"type":"link","label":"On the rules of the red-black tree","href":"/algorithms/rb-trees/rules","docId":"rb-trees/rules","unlisted":false}],"href":"/algorithms/category/red-black-trees"},{"type":"category","label":"Graphs","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Iterative algorithms via iterators","href":"/algorithms/graphs/iterative-and-iterators","docId":"graphs/iterative-and-iterators","unlisted":false},{"type":"link","label":"Distance boundaries from BFS tree on undirected graphs","href":"/algorithms/graphs/bfs-tree","docId":"graphs/bfs-tree","unlisted":false}],"href":"/algorithms/category/graphs"},{"type":"category","label":"Hash Tables","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Breaking Hash Table","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Breaking Python","href":"/algorithms/hash-tables/breaking/python","docId":"hash-tables/2023-11-28-breaking/python","unlisted":false},{"type":"link","label":"Possible Mitigations","href":"/algorithms/hash-tables/breaking/mitigations","docId":"hash-tables/2023-11-28-breaking/mitigations","unlisted":false}],"href":"/algorithms/hash-tables/breaking"}],"href":"/algorithms/category/hash-tables"}]},"docs":{"algorithms-correctness/postcondition-ambiguity":{"id":"algorithms-correctness/postcondition-ambiguity","title":"Vague postconditions and proving correctness of algorithms","description":"Debugging and testing with precise postconditions.\\n","sidebar":"autogeneratedBar"},"algorithms-intro":{"id":"algorithms-intro","title":"Introduction","description":"In this part you can find \u201crandom\u201d additional materials I have written over the","sidebar":"autogeneratedBar"},"graphs/bfs-tree":{"id":"graphs/bfs-tree","title":"Distance boundaries from BFS tree on undirected graphs","description":"Short explanation of distance boundaries deduced from a BFS tree.\\n","sidebar":"autogeneratedBar"},"graphs/iterative-and-iterators":{"id":"graphs/iterative-and-iterators","title":"Iterative algorithms via iterators","description":"Iterative DFS using iterators.\\n","sidebar":"autogeneratedBar"},"hash-tables/2023-11-28-breaking/breaking":{"id":"hash-tables/2023-11-28-breaking/breaking","title":"Breaking Hash Table","description":"How to get the linear time complexity in a hash table.\\n","sidebar":"autogeneratedBar"},"hash-tables/2023-11-28-breaking/mitigations":{"id":"hash-tables/2023-11-28-breaking/mitigations","title":"Possible Mitigations","description":"Talking about the ways how to prevent the attacks on the hash table.\\n","sidebar":"autogeneratedBar"},"hash-tables/2023-11-28-breaking/python":{"id":"hash-tables/2023-11-28-breaking/python","title":"Breaking Python","description":"Actually getting the worst-case time complexity in Python.\\n","sidebar":"autogeneratedBar"},"rb-trees/applications":{"id":"rb-trees/applications","title":"Pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f","description":"Uk\xe1zka pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f v standardn\xedch kni\u017enic\xedch zn\xe1m\xfdch jazyk\u016f.\\n","sidebar":"autogeneratedBar"},"rb-trees/rules":{"id":"rb-trees/rules","title":"On the rules of the red-black tree","description":"Shower thoughts on the rules of the red-black tree.\\n","sidebar":"autogeneratedBar"},"recursion/2022-11-29-karel/karel":{"id":"recursion/2022-11-29-karel/karel","title":"Recursion and backtracking with Robot Karel","description":"A problem with too many restrictions.\\n","sidebar":"autogeneratedBar"},"recursion/2022-11-29-karel/solution":{"id":"recursion/2022-11-29-karel/solution","title":"Solution to the problem","description":"Solving the problem introduced in the previous post.\\n","sidebar":"autogeneratedBar"},"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp":{"id":"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp","title":"Bottom-up DP solution","description":"Bottom-up DP solution of the Pyramid Slide Down.\\n","sidebar":"autogeneratedBar"},"recursion/2023-08-17-pyramid-slide-down/greedy":{"id":"recursion/2023-08-17-pyramid-slide-down/greedy","title":"Greedy solution","description":"Greedy solution of the Pyramid Slide Down.\\n","sidebar":"autogeneratedBar"},"recursion/2023-08-17-pyramid-slide-down/naive":{"id":"recursion/2023-08-17-pyramid-slide-down/naive","title":"Na\xefve solution","description":"Na\xefve solution of the Pyramid Slide Down.\\n","sidebar":"autogeneratedBar"},"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down":{"id":"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down","title":"Introduction to dynamic programming","description":"Solving a problem in different ways.\\n","sidebar":"autogeneratedBar"},"recursion/2023-08-17-pyramid-slide-down/top-down-dp":{"id":"recursion/2023-08-17-pyramid-slide-down/top-down-dp","title":"Top-down DP solution","description":"Top-down DP solution of the Pyramid Slide Down.\\n","sidebar":"autogeneratedBar"},"time-complexity/extend":{"id":"time-complexity/extend","title":"Time complexity of \u2039extend\u203a","description":"How to make inefficient algorithm unknowingly.\\n","sidebar":"autogeneratedBar"}}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[3276],{29538:e=>{e.exports=JSON.parse('{"pluginId":"algorithms","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"autogeneratedBar":[{"type":"link","label":"Introduction","href":"/algorithms/","docId":"algorithms-intro","unlisted":false},{"type":"category","label":"Algorithms and Correctness","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Vague postconditions and proving correctness of algorithms","href":"/algorithms/algorithms-correctness/postcondition-ambiguity","docId":"algorithms-correctness/postcondition-ambiguity","unlisted":false}],"href":"/algorithms/category/algorithms-and-correctness"},{"type":"category","label":"Asymptotic Notation and Time Complexity","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Time complexity of \u2039extend\u203a","href":"/algorithms/time-complexity/extend","docId":"time-complexity/extend","unlisted":false}],"href":"/algorithms/category/asymptotic-notation-and-time-complexity"},{"type":"category","label":"Recursion","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Recursion and backtracking with Robot Karel","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Solution to the problem","href":"/algorithms/recursion/karel/solution","docId":"recursion/2022-11-29-karel/solution","unlisted":false}],"href":"/algorithms/recursion/karel"},{"type":"category","label":"Introduction to dynamic programming","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Na\xefve solution","href":"/algorithms/recursion/pyramid-slide-down/naive","docId":"recursion/2023-08-17-pyramid-slide-down/naive","unlisted":false},{"type":"link","label":"Greedy solution","href":"/algorithms/recursion/pyramid-slide-down/greedy","docId":"recursion/2023-08-17-pyramid-slide-down/greedy","unlisted":false},{"type":"link","label":"Top-down DP solution","href":"/algorithms/recursion/pyramid-slide-down/top-down-dp","docId":"recursion/2023-08-17-pyramid-slide-down/top-down-dp","unlisted":false},{"type":"link","label":"Bottom-up DP solution","href":"/algorithms/recursion/pyramid-slide-down/bottom-up-dp","docId":"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp","unlisted":false}],"href":"/algorithms/recursion/pyramid-slide-down"}],"href":"/algorithms/category/recursion"},{"type":"category","label":"Red-Black Trees","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f","href":"/algorithms/rb-trees/applications","docId":"rb-trees/applications","unlisted":false},{"type":"link","label":"On the rules of the red-black tree","href":"/algorithms/rb-trees/rules","docId":"rb-trees/rules","unlisted":false}],"href":"/algorithms/category/red-black-trees"},{"type":"category","label":"Graphs","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Iterative algorithms via iterators","href":"/algorithms/graphs/iterative-and-iterators","docId":"graphs/iterative-and-iterators","unlisted":false},{"type":"link","label":"Distance boundaries from BFS tree on undirected graphs","href":"/algorithms/graphs/bfs-tree","docId":"graphs/bfs-tree","unlisted":false}],"href":"/algorithms/category/graphs"},{"type":"category","label":"Paths in Graphs","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"From BF to A*","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"BF","href":"/algorithms/paths/bf-to-astar/bf","docId":"paths/2024-01-01-bf-to-astar/bf","unlisted":false},{"type":"link","label":"Dijkstra\'s algorithm","href":"/algorithms/paths/bf-to-astar/dijkstra","docId":"paths/2024-01-01-bf-to-astar/dijkstra","unlisted":false},{"type":"link","label":"A* algorithm","href":"/algorithms/paths/bf-to-astar/astar","docId":"paths/2024-01-01-bf-to-astar/astar","unlisted":false}],"href":"/algorithms/paths/bf-to-astar"}],"href":"/algorithms/category/paths-in-graphs"},{"type":"category","label":"Hash Tables","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Breaking Hash Table","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Breaking Python","href":"/algorithms/hash-tables/breaking/python","docId":"hash-tables/2023-11-28-breaking/python","unlisted":false},{"type":"link","label":"Possible Mitigations","href":"/algorithms/hash-tables/breaking/mitigations","docId":"hash-tables/2023-11-28-breaking/mitigations","unlisted":false}],"href":"/algorithms/hash-tables/breaking"}],"href":"/algorithms/category/hash-tables"}]},"docs":{"algorithms-correctness/postcondition-ambiguity":{"id":"algorithms-correctness/postcondition-ambiguity","title":"Vague postconditions and proving correctness of algorithms","description":"Debugging and testing with precise postconditions.\\n","sidebar":"autogeneratedBar"},"algorithms-intro":{"id":"algorithms-intro","title":"Introduction","description":"In this part you can find \u201crandom\u201d additional materials I have written over the","sidebar":"autogeneratedBar"},"graphs/bfs-tree":{"id":"graphs/bfs-tree","title":"Distance boundaries from BFS tree on undirected graphs","description":"Short explanation of distance boundaries deduced from a BFS tree.\\n","sidebar":"autogeneratedBar"},"graphs/iterative-and-iterators":{"id":"graphs/iterative-and-iterators","title":"Iterative algorithms via iterators","description":"Iterative DFS using iterators.\\n","sidebar":"autogeneratedBar"},"hash-tables/2023-11-28-breaking/breaking":{"id":"hash-tables/2023-11-28-breaking/breaking","title":"Breaking Hash Table","description":"How to get the linear time complexity in a hash table.\\n","sidebar":"autogeneratedBar"},"hash-tables/2023-11-28-breaking/mitigations":{"id":"hash-tables/2023-11-28-breaking/mitigations","title":"Possible Mitigations","description":"Talking about the ways how to prevent the attacks on the hash table.\\n","sidebar":"autogeneratedBar"},"hash-tables/2023-11-28-breaking/python":{"id":"hash-tables/2023-11-28-breaking/python","title":"Breaking Python","description":"Actually getting the worst-case time complexity in Python.\\n","sidebar":"autogeneratedBar"},"paths/2024-01-01-bf-to-astar/astar":{"id":"paths/2024-01-01-bf-to-astar/astar","title":"A* algorithm","description":"Moving from Dijkstra\'s algorithm into the A* algorithm.\\n","sidebar":"autogeneratedBar"},"paths/2024-01-01-bf-to-astar/bf":{"id":"paths/2024-01-01-bf-to-astar/bf","title":"BF","description":"Solving the shortest path problem with a na\xefve approach that turns into\\nsomething.\\n","sidebar":"autogeneratedBar"},"paths/2024-01-01-bf-to-astar/dijkstra":{"id":"paths/2024-01-01-bf-to-astar/dijkstra","title":"Dijkstra\'s algorithm","description":"Moving from Bellman-Ford into the Dijsktra\'s algorithm.\\n","sidebar":"autogeneratedBar"},"paths/2024-01-01-bf-to-astar/index":{"id":"paths/2024-01-01-bf-to-astar/index","title":"From BF to A*","description":"Figuring out shortest-path problem from the BF to the A* algorithm.\\n","sidebar":"autogeneratedBar"},"rb-trees/applications":{"id":"rb-trees/applications","title":"Pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f","description":"Uk\xe1zka pou\u017eit\xed \u010derveno-\u010dern\xfdch strom\u016f v standardn\xedch kni\u017enic\xedch zn\xe1m\xfdch jazyk\u016f.\\n","sidebar":"autogeneratedBar"},"rb-trees/rules":{"id":"rb-trees/rules","title":"On the rules of the red-black tree","description":"Shower thoughts on the rules of the red-black tree.\\n","sidebar":"autogeneratedBar"},"recursion/2022-11-29-karel/karel":{"id":"recursion/2022-11-29-karel/karel","title":"Recursion and backtracking with Robot Karel","description":"A problem with too many restrictions.\\n","sidebar":"autogeneratedBar"},"recursion/2022-11-29-karel/solution":{"id":"recursion/2022-11-29-karel/solution","title":"Solution to the problem","description":"Solving the problem introduced in the previous post.\\n","sidebar":"autogeneratedBar"},"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp":{"id":"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp","title":"Bottom-up DP solution","description":"Bottom-up DP solution of the Pyramid Slide Down.\\n","sidebar":"autogeneratedBar"},"recursion/2023-08-17-pyramid-slide-down/greedy":{"id":"recursion/2023-08-17-pyramid-slide-down/greedy","title":"Greedy solution","description":"Greedy solution of the Pyramid Slide Down.\\n","sidebar":"autogeneratedBar"},"recursion/2023-08-17-pyramid-slide-down/naive":{"id":"recursion/2023-08-17-pyramid-slide-down/naive","title":"Na\xefve solution","description":"Na\xefve solution of the Pyramid Slide Down.\\n","sidebar":"autogeneratedBar"},"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down":{"id":"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down","title":"Introduction to dynamic programming","description":"Solving a problem in different ways.\\n","sidebar":"autogeneratedBar"},"recursion/2023-08-17-pyramid-slide-down/top-down-dp":{"id":"recursion/2023-08-17-pyramid-slide-down/top-down-dp","title":"Top-down DP solution","description":"Top-down DP solution of the Pyramid Slide Down.\\n","sidebar":"autogeneratedBar"},"time-complexity/extend":{"id":"time-complexity/extend","title":"Time complexity of \u2039extend\u203a","description":"How to make inefficient algorithm unknowingly.\\n","sidebar":"autogeneratedBar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/7052c0bc.54d577f1.js b/assets/js/7052c0bc.54d577f1.js new file mode 100644 index 0000000..f5608aa --- /dev/null +++ b/assets/js/7052c0bc.54d577f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[9731],{42286:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var o=n(85893),r=n(11151);const i={id:"cpp-intro",title:"Introduction",slug:"/"},c=void 0,a={id:"cpp-intro",title:"Introduction",description:"",source:"@site/cpp/00-intro.md",sourceDirName:".",slug:"/",permalink:"/cpp/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/cpp/00-intro.md",tags:[],version:"current",lastUpdatedAt:1704291155,formattedLastUpdatedAt:"Jan 3, 2024",sidebarPosition:0,frontMatter:{id:"cpp-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Exceptions and RAII",permalink:"/cpp/category/exceptions-and-raii"}},s={},p=[];function u(t){return(0,o.jsx)(o.Fragment,{})}function d(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u()}},11151:(t,e,n)=>{n.d(e,{Z:()=>a,a:()=>c});var o=n(67294);const r={},i=o.createContext(r);function c(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:c(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/7052c0bc.6b9d4e57.js b/assets/js/7052c0bc.6b9d4e57.js deleted file mode 100644 index dfca284..0000000 --- a/assets/js/7052c0bc.6b9d4e57.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[9731],{42286:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var o=n(85893),r=n(11151);const i={id:"cpp-intro",title:"Introduction",slug:"/"},c=void 0,s={id:"cpp-intro",title:"Introduction",description:"",source:"@site/cpp/00-intro.md",sourceDirName:".",slug:"/",permalink:"/cpp/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/cpp/00-intro.md",tags:[],version:"current",lastUpdatedAt:1703979877,formattedLastUpdatedAt:"Dec 30, 2023",sidebarPosition:0,frontMatter:{id:"cpp-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Exceptions and RAII",permalink:"/cpp/category/exceptions-and-raii"}},a={},p=[];function u(t){return(0,o.jsx)(o.Fragment,{})}function d(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u()}},11151:(t,e,n)=>{n.d(e,{Z:()=>s,a:()=>c});var o=n(67294);const r={},i=o.createContext(r);function c(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:c(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/794ef108.5b256546.js b/assets/js/794ef108.5b256546.js new file mode 100644 index 0000000..c521a1a --- /dev/null +++ b/assets/js/794ef108.5b256546.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[3803],{86427:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var o=n(85893),r=n(11151);const i={id:"c-intro",title:"Introduction",slug:"/"},s=void 0,c={id:"c-intro",title:"Introduction",description:"",source:"@site/c/00-intro.md",sourceDirName:".",slug:"/",permalink:"/c/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/00-intro.md",tags:[],version:"current",lastUpdatedAt:1704291155,formattedLastUpdatedAt:"Jan 3, 2024",sidebarPosition:0,frontMatter:{id:"c-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Bonuses",permalink:"/c/category/bonuses"}},a={},u=[];function d(t){return(0,o.jsx)(o.Fragment,{})}function l(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(d,{...t})}):d()}},11151:(t,e,n)=>{n.d(e,{Z:()=>c,a:()=>s});var o=n(67294);const r={},i=o.createContext(r);function s(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:s(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/794ef108.9378da0c.js b/assets/js/794ef108.9378da0c.js deleted file mode 100644 index 699301a..0000000 --- a/assets/js/794ef108.9378da0c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[3803],{86427:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var o=n(85893),r=n(11151);const i={id:"c-intro",title:"Introduction",slug:"/"},c=void 0,s={id:"c-intro",title:"Introduction",description:"",source:"@site/c/00-intro.md",sourceDirName:".",slug:"/",permalink:"/c/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/00-intro.md",tags:[],version:"current",lastUpdatedAt:1703979877,formattedLastUpdatedAt:"Dec 30, 2023",sidebarPosition:0,frontMatter:{id:"c-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Bonuses",permalink:"/c/category/bonuses"}},a={},u=[];function d(t){return(0,o.jsx)(o.Fragment,{})}function l(t={}){const{wrapper:e}={...(0,r.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(d,{...t})}):d()}},11151:(t,e,n)=>{n.d(e,{Z:()=>s,a:()=>c});var o=n(67294);const r={},i=o.createContext(r);function c(t){const e=o.useContext(i);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:c(t.components),o.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/84d1e0d8.a5a56acc.js b/assets/js/84d1e0d8.a5a56acc.js deleted file mode 100644 index 15f78c7..0000000 --- a/assets/js/84d1e0d8.a5a56acc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[1885],{49713:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var o=n(85893),s=n(11151);const r={id:"algorithms-intro",title:"Introduction",slug:"/"},i=void 0,a={id:"algorithms-intro",title:"Introduction",description:"In this part you can find \u201crandom\u201d additional materials I have written over the",source:"@site/algorithms/00-intro.md",sourceDirName:".",slug:"/",permalink:"/algorithms/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/00-intro.md",tags:[],version:"current",lastUpdatedAt:1703979877,formattedLastUpdatedAt:"Dec 30, 2023",sidebarPosition:0,frontMatter:{id:"algorithms-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Algorithms and Correctness",permalink:"/algorithms/category/algorithms-and-correctness"}},c={},d=[];function l(t){const e={a:"a",em:"em",p:"p",...(0,s.a)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(e.p,{children:["In this part you can find \u201crandom\u201d additional materials I have written over the\ncourse of teaching ",(0,o.jsx)(e.em,{children:"Algorithms and data structures I"}),"."]}),"\n",(0,o.jsx)(e.p,{children:"It is a various mix of stuff that may have been produced as a follow-up on some\nquestion asked at the seminar or spontanously."}),"\n",(0,o.jsxs)(e.p,{children:["If you have some ideas for posts, please do not hesitate to submit them as issues\nin the linked ",(0,o.jsx)(e.a,{href:"https://gitlab.fi.muni.cz/xfocko/kb/issues",children:"GitLab"}),"."]})]})}function u(t={}){const{wrapper:e}={...(0,s.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(l,{...t})}):l(t)}},11151:(t,e,n)=>{n.d(e,{Z:()=>a,a:()=>i});var o=n(67294);const s={},r=o.createContext(s);function i(t){const e=o.useContext(r);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),o.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/84d1e0d8.e078634a.js b/assets/js/84d1e0d8.e078634a.js new file mode 100644 index 0000000..d86312a --- /dev/null +++ b/assets/js/84d1e0d8.e078634a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[1885],{49713:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var o=n(85893),s=n(11151);const r={id:"algorithms-intro",title:"Introduction",slug:"/"},i=void 0,a={id:"algorithms-intro",title:"Introduction",description:"In this part you can find \u201crandom\u201d additional materials I have written over the",source:"@site/algorithms/00-intro.md",sourceDirName:".",slug:"/",permalink:"/algorithms/",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/00-intro.md",tags:[],version:"current",lastUpdatedAt:1704291155,formattedLastUpdatedAt:"Jan 3, 2024",sidebarPosition:0,frontMatter:{id:"algorithms-intro",title:"Introduction",slug:"/"},sidebar:"autogeneratedBar",next:{title:"Algorithms and Correctness",permalink:"/algorithms/category/algorithms-and-correctness"}},c={},d=[];function l(t){const e={a:"a",em:"em",p:"p",...(0,s.a)(),...t.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(e.p,{children:["In this part you can find \u201crandom\u201d additional materials I have written over the\ncourse of teaching ",(0,o.jsx)(e.em,{children:"Algorithms and data structures I"}),"."]}),"\n",(0,o.jsx)(e.p,{children:"It is a various mix of stuff that may have been produced as a follow-up on some\nquestion asked at the seminar or spontanously."}),"\n",(0,o.jsxs)(e.p,{children:["If you have some ideas for posts, please do not hesitate to submit them as issues\nin the linked ",(0,o.jsx)(e.a,{href:"https://gitlab.fi.muni.cz/xfocko/kb/issues",children:"GitLab"}),"."]})]})}function u(t={}){const{wrapper:e}={...(0,s.a)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(l,{...t})}):l(t)}},11151:(t,e,n)=>{n.d(e,{Z:()=>a,a:()=>i});var o=n(67294);const s={},r=o.createContext(s);function i(t){const e=o.useContext(r);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),o.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/97a42631.7eff63e9.js b/assets/js/97a42631.7eff63e9.js new file mode 100644 index 0000000..4ba17d1 --- /dev/null +++ b/assets/js/97a42631.7eff63e9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[1464],{77343:a=>{a.exports=JSON.parse('[{"label":"python","permalink":"/algorithms/tags/python","count":7},{"label":"testing","permalink":"/algorithms/tags/testing","count":1},{"label":"postconditions","permalink":"/algorithms/tags/postconditions","count":1},{"label":"sorting","permalink":"/algorithms/tags/sorting","count":1},{"label":"graphs","permalink":"/algorithms/tags/graphs","count":2},{"label":"bfs","permalink":"/algorithms/tags/bfs","count":1},{"label":"csharp","permalink":"/algorithms/tags/csharp","count":1},{"label":"iterators","permalink":"/algorithms/tags/iterators","count":1},{"label":"iterative","permalink":"/algorithms/tags/iterative","count":1},{"label":"cpp","permalink":"/algorithms/tags/cpp","count":7},{"label":"hash-tables","permalink":"/algorithms/tags/hash-tables","count":3},{"label":"dynamic programming","permalink":"/algorithms/tags/dynamic-programming","count":7},{"label":"astar","permalink":"/algorithms/tags/astar","count":1},{"label":"brute force","permalink":"/algorithms/tags/brute-force","count":2},{"label":"bellman ford","permalink":"/algorithms/tags/bellman-ford","count":2},{"label":"greedy","permalink":"/algorithms/tags/greedy","count":4},{"label":"dijkstra","permalink":"/algorithms/tags/dijkstra","count":2},{"label":"a star","permalink":"/algorithms/tags/a-star","count":1},{"label":"balanced trees","permalink":"/algorithms/tags/balanced-trees","count":2},{"label":"red-black trees","permalink":"/algorithms/tags/red-black-trees","count":2},{"label":"applications","permalink":"/algorithms/tags/applications","count":1},{"label":"karel","permalink":"/algorithms/tags/karel","count":2},{"label":"recursion","permalink":"/algorithms/tags/recursion","count":5},{"label":"backtracking","permalink":"/algorithms/tags/backtracking","count":2},{"label":"solution","permalink":"/algorithms/tags/solution","count":1},{"label":"java","permalink":"/algorithms/tags/java","count":5},{"label":"bottom-up-dp","permalink":"/algorithms/tags/bottom-up-dp","count":2},{"label":"exponential","permalink":"/algorithms/tags/exponential","count":2},{"label":"top-down-dp","permalink":"/algorithms/tags/top-down-dp","count":2},{"label":"c","permalink":"/algorithms/tags/c","count":1},{"label":"dynamic array","permalink":"/algorithms/tags/dynamic-array","count":1},{"label":"time complexity","permalink":"/algorithms/tags/time-complexity","count":1}]')}}]); \ No newline at end of file diff --git a/assets/js/97a42631.dd58f185.js b/assets/js/97a42631.dd58f185.js deleted file mode 100644 index dfdf989..0000000 --- a/assets/js/97a42631.dd58f185.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[1464],{77343:a=>{a.exports=JSON.parse('[{"label":"python","permalink":"/algorithms/tags/python","count":7},{"label":"testing","permalink":"/algorithms/tags/testing","count":1},{"label":"postconditions","permalink":"/algorithms/tags/postconditions","count":1},{"label":"sorting","permalink":"/algorithms/tags/sorting","count":1},{"label":"graphs","permalink":"/algorithms/tags/graphs","count":2},{"label":"bfs","permalink":"/algorithms/tags/bfs","count":1},{"label":"csharp","permalink":"/algorithms/tags/csharp","count":1},{"label":"iterators","permalink":"/algorithms/tags/iterators","count":1},{"label":"iterative","permalink":"/algorithms/tags/iterative","count":1},{"label":"cpp","permalink":"/algorithms/tags/cpp","count":3},{"label":"hash-tables","permalink":"/algorithms/tags/hash-tables","count":3},{"label":"balanced trees","permalink":"/algorithms/tags/balanced-trees","count":2},{"label":"red-black trees","permalink":"/algorithms/tags/red-black-trees","count":2},{"label":"applications","permalink":"/algorithms/tags/applications","count":1},{"label":"karel","permalink":"/algorithms/tags/karel","count":2},{"label":"recursion","permalink":"/algorithms/tags/recursion","count":5},{"label":"backtracking","permalink":"/algorithms/tags/backtracking","count":2},{"label":"solution","permalink":"/algorithms/tags/solution","count":1},{"label":"java","permalink":"/algorithms/tags/java","count":5},{"label":"dynamic-programming","permalink":"/algorithms/tags/dynamic-programming","count":3},{"label":"bottom-up-dp","permalink":"/algorithms/tags/bottom-up-dp","count":2},{"label":"greedy","permalink":"/algorithms/tags/greedy","count":2},{"label":"exponential","permalink":"/algorithms/tags/exponential","count":2},{"label":"top-down-dp","permalink":"/algorithms/tags/top-down-dp","count":2},{"label":"c","permalink":"/algorithms/tags/c","count":1},{"label":"dynamic array","permalink":"/algorithms/tags/dynamic-array","count":1},{"label":"time complexity","permalink":"/algorithms/tags/time-complexity","count":1}]')}}]); \ No newline at end of file diff --git a/assets/js/a2ba8888.ab09cb54.js b/assets/js/a2ba8888.ab09cb54.js new file mode 100644 index 0000000..f16d76e --- /dev/null +++ b/assets/js/a2ba8888.ab09cb54.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[8289],{55941:t=>{t.exports=JSON.parse('{"label":"brute force","permalink":"/algorithms/tags/brute-force","allTagsPath":"/algorithms/tags","count":2,"items":[{"id":"paths/2024-01-01-bf-to-astar/bf","title":"BF","description":"Solving the shortest path problem with a na\xefve approach that turns into\\nsomething.\\n","permalink":"/algorithms/paths/bf-to-astar/bf"},{"id":"paths/2024-01-01-bf-to-astar/index","title":"From BF to A*","description":"Figuring out shortest-path problem from the BF to the A* algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/b1288602.2a7bb9cd.js b/assets/js/b1288602.2a7bb9cd.js new file mode 100644 index 0000000..d565b63 --- /dev/null +++ b/assets/js/b1288602.2a7bb9cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[59],{51456:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var r=t(85893),s=t(11151);const o={title:"Submitting merge requests"},i="Submitting merge requests for review",a={id:"mr",title:"Submitting merge requests",description:"This tutorial aims to show you how to follow basic git workflow and submit changes",source:"@site/c/mr.md",sourceDirName:".",slug:"/mr",permalink:"/c/mr",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/mr.md",tags:[],version:"current",lastUpdatedAt:1704291155,formattedLastUpdatedAt:"Jan 3, 2024",frontMatter:{title:"Submitting merge requests"},sidebar:"autogeneratedBar",previous:{title:"Practice exam C",permalink:"/c/pexam/cams"}},c={},h=[{value:"Tutorial",id:"tutorial",level:2},{value:"Step #1 - Starting from the clean repository",id:"step-1---starting-from-the-clean-repository",level:3},{value:"Step #2 - Create new branch",id:"step-2---create-new-branch",level:3},{value:"Step #3 - Do the assignment",id:"step-3---do-the-assignment",level:3},{value:"Step #4 - Commit and upload the changes to GitLab",id:"step-4---commit-and-upload-the-changes-to-gitlab",level:3},{value:"Step #5 - Creating a merge request manually",id:"step-5---creating-a-merge-request-manually",level:3},{value:"Step #6 - Set assignees",id:"step-6---set-assignees",level:3},{value:"Step #7 - Return to default branch",id:"step-7---return-to-default-branch",level:3}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"submitting-merge-requests-for-review",children:"Submitting merge requests for review"}),"\n",(0,r.jsxs)(n.p,{children:["This tutorial aims to show you how to follow basic git workflow and submit changes\nthrough ",(0,r.jsx)(n.em,{children:"Merge Requests"})," for review."]}),"\n",(0,r.jsxs)(n.p,{children:["The rudimentary idea behind aims for changes to be present on a separate branch\nthat is supposedly ",(0,r.jsx)(n.em,{children:"merged"})," into the default branch. Till then changes can be reviewed\non ",(0,r.jsx)(n.em,{children:"Merge Request"})," and additional changes may be made based on the reviews. Once\nthe changes satisfy requirements, the merge request is merged."]}),"\n",(0,r.jsx)(n.h2,{id:"tutorial",children:"Tutorial"}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["Use this tutorial only for bonus assignments ",(0,r.jsx)(n.strong,{children:"made by your tutors"})," or in case\nyou need to make up for the absence."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-1---starting-from-the-clean-repository",children:"Step #1 - Starting from the clean repository"}),"\n",(0,r.jsxs)(n.p,{children:["In your repository (either locally or on aisa) type ",(0,r.jsx)(n.code,{children:"git status"})," and check if your\nrepository is clean and you are present on the main branch (",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"})," or\n",(0,r.jsx)(n.code,{children:"trunk"}),"). If you do not know what your default branch is, it is probably ",(0,r.jsx)(n.code,{children:"master"}),"\nand you should not be on any other branch."]}),"\n",(0,r.jsx)(n.p,{children:"Output of the command should look like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\nOn branch master # Or main or trunk.\nYour branch is up to date with 'origin/master'.\n\nnothing to commit, working tree clean\n"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["In case you are on different branch or there are uncommitted changes,\n",(0,r.jsx)(n.strong,{children:"do not continue!!!"})," Clean your repository (commit the changes or discard\nthem), before you continue."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-2---create-new-branch",children:"Step #2 - Create new branch"}),"\n",(0,r.jsx)(n.p,{children:"In your repository write command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git checkout -b BRANCH\nSwitched to a new branch 'BRANCH'\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Instead of ",(0,r.jsx)(n.code,{children:"BRANCH"})," use some reasonable name for the branch. For example if you\nare working on the seminar from 3rd week, name the branch ",(0,r.jsx)(n.code,{children:"seminar-03"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-3---do-the-assignment",children:"Step #3 - Do the assignment"}),"\n",(0,r.jsx)(n.p,{children:"Download the skeleton for the seminar assignment, extract and program. For example\nif you are working on 3rd seminar, you can do so by:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ wget https://www.fi.muni.cz/pb071/seminars/seminar-03/pb071-seminar-03.zip\naisa$ unzip pb071-seminar-03.zip\n# Now you should have directory 'seminar-03'.\naisa$ rm pb071-seminar-03.zip\naisa$ cd seminar-03\n# You can work on the assignment.\n"})}),"\n",(0,r.jsx)(n.h3,{id:"step-4---commit-and-upload-the-changes-to-gitlab",children:"Step #4 - Commit and upload the changes to GitLab"}),"\n",(0,r.jsxs)(n.p,{children:["The same way you ",(0,r.jsx)(n.em,{children:"add"})," and ",(0,r.jsx)(n.em,{children:"commit"})," files for the homework assignments, you do for\nthe seminar."]}),"\n",(0,r.jsxs)(n.p,{children:["Now you can upload the changes to GitLab. ",(0,r.jsx)(n.code,{children:"git push"})," is not enough, since repository\non GitLab does not know your new branch. You can solve this by adding arguments:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git push origin BRANCH\n...\nremote: To create a merge request for BRANCH, visit:\nremote: https://gitlab.fi.muni.cz/login/pb071/merge_requests/new?merge_request%5Bsource_branch%5D=BRANCH\n...\n"})}),"\n",(0,r.jsx)(n.p,{children:"In the output you should have a link for creating a merge request. If you see this\nlink, open it and skip next step."}),"\n",(0,r.jsx)(n.h3,{id:"step-5---creating-a-merge-request-manually",children:"Step #5 - Creating a merge request manually"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Open your repository on GitLab."}),"\n",(0,r.jsxs)(n.li,{children:["On the left panel click on ",(0,r.jsx)(n.em,{children:"Merge Requests"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"New Merge Request"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Source branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and ",(0,r.jsx)(n.code,{children:"BRANCH"}),", which you created."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Target branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and your default branch you have seen\nin the output of the first command. (most likely ",(0,r.jsx)(n.code,{children:"master"}),")"]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"Compare branches and continue"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-6---set-assignees",children:"Step #6 - Set assignees"}),"\n",(0,r.jsxs)(n.p,{children:["On the page that is opened, please check at the top that you are creating merge\nrequest ",(0,r.jsx)(n.strong,{children:"from"})," your new branch ",(0,r.jsx)(n.strong,{children:"to"})," your default branch (one of ",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"}),"\nor ",(0,r.jsx)(n.code,{children:"trunk"}),")."]}),"\n",(0,r.jsxs)(n.p,{children:["Then in the field ",(0,r.jsx)(n.em,{children:"Assignees"})," set your tutors based on the seminar group. You can\nuse login for a quick look up."]}),"\n",(0,r.jsxs)(n.p,{children:["In the end click on ",(0,r.jsx)(n.em,{children:"Submit merge request"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-7---return-to-default-branch",children:"Step #7 - Return to default branch"}),"\n",(0,r.jsx)(n.p,{children:"Homework assignments can be submitted only from branches specified in the rules\nfor the course. Because of that, before you do anything else, you should switch\nback to your default branch."}),"\n",(0,r.jsxs)(n.p,{children:["First of all, same as in step #1, check that your repository is clean with ",(0,r.jsx)(n.code,{children:"git status"}),".\nFor the sake of safety, do not continue without clean repository. Then with command\n",(0,r.jsx)(n.code,{children:"git checkout BRANCH"})," switch to your default branch ",(0,r.jsx)(n.code,{children:"BRANCH"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["If you do not know which branch is your default, try ",(0,r.jsx)(n.code,{children:"git branch"})," that outputs all branches in your repository. Default branch is typically ",(0,r.jsx)(n.code,{children:"master"}),", but can\nbe ",(0,r.jsx)(n.code,{children:"main"})," or ",(0,r.jsx)(n.code,{children:"trunk"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\n# Check if repository is clean\n\n# If you know, what is your default branch, you can skip next command.\naisa$ git branch\n# Find the default branch in the list; should be one of the `master`, `main` or\n# `trunk` and you should not have more than one of those.\n# In case the list clears the terminal and you cannot see shell prompt, you can\n# press `q` to quit the pager.\n\naisa$ git checkout master\n"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["Adapted from: ",(0,r.jsx)(n.a,{href:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html",children:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html"})]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>i});var r=t(67294);const s={},o=r.createContext(s);function i(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1288602.9422d997.js b/assets/js/b1288602.9422d997.js deleted file mode 100644 index bfa9e1d..0000000 --- a/assets/js/b1288602.9422d997.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[59],{51456:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var r=t(85893),s=t(11151);const o={title:"Submitting merge requests"},i="Submitting merge requests for review",a={id:"mr",title:"Submitting merge requests",description:"This tutorial aims to show you how to follow basic git workflow and submit changes",source:"@site/c/mr.md",sourceDirName:".",slug:"/mr",permalink:"/c/mr",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/mr.md",tags:[],version:"current",lastUpdatedAt:1703979877,formattedLastUpdatedAt:"Dec 30, 2023",frontMatter:{title:"Submitting merge requests"},sidebar:"autogeneratedBar",previous:{title:"Practice exam C",permalink:"/c/pexam/cams"}},c={},h=[{value:"Tutorial",id:"tutorial",level:2},{value:"Step #1 - Starting from the clean repository",id:"step-1---starting-from-the-clean-repository",level:3},{value:"Step #2 - Create new branch",id:"step-2---create-new-branch",level:3},{value:"Step #3 - Do the assignment",id:"step-3---do-the-assignment",level:3},{value:"Step #4 - Commit and upload the changes to GitLab",id:"step-4---commit-and-upload-the-changes-to-gitlab",level:3},{value:"Step #5 - Creating a merge request manually",id:"step-5---creating-a-merge-request-manually",level:3},{value:"Step #6 - Set assignees",id:"step-6---set-assignees",level:3},{value:"Step #7 - Return to default branch",id:"step-7---return-to-default-branch",level:3}];function l(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"submitting-merge-requests-for-review",children:"Submitting merge requests for review"}),"\n",(0,r.jsxs)(n.p,{children:["This tutorial aims to show you how to follow basic git workflow and submit changes\nthrough ",(0,r.jsx)(n.em,{children:"Merge Requests"})," for review."]}),"\n",(0,r.jsxs)(n.p,{children:["The rudimentary idea behind aims for changes to be present on a separate branch\nthat is supposedly ",(0,r.jsx)(n.em,{children:"merged"})," into the default branch. Till then changes can be reviewed\non ",(0,r.jsx)(n.em,{children:"Merge Request"})," and additional changes may be made based on the reviews. Once\nthe changes satisfy requirements, the merge request is merged."]}),"\n",(0,r.jsx)(n.h2,{id:"tutorial",children:"Tutorial"}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["Use this tutorial only for bonus assignments ",(0,r.jsx)(n.strong,{children:"made by your tutors"})," or in case\nyou need to make up for the absence."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-1---starting-from-the-clean-repository",children:"Step #1 - Starting from the clean repository"}),"\n",(0,r.jsxs)(n.p,{children:["In your repository (either locally or on aisa) type ",(0,r.jsx)(n.code,{children:"git status"})," and check if your\nrepository is clean and you are present on the main branch (",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"})," or\n",(0,r.jsx)(n.code,{children:"trunk"}),"). If you do not know what your default branch is, it is probably ",(0,r.jsx)(n.code,{children:"master"}),"\nand you should not be on any other branch."]}),"\n",(0,r.jsx)(n.p,{children:"Output of the command should look like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\nOn branch master # Or main or trunk.\nYour branch is up to date with 'origin/master'.\n\nnothing to commit, working tree clean\n"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["In case you are on different branch or there are uncommitted changes,\n",(0,r.jsx)(n.strong,{children:"do not continue!!!"})," Clean your repository (commit the changes or discard\nthem), before you continue."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-2---create-new-branch",children:"Step #2 - Create new branch"}),"\n",(0,r.jsx)(n.p,{children:"In your repository write command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git checkout -b BRANCH\nSwitched to a new branch 'BRANCH'\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Instead of ",(0,r.jsx)(n.code,{children:"BRANCH"})," use some reasonable name for the branch. For example if you\nare working on the seminar from 3rd week, name the branch ",(0,r.jsx)(n.code,{children:"seminar-03"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-3---do-the-assignment",children:"Step #3 - Do the assignment"}),"\n",(0,r.jsx)(n.p,{children:"Download the skeleton for the seminar assignment, extract and program. For example\nif you are working on 3rd seminar, you can do so by:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ wget https://www.fi.muni.cz/pb071/seminars/seminar-03/pb071-seminar-03.zip\naisa$ unzip pb071-seminar-03.zip\n# Now you should have directory 'seminar-03'.\naisa$ rm pb071-seminar-03.zip\naisa$ cd seminar-03\n# You can work on the assignment.\n"})}),"\n",(0,r.jsx)(n.h3,{id:"step-4---commit-and-upload-the-changes-to-gitlab",children:"Step #4 - Commit and upload the changes to GitLab"}),"\n",(0,r.jsxs)(n.p,{children:["The same way you ",(0,r.jsx)(n.em,{children:"add"})," and ",(0,r.jsx)(n.em,{children:"commit"})," files for the homework assignments, you do for\nthe seminar."]}),"\n",(0,r.jsxs)(n.p,{children:["Now you can upload the changes to GitLab. ",(0,r.jsx)(n.code,{children:"git push"})," is not enough, since repository\non GitLab does not know your new branch. You can solve this by adding arguments:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git push origin BRANCH\n...\nremote: To create a merge request for BRANCH, visit:\nremote: https://gitlab.fi.muni.cz/login/pb071/merge_requests/new?merge_request%5Bsource_branch%5D=BRANCH\n...\n"})}),"\n",(0,r.jsx)(n.p,{children:"In the output you should have a link for creating a merge request. If you see this\nlink, open it and skip next step."}),"\n",(0,r.jsx)(n.h3,{id:"step-5---creating-a-merge-request-manually",children:"Step #5 - Creating a merge request manually"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Open your repository on GitLab."}),"\n",(0,r.jsxs)(n.li,{children:["On the left panel click on ",(0,r.jsx)(n.em,{children:"Merge Requests"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"New Merge Request"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Source branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and ",(0,r.jsx)(n.code,{children:"BRANCH"}),", which you created."]}),"\n",(0,r.jsxs)(n.li,{children:["In ",(0,r.jsx)(n.em,{children:"Target branch"})," select ",(0,r.jsx)(n.code,{children:"login/pb071"})," and your default branch you have seen\nin the output of the first command. (most likely ",(0,r.jsx)(n.code,{children:"master"}),")"]}),"\n",(0,r.jsxs)(n.li,{children:["Click on ",(0,r.jsx)(n.em,{children:"Compare branches and continue"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"step-6---set-assignees",children:"Step #6 - Set assignees"}),"\n",(0,r.jsxs)(n.p,{children:["On the page that is opened, please check at the top that you are creating merge\nrequest ",(0,r.jsx)(n.strong,{children:"from"})," your new branch ",(0,r.jsx)(n.strong,{children:"to"})," your default branch (one of ",(0,r.jsx)(n.code,{children:"master"}),", ",(0,r.jsx)(n.code,{children:"main"}),"\nor ",(0,r.jsx)(n.code,{children:"trunk"}),")."]}),"\n",(0,r.jsxs)(n.p,{children:["Then in the field ",(0,r.jsx)(n.em,{children:"Assignees"})," set your tutors based on the seminar group. You can\nuse login for a quick look up."]}),"\n",(0,r.jsxs)(n.p,{children:["In the end click on ",(0,r.jsx)(n.em,{children:"Submit merge request"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"step-7---return-to-default-branch",children:"Step #7 - Return to default branch"}),"\n",(0,r.jsx)(n.p,{children:"Homework assignments can be submitted only from branches specified in the rules\nfor the course. Because of that, before you do anything else, you should switch\nback to your default branch."}),"\n",(0,r.jsxs)(n.p,{children:["First of all, same as in step #1, check that your repository is clean with ",(0,r.jsx)(n.code,{children:"git status"}),".\nFor the sake of safety, do not continue without clean repository. Then with command\n",(0,r.jsx)(n.code,{children:"git checkout BRANCH"})," switch to your default branch ",(0,r.jsx)(n.code,{children:"BRANCH"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["If you do not know which branch is your default, try ",(0,r.jsx)(n.code,{children:"git branch"})," that outputs all branches in your repository. Default branch is typically ",(0,r.jsx)(n.code,{children:"master"}),", but can\nbe ",(0,r.jsx)(n.code,{children:"main"})," or ",(0,r.jsx)(n.code,{children:"trunk"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"aisa$ git status\n# Check if repository is clean\n\n# If you know, what is your default branch, you can skip next command.\naisa$ git branch\n# Find the default branch in the list; should be one of the `master`, `main` or\n# `trunk` and you should not have more than one of those.\n# In case the list clears the terminal and you cannot see shell prompt, you can\n# press `q` to quit the pager.\n\naisa$ git checkout master\n"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["Adapted from: ",(0,r.jsx)(n.a,{href:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html",children:"https://www.fi.muni.cz/~xlacko1/pb071/mr.html"})]})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>i});var r=t(67294);const s={},o=r.createContext(s);function i(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b8cbf382.6ba7c9a6.js b/assets/js/b8cbf382.6ba7c9a6.js deleted file mode 100644 index 9ac3cdc..0000000 --- a/assets/js/b8cbf382.6ba7c9a6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[7438],{74632:e=>{e.exports=JSON.parse('{"label":"greedy","permalink":"/algorithms/tags/greedy","allTagsPath":"/algorithms/tags","count":2,"items":[{"id":"recursion/2023-08-17-pyramid-slide-down/greedy","title":"Greedy solution","description":"Greedy solution of the Pyramid Slide Down.\\n","permalink":"/algorithms/recursion/pyramid-slide-down/greedy"},{"id":"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down","title":"Introduction to dynamic programming","description":"Solving a problem in different ways.\\n","permalink":"/algorithms/recursion/pyramid-slide-down"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/b8cbf382.e3b79fad.js b/assets/js/b8cbf382.e3b79fad.js new file mode 100644 index 0000000..b6321dd --- /dev/null +++ b/assets/js/b8cbf382.e3b79fad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[7438],{74632:i=>{i.exports=JSON.parse('{"label":"greedy","permalink":"/algorithms/tags/greedy","allTagsPath":"/algorithms/tags","count":4,"items":[{"id":"paths/2024-01-01-bf-to-astar/dijkstra","title":"Dijkstra\'s algorithm","description":"Moving from Bellman-Ford into the Dijsktra\'s algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar/dijkstra"},{"id":"paths/2024-01-01-bf-to-astar/index","title":"From BF to A*","description":"Figuring out shortest-path problem from the BF to the A* algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar"},{"id":"recursion/2023-08-17-pyramid-slide-down/greedy","title":"Greedy solution","description":"Greedy solution of the Pyramid Slide Down.\\n","permalink":"/algorithms/recursion/pyramid-slide-down/greedy"},{"id":"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down","title":"Introduction to dynamic programming","description":"Solving a problem in different ways.\\n","permalink":"/algorithms/recursion/pyramid-slide-down"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/c4c4056e.3de7285f.js b/assets/js/c4c4056e.3de7285f.js new file mode 100644 index 0000000..3625485 --- /dev/null +++ b/assets/js/c4c4056e.3de7285f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[635],{61381:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>h});var r=n(85893),s=n(11151);const o={id:"index",slug:"/paths/bf-to-astar",title:"From BF to A*",description:"Figuring out shortest-path problem from the BF to the A* algorithm.\n",tags:["cpp","brute force","bellman ford","dynamic programming","dijkstra","greedy","a star"],last_update:{date:new Date("2024-01-01T00:00:00.000Z")}},a=void 0,i={id:"paths/2024-01-01-bf-to-astar/index",title:"From BF to A*",description:"Figuring out shortest-path problem from the BF to the A* algorithm.\n",source:"@site/algorithms/11-paths/2024-01-01-bf-to-astar/index.md",sourceDirName:"11-paths/2024-01-01-bf-to-astar",slug:"/paths/bf-to-astar",permalink:"/algorithms/paths/bf-to-astar",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/algorithms/11-paths/2024-01-01-bf-to-astar/index.md",tags:[{label:"cpp",permalink:"/algorithms/tags/cpp"},{label:"brute force",permalink:"/algorithms/tags/brute-force"},{label:"bellman ford",permalink:"/algorithms/tags/bellman-ford"},{label:"dynamic programming",permalink:"/algorithms/tags/dynamic-programming"},{label:"dijkstra",permalink:"/algorithms/tags/dijkstra"},{label:"greedy",permalink:"/algorithms/tags/greedy"},{label:"a star",permalink:"/algorithms/tags/a-star"}],version:"current",lastUpdatedAt:1704067200,formattedLastUpdatedAt:"Jan 1, 2024",frontMatter:{id:"index",slug:"/paths/bf-to-astar",title:"From BF to A*",description:"Figuring out shortest-path problem from the BF to the A* algorithm.\n",tags:["cpp","brute force","bellman ford","dynamic programming","dijkstra","greedy","a star"],last_update:{date:"2024-01-01T00:00:00.000Z"}},sidebar:"autogeneratedBar",previous:{title:"Paths in Graphs",permalink:"/algorithms/category/paths-in-graphs"},next:{title:"BF",permalink:"/algorithms/paths/bf-to-astar/bf"}},l={},h=[{value:"Intro",id:"intro",level:2},{value:"Boilerplate",id:"boilerplate",level:2}];function c(t){const e={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.h2,{id:"intro",children:"Intro"}),"\n",(0,r.jsx)(e.p,{children:"We will delve into the details and ideas of the most common path-finding\nalgorithms. For the purpose of demonstrating some \u201cfeatures\u201d of the improved\nalgorithms, we will use a 2D map with some rules that will allow us to show cons\nand pros of the shown algorithms."}),"\n",(0,r.jsx)(e.p,{children:"Let's have a look at the example map:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{children:"#############\n#..#..*.*.**#\n##***.....**#\n#..########.#\n#...###...#.#\n#..#...##.#.#\n#..#.*.#..#.#\n#....#....#.#\n########*.*.#\n#...........#\n#############\n"})}),"\n",(0,r.jsx)(e.p,{children:"We can see three different kinds of cells:"}),"\n",(0,r.jsxs)(e.ol,{children:["\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.code,{children:"#"})," which represent walls, that cannot be entered at all"]}),"\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.code,{children:"*"})," which represent vortices that can be entered at the cost of 5 coins"]}),"\n",(0,r.jsxs)(e.li,{children:[(0,r.jsx)(e.code,{children:"."})," which represent normal cells that can be entered for 1 coin (which is the\nbase price of moving around the map)"]}),"\n"]}),"\n",(0,r.jsx)(e.p,{children:"Let's dissect a specific position on the map to get a better grasp of the rules:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{children:" .\n#S*\n .\n"})}),"\n",(0,r.jsxs)(e.p,{children:["We are standing in the cell marked with ",(0,r.jsx)(e.code,{children:"S"})," and we have the following options"]}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsxs)(e.li,{children:["move to the north (",(0,r.jsx)(e.code,{children:"."}),") with the cost of 1 coin,"]}),"\n",(0,r.jsxs)(e.li,{children:["move to the west (",(0,r.jsx)(e.code,{children:"#"}),") ",(0,r.jsx)(e.strong,{children:"is not"})," allowed because of the wall,"]}),"\n",(0,r.jsxs)(e.li,{children:["move to the east (",(0,r.jsx)(e.code,{children:"*"}),") is allowed with the cost of 5 coins, and finally"]}),"\n",(0,r.jsxs)(e.li,{children:["move to the south (",(0,r.jsx)(e.code,{children:"."}),") with the cost of 1 coin."]}),"\n"]}),"\n",(0,r.jsx)(e.admonition,{type:"info",children:(0,r.jsxs)(e.p,{children:["Further on I will follow the same scheme for marking cells with an addition of\n",(0,r.jsx)(e.code,{children:"D"})," to denote the ",(0,r.jsx)(e.em,{children:"destination"})," to which we will be finding the shortest path."]})}),"\n",(0,r.jsx)(e.h2,{id:"boilerplate",children:"Boilerplate"}),"\n",(0,r.jsx)(e.p,{children:"For working with this map I have prepared a basic structure for the graph in C++\nthat will abstract some of the internal workings of our map, namely:"}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"remembers the costs of moving around"}),"\n",(0,r.jsxs)(e.li,{children:["provides a simple function that returns price for moving ",(0,r.jsx)(e.strong,{children:"directly"})," between\ntwo positions on the map"]}),"\n",(0,r.jsx)(e.li,{children:"allows us to print the map out, just in case we'd need some adjustments to be\nmade"}),"\n"]}),"\n",(0,r.jsxs)(e.p,{children:["We can see the ",(0,r.jsx)(e.code,{children:"graph"})," header here:"]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-cpp",children:"#ifndef _GRAPH_HPP\n#define _GRAPH_HPP\n\n#include \n#include \n#include \n#include \n#include \n\nusing vertex_t = std::pair;\n\nstruct graph {\n graph(const std::vector>& map)\n : map(map),\n _height(static_cast(map.size())),\n _width(map.empty() ? 0 : static_cast(map[0].size())) {}\n\n static auto unreachable() -> int { return UNREACHABLE; }\n static auto normal_cost() -> int { return NORMAL_COST; }\n static auto vortex_cost() -> int { return VORTEX_COST; }\n\n auto cost(const vertex_t& u, const vertex_t& v) const -> int {\n auto [ux, uy] = u;\n auto [vx, vy] = v;\n\n auto hd = std::abs(ux - vx) + std::abs(uy - vy);\n switch (hd) {\n // \u2039u = v\u203a; staying on the same cell\n case 0:\n return 0;\n // \u2039u\u203a and \u2039v\u203a are neighbours\n case 1:\n break;\n // \u2039u\u203a and \u2039v\u203a are not neighbouring cells\n default:\n return UNREACHABLE;\n }\n\n // boundary check\n if (vy < 0 || vy >= _height || vx < 0 || vx >= _width) {\n return UNREACHABLE;\n }\n\n switch (map[vy][vx]) {\n case '#':\n return UNREACHABLE;\n case '*':\n return VORTEX_COST;\n default:\n return NORMAL_COST;\n }\n }\n\n auto width() const -> int { return _width; }\n auto height() const -> int { return _height; }\n auto has(const vertex_t& v) const -> bool {\n auto [x, y] = v;\n return (0 <= y && y < _height) && (0 <= x && x < _width);\n }\n\n friend std::ostream& operator<<(std::ostream& os, const graph& g);\n\n private:\n std::vector> map;\n int _height, _width;\n\n const static int UNREACHABLE = std::numeric_limits::max();\n // XXX: modify here to change the price of entering the vortex\n const static int VORTEX_COST = 5;\n const static int NORMAL_COST = 1;\n};\n\nstd::ostream& operator<<(std::ostream& os, const graph& g) {\n for (const auto& row : g.map) {\n for (const char cell : row) {\n os << cell;\n }\n os << \"\\n\";\n }\n\n return os;\n}\n\n#endif /* _GRAPH_HPP */\n"})}),"\n",(0,r.jsx)(e.admonition,{title:"Source code",type:"info",children:(0,r.jsxs)(e.p,{children:["You can find all the source code referenced in this series\n",(0,r.jsx)(e.a,{href:"pathname:///files/algorithms/paths/bf-to-astar.tar.gz",children:"here"}),"."]})}),"\n",(0,r.jsx)(e.p,{children:"Let's finally start with some algorithms!"})]})}function d(t={}){const{wrapper:e}={...(0,s.a)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(c,{...t})}):c(t)}},11151:(t,e,n)=>{n.d(e,{Z:()=>i,a:()=>a});var r=n(67294);const s={},o=r.createContext(s);function a(t){const e=r.useContext(o);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function i(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:a(t.components),r.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/d05e838c.3caaf7e6.js b/assets/js/d05e838c.3caaf7e6.js new file mode 100644 index 0000000..0a36be3 --- /dev/null +++ b/assets/js/d05e838c.3caaf7e6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[6544],{63004:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>a,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=r(85893),t=r(11151);const i={id:"seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n"},c=void 0,o={id:"bonuses/seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n",source:"@site/c/bonuses/05-06.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-05-06",permalink:"/c/bonuses/seminar-05-06",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/05-06.md",tags:[],version:"current",lastUpdatedAt:1704291155,formattedLastUpdatedAt:"Jan 3, 2024",frontMatter:{id:"seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n"},sidebar:"autogeneratedBar",previous:{title:"4th seminar",permalink:"/c/bonuses/seminar-04"},next:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Task no. 1: Reverse (0.5 K\u20a1)",id:"task-no-1-reverse-05-k",level:3},{value:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)",id:"task-no-2-vigen\xe8re-05-k",level:3},{value:"Bonus part (0.5 K\u20a1)",id:"bonus-part-05-k",level:4},{value:"Task no. 3: Bit madness (0.5 K\u20a1)",id:"task-no-3-bit-madness-05-k",level:3},{value:"Task no. 4: All combined to BMP (0.5 K\u20a1)",id:"task-no-4-all-combined-to-bmp-05-k",level:3},{value:"Submitting",id:"submitting",level:2}];function h(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/05-06.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"In this bonus you will implement few functions that will be used together for\nimplementing a very special cipher."}),"\n",(0,s.jsx)(n.h3,{id:"task-no-1-reverse-05-k",children:"Task no. 1: Reverse (0.5 K\u20a1)"}),"\n",(0,s.jsxs)(n.p,{children:["Write a function ",(0,s.jsx)(n.code,{children:"char* reverse(const char* text)"})," that returns copy of the input\nstring in reversed order (also uppercase)."]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are given ",(0,s.jsx)(n.code,{children:"NULL"}),", return ",(0,s.jsx)(n.code,{children:"NULL"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Example (more in tests):"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char* reversed = reverse("Hello world!");\n\nprintf("%s\\n", reversed);\n// "!DLROW OLLEH"\n\nif (reversed != NULL) {\n free(reversed);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-2-vigen\xe8re-05-k",children:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Vigen\xe8re cipher is similar to the Caesar cipher, but you also have a key that is\nused for encrypting (or decrypting)."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to write two functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_encrypt(const char* key, const char* text)"})," for encrypting"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_decrypt(const char* key, const char* text)"})," for decrypting"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In both of those you should return uppercase characters."}),"\n",(0,s.jsx)(n.p,{children:"Meaning of the parameters you are given:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"key"})," - String that represents key that is used for *crypting. It consists of\none word and can have only characters of the alphabet. Does not matter if they\nare uppercase or lowercase."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"text"})," - String that is to be *crypted."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Function returns address of the encrypted (or decrypted) string. Or ",(0,s.jsx)(n.code,{children:"NULL"})," in case\nerror occurs."]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char *encrypted = vigenere_encrypt("CoMPuTeR", "Hello world!");\n\nprintf("%s\\n", encrypted);\n// "JSXAI PSINR!"\n\nif (encrypted != NULL) {\n free(encrypted)\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"bonus-part-05-k",children:"Bonus part (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"If you can utilize helper function that would do both encrypting and decrypting,\nyou can gain 0.5 K\u20a1."}),"\n",(0,s.jsxs)(n.p,{children:["Usage of ",(0,s.jsx)(n.code,{children:"true"}),"/",(0,s.jsx)(n.code,{children:"false"})," to decide path in code is prohibited. It leads to merging\nof both functions into one. Point of this part is to discover a way to do this\ngenerically in such way that there are no separate paths for one or the other. One\nfunction with no branching for both of them, parametrization is your friend :)"]}),"\n",(0,s.jsx)(n.h3,{id:"task-no-3-bit-madness-05-k",children:"Task no. 3: Bit madness (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"This is a state of the art crypto. Please do not share :)"}),"\n",(0,s.jsx)(n.p,{children:"For encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Split the character that is to be encrypted in halves (4 and 4 bits each)."}),"\n",(0,s.jsx)(n.li,{children:"Bits in 1st half are to be split into pairs. Swap bits in those pairs."}),"\n",(0,s.jsxs)(n.li,{children:["Then use the 4 bits that you created in the 2nd step for ",(0,s.jsx)(n.code,{children:"XOR"})," with the other\n4 bits."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["This simple and ingenious principle will be illustrated on the following example.\nString we want to encrypt is ",(0,s.jsx)(n.code,{children:"Hello world!"}),". We need to encrypt each letter separately,\nso we will demonstrate on letter ",(0,s.jsx)(n.code,{children:"H"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Letter ",(0,s.jsx)(n.code,{children:"H"})," is represented in ASCII as ",(0,s.jsx)(n.code,{children:"72"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"72"})," represented in binary is: ",(0,s.jsx)(n.code,{children:"01001000"}),". So first 4 bits are: ",(0,s.jsx)(n.code,{children:"0100"})," and last\n4 bits are ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["First half of bits (",(0,s.jsx)(n.code,{children:"0100"}),") consists of 2 pairs (",(0,s.jsx)(n.code,{children:"01"})," and ",(0,s.jsx)(n.code,{children:"00"}),") which we swap\n(",(0,s.jsx)(n.code,{children:"01 ~> 10"})," and ",(0,s.jsx)(n.code,{children:"00 ~> 00"}),"). That way we get ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"That half is used for xor with the other 4 bits:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" 1000 // second half\nXOR 1000 // first half after 2nd step\n--------\n 0000\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Now we combine both halves (first one is ",(0,s.jsx)(n.code,{children:"1000"}),", which we got from the 2nd step\nand second one is ",(0,s.jsx)(n.code,{children:"0000"}),", which we got from the 3rd step) and get ",(0,s.jsx)(n.code,{children:"10000000"}),",\nwhich is encrypted character ",(0,s.jsx)(n.code,{children:"H"})," using this method."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In case of decryption, reverse those steps."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to implement functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bit_encrypt(const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bit_decrypt(const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'unsigned char* encrypted = bit_encrypt("Hello world!");\n\nfor (int i = 0; i < 12;i++) {\n printf("%x ", encrypted[i]);\n //80 9c 95 95 96 11 bc 96 b9 95 9d 10\n}\n\nif (encrypted != NULL) {\n free(encrypted);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-4-all-combined-to-bmp-05-k",children:"Task no. 4: All combined to BMP (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Authors of the BMP cipher are non-disclosed :)"}),"\n",(0,s.jsx)(n.p,{children:"Create pair of functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bmp_encrypt(const char* key, const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bmp_decrypt(const char* key, const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"BMP cipher consists of following steps for encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Reverse the input string"}),"\n",(0,s.jsx)(n.li,{children:"Use Vigenere on the string you got from step #1"}),"\n",(0,s.jsx)(n.li,{children:"Use bit madness on the string you got from step #2"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For decrypting, reverse the steps."}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function a(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},11151:(e,n,r)=>{r.d(n,{Z:()=>o,a:()=>c});var s=r(67294);const t={},i=s.createContext(t);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d05e838c.ee3d8fcc.js b/assets/js/d05e838c.ee3d8fcc.js deleted file mode 100644 index 8833ba2..0000000 --- a/assets/js/d05e838c.ee3d8fcc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[6544],{63004:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>a,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=r(85893),t=r(11151);const i={id:"seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n"},c=void 0,o={id:"bonuses/seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n",source:"@site/c/bonuses/05-06.md",sourceDirName:"bonuses",slug:"/bonuses/seminar-05-06",permalink:"/c/bonuses/seminar-05-06",draft:!1,unlisted:!1,editUrl:"https://github.com/mfocko/blog/tree/main/c/bonuses/05-06.md",tags:[],version:"current",lastUpdatedAt:1703979877,formattedLastUpdatedAt:"Dec 30, 2023",frontMatter:{id:"seminar-05-06",title:"5th and 6th seminar",description:"200IQ encryption.\n"},sidebar:"autogeneratedBar",previous:{title:"4th seminar",permalink:"/c/bonuses/seminar-04"},next:{title:"8th seminar",permalink:"/c/bonuses/seminar-08"}},d={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Task no. 1: Reverse (0.5 K\u20a1)",id:"task-no-1-reverse-05-k",level:3},{value:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)",id:"task-no-2-vigen\xe8re-05-k",level:3},{value:"Bonus part (0.5 K\u20a1)",id:"bonus-part-05-k",level:4},{value:"Task no. 3: Bit madness (0.5 K\u20a1)",id:"task-no-3-bit-madness-05-k",level:3},{value:"Task no. 4: All combined to BMP (0.5 K\u20a1)",id:"task-no-4-all-combined-to-bmp-05-k",level:3},{value:"Submitting",id:"submitting",level:2}];function h(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"For this bonus you can get at maximum 2.5 K\u20a1."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"pathname:///files/c/bonuses/05-06.tar.gz",children:"Source"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(n.p,{children:"In this bonus you will implement few functions that will be used together for\nimplementing a very special cipher."}),"\n",(0,s.jsx)(n.h3,{id:"task-no-1-reverse-05-k",children:"Task no. 1: Reverse (0.5 K\u20a1)"}),"\n",(0,s.jsxs)(n.p,{children:["Write a function ",(0,s.jsx)(n.code,{children:"char* reverse(const char* text)"})," that returns copy of the input\nstring in reversed order (also uppercase)."]}),"\n",(0,s.jsxs)(n.p,{children:["In case you are given ",(0,s.jsx)(n.code,{children:"NULL"}),", return ",(0,s.jsx)(n.code,{children:"NULL"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Example (more in tests):"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char* reversed = reverse("Hello world!");\n\nprintf("%s\\n", reversed);\n// "!DLROW OLLEH"\n\nif (reversed != NULL) {\n free(reversed);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-2-vigen\xe8re-05-k",children:"Task no. 2: Vigen\xe8re (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Vigen\xe8re cipher is similar to the Caesar cipher, but you also have a key that is\nused for encrypting (or decrypting)."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to write two functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_encrypt(const char* key, const char* text)"})," for encrypting"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"char* vigenere_decrypt(const char* key, const char* text)"})," for decrypting"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In both of those you should return uppercase characters."}),"\n",(0,s.jsx)(n.p,{children:"Meaning of the parameters you are given:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"key"})," - String that represents key that is used for *crypting. It consists of\none word and can have only characters of the alphabet. Does not matter if they\nare uppercase or lowercase."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"text"})," - String that is to be *crypted."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Function returns address of the encrypted (or decrypted) string. Or ",(0,s.jsx)(n.code,{children:"NULL"})," in case\nerror occurs."]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'char *encrypted = vigenere_encrypt("CoMPuTeR", "Hello world!");\n\nprintf("%s\\n", encrypted);\n// "JSXAI PSINR!"\n\nif (encrypted != NULL) {\n free(encrypted)\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"bonus-part-05-k",children:"Bonus part (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"If you can utilize helper function that would do both encrypting and decrypting,\nyou can gain 0.5 K\u20a1."}),"\n",(0,s.jsxs)(n.p,{children:["Usage of ",(0,s.jsx)(n.code,{children:"true"}),"/",(0,s.jsx)(n.code,{children:"false"})," to decide path in code is prohibited. It leads to merging\nof both functions into one. Point of this part is to discover a way to do this\ngenerically in such way that there are no separate paths for one or the other. One\nfunction with no branching for both of them, parametrization is your friend :)"]}),"\n",(0,s.jsx)(n.h3,{id:"task-no-3-bit-madness-05-k",children:"Task no. 3: Bit madness (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"This is a state of the art crypto. Please do not share :)"}),"\n",(0,s.jsx)(n.p,{children:"For encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Split the character that is to be encrypted in halves (4 and 4 bits each)."}),"\n",(0,s.jsx)(n.li,{children:"Bits in 1st half are to be split into pairs. Swap bits in those pairs."}),"\n",(0,s.jsxs)(n.li,{children:["Then use the 4 bits that you created in the 2nd step for ",(0,s.jsx)(n.code,{children:"XOR"})," with the other\n4 bits."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["This simple and ingenious principle will be illustrated on the following example.\nString we want to encrypt is ",(0,s.jsx)(n.code,{children:"Hello world!"}),". We need to encrypt each letter separately,\nso we will demonstrate on letter ",(0,s.jsx)(n.code,{children:"H"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Letter ",(0,s.jsx)(n.code,{children:"H"})," is represented in ASCII as ",(0,s.jsx)(n.code,{children:"72"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"72"})," represented in binary is: ",(0,s.jsx)(n.code,{children:"01001000"}),". So first 4 bits are: ",(0,s.jsx)(n.code,{children:"0100"})," and last\n4 bits are ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["First half of bits (",(0,s.jsx)(n.code,{children:"0100"}),") consists of 2 pairs (",(0,s.jsx)(n.code,{children:"01"})," and ",(0,s.jsx)(n.code,{children:"00"}),") which we swap\n(",(0,s.jsx)(n.code,{children:"01 ~> 10"})," and ",(0,s.jsx)(n.code,{children:"00 ~> 00"}),"). That way we get ",(0,s.jsx)(n.code,{children:"1000"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"That half is used for xor with the other 4 bits:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:" 1000 // second half\nXOR 1000 // first half after 2nd step\n--------\n 0000\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Now we combine both halves (first one is ",(0,s.jsx)(n.code,{children:"1000"}),", which we got from the 2nd step\nand second one is ",(0,s.jsx)(n.code,{children:"0000"}),", which we got from the 3rd step) and get ",(0,s.jsx)(n.code,{children:"10000000"}),",\nwhich is encrypted character ",(0,s.jsx)(n.code,{children:"H"})," using this method."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"In case of decryption, reverse those steps."}),"\n",(0,s.jsx)(n.p,{children:"Your task is to implement functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bit_encrypt(const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bit_decrypt(const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-c",children:'unsigned char* encrypted = bit_encrypt("Hello world!");\n\nfor (int i = 0; i < 12;i++) {\n printf("%x ", encrypted[i]);\n //80 9c 95 95 96 11 bc 96 b9 95 9d 10\n}\n\nif (encrypted != NULL) {\n free(encrypted);\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"task-no-4-all-combined-to-bmp-05-k",children:"Task no. 4: All combined to BMP (0.5 K\u20a1)"}),"\n",(0,s.jsx)(n.p,{children:"Authors of the BMP cipher are non-disclosed :)"}),"\n",(0,s.jsx)(n.p,{children:"Create pair of functions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"unsigned char* bmp_encrypt(const char* key, const char* text)"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"char* bmp_decrypt(const char* key, const unsigned char* text)"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"BMP cipher consists of following steps for encrypting:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Reverse the input string"}),"\n",(0,s.jsx)(n.li,{children:"Use Vigenere on the string you got from step #1"}),"\n",(0,s.jsx)(n.li,{children:"Use bit madness on the string you got from step #2"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"For decrypting, reverse the steps."}),"\n",(0,s.jsx)(n.h2,{id:"submitting",children:"Submitting"}),"\n",(0,s.jsx)(n.p,{children:"In case you have any questions, feel free to reach out to me."}),"\n",(0,s.jsx)(n.hr,{})]})}function a(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},11151:(e,n,r)=>{r.d(n,{Z:()=>o,a:()=>c});var s=r(67294);const t={},i=s.createContext(t);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dd841e73.afb9a531.js b/assets/js/dd841e73.afb9a531.js deleted file mode 100644 index b75874c..0000000 --- a/assets/js/dd841e73.afb9a531.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[2482],{40155:i=>{i.exports=JSON.parse('{"label":"dynamic-programming","permalink":"/algorithms/tags/dynamic-programming","allTagsPath":"/algorithms/tags","count":3,"items":[{"id":"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp","title":"Bottom-up DP solution","description":"Bottom-up DP solution of the Pyramid Slide Down.\\n","permalink":"/algorithms/recursion/pyramid-slide-down/bottom-up-dp"},{"id":"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down","title":"Introduction to dynamic programming","description":"Solving a problem in different ways.\\n","permalink":"/algorithms/recursion/pyramid-slide-down"},{"id":"recursion/2023-08-17-pyramid-slide-down/top-down-dp","title":"Top-down DP solution","description":"Top-down DP solution of the Pyramid Slide Down.\\n","permalink":"/algorithms/recursion/pyramid-slide-down/top-down-dp"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/dd841e73.c1ec5d72.js b/assets/js/dd841e73.c1ec5d72.js new file mode 100644 index 0000000..76d13e1 --- /dev/null +++ b/assets/js/dd841e73.c1ec5d72.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[2482],{40155:t=>{t.exports=JSON.parse('{"label":"dynamic programming","permalink":"/algorithms/tags/dynamic-programming","allTagsPath":"/algorithms/tags","count":7,"items":[{"id":"paths/2024-01-01-bf-to-astar/astar","title":"A* algorithm","description":"Moving from Dijkstra\'s algorithm into the A* algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar/astar"},{"id":"paths/2024-01-01-bf-to-astar/bf","title":"BF","description":"Solving the shortest path problem with a na\xefve approach that turns into\\nsomething.\\n","permalink":"/algorithms/paths/bf-to-astar/bf"},{"id":"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp","title":"Bottom-up DP solution","description":"Bottom-up DP solution of the Pyramid Slide Down.\\n","permalink":"/algorithms/recursion/pyramid-slide-down/bottom-up-dp"},{"id":"paths/2024-01-01-bf-to-astar/dijkstra","title":"Dijkstra\'s algorithm","description":"Moving from Bellman-Ford into the Dijsktra\'s algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar/dijkstra"},{"id":"paths/2024-01-01-bf-to-astar/index","title":"From BF to A*","description":"Figuring out shortest-path problem from the BF to the A* algorithm.\\n","permalink":"/algorithms/paths/bf-to-astar"},{"id":"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down","title":"Introduction to dynamic programming","description":"Solving a problem in different ways.\\n","permalink":"/algorithms/recursion/pyramid-slide-down"},{"id":"recursion/2023-08-17-pyramid-slide-down/top-down-dp","title":"Top-down DP solution","description":"Top-down DP solution of the Pyramid Slide Down.\\n","permalink":"/algorithms/recursion/pyramid-slide-down/top-down-dp"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/df078f58.4f109cb4.js b/assets/js/df078f58.4f109cb4.js new file mode 100644 index 0000000..f6fc9f0 --- /dev/null +++ b/assets/js/df078f58.4f109cb4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfi=self.webpackChunkfi||[]).push([[7743],{88298:t=>{t.exports=JSON.parse('{"title":"Paths in Graphs","description":"Materials related to finding paths in graphs.\\n","slug":"/category/paths-in-graphs","permalink":"/algorithms/category/paths-in-graphs","navigation":{"previous":{"title":"Distance boundaries from BFS tree on undirected graphs","permalink":"/algorithms/graphs/bfs-tree"},"next":{"title":"From BF to A*","permalink":"/algorithms/paths/bf-to-astar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/main.2a166133.js b/assets/js/main.2a166133.js new file mode 100644 index 0000000..974fbb1 --- /dev/null +++ b/assets/js/main.2a166133.js @@ -0,0 +1,2 @@ +/*! For license information please see main.2a166133.js.LICENSE.txt */ +(self.webpackChunkfi=self.webpackChunkfi||[]).push([[179],{20830:(e,t,n)=>{"use strict";n.d(t,{W:()=>a});var r=n(67294);function a(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});n(67294);var r=n(68356),a=n.n(r),o=n(16887);const i={"0123bc76":[()=>n.e(3734).then(n.t.bind(n,76554,19)),"~docs/algorithms/tag-algorithms-tags-c-e22.json",76554],"0178f9ad":[()=>n.e(9898).then(n.bind(n,35610)),"@site/algorithms/08-rb-trees/2022-04-05-applications.md",35610],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,24524)),"@theme/BlogTagsListPage",24524],"0220f5fc":[()=>n.e(1378).then(n.t.bind(n,85804,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-blog/blog/plugin-route-context-module-100.json",85804],"0608d96f":[()=>n.e(7568).then(n.t.bind(n,77158,19)),"~blog/blog/blog-tags-vps-843-list.json",77158],"06c4a8fc":[()=>n.e(2125).then(n.t.bind(n,4697,19)),"~docs/algorithms/tag-algorithms-tags-testing-0c4.json",4697],"087808f1":[()=>n.e(3731).then(n.bind(n,48157)),"@site/algorithms/12-hash-tables/2023-11-28-breaking/index.md",48157],"08dfa3a2":[()=>n.e(2606).then(n.t.bind(n,32412,19)),"~docs/algorithms/tag-algorithms-tags-astar-f6e.json",32412],"0bfe45d5":[()=>n.e(4269).then(n.t.bind(n,13847,19)),"~blog/blog/blog-tags-rust-0c9-list.json",13847],"0fcbc6ca":[()=>Promise.all([n.e(532),n.e(1851)]).then(n.bind(n,39900)),"@site/src/pages/talks.tsx",39900],"146d9b84":[()=>n.e(9300).then(n.t.bind(n,96671,19)),"~blog/blog/blog-tags-admin-b05-list.json",96671],"14eb3368":[()=>Promise.all([n.e(532),n.e(9817)]).then(n.bind(n,34228)),"@theme/DocCategoryGeneratedIndexPage",34228],"1535ede8":[()=>n.e(5376).then(n.bind(n,44969)),"@site/c/bonuses/10.md",44969],15966941:[()=>n.e(8326).then(n.bind(n,16721)),"@site/algorithms/12-hash-tables/2023-11-28-breaking/02-mitigations.md",16721],"16cbc838":[()=>n.e(1494).then(n.t.bind(n,98252,19)),"~docs/algorithms/tag-algorithms-tags-iterative-d5b.json",98252],17896441:[()=>Promise.all([n.e(532),n.e(1325),n.e(7918)]).then(n.bind(n,15154)),"@theme/DocItem",15154],"19d7c045":[()=>n.e(4637).then(n.t.bind(n,67772,19)),"~blog/blog/blog-tags-advent-of-code-49f.json",67772],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,48852)),"@theme/SearchPage",48852],"1a606400":[()=>n.e(494).then(n.t.bind(n,82400,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-docs/algorithms/plugin-route-context-module-100.json",82400],"1acf65cc":[()=>n.e(8529).then(n.bind(n,34568)),"@site/c/pexam/b-garbage_collect.md",34568],"1cd58e77":[()=>n.e(1547).then(n.bind(n,32090)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/04-bottom-up-dp.md",32090],"22a175ec":[()=>Promise.all([n.e(532),n.e(6890)]).then(n.bind(n,40707)),"@site/src/pages/contributions.tsx",40707],"24fecc0a":[()=>n.e(3707).then(n.bind(n,69383)),"@site/algorithms/03-time-complexity/2021-03-31-extend.md",69383],"28d80ff8":[()=>n.e(6435).then(n.t.bind(n,7465,19)),"~docs/algorithms/tag-algorithms-tags-sorting-d73.json",7465],29694455:[()=>n.e(3388).then(n.t.bind(n,39828,19)),"~blog/blog/blog-tags-iterators-977-list.json",39828],"2af5d0a7":[()=>n.e(3979).then(n.t.bind(n,53703,19)),"~docs/algorithms/tag-algorithms-tags-a-star-775.json",53703],"2b89902a":[()=>n.e(6342).then(n.t.bind(n,45443,19)),"~docs/algorithms/tag-algorithms-tags-recursion-1bd.json",45443],"2ca64e35":[()=>n.e(281).then(n.bind(n,99544)),"@site/algorithms/04-recursion/2022-11-29-karel/index.md",99544],"2fcf0558":[()=>n.e(4638).then(n.t.bind(n,69470,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-hash-tables-062.json",69470],"3011a4c0":[()=>n.e(7926).then(n.t.bind(n,31670,19)),"~blog/blog/blog-tags-copr-70b-list.json",31670],30814625:[()=>n.e(115).then(n.bind(n,78416)),"@site/algorithms/04-recursion/2022-11-29-karel/2023-12-24-solution.md",78416],"34ab65f4":[()=>n.e(3220).then(n.t.bind(n,28865,19)),"~docs/algorithms/tag-algorithms-tags-postconditions-1f3.json",28865],"354a7b72":[()=>n.e(9414).then(n.bind(n,46617)),"@site/algorithms/10-graphs/2022-04-30-bfs-tree.md",46617],"3720c009":[()=>Promise.all([n.e(532),n.e(3751)]).then(n.bind(n,10727)),"@theme/DocTagsListPage",10727],"377f3aa1":[()=>n.e(1011).then(n.bind(n,7582)),"@site/blog/aoc-2022/02-week-2.md",7582],"3adcbc3a":[()=>n.e(5701).then(n.bind(n,62535)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/01-bf.md",62535],"3d92ba6e":[()=>n.e(8236).then(n.t.bind(n,77778,19)),"~docs/algorithms/tag-algorithms-tags-dijkstra-48e.json",77778],"3da4b779":[()=>n.e(2177).then(n.bind(n,28737)),"@site/blog/aoc-2022/04-week-4.md",28737],"4200b1a9":[()=>n.e(866).then(n.t.bind(n,24612,19)),"~blog/blog/blog-archive-80c.json",24612],"45c9e308":[()=>n.e(7084).then(n.bind(n,53181)),"@site/cpp/07-exceptions-and-raii/2023-11-24-placeholders.md",53181],"4621632b":[()=>n.e(3519).then(n.t.bind(n,29760,19)),"~blog/blog/blog-tags-cpp-7c7-list.json",29760],"48b268a6":[()=>n.e(1648).then(n.t.bind(n,35067,19)),"~docs/c/category-c-autogeneratedbar-category-bonuses-216.json",35067],"493c0536":[()=>n.e(7292).then(n.bind(n,45594)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/03-astar.md",45594],"4e546705":[()=>n.e(4327).then(n.t.bind(n,61795,19)),"~docs/c/version-current-metadata-prop-751.json",61795],"4edd2021":[()=>n.e(5975).then(n.t.bind(n,21705,19)),"~blog/blog/blog-tags-cpp-7c7.json",21705],"4f96b16e":[()=>n.e(6306).then(n.bind(n,24693)),"@site/c/pexam/c-cams.md",24693],51624505:[()=>n.e(4394).then(n.bind(n,32609)),"@site/blog/aoc-2022/00-intro.md",32609],"520f8175":[()=>n.e(8058).then(n.t.bind(n,24353,19)),"~docs/algorithms/tag-algorithms-tags-cpp-0d2.json",24353],"52f2a5bf":[()=>n.e(5430).then(n.t.bind(n,61387,19)),"~blog/blog/blog-tags-red-hat-df4.json",61387],"534d4833":[()=>n.e(9771).then(n.bind(n,93019)),"@site/algorithms/02-algorithms-correctness/2021-03-18-postcondition-ambiguity.md",93019],"595c7293":[()=>n.e(5634).then(n.bind(n,58396)),"@site/c/bonuses/08.md",58396],"5c15401e":[()=>n.e(9579).then(n.t.bind(n,43761,19)),"~docs/algorithms/tag-algorithms-tags-bellman-ford-731.json",43761],"5ca803d2":[()=>n.e(9173).then(n.t.bind(n,24890,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-docs/c/plugin-route-context-module-100.json",24890],"5e95c892":[()=>n.e(9661).then(n.bind(n,41892)),"@theme/DocsRoot",41892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,36809)),"@generated/docusaurus.config",36809],"62d847b3":[()=>n.e(8520).then(n.t.bind(n,91901,19)),"~blog/blog/blog-tags-advent-of-code-2022-3db-list.json",91901],"66d5ef6c":[()=>n.e(9228).then(n.t.bind(n,4087,19)),"~blog/blog/blog-tags-tags-4c2.json",4087],"686a7a89":[()=>n.e(728).then(n.t.bind(n,77507,19)),"~docs/algorithms/tag-algorithms-tags-graphs-31d.json",77507],"6875c492":[()=>Promise.all([n.e(532),n.e(1325),n.e(130),n.e(8610)]).then(n.bind(n,41714)),"@theme/BlogTagsPostsPage",41714],"698e2076":[()=>n.e(3713).then(n.bind(n,38961)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/02-dijkstra.md",38961],"6bc697d0":[()=>n.e(5287).then(n.t.bind(n,68529,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-docs/cpp/plugin-route-context-module-100.json",68529],"6e3cbca1":[()=>n.e(3276).then(n.t.bind(n,29538,19)),"~docs/algorithms/version-current-metadata-prop-751.json",29538],"7052c0bc":[()=>n.e(9731).then(n.bind(n,42286)),"@site/cpp/00-intro.md",42286],"70a4540f":[()=>n.e(9249).then(n.bind(n,44493)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/01-naive.md",44493],"75cccf44":[()=>n.e(4256).then(n.bind(n,98215)),"@site/blog/leetcode/sort-matrix-diagonally.md?truncated=true",98215],"765ea78b":[()=>n.e(3039).then(n.t.bind(n,83010,19)),"~blog/blog/blog-tags-\ud83c\udfed-551.json",83010],"794ef108":[()=>n.e(3803).then(n.bind(n,86427)),"@site/c/00-intro.md",86427],"7ce7faac":[()=>n.e(6064).then(n.t.bind(n,12884,19)),"~docs/algorithms/tag-algorithms-tags-solution-61b.json",12884],"7e6d325b":[()=>n.e(3184).then(n.t.bind(n,26139,19)),"~docs/cpp/version-current-metadata-prop-751.json",26139],"84d1e0d8":[()=>n.e(1885).then(n.bind(n,49713)),"@site/algorithms/00-intro.md",49713],"86cd1460":[()=>n.e(1235).then(n.t.bind(n,38968,19)),"~blog/blog/blog-tags-leetcode-042.json",38968],"8a25f659":[()=>n.e(7728).then(n.bind(n,73212)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/03-top-down-dp.md",73212],"8b1802c5":[()=>n.e(8480).then(n.t.bind(n,60832,19)),"~blog/blog/blog-tags-advent-of-code-49f-list.json",60832],"8c0e532b":[()=>n.e(822).then(n.t.bind(n,73968,19)),"~blog/blog/blog-tags-vps-843.json",73968],"8d31a880":[()=>n.e(9066).then(n.t.bind(n,72232,19)),"~docs/algorithms/tag-algorithms-tags-python-48f.json",72232],"8e6bb954":[()=>n.e(5775).then(n.t.bind(n,76206,19)),"~docs/algorithms/tag-algorithms-tags-exponential-60a.json",76206],"9287eafd":[()=>n.e(5521).then(n.t.bind(n,90716,19)),"~blog/blog/blog-tags-rust-0c9.json",90716],"933b95b3":[()=>n.e(3887).then(n.t.bind(n,7405,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-recursion-257.json",7405],"947341b7":[()=>n.e(1145).then(n.t.bind(n,2897,19)),"~docs/algorithms/tag-algorithms-tags-bfs-69f.json",2897],"95b96bb9":[()=>n.e(3561).then(n.t.bind(n,24577,19)),"~blog/blog/blog-post-list-prop-blog.json",24577],"95f41f0b":[()=>n.e(9385).then(n.bind(n,93195)),"@site/blog/aoc-2022/01-week-1.md?truncated=true",93195],"962da50c":[()=>n.e(2264).then(n.t.bind(n,9705,19)),"~docs/c/category-c-autogeneratedbar-category-practice-exams-e97.json",9705],"976c4f3b":[()=>n.e(4562).then(n.t.bind(n,69019,19)),"~docs/algorithms/tag-algorithms-tags-java-6c3.json",69019],"97a42631":[()=>n.e(1464).then(n.t.bind(n,77343,19)),"~docs/algorithms/tags-list-current-prop-15a.json",77343],"9a3dc578":[()=>n.e(655).then(n.t.bind(n,9916,19)),"~docs/algorithms/tag-algorithms-tags-dynamic-array-5d3.json",9916],"9b91a88c":[()=>n.e(2545).then(n.bind(n,19466)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/index.md",19466],"9df0e937":[()=>n.e(2210).then(n.t.bind(n,55256,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-graphs-2e2.json",55256],"9e4087bc":[()=>n.e(3608).then(n.bind(n,63169)),"@theme/BlogArchivePage",63169],a082abd3:[()=>n.e(8786).then(n.t.bind(n,73276,19)),"~blog/blog/blog-tags-admin-b05.json",73276],a2ba8888:[()=>n.e(8289).then(n.t.bind(n,55941,19)),"~docs/algorithms/tag-algorithms-tags-brute-force-3cb.json",55941],a4c10cf4:[()=>n.e(4382).then(n.t.bind(n,30685,19)),"~docs/algorithms/tag-algorithms-tags-time-complexity-c50.json",30685],a6a48ea2:[()=>n.e(3618).then(n.bind(n,1176)),"@site/blog/aoc-2022/02-week-2.md?truncated=true",1176],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(1325),n.e(130),n.e(3089)]).then(n.bind(n,80046)),"@theme/BlogListPage",80046],a7098721:[()=>n.e(1050).then(n.t.bind(n,26615,19)),"~blog/blog/blog-c06.json",26615],a7bd4aaa:[()=>n.e(8518).then(n.bind(n,8564)),"@theme/DocVersionRoot",8564],a80747a0:[()=>n.e(5824).then(n.t.bind(n,4464,19)),"~blog/blog/blog-tags-advent-of-code-2022-3db.json",4464],a94703ab:[()=>Promise.all([n.e(532),n.e(4368)]).then(n.bind(n,12674)),"@theme/DocRoot",12674],aa24fd5d:[()=>n.e(7257).then(n.bind(n,90251)),"@site/algorithms/12-hash-tables/2023-11-28-breaking/01-python.md",90251],ab2721d4:[()=>n.e(7755).then(n.bind(n,53037)),"@site/blog/aoc-2022/04-week-4.md?truncated=true",53037],af8b72a7:[()=>n.e(5658).then(n.bind(n,10507)),"@site/blog/2023-08-02-copr.md?truncated=true",10507],b0291f37:[()=>n.e(6097).then(n.t.bind(n,7085,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],b1288602:[()=>n.e(59).then(n.bind(n,51456)),"@site/c/mr.md",51456],b25fbc58:[()=>n.e(9197).then(n.t.bind(n,75617,19)),"~blog/blog/blog-tags-\ud83c\udfed-551-list.json",75617],b45dccf0:[()=>n.e(9679).then(n.t.bind(n,58296,19)),"~blog/blog/blog-tags-copr-70b.json",58296],b5a32f14:[()=>n.e(2433).then(n.bind(n,31976)),"@site/blog/2023-08-02-copr.md",31976],b8cbf382:[()=>n.e(7438).then(n.t.bind(n,74632,19)),"~docs/algorithms/tag-algorithms-tags-greedy-02f.json",74632],b9f7f5c4:[()=>n.e(9179).then(n.bind(n,76699)),"@site/cpp/environment.md",76699],bb882650:[()=>n.e(8091).then(n.bind(n,66765)),"@site/blog/aoc-2022/03-week-3.md?truncated=true",66765],bb984793:[()=>n.e(6864).then(n.t.bind(n,82505,19)),"~docs/algorithms/tag-algorithms-tags-karel-df7.json",82505],bc0c9d90:[()=>n.e(354).then(n.bind(n,50476)),"@site/c/bonuses/04.md",50476],bc2d22bc:[()=>n.e(6519).then(n.t.bind(n,70428,19)),"~docs/algorithms/tag-algorithms-tags-bottom-up-dp-4f9.json",70428],c4c4056e:[()=>n.e(635).then(n.bind(n,61381)),"@site/algorithms/11-paths/2024-01-01-bf-to-astar/index.md",61381],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,53261)),"@site/src/pages/index.js",53261],c580b66a:[()=>n.e(6573).then(n.t.bind(n,45021,19)),"~docs/algorithms/tag-algorithms-tags-top-down-dp-c2f.json",45021],ccc49370:[()=>Promise.all([n.e(532),n.e(1325),n.e(130),n.e(6103)]).then(n.bind(n,65203)),"@theme/BlogPostPage",65203],cfa2b263:[()=>n.e(3086).then(n.bind(n,34437)),"@site/blog/leetcode/sort-matrix-diagonally.md",34437],d05e838c:[()=>n.e(6544).then(n.bind(n,63004)),"@site/c/bonuses/05-06.md",63004],d255bd7f:[()=>n.e(6292).then(n.t.bind(n,60341,19)),"~docs/algorithms/tag-algorithms-tags-red-black-trees-c61.json",60341],d309b5b1:[()=>n.e(8908).then(n.t.bind(n,26102,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-algorithms-and-correctness-d51.json",26102],d4b1e057:[()=>n.e(1492).then(n.t.bind(n,12842,19)),"~docs/algorithms/tag-algorithms-tags-balanced-trees-b3e.json",12842],d57b4369:[()=>n.e(6179).then(n.t.bind(n,52715,19)),"~docs/algorithms/tag-algorithms-tags-csharp-d1d.json",52715],d675395f:[()=>n.e(2741).then(n.t.bind(n,15745,19)),"/home/runner/work/blog/blog/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",15745],d79dd549:[()=>n.e(5169).then(n.t.bind(n,29261,19)),"~blog/blog/blog-tags-red-hat-df4-list.json",29261],d7f7fb17:[()=>n.e(1171).then(n.bind(n,3455)),"@site/blog/aoc-2022/00-intro.md?truncated=true",3455],d8f4410e:[()=>n.e(2997).then(n.t.bind(n,41941,19)),"~docs/algorithms/tag-algorithms-tags-hash-tables-b36.json",41941],dd841e73:[()=>n.e(2482).then(n.t.bind(n,40155,19)),"~docs/algorithms/tag-algorithms-tags-dynamic-programming-3e6.json",40155],ddc7679f:[()=>n.e(569).then(n.bind(n,64322)),"@site/algorithms/10-graphs/2021-05-18-iterative-and-iterators.md",64322],dead8108:[()=>n.e(8807).then(n.bind(n,21431)),"@site/c/bonuses/03.md",21431],decbf9d1:[()=>n.e(2445).then(n.t.bind(n,88876,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-asymptotic-notation-and-time-complexity-e0d.json",88876],df078f58:[()=>n.e(7743).then(n.t.bind(n,88298,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-paths-in-graphs-202.json",88298],df0885f0:[()=>n.e(4343).then(n.t.bind(n,34175,19)),"~docs/algorithms/tag-algorithms-tags-iterators-13a.json",34175],df203c0f:[()=>Promise.all([n.e(532),n.e(9924)]).then(n.bind(n,40491)),"@theme/DocTagDocListPage",40491],dff2ebad:[()=>n.e(146).then(n.bind(n,42492)),"@site/blog/aoc-2022/01-week-1.md",42492],e1d2ae23:[()=>n.e(1475).then(n.t.bind(n,36302,19)),"~docs/algorithms/tag-algorithms-tags-applications-020.json",36302],e31003e9:[()=>n.e(1960).then(n.t.bind(n,81695,19)),"~docs/cpp/category-cpp-autogeneratedbar-category-exceptions-and-raii-6e9.json",81695],e89da83e:[()=>n.e(8757).then(n.t.bind(n,97416,19)),"~blog/blog/blog-tags-leetcode-042-list.json",97416],eba2374c:[()=>n.e(8387).then(n.t.bind(n,47662,19)),"~docs/algorithms/tag-algorithms-tags-backtracking-bb2.json",47662],f48be158:[()=>n.e(4064).then(n.bind(n,12326)),"@site/blog/aoc-2022/03-week-3.md",12326],f75910c4:[()=>n.e(5934).then(n.bind(n,1910)),"@site/algorithms/04-recursion/2023-08-17-pyramid-slide-down/02-greedy.md",1910],fb4361d3:[()=>n.e(6327).then(n.t.bind(n,9631,19)),"~docs/algorithms/category-algorithms-autogeneratedbar-category-red-black-trees-d8a.json",9631],ff472cd9:[()=>n.e(8643).then(n.t.bind(n,7122,19)),"~blog/blog/blog-tags-iterators-977.json",7122],ff82dde7:[()=>Promise.all([n.e(532),n.e(8472)]).then(n.bind(n,63935)),"@site/algorithms/08-rb-trees/2023-06-10-rules.md",63935]};var s=n(85893);function l(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(99670),u=n(30226);function d(e,t){if("*"===e)return a()({loading:l,loader:()=>n.e(1772).then(n.bind(n,51772)),modules:["@theme/NotFound"],webpack:()=>[51772],render(e,t){const n=e.default;return(0,s.jsx)(u.z,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=o[`${e}-${t}`],d={},p=[],f=[],g=(0,c.Z)(r);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],p.push(r[1]),f.push(r[2]))})),a().Map({loading:l,loader:d,modules:p,webpack:()=>f,render(t,n){const a=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const o=r.default;if(!o)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof o&&"function"!=typeof o||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{o[e]=r[e]}));let i=a;const s=n.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=o}));const o=a.__comp;delete a.__comp;const i=a.__context;return delete a.__context,(0,s.jsx)(u.z,{value:i,children:(0,s.jsx)(o,{...a,...n})})}})}const p=[{path:"/blog/",component:d("/blog/","608"),exact:!0},{path:"/blog/2023/08/02/copr/",component:d("/blog/2023/08/02/copr/","69d"),exact:!0},{path:"/blog/aoc-2022/1st-week/",component:d("/blog/aoc-2022/1st-week/","df4"),exact:!0},{path:"/blog/aoc-2022/2nd-week/",component:d("/blog/aoc-2022/2nd-week/","783"),exact:!0},{path:"/blog/aoc-2022/3rd-week/",component:d("/blog/aoc-2022/3rd-week/","7c5"),exact:!0},{path:"/blog/aoc-2022/4th-week/",component:d("/blog/aoc-2022/4th-week/","1ac"),exact:!0},{path:"/blog/aoc-2022/intro/",component:d("/blog/aoc-2022/intro/","ada"),exact:!0},{path:"/blog/archive/",component:d("/blog/archive/","22d"),exact:!0},{path:"/blog/leetcode/sort-diagonally/",component:d("/blog/leetcode/sort-diagonally/","d97"),exact:!0},{path:"/blog/tags/",component:d("/blog/tags/","f23"),exact:!0},{path:"/blog/tags/\ud83c\udfed/",component:d("/blog/tags/\ud83c\udfed/","ffd"),exact:!0},{path:"/blog/tags/admin/",component:d("/blog/tags/admin/","d3a"),exact:!0},{path:"/blog/tags/advent-of-code-2022/",component:d("/blog/tags/advent-of-code-2022/","7bd"),exact:!0},{path:"/blog/tags/advent-of-code/",component:d("/blog/tags/advent-of-code/","313"),exact:!0},{path:"/blog/tags/copr/",component:d("/blog/tags/copr/","959"),exact:!0},{path:"/blog/tags/cpp/",component:d("/blog/tags/cpp/","770"),exact:!0},{path:"/blog/tags/iterators/",component:d("/blog/tags/iterators/","2eb"),exact:!0},{path:"/blog/tags/leetcode/",component:d("/blog/tags/leetcode/","e31"),exact:!0},{path:"/blog/tags/red-hat/",component:d("/blog/tags/red-hat/","a58"),exact:!0},{path:"/blog/tags/rust/",component:d("/blog/tags/rust/","281"),exact:!0},{path:"/blog/tags/vps/",component:d("/blog/tags/vps/","1b8"),exact:!0},{path:"/contributions/",component:d("/contributions/","541"),exact:!0},{path:"/search/",component:d("/search/","c7b"),exact:!0},{path:"/talks/",component:d("/talks/","819"),exact:!0},{path:"/algorithms/",component:d("/algorithms/","c61"),routes:[{path:"/algorithms/",component:d("/algorithms/","b39"),routes:[{path:"/algorithms/tags/",component:d("/algorithms/tags/","bb8"),exact:!0},{path:"/algorithms/tags/a-star/",component:d("/algorithms/tags/a-star/","83e"),exact:!0},{path:"/algorithms/tags/applications/",component:d("/algorithms/tags/applications/","b32"),exact:!0},{path:"/algorithms/tags/astar/",component:d("/algorithms/tags/astar/","08b"),exact:!0},{path:"/algorithms/tags/backtracking/",component:d("/algorithms/tags/backtracking/","e2d"),exact:!0},{path:"/algorithms/tags/balanced-trees/",component:d("/algorithms/tags/balanced-trees/","591"),exact:!0},{path:"/algorithms/tags/bellman-ford/",component:d("/algorithms/tags/bellman-ford/","2bc"),exact:!0},{path:"/algorithms/tags/bfs/",component:d("/algorithms/tags/bfs/","334"),exact:!0},{path:"/algorithms/tags/bottom-up-dp/",component:d("/algorithms/tags/bottom-up-dp/","9e5"),exact:!0},{path:"/algorithms/tags/brute-force/",component:d("/algorithms/tags/brute-force/","99b"),exact:!0},{path:"/algorithms/tags/c/",component:d("/algorithms/tags/c/","cc5"),exact:!0},{path:"/algorithms/tags/cpp/",component:d("/algorithms/tags/cpp/","f5b"),exact:!0},{path:"/algorithms/tags/csharp/",component:d("/algorithms/tags/csharp/","7a9"),exact:!0},{path:"/algorithms/tags/dijkstra/",component:d("/algorithms/tags/dijkstra/","aa8"),exact:!0},{path:"/algorithms/tags/dynamic-array/",component:d("/algorithms/tags/dynamic-array/","00e"),exact:!0},{path:"/algorithms/tags/dynamic-programming/",component:d("/algorithms/tags/dynamic-programming/","f82"),exact:!0},{path:"/algorithms/tags/exponential/",component:d("/algorithms/tags/exponential/","a74"),exact:!0},{path:"/algorithms/tags/graphs/",component:d("/algorithms/tags/graphs/","d5b"),exact:!0},{path:"/algorithms/tags/greedy/",component:d("/algorithms/tags/greedy/","079"),exact:!0},{path:"/algorithms/tags/hash-tables/",component:d("/algorithms/tags/hash-tables/","ae4"),exact:!0},{path:"/algorithms/tags/iterative/",component:d("/algorithms/tags/iterative/","783"),exact:!0},{path:"/algorithms/tags/iterators/",component:d("/algorithms/tags/iterators/","1bc"),exact:!0},{path:"/algorithms/tags/java/",component:d("/algorithms/tags/java/","2b4"),exact:!0},{path:"/algorithms/tags/karel/",component:d("/algorithms/tags/karel/","79f"),exact:!0},{path:"/algorithms/tags/postconditions/",component:d("/algorithms/tags/postconditions/","a27"),exact:!0},{path:"/algorithms/tags/python/",component:d("/algorithms/tags/python/","eb2"),exact:!0},{path:"/algorithms/tags/recursion/",component:d("/algorithms/tags/recursion/","2b0"),exact:!0},{path:"/algorithms/tags/red-black-trees/",component:d("/algorithms/tags/red-black-trees/","9ca"),exact:!0},{path:"/algorithms/tags/solution/",component:d("/algorithms/tags/solution/","fa0"),exact:!0},{path:"/algorithms/tags/sorting/",component:d("/algorithms/tags/sorting/","7ca"),exact:!0},{path:"/algorithms/tags/testing/",component:d("/algorithms/tags/testing/","2af"),exact:!0},{path:"/algorithms/tags/time-complexity/",component:d("/algorithms/tags/time-complexity/","2d3"),exact:!0},{path:"/algorithms/tags/top-down-dp/",component:d("/algorithms/tags/top-down-dp/","779"),exact:!0},{path:"/algorithms/",component:d("/algorithms/","b7c"),routes:[{path:"/algorithms/",component:d("/algorithms/","9b0"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/algorithms-correctness/postcondition-ambiguity/",component:d("/algorithms/algorithms-correctness/postcondition-ambiguity/","c18"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/algorithms-and-correctness/",component:d("/algorithms/category/algorithms-and-correctness/","ea2"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/asymptotic-notation-and-time-complexity/",component:d("/algorithms/category/asymptotic-notation-and-time-complexity/","fba"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/graphs/",component:d("/algorithms/category/graphs/","a92"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/hash-tables/",component:d("/algorithms/category/hash-tables/","ddd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/paths-in-graphs/",component:d("/algorithms/category/paths-in-graphs/","7c7"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/recursion/",component:d("/algorithms/category/recursion/","61f"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/category/red-black-trees/",component:d("/algorithms/category/red-black-trees/","0c0"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/graphs/bfs-tree/",component:d("/algorithms/graphs/bfs-tree/","2fb"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/graphs/iterative-and-iterators/",component:d("/algorithms/graphs/iterative-and-iterators/","bfd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/hash-tables/breaking/",component:d("/algorithms/hash-tables/breaking/","319"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/hash-tables/breaking/mitigations/",component:d("/algorithms/hash-tables/breaking/mitigations/","4c2"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/hash-tables/breaking/python/",component:d("/algorithms/hash-tables/breaking/python/","3d1"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/",component:d("/algorithms/paths/bf-to-astar/","050"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/astar/",component:d("/algorithms/paths/bf-to-astar/astar/","b4d"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/bf/",component:d("/algorithms/paths/bf-to-astar/bf/","e9c"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/paths/bf-to-astar/dijkstra/",component:d("/algorithms/paths/bf-to-astar/dijkstra/","fe4"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/rb-trees/applications/",component:d("/algorithms/rb-trees/applications/","46a"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/rb-trees/rules/",component:d("/algorithms/rb-trees/rules/","21a"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/karel/",component:d("/algorithms/recursion/karel/","4cf"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/karel/solution/",component:d("/algorithms/recursion/karel/solution/","115"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/",component:d("/algorithms/recursion/pyramid-slide-down/","236"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/bottom-up-dp/",component:d("/algorithms/recursion/pyramid-slide-down/bottom-up-dp/","00d"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/greedy/",component:d("/algorithms/recursion/pyramid-slide-down/greedy/","4bf"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/naive/",component:d("/algorithms/recursion/pyramid-slide-down/naive/","c1b"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/recursion/pyramid-slide-down/top-down-dp/",component:d("/algorithms/recursion/pyramid-slide-down/top-down-dp/","fe9"),exact:!0,sidebar:"autogeneratedBar"},{path:"/algorithms/time-complexity/extend/",component:d("/algorithms/time-complexity/extend/","250"),exact:!0,sidebar:"autogeneratedBar"}]}]}]},{path:"/c/",component:d("/c/","dae"),routes:[{path:"/c/",component:d("/c/","fc8"),routes:[{path:"/c/",component:d("/c/","1c4"),routes:[{path:"/c/",component:d("/c/","a0f"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-03/",component:d("/c/bonuses/seminar-03/","aaa"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-04/",component:d("/c/bonuses/seminar-04/","ffe"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-05-06/",component:d("/c/bonuses/seminar-05-06/","4cd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-08/",component:d("/c/bonuses/seminar-08/","09a"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/bonuses/seminar-10/",component:d("/c/bonuses/seminar-10/","b9e"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/category/bonuses/",component:d("/c/category/bonuses/","17e"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/category/practice-exams/",component:d("/c/category/practice-exams/","009"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/mr/",component:d("/c/mr/","4c5"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/pexam/cams/",component:d("/c/pexam/cams/","a10"),exact:!0,sidebar:"autogeneratedBar"},{path:"/c/pexam/garbage_collect/",component:d("/c/pexam/garbage_collect/","44e"),exact:!0,sidebar:"autogeneratedBar"}]}]}]},{path:"/cpp/",component:d("/cpp/","269"),routes:[{path:"/cpp/",component:d("/cpp/","187"),routes:[{path:"/cpp/",component:d("/cpp/","102"),routes:[{path:"/cpp/",component:d("/cpp/","fcd"),exact:!0,sidebar:"autogeneratedBar"},{path:"/cpp/category/exceptions-and-raii/",component:d("/cpp/category/exceptions-and-raii/","cfa"),exact:!0,sidebar:"autogeneratedBar"},{path:"/cpp/environment/",component:d("/cpp/environment/","e0b"),exact:!0,sidebar:"autogeneratedBar"},{path:"/cpp/exceptions-and-raii/placeholders/",component:d("/cpp/exceptions-and-raii/placeholders/","9b3"),exact:!0,sidebar:"autogeneratedBar"}]}]}]},{path:"/",component:d("/","dfb"),exact:!0},{path:"*",component:d("*")}]},98934:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,t:()=>i});var r=n(67294),a=n(85893);const o=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,a.jsx)(o.Provider,{value:n,children:t})}},97221:(e,t,n)=>{"use strict";var r=n(67294),a=n(20745),o=n(73727),i=n(70405),s=n(10412);const l=[n(32497),n(3310),n(18320),n(7439),n(57800)];var c=n(723),u=n(16550),d=n(18790),p=n(85893);function f(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var g=n(35742),h=n(52263),m=n(44996),b=n(86668),y=n(10833),v=n(94711),w=n(19727),k=n(43320),x=n(18780),S=n(90197);function _(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.Z)(),r=(0,v.l)(),a=n[e].htmlLang,o=e=>e.replace("-","_");return(0,p.jsxs)(g.Z,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:o(a)}),Object.values(n).filter((e=>a!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:o(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function E(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.Z)(),{pathname:r}=(0,u.TH)();return e+(0,x.applyTrailingSlash)((0,m.Z)(r),{trailingSlash:n,baseUrl:t})}(),a=t?`${n}${t}`:r;return(0,p.jsxs)(g.Z,{children:[(0,p.jsx)("meta",{property:"og:url",content:a}),(0,p.jsx)("link",{rel:"canonical",href:a})]})}function C(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,b.L)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(g.Z,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:w.h})]}),n&&(0,p.jsx)(y.d,{image:n}),(0,p.jsx)(E,{}),(0,p.jsx)(_,{}),(0,p.jsx)(S.Z,{tag:k.HX,locale:e}),(0,p.jsx)(g.Z,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const T=new Map;function A(e){if(T.has(e.pathname))return{...e,pathname:T.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}var j=n(98934),N=n(58940),L=n(20469);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const I=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,L.Z)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),P("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function R(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class O extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?P("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),R(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(I,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(u.AW,{location:t,render:()=>e})})}}const F=O,M="__docusaurus-base-url-issue-banner-container",D="__docusaurus-base-url-issue-banner",B="__docusaurus-base-url-issue-banner-suggestion-container";function z(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${M}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Y=n(99670);const Q=new Set,X=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!X.has(e)&&!Q.has(e))(e))return!1;Q.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(q).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Y.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?K(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!X.has(e))(e)&&(X.add(e),R(e))},te=Object.freeze(ee),ne=Boolean(!0);if(s.Z.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(i.B6,{children:(0,p.jsx)(o.VK,{children:(0,p.jsx)(G,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},s=()=>{if(ne)r.startTransition((()=>{a.hydrateRoot(e,t,{onRecoverableError:n})}));else{const o=a.createRoot(e,{onRecoverableError:n});r.startTransition((()=>{o.render(t)}))}};R(window.location.pathname).then(s)}},58940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>p});var r=n(67294),a=n(36809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"c":{"path":"/c","versions":[{"name":"current","label":"Next","isLast":true,"path":"/c","mainDocId":"c-intro","docs":[{"id":"bonuses/seminar-03","path":"/c/bonuses/seminar-03","sidebar":"autogeneratedBar"},{"id":"bonuses/seminar-04","path":"/c/bonuses/seminar-04","sidebar":"autogeneratedBar"},{"id":"bonuses/seminar-05-06","path":"/c/bonuses/seminar-05-06","sidebar":"autogeneratedBar"},{"id":"bonuses/seminar-08","path":"/c/bonuses/seminar-08","sidebar":"autogeneratedBar"},{"id":"bonuses/seminar-10","path":"/c/bonuses/seminar-10","sidebar":"autogeneratedBar"},{"id":"c-intro","path":"/c/","sidebar":"autogeneratedBar"},{"id":"mr","path":"/c/mr","sidebar":"autogeneratedBar"},{"id":"pexam/b-garbage_collect","path":"/c/pexam/garbage_collect","sidebar":"autogeneratedBar"},{"id":"pexam/c-cams","path":"/c/pexam/cams","sidebar":"autogeneratedBar"},{"id":"/category/bonuses","path":"/c/category/bonuses","sidebar":"autogeneratedBar"},{"id":"/category/practice-exams","path":"/c/category/practice-exams","sidebar":"autogeneratedBar"}],"draftIds":[],"sidebars":{"autogeneratedBar":{"link":{"path":"/c/","label":"c-intro"}}}}],"breadcrumbs":true},"cpp":{"path":"/cpp","versions":[{"name":"current","label":"Next","isLast":true,"path":"/cpp","mainDocId":"cpp-intro","docs":[{"id":"cpp-intro","path":"/cpp/","sidebar":"autogeneratedBar"},{"id":"environment","path":"/cpp/environment","sidebar":"autogeneratedBar"},{"id":"exceptions-and-raii/2023-11-24-placeholders","path":"/cpp/exceptions-and-raii/placeholders","sidebar":"autogeneratedBar"},{"id":"/category/exceptions-and-raii","path":"/cpp/category/exceptions-and-raii","sidebar":"autogeneratedBar"}],"draftIds":[],"sidebars":{"autogeneratedBar":{"link":{"path":"/cpp/","label":"cpp-intro"}}}}],"breadcrumbs":true},"algorithms":{"path":"/algorithms","versions":[{"name":"current","label":"Next","isLast":true,"path":"/algorithms","mainDocId":"algorithms-intro","docs":[{"id":"algorithms-correctness/postcondition-ambiguity","path":"/algorithms/algorithms-correctness/postcondition-ambiguity","sidebar":"autogeneratedBar"},{"id":"algorithms-intro","path":"/algorithms/","sidebar":"autogeneratedBar"},{"id":"graphs/bfs-tree","path":"/algorithms/graphs/bfs-tree","sidebar":"autogeneratedBar"},{"id":"graphs/iterative-and-iterators","path":"/algorithms/graphs/iterative-and-iterators","sidebar":"autogeneratedBar"},{"id":"hash-tables/2023-11-28-breaking/breaking","path":"/algorithms/hash-tables/breaking","sidebar":"autogeneratedBar"},{"id":"hash-tables/2023-11-28-breaking/mitigations","path":"/algorithms/hash-tables/breaking/mitigations","sidebar":"autogeneratedBar"},{"id":"hash-tables/2023-11-28-breaking/python","path":"/algorithms/hash-tables/breaking/python","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/astar","path":"/algorithms/paths/bf-to-astar/astar","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/bf","path":"/algorithms/paths/bf-to-astar/bf","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/dijkstra","path":"/algorithms/paths/bf-to-astar/dijkstra","sidebar":"autogeneratedBar"},{"id":"paths/2024-01-01-bf-to-astar/index","path":"/algorithms/paths/bf-to-astar","sidebar":"autogeneratedBar"},{"id":"rb-trees/applications","path":"/algorithms/rb-trees/applications","sidebar":"autogeneratedBar"},{"id":"rb-trees/rules","path":"/algorithms/rb-trees/rules","sidebar":"autogeneratedBar"},{"id":"recursion/2022-11-29-karel/karel","path":"/algorithms/recursion/karel","sidebar":"autogeneratedBar"},{"id":"recursion/2022-11-29-karel/solution","path":"/algorithms/recursion/karel/solution","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/bottom-up-dp","path":"/algorithms/recursion/pyramid-slide-down/bottom-up-dp","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/greedy","path":"/algorithms/recursion/pyramid-slide-down/greedy","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/naive","path":"/algorithms/recursion/pyramid-slide-down/naive","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/pyramid-slide-down","path":"/algorithms/recursion/pyramid-slide-down","sidebar":"autogeneratedBar"},{"id":"recursion/2023-08-17-pyramid-slide-down/top-down-dp","path":"/algorithms/recursion/pyramid-slide-down/top-down-dp","sidebar":"autogeneratedBar"},{"id":"time-complexity/extend","path":"/algorithms/time-complexity/extend","sidebar":"autogeneratedBar"},{"id":"/category/algorithms-and-correctness","path":"/algorithms/category/algorithms-and-correctness","sidebar":"autogeneratedBar"},{"id":"/category/asymptotic-notation-and-time-complexity","path":"/algorithms/category/asymptotic-notation-and-time-complexity","sidebar":"autogeneratedBar"},{"id":"/category/recursion","path":"/algorithms/category/recursion","sidebar":"autogeneratedBar"},{"id":"/category/red-black-trees","path":"/algorithms/category/red-black-trees","sidebar":"autogeneratedBar"},{"id":"/category/graphs","path":"/algorithms/category/graphs","sidebar":"autogeneratedBar"},{"id":"/category/paths-in-graphs","path":"/algorithms/category/paths-in-graphs","sidebar":"autogeneratedBar"},{"id":"/category/hash-tables","path":"/algorithms/category/hash-tables","sidebar":"autogeneratedBar"}],"draftIds":[],"sidebars":{"autogeneratedBar":{"link":{"path":"/algorithms/","label":"algorithms-intro"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(57529);const l=JSON.parse('{"docusaurusVersion":"3.0.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.0.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.0.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.0.1"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"3.0.1"},"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.0.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.0.1"},"docusaurus-plugin-sass":{"type":"package","name":"docusaurus-plugin-sass","version":"0.2.5"},"docusaurus-plugin-client-redirects":{"type":"package","name":"@docusaurus/plugin-client-redirects","version":"3.0.1"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"3.0.1"}}}');var c=n(85893);const u={siteConfig:a.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},d=r.createContext(u);function p(e){let{children:t}=e;return(0,c.jsx)(d.Provider,{value:u,children:t})}},44763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(67294),a=n(10412),o=n(35742),i=n(18780),s=n(80647),l=n(85893);function c(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(u,{error:t})]})}function u(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function d(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)(f,{fallback:()=>(0,l.jsx)(c,{error:t,tryAgain:n}),children:[(0,l.jsx)(o.Z,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(s.Z,{children:(0,l.jsx)(c,{error:t,tryAgain:n})})]})}const p=e=>(0,l.jsx)(d,{...e});class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??p)(e)}return e??null}}},10412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},35742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(67294);var r=n(70405),a=n(85893);function o(e){return(0,a.jsx)(r.ql,{...e})}},39960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(67294),a=n(73727),o=n(18780),i=n(52263),s=n(13919),l=n(10412),c=n(85893);const u=r.createContext({collectLink:()=>{}});var d=n(44996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:g,isActive:h,"data-noBrokenLinkCheck":m,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:v,baseUrl:w}}=(0,i.Z)(),{withBaseUrl:k}=(0,d.C)(),x=(0,r.useContext)(u),S=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>S.current));const _=p||f;const E=(0,s.Z)(_),C=_?.replace("pathname://","");let T=void 0!==C?(A=C,b&&(e=>e.startsWith("/"))(A)?k(A):A):void 0;var A;T&&E&&(T=(0,o.applyTrailingSlash)(T,{trailingSlash:v,baseUrl:w}));const j=(0,r.useRef)(!1),N=n?a.OL:a.rU,L=l.Z.canUseIntersectionObserver,P=(0,r.useRef)(),I=()=>{j.current||null==T||(window.docusaurus.preload(T),j.current=!0)};(0,r.useEffect)((()=>(!L&&E&&null!=T&&window.docusaurus.prefetch(T),()=>{L&&P.current&&P.current.disconnect()})),[P,T,L,E]);const R=T?.startsWith("#")??!1,O=!T||!E||R;return O||m||x.collectLink(T),O?(0,c.jsx)("a",{ref:S,href:T,..._&&!E&&{target:"_blank",rel:"noopener noreferrer"},...y}):(0,c.jsx)(N,{...y,onMouseEnter:I,onTouchStart:I,innerRef:e=>{S.current=e,L&&e&&E&&(P.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(P.current.unobserve(e),P.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),P.current.observe(e))},to:T,...n&&{isActive:h,activeClassName:g}})}const f=r.forwardRef(p)},95999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c,I:()=>l});var r=n(67294),a=n(85893);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(57529);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return o(s({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=s({message:t,id:n});return(0,a.jsx)(a.Fragment,{children:o(i,r)})}},29935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},13919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},44996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>s});var r=n(67294),a=n(52263),o=n(13919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},52263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294),a=n(58940);function o(){return(0,r.useContext)(a._)}},72389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294),a=n(98934);function o(){return(0,r.useContext)(a._)}},20469:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294);const a=n(10412).Z.canUseDOM?r.useLayoutEffect:r.useEffect},99670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const s=a?`${a}.${o}`:o;r(i)?e(i,s):t[s]=i}))}(e),t}},30226:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,z:()=>i});var r=n(67294),a=n(85893);const o=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(o),s=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,a.jsx)(o.Provider,{value:s,children:t})}},80143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>b,gA:()=>f,WS:()=>g,_r:()=>d,Jo:()=>y,zh:()=>p,yW:()=>m,gB:()=>h});var r=n(16550),a=n(52263),o=n(29935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}function c(e,t){const n=l(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const u={},d=()=>i("docusaurus-plugin-content-docs")??u,p=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const t=d(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function g(e){void 0===e&&(e={});const t=f(e),{pathname:n}=(0,r.TH)();if(!t)return;return{activePlugin:t,activeVersion:l(t.pluginData,n)}}function h(e){return p(e).versions}function m(e){const t=p(e);return s(t)}function b(e){const t=p(e),{pathname:n}=(0,r.TH)();return c(t,n)}function y(e){const t=p(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:c(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},18320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(74865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(14965),a=n(36809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(96854),n(30218)(`./prism-${e}`)})),delete globalThis.Prism}(r.p1)},92503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});n(67294);var r=n(36905),a=n(95999),o=n(86668),i=n(39960);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var l=n(85893);function c(e){let{as:t,id:n,...c}=e;const{navbar:{hideOnScroll:u}}=(0,o.L)();if("h1"===t||!n)return(0,l.jsx)(t,{...c,id:void 0});const d=(0,a.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof c.children?c.children:n});return(0,l.jsxs)(t,{...c,className:(0,r.Z)("anchor",u?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,c.className),id:n,children:[c.children,(0,l.jsx)(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":d,title:d,children:"\u200b"})]})}},39471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(67294);const r={iconExternalLink:"iconExternalLink_nPIU"};var a=n(85893);function o(e){let{width:t=13.5,height:n=13.5}=e;return(0,a.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,a.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},80647:(e,t,n)=>{"use strict";n.d(t,{Z:()=>At});var r=n(67294),a=n(36905),o=n(44763),i=n(10833),s=n(16550),l=n(95999),c=n(85936),u=n(85893);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const g=(0,l.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??g,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":g,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var m=n(35281),b=n(19727);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(h,{className:y.skipToContent})}var w=n(86668),k=n(59689);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:a=1.2,className:o,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:a,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function _(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,a.Z)("clean-btn close",S.closeButton,e.className),children:(0,u.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,a.Z)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function A(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:r,textColor:a,isCloseable:o}=e;return(0,u.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:r,color:a},role:"banner",children:[o&&(0,u.jsx)("div",{className:T.announcementBarPlaceholder}),(0,u.jsx)(C,{className:T.announcementBarContent}),o&&(0,u.jsx)(_,{onClick:n,className:T.announcementBarClose})]})}var j=n(93163),N=n(12466);var L=n(902),P=n(13102);const I=r.createContext(null);function R(e){let{children:t}=e;const n=function(){const e=(0,j.e)(),t=(0,P.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,L.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return(0,u.jsx)(I.Provider,{value:n,children:t})}function O(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function F(){const e=(0,r.useContext)(I);if(!e)throw new L.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,P.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:O(o)})),[a,o,t])}function M(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:o}=F();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":o}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var D=n(92949),B=n(72389);function z(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function Z(e){let{className:t,buttonClassName:n,value:r,onChange:o}=e;const i=(0,B.Z)(),s=(0,l.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,l.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,a.Z)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,a.Z)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>o("dark"===r?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite",children:[(0,u.jsx)(z,{className:(0,a.Z)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,a.Z)(U.toggleIcon,U.darkToggleIcon)})]})})}const H=r.memo(Z),V={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function W(e){let{className:t}=e;const n=(0,w.L)().navbar.style,r=(0,w.L)().colorMode.disableSwitch,{colorMode:a,setColorMode:o}=(0,D.I)();return r?null:(0,u.jsx)(H,{className:t,buttonClassName:"dark"===n?V.darkNavbarColorModeToggle:void 0,value:a,onChange:o})}var G=n(21327);function q(){return(0,u.jsx)(G.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,j.e)();return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function Y(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(q,{}),(0,u.jsx)(W,{className:"margin-right--md"}),(0,u.jsx)(K,{})]})}var Q=n(39960),X=n(44996),J=n(13919),ee=n(98022),te=n(39471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:a,label:o,html:i,isDropdownLink:s,prependBaseUrlToHref:l,...c}=e;const d=(0,X.Z)(r),p=(0,X.Z)(t),f=(0,X.Z)(a,{forcePrependBaseUrl:!0}),g=o&&a&&!(0,J.Z)(a),h=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[o,g&&(0,u.jsx)(te.Z,{...s&&{width:12,height:12}})]})};return a?(0,u.jsx)(Q.Z,{href:l?f:a,...c,...h}):(0,u.jsx)(Q.Z,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?(0,ee.F)(n,t.pathname):t.pathname.startsWith(p)},...c,...h})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const o=(0,u.jsx)(ne,{className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:o}):o}function ae(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,a.Z)("menu__link",t),...r})})}function oe(e){let{mobile:t=!1,position:n,...r}=e;const a=t?ae:re;return(0,u.jsx)(a,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(86043),se=n(48596),le=n(52263);const ce={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(e,t){return e.some((e=>function(e,t){return!!(0,se.Mg)(e.to,t)||!!(0,ee.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const l=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),(0,u.jsxs)("div",{ref:l,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":c,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",o),...s,onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))},children:s.children??s.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(He,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(e){let{items:t,className:n,position:o,onClick:i,...l}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,le.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ue(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:g}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&g(!d)}),[c,d,g]),(0,u.jsxs)("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,a.Z)(ce.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...l,onClick:e=>{e.preventDefault(),f()},children:l.children??l.label}),(0,u.jsx)(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,r.createElement)(He,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?pe:de;return(0,u.jsx)(r,{...n})}var ge=n(94711);function he(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const me="iconLanguage_nlXk";function be(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var ye=n(20830),ve=["translations"];function we(){return we=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var _e="Ctrl";var Ee=r.forwardRef((function(e,t){var n=e.translations,a=void 0===n?{}:n,o=Se(e,ve),i=a.buttonText,s=void 0===i?"Search":i,l=a.buttonAriaLabel,c=void 0===l?"Search":l,u=ke((0,r.useState)(null),2),d=u[0],p=u[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(_e))}),[]),r.createElement("button",we({type:"button",className:"DocSearch DocSearch-Button","aria-label":c},o,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(ye.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},s)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&r.createElement(r.Fragment,null,r.createElement("kbd",{className:"DocSearch-Button-Key"},d===_e?r.createElement(be,null):d),r.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Ce=n(35742),Te=n(66177),Ae=n(239),je=n(43320);var Ne=n(73935);const Le={button:{buttonText:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,l.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,l.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,l.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,l.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,l.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,l.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,l.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,l.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Pe=null;function Ie(e){let{hit:t,children:n}=e;return(0,u.jsx)(Q.Z,{to:t.url,children:n})}function Re(e){let{state:t,onClose:n}=e;const r=(0,Te.M)();return(0,u.jsx)(Q.Z,{to:r(t.query),onClick:n,children:(0,u.jsx)(l.Z,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits},children:"See all {count} results"})})}function Oe(e){let{contextualSearch:t,externalUrlRegex:a,...o}=e;const{siteMetadata:i}=(0,le.Z)(),l=(0,Ae.l)(),c=function(){const{locale:e,tags:t}=(0,je._q)();return[`language:${e}`,t.map((e=>`docusaurus_tag:${e}`))]}(),d=o.searchParameters?.facetFilters??[],p=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(c,d):d,f={...o.searchParameters,facetFilters:p},g=(0,s.k6)(),h=(0,r.useRef)(null),m=(0,r.useRef)(null),[b,y]=(0,r.useState)(!1),[v,w]=(0,r.useState)(void 0),k=(0,r.useCallback)((()=>Pe?Promise.resolve():Promise.all([n.e(1426).then(n.bind(n,61426)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,46945)),Promise.all([n.e(532),n.e(8894)]).then(n.bind(n,18894))]).then((e=>{let[{DocSearchModal:t}]=e;Pe=t}))),[]),x=(0,r.useCallback)((()=>{k().then((()=>{h.current=document.createElement("div"),document.body.insertBefore(h.current,document.body.firstChild),y(!0)}))}),[k,y]),S=(0,r.useCallback)((()=>{y(!1),h.current?.remove()}),[y]),_=(0,r.useCallback)((e=>{k().then((()=>{y(!0),w(e.key)}))}),[k,y,w]),E=(0,r.useRef)({navigate(e){let{itemUrl:t}=e;(0,ee.F)(a,t)?window.location.href=t:g.push(t)}}).current,C=(0,r.useRef)((e=>o.transformItems?o.transformItems(e):e.map((e=>({...e,url:l(e.url)}))))).current,T=(0,r.useMemo)((()=>e=>(0,u.jsx)(Re,{...e,onClose:S})),[S]),A=(0,r.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",i.docusaurusVersion),e)),[i.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,a=e.onClose,o=e.onInput,i=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?a():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&o&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&o(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,a,o,i])}({isOpen:b,onOpen:x,onClose:S,onInput:_,searchButtonRef:m}),(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Ce.Z,{children:(0,u.jsx)("link",{rel:"preconnect",href:`https://${o.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})}),(0,u.jsx)(Ee,{onTouchStart:k,onFocus:k,onMouseOver:k,onClick:x,ref:m,translations:Le.button}),b&&Pe&&h.current&&(0,Ne.createPortal)((0,u.jsx)(Pe,{onClose:S,initialScrollY:window.scrollY,initialQuery:v,navigator:E,transformItems:C,hitComponent:Ie,transformSearchClient:A,...o.searchPagePath&&{resultsFooterComponent:T},...o,searchParameters:f,placeholder:Le.placeholder,translations:Le.modal}),h.current)]})}function Fe(){const{siteConfig:e}=(0,le.Z)();return(0,u.jsx)(Oe,{...e.themeConfig.algolia})}const Me={navbarSearchContainer:"navbarSearchContainer_Bca1"};function De(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,a.Z)(n,Me.navbarSearchContainer),children:t})}var Be=n(80143),ze=n(53438);var $e=n(60373);const Ue=e=>e.docs.find((t=>t.id===e.mainDocId));const Ze={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:a="",...o}=e;const{i18n:{currentLocale:i,locales:c,localeConfigs:d}}=(0,le.Z)(),p=(0,ge.l)(),{search:f,hash:g}=(0,s.TH)(),h=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${g}${a}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],m=t?(0,l.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,u.jsx)(fe,{...o,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(he,{className:me}),m]}),items:h})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(De,{className:n,children:(0,u.jsx)(Fe,{})})},dropdown:fe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:o=!1}=e;const i=o?"li":"div";return(0,u.jsx)(i,{className:(0,a.Z)({navbar__item:!r&&!o,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,Be.Iw)(r),i=(0,ze.vY)(t,r),s=o?.path===i?.path;return null===i||i.unlisted&&!s?null:(0,u.jsx)(oe,{exact:!0,...a,isActive:()=>s||!!o?.sidebar&&o.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,Be.Iw)(r),i=(0,ze.oz)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(oe,{exact:!0,...a,isActive:()=>o?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...a}=e;const o=(0,ze.lO)(r)[0],i=t??o.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(o).path;return(0,u.jsx)(oe,{...a,label:i,to:s})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:a,dropdownItemsAfter:o,...i}=e;const{search:c,hash:d}=(0,s.TH)(),p=(0,Be.Iw)(n),f=(0,Be.gB)(n),{savePreferredVersionName:g}=(0,$e.J)(n),h=[...a,...f.map((e=>{const t=p.alternateDocVersions[e.name]??Ue(e);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>g(e.name)}})),...o],m=(0,ze.lO)(n)[0],b=t&&h.length>1?(0,l.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):m.label,y=t&&h.length>1?void 0:Ue(m).path;return h.length<=1?(0,u.jsx)(oe,{...i,mobile:t,label:b,to:y,isActive:r?()=>!1:void 0}):(0,u.jsx)(fe,{...i,mobile:t,label:b,to:y,items:h,isActive:r?()=>!1:void 0})}};function He(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=Ze[r];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(a,{...n})}function Ve(){const e=(0,j.e)(),t=(0,w.L)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(He,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function We(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ge(){const e=0===(0,w.L)().navbar.items.length,t=F();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(We,{onClick:()=>t.hide()}),t.content]})}function qe(){const e=(0,j.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(M,{header:(0,u.jsx)(Y,{}),primaryMenu:(0,u.jsx)(Ve,{}),secondaryMenu:(0,u.jsx)(Ge,{})}):null}const Ke={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ye(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,a.Z)("navbar-sidebar__backdrop",e.className)})}function Qe(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,j.e)(),{navbarRef:s,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,N.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:s,"aria-label":(0,l.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Ke.navbarHideable,!d&&Ke.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Ye,{onClick:i.toggle}),(0,u.jsx)(qe,{})]})}var Xe=n(69690);const Je="right";function et(e){let{width:t=30,height:n=30,className:r,...a}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...a,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function tt(){const{toggle:e,shown:t}=(0,j.e)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,l.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(et,{})})}const nt={colorModeToggle:"colorModeToggle_DEke"};function rt(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(Xe.QW,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(He,{...e})},t)))})}function at(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function ot(){const e=(0,j.e)(),t=(0,w.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Je)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),a=t.find((e=>"search"===e.type));return(0,u.jsx)(at,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(tt,{}),(0,u.jsx)(q,{}),(0,u.jsx)(rt,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(rt,{items:r}),(0,u.jsx)(W,{className:nt.colorModeToggle}),!a&&(0,u.jsx)(De,{children:(0,u.jsx)(Fe,{})})]})})}function it(){return(0,u.jsx)(Qe,{children:(0,u.jsx)(ot,{})})}function st(e){let{item:t}=e;const{to:n,href:r,label:a,prependBaseUrlToHref:o,...i}=t,s=(0,X.Z)(n),l=(0,X.Z)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Q.Z,{className:"footer__link-item",...r?{href:o?l:r}:{to:s},...i,children:[a,r&&!(0,J.Z)(r)&&(0,u.jsx)(te.Z,{})]})}function lt(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(st,{item:t})},t.href??t.to)}function ct(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(lt,{item:e},t)))})]})}function ut(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(ct,{column:e},t)))})}function dt(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function pt(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(st,{item:t})}function ft(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(pt,{item:e}),t.length!==n+1&&(0,u.jsx)(dt,{})]},n)))})})}function gt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(ut,{columns:t}):(0,u.jsx)(ft,{links:t})}var ht=n(19965);const mt={footerLogoLink:"footerLogoLink_BH7S"};function bt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(ht.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function yt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Q.Z,{href:t.href,className:mt.footerLogoLink,target:t.target,children:(0,u.jsx)(bt,{logo:t})}):(0,u.jsx)(bt,{logo:t})}function vt(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function wt(e){let{style:t,links:n,logo:r,copyright:o}=e;return(0,u.jsx)("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||o)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),o]})]})})}function kt(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:a}=e;return(0,u.jsx)(wt,{style:a,links:n&&n.length>0&&(0,u.jsx)(gt,{links:n}),logo:r&&(0,u.jsx)(yt,{logo:r}),copyright:t&&(0,u.jsx)(vt,{copyright:t})})}const xt=r.memo(kt),St=(0,L.Qc)([D.S,k.pl,N.OC,$e.L5,i.VC,function(e){let{children:t}=e;return(0,u.jsx)(P.n2,{children:(0,u.jsx)(j.M,{children:(0,u.jsx)(R,{children:t})})})}]);function _t(e){let{children:t}=e;return(0,u.jsx)(St,{children:t})}var Et=n(92503);function Ct(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(Et.Z,{as:"h1",className:"hero__title",children:(0,u.jsx)(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(Xe.Cw,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(Xe.aG,{error:t})})]})})})}const Tt={mainWrapper:"mainWrapper_z2l0"};function At(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:l}=e;return(0,b.t)(),(0,u.jsxs)(_t,{children:[(0,u.jsx)(i.d,{title:s,description:l}),(0,u.jsx)(v,{}),(0,u.jsx)(A,{}),(0,u.jsx)(it,{}),(0,u.jsx)("div",{id:d,className:(0,a.Z)(m.k.wrapper.main,Tt.mainWrapper,r),children:(0,u.jsx)(o.Z,{fallback:e=>(0,u.jsx)(Ct,{...e}),children:t})}),!n&&(0,u.jsx)(xt,{})]})}},21327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(67294);var r=n(39960),a=n(44996),o=n(52263),i=n(86668),s=n(19965),l=n(85893);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,a.Z)(t.src),dark:(0,a.Z)(t.srcDark||t.src)},i=(0,l.jsx)(s.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,l.jsx)("div",{className:r,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,o.Z)(),{navbar:{title:n,logo:s}}=(0,i.L)(),{imageClassName:u,titleClassName:d,...p}=e,f=(0,a.Z)(s?.href||"/"),g=n?"":t,h=s?.alt??g;return(0,l.jsxs)(r.Z,{to:f,...p,...s?.target&&{target:s.target},children:[s&&(0,l.jsx)(c,{logo:s,alt:h,imageClassName:u}),null!=n&&(0,l.jsx)("b",{className:d,children:n})]})}},90197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(67294);var r=n(35742),a=n(85893);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return(0,a.jsxs)(r.Z,{children:[t&&(0,a.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,a.jsx)("meta",{name:"docusaurus_version",content:n}),o&&(0,a.jsx)("meta",{name:"docusaurus_tag",content:o}),i&&(0,a.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,a.jsx)("meta",{name:"docsearch:version",content:n}),o&&(0,a.jsx)("meta",{name:"docsearch:docusaurus_tag",content:o})]})}},19965:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(67294),a=n(788),o=n(72389),i=n(92949);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var l=n(85893);function c(e){let{className:t,children:n}=e;const c=(0,o.Z)(),{colorMode:u}=(0,i.I)();return(0,l.jsx)(l.Fragment,{children:(c?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const o=n({theme:e,className:(0,a.Z)(t,s.themedComponent,s[`themedComponent--${e}`])});return(0,l.jsx)(r.Fragment,{children:o},e)}))})}function u(e){const{sources:t,className:n,alt:r,...a}=e;return(0,l.jsx)(c,{className:n,children:e=>{let{theme:n,className:o}=e;return(0,l.jsx)("img",{src:t[n],alt:r,className:o,...a})}})}},86043:(e,t,n)=>{"use strict";n.d(t,{u:()=>c,z:()=>b});var r=n(67294),a=n(10412),o=n(20469),i=n(91442),s=n(85893);const l="ease-in-out";function c(e){let{initialState:t}=e;const[n,a]=(0,r.useState)(t??!1),o=(0,r.useCallback)((()=>{a((e=>!e))}),[]);return{collapsed:n,setCollapsed:a,toggleCollapsed:o}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:a}=e;const o=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=a?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${a?.easing??l}`,height:`${t}px`}}function s(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return p(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,a])}function g(e){if(!a.Z.canUseDOM)return e?u:d}function h(e){let{as:t="div",collapsed:n,children:a,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:c}=e;const u=(0,r.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:o}),(0,s.jsx)(t,{ref:u,style:c?void 0:g(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),i?.(n))},className:l,children:a})}function m(e){let{collapsed:t,...n}=e;const[a,i]=(0,r.useState)(!t),[l,c]=(0,r.useState)(t);return(0,o.Z)((()=>{t||i(!0)}),[t]),(0,o.Z)((()=>{a&&c(t)}),[a,t]),a?(0,s.jsx)(h,{...n,collapsed:l}):null}function b(e){let{lazy:t,...n}=e;const r=t?m:h;return(0,s.jsx)(r,{...n})}},59689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>h,pl:()=>g});var r=n(67294),a=n(72389),o=n(50012),i=n(902),s=n(86668),l=n(85893);const c=(0,o.WA)("docusaurus.announcement.dismiss"),u=(0,o.WA)("docusaurus.announcement.id"),d=()=>"true"===c.get(),p=e=>c.set(String(e)),f=r.createContext(null);function g(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{o(d())}),[]);const i=(0,r.useCallback)((()=>{p(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&p(!1),!r&&d()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,l.jsx)(f.Provider,{value:n,children:t})}function h(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},92949:(e,t,n)=>{"use strict";n.d(t,{I:()=>b,S:()=>m});var r=n(67294),a=n(10412),o=n(902),i=n(50012),s=n(86668),l=n(85893);const c=r.createContext(void 0),u="theme",d=(0,i.WA)(u),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,g=e=>a.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),h=e=>{d.set(f(e))};function m(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[a,o]=(0,r.useState)(g(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&h(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const l=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===p.dark},setLightTheme(){i(p.light)},setDarkTheme(){i(p.dark)}})),[a,i])}();return(0,l.jsx)(c.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(c);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},60373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>b,Oh:()=>w});var r=n(67294),a=n(80143),o=n(29935),i=n(86668),s=n(53438),l=n(902),c=n(50012),u=n(85893);const d=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,c.WA)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(d(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const g=r.createContext(null);function h(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,s]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=p.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function m(e){let{children:t}=e;const n=h();return(0,u.jsx)(g.Provider,{value:n,children:t})}function b(e){let{children:t}=e;return s.cE?(0,u.jsx)(m,{children:t}):(0,u.jsx)(u.Fragment,{children:t})}function y(){const e=(0,r.useContext)(g);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=y(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function w(){const e=(0,a._r)(),[t]=y();function n(n){const r=e[n],{preferredVersionName:a}=t[n];return r.versions.find((e=>e.name===a))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,b:()=>l});var r=n(67294),a=n(902),o=n(85893);const i=Symbol("EmptyContext"),s=r.createContext(i);function l(e){let{children:t,name:n,items:a}=e;const i=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return(0,o.jsx)(s.Provider,{value:i,children:t})}function c(){const e=(0,r.useContext)(s);if(e===i)throw new a.i6("DocsSidebarProvider");return e}},74477:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>s});var r=n(67294),a=n(902),o=n(85893);const i=r.createContext(null);function s(e){let{children:t,version:n}=e;return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(i);if(null===e)throw new a.i6("DocsVersionProvider");return e}},93163:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(67294),a=n(13102),o=n(87524),i=n(91980),s=n(86668),l=n(902),c=n(85893);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,s.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[l,c]=(0,r.useState)(!1);(0,i.Rb)((()=>{if(l)return c(!1),!1}));const u=(0,r.useCallback)((()=>{c((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&c(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:l})),[e,n,u,l])}function p(e){let{children:t}=e;const n=d();return(0,c.jsx)(u.Provider,{value:n,children:t})}function f(){const e=r.useContext(u);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},13102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>c,n2:()=>s});var r=n(67294),a=n(902),o=n(85893);const i=r.createContext(null);function s(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(i);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const o=(0,r.useContext)(i);if(!o)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,s]=o,l=(0,a.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},19727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(67294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},66177:(e,t,n)=>{"use strict";n.d(t,{K:()=>s,M:()=>l});var r=n(67294),a=n(52263),o=n(91980);const i="q";function s(){return(0,o.Nc)(i)}function l(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,a.Z)(),{algolia:{searchPagePath:n}}=t;return(0,r.useCallback)((t=>`${e}${n}?${i}=${encodeURIComponent(t)}`),[e,n])}},87524:(e,t,n)=>{"use strict";n.d(t,{i:()=>s});var r=n(67294),a=n(10412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(){const[e,t]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){t(function(){if(!a.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>i?o.desktop:o.mobile}())}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[]),e}},35281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},91442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},53438:(e,t,n)=>{"use strict";n.d(t,{LM:()=>g,MN:()=>T,SN:()=>C,_F:()=>y,cE:()=>p,f:()=>w,jA:()=>h,lO:()=>S,oz:()=>_,s1:()=>x,vY:()=>E,xz:()=>f});var r=n(67294),a=n(16550),o=n(18790),i=n(80143),s=n(60373),l=n(74477),c=n(1116),u=n(67392),d=n(48596);const p=!!i._r;function f(e){const t=(0,l.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function g(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=g(t);if(e)return e}}(e):void 0:e.href}function h(){const{pathname:e}=(0,a.TH)(),t=(0,c.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=k({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const m=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),b=(e,t)=>e.some((e=>y(e,t)));function y(e,t){return"link"===e.type?m(e.href,t):"category"===e.type&&(m(e.href,t)||b(e.items,t))}function v(e,t){switch(e.type){case"category":return y(e,t)||e.items.some((e=>v(e,t)));case"link":return!e.unlisted||y(e,t);default:return!0}}function w(e,t){return(0,r.useMemo)((()=>e.filter((e=>v(e,t)))),[e,t])}function k(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function x(){const e=(0,c.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?k({sidebarItems:e.items,pathname:t}):null}function S(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>(0,u.j)([t,n,a].filter(Boolean))),[t,n,a])}function _(e,t){const n=S(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function E(e,t){const n=S(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,u.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function C(e){let{route:t}=e;const n=(0,a.TH)(),r=(0,l.E)(),i=t.routes,s=i.find((e=>(0,a.LX)(n.pathname,e)));if(!s)return null;const c=s.sidebar,u=c?r.docsSidebars[c]:void 0;return{docElement:(0,o.H)(i),sidebarName:c,sidebarItems:u}}function T(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!g(e)))}},69690:(e,t,n)=>{"use strict";n.d(t,{aG:()=>u,Ac:()=>c,Cw:()=>l,QW:()=>d});var r=n(67294),a=n(95999),o=n(18780);const i={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};var s=n(85893);function l(e){return(0,s.jsx)("button",{type:"button",...e,children:(0,s.jsx)(a.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function c(e){let{error:t,tryAgain:n}=e;return(0,s.jsxs)("div",{className:i.errorBoundaryFallback,children:[(0,s.jsx)("p",{children:t.message}),(0,s.jsx)(l,{onClick:n})]})}function u(e){let{error:t}=e;const n=(0,o.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,s.jsx)("p",{className:i.errorBoundaryError,children:n})}class d extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},82128:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(52263);function a(e){const{siteConfig:t}=(0,r.Z)(),{title:n,titleDelimiter:a}=t;return e?.trim().length?`${e.trim()} ${a} ${n}`:n}},91980:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>l,Rb:()=>i,_X:()=>s});var r=n(67294),a=n(16550),o=n(902);function i(e){!function(e){const t=(0,a.k6)(),n=(0,o.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function s(e){return function(e){const t=(0,a.k6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}function l(e){const t=s(e)??"",n=function(){const e=(0,a.k6)();return(0,r.useCallback)(((t,n,r)=>{const a=new URLSearchParams(e.location.search);n?a.set(t,n):a.delete(t),(r?.push?e.push:e.replace)({search:a.toString()})}),[e])}();return[t,(0,r.useCallback)(((t,r)=>{n(e,t,r)}),[n,e])]}},67392:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function a(e){return Array.from(new Set(e))}n.d(t,{j:()=>a,l:()=>r})},10833:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>d,VC:()=>g});var r=n(67294),a=n(788),o=n(35742),i=n(30226);function s(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(44996),c=n(82128),u=n(85893);function d(e){let{title:t,description:n,keywords:r,image:a,children:i}=e;const s=(0,c.p)(t),{withBaseUrl:d}=(0,l.C)(),p=a?d(a,{absolute:!0}):void 0;return(0,u.jsxs)(o.Z,{children:[t&&(0,u.jsx)("title",{children:s}),t&&(0,u.jsx)("meta",{property:"og:title",content:s}),n&&(0,u.jsx)("meta",{name:"description",content:n}),n&&(0,u.jsx)("meta",{property:"og:description",content:n}),r&&(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,u.jsx)("meta",{property:"og:image",content:p}),p&&(0,u.jsx)("meta",{name:"twitter:image",content:p}),i]})}const p=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(p),s=(0,a.Z)(i,t);return(0,u.jsxs)(p.Provider,{value:s,children:[(0,u.jsx)(o.Z,{children:(0,u.jsx)("html",{className:s})}),n]})}function g(e){let{children:t}=e;const n=s(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const o=`plugin-id-${n.plugin.id}`;return(0,u.jsx)(f,{className:(0,a.Z)(r,o),children:t})}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>s,Qc:()=>u,Ql:()=>c,i6:()=>l,zX:()=>i});var r=n(67294),a=n(20469),o=n(85893);function i(e){const t=(0,r.useRef)(e);return(0,a.Z)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function s(e){const t=(0,r.useRef)();return(0,a.Z)((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,o.jsx)(o.Fragment,{children:e.reduceRight(((e,t)=>(0,o.jsx)(t,{children:e})),n)})}}},98022:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:()=>r})},48596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var r=n(67294),a=n(723),o=n(52263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},12466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>h,OC:()=>u,RF:()=>f,o5:()=>g});var r=n(67294),a=n(10412),o=n(72389),i=n(20469),s=n(902),l=n(85893);const c=r.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,l.jsx)(c.Provider,{value:n,children:t})}function d(){const e=(0,r.useContext)(c);if(null==e)throw new s.i6("ScrollControllerProvider");return e}const p=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=d(),a=(0,r.useRef)(p()),o=(0,s.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=p();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function g(){const e=d(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),a=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,i.Z)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:a}}function h(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},43320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>i,_q:()=>l,os:()=>s});var r=n(80143),a=n(52263),o=n(60373);const i="default";function s(e,t){return`docs-${e}-${t}`}function l(){const{i18n:e}=(0,a.Z)(),t=(0,r._r)(),n=(0,r.WS)(),l=(0,o.Oh)();const c=[i,...Object.keys(t).map((function(e){const r=n?.activePlugin.pluginId===e?n.activeVersion:void 0,a=l[e],o=t[e].versions.find((e=>e.isLast));return s(e,(r??a??o).name)}))];return{locale:e.currentLocale,tags:c}}},50012:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>u,WA:()=>c});var r=n(67294);const a="localStorage";function o(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function i(e){if(void 0===e&&(e=a),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,s||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),s=!0),null}var t}let s=!1;const l={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=i(t?.persistence);return null===n?l:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),o({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),o({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}function u(e,t){const n=(0,r.useRef)((()=>null===e?l:c(e,t))).current(),a=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,r.useSyncExternalStore)(a,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},94711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(52263),a=n(16550),o=n(18780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,r.Z)(),{pathname:l}=(0,a.TH)(),c=(0,o.applyTrailingSlash)(l,{trailingSlash:n,baseUrl:e}),u=s===i?e:e.replace(`/${s}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},85936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(67294),a=n(16550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},86668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(52263);function a(){return(0,r.Z)().siteConfig.themeConfig}},6278:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(52263);function a(){const{siteConfig:{themeConfig:e}}=(0,r.Z)();return e}},239:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var r=n(67294),a=n(98022),o=n(44996),i=n(6278);function s(){const{withBaseUrl:e}=(0,o.C)(),{algolia:{externalUrlRegex:t,replaceSearchResultPathname:n}}=(0,i.L)();return(0,r.useCallback)((r=>{const o=new URL(r);if((0,a.F)(t,o.href))return r;const i=`${o.pathname+o.hash}`;return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(i,n))}),[e,t,n])}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},54143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},18780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(54143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},99318:(e,t,n)=>{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>f,PP:()=>A,Ep:()=>p});var r=n(87462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var g=i.join("/");return n&&"/"!==g.substr(-1)&&(g+="/"),g};var s=n(38776);function l(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function g(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,h(),w.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(59864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?i:s[e.$$typeof]||a}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,g=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(g){var a=f(n);a&&a!==g&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=l(t),h=l(n),m=0;m{"use strict";e.exports=function(e,t,n,r,a,o,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,s],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},7439:(e,t,n)=>{"use strict";n.r(t)},32497:(e,t,n)=>{"use strict";n.r(t)},57800:(e,t,n)=>{"use strict";n.r(t)},74865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(c,i(e,u,d)),1===e?(l(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){l(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),s=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&f(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},85795:()=>{Prism.languages.ada={comment:/--.*/,string:/"(?:""|[^"\r\f\n])*"/,number:[{pattern:/\b\d(?:_?\d)*#[\dA-F](?:_?[\dA-F])*(?:\.[\dA-F](?:_?[\dA-F])*)?#(?:E[+-]?\d(?:_?\d)*)?/i},{pattern:/\b\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:E[+-]?\d(?:_?\d)*)?\b/i}],attribute:{pattern:/\b'\w+/,alias:"attr-name"},keyword:/\b(?:abort|abs|abstract|accept|access|aliased|all|and|array|at|begin|body|case|constant|declare|delay|delta|digits|do|else|elsif|end|entry|exception|exit|for|function|generic|goto|if|in|interface|is|limited|loop|mod|new|not|null|of|or|others|out|overriding|package|pragma|private|procedure|protected|raise|range|record|rem|renames|requeue|return|reverse|select|separate|some|subtype|synchronized|tagged|task|terminate|then|type|until|use|when|while|with|xor)\b/i,boolean:/\b(?:false|true)\b/i,operator:/<[=>]?|>=?|=>?|:=|\/=?|\*\*?|[&+-]/,punctuation:/\.\.?|[,;():]/,char:/'.'/,variable:/\b[a-z](?:\w)*\b/i}},57874:()=>{!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},parameter:{pattern:/(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","parameter","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i{!function(e){function t(e,t){return e.replace(/<<(\d+)>>/g,(function(e,n){return"(?:"+t[+n]+")"}))}function n(e,n,r){return RegExp(t(e,n),r||"")}function r(e,t){for(var n=0;n>/g,(function(){return"(?:"+e+")"}));return e.replace(/<>/g,"[^\\s\\S]")}var a="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",o="class enum interface record struct",i="add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",s="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var c=l(o),u=RegExp(l(a+" "+o+" "+i+" "+s)),d=l(o+" "+i+" "+s),p=l(a+" "+o+" "+s),f=r(/<(?:[^<>;=+\-*/%&|^]|<>)*>/.source,2),g=r(/\((?:[^()]|<>)*\)/.source,2),h=/@?\b[A-Za-z_]\w*\b/.source,m=t(/<<0>>(?:\s*<<1>>)?/.source,[h,f]),b=t(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source,[d,m]),y=/\[\s*(?:,\s*)*\]/.source,v=t(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source,[b,y]),w=t(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source,[f,g,y]),k=t(/\(<<0>>+(?:,<<0>>+)+\)/.source,[w]),x=t(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source,[k,b,y]),S={keyword:u,punctuation:/[<>()?,.:[\]]/},_=/'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source,E=/"(?:\\.|[^\\"\r\n])*"/.source,C=/@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source;e.languages.csharp=e.languages.extend("clike",{string:[{pattern:n(/(^|[^$\\])<<0>>/.source,[C]),lookbehind:!0,greedy:!0},{pattern:n(/(^|[^@$\\])<<0>>/.source,[E]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:n(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source,[b]),lookbehind:!0,inside:S},{pattern:n(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source,[h,x]),lookbehind:!0,inside:S},{pattern:n(/(\busing\s+)<<0>>(?=\s*=)/.source,[h]),lookbehind:!0},{pattern:n(/(\b<<0>>\s+)<<1>>/.source,[c,m]),lookbehind:!0,inside:S},{pattern:n(/(\bcatch\s*\(\s*)<<0>>/.source,[b]),lookbehind:!0,inside:S},{pattern:n(/(\bwhere\s+)<<0>>/.source,[h]),lookbehind:!0},{pattern:n(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source,[v]),lookbehind:!0,inside:S},{pattern:n(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source,[x,p,h]),inside:S}],keyword:u,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),e.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),e.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:n(/([(,]\s*)<<0>>(?=\s*:)/.source,[h]),lookbehind:!0,alias:"punctuation"}}),e.languages.insertBefore("csharp","class-name",{namespace:{pattern:n(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source,[h]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:n(/(\b(?:default|sizeof|typeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source,[g]),lookbehind:!0,alias:"class-name",inside:S},"return-type":{pattern:n(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source,[x,b]),inside:S,alias:"class-name"},"constructor-invocation":{pattern:n(/(\bnew\s+)<<0>>(?=\s*[[({])/.source,[x]),lookbehind:!0,inside:S,alias:"class-name"},"generic-method":{pattern:n(/<<0>>\s*<<1>>(?=\s*\()/.source,[h,f]),inside:{function:n(/^<<0>>/.source,[h]),generic:{pattern:RegExp(f),alias:"class-name",inside:S}}},"type-list":{pattern:n(/\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source,[c,m,h,x,u.source,g,/\bnew\s*\(\s*\)/.source]),lookbehind:!0,inside:{"record-arguments":{pattern:n(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source,[m,g]),lookbehind:!0,greedy:!0,inside:e.languages.csharp},keyword:u,"class-name":{pattern:RegExp(x),greedy:!0,inside:S},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var T=E+"|"+_,A=t(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source,[T]),j=r(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[A]),2),N=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,L=t(/<<0>>(?:\s*\(<<1>>*\))?/.source,[b,j]);e.languages.insertBefore("csharp","class-name",{attribute:{pattern:n(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[N,L]),lookbehind:!0,greedy:!0,inside:{target:{pattern:n(/^<<0>>(?=\s*:)/.source,[N]),alias:"keyword"},"attribute-arguments":{pattern:n(/\(<<0>>*\)/.source,[j]),inside:e.languages.csharp},"class-name":{pattern:RegExp(b),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var P=/:[^}\r\n]+/.source,I=r(t(/[^"'/()]|<<0>>|\(<>*\)/.source,[A]),2),R=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[I,P]),O=r(t(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<>*\)/.source,[T]),2),F=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[O,P]);function M(t,r){return{interpolation:{pattern:n(/((?:^|[^{])(?:\{\{)*)<<0>>/.source,[t]),lookbehind:!0,inside:{"format-string":{pattern:n(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source,[r,P]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:e.languages.csharp}}},string:/[\s\S]+/}}e.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:n(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source,[R]),lookbehind:!0,greedy:!0,inside:M(R,I)},{pattern:n(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source,[F]),lookbehind:!0,greedy:!0,inside:M(F,O)}],char:{pattern:RegExp(_),greedy:!0}}),e.languages.dotnet=e.languages.cs=e.languages.csharp}(Prism)},60397:()=>{!function(e){var t="(?:"+[/[a-zA-Z_\x80-\uFFFF][\w\x80-\uFFFF]*/.source,/-?(?:\.\d+|\d+(?:\.\d*)?)/.source,/"[^"\\]*(?:\\[\s\S][^"\\]*)*"/.source,/<(?:[^<>]|(?!)*>/.source].join("|")+")",n={markup:{pattern:/(^<)[\s\S]+(?=>$)/,lookbehind:!0,alias:["language-markup","language-html","language-xml"],inside:e.languages.markup}};function r(e,n){return RegExp(e.replace(//g,(function(){return t})),n)}e.languages.dot={comment:{pattern:/\/\/.*|\/\*[\s\S]*?\*\/|^#.*/m,greedy:!0},"graph-name":{pattern:r(/(\b(?:digraph|graph|subgraph)[ \t\r\n]+)/.source,"i"),lookbehind:!0,greedy:!0,alias:"class-name",inside:n},"attr-value":{pattern:r(/(=[ \t\r\n]*)/.source),lookbehind:!0,greedy:!0,inside:n},"attr-name":{pattern:r(/([\[;, \t\r\n])(?=[ \t\r\n]*=)/.source),lookbehind:!0,greedy:!0,inside:n},keyword:/\b(?:digraph|edge|graph|node|strict|subgraph)\b/i,"compass-point":{pattern:/(:[ \t\r\n]*)(?:[ewc_]|[ns][ew]?)(?![\w\x80-\uFFFF])/,lookbehind:!0,alias:"builtin"},node:{pattern:r(/(^|[^-.\w\x80-\uFFFF\\])/.source),lookbehind:!0,greedy:!0,inside:n},operator:/[=:]|-[->]/,punctuation:/[\[\]{};,]/},e.languages.gv=e.languages.dot}(Prism)},81295:()=>{Prism.languages.haskell={comment:{pattern:/(^|[^-!#$%*+=?&@|~.:<>^\\\/])(?:--(?:(?=.)[^-!#$%*+=?&@|~.:<>^\\\/].*|$)|\{-[\s\S]*?-\})/m,lookbehind:!0},char:{pattern:/'(?:[^\\']|\\(?:[abfnrtv\\"'&]|\^[A-Z@[\]^_]|ACK|BEL|BS|CAN|CR|DC1|DC2|DC3|DC4|DEL|DLE|EM|ENQ|EOT|ESC|ETB|ETX|FF|FS|GS|HT|LF|NAK|NUL|RS|SI|SO|SOH|SP|STX|SUB|SYN|US|VT|\d+|o[0-7]+|x[0-9a-fA-F]+))'/,alias:"string"},string:{pattern:/"(?:[^\\"]|\\(?:\S|\s+\\))*"/,greedy:!0},keyword:/\b(?:case|class|data|deriving|do|else|if|in|infixl|infixr|instance|let|module|newtype|of|primitive|then|type|where)\b/,"import-statement":{pattern:/(^[\t ]*)import\s+(?:qualified\s+)?(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*(?:\s+as\s+(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*)?(?:\s+hiding\b)?/m,lookbehind:!0,inside:{keyword:/\b(?:as|hiding|import|qualified)\b/,punctuation:/\./}},builtin:/\b(?:abs|acos|acosh|all|and|any|appendFile|approxRational|asTypeOf|asin|asinh|atan|atan2|atanh|basicIORun|break|catch|ceiling|chr|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|denominator|digitToInt|div|divMod|drop|dropWhile|either|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromDouble|fromEnum|fromInt|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|group|head|id|inRange|index|init|intToDigit|interact|ioError|isAlpha|isAlphaNum|isAscii|isControl|isDenormalized|isDigit|isHexDigit|isIEEE|isInfinite|isLower|isNaN|isNegativeZero|isOctDigit|isPrint|isSpace|isUpper|iterate|last|lcm|length|lex|lexDigits|lexLitChar|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|numerator|odd|or|ord|otherwise|pack|pi|pred|primExitWith|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|range|rangeSize|read|readDec|readFile|readFloat|readHex|readIO|readInt|readList|readLitChar|readLn|readOct|readParen|readSigned|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showInt|showList|showLitChar|showParen|showSigned|showString|shows|showsPrec|significand|signum|sin|sinh|snd|sort|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|threadToIOResult|toEnum|toInt|toInteger|toLower|toRational|toUpper|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\b/,number:/\b(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?|0o[0-7]+|0x[0-9a-f]+)\b/i,operator:[{pattern:/`(?:[A-Z][\w']*\.)*[_a-z][\w']*`/,greedy:!0},{pattern:/(\s)\.(?=\s)/,lookbehind:!0},/[-!#$%*+=?&@|~:<>^\\\/][-!#$%*+=?&@|~.:<>^\\\/]*|\.[-!#$%*+=?&@|~.:<>^\\\/]+/],hvariable:{pattern:/\b(?:[A-Z][\w']*\.)*[_a-z][\w']*/,inside:{punctuation:/\./}},constant:{pattern:/\b(?:[A-Z][\w']*\.)*[A-Z][\w']*/,inside:{punctuation:/\./}},punctuation:/[{}[\];(),.:]/},Prism.languages.hs=Prism.languages.haskell},52503:()=>{!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,r={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[r,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:r.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:r.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":r,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:r.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:r.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism)},96854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,s=i.length;-1!==n.code.indexOf(a=t(r,s));)++s;return i[s]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l=o.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),g=p.indexOf(f);if(g>-1){++a;var h=p.substring(0,g),m=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(g+f.length),y=[];h&&y.push.apply(y,i([h])),y.push(m),b&&y.push.apply(y,i([b])),"string"==typeof c?s.splice.apply(s,[l,1].concat(y)):c.content=y}}else c.content&&i(c.content)}return s}(n.tokens)}}}})}(Prism)},58704:()=>{Prism.languages.nix={comment:{pattern:/\/\*[\s\S]*?\*\/|#.*/,greedy:!0},string:{pattern:/"(?:[^"\\]|\\[\s\S])*"|''(?:(?!'')[\s\S]|''(?:'|\\|\$\{))*''/,greedy:!0,inside:{interpolation:{pattern:/(^|(?:^|(?!'').)[^\\])\$\{(?:[^{}]|\{[^}]*\})*\}/,lookbehind:!0,inside:null}}},url:[/\b(?:[a-z]{3,7}:\/\/)[\w\-+%~\/.:#=?&]+/,{pattern:/([^\/])(?:[\w\-+%~.:#=?&]*(?!\/\/)[\w\-+%~\/.:#=?&])?(?!\/\/)\/[\w\-+%~\/.:#=?&]*/,lookbehind:!0}],antiquotation:{pattern:/\$(?=\{)/,alias:"important"},number:/\b\d+\b/,keyword:/\b(?:assert|builtins|else|if|in|inherit|let|null|or|then|with)\b/,function:/\b(?:abort|add|all|any|attrNames|attrValues|baseNameOf|compareVersions|concatLists|currentSystem|deepSeq|derivation|dirOf|div|elem(?:At)?|fetch(?:Tarball|url)|filter(?:Source)?|fromJSON|genList|getAttr|getEnv|hasAttr|hashString|head|import|intersectAttrs|is(?:Attrs|Bool|Function|Int|List|Null|String)|length|lessThan|listToAttrs|map|mul|parseDrvName|pathExists|read(?:Dir|File)|removeAttrs|replaceStrings|seq|sort|stringLength|sub(?:string)?|tail|throw|to(?:File|JSON|Path|String|XML)|trace|typeOf)\b|\bfoldl'\B/,boolean:/\b(?:false|true)\b/,operator:/[=!<>]=?|\+\+?|\|\||&&|\/\/|->?|[?@]/,punctuation:/[{}()[\].,:;]/},Prism.languages.nix.string.inside.interpolation.inside=Prism.languages.nix},13210:()=>{Prism.languages.pascal={directive:{pattern:/\{\$[\s\S]*?\}/,greedy:!0,alias:["marco","property"]},comment:{pattern:/\(\*[\s\S]*?\*\)|\{[\s\S]*?\}|\/\/.*/,greedy:!0},string:{pattern:/(?:'(?:''|[^'\r\n])*'(?!')|#[&$%]?[a-f\d]+)+|\^[a-z]/i,greedy:!0},asm:{pattern:/(\basm\b)[\s\S]+?(?=\bend\s*[;[])/i,lookbehind:!0,greedy:!0,inside:null},keyword:[{pattern:/(^|[^&])\b(?:absolute|array|asm|begin|case|const|constructor|destructor|do|downto|else|end|file|for|function|goto|if|implementation|inherited|inline|interface|label|nil|object|of|operator|packed|procedure|program|record|reintroduce|repeat|self|set|string|then|to|type|unit|until|uses|var|while|with)\b/i,lookbehind:!0},{pattern:/(^|[^&])\b(?:dispose|exit|false|new|true)\b/i,lookbehind:!0},{pattern:/(^|[^&])\b(?:class|dispinterface|except|exports|finalization|finally|initialization|inline|library|on|out|packed|property|raise|resourcestring|threadvar|try)\b/i,lookbehind:!0},{pattern:/(^|[^&])\b(?:absolute|abstract|alias|assembler|bitpacked|break|cdecl|continue|cppdecl|cvar|default|deprecated|dynamic|enumerator|experimental|export|external|far|far16|forward|generic|helper|implements|index|interrupt|iochecks|local|message|name|near|nodefault|noreturn|nostackframe|oldfpccall|otherwise|overload|override|pascal|platform|private|protected|public|published|read|register|reintroduce|result|safecall|saveregisters|softfloat|specialize|static|stdcall|stored|strict|unaligned|unimplemented|varargs|virtual|write)\b/i,lookbehind:!0}],number:[/(?:[&%]\d+|\$[a-f\d]+)/i,/\b\d+(?:\.\d+)?(?:e[+-]?\d+)?/i],operator:[/\.\.|\*\*|:=|<[<=>]?|>[>=]?|[+\-*\/]=?|[@^=]/,{pattern:/(^|[^&])\b(?:and|as|div|exclude|in|include|is|mod|not|or|shl|shr|xor)\b/,lookbehind:!0}],punctuation:/\(\.|\.\)|[()\[\]:;,.]/},Prism.languages.pascal.asm.inside=Prism.languages.extend("pascal",{asm:void 0,keyword:void 0,operator:void 0}),Prism.languages.objectpascal=Prism.languages.pascal},80366:()=>{Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python},59385:()=>{!function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===||[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var t={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var n="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",r=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+n+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:t,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+r),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+r+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+n),greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:t,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+n),greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:t,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby}(Prism)},70767:()=>{!function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|)*\*\//.source,n=0;n<2;n++)t=t.replace(//g,(function(){return t}));t=t.replace(//g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism)},30218:(e,t,n)=>{var r={"./prism-ada":85795,"./prism-bash":57874,"./prism-csharp":79016,"./prism-dot":60397,"./prism-haskell":81295,"./prism-java":52503,"./prism-nix":58704,"./prism-pascal":13210,"./prism-python":80366,"./prism-ruby":59385,"./prism-rust":70767};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=30218},92703:(e,t,n)=>{"use strict";var r=n(50414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},64448:(e,t,n)=>{"use strict";var r=n(67294),a=n(63840);function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n