From 73bccb8160d3fe1ad307c7f5d495142e14347b3b Mon Sep 17 00:00:00 2001
From: Tue Herlau <tuhe@dtu.dk>
Date: Sun, 5 Sep 2021 17:31:26 +0200
Subject: [PATCH] Refactor citation + tags and update README.md

---
 README.md                                     | 284 ++++++++++++------
 docs/README.jinja.md                          | 167 +++++-----
 docs/build_docs.py                            |  56 ++--
 docs/index.png                                | Bin 0 -> 30083 bytes
 examples/cs101_instructor/b_tag.py            |  15 +
 examples/cs101_instructor/f_tag.py            |   6 +
 examples/cs101_instructor/i_tag.py            |   8 +
 examples/cs101_instructor/o_tag.py            |  11 +
 .../{homework1.py => references.py}           |  12 +-
 examples/cs101_instructor/s_tag.py            |  17 ++
 examples/cs101_output/homework1.py            |  17 ++
 examples/cs101_output/i_tag_a.shell           |   6 +
 examples/cs101_output/i_tag_b.shell           |   5 +
 examples/cs101_output/o_tag_a.txt             |   5 +
 examples/cs101_output/o_tag_b.txt             |   3 +
 examples/cs101_output/s_tag.py                |  39 +++
 examples/cs101_students/b_tag.py              |  12 +
 examples/cs101_students/f_tag.py              |   7 +
 examples/cs101_students/i_tag.py              |  10 +
 examples/cs101_students/o_tag.py              |  11 +
 examples/cs101_students/references.py         |  18 ++
 examples/cs101_students/s_tag.py              |  18 ++
 examples/process_cs101.py                     |  26 +-
 examples/process_cs101_references.py          |  15 +
 .../__pycache__/block_parsing.cpython-38.pyc  | Bin 0 -> 2572 bytes
 src/snipper/__pycache__/fix_bf.cpython-38.pyc | Bin 0 -> 2163 bytes
 .../__pycache__/fix_cite.cpython-38.pyc       | Bin 2453 -> 2762 bytes
 src/snipper/__pycache__/fix_o.cpython-38.pyc  | Bin 0 -> 1387 bytes
 src/snipper/__pycache__/fix_s.cpython-38.pyc  | Bin 3728 -> 1384 bytes
 src/snipper/__pycache__/legacy.cpython-38.pyc | Bin 0 -> 1790 bytes
 .../__pycache__/load_citations.cpython-38.pyc | Bin 0 -> 4979 bytes
 .../__pycache__/snip_dir.cpython-38.pyc       | Bin 1978 -> 2103 bytes
 .../__pycache__/snipper_main.cpython-38.pyc   | Bin 10073 -> 5835 bytes
 src/snipper/block_parsing.py                  |  11 +-
 src/snipper/fix_bf.py                         |  67 +++++
 src/snipper/fix_cite.py                       |  20 +-
 src/snipper/fix_i.py                          |   0
 src/snipper/fix_o.py                          |  38 +++
 src/snipper/legacy.py                         |  75 +++++
 src/snipper/snip_dir.py                       |  27 +-
 src/snipper/snipper_main.py                   | 191 ++----------
 41 files changed, 788 insertions(+), 409 deletions(-)
 create mode 100644 docs/index.png
 create mode 100644 examples/cs101_instructor/b_tag.py
 create mode 100644 examples/cs101_instructor/f_tag.py
 create mode 100644 examples/cs101_instructor/i_tag.py
 create mode 100644 examples/cs101_instructor/o_tag.py
 rename examples/cs101_instructor/{homework1.py => references.py} (62%)
 create mode 100644 examples/cs101_instructor/s_tag.py
 create mode 100644 examples/cs101_output/homework1.py
 create mode 100644 examples/cs101_output/i_tag_a.shell
 create mode 100644 examples/cs101_output/i_tag_b.shell
 create mode 100644 examples/cs101_output/o_tag_a.txt
 create mode 100644 examples/cs101_output/o_tag_b.txt
 create mode 100644 examples/cs101_output/s_tag.py
 create mode 100644 examples/cs101_students/b_tag.py
 create mode 100644 examples/cs101_students/f_tag.py
 create mode 100644 examples/cs101_students/i_tag.py
 create mode 100644 examples/cs101_students/o_tag.py
 create mode 100644 examples/cs101_students/references.py
 create mode 100644 examples/cs101_students/s_tag.py
 create mode 100644 examples/process_cs101_references.py
 create mode 100644 src/snipper/__pycache__/block_parsing.cpython-38.pyc
 create mode 100644 src/snipper/__pycache__/fix_bf.cpython-38.pyc
 create mode 100644 src/snipper/__pycache__/fix_o.cpython-38.pyc
 create mode 100644 src/snipper/__pycache__/legacy.cpython-38.pyc
 create mode 100644 src/snipper/__pycache__/load_citations.cpython-38.pyc
 create mode 100644 src/snipper/fix_i.py
 create mode 100644 src/snipper/fix_o.py
 create mode 100644 src/snipper/legacy.py

diff --git a/README.md b/README.md
index 4541d88..5a4acc3 100644
--- a/README.md
+++ b/README.md
@@ -20,82 +20,205 @@ The project is currently used in **02465** at DTU. An example of student code ca
 A set of lectures notes where all code examples/output are automatically generated from the working repository can be found a
 - https://lab.compute.dtu.dk/tuhe/books (see **Sequential decision making**)
  
-## How it works
-The basic functionality is quite simple. You start with your working script in your private repository and add special tags to the script. 
-In this case I have added the tags `#!b` (cut a block) and `#!f` (cut function scope). 
+# Usage
+All examples can be found in the `/examples` directory. The idea is all our (complete) files are found in the instructor directory and snipper keeps everything up-to-date:
+```text
+examples/cs101_instructor  # This directory contains the (hidden) instructor files. You edit these
+examples/cs101_students    # This directory contains the (processed) student files. Don't edit these
+examples/cs101_output      # This contains automatically generated contents (snippets, etc.).
+```
+The basic functionality is you insert special comment tags in your source, such as `#!b` or `#!s` and the script then process
+the sources based on the tags.  The following will show most basic usages:
+
+## The #f!-tag
+Let's start with the simplest example, blocking out a function (see `examples/cs101_instructor/f_tag.py`; actually it will work for any scope)
+You insert a comment like: `#!f <exception message>` like so:
 ```python
-def myfun(): #!f The error I am going to raise
-    """ The function docstring will not be removed"""
-    print("This is a function")
-    return 42
-    
-def a_long_function():
-    a = 234
-    print("a line")
-    print("a line") #!b
-    print("a line")
-    print("a line") #!b Insert three missing print statements. 
-    print("a line")
-    return a
-    
-if __name__ == "__main__":
-    myfun()
+def myfun(a,b): #!f return the sum of a and b
+    """ The doc-string is not removed. """
+    sm = a+b
+    return sm
 ```
-This will produce the following file:
+To compile this (and all other examples) use the script `examples/process_cs101.py`
 ```python
-def myfun():
-    """ The function docstring will not be removed"""
-    # TODO: 2 lines missing.
-    raise NotImplementedError("The error I am going to raise")
-    
-def a_long_function():
-    a = 234
-    print("a line")
-    # TODO: 3 lines missing.
-    raise NotImplementedError("Insert three missing print statements.")
-    print("a line")
-    return a
-    
 if __name__ == "__main__":
-    myfun()
+    from snipper.snip_dir import snip_dir
+    snip_dir("./cs101_instructor", "./cs101_students", output_dir="./cs101_output")
+```
+The output can be found in `examples/students/f_tag.py`. It will cut out the body of the function but leave any return statement and docstrings. It will also raise an exception (and print how many lines are missing) to help students.
+```python
+"""
+"""
+def myfun(a,b): 
+    """ The doc-string is not removed. """
+    # TODO: 1 lines missing.
+    raise NotImplementedError("return the sum of a and b")
+    return sm
 ```
-You can also use the framework to capture code snippets, outputs and interactive python output. 
-To do this, save the following in `foo.py`
+
+## The #b!-tag
+The #!b-tag allows you more control over what is cut out. The instructor file:
 ```python
-def myfun(): #!s This snippet will be saved to foo.py in the output directory. 
-    print("Hello") #!s 
-
-print("Do not capture me") 
-for i in range(4): #!o
-    print("Output", i)
-print("Goodbuy world") #!o
-print("don't capture me")
-
-# Interactive pythong example
-print("Hello World") #!i #!i # this is a single-line cutout.
-````
-These block-tags will create a file `foo.py` (in the output directory) containing
+def primes_sieve(limit):
+    limitn = limit+1 #!b
+    primes = range(2, limitn)
+    for i in primes:
+        factors = list(range(i, limitn, i))
+        for f in factors[1:]:
+            if f in primes:
+                primes.remove(f) #!b Compute the list `primes` here of all primes up to `limit`
+    return primes
+width, height = 2, 4
+print("Area of square of width", width, "and height", height, "is:")
+print(width*height) #!b #!b Compute and print area here
+print("and that is a fact!")
+```
+Is compiled into:
+```python 
+"""
+"""
+def primes_sieve(limit):
+    # TODO: 8 lines missing.
+    raise NotImplementedError("Compute the list `primes` here of all primes up to `limit`")
+    return primes
+width, height = 2, 4
+print("Area of square of width", width, "and height", height, "is:")
+# TODO: 1 lines missing.
+raise NotImplementedError("Compute and print area here")
+print("and that is a fact!")
+```
+This allows you to cut out text across scopes, but still allows you to insert exceptions. 
+
+
+
+## The #s!-tag
+The #!s-tag is useful for making examples to include in exercises and lecture notes. The #!s (snip) tag cuts out the text between 
+tags and places it in files found in the output-directory. As an example, here is the instructor file:
 ```python
-def myfun():
-    print("Hello") 
-```
-A file `foo.txt` containing the captured output
-```txt
-Output 0
-Output 1
-Output 2
-Output 3
-Goodbuy world
-```
-and a typeset version of an interactive python session in `foo.pyi` (use `pycon` in minted; this gitlab server appears not to support `pycon`)
+width, height = 2, 4
+print("Area of square of width", width, "and height", height, "is:") #!s
+print(width*height)  #!s  # This is an example of a simple cutout
+print("and that is a fact!")
+print("An extra cutout") #!s #!s  # This will be added to the above cutout
+def primes_sieve(limit): #!s=a # A named cutout
+    limitn = limit+1
+    primes = range(2, limitn)
+    for i in primes: #!s=b A nested/named cutout.
+        factors = list(range(i, limitn, i))
+        for f in factors[1:]:
+            if f in primes:
+                primes.remove(f)  #!s=b
+    return primes #!s=a
+```
+Note it allows 
+ - naming using the #!s=<name> command 
+ - automatically join snippets with the same name (useful to cut out details)
+ - The named tags will be matched, and do not have to strictly contained in each other
+
+This example will produce three files
+`cs101_output/s_tag.py`, `cs101_output/s_tag_a.py`, and `cs101_output/s_tag_b.py` containing the output:
+```python 
+# s_tag.py
+print("Area of square of width", width, "and height", height, "is:") 
+print(width*height)  #!s  # This is an example of a simple cutout
+print("and that is a fact!")
+print("An extra cutout") #!s #!s  # This will be added to the above cutout
+def primes_sieve(limit): 
+print(width*height)  
+print("and that is a fact!")
+print("An extra cutout") #!s #!s  # This will be added to the above cutout
+def primes_sieve(limit): 
+    limitn = limit+1
+    primes = range(2, limitn)
+    for i in primes: 
+print("An extra cutout") 
+def primes_sieve(limit): 
+    limitn = limit+1
+    primes = range(2, limitn)
+    for i in primes: 
+        factors = list(range(i, limitn, i))
+        for f in factors[1:]:
+            if f in primes:
+                primes.remove(f)  
+print("An extra cutout") 
+def primes_sieve(limit): 
+    limitn = limit+1
+    primes = range(2, limitn)
+    for i in primes: 
+        factors = list(range(i, limitn, i))
+        for f in factors[1:]:
+            if f in primes:
+                primes.remove(f)  
+    return primes
+```
+and 
+```python 
+
+```
+and finally:
+```python 
+
+```
+I recommend using `\inputminted{filename}` to insert the cutouts in LaTeX. 
+
+
+## The #o!-tag
+The #!o-tag allows you to capture output from the code, which can be useful when showing students the expected 
+behavior of their scripts. Like the #!s-tag, the #!o-tags can be named. 
+
+As an example, Consider the instructor file
+```python
+if __name__ == "__main__":
+    print("Here are the first 4 square numbers") #!o=a
+    for k in range(1,5):
+        print(k*k, "is a square")
+    #!o=a
+    print("This line will not be part of a cutout.")
+    width, height = 2, 4 #!o=b
+    print("Area of square of width", width, "and height", height, "is:")
+    print(width*height)
+    print("and that is a fact!") #!o=b
+```
+This example will produce two files `cs101_output/o_tag_a.txt`, `cs101_output/o_tag_b.txt`:
+```python 
+
+```
+and 
+```python 
+
+```
+
+## The #i!-tag
+The #!i-tag allows you to create interactive python shell-snippets that can be imported using the minted `pycon` environment ('\inputminted{python}{input.shell}').
+ As an example, consider the instructor file
+```python
+for animal in ["Dog", "cat", "wolf"]: #!i=a
+    print("An example of a four legged animal is", animal) #!i=a
+#!i=b
+def myfun(a,b):
+    return a+b
+myfun(3,4) #!i=b
+# Snipper will automatically insert an 'enter' after the function definition.
+```
+This example will produce two files `cs101_output/i_tag_a.shell`, `cs101_output/i_tag_b.shell`:
 ```pycon
->>> print("hello world")
-Hello World"
+
 ```
-All these files can be directly imported into `LaTeX` using e.g. `minted`: You never need to mix `LaTeX` code and python again!
+and 
+```pycon 
+
+```
+Note that apparently there 
+ is no library for converting python code to shell sessions so I had to write it myself, which means it can properly get confused with multi-line statements (lists, etc.). On the plus-side, it will automatically insert newlines after the end of scopes. 
+ My parse is also known to be a bit confused if your code outputs `...` since it has to manually parse the interactive python session and this normally indicates a new line. 
+
+## References and citations (`\ref` and `\cite`)
+One of the most annoying parts of maintaining student code is to constantly write "see equation on slide 41 bottom" only to have the reference go stale because slide 23 got removed. Well now anymore, now you can direcly refence anything with a bibtex or aux file!
+Let's consider the following example of a simple document with a couple of references: (see `examples/latex/index.pdf`):
+
+![LaTeX sample](https://gitlab.compute.dtu.dk/tuhe/snipper/-/blob/maindocs/index.png)
 
 
-## References: 
 Bibliography references can be loaded from `references.bib`-files and in-document references from the `.aux` file. 
 For this example, we will insert references shown in the `examples/latex/index.tex`-document. To do so, we can use these tags:
 ```python
@@ -112,39 +235,20 @@ def myfun(): #!s
 ```
 We can manually compile this example by first loading the aux-files and the bibliographies as follows:
 ```python 
-# load_references.py
-    from snipper.citations import get_bibtex, get_aux 
-    bibfile = "latex/library.bib"
-    auxfile = 'latex/index.aux'
-    bibtex = get_bibtex(bibfile)
-    aux = get_aux(auxfile) 
+
 ```
 Next, we load the python file containing the reference code and fix all references based on the aux and bibliography data. 
 ```python 
-# load_references.py
-    file = "citations.py" 
-    with open(file, 'r') as f:
-        lines = f.read().splitlines()
-    lines = fix_aux(lines, aux=aux)
-    lines = fix_aux_special(lines, aux=aux, command='\\nref', bibref='herlau')
-    lines = fix_bibtex(lines, bibtex=bibtex)
-    with open('output/citations.py', 'w') as f:
-        f.write("\n".join(lines)) 
+
 ```
 The middle command is a convenience feature: It allows us to specify a special citation command `\nref{..}` which always compiles to `\cite[\ref{...}]{herlau}`. This is useful if e.g. `herlau` is the bibtex key for your lecture notes. The result is as follows:
 ```python 
-"""
-References:
-  [Ber07] Dimitri P. Bertsekas. Dynamic Programming and Optimal Control, Vol. II. Athena Scientific, 3rd edition, 2007. ISBN 1886529302.
-  [Her21] Tue Herlau. Sequential decision making. (See 02465_Notes.pdf), 2021.
-"""
 def myfun(): #!s
     """
-    To solve this exercise, look at eq. (1) in Section 1.
-    You can also look at (Ber07) and (Her21)
-    More specifically, look at (Ber07, Equation 117) and (Her21, Figure 1)
-
-    We can also write a special tag to reduce repetition: (Her21, Figure 1) and (Her21, Section 1).
+    To solve this exercise, look at \ref{eq1} in \ref{sec1}.
+    You can also look at \cite{bertsekasII} and \cite{herlau}
+    More specifically, look at \cite[Equation 117]{bertsekasII} and \cite[\ref{fig1}]{herlau}
+    We can also write a special tag to reduce repetition: \nref{fig1} and \nref{sec1}.
     """
     return 42 #!s
 ```
diff --git a/docs/README.jinja.md b/docs/README.jinja.md
index add4775..28e0cd2 100644
--- a/docs/README.jinja.md
+++ b/docs/README.jinja.md
@@ -20,82 +20,113 @@ The project is currently used in **02465** at DTU. An example of student code ca
 A set of lectures notes where all code examples/output are automatically generated from the working repository can be found a
 - https://lab.compute.dtu.dk/tuhe/books (see **Sequential decision making**)
  
-## How it works
-The basic functionality is quite simple. You start with your working script in your private repository and add special tags to the script. 
-In this case I have added the tags `#!b` (cut a block) and `#!f` (cut function scope). 
+# Usage
+All examples can be found in the `/examples` directory. The idea is all our (complete) files are found in the instructor directory and snipper keeps everything up-to-date:
+```text
+examples/cs101_instructor  # This directory contains the (hidden) instructor files. You edit these
+examples/cs101_students    # This directory contains the (processed) student files. Don't edit these
+examples/cs101_output      # This contains automatically generated contents (snippets, etc.).
+```
+The basic functionality is you insert special comment tags in your source, such as `#!b` or `#!s` and the script then process
+the sources based on the tags.  The following will show most basic usages:
+
+## The #f!-tag
+Let's start with the simplest example, blocking out a function (see `examples/cs101_instructor/f_tag.py`; actually it will work for any scope)
+You insert a comment like: `#!f <exception message>` like so:
+```python
+{{ cs101_instructor.f_tag_py }}
+```
+To compile this (and all other examples) use the script `examples/process_cs101.py`
+```python
+{{ process_cs101_py }}
+```
+The output can be found in `examples/students/f_tag.py`. It will cut out the body of the function but leave any return statement and docstrings. It will also raise an exception (and print how many lines are missing) to help students.
+```python
+{{ cs101_students.f_tag_py }}
+```
+
+## The #b!-tag
+The #!b-tag allows you more control over what is cut out. The instructor file:
 ```python
-def myfun(): #!f The error I am going to raise
-    """ The function docstring will not be removed"""
-    print("This is a function")
-    return 42
-    
-def a_long_function():
-    a = 234
-    print("a line")
-    print("a line") #!b
-    print("a line")
-    print("a line") #!b Insert three missing print statements. 
-    print("a line")
-    return a
-    
-if __name__ == "__main__":
-    myfun()
-```
-This will produce the following file:
+{{ cs101_instructor.b_tag_py }}
+```
+Is compiled into:
+```python 
+{{ cs101_students.b_tag_py }}
+```
+This allows you to cut out text across scopes, but still allows you to insert exceptions. 
+
+
+
+## The #s!-tag
+The #!s-tag is useful for making examples to include in exercises and lecture notes. The #!s (snip) tag cuts out the text between 
+tags and places it in files found in the output-directory. As an example, here is the instructor file:
 ```python
-def myfun():
-    """ The function docstring will not be removed"""
-    # TODO: 2 lines missing.
-    raise NotImplementedError("The error I am going to raise")
-    
-def a_long_function():
-    a = 234
-    print("a line")
-    # TODO: 3 lines missing.
-    raise NotImplementedError("Insert three missing print statements.")
-    print("a line")
-    return a
-    
-if __name__ == "__main__":
-    myfun()
-```
-You can also use the framework to capture code snippets, outputs and interactive python output. 
-To do this, save the following in `foo.py`
+{{ cs101_instructor.s_tag_py }}
+```
+Note it allows 
+ - naming using the #!s=<name> command 
+ - automatically join snippets with the same name (useful to cut out details)
+ - The named tags will be matched, and do not have to strictly contained in each other
+
+This example will produce three files
+`cs101_output/s_tag.py`, `cs101_output/s_tag_a.py`, and `cs101_output/s_tag_b.py` containing the output:
+```python 
+{{ cs101_output.s_tag_py }}
+```
+and 
+```python 
+{{ cs101_output.s_tag_a_py }}
+```
+and finally:
+```python 
+{{ cs101_output.s_tag_b_py }}
+```
+I recommend using `\inputminted{filename}` to insert the cutouts in LaTeX. 
+
+
+## The #o!-tag
+The #!o-tag allows you to capture output from the code, which can be useful when showing students the expected 
+behavior of their scripts. Like the #!s-tag, the #!o-tags can be named. 
+
+As an example, Consider the instructor file
 ```python
-def myfun(): #!s This snippet will be saved to foo.py in the output directory. 
-    print("Hello") #!s 
-
-print("Do not capture me") 
-for i in range(4): #!o
-    print("Output", i)
-print("Goodbuy world") #!o
-print("don't capture me")
-
-# Interactive pythong example
-print("Hello World") #!i #!i # this is a single-line cutout.
-````
-These block-tags will create a file `foo.py` (in the output directory) containing
+{{ cs101_instructor.o_tag_py }}
+```
+This example will produce two files `cs101_output/o_tag_a.txt`, `cs101_output/o_tag_b.txt`:
+```python 
+{{ cs101_output.o_tag_a_py }}
+```
+and 
+```python 
+{{ cs101_output.o_tag_b_py }}
+```
+
+## The #i!-tag
+The #!i-tag allows you to create interactive python shell-snippets that can be imported using the minted `pycon` environment ('\inputminted{python}{input.shell}').
+ As an example, consider the instructor file
 ```python
-def myfun():
-    print("Hello") 
-```
-A file `foo.txt` containing the captured output
-```txt
-Output 0
-Output 1
-Output 2
-Output 3
-Goodbuy world
-```
-and a typeset version of an interactive python session in `foo.pyi` (use `pycon` in minted; this gitlab server appears not to support `pycon`)
+{{ cs101_instructor.i_tag_py }}
+```
+This example will produce two files `cs101_output/i_tag_a.shell`, `cs101_output/i_tag_b.shell`:
 ```pycon
->>> print("hello world")
-Hello World"
+{{ cs101_output.i_tag_a_py }}
+```
+and 
+```pycon 
+{{ cs101_output.i_tag_b_py }}
 ```
-All these files can be directly imported into `LaTeX` using e.g. `minted`: You never need to mix `LaTeX` code and python again!
+Note that apparently there 
+ is no library for converting python code to shell sessions so I had to write it myself, which means it can properly get confused with multi-line statements (lists, etc.). On the plus-side, it will automatically insert newlines after the end of scopes. 
+ My parse is also known to be a bit confused if your code outputs `...` since it has to manually parse the interactive python session and this normally indicates a new line. 
+
+## References and citations (`\ref` and `\cite`)
+One of the most annoying parts of maintaining student code is to constantly write "see equation on slide 41 bottom" only to have the reference go stale because slide 23 got removed. Well now anymore, now you can direcly refence anything with a bibtex or aux file!
+Let's consider the following example of a simple document with a couple of references: (see `examples/latex/index.pdf`):
+
+![LaTeX sample]({{resources}}docs/index.png)
 
 
-## References: 
 Bibliography references can be loaded from `references.bib`-files and in-document references from the `.aux` file. 
 For this example, we will insert references shown in the `examples/latex/index.tex`-document. To do so, we can use these tags:
 ```python
diff --git a/docs/build_docs.py b/docs/build_docs.py
index 46e7a45..35d26b8 100644
--- a/docs/build_docs.py
+++ b/docs/build_docs.py
@@ -19,47 +19,47 @@ def my_nup(path):
 if __name__ == "__main__":
     from snipper.fix_s import save_s
     from snipper.snipper_main import censor_file
-
+    data = {}
     EX_BASE = "../examples"
     np = EX_BASE + "/latex"
+    import glob
+
+    dirs = ['cs101_output', 'cs101_instructor', 'cs101_students']
+    def dir_import(dir):
+        dat = {}
+        for f in glob.glob(dir+"/*.*"):
+            name = os.path.basename(f).replace(".", '_')
+            with open(f, 'r') as f:
+                s = [s for s in f.read().rstrip().splitlines() if s.strip() != '']
+                dat[name] = '\n'.join(s)
+        return dat
+
+    for d in dirs:
+        data[d] = dir_import("../examples/"+d)
+        # for f in glob.glob("../examples/"+d+"/*.*"):
+        #     name = os.path.basename(f).replace(".",'_')
+        #     with open(f, 'r') as f:
+        #         data[d][name] = f.read()
+
+    data = {**data, **dir_import('../examples')}
+    data['resources'] = 'https://gitlab.compute.dtu.dk/tuhe/snipper/-/blob/main'
 
-    # if os.path.isdir(np):
-    #     shutil.rmtree(np)
-    # os.makedirs(np)
-    # slider_cli(latexfile=f"{np}/index.tex", force=True)
-    # np_basic1 = EX_BASE + "/basic1"
-    # if os.path.isdir(np_basic1):
-    #     shutil.rmtree(np_basic1)
-    # shutil.copytree(np, np_basic1)
-    # shutil.copyfile("myoverlay.svg", np_basic1 +"/osvgs/myoverlay.svg")
-    # slider_cli(latexfile=f"{np_basic1}/index.tex")
-    #
-    #
-    # my_nup(np + "/index.pdf")
-    # my_nup(f"{np_basic1}/index.pdf")
-    #
     convert.pdf2png(np + "/index.pdf", "./index.png", scale_to=600)
-    # output = np +"/index_2up.pdf"
-    #
-    # data = {}
-    # data['resources'] = 'https://gitlab.compute.dtu.dk/tuhe/slider/-/raw/main'
-    # with open(np + "/index.tex", 'r') as f:
-    #     data['basic0_tex'] = f.read()
 
-    data = {}
     # Build the docs.
     import glob
-    with open("../example/citations.py", 'r') as f:
+    with open("../examples/citations.py", 'r') as f:
         data['citations_orig_py'] = f.read()
-    for file in glob.glob("../example/output/*.*"):
-        with open(file, 'r') as f:
-            data[os.path.basename(file).replace(".", "_")] = f.read()
+    # for file in glob.glob("../examples/output/*.*"):
+    #     with open(file, 'r') as f:
+    #         data[os.path.basename(file).replace(".", "_")] = f.read()
 
     with open("README.jinja.md", 'r') as f:
         s = jinja2.Environment(loader=jinja2.FileSystemLoader([".", "../example"])).from_string(f.read()).render(data)
-    with open("../README.md",'w') as f:
+    with open("../README.md", 'w') as f:
         f.write(s)
 
 
 
+
     pass
\ No newline at end of file
diff --git a/docs/index.png b/docs/index.png
new file mode 100644
index 0000000000000000000000000000000000000000..53392ac5e0855f43a4b1ac49f61f6b5dad857278
GIT binary patch
literal 30083
zcmeAS@N?(olHy`uVBq!ia0y~yV7$P<z!bs3#K6E1Yobukz`(#+;1OBOz`)@P!i<U?
zij52m3Jjhujv*Dd-rOyZ5V?Mc?Zf8XZ!TE}vABfH@(L6YaSRMdGCw9Iy14G;tQ8xV
zRQ5hoyQbonoU`$G!(IlhjwXc#8XoVPzT7*_boyOQy^m4(rrio+9gW|=KRIb^UHxs&
zP2<zA-`un`mg!o=!N5>rtGA1RfuWI`q2T~40|Sd50|S#dn9slw1K}$aFfs`2U;y(S
z9xyS0_%ID1K86O60q7b)e2@*u8bExwjUWZ+Hi8s@G$7ju*U-ofaT3VMAO$c3&^3Vg
zgWHKe(x*(Fx^&sHE|*0uEiJ!(Rh4ik6fo{`si~<64Gnd3JGQIzby0C~znrZX$3l%&
zzw~u=bzi8yP~v*Q^dfZ2mMv$_oXNYl=jEF>HnqP>s+PJa{rvTM{oJ{8+j%65-rh1*
zS6{v|c=@9B4DLG^^pBo7(<2}xDQTH^$D(UdRCF|_qK(}8UAw9t9%}9D>#M4&`r^gF
zqIbai=cm*9uV25OJb7|&Z}0m%J1<|k;v)a>+LbFRDk^hqtGBIN_wKCueHVAf@CN}R
zt#J+a9{1b-yKwn(aA2SyS8G~Y+O%oYS|%Ltm%qQK@^iQTK7|&a*=BE#bP88hRlU%z
zcxur0`+aaw(4rM9R;*q7H)eg+uP-b2?c3MY<)#0A@Amt3(OJIP*{`3To<4WZoKvSy
zA3k)bjZd~~3#-gSCdC#L6B8Nxx|*x2LR%)>xN)Pai)*5XN$M#PzINr%APo^VHa0B{
zjT^Ua&6+v0^XQ}b_5Uj0-rD-YSu->=)Y8)O%chkpSMJ+q_lsp0$FYL{seCdP8&XaR
zIeGZ`o%{Luxw`MHl!Sy2m;LQePK()FwRQLI-&a-!Z_l}T>C&Y`k3ZhIb4M?BSBu@0
zMT-|d{vp0ZSE1nlUG^oKnwq(}xvHwFsi~>!pA`6bdv^;IJv_w9&d%=Cv3T*~{{H@u
zjmwrTn=(a2S67#>eewGB@^W&19FmqrDFp=vWn2gBS(A6fYFJoUXli=;`sRLobaZq2
zdAs6gXO4D@v-8X8Y%fSmOw7t!b;V0mR8(AC{8?gHn3!?N?1>W-lark}9u`;}J$f`q
z|IF#r!2v&tpRZcIIz1(&qN+;BsUXarfoXgCsx@n3_EwcTI5?!GJxiZod+pY(tfZt%
zckajt2rO8%$SCKAfwQyovJGu*#~K)!mt+ZWu)Jyi`SWM(uP+OyyDAA9=V^;|FOAa>
z>ioC8UsPnqoY26)m8(}@zHs5dJ;nnQocfLG|J691*jxQQCN_5J)T!I^?yg$6aAW%U
zc^4PES65cn{{Q>^&7n>Et4=;Du<$XowY7a_#Spa9hvVYatEuzWu3vxr{5uAYJ92q<
zb`(B*_|QD>PC-$TQcKRgJv&#feEIM1@7iBq9v1CnWo3PH=<3z0hDJ-+Bzt;$y}i9(
zrt0gjpEOD6mqpc=7Z+P5oH=vm%a@X0H}}>4HroGx%9JTRvewh$^78VIJ=A4r6RBDd
zxY+IP{`&uWzu)ur@%i)hdi-*qnTr-JI`p*YXp-Ul^V6l+4NO7c?G7hy?(S8qw5o1i
zzHF?gr)OgF<>F%Z+uL%LTU^}T(^FD%Zf<JT`*2h|evVyjRCM(1n>T09JMYDD@#4jU
zb&L)VzByQzy_rybBRV7`B`eG8|C6tKwrtswm7Q&BYHBHS?$_7XoQm(>z55c}EvCDx
z^0Qj-rL!Q=`}bBmzr2;Tb@KiVxj(<%K0DiNq5OjCgh$Th+1c5jzkh#TwDa+?-pg06
z)ZCkX{rdI!7KKgoekiD#n@?Y~;@{ujr)w8R==^)wE`M!({Qa2+AKhzK7w9NlDdq6M
zshW$MJ2WI@UU^o&pI_g;efw6e(y|h0<mQNBVA1<hVB!5xG&?WPO`U;(X?yn5XHR>J
z%dTC$YHIwd`tvc~5)Xe-0fB<o*VZ08=2pULqtBzc$0)x?{{5U;KUdDWwpeUod2p^*
z8r!*pRe$#$n9#JUt!>ewMFARHBup|sJvli~SZ&9S9SH?80z2+{1v@K8o_CpgTD4_Q
zV60WnzdMZ2p1qiM{f>Bi?bf%u-_QH5`i04rWBOr14wl^9++)X%8K<9_VO42#NZhL7
zbHV)c)AIM<{q=Tx(fpw2Ma(U{pF>QGZo5e8I;~!|?9Kjlo4D3*7Qg2!<D}6w$wP&U
zi_6v3bz{FgzpPQphY5-tF$V<mrg!^$%&<*e<+ORjlAS-7+g4BefB*kN|EebwnEVwk
zT)K4W+O>77)?B%AWsYg~wJRql-@S83L{#+R{DuQ>?Q(N-?cd)n|MTPHk`|UPZvMP6
zqNSzg=G!&%_ZX(066tnqzR=#F*jm5BTvVjz_qV4-h40+`!@^?LEL+xA*C5`I!BAo6
z5e=%FKy?=bwEhM0A$8U5*98`H?%av_!pxvhusddd-QSv;nhX344F}#9ty;B8X(Gp8
zMD>Tg!u>GkM~$7@Y(@sA?bbRmI|L@5WngH$Eqmt78H1ZV@ERSt`fNDxR?b3HoIzm6
zU6$pKm>8J0&wdaR!vJy>$dv*+J|unEEeUcEXPr4S152Ly!S`t(C)wG^@z3OD;JEYd
z!uI_8O-)QtXaE2A_aj6@^URr&Okk4_9yzjP!v+D6^Y7>#fByMslHo6C1LMxT(h0XO
zTxh6cU|`9cE^Sv+5fUN-mW(}j^r)(u8XH8{@@321I1Zjn1X<0uql*{pqIF5k;3f)7
zUVn4<L}rlV6C}VkvK-z4QfVg<%HZ(8$^767CI%+)U7T*B3<5hY)EcZ}XgJWC*A&Rg
zz@k?oY;0`Y^jeESp<v-{zM}JUt*>9Z*0v6$Z@T=GS1(?Oh>I`Q2I+g+)7x8IRCIx#
zfg|Qc(YbTyCQh9Af*oXpWo~Y+lSgT(=`JRQM($WpX?A^myt_Tf%+r?EAQQ`u{!A1V
z6@Amr%gcNA?AaFu3@my2@5=SAA3dt7r1U6N%hT8Q?3ptu>n+RPNVo>RF<rH4)&9TV
zq?d^>D-=|lT3he#>gsB0Y7$?kXl7<+XgIM_LSBCT%9S^l`^*1&xGD8ChoTH$`nfrl
z?fmj??I1m09oNmC9i5T!g8TZ0jEjqIZcaDm*N@$0QvA%PYUjFj>$Yv17H4K+a^}pL
zDOR6Y8Cde(C*|kI2M2#<Qr`LV=g-8%#M|5R_ZL1sc5Q9+<HwIV6;o4FxwyDmCbYD)
zyx;fRFFM*<MWsbAKPzk2ym@_m><$mUy=uPm@$vEdyGmbI^4nj&eEE2vY;;uAss#%S
z^6u=Y`}?c&Xj0m)4RhzpDyCdr75eyi|MKe+l9ErKK3#a2QDDd3TN4zWMMOk|goNh3
z4xKk|9;l{|FgM>``1n|6cJ}sd+dfs;EOQ775|Z6*qN=L8Freceo5O=|Ws}u>xi~p9
zb93MR@t$W>dFjTD6OTVmnKDJrw#tPgFf1(1&ov_}D=0MdY0=Iz{#jSAUj6m!*NZF$
zmc0Dy+w<=?GP9TcyS{nVs#ROFugC2!JA3Tdvx|$}&tz^pBbZlQym{TacW-ZR=jG*n
zX?pYK&BJZH&f&~|Hj7+fUC-?Af4-TW|JJQrQj(Ikn>Y0J^{rpO-a%o8b$MQP_Uf)K
zuDx|nPE1_6a;2G>nU$5*?(+9xVPVgTcD4v~x;XV~Ett<((8BE!8F};YVPyq{2EOCx
zrab>x!NtYpb4$qSUgh(-+1J-yJpE+?)83kwmzFN|p1x=@qri?2>eklQp`ll+zrWjC
zz*}Qie{qp((DHgy6O$P;W<*3qEox^pSi<n%IQP~TW%s_2>sL%nOm^(rHS6o^?|V#V
z%$VV^HZV9?+B8c<QN>8>RO*+E5+jDbf<^(SD_5_|A9Gm~z5mCm|5?v3@-;R#uHR6!
z{^Vr)$i2V*HM7qsVrw|SI%&?NqW_L3)>`kG|9#ur|Dk&xehyu~;nT8Z%bMHy_8O*k
zCEnjRe@)z91uLnO+zkib?mgw@{aYfSt4qeIqg8eJmNi`hpC0?$e`H~r=kVd>EYp&W
zhu!-wWP^(0i`g|bwJ%LSi|H)5{^RHG%h_uFvyWZT7wdlg`n9%}Hou(JlSi+zveLdC
z4Uez=_jI~VW5VTUXIm!7T9<!fX)2XA6L9+W?)GtEj<C8<oR=T{-}_xo@yVC>`#-ZZ
zxq43%a5@*i<A5;7y;;`N1s=%@91!MM<}=@qgOiW%87GUdnx9Hb%l+NQg*jqkVmTH2
zlaeZ!4t@|+=1}xJdD5ma;lqW6Efdsl-n3~vQ1igS$s;jP&|kq|lB6`_3q}izGnHFw
z&d=Lh^mWyH`T9KvvZbY@+HOSE>{*rBBAkBw``WCmdE)0|t3#!a33I$)ZFE?mAy83O
zb#A`7zM5It@9+1&Kl^)BnB&NK<EJbP?mKK-X3e_Q`?_4|&|Ldj>Y166a*~3<At7H@
zX^C^NJY!~C6TA7DV@QZ^=+)NZ=g-c~+?@SAuf*D6`@u-A_0tcUnT6}K$Cek&DEfV`
zCvtPznOUXwMw9lj-SA$ep&J?+>dMdjfJ6M>vQ@ig2^4+&Q@JqUNB#SKzr9{fnZ0d(
z{vAlR%9<r5)goXwU%ujTTfM`9b91eCuUPng-(Ru4ybTB5UM(pteaR{;Jo)qUbGf&7
zetxwz`-K<-i{759Gj|I)6d&KcYkz-3;?q^3hK7dg_bimJ|HTQ>r?q<34Sw^y8xNj6
z`}VJ0-mdb~ldEQ1<dSzVaNLRWbB>M8I=k_HopATj*XB7V&Yg4n&!AB7aO%a&mnTOp
zUb3X*>8GbF*!k;zd^{dLW2b!m7r`oNhQ`~guU@@+a-GTR>+jF344%F|#<KENNLt!6
z?aYk#^K4(_GO*;W4-1UcEdSfWDQx%m$>i7Oc`^HHEKN;CWmy{zv`$~TZrQba!P3{(
z%UcvA6lG;4Bs_S0ygz=^!o%);B{2)OY?<<R!^Vvp_wAFj=3r>NUHs+c<>h;qTgaTt
zZ|AqK`!nP4Q#UuadwZ+Dr%L_$@VNgbzkbY)1N)Ajzqr`_=Jq)CmKCd3&9f@)+L^1$
zpiuDttCd|>NO17(iid}`$y%>jvv$5sWzo}9q8lUreCiDn5tWfS(~{}r)HH3H*yqo8
zC#ibBXl3OVld-7~_zkk%c}jRlNz8$y3k&Y^$;a(WYJGmBGil?GFE20m_V(&unD9N`
z&`aK0-lk&0PVJ{hyT#Mb%y85<H!(5z&-UWgt7%iGCdxA^6jXC;^^3Wdee24~)6@0i
zw^V%m^78W8vuFEdt;2$XKJDR^wXd2Y5EK(5BO>AwzwzP2!|l`c<JDTGOqufGXN{9b
zQqrUH`?bs0uC0B3PWD$Q8ynlnlP7QZGH~3P=MW#i-}vai&tI?Kva*ui|0C(nj>38K
z=GFiC=w4IvhudWO%$b>4Sy2%Y9vnMser{U0P|-C|X<|p+wQJX=oqoD5W@pi%7S1nH
z%F2u9%#nGc#=w&2f8pduM!o6P&#tVD-kvwtru5XYW5;gaw${>m_3G;CwR88iHukUA
zS4??xW8?F4bE`j}HRn|9m$Q{JOmc~imTo_s*md;yacc_;1Ab9aQBd=QX?wfI+b;?$
zckTMs`uVy2|4*l9+=#HX-7BgcrlFxBV_CFh^7gKXH*bCQZEAj8IC^yHzI|~D0v~?X
z*v&tGr+VeiospiNoyQ*=rY{T)4V9FTNH7P5DAU#bbvs}2WNWW3eZ6h3Wp$pbE9?C8
z^Q}r(wYRsgU!Px5VewmLeV?VZ_5Hoo-+#Z~FK?X2v)3&;dUjk!Ztm5K7diR(%znN;
z);DwJ%)Y)pNN7IT*(Wb=qqDov`}*PJUx$u%zx;f7&Dyp1Yro%ZYHC{S-Y+IDUjE_M
z&HR0y9Gd$2-@kk*DJ@;QYSk?Be7V0@Is}zpI7jjF_Qu!!JbL-^WIO8_e1%h=|5OLH
zzt*o`wrrW-v^}rp|GsM8UsnIV=F5rx8oT-XZd=-3*--HCP~c*>pTB<H+f%uD=~CBs
zr_ax~_2#Jj@W8RK@Z((T@|c(yHa-~-d(--Ve-0dQs7i4Ba9y^ZQ&C($E@oSf<Tt?s
z+y{JB;@ws2=LcwqCnw+b->+iVxBk!D12_Kty~3fmf4<F2o2oAc?Cm>?pIu1J$<5W(
z(aF2N@9*pN`*-c$ZEaz(p`I(*XSSKHsp-`N2OQkppV$8vDc*T{ny$CE_vVco6HRYr
zq@|@LCN|cxG$`MZTl84}jfiWLGuLw+J~a``ud}V^Zfg;cm7UA|{CxeUs?s7auHXny
z&&*d>R&tB!c=-6()chz23lrO|WnW)kb@14+wz=ERoM5xg<y2g?YL%a#-wj6wi$iZM
zd2UM{7VT77n0VCPf7xddi~IG)MKkuU3t_Cb-YsADc9wB@UWiM}v}t0S@0~bt;`VK8
zWo2ax3kxHoqB}bZ)6&vfCPZ#d@3yYx12v?p6&41ZsEdfcE+rl>S-9WCV#$T1hG)m+
zdCFvSPduD3WlNT*s9kZ3cfawBZ_@UeL0>MVp4N-sbK>d0x6(aJmo9B>b#-!T+P{DQ
zu3f)&6h6Lim4V~Vy>&a5q#W=6c=qh0OGb%~iOHqD-Fw%ryWC-CcU)aULgR9(l$1-S
z=he^8c^1gu+ZAhZ@o+?FXyf_kdhy?`&f3bo@AtpozVY?Cp~mfpH*Vj)ed|_VAD=yS
ze|Pov`g(bF_4fAO*%-^<@Zehw)4rttb+4EhuRFxw+_8RD=SHo5b=i*VOhxL|GcTP^
zGAuo6U%sf_P%&l7<bV3?lWWh-DU`Flb?sW&wKFp}eJ$P@Qw;|E{QWCdthl{B-`dK`
z%EID7iaw}_PENXX{pot=a8T76{A_Ymxw*2FM^e$$w*s<G9)X3Ew@p)0RMB0m_AAh`
z|8!?%%tH&Get|;|i>{cKod5Of+zivxr%s(Zc5Bz(HXU6M=<e=LPD=Xr{(gRTwsqPW
ziPD+T5ljcP8#jx@xxdjC-Llnl)BJ0$E>puo%)C{uG%Bxb5$J3YGW%c28<Xv=>*XY-
zFXOUYSMkUR2i4b}b2m@ET)#bUu5tOgJJw4sIypOYD!RG3U0&w<`^Dn^3Y&Wio!gn1
znWd$qHh{Vydz}Qct0JPMpV|c3>#uk857*RPeC(9dWPwXpt}I*eV}G@wic0uR-oN)f
zV_#+cxpgbd>BR2;-|N?{TlZck{#=ZNW7qK|o@X|#TJ`Ekr?CB>56*n;oAdAQ%isUE
z?Dw~~J9qB9A<G~U^x~w5sOZd8Rn@qxsNStp#T1_e=CnR8*!zoZV%H|8?9=nzcL;H+
zig{0&Qn7XG+F7%hoH{n_^!4}etot^7Z?&zO-<`jQ`CngO``YL7s#U8dtNG3{$rMsl
zF*pBysFi!$wrzTPdRcGpr|~if?D(H_toHXN`E6S|e!tM{beYs~;?l?D-*zY06>qql
zEBwFmLR6HRiD8(wuIRO^|0Q=ERXt?5nD=G+&zgUc^78}r^vbqvi;Ig3;@#OJclTi0
zjF~g{{{Q!T;>3yj|9s-Et&FjozrWz2(=VAgP%>i)nr>IH;d*XPmbcHkTYs*8_|wF;
zT<}+mK&-6m!hkhv&KMhoNWNWiUnOU=#1hZx;+;o!S^c+mGcz*!^z(7Q<>zO2xw)ki
z^87e5v$8I|yxe{+V4lN*RjaCA{;Bl$_rIwd7#y6;SMf4APF`MqqDRXUR)+`Q1X_*4
zH_ICTI=?f$w)dY+arQT#&(Y;vX+EaO_TC&PtAf&#*XmZQ{QlX-Tm0<YUU9Kyi@;#z
z%E-V#M~=Y2z?*wAC*RpJwffBOpU>xetG@s6@UY=ChK2)ww<pEVUHvzaed-$ZrbUm`
z)S5UI*RFlk@?_Ob<6ozz{ZF~NYR8Ws-|hc=_;PY`i-5TJ^z7^F1f4XxW?7fN`<$mZ
zc@HlyuS79}!-Id_GbN<Um))>1SDyGHf4ao;0*j){)4sjd-``VO{y+79-RFOQ7t7l`
zDB3C1new24@vo0>d`0kW>0*Z;ObP}6Wv%LijqK*%KIp9J<>i%LTPxefpD)~L5u;~2
z_xs$X-tiBo8N2V>^ssv(I|IwR*DDrm*r2^??YebwAK&fH&CNZlt1H9j?&`X9<Ho{s
z@#5!epWb+QTCURJ$F{9oRn^q^q|MfNM{DZnJSniK{a<&CTcN=5+m5OCT`l7#%s>D5
zBZs1h>((t>ZbU@S{#UwulipFe$_Y~6Qun`(Gh!+H@!_Fsw^(VZ_OWBf?EnAy%r0MZ
zz;3Oyzz&7A-A)(EUR;>6WQnYGdEWh<!5Sh$U7I#<efzIm-So}r1b)Xa5B{7zaUviz
z^y-x>Z`!s!J2SKR$A^cZtHU1Vb2W0mon-Z;dg||J$A_!+_s_8`es*a4eLr9C?mhMY
zzgAv<qsVddkLq1JftY}R3G?RJ6+Jo8)zx+EnA`2}Fa4K~c8lBpdZGO7_LZwwr+TPd
zy?S--|LaS4?TXS7d;Rj|#re~|?GuuemR46+f6UL-$Sr$PU*pB4U+sL7LgLc9bANwZ
z`~Po#UfjIM{dMaT)jgi(hxfRqq@)Qs^~qUpD>%rs(mObAZ`IaayLS1{w<{|vTOGb0
z<be14|NlD^cwJcC@5H|cmdVF>oSmJYC6<+$6<0{h$k=3DSa5Z9xc_{+zb`H>R`;7T
zVeiF>YaTs%G-b+^;N^aEZ7PjaRiD1NxENGuRJV$Xir&6;OGM<u^nX<g9!&l8@$20E
z1rNQ$itb&SbozPy-}(OoM7Gu*=hK`2|K_i+BCdb;l<QAF|G(m@R@WjvS-Ue&KZo!6
zt>+rJ+;9G~Pe1eZ<9q_I?EL(EXU)Gimc<%fpFV$o{^{rB<-UtGUR_%o9b;F&XSup-
zVB*7vF?RJ|W*EMdlq`RDC-Ii9w)W&(lP+DlbbbH%`F6Fta&K>2TmSuT`F&aYIvW)g
z6>IC=TepUO3r&3Zu+7R!{^g7FMsKq7b1z@Ha-{Ctv$L~BTz~%jxpMXD?c27=SrjbT
zxpU^C6{}Wh>Fck*yxbo&-!MCWA160=^8QuJmM!yYi_l4%9=R!nbMu@jQ(OY4ba!_L
zXslVcF6~}ld;9UV(c77rn8MaZsS0&2*=A#FyLZWwl#7d8MO@$B-v0hjE4PU2(q+r6
zEG_Tusl0ste1Bcnw$#(p+S=IuB<@qQcpK}^71#6r=H~EqabN#F?w`I=<<i}|swP`z
zZ~t>~v3qH0sj!+)!g?Mqu2;9WzrV21`G4<WBUV<{ojZ5>&$rXn(h}-E8q|LHvbx`#
zsdEgYUFQmH@`!l-_whT{&(DqZ#k-H%$i4r3-oC%Te}CcQHV>6YA1l7-cB}c#sd#;D
z?Wt2<8zW+ZgOf8ePwvq&GYk91f9lX7Cuis8${jg3H$6VyznTB`{i@e%4;*m#R&elG
zuQb2BoloGEHIbXo&9PLrZYlckz)@CqZsq4^XXjdfKhVfrRaI44SsA@8$Fk~6Mrvwm
zR@SQ3tF>c`K0iAvZJu{z=~Kfc4C@6qM#u;VY^eO4_U!%5d-v+Tytp`7&G*)p%*zuL
zo&S}7fAH}0&u3r|^m^vPhw3vUtM1tA7q0XU44Td$XIJy%++6FwfBxL7`Rwa-;(9zN
z)%|e~4c)qB%a)BBKVDfGoSK^Y`r6vd*RQAV?>aoOm__+&>6b{QFDD#IN=$0M^E!3x
z-~WG0=4B4W#Kgp?s3=EA$At?Q#@Buoox82Eu`w(x?C<aI|BDS&lppW?eovSSl<L2D
z<Yi=N%s+pBYxeZ!=EFxig>QcB-7F%o<3m+vPmhdgmdNK1zrMacQ|Y~J+crT#!83xF
z_sbfa<Xk)dru)3z?@5!Mbl-mG;j(*~U#fWY#w1rKr$hDsf8RfG;zTn$zh3OFkkHVn
z0!827-F<p`dUbWRySw}8uzNFuv){gb%gx2*<Ky${_3O`{KD~MKrl+^p+1YvS+_^8A
z%HQ9M-JI6Da^=dYQ?DNDm9DL=<y4G}j9j{Osm}wwxII4(HnTG_GL}SKUVm#(WpQn-
zZE)MNMT-u(*d*|XC+{e7>5;y^R9aF*WJ}>=w}~DiA|hL=zvp!=GRwOY5ghCs7?PU0
zw7>uShQ!0?=32Y+XFq%TwD$8^bKBzdpFc7<MebMretTuh7QcN@{(isj@9$qf)2+L!
ztM1>==X_je=Go3(q%qOs%iZ$(b8V}q#ofGiO-w@K1kcv|`}^iDT2cD?nyR{bu!!nJ
z4>g||3ellSNsne4r+*0l`RjnJeAV1ZlZ3pzPq(zNbh<ox^-61^2M1`t@QeR*D=RB8
zF|pufJ~OS$*KOKlq<G}S2@QSy_3mXyn^?JDX`K9MoW5r58mnMCZSB*C4=?t37L|AY
z=!p{^{{HV@US3`_e{cQ&f4B4Z%gV^qyuPNJpZ~t{^RtVuCr_F*<Mu6Y6(L{Wv)tl(
z6_u5|ayByrgaidYK5Um?wq%J1ukhU+g~<;Owf;Dh?7{fYu&u4_=g*(Ne*I!<T(EFq
z;+Gc}zsRcxE9mI-{JgE!qM@Nta<}r}f4yclUMZ7|3#YGt{&qY6`I9FnYP)PVD4Pl#
z)RC5usQGY^{Z0B)z8_PjPF)+b^HaR}k9(URa(v%<<mIiupFTWv78e({ihjA!IW_g^
zwryt56iy#Ks%mF9uP!1yeEI6tw}Y#H+0QontNixVzggc;NlHpyydTKW$o<K4*6jSI
ze-jd5YXN5Si#&UFPclU@@$T;LS2u0ne*WCKzMdWv1A_(Xn!S?7Z8Ik=S-N!UlqoL!
zrUFhvLPE#-WN!ys*L=1Y+0mfLTEY8|F(gPy#);#h#)q9=Ua?nB9cX0Uo_E(PBHU`e
zS?;Zc&h0PWuVv?x5$JR|v(rUUQ8D}ax})nD4+y@?Ub1s%WT0#6#Yw8q^<y4zvPj*!
zwLSlS-Nc71tgKEQv$mE_&s*!DkZ?cTDLOjZ-+%p<EmH&zJuRBK<?Q+M@2{_yuXPgv
z4bR5}2L~r4Jh->Fnp3f|vhqvi#7$GCOquc1#zyY_<9@qOA3jt})R%oF)gn;4zVq%M
zv+4TrdS8vr6;+g#58u8mJ)e<*CC|L_!-K}fi<2uVEEJF2zrVlv@`<(otaf|&`kwv#
zzBt9&|L(Cafut*`*IDzwFFx?JPu@N*YiWBsd)+fOhX-ZzKR!PG`{z&J`F3*!gruZS
z*`<2zTC&@EuYw5IZR`EdXO_go{+u<d$*%UoXHX|f!^URLypzFkaeAh;^Kx%pS^4Fw
z?;0K5_=-Eh=MNwL@pk*g=M1*|=Yn2{WM{u#vu4fd>H3$2t8W>fIoK$0=wX4H|GYnk
za#!-mWc+)n{-T&c=HWLtr-c_TU%q_k(4s|)lHT3fDVw^qt83XZwf4gwCrI+Vwc(q7
zI(4o+18C$+MNJJf==}8QQ!g*CclEuOwjEFXlHtT*8!yJd;LLUY_|>bSfq{XZo-e!g
z_f@1l<a~TwTtwu-5zqw3z6BGN-ODyDS-d#eHC43=G}9BC*RnX7f8P~uhCMuYF7q%f
znEk-r7_ztndFqG-+ftAP+YfIQSrFUW+G=WQdgicWGn--g=eJoWPo8vc<Cz$%FTyq7
zrgG8Z#h16|$G=fHAgK36#>>m=-o1OXX3dI<iYhEDtgEa0_wS#6aH6ww^Zxz++jym|
z^rp?7ySM6V*3GXXu507=R(*JIaC_d}L-!b2^uB29+O^Bd%1TX5ZPlt(-D0|%Hf@?^
zmMgWp!9%4gO;xC~B{D2Hc(zStQE6%Eas890Pa7K>pFVePT2y>^czR08k*7t|^<sY+
z&1P&k(0YBMi&AG#&z)_#(uzwKElRq(tF&c8Q&ZFB<^Jz)ZdO-Od2(fC@at=9SFc+)
z&m=R*+xzs@)#3L4emtJ6?tksdl_krT&9f@iQczG(Qd+c^`QGOA^QUUF4mPpc+1UkY
zKYsLR)22;LO-(kow($?sKqHe|4?HYr<CD$G%JSlnv@Tl{p`+H)($W$U1p-Ao?|{}d
z=!j)!XJ2++_wL<0rHL6YFD;FVin1<yBVkkVp@EV4-QC^l+lx$1xBmS6+<R?Lf4{!2
zu4wnsy1Kd`e@hFC8M9~m&oViA?ASBWJT`~z2m8}L^c=W);X=jxz29$WyZ6aR%F5<u
zWLP8~Vo6I44i?^<kdSa-&6cfOLqkHgY}oLkru*sBrzKqR`|E5K6%U>}w{GvG*j<tg
z7Kd8%rp}lV5fM@G_Liw!zdJ`~SJ$air&g_BKixxxU(RMn_4jvQUtixDvu@U`TZh~E
zySus$ffI62P*7KQH>aYsd7e$#n}`|^u!&79F8;jKd%BUaadL9<Q$Ed>mX;qseq2c2
zv}@O{+uQS(uU_Qp3TjrRrKhK-q`0`d@Bfg-@F&^bV8>%-oArCEzpsnh+I9HhoBR9g
zkM&3{Tej>=q3Zne&p-csGYQ;n(9qQU`rs_XfeB0{3m+bCcXxOH{PT}p?Jo&wX<?_3
zkdRx_6JP9_QSEES3|jQUuwJ(3A!OYWXps<NRnbLO#2hMQf)m1rO?Wai-kutFTYL4x
zN%;&Mcj}Kdv-5*Sq?q)1cz9~w@BQxM>wCOcdVAX0S^f6^DlRSYT()f4!-o$`8aE~%
z_nU9G_p|7-B}+;!R!>>=v(g-t5%sfwe|sBW^RadH>TJ+l+@3q9PrqKhexH_x1}Ogh
z?f-76|Nn2nf(7OGD%FjRC+iucotY81*sXNawq?tfZOy)3cJ%g?wLf>7@i6?;w0+gb
zKfnH;rQ(z6@pYA|Tc=K)s;RAA|Lf)Q-{0OQGwuDXZ(sc_$J^UGe2?$VS@W|GGcYv%
zzGYeU<wXmp@SM4G@7I2hb@E6_0cl^kY}vE-@9RH4IvTsX%y*7OU})&qdwZ*+x97>4
zWL)sK|C^GKaNucC{+%6$$;W#1_x}lUbWA)u%hb=$k6T=C%Bnr<*7e2y`}Fj5iSY4$
z`R$uFd3kzP{{Q=Z?%cUAFE+>SE}J=X=G5uaqobm-GBP}_p1Eh>bmH;x{(c$Dq}0^V
zfPjSD+`TnFKi%G*pMQ7P*7*H(+F@%>oI7V%{_f7Lt=W6`?Ag%GxJ&x#;}t7c*8cr^
zUH{vy<^J=9oN{t=r|ZS8TC=9+|G(OAn_pjBD{WPxv3F0xL8jv3&rMBDGmX>d+138~
z@bIvF-4DgTSK4@`HM(XQr}ypNU0uz4a+<%lcW_7u4>$K>4J|XXYZoqn2KKjX2?-AV
zd}U>@i0j`UkNelHTUV5wW~O6p9qsC>s-@MnXvMZ|X2HRi<LiF5E?RMQb-1*&w0+f=
zjzud%SBLG~xigUA!rOvrO)|;HdMpbc9eH(i_0s)(8X6m>^YZfc_V%ui*}19WW0JJ=
zY-RVpFYoW)zkU1n+U@tM(u6lXt*xyEg;92P{{4NiadB~hfr8@V<v%|?y>%-}TwL7g
z#4OY78S~%Yy1l{v-;c#BSDw6fZJNNL#~;_MUE42f?Ixa)n_F5^qSEr>)vIO8mL=&k
zm)Nu9?Y>w0{Vr%;Gr%D@cygqiVUmlF&zVb0y}7x#?%ciW?d3IN`J~B{Q{%Ox<8;J?
zoz|>bvu5qub{@%3UtR{Qt1rKHEzGH7)~s1~cqgpgxpCvf!w)}H*!)uLKc1bDv0!>=
zXy`_NMu8pcHH(XjZEg4ZiQU_n?C$J*c$#kXyE{9L)6UG8G)X8mHPuSbf4<$_nV&8%
z_kaGeA~iMj7#J8D8oIi=3ak5xaIhpMCVp96Q(Nn*6v%GsKhvmHVA8~ij{IV&X=#s2
z3>&Vqzn`7I@1<dW+WUKZr|ZR5{rHgR?d|R5)z#VQIp40<>i?$&3l`k3`>kte7^owb
zo|g9Q<>liiPIOd$ySKO6y<bjOPtVNA2(;9!zu&*Ia%X^sjBy%|qKcLlsE}7zSGTj9
zclv2nb#-=j_I&H|b*oloy|}Q@xt(unmiM+jot>S%y=ULu-TnE~r$dJiXJ=(C^O?D5
z`SSGaZ143oe|~J7HEY)1y?duk6Wg8kt<86?)z<p||9*datF5DBQ~0Q5>eQ>>-riPL
zQu3Q)5f~M<YSAJmetB_macvEa3(BGl7ji9TEcxOUAae9!L5tJEMT?ZC|K9(eS7~C$
z`RC>PY!pEaF;7p=ReRo?`j)kfv(+gzHT8`+XgQ=qev2V=ttK(mxvV@x6)&IrIWM1g
z#|7VUYiMYAczGqQ_w@EYeePV|`kJaLt6Is!&#(RzzjpQN-M!V}=Z?=Sh`U-J8<J~o
zA}Anm;q3egU%=qp6dzyTv!_nIdi8eYs#RUx-LJQ8|Nne$sAkts{nzVvFSc9%&F;p9
zZl>_q*xK9MavdEVzZ{-3XO5_L*oO6j=N3E;3Jm;sVxn@<YAtQ;#qasm!rAqw=>B}Y
ze*dZ3Rm-*=%Uu)gndy0L@|w{3Yr6b9mfxu7TJ!&v^s9bZdoeM&vd7POy8@=`#m_P-
zJ=N68z07B>()K9z^yP;Z9oq3@2d}hwNJ!WP{hPb<^Bofpo;@)8{oeocaxQ=6{aW|0
z?zQ=v<<U7gS$k@qm!*WHyto^1Q*BlDs&;EWeJ#B#;q7nlZZH3AK0DfVZPE5U8&-Un
zb$@H{a(`Ltx}G{^AMF-_XQy7=bqfsq_~2mkTun`}ZvS~UH?Q9Qd|H41mFw3pi_d%C
zwq@yhhx->UJb3?pf8t>_rxObto8xw<-~OH8oX;8K>wEU;>FM+B>*v))L`UD=o*y3@
zdw2gnv%f$0uH3h8p4~PhQ`6k_TD7%*GcPX_bW#!Oe6x9ze$M-@?5?h^U%!66&0V{0
z-MYrcg9jR!Wo2dG-`#!OM)m58jmgL7%$alN&Yg9!yWKc8ZrQ@a!C_JS?943F>?dKX
zA#Jqk>S|S0)nC(WtgNiG!`GRZnEd(qeE#<Q`+B#x%$jxU$;rv9SFfIF?^j#<_u^uA
zaWSz|W($`tUAlO2a!SgP#~*)vdz+n-awJAIDC;yc6VsfzbEoS>I{p8xa<yyE`fc^E
z-FD7BA9w#G_g%xIH>~?&cjh?1tu;&W_FDULN7PE6^{ZDG7Z)ezoxeCUyfkg{6E7bh
z(Dd4!y%RKx=lnj?_x3?Euk7o<<Q<?El$Td%XsDEw6jNhEWPC)#jA_%tLPAo~)58M-
z1cZf!Wo6&Kcrjz{Tv=h^$B!RxuKu1^W~->E$jHbzZ{9pMHa0;)LGAE$Q?fe#I+Z>3
zpKr&@#Z?3byXyb%n>#l)FE5Y1zUbq}kCBm)KY#u#sam#dnO)6~favIGclYIs7B#JV
z_3!WR&(F>--ru-w+crK)qZWZj&!3x@zPj>lm9LkVmagvA3l|przbRp!C!?5hex9xO
zG@Xmru1&jba{I={<n%K$46DApNIgAm>-8gVZ*S*R<mBY6{rxRB|8)AfIV;z%zklh{
zrTz8))8AQ_ncup7`~IHF;BB8jfBLj8X6K_<ucD%(vokYKPSMxbw=aEl<<{2h`u~5+
zSH_-PH*F`6P4Letn!!oQ$!E`=oo`pGRjO`PCGPI-etx!j|2}S+&ulNf&uxAkxwA-h
zcSBzv-(DGM>EBOI3h$H_6BnO8dGh3W^X5&P=2kv^?b_V3GPBKw2M-?nGJ99i)2{aR
z<CE3>eSCauY;A8omh<UmX5+D_{`RIrP??E|X<P1XHR%OMj~;#d_0QSa=DIpMw{8ob
zNxP80aL0}x&(6-4t>3UPT;|~=G2N(=XJ=+knIa-BEuFTstE+3<Hqgk-{Q2`&uU@@#
z=g!HKg%w>wL$6-E7^ouD>7umqh+y~8&d$#3>tZ)=-aI+C6%=Lg_AxuZ+#J*FX^R&t
z&vh^QSYcCL{d@bps?!%POprTxV`K912M3$kc_a$n-?Lq&Wol~rOku^^wY_l_zrJYx
z?wb~Ll~2|xBtCxso;`CkC(oWOEh)LP;NhW5mx6ZsdiSoV`TO<ys#U9ge}A99o|7L8
zmK8tAv#b>;d2wN(taX`9@$rqjC)z1Ze)}hOcbRU~mJ|2x-8*xpC${d-kB=<^?Ck6}
zV>Lr{i+8w(?<;=pS7q+%;&SEsb#K`xR#sNKcJID?f9}ovfNgRsna&v1zR@o~EF&ZH
z>+9?E)YPLT*B>5kzbSoq&&pS?UNthaS5;Pm)+lBtY~NA)yG&nSKRo>UrcFjS_pM#C
z#>C7lZ~gPrr%zkIFkHFs?!MaJ#`d6+wfxG8z%S1y9scELW@BTctDF1b!NH`BJC-eL
zTeM=%92qAL+Xn}p7Co)gpKV+H&HDYG;%8?hZ}J=dZVj3$Eg>P`G;8*3%c6S0X~)l=
z?cHfTbM4x<6BM0aEcV-_Rb2de*DkAH`i`!ytpby#PCaT@H~sXrYi4F<+g7gZtlN=y
z*XkFCwuQxxy~`x8uaBQ^ka%c%d|hTn#*Lrzrr#~9DoHvw$8v7v&JgocZ)+xc9C=z)
zX)|x-%9SBMzm+WwF<faod-CMVH*R=vtX#QrBA3goNt1+Xe_O0H*Z3}cNbi77`5(!}
z7w=xZaYJLP;hF5x($c5b4s5w}=Z;Uk*^@ehDO0D;{I2)iw(L&wo9!QB<a1t}Y@9t|
zLcyaWosS+py13Z=^{ZFMjvlqG{Pg7E;r5mZ%a*B`nr>aPWXY^qvz|SBHfz?bKY#w5
zIB}w<rw247*VDt!FSlWJ7r4)3Rq((eH+Svy>EeG)=O})4Dtj8fKF-(EQ&UebZg<(+
zoyE^DUAk0MRHUS=oVwjiQ&ZF0+FC>7#jUN``}XadZI-Lll5=Or#~T}yKY~GEU|>n;
zy?gg2PMla-S-EcAx-Z$uNl7IoB{L4otX#P3&!3uK%O>~r^(7`Io;-Q--@kuCohr7r
ze{XC|294(D?%KKY=cT3IGiT1+xN&2PKz8<PY4g04)YOa4GdKB)h>5kewV9ci+}U4m
zZ)Ub_)he%d(|-T{{r<+r<il;ev(59D{TEEyuGD(BH#IeN|NnoxbDr0KyP4k3C)?HC
z?d|22G@YM^CnrDL>+Rg0o}O2)vX*^%dwYBQt`bc(wX`cM0)3_%UAlDX&)>iH|9&K|
zj6E!pkgu|vVROxc1C4xk$uD2N{Q2{zPkHX09TWE&zUhw)0fVS0so&Gx%DU&*e!F?J
zTRb>8*x1-uT1x8NJX`Irtvx^URCbHA@yp#g*f-(V7W>c5yyyRUE;JY5Y87$yR1xZ0
zbR?-TI{LP8ywXGuDJiLW+l#)Po;`cEw3L*K(!`KTr-|WT<I~d8!b5KJ`u_O!tL#GW
z+tPh5N(;NUUVl6HruCasszRQ@!ISTZd#z13*ZnShNKYYphq2X-8Q)HAj?T%;`}d%k
z|H(9)k{1&KG?t|NzsEW8?zukeZO!~<Ho^HbGu`U*7wzZ081Fs*rx0Je^L)?GF;h3k
zuUoMKG{azhqw38M!@$`q_I^HK^?!bZQkwa%Poibf!e4p6ZnAIPynEx`bI%Jb&V(oI
zynAov-oxwW9DcZ^e7o<;uWyz;t#i7;n!;V~#x8w1uClEA>({R_dei@fssFxxY^nG3
zl=>A@WP>Wwj+cEn*p~j@=#I;#->q$Jw{G4%S=av7R?em(At~w7L4C^)r><VVzB)T&
z!}F;p*D<oZ%f695L!R@;i$mQn0-d?^EyIH}MATGOMMXtR)1Lg!|IheG`-JQRMwWNo
zl{0rvLLP6aN=y9q$Ah6EPJGAPvr|>(&i)sHG=y?0PXGItGwJ7oSQ#c<Ev`$SGFRKO
z_}Q6NtF+SIEnBuMjlEbEJ_1tq?vA94OiVz4fRIp7WTa)qhXi(Z_A@f<3^EV@^}mVn
z)YaAfcIT|1vfG4j&%LZ*;~1Uugk^+;k}^Ty<kO;w+ZY-S<cb?_4awT|#Q3?Fkz1e4
z%z5+HEm&ZXc!;IO3)Fu#-&Cy1srcsQq|D4r*)vmny1Kl4eV5Mf?dzL{JW#=@7<5@R
z^|`y3?=lvK30FU#KfF|9)y|zicdC65aQgP{?(VFsT72!B>;M0gG*0{TmT9F--<Ojn
zo3a@gQoj5-S$W<%c9L1mj}I?iWZ2EWzuaHmr-KRPm1IG^?+#M3%nW<~a(ut)yp8Dq
z_rpcp58~T*?$R#VYXAQ0=}A+ks(#-m1X@uX8WQs4`SbE$UtT^w-hbNe_N7aoVxHc9
z{P=NmbxC>jty6oiukY{Yw_<PP{%^4I_7|^-dn==kKYhAt&6+dk&bft`_kVl$H9I#~
zw|ag23!a{bhqO1BybNk|xN!3Jmu=zuR;<u4HJuuJ=HS7`op)>9+}gHoHQlvKx};!z
zytMS})#2+mz5mM15%VJNi!9I5yvwtvPj|oH+%VJQ?XzcY=ci4Jj*E|ve-+37>eZ_+
zPC-GF)~?N6zHUCJ{@Uj1zq4k|^1Az4Twuos{ssA$Pw#U|+h6zh*VotX`uo3Li$1Rt
z9}u8Wy5F_Dyu4~%S!!x(X6DPq?)@btC3EJ^y?W)!g@>`ro2&ntnVIc7z}v#m$i05j
z{{8>|{rz29TFT0FaAWfEI8cB6?``Rc66Sd^xw&trYKM!6iWWMrU8h#MKHlEmzDn=+
zhlhtZZ`!ov-B<3pEuH)qe1(LB-n@Bpf&af!JHPz5Z{Mcb&iMQFdi-?#_`c>l;tiWc
z7R*-2{a<=(_x1HFS884obKk-6q3i1P>&Es`+qScT#(mby@@O)EcdvnXq>KVVHphWR
zg&05`EaaVMAU?=A(AG7O0@yGT%y^gv5FgZ6V_@3ezH;Tt%$yt-dj^N=fiDc-s~8x3
z`1A8~`uTZVH*YR3DiY#qWo2bmcI%1QUADHZ&Fy%gb^X6T6P4ZP*;ao$(8xS*-n<_X
zpxqhDadC0iu3dBQmy@+Fd$TR~HizQZuV0(lc)9rb_t*X|W7oH-{FIWIn3#}|P+Yuu
z+B7jcVTOhSwRx{zy%G}>D}Q$<Gb<}7Ffem{gr{fcwrysLDc|4S{o%mC!1Uc!L|j~5
zUH$xg`}v-?Pn-Y^)<j1}E?u%@&;NhF&z(EBJ?}0TAK$str=vHgo$V6Ue)a0r60Vp%
z6@}N=#R{wYg@lIgEq{OS+S=%LetErU|AK-K*Vab={`z`*($TIrZ{8F?Kesk^_qEff
zy9FjqnzSkVx}LG|=1-rByuDBR+y4zI^Ulf1sr&U(otc?gZ+i9PW4))R>px!1d4W05
z_Qd7o{+x<(a&pz*-u!&AxZlLYWZ&<1)*B;y>}OA#wrs@;2{AFZz>u7rH47IeCMPSq
z2F|bl_w&L+XKRfOXyZb=_9m?kUvFk+R`=zFpljgju(d_S#fvpoVHp6DzO_01e7k&|
zNB(or7!t#a&Z-BIT*~f!f4*Gy|Nj2|{*srM{{Q>F|K`n`U#jBc?@yaH?bfYZx3}j{
zpFTZ2B;?4^qZ{LI#4)n6vN}6ECnrDF4qvAew`WIl(%Q9a`}+D?1Y%?FUbzzDbmHmh
z>Dk%Yu`w|mirLrJaPsp{za8N1eR`s@`>*fs-@kqP_gZxRLkrL>z<(oQHJ=;X^Wz;H
z82;+QMs8jRwk`LcFC`(d;dD7@yl1oV(U8#4rP~&6-8xlZ(XwUN3Y}-onw7uj<FTXN
z;)f3(zI*rX=FOXVd3is+WO<QT^{H})m6a7}SwD-DM@`M2FE1}w+Qdahf|?&2Hx~N%
z_yh(D?*3!UZ4+*I>qw_CE0beHgha7`u25%6_Kz=@{iUU(w&mO`dVX%MVe+vlQ>Hvv
z%z5GShkZYv&7Swsuc@i2?)Tg6M~)oXwr$&;JD~jm($dn)mo5bjGx+=KD=8&?e00>z
z%xri0`*WvHbMy1BU%7IoQR=C^)!+N%Y@=dgVgdsnzJ043ec=50^T&@b-?Jx1L!?jA
zxJ@7_Cr2k*$He5zkxt>IOP6YCX^FVX+STmXu_MCKG4WWB<hE_wN**5XmtVbd<;~l-
zPhVTGbg8I-z=X+@h2`bXKP}q3cdw-kpWR#rTb}ksE9U*>%g)M@l9KZA@tI+I_Uu_N
zFE80WPiC^tTOGmPI&-RsYoUeA!hjVkR-Aa6^h+L`%j1~%mN77376vbvuuZivFqCx5
zmD=6`t$m2txM=CprK?tT2`pN&BqcTV>dEWdwrtVR(z<l|;K75sy1K#3{oXF9sjIWQ
z+vT9JVat{$A1l^>=rx$Ct);~$V=>|U^V7B8cHUbMvvTFi8oT-n3mo-7-0JD!Ss38K
zVQ6G@>H78eujZaMNzcq&xn|9u{695jCMHLY9^JWX*QW4oTemJ<y7cPRs~5vp)>pQ+
zwoaWowXCe{&D5lg7G`E)I%53NW<DAs`_7yVdU}n2??;aE0}YJ7e*Kb?l3E?M*2u&p
zBp~3&lga)sUO(LSoxR}CkB=Wde3)&XAGg1*7PPcdTyKt5>8hPOE1jL4kLPA)WbFBV
zuez<Rt*fic{{NrPd#k^Lr-uLi`&V>&^ZZjMPP}*!S@yKXuKw+<t&x$DLB8dmcu(be
zzk2`S$;rw3*KTjzxY5zkv8}C5TrcLw-|zS1>%N0_^36OeDIxLa$K(Eu8#mtlw(wQO
z>UrIhCS7`YdHK!kO`A8@|9)$pot-T#JlS`)*~wbb&j(*TnWmws>G`&A&YU@ScbCte
zIrHZ2+xl^PA{-w|wnx6LZM(f%zUu3Qre({PArG~@)KF>hP!U==>3E-PaZyoGaq;f5
zx3iWmO?7ZMFw;2w+L}n?f(HlAZCSK<adJX}LBfHCt=ZTAeK^d&cJ10<zkXd_<~uoh
zUgfHN`|K1H7VJ%5swHnx@ZiKmW&OB4Ka%n%+?{r1^B3pf;NWjw-<Cd3$(}rE+BCE5
zYdXx#&HZ-2Uc9=xT7Umzw_d5Mg~i5cXBNCKz4CFt;rg)S(O+X!ggWQVllvT?A_N*C
zm#_KI*wo~-zwYmnydN&vIXNjs+a^a(nltCkvuDThQbE=E_4U`UUk?upt9#sQzT}<#
zCCBc$E9I-+Phk3eK-bRBPFq{s-oF0qEYp=MSMtl-UAcDc+Qo}2SFGRwkE6`8EKZAx
zy0xeBGlybmXsDQ&Sc`zY{r*08p<BsGNt32b35kxD77+MwOgev#RcY4STU*1|#eDqm
zq2kk%&dyHG{^Q&n95?n>mq$cI`1tsgl#~<}8g5qYm$zRwKlOj%v}x0>UAy+|*)zS!
zO;3*AOK@>vxf>Q5I<>LU(Z%J+sj1pGTif|$y*N&uIdf-o`uW}O_eDoWMnXo1Vq(rr
zdH>+X%y%YE9RV79Dn2Ip`kuX=zyIyy$D1=QE^=<?>vT~vH{br{%NJGeX-}R#b8~Z>
zHhsFamDRB$N49L;x^veqHg@*vs;YbY>;E6-x8GCtHYzvw?Wd=wySuuaoSk>ZynAwT
z^38HHFAt9&51RQGEn4*H)2D0eVt1#Xm+M+|=FFKZSFfHvefsLvt83S;6%`SAcYl9;
zV4z{umyGD>+sy2I7gDE8otmAMbu0VtWPiKN%uLIY7Xj7Ls=v#Mii&2mx%EgmawOhc
z(B0j=cJ10b+vm@m`7@?w7i=xS%QtV%>{)F8@5kZ8hnp*J+_`h-(xsvg4-QV7CdSUr
zo}2qN@o?MQo15LEqj#@brKO^>WX&2M6`_-PdqQ3(CMK>9Tbs1%>&K6h_H{PJ6Q8<v
zi(Rz!`5v*q?(dD+y9ypU?K;}k)pfuAf9$q)T^*ezuiEd`wRm$p{8;hr+qe9^U#Bfx
zxN!ge|9!I7Z2WRI2?rXgzrWkLdv~|XqNU!`vobTcZry5_ygoNKw`Ia||M_;Gxx=dk
z*DqLLQ1&KbV}woJp9-gr=4R*8(ys>^nfLD5vuM$x7t1*m*R5Ok?AbFvKfgD+iSts!
zZ``@FX6@R&nU|OS`}=$U4e69yUOqm1%HB%ZzB{Jp!?AMRIzA4L8~f|`&zw0EHn1eW
zyQbRt-Wi9il9DZrjg9Npt(!J2EG1>h!i9;kv2$n6oC#SgT~}wPnDYGGTy8O)73<eu
zzkJ!)*m(1X4H8Bv9;vBICr=KJi;MI1?d|L1tMy*8HhTNH`S$nEp7nKhZoWIGsmaOP
z`}Bi@&Hq2o|Ig9tR9yU7(Yfu+Jlo%oj&^^3et!GLjXMh;v)%Q|&0V{5XJu@xZ16GA
zB86+5ieK2aZx4ODS9X_T757YYi-ZFW-%e?3Xl&@`UA$<Kn$L^_J-QOo($}wE{rdj?
z{fie1FDwA9X!?@tdB6UD?Z${Tix)3mut1^w@zSXEYuBd!cP{<^@2_U?G6VUdu0=28
zmR0*?1<w@I?3#4@aErjoUyO~v?ep^TzN~-_=UiJ8>CBP%?x)B9NFmVVXh=xNrcIkz
zm=1DpaS9A6Ec`e@(RqgHu3fuY1oWn_UcLJC)1syO<^_vPojm#QJ)uY$zT;=ktnr_3
zr~jF4=C-u+^ZuT*em}>uc-fjYKC2AopU=<D_4V-J;OF=E_LjD(*bt#J&mfU$_ntNE
z{BjrW7ie}_)&BbO?(S}9C#OAo_8dBVI5sx+_m`KSUtCo7_dgHvSNZo}zkY4oX2#bZ
z92vQC`EqxAQ9;3v$E5S8Or0tzB~@fGN7_8EN5*o}I}^G7^qd@>t9N!3K0b5i%nSR{
zUH>*FA2)h>_|PG@9*Khw3tohkl$PF1waVMOXi?M6gq@&lb%WP1(rx`hja7TM$H&H=
z{imX#rDbMre)+Wh|39Cvt&M&u-Y04N?B3q$#qRyf_CN4e5i&L1Ds7(UGt<cR-LcKl
z`I(u4K|xyj`sw{Y!o$NapPo2zVvOGOyUCkopW33ay*)ZQdg-h7dvZHGJw0#Uyy@uZ
zczs>$=dWMyZpplStXH~U)>=#+3`9kzPMQ=H6XV12@!Pk)o}M$OPcN>w=<DoU$iK--
z+0f9?+}zy2;KKd;_4oJH?k;=#=wn4-U|?iqWMgBaq@?7{n>QsTB?G}AGc$90-d)HP
z{q+kMR;*lk^8ESqe9pgze*LOi_UX`}LlY(l{7Q6oK74a?di(=kqujs$e!t(kb!%K)
z+^t);f?B=3yq=w(zdz^ZrZZ=J;DclG^?xR6>R+|8Wh(yhA#r0w&EH>N7rXbbi{Bp?
z9lg8$|3CkEHYd-WOY8HQI(6#j&!119Iu#NU(#9t%B_-t*c;)f&{-a47H*Na#_;~;E
z9?8iwXRchdC@4I9`JzRWrc80+kTlDYxZD1voX^Q4HTCJm#qKYyWxW4ZIZv<u^TTlZ
z>C(bNNyDTgUteFpxzKHTW!md6;az;&yk5OMVRj_X>D_I9PR`8i?Bsc>Eo)+Se!8_a
z`{>c5%l+ra?JCLKU-y>-w06$W(6G0+_e*+^x3{*2hDT)N%zKl*na#_z)zR_s^z8h5
z{>iDS+WvE`rp}ooBP#0p|JdnwhBtjvqo&+G{PpYClD}U9*!G;b7}@{u_3PXBf`vL=
zG(=9V%g@Tv($!6!79ABeFY@YX;qIefrtc14vDe&VyDDUmDso1g=0uMrr^=UoeevSO
zmMvQryZ0Ntz4Y2uNpQ16x&B{~zx7?9(>7-Q-+bL>GylxgT~VDbPJtl>1s~4NHeY(m
zX7ktdJkj58PnfA(bvd3tf9=klmgeTuD<i_gx2K*KD>F=Ee$o2PY+kJWU8U&k>})?j
zzG~jxoGX2&R-NAT^kovioXvs<KfkV!KRavItXsEkJ>ff4WFfQDye1?pEbW-mOjfJx
zT_3Vt#qX$X+G~Dd%hFY=ew{h=#p_qw!8f1IU%7TIEGjB0BI3t6>-QUOKP|BM@-9Ja
z#_}1wi_aUS&Ck{;z4y`h_XIhPU8S$5?b=mUTl;rS<mM%CN3*c9dYVGq?Hd?4(Qd=i
zyE_V<!^5ZBt~;8;u=m2fW1C-3&+Rz>-1{%jfjp<I;HCFA<y5k=wsv)KeM>uB{AcdB
zC9^%+z=K_-brB0}`Q>a33=Jnrxv?;S`qY1{A4GBK`zcLSQBzyCY}qCL%a<<~7Z=Y=
z=jP_VZEbI_tJ`ar8J-on?#Yvsm8LIWzLY&L|GMYNlP41<OxU%{>e=*N(-lRyCQq8w
z)zuZZY|^e>yLOkq-&Zp;eBIKetn<qp9{jspd;IA<`+7S=!-;hg5)vo&EplQvRuC2v
zS{Jw1%l}8B{^?Wa&c*GmGW|T^T%@b(QDyhOJ!ht=tExVI{=8q>{N06x&S!Sc*}|8m
z?w!jPJPEugfM3q$$F;T5vimnITBKxR^5xal)kW2yIm7Gm^>25u?do}B^YUEIwl#|u
zDcRfazr5UE-o9>*?fKbzeK->Rf7g9_!fE%j;lSVY8#iuTus3}A{JH-ei;G8&wA6Ck
zyvK85$&w|O#m_FhJQFu<>h$U9X=&5u&h?G>T(b1pW25%lMcEUqQ$!>rGQjJh#C4;N
z{0Z^6eqdgT&UU{v;~A4mOG`^~y{GHFtw`qL=KlKi>vEr&pgo5>6Scl8Sp+>__v-cQ
z)8{5nn<f4COy$Wf4Gj$G>CaWYr^#3rwLqL$c`x%m1IHb`i`(<#fAw77vc*JNdiJ74
zi$D#N^XK)Ajg575dhGIJ!m_foil^#-+Z4ksrt{(BN5vL{;-;6%_h-zQQTqDYMbkO3
z^;Jq17B_C+w${_@t6Q~U!-sQot(W`H@9XcMzN+|WmndkLm%qQfL4reE+`W5ys~<ml
z<OBxS)<$1<oO>qif-0wCVPRopWTc~`<GgwE-mFTw-@SKl?R>jhP>*wM^!B*DRbL<X
z+uK!sO7ZpeEiC-_@$vEGq@)|kMnU<#v2B@AWyza1Z`P05@!`kE$KB%kUb#EhEcKrL
z>h<gGTef_8e;<_0<{b?P4V^k+!U3J_+qPW_j{5WG&z-w>Kh9)ld1rs@#EBI<c37yX
zwap7SKhNamJsyvR0ViZaHcd}Gdi?nGY16unCfVEDADSiX!x0!7T3S*f(&?f!vBNfW
z`pi%t`=yH(9XfL@^?FWDj*P7A-;c-T-{0N+{p4iz-DPj1wq#7)yLa!*nUc0AcQjkg
zJe#mg*%~&8dh*z@w%Dn6%&#u@m*?m27gqP%uv{Vk{=V94Ya;vl`f7iFOBGMcXWQNL
z#wIiE?76wtFOviX1;6+uZi^{PezAEjpRCoE<l}tbY~DY6mbTLJ{u9+@waf|y@sSUn
zJ$b^>>Xe(CduSF*W_tSddpsvrtk9^sw(QELHJ?6x`uX{Jb!DZcwe{uw`wfemX0AN^
zr9AyxNbI-ZH#c{gnwq{@e<?<<{78r3{kq?8A0O{`RTA9$^v%JpZ?97F+jMq@8uo#A
zmnLOqR{s8$yD{R7k7Hh5-ZJ;J6vNpU<0M!1X6Ar^O3RfiS2|pjR_aa{m6EbbKPU6)
zd*wanHlD=uKh;|HeAtrD!17Le@w#<!(b1rNUB48KIWJwiHf?6&&%5RK4WD{@dxMt7
z{C{b5dQ)-w|NVQ5`@46Y`u{(@?eqeL>5PoLE+UMAg70TFEfoovxpeBzylF4<%!`9h
zo8^YfZ=D^rCA)Rm)UBFnVj3+PT$VZ~c*I#nIuduR<T#PL;|v4ynWx{6|9ty%-rt%w
z!40=>z5aRq%=6-NmHW?I&aXWG{F_yN-{Tacn;VmlpQxO<diCpfcX#jJwX4G~TyJ{t
z%YwW-J?*Pc-@bbHZdq1r*t?Y>T9YSF&d$p6n{Ov8E4w%K^t5JnelbzesZ*v1O#Ilb
zzt19I_8OC!Cnkz=xkg4xY6^&nxy`<mwYB=&n?&oU&!1nvaA84!hL~>Dl<CvmRZq+|
z&;R#qcK#HvRA1lT7`^3BZ?4;zdawR}?Lxm<IhB9EUiY74QTX!G(#p@zG^cu9D_&@y
za(DjP=<V-rY;3+-`Pt;YjPh?Y>qrJ3p*`)@yFcV{fBE`#VujU&XK%|C76m;NHdESX
zqAhp%Wl33CncCz|TiZ9UUvJ*Hac9-nS2GNgJ#-Vf#cs)*;7vSw>XcWURVQeA%sii~
z)XODg)%Dk^LY&rlIoWBaIp!)(iroA?tL5K^WkHKCPGB#8lm6-IsZ(6)I~f?o|9BZn
z^_rTR?w@!3*M75l1|~fQhKBiEcMgLND~n-ZZ~&cJ*3bYt3v34iLqkKiA_D^h3rxbG
zWKG$-JC(;v(yp(IWn^T`&CT7qb*rqb?6+^<yp~Q<sh3-&VQg!=cg>nJ_wUy)V9MIM
zYu~<oZ|zG;N+x{G)+u;=tk=;hEH3Wety{02Ju|x^r~%qZs9RcE`u6qf$sQ{9UmIqB
z-Mo3TvATNu^sOJBFIlr@&Emz6zXjh;O-Y#$_vg&wtZAoCodO;G5cmGgn=^%Tyq4~&
z`kIxW|6aF$*Tce(kB+vrv2CiD?YBHwLquufik&+n*I(z?+^w-=^7#UFpBWF{y?giI
z!G^T6Qta&P($dm1eZ=JD?JxAVY=7{7W$^NCd3U|aTwPo;wnlMp>yx#<2Cm6><=!^i
z8(06~!NKTV<`u_Pgibaxv$x%<<*t-z<30N{*=%W3q<#L(9ga7yeE4L_({eE3$EVZ!
z`I|rX^zaBpwpp!mTm13u_WORGo|TV#%}cEAo}F#ZFK_qf-|zSPKOExD+B$2>%a<=B
zHzu+E{Bt!tzV^q%_WJ+7@2_6Hy4UUTlarG{>u+By?*I1X%Z9VJZr%jRUtaF7F6ow&
zlVkVuiSXu^z5Q~wRlk!XqN091o1H)D{KSb9uU)%#dt2`3&!3gOjhR{Q{6Bp2W~A2C
zK1t(ar%q+Pxv??%SdZfIr3H<4We4lo+1p>dc(HBUHpi&Q4G9O=L~dqcV!CtpE;AF;
zyvk>i_w-#d3KfpGsNUSl%f5c^wh6}*4LH0n)o{s74r=^*{Ebx4o+G?DoA)dcD!HzE
z+2@WBcihKGjvowm`{^AoJbLu#=JfM&XI6ZY>Fe&!&dsg;aF89euvS`n_KX=brcT`o
z-u}~e<3>c#vjdIHGiT0}IW8(9QuE_syR><pjB%PzboA_#DZ8G}tG>22`uo-J_>W@u
zKYseO>-W3epptN@_jEIJ^WVRIwY9Wd;88Ald-mJ6Z_Mm`U%q|2#JI4%Bt2a{@>l!U
zIdek4eEqs{TZxry?4#xT_wQe|D(hH}q>6S>LPCP8E9;|Y8+ICthnPw5+^_#{d%Q4w
zU5uo4Sx#hRWL@39?(Xgot=!B^%kp=3=2#X_(~bW2<+A_nTel{${%_AxGBKI*x9aPw
ztLN>0=YZCyg|GAR^INxW-7>M4k9wVspZL1|g1MB!t5>h4c%|0X)_Qn&I6FI6Rau!T
z+E~|pI;lQgH`=W9)fLn1Yj>*O@69<atmb1;_vgo&$jw1PL1k}mO`SFCl$q;ZT@8&D
zt5$)wuEfN|`1tUgU2c$mPG+Xhv`LdTWnNZ$b$(0c<qAF%6O$#&mbJCCOgO^3hWXyT
zd!3z~+~RsFFO7nOf|Qh$Y;0^cZQg92bHhQZ{^L<`ZZ58x+S>JTdtW_yQu5<N;w#ST
z)$KX{K0Yy<QanRLr%s=K{mIG6t#P3tA#d*P{;psD(>pRU(#y*$Bt+!)gI;O#6r;%O
z?CgMmfQ$?c{jL2cQ<Pr2MahM(4AGkNw5f?{(}z8qH*b#7v#<K1(OGDocc<dxQE|&Y
z>&j0lDJf5^-|snGcxPwv^O%?zP=336*Eea-+O=z^PQCi??{D+GI~q2PcQ+(DXJ)?q
z^z`(}Ko>p7vbVRso-sZTI<M~Uudkt@p+}D%{rK_Y#EBDodwXwh&;Nf|{@;hI;qhl@
zo1edZ`*wy2XyWX{A?_u4H8p>JeSIw~B=qUir&Fg-^UK@CL`UyVJv}Xbe(khB@&z)}
z=g+@??V6ap{Qj!1S$&Vy{O8S?GQ}kGl1hu;oQFo`%hs-$rW3g-<>aIZ69nGv7iQnk
z$##SFfBxkp7nhcU2?d3PiZ3G~y2WHRKajq8dRfkcnF5DSKR)0+T>!jD#%Yt*JBNFd
z;&&MAWIkS~vh<LHrV7U%P$V5%B6RfV(fhUEWhL1+r5c=+%J|i}ZQHg^VRbh*H!Tsa
zh2gomxtf}qzrVfx{N;;E@8?fpCsK^+!C+&Aj?a>7w{BHkk1fAj6ms^QQS7u}9kJJ6
zt2RdDWM}WrzrXMKyy|!Ve!th((D?A>%aUGmQ`4_szpjnix@yxVBQ>>Sr%t`fum64f
z(o%0@V`KJH!oM!M%ip|p%kKM~;wLg?-{0L`xNu>&m@XGT|NWiC&mSG_cJGncSoJl_
z+<d!j^|y+us#`a2zWn;@$B!R(cbCWSE_?g&xcqWoS2wq)$jH0p_iJx&&-eHCK7I1!
z&*S$01O)^HL`An|TvQ5r_HOrk(B{^Q(_(CA#D>ZLS$4jl)n~3%sM18AStcu&FK<_q
zdhl=a1N)QbilXad9{vA+{p#JjXE$5q+_&gEed^SutgR0pKICd`dZLiv%kh4K&5sAo
zCjHE}Kb_X!?_(rB;s1=rJ#!5b4{gi6ZQ)qN9v>gS(Ejb)w~O6+AH{Zknq(BfZkBiF
z#A%j|H9w28vtO6rt5i2InD8W3;iS}@IdgQ>vlrZsjg7s1`?hBi_ciT_9x2Jmm#<$h
ze|k#v*YRV2%kOpF+?@XW>C?)pD!sTp5f+n_-Fg;?zZ7%(+F$=?aly2|fB(LI_3Ffp
zNjasQoSgUW-TVCP?C&p^{oQ*cF5bR9d+OAsmtRhrG^we%`K0RpwQJW#t^Id>|G&_<
zxP95z^`xa|A3Nsud4ELqYtW|jcXxI^SztQTC#B|v#zY65>8DkNI`{AYKS|YFOh0bU
z{Q3G5Jtj?>l$4YNI@M^=qD7L%X&>YaCj93--EC1`S~@dUN%BwG`GW55?$@tg85tRE
ziOTi!^K*1ODF5#R`z#BGg#i~_nBO%0x0?IzNT;x<s3<EdYqQCf3l}C#o3<=y<)_b|
zk0xzwZg#G#tE;W8O-oaoz3M<ya@N*ax}LSc8X{U#SFK&!>wELUrAvoq2`rO)@U$=?
z`rf8gZzm_G$VkbZjOG)z%h&(ec=HLL%<+j+xO#hgbGSHPsTVd(-_iJ-L4W0u<MQ=)
zE?yLrlzjQ<k<(=#o+)b@zfJVDUl^bv!o^y7zxnyqv$M^^*Tw8CdwXlsCZkI~Zf;J$
z$=2(ZoR{}*|Np=5FE97!cE5D*-n@ISw-~HSORs!;Yb!4=ucoHv(W6H}Lr=cGwU0X0
zr|CvNd-yOhIr;PN`~UxaJT9-Uy{y}1(bd)A-A5n&_)#&{>+2<NeOFgkRu&c&6_t{*
zGQ0nOKCkh9ety1v`8yd;7yYSTlP6C;d0O%Iwp?vJJ-fn3E@5HUK%?QWURf1CJLBBW
zw{ypiocsIsZrEU8XJ=<-_HFO?d%J6Xemc@A?Ck8Eot-UT{l-veL8(=2RMf5e|NoVL
zS`I3_r+Q7DHA`#y>D8-1;7QTWg9#SJ&v*(KZ`x#}q2V#ZnwjTe=3&{x*W>GLFX%14
zc;oWr&&gZO1fIyOUB5oxLrizN%5IN1=6RfQd-v{jTfA}Cu36iTZObu{Dz&=%`MkZo
zN<J@JbKLsv5BfLgTg~-bef8V-@7%Hpz7y2V4!yd2_wL~tRj1=Pe?DmD_jq{Y#*Nq4
z*K>2r*i=l|Qh7Si)H?6by2u5aH&6b$XYu0Znj0IF*?&%acVpw>BJMqwNzsdU^RO}J
z*W9{&d+yx1C-ojKnXH~~^X=_z_g~S0fr(7c&-<(nzkT;EP5#iP4wprWv0M}7&jiRS
zShAm-d*NX8mY7Lz7EOP(hEs0awrxriPh7t~ecQ2ZIzpW$QoRv6=gyy(-?RORT?1=<
zOYKAtm2cm^JvlYyIYYLSiV)}h7b2Z5VwWVM4{Qo|N;@-S;`Hg^0RaY8UoxuPr>1^=
zbyeMOj>MT2vt+j`?p<S*bw%S^vAetbr^M&y<~|9pIz9bqW$}@1ZsnavlkWXE@$}Qq
z;^)tvJ-Za`^JWS6eS!6>SAYKYZQJI}#!|h_@>w6^gNxNuYfhXv!NJM7^RM|m%f8cR
z&wl;%$>?`5%YH!<Dc<*Lrfe+CO`x{(f9V8WRtAP2GdCO);OYPM>zDU*y{+4~zyA8`
zxP1Me+xh#ye*XOW)vK<qu19ZAoj7sg%$b_+cgqbk7!)2fJ)AIU(x#l7M&;$-LGv(+
zFM_I^Q&Tkc_x(r;2@%<y{r1+@ix)3?dU{G2GBD(6@=RVnzwXxEyK_%8P4!Z(Tp71E
z?EBZR8+RK7Ffg#(x!pRI_4U`PU!Qv8*8dk2Jq&8hA1M4kk+oRn`Rmu-CEK5z4J#98
zU<fGSFP{OLS-QWk7JPi&w*38nzy19DJU1stOfTldZP42LCr?rqNz5}$ZVOxO>*)zv
z56dRda9^Q<|NHTU%a^+^zQ}QXE)&QG28JIy58B2+yAz=90|N)RJHgGsz_CMu39H2Z
z(swJ4W|zIawKebVu6y_5wnm*ToHKp8c;vFM#TP@u!zUXFb*dN`Y}mGK+LVo(H*<4v
zY`BwCRaKRr|Gt^u?nK_6!pCmz?(J*WzFp!ud0p)8WfwD!^~=A1@E~EQX4dpyW*(<b
zpSJAVy>vCpqyEjCH&34)9vL|^ZaqI2*CW-kzZ(Vmaw{u$dZ>K*{{8>T<-0d;-n?N$
z!No<cCEl^IvDMYqe_uU+u0GMDZeDV}hx?S)pR#9Mf}^)>+xG9@zr*t)A2Kk_dC1qu
zDXg|*_ik$|tA8K+>t$@KzVu3)$JPJ+dhOb^FJHc#Ipbq)z8%z!{5=2v6N_^fFMfPF
zJ^tI5FI%>4ySJn8@l@^bEm3bF{g6|IG3Djoe|~;0%5`-A|G)WtkCl{^wnXWkpVr)b
zc$R6lN6S<XmCnx2Lt8F6wd~{Flr7Zx<Uk{{%yCmw)45iqr-~j1E_Qo+W8>pTN4sT?
ztE#GQ-M+p1=%a%nPb}VTK5r+T;`uB8h;($P%cqyi=l|omtUJ-;+xz?H^EPhY9KAWM
zck<-Pn>QB+1_tKky*pp_hO>Xg!f&l-^nWH)a-9f#^75tTL=U?k51P5f^*Bzi2w9cL
z^I*a<xd+pjju+0EJb7}67H9>{mdwj<-n`kgY15LRmu<Y#Hnz6*KOQvS-CaJ}Xx+MX
za&mIQ>VBXzBU-t|Wn^R)Ena;4)-8*^(<e?8l$X!9udj=Zz3UJ*XYSmkK`&<*CR_A<
z{_+Jh*`0ad?fdu3kM_7NPQBlvS{ZsGJU>7G)786o|1NBodt`C$&?@Jkm0u?N+jaK#
zu3fdNtEY#Dn_IZkMNDgx*!A`C{@#2nw;dne2nyHS9;48iTkt_tRfsdc(kwhYd}YY1
zr%zM!^Fi%Daq;N~w;$tcdb(2}&%D}&H{{ZqOskA1%}+HI+$XlTA8+9lHp{;U>coMv
z+uq9=CYqX>+uv+0V9>oG>*IbP|MfJcqX`C6rc5ybA5Uoa<%09IYu99szrDNr`^x3>
z7TG&BA1wI!>FKFcr*7T4<vZJK<JH5556jp6c=+@4^YyX2%Rac}-`Sx!`D9ddbaPXa
zle6>Is9Z<K#`WvpUtJv@z9zzOLcYxL(D3lflfHfXCMPF%^X5%yvz&zO_Mc8DFWKdz
z=I!Zub4%vrpp|RZujl9FoN1Oj>w;u>`1M|CbI`WC*X#Fh3z%rSG3hARRIjhMve)nZ
zbV^%OQ`6AU@a4;w?fmlh_EZ)_dK&ASpKSNi^QcUYj*YE-d1-0#@xG%+j$FBVHL&~a
z*|XboChWC02sql-)^_E}l?f9jWM5y$`M4=Y&)>`I*5-8o($cSu%<Rw3%-o!Fa}#Lt
zKWcZ~->RgfM~7Out*xwVY;8Y({u~<<vm|Jx+v0`Aj;BS$#H=hWIhTi4xO_Zjrm6Yz
z&d%cEXJ;N-=;`bCS6sbt!QqUhrR7H7i6^@{J0;IFK7abO^xK=86P4XBWu85AW>3k>
zpt!huvE_GDzgaxwRrq@L;zdJi>*{}hetLR(f;_gf`1z-&r*m_1Ud;IN<;w==c7`tF
zn7+pr+S;ohJV+=n|NiV*no#cg*xhQ=PlvCKx_aY=$7!G0X1PbZMCZ+$x99YVWy_YC
z-><oR?_S;geYMS7GK^-X7|q-d1`#@C<>jE$H{>gyOq^+)o|c}TZ6d|JZ=>qdqMzmW
zYsH0x4&C;P=HTZym*7!$?<*-R{P^L6ho7I^2~~D>c5Us|d-m9Hi&m=r`TO^Hue7^Y
zkxcpfz2A#u#HFNe-3Nj5uNA6K&oJNi?b|ow^m8g(Bf6V&CL}C;^zQEN&fCey`<`AE
z>U24H@Zb}hkMpYEy?p;3w1;u-+_}12zTK;S585AmYfGk`on7^}H=JBtvkVdswQ`Gh
zb$7pvxnOj>U*6n$?IGnZ^KDmVy319zR2`l5`0vxnni5Z5wk}?*Y`vCST<^=*uXByl
z`SN$^$M36od1>jfV{Z2tg6_-J{YY#+xFP8%m$kKZ-{VD#7CAXNMW|PTg16y!z0X{$
ztqT?`*u8u9;~nAgwNw8nE?>U<b60C?tE^>F%iW@1UtS*V7SF%E?d;{tmk$-bfB4X`
zuE=fi#SD{k^K5tT*>mUCt*VcYj>;S_1%pDF>-X;I*_cG$zcI;sx?b(GndyCUwzsZa
zNm<ysW{u9$AW0FC6a$GH$6cn(nk7|U{{6;{8|L>a7H{8PzMyN`T$S`wGRHfQCVkC_
zFlS&86$IT8kjSoiXk%*jM;*Rpj+@tQ5-qiw>!D&~t*JDz<IbZc#U-b&{rdg;Xwt^1
zQ$;y1gN}nSN<FpAclI>>c)#aO(<XW?o#x&n7kFsn(sLL1*X(>K`$TQ>%7qIZ*M@!W
zW1oC7Bslo+>#b31^D;AEzI-Xjr|??nc;V*s^Pn-s46%@Fo@Flt9NKI2b`(E9XT8jL
z>C&YK4<0;v^eE`K^@4&8{r%_p?f)nUbqWay<=xrw@bTlxGiOSQi-WeyPMS2yxt-5<
zj>X0;TTE<iYwzwV&CAR4^z?jUb^6}Dc{W+sv$j5Q>e+I}SX@M;<jD!a^78N8;(9uf
zo0cqH`t-?3(3$jBbNlA(039jrw)o<yQ(a5$J+$z95uKm^zKNAP<K&@3PVw>aD?_Yu
zZ*4hnz+qRcj+nZts_lmZ%&e@eCr_RPoj$d4%hs)1w`?)d(C|>2_~-Nd|4YJxf`ji@
zzu&ujUe&3aH!bb$?F|hLO-#0I*%A^_`0vk88};*ZEFV94GG)%3JtZ$M{rU4}$&w{M
zKR-Wy^k}cVech1`!5sF^wZY5%M8(85CC{Ea_w2Qx)mOiL`*vhe)Y^Ro51VeX9q*Gp
zUDo(`$Du=q8ny0~->+TnKY!cy?e=AFZXD?pe#skPwCCQvdyI^XNgFMcl^?&kx%uJ4
zhl|~MH(j{(_xt_&Cnp5i+1r;bTUPyU=kq5gCvV%f?d#XCoSd8`dM9G6Ei5c7EvHVK
z_G#JF#}*F-OW*JPzA4#z?#_yjN?)}U6dGpy{&qY6^XJbe|EQ^|T3T8zUAj~^cGs5u
z`~N>VIeAa=`W-udY(8)I`Sa&st*Pnf=hePkIz1~pJM(>0Q`50N+3HVEJoEGO%RV$W
zHKm=M_4N7k=WpJ;dH?=AUqWc8XyMCKQ?*lGE%%%I>*ezKlVSp{oc#6c*Q{AmWkt0$
zH3H7<fA}kpfB1Smp4<G|wQGEfL8tvcdzN-ucec;6d-v|WdX=^KVusO7yB`mjKPj4-
zef#zGwc6y9875`r<<T3QY8R{ax-AY{y_8jF%Z1CAow+8g7Znw4ej~MB$u!YGqN=JY
zuJ-HIMlCLD3!83cQ;j!=97IpL&GlP;HS729-}#q$H%)w#YR~<=DQ~;Y+UA*do0sLY
z$GztP_c1QKj^<l%FyY6=xh&;ZoHxIFm$x_0Kd)y~zewA~DZRbDvu8{H^r<UN>%MvG
z)~{c`CY?7<J9Fan>CGEAO4?R^i7mhDs+aHHBa!&CkbSR!nyRbP#JziMs~c?sxS!}r
z?=&!x>Sc~iie7hO){er*Zed|zAt6^BL|bKL=DBX>?UOWi`@xd4petpui<0D}>}}Jc
zm8)-_KeThfZC(G@3Cqr}d3n3>y7k70oSoOV%Q)OR)c-<d$Ks+{sVONfEiE2PFUfDe
zdFM`yzW#c}RtW}%9fz6q7#RM{IvB-eZ#j4FT$hdCvKQ~!Gl#=dGi&Rv6)QM`%{)T1
zu0DvrC)KfQm(@HS-=#sZ`)YQsS@TBSRx&F;UtdS(Nv??m&(EJfEiEng?%kVqzmAb(
z$NsVv4VTvBP4Y6RFA06BdvtDypI2vZ@6`;G?ZPf>i#7hTK7QPP`@#HwUzR_6_Uv}f
zk#pzt^z{1f1_cC6m^LjfKYxGmbH86%n<I;girR9^|Nr}IlUnKP>+9pw)87vo2dw-5
z`~K&7tqd%8;`QHXcZE2dyzDF0>lW5zsS>(0QdW!m_9utZN~xIUgBNbzloS(l6La49
zVcJuN^f;%*Vp5Vzo|Q^4CzV~FP$S(_U9{6iMJ46K>O>xw%*@P)2#MXUD?{x5d^r60
zSnuY|o3(Xyw+58o+f#XX+wE)D!~_K$_ka8Teg8L5i{jg?-MfEx2r4gHv?y<<kgx<>
z`IYJ&_Ub23p3L9-_1Y58$@~6%I(^{4fh}9M^xOUF*b}NZ`D9jhc63x!PEO9F$B%p6
zl7oUStqNV8Vg$N;;NAZJ|6X5TU;p#z^ljU=ZQQs~R8;gyr_9aO7c<J<-~0PwasRtJ
zJA<{RuDbflIQ`s&YsY$}j~B|UT^*w3t9JSO{rdHnUy5+K1_T6DRsA|Q*Sfa0HaRKj
zNYclh#m_xXdwO~vF<*Rf#@xBSr)T>tD}H|N;&mY|ZtlsGCp$YkTU%RaZWa|4UGnb7
z$Hym&U+vnp>(8G*Z{FneJ?`r2;*+s3sQ&gQ_4G8`k4J=!X7)&}UAJyo@0IJ<gO9)4
z|G%zG{Pnj+X7)8})}$CkdV6ypFWhqG>+9>0+Am+ej9P1^sMvTS#j?-a*LP|3qsNcS
z-`?6<^Yas^g>m`v=SxeyQ^M2J)xWM?v!<tSmDf_CsPL5`Ho`U~R<Xgs!S3$un>TOn
z@AuEofB*0AZ~d4Z3Awqo|Ni_0ol*rFmrY7q<g{>xP35PF%I-^oUd}X5PcfP~b?Vg{
z8<YEGEI%C)_TTWH;mzIM(=$5WzI`iS^<v?yS+lNOxw2`~rjL)0tE;PPi*WTlHZnFo
zefo59QPDF0`Fc7JUcQ_;Z{EDglOMl$;W1zF`t|GT>gw@(t3q|eo<Dh_G1W`SRk^xf
z&ep2z&5fPK&nK;SbaeFf_1&_kxtaO4^5(3f2ID*PCw%x&ke~m4!h{K|++uI;@1NhL
z%r9r-Q98kfQT1we&|J{+%ubfc@3t;jrBW6ttL1NV>XhE|b923;m+h<lbW)x9WRU04
z!pFy0Sy(ol6>8PHxNuU^nkW+`r9%k@J9g~wnQ7FTEVA@YeRo^>*;z*ot1dL&$;-~3
zZBdw%lCs2UVZ!M%bFHUuJ*1V#`DWU2x$2%ZN?%SW_p`9FUW{FnpSE??n$m@wa_au`
zu4I^$mX@Z>JaX=wpS-+$ef@vW$!b@xUHi08C~-D;a9iFu?ac1?`+h%}?4M;ai&I#w
zK<4_ziwE_VT)2H(d#cxRzqzyK&$qAtSJU@+TmF4H0Re-oD=Xf;%QH7OPft((^jv+a
zm#0B0w}5kIW@cSo-Q(l^-@klWq6^v{q8+|&j!osKna1hAe*c!Q|5Nzuk@8OKj|Z6f
zC!Bx68n?}6z5Cz4e?iCl=;^u1I2`!9bK|yc?_R%tEK#U()sb(BL+aKgE=?yvf%xRA
zXqS8BP1V~*AKy-Miep+Y;s532DpzZ3>yvJa0-ya`tRZT4$SUn%Zg_ZjqGXl-%!owM
z?J3szr<+*0A3b_>;`hZjdSwo0vO-suF65kc?AWmj7cO*kbbR<wAXMPqFIW5V(b0~M
zj^gL%?iQc7Eh{VAv)*W?j*-!)L#^D6jg3`%<5YyUZrdhQ+dFrzY_+n5xq11!J3Es$
z-bgUGa_w4?jQUis^fNOAWo6$!dsg=E&(9SrG^ToeJ;2OA$Fex>+nbwd+#=%Q?Ck8b
zebm0$CKcUCNlQC7%XIaM6&fZcQ{GNlyjVF>tN)I!VE56S$~gAfvuEeu+vBO{!oc+I
zd`r+u9bH{tZ|~}tOQ(x)9p$(GbK$~;55HcoumAV+`E*b-_UET(XJ_yK`Am9gP-Jkh
z^7PZ9T&}69OWhXV+?0CyU^9DnSJ%4u{rB$O^Q#LldA}-jwULq0iJhFcr3}4ZPn$Aj
z&%a-<)&1t|D0z8lPvz$&K`UeQ!dHe|y?Rw^>Z&zsdU9v}IyNm_Lquz8*S|9&T&|Us
zmASdP(QEeXnR8|7-gocbl@%0dXliEW=jUf;78VqoIDdZq`t|3}oGB?OS>krnZHkv_
zsgAk%^`_fgtxgLAG^U=K9#_>lt+2Q_dF_#-M@vgeT-@9)9X(kQ9kw<qG$O*|kjCAo
zj~^fY<>r2M%~xi2z6nugW@g9x<<r&wzPh@4{oZd<6Sqv8IyE&t{qp~2L1niq*RGkF
znofLO^6mAHkB_yrw4|h^y}i7enwyP{jC|CB6B8G@E#A0!^Wwz4Tep6_u+Uk>ONxiB
z`QU<}m1*bZtPEOtZl3Mx>#uEXY`VI;b3yA2a@_i4B7=es70N^>e0p+{m6f%&wpLYD
z^$n-a@xsf?{q=QpM7ocb->)st&tJcIvGVTn!)?5v-7UJhs^uywLY&d_t~>Jc_n$c7
zQB=s##&)Fa@Z!CD|DLb^w>k2mn!kEhn1ko(0M2I*LZ|Ne#xB%9E4OmOrjXM|E3yKM
z%)F+hr1nN-q)eC<zKv(=q2N28Om^7X+Q!Dl9zA;WP^`^;os7^{wLH$5Mw>+XKCC{O
za_MEs5ynj$w{M@GvwgvurH_h?w!L}q*^G;O##>p#TbD0?{`dR+?5UftU%A3@diGld
z2{{2fp2?uIB)`18T>tlVe5Llxrub>f?tLum?EdrZWStX183eS{FJdFp>vMmU6do`!
zFuZ%n#K6F$C!ykWRqbd~&1I*x^ZC|>Wt)jBeplv<sE_G!OHNB$=CyQJ<>zPXb1xO1
z<Pa#R*V5@OY+dEs#rkvE+_|#)%&iyhyv?v;FDg}7EXJ~Ce@NT)@As<pEi87dU8}38
zn0RBe@rnP6vrf-+c*5-7C-d`Bx4uPR@an4%A3j{a=aW}lT%5D>;p6i4HQ(OcymBQZ
z&U#POo-G&L`{hD4MC9v!EWE(DZBf|jzmK~0H*MPF@muVZ4>QXh>j~@D>78!$UvX<m
z#Dx55)23}&$#Q1aZdu>w4$ph`Z13O@V_CEP%|Cya&`?p&Qscx!EgwF7NIZWoA)(k(
zI4CIS*}1vDuLS!~4Edlo`Q>GQ`@6f#L2F*^e!W<{v-r82t1IV!wu-Gcwp@^ulq@SN
z`~3WT{i9Cx7QPLlpf#nI#m`z=TWi1HEw{PPHaT7DkJN!*B8OepUw?mh_w}Pkmo8nZ
zs;74@#pvgcA3aj0pv@6iRs=RSHcnRaJ$2?x&CjRP&xYx1X;po>=ze~VrE%e-BS*W%
zuV25Oo{}=5%V?&Kg2ICf3!PtITf6x7-#>r+=2$#@^k`Ao>QtjhclYC)&)a!_>pJ@A
z#fyxkK`Sr6+_h`hinxx}CzUyQdGjobpDp#C{_FSe!-o!?I(>S6)ho?Ss~0V5I%TD4
zHMj4C|JAJ0`uhLn_iL};yZ3MR{lD*SY)sC+wnp*p^$ZiK-ZqPuuU}XH`%}5Ca9jN2
zW4+cD9~Q)|kKa*{SXEW!;^N}xckWoP^i8A3$NSUQ+WdaAdFRfZd+I7HDvlgKet%D8
z@#$&0jg5_*oScU~$;!$eJ$m%W-f7dO&6y*kt-boiix>L)emK2oxNyWFeYd8jCg?Dv
zwQF<p^YufQ#q2IyyK?2pbLY-wm<Ub0&2RrF!9e1~BoUT4T{GP;3!U4=bRrf6XjD~I
zMI_GHuqbGyieu#3u<u{L3P!g)d^(fO;_%=5KbLO;)ia=elaJcu_3PhH(F~rZA3txx
z1c$2=<~VHi6g*`fDVZ7_eS5OMU1UhelIyQue%rFeB<Wm&L4dFNO=&T)XD?n<{QL9s
z)G4pT3n~GYD`(G^UVU-N?lo)IwyHl~(=c_p|I)kirdcATpMHFNyysZ!rwg8w)qH0f
zE#11c^xPcF>+9p6Pkk8q(8BMAesy*A&X|7(nEC&FU0<JidUA&ADgB5I4ZGZ@uD6<d
zZVmIa_CDL&u{(=YIg8o(<?d`w=RaP!Zr!@?cgy1=B5sJs*KABY%+~7U_<nzUn!+TT
zsBT~GwHGsFWM!Y9pD!;ht!;8@*5%h<O*&qGt=e|O0GucO?~UeiTYT~0!H18Ic0ai_
zE!3GSbhgOCn#pTDlD7CQ-@I*G+V<e$kjtLm?v-ATjaplFcUS4Ub?a0v%(j(RFA6d@
zHxFC9@?yq`b=$U?-TM_`!}$8e#l?}eT5s$8{rO9ctgL2T-w|1vQC3zK5)u*|JbC%@
zbZ>9&^*q_GH}n@@toZcAb7RDwjEhR;<>gU!+S=I<54Gl0zLHyABWhLf^;PI;XLS{2
z<;NS3%PG$Xom2X5`;_U^`z4Lj{{H$3IoCra)#~Wkv%PDNE^Gbv@uTAFkO?e-VrPE-
z`Zei*ZP62tT`zhz9E`s$?AOrn`|*P}Z))D%v7EG}YmLR>Rf;RKiXR{A&C%Wb$#>hL
z`SatGk{)sE?>Ue?Vb<bV=U!f39v&7p&$b$L$kvi2NABI5H)rW5og$gzr#yH551Y%z
z&VD+@Xm8wkJ@?$O1E*dE-+cGkWI@j3J+W-fiAOpFTU%Q}8wysekgzODNl#Z_&y&4$
z+qP+M#lfpGCZ2wpnwko_{APcht!8{^XlQKg+ZQiROk4hL<Eik4%uAOp-O?4dS~Y#a
z8{es*t&<@kA|fIgTW>u+-ap@}H0%64+vx3icQ+=pA1_=Y+v)_G{%v)dIC0{{88d#|
zDL()4*!*y91A`A|W*SeOI`!VYd)e35+1CI2!*BlwbgSK5zvIOXYj>obmD(9o_xD$6
zQTP0>y}1`oo$A`r75`$rV8`1w-mAfzykf$5JzXa3+__Wi%Yu-7p4y+TOfIoDO%J=g
z^76|S*TOO;PM!S8WR}g+m8mQ2raos|t0&UH^>ks$jtp*_*K0(##k)+)GLg#8%JPU^
zd~wF~>B~d3_+_n*NV9KVoN|rv+K~s7<%6$el{z~!|E&4^?5v~Om(<Hn<)x(;bxur^
zeev#HUQUjT&%8{A%=h^dr%e;v8>e3*QKTOEhxO(A_v*{n@!S6~n4MZyF(JUN@X?X@
zRo44=Fh5w%#wgCfP{1$Fz#ve-$iM)uvY7Nhj3f>Q1_qEUx&-#A9MEJB#0-!g@FFv~
zVTjdaNXyK)!N%V?n6dR%@N&Q0ySqf483hU$e}LLT9esUy+1ZB!z#0+rNT9`RuP(eS
zQTLm(V#Nv#4UGdC4fmOpCZB8xWME*J1F30|7q79zFfgEKhk6s$i4LFza3G~%2Hc4V
q-=Ky7*im4mAU(sy_y^bi*w1h1cg(3T`pLk+z~JfX=d#Wzp$PyxO!k)m

literal 0
HcmV?d00001

diff --git a/examples/cs101_instructor/b_tag.py b/examples/cs101_instructor/b_tag.py
new file mode 100644
index 0000000..6f8be07
--- /dev/null
+++ b/examples/cs101_instructor/b_tag.py
@@ -0,0 +1,15 @@
+def primes_sieve(limit):
+    limitn = limit+1 #!b
+    primes = range(2, limitn)
+
+    for i in primes:
+        factors = list(range(i, limitn, i))
+        for f in factors[1:]:
+            if f in primes:
+                primes.remove(f) #!b Compute the list `primes` here of all primes up to `limit`
+    return primes
+
+width, height = 2, 4
+print("Area of square of width", width, "and height", height, "is:")
+print(width*height) #!b #!b Compute and print area here
+print("and that is a fact!")
diff --git a/examples/cs101_instructor/f_tag.py b/examples/cs101_instructor/f_tag.py
new file mode 100644
index 0000000..354421a
--- /dev/null
+++ b/examples/cs101_instructor/f_tag.py
@@ -0,0 +1,6 @@
+
+def myfun(a,b): #!f return the sum of a and b
+    """ The doc-string is not removed. """
+    sm = a+b
+    return sm
+
diff --git a/examples/cs101_instructor/i_tag.py b/examples/cs101_instructor/i_tag.py
new file mode 100644
index 0000000..111237d
--- /dev/null
+++ b/examples/cs101_instructor/i_tag.py
@@ -0,0 +1,8 @@
+for animal in ["Dog", "cat", "wolf"]: #!i=a
+    print("An example of a four legged animal is", animal) #!i=a
+
+#!i=b
+def myfun(a,b):
+    return a+b
+myfun(3,4) #!i=b
+# Snipper will automatically insert an 'enter' after the function definition.
diff --git a/examples/cs101_instructor/o_tag.py b/examples/cs101_instructor/o_tag.py
new file mode 100644
index 0000000..fa15370
--- /dev/null
+++ b/examples/cs101_instructor/o_tag.py
@@ -0,0 +1,11 @@
+if __name__ == "__main__":
+    print("Here are the first 4 square numbers") #!o=a
+    for k in range(1,5):
+        print(k*k, "is a square")
+    #!o=a
+    print("This line will not be part of a cutout.")
+    width, height = 2, 4 #!o=b
+    print("Area of square of width", width, "and height", height, "is:")
+    print(width*height)
+    print("and that is a fact!") #!o=b
+
diff --git a/examples/cs101_instructor/homework1.py b/examples/cs101_instructor/references.py
similarity index 62%
rename from examples/cs101_instructor/homework1.py
rename to examples/cs101_instructor/references.py
index 49ed989..7c6a590 100644
--- a/examples/cs101_instructor/homework1.py
+++ b/examples/cs101_instructor/references.py
@@ -1,4 +1,4 @@
-def myfun(): #!s
+def myfun():
     """
     Simple aux references \ref{eq1} in \ref{sec1}.
     Simple bibtex citations: \cite{bertsekasII} and \cite[Somewhere around the middle]{herlau}
@@ -9,12 +9,6 @@ def myfun(): #!s
     Other example of custom command (reference assignment)
     > \aref2{sec1}
     """
-    print("See \\ref{sec1}")  # Also works.
-    return 42 #!s
-
-def fun1(l1, l2):
-    s1 = sum(l1) #!s
-    s2 = sum(l2)
-    print("Hello worlds!") #!s
-    return s1 + s2
+    print("See \ref{sec1}")  # Also works.
+    return 42
 
diff --git a/examples/cs101_instructor/s_tag.py b/examples/cs101_instructor/s_tag.py
new file mode 100644
index 0000000..03a8706
--- /dev/null
+++ b/examples/cs101_instructor/s_tag.py
@@ -0,0 +1,17 @@
+width, height = 2, 4
+print("Area of square of width", width, "and height", height, "is:") #!s
+print(width*height)  #!s  # This is an example of a simple cutout
+print("and that is a fact!")
+print("An extra cutout") #!s #!s  # This will be added to the above cutout
+
+def primes_sieve(limit): #!s=a # A named cutout
+    limitn = limit+1
+    primes = range(2, limitn)
+
+    for i in primes: #!s=b A nested/named cutout.
+        factors = list(range(i, limitn, i))
+        for f in factors[1:]:
+            if f in primes:
+                primes.remove(f)  #!s=b
+    return primes #!s=a
+
diff --git a/examples/cs101_output/homework1.py b/examples/cs101_output/homework1.py
new file mode 100644
index 0000000..2305ed7
--- /dev/null
+++ b/examples/cs101_output/homework1.py
@@ -0,0 +1,17 @@
+# homework1.py
+def myfun(): 
+    """
+    Simple aux references eq. (1) in Section 1.
+    Simple bibtex citations: (Ber07) and (Her21, Somewhere around the middle)
+
+    Example of custom command (reference notes)
+    > \nref{fig1}
+
+    Other example of custom command (reference assignment)
+    > (Assignment 2, Section 1)
+    """
+    print("See \Section 1")  # Also works.
+    return 42 
+    s1 = sum(l1) 
+    s2 = sum(l2)
+    print("Hello worlds!") 
\ No newline at end of file
diff --git a/examples/cs101_output/i_tag_a.shell b/examples/cs101_output/i_tag_a.shell
new file mode 100644
index 0000000..f753af9
--- /dev/null
+++ b/examples/cs101_output/i_tag_a.shell
@@ -0,0 +1,6 @@
+>>> for animal in ["Dog", "cat", "wolf"]:
+...     print("An example of a four legged animal is", animal)
+... 
+An example of a four legged animal is Dog
+An example of a four legged animal is cat
+An example of a four legged animal is wolf
\ No newline at end of file
diff --git a/examples/cs101_output/i_tag_b.shell b/examples/cs101_output/i_tag_b.shell
new file mode 100644
index 0000000..da66455
--- /dev/null
+++ b/examples/cs101_output/i_tag_b.shell
@@ -0,0 +1,5 @@
+>>> def myfun(a,b):
+...     return a+b
+...
+>>> myfun(3,4)
+7
\ No newline at end of file
diff --git a/examples/cs101_output/o_tag_a.txt b/examples/cs101_output/o_tag_a.txt
new file mode 100644
index 0000000..5ea6232
--- /dev/null
+++ b/examples/cs101_output/o_tag_a.txt
@@ -0,0 +1,5 @@
+Here are the first 4 square numbers
+1 is a square
+4 is a square
+9 is a square
+16 is a square
diff --git a/examples/cs101_output/o_tag_b.txt b/examples/cs101_output/o_tag_b.txt
new file mode 100644
index 0000000..171adc7
--- /dev/null
+++ b/examples/cs101_output/o_tag_b.txt
@@ -0,0 +1,3 @@
+Area of square of width 2 and height 4 is:
+8
+and that is a fact!
diff --git a/examples/cs101_output/s_tag.py b/examples/cs101_output/s_tag.py
new file mode 100644
index 0000000..fcddb99
--- /dev/null
+++ b/examples/cs101_output/s_tag.py
@@ -0,0 +1,39 @@
+# s_tag.py
+print("Area of square of width", width, "and height", height, "is:") 
+print(width*height)  #!s  # This is an example of a simple cutout
+print("and that is a fact!")
+print("An extra cutout") #!s #!s  # This will be added to the above cutout
+
+def primes_sieve(limit): 
+print(width*height)  
+print("and that is a fact!")
+print("An extra cutout") #!s #!s  # This will be added to the above cutout
+
+def primes_sieve(limit): 
+    limitn = limit+1
+    primes = range(2, limitn)
+
+    for i in primes: 
+print("An extra cutout") 
+
+def primes_sieve(limit): 
+    limitn = limit+1
+    primes = range(2, limitn)
+
+    for i in primes: 
+        factors = list(range(i, limitn, i))
+        for f in factors[1:]:
+            if f in primes:
+                primes.remove(f)  
+print("An extra cutout") 
+
+def primes_sieve(limit): 
+    limitn = limit+1
+    primes = range(2, limitn)
+
+    for i in primes: 
+        factors = list(range(i, limitn, i))
+        for f in factors[1:]:
+            if f in primes:
+                primes.remove(f)  
+    return primes 
\ No newline at end of file
diff --git a/examples/cs101_students/b_tag.py b/examples/cs101_students/b_tag.py
new file mode 100644
index 0000000..b0e5de3
--- /dev/null
+++ b/examples/cs101_students/b_tag.py
@@ -0,0 +1,12 @@
+"""
+"""
+def primes_sieve(limit):
+    # TODO: 8 lines missing.
+    raise NotImplementedError("Compute the list `primes` here of all primes up to `limit`")
+    return primes
+
+width, height = 2, 4
+print("Area of square of width", width, "and height", height, "is:")
+# TODO: 1 lines missing.
+raise NotImplementedError("Compute and print area here")
+print("and that is a fact!")
diff --git a/examples/cs101_students/f_tag.py b/examples/cs101_students/f_tag.py
new file mode 100644
index 0000000..f1e55a7
--- /dev/null
+++ b/examples/cs101_students/f_tag.py
@@ -0,0 +1,7 @@
+"""
+"""
+def myfun(a,b): 
+    """ The doc-string is not removed. """
+    # TODO: 1 lines missing.
+    raise NotImplementedError("return the sum of a and b")
+    return sm
diff --git a/examples/cs101_students/i_tag.py b/examples/cs101_students/i_tag.py
new file mode 100644
index 0000000..59106b7
--- /dev/null
+++ b/examples/cs101_students/i_tag.py
@@ -0,0 +1,10 @@
+"""
+"""
+for animal in ["Dog", "cat", "wolf"]: 
+    print("An example of a four legged animal is", animal) 
+
+#!i=b
+def myfun(a,b):
+    return a+b
+myfun(3,4) 
+# Snipper will automatically insert an 'enter' after the function definition.
diff --git a/examples/cs101_students/o_tag.py b/examples/cs101_students/o_tag.py
new file mode 100644
index 0000000..e0d31b0
--- /dev/null
+++ b/examples/cs101_students/o_tag.py
@@ -0,0 +1,11 @@
+"""
+"""
+if __name__ == "__main__":
+    print("Here are the first 4 square numbers") 
+    for k in range(1,5):
+        print(k*k, "is a square")
+    print("This line will not be part of a cutout.")
+    width, height = 2, 4 
+    print("Area of square of width", width, "and height", height, "is:")
+    print(width*height)
+    print("and that is a fact!") 
diff --git a/examples/cs101_students/references.py b/examples/cs101_students/references.py
new file mode 100644
index 0000000..0fd9ab5
--- /dev/null
+++ b/examples/cs101_students/references.py
@@ -0,0 +1,18 @@
+"""
+References:
+  [Ber07] Dimitri P. Bertsekas. Dynamic Programming and Optimal Control, Vol. II. Athena Scientific, 3rd edition, 2007. ISBN 1886529302.
+  [Her21] Tue Herlau. Sequential decision making. (See 02465_Notes.pdf), 2021.
+"""
+def myfun():
+    """
+    Simple aux references eq. (1) in Section 1.
+    Simple bibtex citations: (Ber07) and (Her21, Somewhere around the middle)
+
+    Example of custom command (reference notes)
+    > (Her21, Figure 1)
+
+    Other example of custom command (reference assignment)
+    > (Assignment 2, Section 1)
+    """
+    print("See Section 1")  # Also works.
+    return 42
diff --git a/examples/cs101_students/s_tag.py b/examples/cs101_students/s_tag.py
new file mode 100644
index 0000000..102fcaf
--- /dev/null
+++ b/examples/cs101_students/s_tag.py
@@ -0,0 +1,18 @@
+"""
+"""
+width, height = 2, 4
+print("Area of square of width", width, "and height", height, "is:") 
+print(width*height)  
+print("and that is a fact!")
+print("An extra cutout") 
+
+def primes_sieve(limit): 
+    limitn = limit+1
+    primes = range(2, limitn)
+
+    for i in primes: 
+        factors = list(range(i, limitn, i))
+        for f in factors[1:]:
+            if f in primes:
+                primes.remove(f)  
+    return primes 
diff --git a/examples/process_cs101.py b/examples/process_cs101.py
index 0268b19..00bebbc 100644
--- a/examples/process_cs101.py
+++ b/examples/process_cs101.py
@@ -1,25 +1,3 @@
-def main():
-    from snipper.snip_dir import snip_dir
-    from snipper.load_citations import get_aux, get_bibtex
-    bibfile = get_bibtex('latex/library.bib')
-    auxfile = get_aux('latex/index.aux')
-
-    references = dict(bibtex=bibfile,
-                      aux=auxfile,
-                      commands=[
-                          dict(command='\\aref2', output="(Assignment 2, \\ref{%s})", aux=auxfile),
-                          dict(command='\\href', output="\cite[\\ref{%s}]{herlau}", aux=auxfile),
-                        ]
-                      )
-
-
-    output = snip_dir(source_dir="./cs101_instructorm", dest_dir="./cs101_students", output_dir="./cs101_output",
-             references=references,
-             )
-
-    a = 234
-
-
-
 if __name__ == "__main__":
-    main()
\ No newline at end of file
+    from snipper.snip_dir import snip_dir
+    snip_dir("./cs101_instructor", "./cs101_students", output_dir="./cs101_output")
diff --git a/examples/process_cs101_references.py b/examples/process_cs101_references.py
new file mode 100644
index 0000000..5f90dba
--- /dev/null
+++ b/examples/process_cs101_references.py
@@ -0,0 +1,15 @@
+from snipper.snip_dir import snip_dir
+from snipper.load_citations import get_aux, get_bibtex
+
+def main():
+    bibfile = get_bibtex('latex/library.bib')
+    auxfile = get_aux('latex/index.aux')
+    references = dict(bibtex=bibfile,
+                      aux=auxfile,
+                      commands=[dict(command='\\aref2', output="(Assignment 2, %s)", aux=auxfile),
+                                dict(command='\\nref', output="\cite[%s]{herlau}", aux=auxfile),
+                               ])
+    snip_dir("./cs101_instructor", "./cs101_students", output_dir="./cs101_output", references=references)
+
+if __name__ == "__main__":
+    main()
diff --git a/src/snipper/__pycache__/block_parsing.cpython-38.pyc b/src/snipper/__pycache__/block_parsing.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..111a915440a38d68e7f4fef83ab63cc6392d7a7e
GIT binary patch
literal 2572
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
KEG%3c99#g2TO~;V

literal 0
HcmV?d00001

diff --git a/src/snipper/__pycache__/fix_bf.cpython-38.pyc b/src/snipper/__pycache__/fix_bf.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..eb22389410ff1cb4db353975d3c62a897782d50c
GIT binary patch
literal 2163
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
MnC4&-Vdl^R08EAIYybcN

literal 0
HcmV?d00001

diff --git a/src/snipper/__pycache__/fix_cite.cpython-38.pyc b/src/snipper/__pycache__/fix_cite.cpython-38.pyc
index f4f2a6a15da1ceb5b8ad897d8a875183ee0e919c..de2b1ae6ef85a05fa5550eb02dee7e157751f4bc 100644
GIT binary patch
delta 1599
zcmbO#d`grrl$V!_fq{YH&v}!?n_Lt5WEjIHYRlLQr?8~3wlGGqq==+&q;R${MzN-d
zrf{Wjw=hPrrSPQiwlGAor--HSrSP{fMscKwrwF77wlGF<rU(TyXi7}1v8j(@U|=X=
zs9~sKT)>#Zn8~n^DTS$*sTRU#PG?xi<iZfEP|IAxRKrlioWdvxB3ZyBt0Y4TTQ5s3
zL!m+mGt>ljun8Ps6BvRSG&%ilF(;N*XfhVDFfcIO;z-WV%}vZpDZa%HVb!PHV#_Zr
zDJU(`WCklKVq;)nC}IaGW=qOUDoF+D<zQf7&}6yAo|ah=pIBOPi#a{D<Q6}a7hhbE
znw*)KbBhZk0M)~Ci!~=RFSYm<S5azOYEf!la%%A{w&Iea%;b_=Ov$+`8HxlM7#My{
zwqdmN<OOL=&MZkR$;{6yW@TVtC<cc%qX?q_qa2e6W05dOEo)3(QEJ*RshH%<lGJF`
z;@Ilk%6N!<@u_(wMU}OaCo!j*DlsrHWHQt+#7f05)iTyH)i9<obTHH~r7%b`h%sa`
zPG%}(31-k_yv3Q9nVg!Fn3S4RBskfTMMMVdZLqtFgg^nnWs{PbT#}rhTVN+JxrD{M
z9vp_u$+;;-{GbqFy2YAVlA2q5O9bSB;>^7CoYZ)@e>K^PctK$a(u4@rD3%mZ2r}gu
zK`fF2DFNA5#Ld9Kzz6a>C<Yjq#25t_!D7kGpp*x~lQmf#>t#SLW8~6gE|LeaSPP0W
z^Ga^9WaVe(X|f>M2y$VO0?2ewKtn78+r!Dgz#sy*hf#o$kFf|OmdpgQ1B!VV7#KkA
za0V%KVPs%PVO+pa!?2KX@*CD&Ts2G!SWDOzG8R9WyoF7X(Pr{BwkSD8kX?)n3=CDQ
z;22uTbc?mPB(bRE7ISuL<z!cOeWsU;lgrq>mBm30XDoua3G6zM!)|fe<YX2@g4<y7
zGj>}gWsr#=SKZ?B%u7kFa4jmzFS^B+SWu9fmvW0aCpB-f9fx@REw18%oXiq%deh{A
z1OX_;-eN4i#h4kzk(iSMik0G9j9Irh;n8!8xul}x7IRT*T9G=)JuF2f6(vP_AS=O6
z0uvy26@kJ+5)=*~Nd`tPMixdECJ9CkMkYoMMjpn=w>bm^xfn$l`546*`53jB!5Svc
zld3mj0EJsIM+rj{V+~^plO%%+L##|Ka|t6TFGECXm?c4JlNp?k1!_Qfmc`HQ7GGX!
zImpq_tfR>YOL2UT#l@*bpo{_z4R9iW#``Un%)GRGu)-o)1_lOb3WIy(79S{?!ULe#
z0^}!9Krw**A;nnaFnKED4gMl{OctpyFfdGRW>Tsz5(5Q{4g&*&n<nEej_lM_P#hF%
zvK7H2smK7N1eE)VKprnL1!WOlNOXXl11Vm>$r6;zi_AdE%|QgnAw`xTmK6g7LljeL
z5hNaLKtf>W^MgrnY=Ba|-Q)mf{dy3~Pm?i3lc@-lo{L057BYr_L>NOfxo(LS=VcZY
zq!#Jr<R_-Y!^@W<CQx+q!6j4E6O${8K$#3&%z*P8I75KrvB&}B2#{4s$rbDxRgiOT
haoFVMr<CTT+JRDjG00;)j6BR-oLp>NtQ_)OYyg^nYt;Y%

delta 1315
zcmX>lI#rl2l$V!_fq{Wx^Bd#DxttUEWEg!WYRi}krm&>2wlGGqqzI+3rLea!MzN*{
zr*Nfkw=hPrrHG{Pr0}*dMzN>xrSP{fL~*1D1T$!gPHeNO*J5B`s9{WDlw@#Wh?S{j
zE@7x)s9}bP)G$jj)G(zm^|I756mrxs1T$zd`$h5PrIyDRrKY78rRF847HcxzVk<5w
z%1kcNWV|JkmRS*BoSB!NlZsHH$#RP|Co?a#_!diMURr(;3j+hgE#~Chl$8ucjGUAA
zFxo2cf%GBF1gR)y19_8?hf#{Lh<kDZ#|^Ptj9f*G3=9k_nQpNbmn0UI++xm7t(@%6
zsZ@W9GcPkaH77ACHRmNriJK<lEspHe)PmH!lwwV`TP#`mnR!J_Ad9&?^HNePT#JhG
zi*B(N6lLa>++xm2&AY`_T#%Dl0(Pe+ZxP7yA`Xyx=ETwph?BVx4!p%!e2X#j7Gu^e
zPLQAuI4Ev0msFHQF{KvWVl2AFQdCk=QpCx?zyKjYkygaYz`(#c`8%h+Fo^YwH72hp
zHSHE#Mru(`V(DZjrqp^p1_p*qh8l)gwHT&a##*Kt#uSDW#u}y+21y2Sh7=}oh7J(T
zEY6V0IGL%CC73~zrAUB*fuV{mCONYtHM)u^w)z%hE!a{`=37j92De!95_3~;F_x`l
zyv3H3nN*aT29_-XIq4RcO-g2RNpgN}ft@k~!(={Y(|QSzqd|TLds~y~7HeinYHl&u
z^_pyupaH45#h#p>o12)IQl!Daz!1ffl2}@Ciz&wlV!ArW6tETipvX-ut%xr!NKMX6
z%u!-sV1UN17^47V5y;QU%%Io?<H?7a9l*)5h=+lJL6aG5Z;>d-IAM?g3&I6p2Nvmq
zq)<cp7CY2VkSm~e2{7_87U?rEFeHQ00oW=A1_oXR1_n@MJA)kM!N|an!nlB;W^z5t
zUcMC0TAmuF1*|1(3mJ=_Om<^cWOSIE!5SqBau+xyR<VKuy$EE;<Oi(!Ohtl|1=+k+
zRX{G12N7t_;<CxfEQW-(>*RViTWOGw!0EC`1eDm=5(_{{wn&VDfnoAJHu3r*agdiG
z=@A@zC8-rfQXrG1L1E63n3Ds_XvIY`ATe1GAqO&u85GL~Ag%(40J$ZKIk}(+5;tI1
zf#Ze?6i!K*NhPTjI-n2$X<=aEVq{@tVUl3vn4HTlUeChF#VEqa$0)|g$Ed|zWW&I~
z;HSwL0zynhiXh`bF$&^x-V!X%%Pc5JEz(QQEJ-ZM%+D(Z`z}fZCJv?Ja}zW3ia?QG
z#0@e5lpnwe0USeMJ77-LM$SUFIBatBQ%ZAE?LgVQ7!(scj66(StXz^@tX!-B^f)g@

diff --git a/src/snipper/__pycache__/fix_o.cpython-38.pyc b/src/snipper/__pycache__/fix_o.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3ea6cd8ef8b3a3776ae9e2d534579277d4ab91b8
GIT binary patch
literal 1387
zcmWIL<>g{vU|=|Q!6dPhm4V?gh=Yuo7#J8F7#J9ebr={JQW#Pga~Pr^G-DKF3PTE0
z4pT036mu?16bmCm3Udle3qurZ3S%&XChJR(IewZ<x7afCQd09uZt*7N<R@px7Zl|u
zrxq6{GlS%zSb%|n0pt*8kX2la3=AoZDNHR4wais2B@8tTDa<8|Sxhy|HB2ciy-X>r
zz05HzwJf!)wQRNQ;S70hEDR;g*<3|Mj109Lj0{y8B`hgyHH^(nj0`0#DeTRRV47nA
zYYoFfMi8%tqlqz`!IU9|p_ZeLBZ484A&)77p@ww=V-Z^kTNe8QjvB^=j4@2LoV8pv
zoGF~*3^iQh47J=~InEmHg^WdON?203KxXAdm2lN?r*Nn6r117K_lwo?)bK3eP664*
zvXF5hBO?RIra*=uh6sifz8Y?EhFabf{uG8Bo?5;dzAWAv-V}ip!Ct0X{t}iNevpYJ
zYzz26b}%xeFa$Gb3i&0oLW2oJaWXJ4urV+&M1z7VkAZ;!96*ec49$$SY&9%3%qa}n
zoJDdeOf}5n40%i`%;F3wEaD8c?CA`(95oy@Y$>eb3^i;iY&Gn&8B*BiGK({$Gnqr=
z7$7v*L=KRNAg`x0LPS#-(wKr7G`akW7#SECZZXE+VyI%#E2$`{;>ye|$S*2UD6TB7
z5-zSR)+;Va$uBKYuvN$}NX^qwuVPo%QBW^e*L?Z^|NsA0(kMzmocMT%j`(;@#v)LX
z)8xFxnv<EAT6~MUxFoTtBtEsGq$u$gXKG#wl*yb}RC0?gzqF*FwB#0Bc6nk^dhso$
z%#>R!`K2Xkx0rH_Rx%WUlGQI0XRDad;?$zzn3B?r)EJli<kH;KyprOW;=Ig)g4Cjz
z;-X|YJ1w&!K3}h(@)jo~v8I*gaexAv4;1u_Jd84oEQ~UY986-2RT4#|dGYyrHaYpp
zi8;k~dT<R@%*u-Snv6x<3=9mKOt+Xz64Q%>7#J9;xSSGG6w)$tQmquKBs~?%6N?p+
zOG`>J^U@VcGEx<k74sEJ64P%nazzQp2Zj2@`-g@EgoeaBI|hV=2Dw&=fV3*4<(KBA
zDCCyrCgr5+>FM2KEU#iMElJb0&}6*Dk(!sBpOTrEUd3KeS(1^TrvQ$t5KYEgti>6r
zIXRmAMWAeVi!-e>FS#T?Kd1N>dqHARNoHcsEl$^p<kW(a%>2AttOZ4xc_p`4vhp+Y
zZZYK--(o39EXlaVQCyIdS&~{&a*HjsBD1)p_!bK&f^V^w7iE^D-r_1QO@e0bD4yhu
z)a2}VSo{>F=H{2BY6=vwgOUyl$Rpt30f);iHgHrM-C|G4Oi9bkOS#3G3X1L`7La1b
z)LTqx1-F<|E220+`r?a9^KLPw-C|D8O({|at0)FXG=vZYiLipB24q*U1~}q4IGGq#
z7zG%)7&#dE7{!>_7zG%47<m}Em;@N57&$<qOdO0w`k)wNE0SPfU?`FW8N>%oBYHWh
t>50je;Is)2L9kMYji5vZVS(-Du*uC&Da}c>1LcxpP)_Aw<X{qD1^}`UX}tgd

literal 0
HcmV?d00001

diff --git a/src/snipper/__pycache__/fix_s.cpython-38.pyc b/src/snipper/__pycache__/fix_s.cpython-38.pyc
index b161b2c89e36fa9e9f5a4b97990c7c3ba4833196..b0366cef21b20d77bc837f78f88a9f18d9d97a4b 100644
GIT binary patch
delta 713
zcmbOr`+|!vl$V!_fq{XcWQ$2+I_pF}nff{g28I-d6viBeT*fFyMi84Rhbf9Fg&~DG
zhdGxeiiMFOg(Zcxg&~SHg)N1>g&~S9g(HeRl_P~So2jTOl{J-p0p~)7X2vM4RIUZw
z3mIG(Vl`rzqIjZsQ~6T3QhA!07#ULeQn(lJr}8djY-R-WctCVvK#Dd~FoP!VOOTs1
z8E<i?q^2d7=9HvlCYShWGT!1%%E?d8j?XMfElMm&o&1e+2HP!`yu{qp$&<P4WNxv7
zrB^a&GT&m-Gq}Z=e2X!sh>d}Pp@?nrCPphBE}NXp;*#Y2+yXn^$$z;lGnp9}7;dp8
z78IoBrQBl8EJ@8R)?~ZInv<EAS{%g&Hm$gb1FR^&w4|W4q=*H?VM@-28VfQT6o9u_
z(^E_0i$Qi3^MM@C#KFkND8k6XD8MMfSR^!gF83w*TZ~-481-NN{r~@e5hKVP#`r2`
zy@JYHjOCi#MM9G&@W|AIG~Z&$%FoQZ#gbo;ns<vMDX};e<i%UeIjMQKSj&qtOHwsC
ziugeWa6w!ZpORU0i!&`VCpEqxu_WUbdvbnWNormR*tJniIXSnO^Gi!^F{Yurnyomo
zEH%DZfPsObSP10o$y&TZjB1l@d4qj~85kI<xNPA-Q{WbNa(+%uYH~?teqM1A6Ugrp
z3=9lWqQ!Zc1qG=^df)(yFGwsZ&df_M0tIdn$kZaW$=rN$5g=QN!2V;*zQtH}i?yIA
zGq0pb24oH>;Lsh%VUwGmQks)$2MViVF$M+(9!3sE9%c?M4sI4+4rU%k0Y)xHK1Kk<
CzPbwl

literal 3728
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

diff --git a/src/snipper/__pycache__/legacy.cpython-38.pyc b/src/snipper/__pycache__/legacy.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ca245802a659eb097945ed2488813d2fc128f72b
GIT binary patch
literal 1790
zcmWIL<>g{vU|>+bV3Nqn$-wX!#6iYP3=9ko3=9m#3JeSkDGVu$Eeuf%DNIp}Da<J>
zEeugiDXb}MEeui2DeS=vnjFcDNSZ-<Sr`}?oMHM)7-|@r8A0R%#)S;cj1mmBj5Q1?
z3^k0cOp*-244RC7noPHtb5iqevE>w(6lE4@GTma#xy4wvlA(x|fq~(dsk2o~XmM&$
zaZE{RMrw>pesXDUYF<fkOmSXjK|yL!OmR^%oSl=Jo|s&zS5SG2Ei*4AHLnEZxMGlt
z7#Kwui`W?$7^;|+l$1~$4U%SqIl6~|fgv62$OQ}~j0+iSnQE9)7_(W6T51?TA~j4U
zOeKuXjN%LnnNpa<8ETpHm<n5Jm{S<D8H$`rm{XXW8Jieu7#FbAFw`*BFoV3gkdcuA
z>}e(tuZE$9IfVhl5@)DoC}FB$Y-UVh$z~~HDPc`vtzl|rVq_>}sbQ>PNMj0S&}8#_
z2@2qs%pkXmCFkdYe6LWFn68kQU!stllV6;g@)8uIRiZihdFcvJ6~zjfc?xNnIjNd#
zw^-6L^HOfHJNx_ky849_fx_e#r)x!WYC%b6e%>v%#Dap<yp&t41x1;8C7LX^7>lD=
zlJj$mZ!u=xV$1?Z1B3vD(k<3>kQ^r{h9y8QV`O3CV&q_yVq#+CVB}yFVw7OyVdP;f
z5@ujvNCvqYqzHtC7#J8p+Q5k;jER9Eg|U`7g{hV$ouQUBouQU3ouQV!h8dJtni;bh
zCNLFwfx=3Xp_ZeDV*z6gC^k52I6<*7fvLz0B38qh!VHcJ#%z|Nh#KZvuDpm6rW$6D
zXbMX+lM6$vM=e(k7t~bNq8TO3DXgH_S;*MT$jDH_oWfSa2nzEO))aOStBJ9Op@vJ6
z0b(P_wxTpfhQbYnX&~3saDhw)#a=CU4RZ}wHq!*gA_0hw8cqnkfDPnUkeUVT3mIy8
zAfgZwB3Hryigj@YNIC$k;?1)HnJ>vu!-*tHq~03#1spZp;B>~bfHQ?-A!99H2}2EE
zGh+&KHsb`wqJk8LJb@a%6lO_=1)M3I3mH=wB^he@Q#co})PQt=M4+j1A!9914L3+W
zg`tKM<O>kbhM|V5hB=#M0%Os&8txP>Nl+#R(~xk2s^hW&rF!lfo*Ld7esG!x=Kzr3
zLE#4RSqgVATMSdJK&@a6YmI<8LoI6!+X9XnL9qM5;akg`!c)tV!dt_e%{GCl$RmYm
z0#mU^30D(ip-2tu0*)FEuv+F6W^;yGW{_A7OAT8Mdm2kHgC?I}5eEYUgWF3`LeCUX
zXJEL+$W^6MmReM)kd&CBkeZjGo0FNBs*t5no{^c8s*sjhk(rkc%2QRMPKhZBU`b@D
zUyQcD7!_Xr|NsBLCfhAmkbLni?&6ZfqLTR3ijtzlTb!wRDNrVJVo}L0mW<TIlv^w%
ziJ3VeRZNOWn%qSo*A#IxFfiO=ElSKwPc7mHv01Y6GxLggK}^;na6V-P7lTE7V4>oI
zoXnD2e2&G%sYRg7>RMEkU!*BiBngsbE=f$k#hH|opPU_^R+?8N$iTo5#h#Lx0yc*Y
z>`bF5sDk{`l3Q%ar6u{LB}JfId5bBfq6m~FqgV@)@>42{q!<_&iljkCu$1H$#NT30
zEJ}}J%LAKoixuomNGSj+mW#ke0WZYvf};H7)Z${00mVU}oX*GshkT42j9iRdj3SI|
zOhSx2jC^385F;Ct03#Qp9HR!42%{PkNQDZc1d|9zj7bNqhl7!Yk&BTBB*#>w!@$7c
rr^x~?!Hal6E(H}YU|}RjAza2`lbfGXnv-e=3iV=;V>wt^m^lOiTj8Qs

literal 0
HcmV?d00001

diff --git a/src/snipper/__pycache__/load_citations.cpython-38.pyc b/src/snipper/__pycache__/load_citations.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e79c0857a12b2136f7aa6dcb235a3dc9c4293688
GIT binary patch
literal 4979
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
VHTys<ULHms77ld|4=#QVcL0osoqqrT

literal 0
HcmV?d00001

diff --git a/src/snipper/__pycache__/snip_dir.cpython-38.pyc b/src/snipper/__pycache__/snip_dir.cpython-38.pyc
index 50eb77d4a6c15593ccc6bfb963a021aa51a4b489..a8205b9d82839835b55f286b4d28b2c5c8467e71 100644
GIT binary patch
delta 1407
zcmdnRzg<8(l$V!_fq{WR@0dwqA|C_8V-N=!voJ6)I503U6uV8-HW6e<Va#EVVozaD
zVNGFcVT|IKn4wzFhNNDSfq{XWfq{V;q@{|9fuV*ug&~`%NUVe*g&~C@ogsy>m${a?
zh6OCDl+IAgQo@+Uw1ByWaUo-|MG4~q77&Y(0V>M0kg?bgEXuTy5h}`B!?cjGmI<ta
zwT7X7A!98>IV(tOEhAWht%jk7aUoMtM+tihQ!`@|V-0K3v=WX5oFFwIgJ2fbFxG<9
zvZOH2VX9>>;YwktVNYR|WSGs6!dAmJn_(_XGt6SJBa7}JOaZH`XQ<^U;aI?3!vV68
zk)ecV0dERB*tL8m{56ctj0*%(I2JNCGuCpZGt_d`aJn$WI@NN6ohb+=g=)A#dKWTw
zGPE<KF{W^)aJ6vMu(&WZGuHCda4it7;Vu!W;b~^%VMqgq!vw}ckreJ)-Wo0!hWgk&
zF-*05wftbCL~HmKGEQJDPACzp;cI4GAfCbl=66kCEKC5afLIAtSG1^xFOLf>E&<ZH
zkg-;vhJONMQ9?RH3U3PE9Hv^qOom#abcR~tOom#K6#iP#6#iPV63H6A8o@NC8nK#s
zrW(;2VUX`@m{SDiu-Ax8XX<0D6|WIb;m&56z*Hnu!c`+an;}K8hHo~*TxL*k*6`Md
zn={n%f*b|%Lu^nCQ>_Hl3#>H~3mI!AYWOEG6)S<ACIu3iz*H1g!ni;h#Aam3lL5<!
z)<{^S2#GT+WSqcMqy&x`2~f~aU@BCq;SFZc6!z0(zQvqaT5*dlDKn`gwc-{>a(-@Z
zVqQw|WM<}gX?6w%hAI{XT|0&JSu;W4q<s~emX^Mjp4Q|hW;M1Fh6M~A43pO}D{(R2
zVl6Jn$t)@2n0%kvgVA)d28$MJ5hDWw!{iv2em+h1TbxCudGTqPIjO}_lmD?;sommC
zN-R!|FGwuOxW!eJnwDCWnwOkfT*YLk@QX1<Q|1;+N@jA&WJgvffhe}3+>)Zy)LX0t
zMVWaeQIjXLDzZhfr03)(P2SHMS}z&JRh(a1l$;u$l35hRk&;?m0%G0b$}cS`C<U{N
zL>L$tqS#X_l5<K^QlmtZb5axY;z24i^Abxk^YcI&qL}kbOQM)E%8Nigk7CLxj^av8
zPEIW-NleN~y~UVwi!t{WW8N*sv?w-+cob_|e9Gi@Hi3E}1_p*(Y}w_BMd`&wf(#4{
zMFJojS@McfbEDXca=~6N;s8nTfCxU2dXD0}%mR?jAo1cFP+7so!N|wN!N|hI!^p+R
z!^p+N!w7<Wj2uiXj9iRd%q)ydj7<O8m?gln93XW}LX7n+j2w(&j6#eOtSl@%jB<=D
zjB1Q*oLr17a3}!M$jJ1Ug@x%48!H#15XfLA9!54sK1LoUAx1u?B2xwi22B<}Kfe%7
z&LVM;Gvz>@5CJ)}Ahk#jO2_9WX66+!fqcLYiocx9B;O)XsaB)_(!&WNKt@5l3-TL;
j1@W^@ZhlH>PO2R!aTJ4sO#tK&Mh->}Rt81}kmw%(I2ctm

delta 1257
zcmdlku!~<il$V!_fq{WxwYzSj0zU)8V-N=!GczzSI503U6x&VIHsNGXVNGFcVT@v*
zSfE<Zf}~D@fq{XOfq?;}yf}=BfuV*eg&~`%h$o$)mZ^jxi*W%{4dX(_Vx<y>1<W88
zBLi5JrG{Z4V=au$xR9}y5iHJH!%)Mxkf|u3ge`@!nX!qnhPf!Ngna=AOz#5bdI+<I
zv6iI<WF6BSrdrk#&J^Yv))W>=hS>}$tTimN8RoJyGeRw6s$p5kShNIe49h}BMh1w=
zTDB7Q1za_3H7pC67#T{q7x1L8fn-Z~OZaM7ni&`Hr?4+%Y-X%wPiLs*Na09f$Pwsd
zsHtanVTg6A<pjG|5KIcyaDoh3$k@r)&d|=7#+1UD!qvi2!{oxy%vj4+!?8fPhO<PZ
zhO3#8hars#WJ%$Z6z+7!TJ98%TAmsX7lznFF-*0*wR~XnL~D2#GEQJDHY*XU;caGI
zAfCbl<|j;GEHtYJD}h)HRajI}!<)wi7MB2NUC3C=U&A+nvB)f)A%!=EZw^zfKqf=2
zU^+vsP$omIa0-8|ND6<gXo+MEZ;e2WU>b9cXbpD?LyABvlO#ipNR3bpTZ-Tu)*9jI
zOnr>CVl`qZ9N8=r7>nMOaMsj|&1Ogus^Oi@Fqat=#5FuMV&)9BJRrA$eG(MIR4Wek
z2}_OmLdIHgkYkGffgLCX5}CkMWK_biKpMnmWXO{N%ZS#9rwEHPfP7l?4;)$Ippcrt
zSop7oCzwG~#IH&zIKOnVFLRUvC=FJzDCpWLq|cfO0w?XO*tE3twe+-#7#SECCLdx}
zW9wj8z|g@s`5m(oKT{DK0|Ub?*5ZPk%#tG3$x<vHj5?E(S+uySIP~=MOG^q$OD0cZ
z=@)(p(yhsQi?gUSFFq|ZC$;$2WPMgE&MGE5g<p&@nlh97S)BxKu@&W(6s4x#Vl61j
z%qzJy`5~(!_brz6octuPMUy$$LKP)$aTVv67A2>~r(_o0;z&s?E&;RHQ!A2lN>fsA
zP3~tCGq}Z^Us@8ylu=#;^3yG*oZ=|1#N_1Ef|A6foYY&4Iky;di}*o~XUx0Bn09OO
z1vZ&_K@guUyF9Tdy|_q#fq|ijkAZ<9iY2coH8+aAC>QMVB36(DD0dcdgVb{r=Vcav
zTmZ`X#aW<S%*esW!pOtO#mK|R!^j8baWQf+voJC-GW};`l>o^xaWL^Paxn=pvM_Qm
zaxjW9iZIrTv9d9;u<$U-F|shKF|u)TF|xp+1|t`v5Xe9#9!54sK1LoUAx1vlA}a<4
z22Ccv5KWFEVUW9|Kn~^yIjJDENDoREF@YS)UXWOlk&~HJ1S(aE<Up!Hx*`4nc}f++
eg!sxPH$SB`C)ExVam5@A3=9IyJWM={9LxY$x++Nk

diff --git a/src/snipper/__pycache__/snipper_main.cpython-38.pyc b/src/snipper/__pycache__/snipper_main.cpython-38.pyc
index 6a50df2c7fb13fcde076d5ddf2d54c8687e166e5..21d84830317e97a60e1ba13d898e5f34d4cfb140 100644
GIT binary patch
delta 3023
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

literal 10073
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
Bo__!U

diff --git a/src/snipper/block_parsing.py b/src/snipper/block_parsing.py
index 0b1009c..a386989 100644
--- a/src/snipper/block_parsing.py
+++ b/src/snipper/block_parsing.py
@@ -1,3 +1,7 @@
+"""
+Module for new-style block parsing. Make sure all functions are up-to-date and used.
+"""
+
 def f2(lines, tag, i=0, j=0):
     for k in range(i, len(lines)):
         index = lines[k].find(tag, j if k == i else 0)
@@ -26,10 +30,15 @@ def block_split(lines, tag):
     i, j = f2(lines, tag)
 
     def get_tag_args(line):
+        line = line.strip()
         k = line.find(" ")
-        tag_args = (line[:k + 1] if k >= 0 else line)[len(tag):]
+        tag_args = ((line[:k + 1] if k >= 0 else line)[len(tag):] ).strip()
+
         if len(tag_args) == 0:
             return {'': ''}  # No name.
+
+        # print("TAG ARGS")
+        # print(tag_args)
         tag_args = dict([t.split("=") for t in tag_args.split(";")])
         return tag_args
 
diff --git a/src/snipper/fix_bf.py b/src/snipper/fix_bf.py
index e69de29..36ac1ce 100644
--- a/src/snipper/fix_bf.py
+++ b/src/snipper/fix_bf.py
@@ -0,0 +1,67 @@
+import functools
+
+from snipper.legacy import indent, gcoms, block_process
+
+
+def fix_f(lines, debug):
+    lines2 = []
+    i = 0
+    while i < len(lines):
+        l = lines[i]
+        dx = l.find("#!f")
+        if dx >= 0:
+            l_head = l[dx+3:].strip()
+            l = l[:dx]
+            lines2.append(l)
+            id = indent(lines[i+1])
+            for j in range(i+1, 10000):
+                jid = len( indent(lines[j]) )
+                if  j+1 == len(lines) or ( jid < len(id) and len(lines[j].strip() ) > 0):
+                    break
+
+            if len(lines[j-1].strip()) == 0:
+                j = j - 1
+            funbody = "\n".join( lines[i+1:j] )
+            if i == j:
+                raise Exception("Empty function body")
+            i = j
+            comments, funrem = gcoms(funbody)
+            comments = [id + c for c in comments]
+            if len(comments) > 0:
+                lines2 += comments[0].split("\n")
+            # lines2 += [id+"#!b"]
+            f = [id + l.strip() for l in funrem.splitlines()]
+            f[0] = f[0] + "#!b"
+
+            # lines2 += (id+funrem.strip()).split("\n")
+            errm = l_head if len(l_head) > 0 else "Implement function body"
+            f[-1] = f[-1] + f' #!b {errm}'
+            lines2 += f
+            # lines2 += [f'{id}#!b {errm}']
+
+        else:
+            lines2.append(l)
+            i += 1
+    return lines2
+
+
+def fix_b2(lines, keep=False):
+    stats = {'n': 0}
+    def block_fun(lines, start_extra, end_extra, art, stats=None, **kwargs):
+        id = indent(lines[0])
+        lines = lines[1:] if len(lines[0].strip()) == 0 else lines
+        lines = lines[:-1] if len(lines[-1].strip()) == 0 else lines
+        cc = len(lines)
+        ee = end_extra.strip()
+        if len(ee) >= 2 and ee[0] == '"':
+            ee = ee[1:-1]
+        start_extra = start_extra.strip()
+        if keep:
+            l2 = ['GARBAGE'] * cc
+        else:
+            l2 = ([id+start_extra] if len(start_extra) > 0 else []) + [id + f"# TODO: {cc} lines missing.", id+f'raise NotImplementedError("{ee}")']
+
+        stats['n'] += cc
+        return l2, cc
+    lines2, _, _, cutout = block_process(lines, tag="#!b", block_fun=functools.partial(block_fun, stats=stats))
+    return lines2, stats['n'], cutout
\ No newline at end of file
diff --git a/src/snipper/fix_cite.py b/src/snipper/fix_cite.py
index 7fbc1b4..ad5b5ee 100644
--- a/src/snipper/fix_cite.py
+++ b/src/snipper/fix_cite.py
@@ -1,14 +1,19 @@
 from snipper.load_citations import find_tex_cite
-from snipper.snipper_main import COMMENT
+from snipper.legacy import COMMENT
 
 
-def fix_citations():
-    # This should be the master function.
-    pass
+def fix_citations(lines, references, strict=True):
+    lines = fix_aux(lines, aux=references.get('aux', {}) )
+    for cm in references.get('commands', []):
+        lines = fix_aux_special(lines, aux=cm['aux'], command=cm['command'], output=cm['output'])
+
+    lines = fix_bibtex(lines, bibtex=references.get('bibtex', {}))
+    return lines
 
 
-def fix_aux_special(lines, aux, command='\\nref', bibref='herlau'):
-    daux = {name: {'nicelabel': f'\\cite[' + v["nicelabel"] + ']{' + bibref + "}"} for name, v in aux.items()}
+def fix_aux_special(lines, aux, command='\\nref', output='\cite[%s]{my_bibtex_entry}'):
+    # out = output %
+    daux = {name: {'nicelabel': output % v['nicelabel'] } for name, v in aux.items()}
     l2 = fix_single_reference(lines, aux=daux, cmd=command, strict=True)
     return l2
 
@@ -18,7 +23,6 @@ def fix_aux(lines, aux, strict=True):
     return l2
 
 def fix_bibtex(lines, bibtex):
-    # lines = fix_references(lines, info, strict=strict)
     s = "\n".join(lines)
     i = 0
     all_refs = []
@@ -37,7 +41,6 @@ def fix_bibtex(lines, bibtex):
         s = s[:i] + rtxt + s[j+1:]
         i = i + len(rtxt)
 
-    cpr = ""
     if not s.startswith(COMMENT):
         s = f"{COMMENT}\n{COMMENT}\n" + s
     if len(all_refs) > 0:
@@ -51,6 +54,7 @@ def fix_bibtex(lines, bibtex):
 
 
 def fix_references(lines, info, strict=True):
+    assert False
     for cmd in info['new_references']:
         lines = fix_single_reference(lines, cmd, info['new_references'][cmd], strict=strict)
     return lines
diff --git a/src/snipper/fix_i.py b/src/snipper/fix_i.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/snipper/fix_o.py b/src/snipper/fix_o.py
new file mode 100644
index 0000000..5caf0ac
--- /dev/null
+++ b/src/snipper/fix_o.py
@@ -0,0 +1,38 @@
+import functools
+import os
+
+from snipper.legacy import indent, block_process
+
+
+def run_o(lines, file, output):
+    def block_fun(lines, start_extra, end_extra, art, output, **kwargs):
+        id = indent(lines[0])
+        outf = output + ("_" + art if art is not None else "") + ".txt"
+        l2 = []
+        l2 += [id + "import sys", id + f"sys.stdout = open('{outf}', 'w')"]
+        l2 += lines
+        # l2 += [indent(lines[-1]) + "sys.stdout.close()"]
+        l2 += [indent(lines[-1]) + "sys.stdout = sys.__stdout__"]
+        return l2, None
+    try:
+        lines2, didfind, extra, _ = block_process(lines, tag="#!o", block_fun=functools.partial(block_fun, output=output) )
+    except Exception as e:
+        print("Bad file: ", file)
+        print("I was cutting the #!o tag")
+        print("\n".join( lines) )
+        raise(e)
+
+    if didfind:
+        fp, ex = os.path.splitext(file)
+        file_run = fp + "_RUN_OUTPUT_CAPTURE" +ex
+        if os.path.exists(file_run):
+            print("file found mumble...")
+        else:
+            with open(file_run, 'w', encoding="utf-8") as f:
+                f.write("\n".join(lines2) )
+            cmd = "python " + file_run
+            import subprocess
+            s = subprocess.check_output(cmd, shell=True)
+            # s,ok = execute_command(cmd.split(), shell=True)
+            print(s)
+            os.remove(file_run)
\ No newline at end of file
diff --git a/src/snipper/legacy.py b/src/snipper/legacy.py
new file mode 100644
index 0000000..c122039
--- /dev/null
+++ b/src/snipper/legacy.py
@@ -0,0 +1,75 @@
+def indent(l):
+    v = len(l) - len(l.lstrip())
+    return l[:v]
+
+
+COMMENT = '"""'
+
+
+def gcoms(s):
+    coms = []
+    while True:
+        i = s.find(COMMENT)
+        if i >= 0:
+            j = s.find(COMMENT, i+len(COMMENT))+3
+        else:
+            break
+        if j < 0:
+            raise Exception("comment tag not closed")
+        coms.append(s[i:j])
+        s = s[:i] + s[j:]
+        if len(coms) > 10:
+            print("long comments in file", i)
+    return coms, s
+
+
+def block_process(lines, tag, block_fun):
+    i = 0
+    didfind = False
+    lines2 = []
+    block_out = []
+    cutout = []
+    while i < len(lines):
+        l = lines[i]
+        dx = l.find(tag)
+        if dx >= 0:
+            if l.find(tag, dx+1) > 0:
+                j = i
+            else:
+                for j in range(i + 1, 10000):
+                    if j >= len(lines):
+                        print("\n".join(lines))
+                        print("very bad end-line j while fixing tag", tag)
+                        raise Exception("Bad line while fixing", tag)
+                    if lines[j].find(tag) >= 0:
+                        break
+
+            pbody = lines[i:j+1]
+            if i == j:
+                start_extra = lines[j][dx:lines[j].rfind(tag)].strip()
+                end_extra = lines[j][lines[j].rfind(tag) + len(tag):].strip()
+            else:
+                start_extra = lines[i][dx:].strip()
+                end_extra = lines[j][lines[j].rfind(tag) + len(tag):].strip()
+
+            cutout.append(pbody)
+            tmp_ = start_extra.split("=")
+            arg = None if len(tmp_) <= 1 else tmp_[1].split(" ")[0]
+            start_extra = ' '.join(start_extra.split(" ")[1:] )
+
+            pbody[0] = pbody[0][:dx]
+            if j > i:
+                pbody[-1] = pbody[-1][:pbody[-1].find(tag)]
+
+            nlines, extra = block_fun(lines=pbody, start_extra=start_extra, end_extra=end_extra, art=arg, head=lines[:i], tail=lines[j+1:])
+            lines2 += nlines
+            block_out.append(extra)
+            i = j+1
+            didfind = True
+            if "!b" in end_extra:
+                assert(False)
+        else:
+            lines2.append(l)
+            i += 1
+
+    return lines2, didfind, block_out, cutout
\ No newline at end of file
diff --git a/src/snipper/snip_dir.py b/src/snipper/snip_dir.py
index 15657af..6032800 100644
--- a/src/snipper/snip_dir.py
+++ b/src/snipper/snip_dir.py
@@ -16,41 +16,46 @@ def snip_dir(source_dir,  # Sources
 
     if exclude == None:
         exclude = []
+
     if not os.path.exists(dest_dir):
         os.makedirs(dest_dir)
+    if not os.path.exists(output_dir):
+        os.makedirs(output_dir)
+
+    output_dir = os.path.abspath(output_dir)
     source_dir = os.path.abspath(source_dir)
     dest_dir = os.path.abspath(dest_dir)
     if os.path.samefile( source_dir, dest_dir):
         raise Exception("Source and destination is the same")
+
     if clean_destination_dir:
         shutil.rmtree(dest_dir)
     os.makedirs(dest_dir)
-    # Now the destination dir is set up.
+
 
     out = dest_dir
     hw = {'base': source_dir,
           'exclusion': exclude}
 
     print(f"[snipper] Synchronizing directories: {hw['base']} -> {out}")
-    if os.path.exists(out):
-        shutil.rmtree(out)
+    if os.path.exists(dest_dir):
+        shutil.rmtree(dest_dir)
 
     base = hw['base']
 
-    shutil.copytree(base, out)
+    shutil.copytree(base, dest_dir)
     time.sleep(0.2)
 
-    ls = list(Path(out).glob('**/*.*'))
+    ls = list(Path(dest_dir).glob('**/*.*'))
     acceptable = []
     for l in ls:
-        split = os.path.normpath(os.path.relpath(l, out))
+        split = os.path.normpath(os.path.relpath(l, dest_dir))
         m = [fnmatch.fnmatch(split, ex) for ex in exclude]
         acceptable.append( (l, not any(m) ))
 
     # print(acceptable)
     # now we have acceptable files in list.
-
-    run_out_dirs = ["./output"]
+    # run_out_dirs = ["./output"]
     n = 0
     # edirs = [os.path.join(out, f_) for f_ in hw['exclusion']]  # Exclude directories on exclude list (speed)
     # edirs = {os.path.normpath(os.path.dirname(f_) if not os.path.isdir(f_) else f_) for f_ in edirs}
@@ -74,7 +79,11 @@ def snip_dir(source_dir,  # Sources
             kwargs = {}
             cut_files = True
             run_files = True
-            nrem = censor_file(f, info, paths, run_files=run_files, run_out_dirs=run_out_dirs[:1], cut_files=cut_files, solution_list=solution_list, include_path_base=base, **kwargs)
+            nrem = censor_file(f, info, run_files=run_files, run_out_dirs=output_dir, cut_files=cut_files, solution_list=solution_list,
+                               include_path_base=base,
+                               base_path=dest_dir,
+                               references=references,
+                               **kwargs)
             if nrem > 0:
                 print(f"{nrem}> {f}")
             n += nrem
diff --git a/src/snipper/snipper_main.py b/src/snipper/snipper_main.py
index dc6bbdc..2425f10 100644
--- a/src/snipper/snipper_main.py
+++ b/src/snipper/snipper_main.py
@@ -3,11 +3,10 @@ import functools
 import textwrap
 import re
 # from snipper.fix_s import save_s
+from snipper.fix_bf import fix_f, fix_b2
+from snipper.fix_o import run_o
+from snipper.legacy import indent, block_process
 
-COMMENT = '"""'
-def indent(l):
-    v = len(l) - len(l.lstrip())
-    return l[:v]
 
 def fix_r(lines):
     for i,l in enumerate(lines):
@@ -15,21 +14,6 @@ def fix_r(lines):
             lines[i] = indent(l) + l[l.find("#!r") + 3:].lstrip()
     return lines
 
-def gcoms(s):
-    coms = []
-    while True:
-        i = s.find(COMMENT)
-        if i >= 0:
-            j = s.find(COMMENT, i+len(COMMENT))+3
-        else:
-            break
-        if j < 0:
-            raise Exception("comment tag not closed")
-        coms.append(s[i:j])
-        s = s[:i] + s[j:]
-        if len(coms) > 10:
-            print("long comments in file", i)
-    return coms, s
 
 def strip_tag(lines, tag):
     lines2 = []
@@ -43,57 +27,6 @@ def strip_tag(lines, tag):
             lines2.append(l)
     return lines2
 
-def block_process(lines, tag, block_fun):
-    i = 0
-    didfind = False
-    lines2 = []
-    block_out = []
-    cutout = []
-    while i < len(lines):
-        l = lines[i]
-        dx = l.find(tag)
-        if dx >= 0:
-            if l.find(tag, dx+1) > 0:
-                j = i
-            else:
-                for j in range(i + 1, 10000):
-                    if j >= len(lines):
-                        print("\n".join(lines))
-                        print("very bad end-line j while fixing tag", tag)
-                        raise Exception("Bad line while fixing", tag)
-                    if lines[j].find(tag) >= 0:
-                        break
-
-            pbody = lines[i:j+1]
-            if i == j:
-                start_extra = lines[j][dx:lines[j].rfind(tag)].strip()
-                end_extra = lines[j][lines[j].rfind(tag) + len(tag):].strip()
-            else:
-                start_extra = lines[i][dx:].strip()
-                end_extra = lines[j][lines[j].rfind(tag) + len(tag):].strip()
-
-            cutout.append(pbody)
-            tmp_ = start_extra.split("=")
-            arg = None if len(tmp_) <= 1 else tmp_[1].split(" ")[0]
-            start_extra = ' '.join(start_extra.split(" ")[1:] )
-
-            pbody[0] = pbody[0][:dx]
-            if j > i:
-                pbody[-1] = pbody[-1][:pbody[-1].find(tag)]
-
-            nlines, extra = block_fun(lines=pbody, start_extra=start_extra, end_extra=end_extra, art=arg, head=lines[:i], tail=lines[j+1:])
-            lines2 += nlines
-            block_out.append(extra)
-            i = j+1
-            didfind = True
-            if "!b" in end_extra:
-                assert(False)
-        else:
-            lines2.append(l)
-            i += 1
-
-    return lines2, didfind, block_out, cutout
-
 
 def rem_nonprintable_ctrl_chars(txt):
     """Remove non_printable ascii control characters """
@@ -203,102 +136,6 @@ def run_i(lines, file, output):
     return lines
 
 
-def run_o(lines, file, output):
-    def block_fun(lines, start_extra, end_extra, art, output, **kwargs):
-        id = indent(lines[0])
-        outf = output + ("_" + art if art is not None else "") + ".txt"
-        l2 = []
-        l2 += [id + "import sys", id + f"sys.stdout = open('{outf}', 'w')"]
-        l2 += lines
-        # l2 += [indent(lines[-1]) + "sys.stdout.close()"]
-        l2 += [indent(lines[-1]) + "sys.stdout = sys.__stdout__"]
-        return l2, None
-    try:
-        lines2, didfind, extra, _ = block_process(lines, tag="#!o", block_fun=functools.partial(block_fun, output=output) )
-    except Exception as e:
-        print("Bad file: ", file)
-        print("I was cutting the #!o tag")
-        print("\n".join( lines) )
-        raise(e)
-
-    if didfind:
-        fp, ex = os.path.splitext(file)
-        file_run = fp + "_RUN_OUTPUT_CAPTURE" +ex
-        if os.path.exists(file_run):
-            print("file found mumble...")
-        else:
-            with open(file_run, 'w', encoding="utf-8") as f:
-                f.write("\n".join(lines2) )
-            cmd = "python " + file_run
-
-            s,ok = execute_command(cmd.split(), shell=True)
-            print(s)
-            os.remove(file_run)
-
-def fix_f(lines, debug):
-    lines2 = []
-    i = 0
-    while i < len(lines):
-        l = lines[i]
-        dx = l.find("#!f")
-        if dx >= 0:
-            l_head = l[dx+3:].strip()
-            l = l[:dx]
-            lines2.append(l)
-            id = indent(lines[i+1])
-            for j in range(i+1, 10000):
-                jid = len( indent(lines[j]) )
-                if  j+1 == len(lines) or ( jid < len(id) and len(lines[j].strip() ) > 0):
-                    break
-
-            if len(lines[j-1].strip()) == 0:
-                j = j - 1
-            funbody = "\n".join( lines[i+1:j] )
-            if i == j:
-                raise Exception("Empty function body")
-            i = j
-            comments, funrem = gcoms(funbody)
-            comments = [id + c for c in comments]
-            if len(comments) > 0:
-                lines2 += comments[0].split("\n")
-            # lines2 += [id+"#!b"]
-            f = [id + l.strip() for l in funrem.splitlines()]
-            f[0] = f[0] + "#!b"
-
-            # lines2 += (id+funrem.strip()).split("\n")
-            errm = l_head if len(l_head) > 0 else "Implement function body"
-            f[-1] = f[-1] + f' #!b {errm}'
-            lines2 += f
-            # lines2 += [f'{id}#!b {errm}']
-
-        else:
-            lines2.append(l)
-            i += 1
-    return lines2
-
-def fix_b2(lines, keep=False):
-    stats = {'n': 0}
-    def block_fun(lines, start_extra, end_extra, art, stats=None, **kwargs):
-        id = indent(lines[0])
-        lines = lines[1:] if len(lines[0].strip()) == 0 else lines
-        lines = lines[:-1] if len(lines[-1].strip()) == 0 else lines
-        cc = len(lines)
-        ee = end_extra.strip()
-        if len(ee) >= 2 and ee[0] == '"':
-            ee = ee[1:-1]
-        start_extra = start_extra.strip()
-        if keep:
-            l2 = ['GARBAGE'] * cc
-        else:
-            l2 = ([id+start_extra] if len(start_extra) > 0 else []) + [id + f"# TODO: {cc} lines missing.", id+f'raise NotImplementedError("{ee}")']
-
-        stats['n'] += cc
-        return l2, cc
-    lines2, _, _, cutout = block_process(lines, tag="#!b", block_fun=functools.partial(block_fun, stats=stats))
-    return lines2, stats['n'], cutout
-
-
-
 def full_strip(lines, tags=None):
     if tags is None:
         tags = ["#!s", "#!o", "#!f", "#!b"]
@@ -315,10 +152,18 @@ def censor_code(lines, keep=True):
 
 
 
-def censor_file(file, info, paths, run_files=True, run_out_dirs=None, cut_files=True, solution_list=None,
+def censor_file(file, info, run_files=True, run_out_dirs=None, cut_files=True, solution_list=None,
                 censor_files=True,
+                base_path=None,
                 include_path_base=None,
-                strict=True):
+                strict=True,
+                references=None):
+
+    if references == None:
+        references = {}
+
+    from snipper.fix_cite import fix_citations
+
     dbug = False
     with open(file, 'r', encoding='utf8') as f:
         s = f.read()
@@ -330,8 +175,8 @@ def censor_file(file, info, paths, run_files=True, run_out_dirs=None, cut_files=
             lines[k] = l.replace("# !", "#!")
 
         try:
-            s = fix_cite(lines, info, strict=strict)
-            lines = s.split("\n")
+            lines = fix_citations(lines, references, strict=strict)
+            # lines = s.split("\n")
         except IndexError as e:
             print(e)
             print("Fuckup in file, cite/reference tag not found!>", file)
@@ -339,7 +184,7 @@ def censor_file(file, info, paths, run_files=True, run_out_dirs=None, cut_files=
 
         if run_files or cut_files:
             ofiles = []
-            for rod in run_out_dirs:
+            for rod in [run_out_dirs]:
                 # if not os.path.isdir(rod):
                 #     os.mkdir(rod)
                 ofiles.append(os.path.join(rod, os.path.basename(file).split(".")[0]) )
@@ -349,7 +194,9 @@ def censor_file(file, info, paths, run_files=True, run_out_dirs=None, cut_files=
                 run_o(lines, file=file, output=ofiles[0])
                 run_i(lines, file=file, output=ofiles[0])
             if cut_files:
-                save_s(lines, file=file, output=ofiles[0], include_path_base=include_path_base)  # save file snips to disk
+                from snipper.fix_s import save_s
+
+                save_s(lines, file_path=os.path.relpath(file, base_path), output_dir=run_out_dirs)  # save file snips to disk
         lines = full_strip(lines, ["#!s", "#!o", '#!i'])
 
         # lines = fix_c(lines)
-- 
GitLab