diff --git a/README.md b/README.md index c66b432..dc7f210 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,7 @@ -# trees-sorted +# tree(s) sort(ed) +Poster generator and web interface for a collection of images based on the tree sort algorithm. +In the folder `posters` a script to generate a collection of posters using graphviz. Install the requirements and run `posters/posters.py` to generate a collection of svg-files. -## Getting started - -To make it easy for you to get started with GitLab, here's a list of recommended next steps. - -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://gitlab.constantvzw.org/anais_berck/trees-sorted.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://gitlab.constantvzw.org/anais_berck/trees-sorted/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +In the folder `webinterface` a flask app generating an interface as accesible here: https://frart.algoliterarypublishing.net/treesort/ \ No newline at end of file diff --git a/posters/descriptions.py b/posters/descriptions.py new file mode 100644 index 0000000..a795900 --- /dev/null +++ b/posters/descriptions.py @@ -0,0 +1,182 @@ +descriptions = [ + ( + "images/20211019_151924.jpg", + "Two white people are sitting at a table typing on their computer keyboards under a roof window. On the table are cups, mandarines and water bottles; on the wall, black and white pictures of statues and people. The mood is studious.", + (147, 169, 183) + ), + ( + "images/20211019_162946.jpg", + "A tree is standing next to a lake, as if about to jump in it. On the ground, a mix of fallen leaves and grass. The weather is sunny and the ambiance is peaceful.", + (119, 115, 84) + ), + ( + "images/20211022_101225.jpg", + "Several tree branches form a canopy through which one can see the sky. The leaves go from translucent to opaque.", + (96, 102, 75) + ), + ( + "images/20211025_113835.jpg", + "A white person is standing between a desk and a blackboard, holding a mic while typing on a keyboard and is giving a presentation to an audience of white masked people.", + (62, 81, 88) + ), + ( + "images/20211025_113843.jpg", + "Masked students are sitting in an auditorium, they watch and listen. A white person is sitting in front. Large windows appear in the back of the students.", + (131, 114, 109) + ), + ( + "images/20211025_151107.jpg", + "An indigenous person talks in a microphone while a slide is shown in the back. The slide shows four indigenous people of different ages at the left, it mentions the word family tree at the left.", + (151, 150, 148) + ), + ( + "images/20211025_152322.jpg", + "A white person speaks in the microphone to two people sitting down at a desk in front of a white screen. One of them is from indigenous background, the other from hispanic descent. On the desk are two laptops. One is showing text. A white person with glasses looks at the scene.", + (50, 43, 37) + ), + ( + "images/20211025_172905.jpg", + "A white person with long grey hair speaks in the microphone. In the back is a projection screen showing a slide with text. The title of the slide is Nature-Culture.", + (252, 254, 253) + ), + ( + "images/20211026_145331.jpg", + "Three young people are touching trees in a forest. The tree in the middle is very large and is being hugged by one of the three people.", + (115, 125, 112) + ), + ( + "images/20211026_145339.jpg", + "Three young people are touching young beech trees in the forest. One person is bending down to a small sapling.", + (116, 123, 113) + ), + ( + "images/20211027_111356.jpg", + "Nine young people of mixed origin are standing in a room with naked walls. They take on specific positions in the room, forming a tree. In front stands a taller masked person with the back to the camera.", + (255, 255, 255) + ), + ( + "images/20211027_125357.jpg", + "A sunny image showing a clean swimming pool with black squares at the bottom of the water. People are sitting in small groups next to the swimmingpool, concentrated on something that lies between them.", + (88, 110, 112) + ), + ( + "images/20211027_125504.jpg", + "Nine people stand next to a swimmingpool. Two people are sitting. One person bends over next to them. It is a sunny day. They discuss a presentation on two white sheets that are lying on the tiles.", + (89, 87, 76) + ), + ( + "images/20211027_125747.jpg", + "On a sheet of paper about a dozen flowers without stems, varying in color. They cast a sharp, long shadow; the sun is bright and low. All but one flower is put in the top-half of the sheet.", + (182, 182, 184) + ), + ( + "images/20211027_130052.jpg", + "About a dozen thumbnail-sized rocks are laid in a straight line on the pavement. The light is bright and the rocks cast a sharp shadow. The rocks are similar in color but vary in shape. While the arrangement is deliberate the system is not clear.", + (255, 255, 255) + ), + ( + "images/20211027_130250.jpg", + "Thumbnail-sized rocks, mushrooms, a chestnut, leaves and flowers are laid out on a surface. The arrangement is careful and deliberate. It seems as they have been arranged in two arms or strings, the string on the left consists of brown, dried leaves and the one on the right contains the flowers. The stones and chestnut are put in the middle the two strings meet.", + (143, 132, 130) + ), + ( + "images/20211027_140938.jpg", + "A group of people is seen from the back, it seems they are entering a park. The weather is nice. Two trees in the foreground frame the picture and give the suggestion of an entrance.", + (253, 255, 254) + ), + ( + "images/20211027_152654.jpg", + "Six people stand in a clearing in a forest. They are seen on the back. The people look in the same direction, away from the camera, and do not seem to interact with each other.", + (126, 126, 124) + ), + ( + "images/Anais_berck-6.jpg", + "A small houseplant in a rustic pot. The plant has wires attached to it which lead to a chipboard which in turn is connected to a powerbank. In the foreground two laptops complete the contrast between the rigid shapes of the technology and the leaves of the plant.", + (225, 212, 196) + ), + ( + "images/forest_walk-11.jpg", + "A tree seen from the beneath along its trunk. In the bright light, the branches of the tree are reduced to dark shapes. The shape and dark color of the branches contrasts with the translucency and refined shapes of the leaves.", + (80, 93, 35) + ), + ( + "images/forest_walk-6.jpg", + "A forest, two people, seen from the back walk in it. The light is bright but the people wear coats. The photo is taken from afar and the people look small next to the trees.", + (71, 103, 66) + ), + ( + "images/IMG_9369.JPG", + "On a tree stump a group of mushrooms bloom up from the center of the stump. The mushrooms are mid-sized.", + (115, 115, 106) + ), + ( + "images/IMG_9372.JPG", + "A tree with three main trunks sits in the middle of the image, beyond the trunks are the woodlands of the forest.", + (110, 112, 102) + ), + ( + "images/IMG_9379.JPG", + "Two fingers of white people hold down a sheet of paper. One of the fingernails is painted with black nailpolish. The paper holds a map of interwoven concepts, organised for a talk.", + (123, 154, 244) + ), + ( + "images/IMG_9380.JPG", + "A white person stands holding a microphone. Projected onto a screen behind them is the text '\"A tree is never felled for the reason it has been planted.\" ............1800.............2000.............2200....'", + (207, 223, 238) + ), + ( + "images/IMG_9397.JPG", + "Four white people are in a room, one stands and holds a microphone and is speaking, the other three are wearing face masks. Everyone is looking at a projected screen with a pad on it. The first line reads \"14:10-14:30, ORACLE, 1. Octavia Butler: lier ce qu'on fait artistiquement a la politique, 4 questions.\"", + (76, 87, 70) + ), + ( + "images/IMG_9405.JPG", + "Many people are in a room, four are infront of a chalkboard and projector. Some are gazing up at the projected screen, others are gazing downwards. On the projected screen are marker, pencil and crayon drawings on sheets of paper of plant life.", + (78, 94, 84) + ), + ( + "images/IMG_9412.JPG", + "Six people stand infront of a chalkboard, presumibly giving a presentation. They are of similar height but of various cultural backgrounds. Some are wearing face masks others aren't, behind them is a projection that is not so clear.", + (189, 170, 138) + ), + ( + "images/IMG_9415.JPG", + "Three people stand and sit infront of a chalkboard with a projection above them. Two white people are holding a drawing taught, and one person of color is speaking into a microphone. On the projection above their heads is a hand with red paint on the fingertips.", + (175, 159, 143) + ), + ( + "images/IMG_9417.JPG", + "Three people stand and sit infront of a chalkboard with a projection above them. Two white people are holding a drawing loosely and one person of color is speaking into a microphone. On the projection above their heads is an image of a path through a forest.", + (86, 96, 85) + ), + ( + "images/IMG_9422.JPG", + "Five white people are standing before an audience and in front of a projected image. One of these people is giving a presentation while the four others are masked. The person on the far right has their mask falling under their nose which is discovering their smile. On the projected image is an electronic device connected to a plant. The ambiance is joyful.", + (134, 126, 117) + ), + ( + "images/IMG_9424.JPG", + "One white person is standing before an audience and in front of a projected image and is talking into a small microphone. Another person on the far left is looking at the projected image, on it, there is a graphic diagram of a system including a computer, a coffee machine and a plant with the words \"voice recognition\" and \"kindness list\".", + (65, 66, 58) + ), + ( + "images/IMG_9432.JPG", + "Four people are standing before an audience and in front of a projected image. All are masked except for one who bends to reach a keyboard. The person on the far left is looking at the projected image, on it, there is the glitched representation of a bag of crips.", + (219, 217, 218) + ), + ( + "images/IMG_9435.JPG", + "Four people are standing before an audience and in front of a projected image on which is presented a new alphabet. The person in the middle is talking in a microphone while pointing at a device that the person on the far right is holding. A clock on the wall indicates 4:07.", + (116, 104, 90) + ), + ( + "images/IMG_9436.JPG", + "One white person is standing before an audience, in front of a projected image and is talking into a small microphone while looking at a computer. The projected image is an otherwordly drawing of the forest.", + (67, 76, 71) + ), + ( + "images/Saint_Luc.jpg", + "Three people hold up two A3-sized sheets, they are giving a presentation. The picture is taken from the audience. The sheets contain small illustrations of leaves and animals, the illustrations were cut, and recomposed to fill the sheet like a pattern.", + (94, 100, 96) + ) +] \ No newline at end of file diff --git a/posters/graph_utils.py b/posters/graph_utils.py new file mode 100644 index 0000000..3450cfe --- /dev/null +++ b/posters/graph_utils.py @@ -0,0 +1,26 @@ +import textwrap +from string import ascii_uppercase + +# Returns a function to generate node names with given prefix +def make_name_generator (prefix = '', length = 1): + wheels = [{ 'position': None, 'max': len(ascii_uppercase), 'values': list(ascii_uppercase)} for _ in range(length)] + + def name_generator (): + for wheel in wheels: + if wheel['position'] is None: + wheel['position'] = 0 + else: + wheel['position'] += 1 + if wheel['position'] < wheel['max']: + break + else: + wheel['position'] = 0 + + return prefix + ''.join(reversed([wheel['values'][wheel['position']] for wheel in wheels])) + + return name_generator + + +# Wrap text on labels +def wrapped (text, width=45, join='\n'): + return join.join(textwrap.wrap(text, width=width)) diff --git a/posters/pdf/description_images_random-resampled.pdf b/posters/pdf/description_images_random-resampled.pdf new file mode 100644 index 0000000..b5182f7 Binary files /dev/null and b/posters/pdf/description_images_random-resampled.pdf differ diff --git a/posters/pdf/description_text_random-resampled-gray.pdf b/posters/pdf/description_text_random-resampled-gray.pdf new file mode 100644 index 0000000..abb7c95 Binary files /dev/null and b/posters/pdf/description_text_random-resampled-gray.pdf differ diff --git a/posters/pdf/images_colors-resampled.pdf b/posters/pdf/images_colors-resampled.pdf new file mode 100644 index 0000000..26db8a2 Binary files /dev/null and b/posters/pdf/images_colors-resampled.pdf differ diff --git a/posters/pdf/images_dates-resampled.pdf b/posters/pdf/images_dates-resampled.pdf new file mode 100644 index 0000000..5d9508a Binary files /dev/null and b/posters/pdf/images_dates-resampled.pdf differ diff --git a/posters/posters.py b/posters/posters.py new file mode 100644 index 0000000..2c82227 --- /dev/null +++ b/posters/posters.py @@ -0,0 +1,132 @@ +from text_tree import insert +from treesort import measure_tree +from visualizer import visualize_node +from descriptions import descriptions +from graph_utils import make_name_generator, wrapped +from graphviz import Graph +from random import shuffle +import datetime + +import exifread +from PIL import Image + +def get_image_date (path): + f = open(path, 'rb') + + # Return Exif tags + tags = exifread.process_file(f) + + if 'EXIF DateTimeOriginal' in tags.keys(): + return datetime.datetime.strptime(str(tags['EXIF DateTimeOriginal']), '%Y:%m:%d %H:%M:%S') + elif 'Image DateTime' in tags.keys(): + return datetime.datetime.strptime(str(tags['Image DateTime']), '%Y:%m:%d %H:%M:%S') + else: + print('No date for "{}"'.format(path)) + return datetime.datetime.now() + + +def count_trees (text): + count = 0 + words = ['tree', 'forest', 'leave', 'branch', 'stump', 'grass', 'nature', 'flower', 'rock', 'mushroom', 'nature', 'plant'] + neg_words = ['computer', 'microphone', 'screen', 'laptop', 'machine', 'pool', 'project', 'text', 'culture', 'board', 'wire', 'chip', 'technology'] + text = text.lower() + + for word in words: + count += text.count(word) + + + for word in neg_words: + count -= text.count(word) + + return count + + +def make_tree (values, key = lambda word: word): + tree = None + + for value in values: + tree = insert(tree, value, key) + + return tree + +def make_image_node(graph, generate_node_name, image): + node_name = generate_node_name() + + im = Image.open(image[1]) + w, h = im.size + + sw = 4.75 if w < h else 3.75 + + graph.node(node_name, + image=image[1], + label='', + shape='box', + color='transparent', + width=str(sw*(w/h)), + height=str(sw), + imagepos='mc', + fixedsize='true', + fillcolor='transparent', + imagescale='height' + ) + + return node_name + +def make_text_node(graph, generate_node_name, image): + node_name = generate_node_name() + graph.node(node_name, + label='<{}
>'.format(wrapped(image[0], 35, join="
")), + fontname='Fira Mono', + fontcolor='black', + shape='plaintext', + color='black', + fontsize='14' + ) + return node_name + + +if __name__ == '__main__': + generate_node_name = make_name_generator(length=3) + + images = [(description, image, color, get_image_date(image)) for image, description, color in descriptions] + + shuffle(images) + description_tree = make_tree(images, lambda image: count_trees(image[0])) + date_tree = make_tree(images, lambda image: image[3]) + color_tree = make_tree(images, lambda image: image[2][0]) + + while measure_tree(description_tree) > 8 or measure_tree(date_tree) > 9 or measure_tree(color_tree) > 9: + print(measure_tree(description_tree), measure_tree(date_tree), measure_tree(color_tree)) + shuffle(images) + description_tree = make_tree(images, lambda image: count_trees(image[0])) + date_tree = make_tree(images, lambda image: image[3]) + color_tree = make_tree(images, lambda image: image[2][0]) + + + graph = Graph(name='images_description', format='svg', engine='dot') + graph.attr('graph', splines='line', rankdir='BT', ranksep='1', nodesep='0.15') + graph.attr(label="<36 Images, ordered by mentions of nature in their description

Listen to the descriptions at frart.algoliterarypublishing.net/treesort>", labelloc='b', labeljust='l', fontname='Fira mono', fontsize='14', fontcolor='black') + visualize_node(graph, make_image_node, generate_node_name, description_tree) + graph.render('description_images_random') + + graph = Graph(name='descriptions_description', format='svg', engine='dot') + graph.attr('graph', splines='line', rankdir='BT', ranksep='2', nodesep='0.15', margin='1,1') + graph.attr(label="<36 Image descriptions, ordered by mentions of nature

Listen to the descriptions at frart.algoliterarypublishing.net/treesort>", labelloc='b', labeljust='l', fontname='Fira mono', fontsize='14', fontcolor='black', image='qr.gif') + visualize_node(graph, make_text_node, generate_node_name, description_tree) + graph.render('description_text_random') + + graph = Graph(name='images_colors', format='svg', engine='dot') + graph.attr('graph', splines='line', rankdir='BT', ranksep='1') + graph.attr(label="<36 Images, ordered by dominant color

Listen to the descriptions at frart.algoliterarypublishing.net/treesort>", labelloc='b', labeljust='l', fontname='Fira mono', fontsize='12', fontcolor='black') + visualize_node(graph, make_image_node, generate_node_name, color_tree) + graph.render('images_colors') + + graph = Graph(name='images_dates', format='svg', engine='dot') + graph.attr('graph', splines='line', rankdir='BT', ranksep='1', nodesep='0.15') + graph.attr(label="<36 Images, ordered by date

Listen to the descriptions at frart.algoliterarypublishing.net/treesort>", labelloc='b', labeljust='l', fontname='Fira mono', fontsize='12', fontcolor='black') + visualize_node(graph, make_image_node, generate_node_name, date_tree) + graph.render('images_dates') + +# Insert later into the SVG's +# style="position: absolute;bottom: 1vh;" +# diff --git a/posters/requirements.txt b/posters/requirements.txt new file mode 100644 index 0000000..e758b2f --- /dev/null +++ b/posters/requirements.txt @@ -0,0 +1,3 @@ +graphviz +Pillow +ExifRead \ No newline at end of file diff --git a/posters/text_tree.py b/posters/text_tree.py new file mode 100644 index 0000000..04d901d --- /dev/null +++ b/posters/text_tree.py @@ -0,0 +1,42 @@ +from treesort import TreeNode +from visualizer import visualize +from random import shuffle + +def insert (root, value, key = lambda value: value): + if not root: + root = TreeNode() + root.value = value + else: + if value == root.value: + root.value = value + else: + if key(value) < key(root.value): + root.left = insert(root.left, value, key) + else: + root.right = insert(root.right, value, key) + return root + + +def make_tree (values, key = lambda word: word): + tree = None + + for value in values: + tree = insert(tree, value, key) + + return tree + +def clean (word): + return word.lower().strip(' .,!?-"()[]‘’“”') + +def not_empty (word): + return (word) + +if __name__ == '__main__': + with open('to-sort.txt', 'r') as h: + text = h.read() + words = text.split(' ') + cleaned_words = list(filter(not_empty, map(clean, words))) + + shuffle(cleaned_words) + + visualize(make_tree(cleaned_words), 'text-tree-random') \ No newline at end of file diff --git a/posters/treesort.py b/posters/treesort.py new file mode 100644 index 0000000..c20aac8 --- /dev/null +++ b/posters/treesort.py @@ -0,0 +1,85 @@ +from random import randint + +# Description of a node +class TreeNode (object): + def __init__ (self, value = None): + self.value = value + self.left = None + self.right = None + +""" + This function defines a root for the tree and initiates + the process of looping through the values and inserting + them into the tree. +""" +def make_tree (values): + tree = None + + for value in values: + tree = insert(tree, value) + + return tree + +""" + Adds a node to the tree +""" +def insert (root, value, key = lambda value: value): + # Test whether there is a node at the current location + if not root: + # If not, insert the node here + + root = TreeNode() + root.value = value + else: + # There is a node, compare value to be inserted + # and the value of the node to decide whether the + # node should be attached to the left or the right + if key(value) < key(root.value): + root.left = insert(root.left, value, key) + else: + root.right = insert(root.right, value, key) + return root + +""" + Measures the depth of a (sub)tree +""" +def measure_tree (node): + if node: + # If there is a node, measure the depth + # of the left and right node + depth_left = measure_tree(node.left) + depth_right = measure_tree(node.right) + + # Return the answer with the highest value + # and add one + return max(depth_left, depth_right) + 1 + else: + # There isn't a node, answer with the value 0 + return 0 + + +def traverse_tree (node): + # Test whether there is a node + if node: + # If there is a node, ask its left node to traverse + tree_left = traverse_tree(node.left) + # and ask the same for its right node + tree_right = traverse_tree(node.right) + + # Then combine into a new list: + # the list answered by the left node + # with the value of the node itself + # And the list answered by the right node + # + # Give this new list as an answer to the root node + return tree_left + [ node.value ] + tree_right + else: + # There is no node, return an empty list + return [] + + +if __name__ == '__main__': + values = [randint(0, 100) for _ in range(15)] + tree = make_tree(values) + + print(values, tree.value, tree.left.value if tree.left else None, tree.right.value if tree.right else None, measure_tree(tree), traverse_tree(tree)) \ No newline at end of file diff --git a/posters/visualizer.py b/posters/visualizer.py new file mode 100644 index 0000000..ec53a8a --- /dev/null +++ b/posters/visualizer.py @@ -0,0 +1,45 @@ +from graph_utils import make_name_generator +from graphviz import Digraph, Graph + +def make_node (graph, generate_node_name, label): + node_name = generate_node_name() + graph.node(node_name, label=label) + return node_name + + +def visualize_node (graph, make_node, generate_node_name, node, previous_node_name = None, tailport = None): + if node: + node_name = make_node(graph, generate_node_name, node.value) + + if previous_node_name: + graph.edge(previous_node_name, node_name, tailport=tailport, headport='s', penwidth='1') + + + visualize_node(graph, make_node, generate_node_name, node.left, node_name, 'nw') + # Hack to have a more beautiful layout + visualize_node(graph, make_node, generate_node_name, None, node_name, 'n') + visualize_node(graph, make_node, generate_node_name, node.right, node_name, 'ne') + + else: + # Invisible node to balance the tree. + node_name = generate_node_name() + graph.node(node_name, label=node_name, style='invis') + graph.edge(previous_node_name, node_name, tailport=tailport, headport='s', style='invis') + +def make_graph (graphname): + graph = Graph(name=graphname, format='svg', engine='dot') + graph.attr('graph', splines='line', rankdir='BT') + return graph + +def visualize (tree, graphname, make_node=make_node, generate_node_name = make_name_generator(length=3)): + graph = make_graph(graphname) + visualize_node(graph, make_node, tree) + graph.render(graphname) + +if __name__ == '__main__': + from treesort import make_tree + from random import randint + + values = [randint(0, 250) for _ in range(15)] + tree = make_tree(values) + visualize(tree, 'tree') \ No newline at end of file diff --git a/webinterface/app.py b/webinterface/app.py new file mode 100644 index 0000000..9b27a2b --- /dev/null +++ b/webinterface/app.py @@ -0,0 +1,22 @@ +from flask import Flask, render_template +from random import choice +from descriptions import descriptions +from local_settings import BASEURL + +app = Flask(__name__) + +@app.route('{}/'.format(BASEURL)) +def index(): + + pick = choice(descriptions) + + context = { + 'BASEURL': BASEURL, + 'image_id': pick[0], + 'file': pick[1], + 'description': pick[2], + 'color': pick[3], + 'color_string': 'rgb({})'.format(', '.join(map(str, pick[3]))), + 'audio': pick[4] + } + return render_template('index.html', **context) \ No newline at end of file diff --git a/webinterface/descriptions.py b/webinterface/descriptions.py new file mode 100644 index 0000000..c9f0550 --- /dev/null +++ b/webinterface/descriptions.py @@ -0,0 +1,254 @@ +descriptions = [ + ( + "image__20211019_151924", + "images/20211019_151924.jpg", + "Two white people are sitting at a table typing on their computer keyboards under a roof window. On the table are cups, mandarines and water bottles; on the wall, black and white pictures of statues and people. The mood is studious.", + (147, 169, 183), + "audio/Recording30.m4a" + ), + ( + "image__20211019_162946", + "images/20211019_162946.jpg", + "A tree is standing next to a lake, as if about to jump in it. On the ground, a mix of fallen leaves and grass. The weather is sunny and the ambiance is peaceful.", + (119, 115, 84), + "audio/Recording42.m4a" + ), + ( + "image__20211022_101225", + "images/20211022_101225.jpg", + "Several tree branches form a canopy through which one can see the sky. The leaves go from translucent to opaque.", + (96, 102, 75), + "audio/Recording49.m4a" + ), + ( + "image__20211025_113835", + "images/20211025_113835.jpg", + "A white person is standing between a desk and a blackboard, holding a mic while typing on a keyboard and is giving a presentation to an audience of white masked people.", + (62, 81, 88), + "audio/Recording26.m4a" + ), + ( + "image__20211025_113843", + "images/20211025_113843.jpg", + "Masked students are sitting in an auditorium, they watch and listen. A white person is sitting in front. Large windows appear in the back of the students.", + (131, 114, 109), + "audio/Recording37.m4a" + ), + ( + "image__20211025_151107", + "images/20211025_151107.jpg", + "An indigenous person talks in a microphone while a slide is shown in the back. The slide shows four indigenous people of different ages at the left, it mentions the word family tree at the left.", + (151, 150, 148), + "audio/Recording38.m4a" + ), + ( + "image__20211025_152322", + "images/20211025_152322.jpg", + "A white person speaks in the microphone to two people sitting down at a desk in front of a white screen. One of them is from indigenous background, the other from hispanic descent. On the desk are two laptops. One is showing text. A white person with glasses looks at the scene.", + (50, 43, 37), + "audio/Recording20.m4a" + ), + ( + "image__20211025_172905", + "images/20211025_172905.jpg", + "A white person with long grey hair speaks in the microphone. In the back is a projection screen showing a slide with text. The title of the slide is Nature-Culture.", + (252, 254, 253), + "audio/Recording18.m4a" + ), + ( + "image__20211026_145331", + "images/20211026_145331.jpg", + "Three young people are touching trees in a forest. The tree in the middle is very large and is being hugged by one of the three people.", + (115, 125, 112), + "audio/Recording48.m4a" + ), + ( + "image__20211026_145339", + "images/20211026_145339.jpg", + "Three young people are touching young beech trees in the forest. One person is bending down to a small sapling.", + (116, 123, 113), + "audio/Recording44.m4a" + ), + ( + "image__20211027_111356", + "images/20211027_111356.jpg", + "Nine young people of mixed origin are standing in a room with naked walls. They take on specific positions in the room, forming a tree. In front stands a taller masked person with the back to the camera.", + (255, 255, 255), + "audio/Recording36.m4a" + ), + ( + "image__20211027_125357", + "images/20211027_125357.jpg", + "A sunny image showing a clean swimming pool with black squares at the bottom of the water. People are sitting in small groups next to the swimmingpool, concentrated on something that lies between them.", + (88, 110, 112), + "audio/Recording31.m4a" + ), + ( + "image__20211027_125504", + "images/20211027_125504.jpg", + "Nine people stand next to a swimmingpool. Two people are sitting. One person bends over next to them. It is a sunny day. They discuss a presentation on two white sheets that are lying on the tiles.", + (89, 87, 76), + "audio/Recording32.m4a" + ), + ( + "image__20211027_125747", + "images/20211027_125747.jpg", + "On a sheet of paper about a dozen flowers without stems, varying in color. They cast a sharp, long shadow; the sun is bright and low. All but one flower is put in the top-half of the sheet.", + (182, 182, 184), + "audio/Recording35.m4a" + ), + ( + "image__20211027_130052", + "images/20211027_130052.jpg", + "About a dozen thumbnail-sized rocks are laid in a straight line on the pavement. The light is bright and the rocks cast a sharp shadow. The rocks are similar in color but vary in shape. While the arrangement is deliberate the system is not clear.", + (255, 255, 255), + "audio/Recording46.m4a" + ), + ( + "image__20211027_130250", + "images/20211027_130250.jpg", + "Thumbnail-sized rocks, mushrooms, a chestnut, leaves and flowers are laid out on a surface. The arrangement is careful and deliberate. It seems as they have been arranged in two arms or strings, the string on the left consists of brown, dried leaves and the one on the right contains the flowers. The stones and chestnut are put in the middle the two strings meet.", + (143, 132, 130), + "audio/Recording50.m4a" + ), + ( + "image__20211027_140938", + "images/20211027_140938.jpg", + "A group of people is seen from the back, it seems they are entering a park. The weather is nice. Two trees in the foreground frame the picture and give the suggestion of an entrance.", + (253, 255, 254), + "audio/Recording39.m4a" + ), + ( + "image__20211027_152654", + "images/20211027_152654.jpg", + "Six people stand in a clearing in a forest. They are seen on the back. The people look in the same direction, away from the camera, and do not seem to interact with each other.", + (126, 126, 124), + "audio/Recording40.m4a" + ), + ( + "image__Anais_berck", + "images/Anais_berck-6.jpg", + "A small houseplant in a rustic pot. The plant has wires attached to it which lead to a chipboard which in turn is connected to a powerbank. In the foreground two laptops complete the contrast between the rigid shapes of the technology and the leaves of the plant.", + (225, 212, 196), + "audio/Recording28.m4a" + ), + ( + "image__forest_walk_11", + "images/forest_walk-11.jpg", + "A tree seen from the beneath along its trunk. In the bright light, the branches of the tree are reduced to dark shapes. The shape and dark color of the branches contrasts with the translucency and refined shapes of the leaves.", + (80, 93, 35), + "audio/Recording51.m4a" + ), + ( + "image__forest_walk_6", + "images/forest_walk-6.jpg", + "A forest, two people, seen from the back walk in it. The light is bright but the people wear coats. The photo is taken from afar and the people look small next to the trees.", + (71, 103, 66), + "audio/Recording45.m4a" + ), + ( + "image__IMG_9369", + "images/IMG_9369.JPG", + "On a tree stump a group of mushrooms bloom up from the center of the stump. The mushrooms are mid-sized.", + (115, 115, 106), + "audio/Recording47.m4a" + ), + ( + "image__IMG_9372", + "images/IMG_9372.JPG", + "A tree with three main trunks sits in the middle of the image, beyond the trunks are the woodlands of the forest.", + (110, 112, 102), + "audio/Recording43.m4a" + ), + ( + "image__IMG_9379", + "images/IMG_9379.JPG", + "Two fingers of white people hold down a sheet of paper. One of the fingernails is painted with black nailpolish. The paper holds a map of interwoven concepts, organised for a talk.", + (123, 154, 244), + "audio/Recording34.m4a" + ), + ( + "image__IMG_9380", + "images/IMG_9380.JPG", + "A white person stands holding a microphone. Projected onto a screen behind them is the text '\"A tree is never felled for the reason it has been planted.\" ............1800.............2000.............2200....'", + (207, 223, 238), + "audio/Recording25.m4a" + ), + ( + "image__IMG_9397", + "images/IMG_9397.JPG", + "Four white people are in a room, one stands and holds a microphone and is speaking, the other three are wearing face masks. Everyone is looking at a projected screen with a pad on it. The first line reads \"14:10-14:30, ORACLE, 1. Octavia Butler: lier ce qu'on fait artistiquement a la politique, 4 questions.\"", + (76, 87, 70), + "audio/Recording23.m4a" + ), + ( + "image__IMG_9405", + "images/IMG_9405.JPG", + "Many people are in a room, four are infront of a chalkboard and projector. Some are gazing up at the projected screen, others are gazing downwards. On the projected screen are marker, pencil and crayon drawings on sheets of paper of plant life.", + (78, 94, 84), + "audio/Recording16.m4a" + ), + ( + "image__IMG_9412", + "images/IMG_9412.JPG", + "Six people stand infront of a chalkboard, presumibly giving a presentation. They are of similar height but of various cultural backgrounds. Some are wearing face masks others aren't, behind them is a projection that is not so clear.", + (189, 170, 138), + "audio/Recording29.m4a" + ), + ( + "image__IMG_9415", + "images/IMG_9415.JPG", + "Three people stand and sit infront of a chalkboard with a projection above them. Two white people are holding a drawing taught, and one person of color is speaking into a microphone. On the projection above their heads is a hand with red paint on the fingertips.", + (175, 159, 143), + "audio/Recording19.m4a" + ), + ( + "image__IMG_9417", + "images/IMG_9417.JPG", + "Three people stand and sit infront of a chalkboard with a projection above them. Two white people are holding a drawing loosely and one person of color is speaking into a microphone. On the projection above their heads is an image of a path through a forest.", + (86, 96, 85), + "audio/Recording24.m4a" + ), + ( + "image__IMG_9422", + "images/IMG_9422.JPG", + "Five white people are standing before an audience and in front of a projected image. One of these people is giving a presentation while the four others are masked. The person on the far right has their mask falling under their nose which is discovering their smile. On the projected image is an electronic device connected to a plant. The ambiance is joyful.", + (134, 126, 117), + "audio/Recording33.m4a" + ), + ( + "image__IMG_9424", + "images/IMG_9424.JPG", + "One white person is standing before an audience and in front of a projected image and is talking into a small microphone. Another person on the far left is looking at the projected image, on it, there is a graphic diagram of a system including a computer, a coffee machine and a plant with the words \"voice recognition\" and \"kindness list\".", + (65, 66, 58), + "audio/Recording17.m4a" + ), + ( + "image__IMG_9432", + "images/IMG_9432.JPG", + "Four people are standing before an audience and in front of a projected image. All are masked except for one who bends to reach a keyboard. The person on the far left is looking at the projected image, on it, there is the glitched representation of a bag of crips.", + (219, 217, 218), + "audio/Recording21.m4a" + ), + ( + "image__IMG_9435", + "images/IMG_9435.JPG", + "Four people are standing before an audience and in front of a projected image on which is presented a new alphabet. The person in the middle is talking in a microphone while pointing at a device that the person on the far right is holding. A clock on the wall indicates 4:07.", + (116, 104, 90), + "audio/Recording27.m4a" + ), + ( + "image__IMG_9436", + "images/IMG_9436.JPG", + "One white person is standing before an audience, in front of a projected image and is talking into a small microphone while looking at a computer. The projected image is an otherwordly drawing of the forest.", + (67, 76, 71), + "audio/Recording22.m4a" + ), + ( + "image__Saint_Luc", + "images/Saint_Luc.jpg", + "Three people hold up two A3-sized sheets, they are giving a presentation. The picture is taken from the audience. The sheets contain small illustrations of leaves and animals, the illustrations were cut, and recomposed to fill the sheet like a pattern.", + (94, 100, 96), + "audio/Recording41.m4a" + ) +] \ No newline at end of file diff --git a/webinterface/local_settings.py.example b/webinterface/local_settings.py.example new file mode 100644 index 0000000..e6cdf24 --- /dev/null +++ b/webinterface/local_settings.py.example @@ -0,0 +1 @@ +BASEURL = '' \ No newline at end of file diff --git a/webinterface/requirements.txt b/webinterface/requirements.txt new file mode 100644 index 0000000..8ab6294 --- /dev/null +++ b/webinterface/requirements.txt @@ -0,0 +1 @@ +flask \ No newline at end of file diff --git a/webinterface/static/audio/Recording16.m4a b/webinterface/static/audio/Recording16.m4a new file mode 100644 index 0000000..b804be8 Binary files /dev/null and b/webinterface/static/audio/Recording16.m4a differ diff --git a/webinterface/static/audio/Recording17.m4a b/webinterface/static/audio/Recording17.m4a new file mode 100644 index 0000000..eeec59d Binary files /dev/null and b/webinterface/static/audio/Recording17.m4a differ diff --git a/webinterface/static/audio/Recording18.m4a b/webinterface/static/audio/Recording18.m4a new file mode 100644 index 0000000..5c8eade Binary files /dev/null and b/webinterface/static/audio/Recording18.m4a differ diff --git a/webinterface/static/audio/Recording19.m4a b/webinterface/static/audio/Recording19.m4a new file mode 100644 index 0000000..c4d23db Binary files /dev/null and b/webinterface/static/audio/Recording19.m4a differ diff --git a/webinterface/static/audio/Recording20.m4a b/webinterface/static/audio/Recording20.m4a new file mode 100644 index 0000000..9b97ad6 Binary files /dev/null and b/webinterface/static/audio/Recording20.m4a differ diff --git a/webinterface/static/audio/Recording21.m4a b/webinterface/static/audio/Recording21.m4a new file mode 100644 index 0000000..1a1b5b5 Binary files /dev/null and b/webinterface/static/audio/Recording21.m4a differ diff --git a/webinterface/static/audio/Recording22.m4a b/webinterface/static/audio/Recording22.m4a new file mode 100644 index 0000000..8f54549 Binary files /dev/null and b/webinterface/static/audio/Recording22.m4a differ diff --git a/webinterface/static/audio/Recording23.m4a b/webinterface/static/audio/Recording23.m4a new file mode 100644 index 0000000..28f766c Binary files /dev/null and b/webinterface/static/audio/Recording23.m4a differ diff --git a/webinterface/static/audio/Recording24.m4a b/webinterface/static/audio/Recording24.m4a new file mode 100644 index 0000000..221a535 Binary files /dev/null and b/webinterface/static/audio/Recording24.m4a differ diff --git a/webinterface/static/audio/Recording25.m4a b/webinterface/static/audio/Recording25.m4a new file mode 100644 index 0000000..4df6659 Binary files /dev/null and b/webinterface/static/audio/Recording25.m4a differ diff --git a/webinterface/static/audio/Recording26.m4a b/webinterface/static/audio/Recording26.m4a new file mode 100644 index 0000000..9db9c86 Binary files /dev/null and b/webinterface/static/audio/Recording26.m4a differ diff --git a/webinterface/static/audio/Recording27.m4a b/webinterface/static/audio/Recording27.m4a new file mode 100644 index 0000000..533d3ad Binary files /dev/null and b/webinterface/static/audio/Recording27.m4a differ diff --git a/webinterface/static/audio/Recording28.m4a b/webinterface/static/audio/Recording28.m4a new file mode 100644 index 0000000..55c7b69 Binary files /dev/null and b/webinterface/static/audio/Recording28.m4a differ diff --git a/webinterface/static/audio/Recording29.m4a b/webinterface/static/audio/Recording29.m4a new file mode 100644 index 0000000..d7f1298 Binary files /dev/null and b/webinterface/static/audio/Recording29.m4a differ diff --git a/webinterface/static/audio/Recording30.m4a b/webinterface/static/audio/Recording30.m4a new file mode 100644 index 0000000..449e85c Binary files /dev/null and b/webinterface/static/audio/Recording30.m4a differ diff --git a/webinterface/static/audio/Recording31.m4a b/webinterface/static/audio/Recording31.m4a new file mode 100644 index 0000000..d76c8c1 Binary files /dev/null and b/webinterface/static/audio/Recording31.m4a differ diff --git a/webinterface/static/audio/Recording32.m4a b/webinterface/static/audio/Recording32.m4a new file mode 100644 index 0000000..02f15cc Binary files /dev/null and b/webinterface/static/audio/Recording32.m4a differ diff --git a/webinterface/static/audio/Recording33.m4a b/webinterface/static/audio/Recording33.m4a new file mode 100644 index 0000000..e2cfa45 Binary files /dev/null and b/webinterface/static/audio/Recording33.m4a differ diff --git a/webinterface/static/audio/Recording34.m4a b/webinterface/static/audio/Recording34.m4a new file mode 100644 index 0000000..3532d83 Binary files /dev/null and b/webinterface/static/audio/Recording34.m4a differ diff --git a/webinterface/static/audio/Recording35.m4a b/webinterface/static/audio/Recording35.m4a new file mode 100644 index 0000000..63ad48f Binary files /dev/null and b/webinterface/static/audio/Recording35.m4a differ diff --git a/webinterface/static/audio/Recording36.m4a b/webinterface/static/audio/Recording36.m4a new file mode 100644 index 0000000..652942e Binary files /dev/null and b/webinterface/static/audio/Recording36.m4a differ diff --git a/webinterface/static/audio/Recording37.m4a b/webinterface/static/audio/Recording37.m4a new file mode 100644 index 0000000..f5fc664 Binary files /dev/null and b/webinterface/static/audio/Recording37.m4a differ diff --git a/webinterface/static/audio/Recording38.m4a b/webinterface/static/audio/Recording38.m4a new file mode 100644 index 0000000..5cb414d Binary files /dev/null and b/webinterface/static/audio/Recording38.m4a differ diff --git a/webinterface/static/audio/Recording39.m4a b/webinterface/static/audio/Recording39.m4a new file mode 100644 index 0000000..9f1b877 Binary files /dev/null and b/webinterface/static/audio/Recording39.m4a differ diff --git a/webinterface/static/audio/Recording40.m4a b/webinterface/static/audio/Recording40.m4a new file mode 100644 index 0000000..1812693 Binary files /dev/null and b/webinterface/static/audio/Recording40.m4a differ diff --git a/webinterface/static/audio/Recording41.m4a b/webinterface/static/audio/Recording41.m4a new file mode 100644 index 0000000..116707f Binary files /dev/null and b/webinterface/static/audio/Recording41.m4a differ diff --git a/webinterface/static/audio/Recording42.m4a b/webinterface/static/audio/Recording42.m4a new file mode 100644 index 0000000..f20ae57 Binary files /dev/null and b/webinterface/static/audio/Recording42.m4a differ diff --git a/webinterface/static/audio/Recording43.m4a b/webinterface/static/audio/Recording43.m4a new file mode 100644 index 0000000..cfd40e9 Binary files /dev/null and b/webinterface/static/audio/Recording43.m4a differ diff --git a/webinterface/static/audio/Recording44.m4a b/webinterface/static/audio/Recording44.m4a new file mode 100644 index 0000000..41905e9 Binary files /dev/null and b/webinterface/static/audio/Recording44.m4a differ diff --git a/webinterface/static/audio/Recording45.m4a b/webinterface/static/audio/Recording45.m4a new file mode 100644 index 0000000..03d9af5 Binary files /dev/null and b/webinterface/static/audio/Recording45.m4a differ diff --git a/webinterface/static/audio/Recording46.m4a b/webinterface/static/audio/Recording46.m4a new file mode 100644 index 0000000..6295a00 Binary files /dev/null and b/webinterface/static/audio/Recording46.m4a differ diff --git a/webinterface/static/audio/Recording47.m4a b/webinterface/static/audio/Recording47.m4a new file mode 100644 index 0000000..297f5a1 Binary files /dev/null and b/webinterface/static/audio/Recording47.m4a differ diff --git a/webinterface/static/audio/Recording48.m4a b/webinterface/static/audio/Recording48.m4a new file mode 100644 index 0000000..55ee105 Binary files /dev/null and b/webinterface/static/audio/Recording48.m4a differ diff --git a/webinterface/static/audio/Recording49.m4a b/webinterface/static/audio/Recording49.m4a new file mode 100644 index 0000000..c709556 Binary files /dev/null and b/webinterface/static/audio/Recording49.m4a differ diff --git a/webinterface/static/audio/Recording50.m4a b/webinterface/static/audio/Recording50.m4a new file mode 100644 index 0000000..fb8499b Binary files /dev/null and b/webinterface/static/audio/Recording50.m4a differ diff --git a/webinterface/static/audio/Recording51.m4a b/webinterface/static/audio/Recording51.m4a new file mode 100644 index 0000000..6f03c43 Binary files /dev/null and b/webinterface/static/audio/Recording51.m4a differ diff --git a/webinterface/static/fonts/fira-mono/FiraMono-Bold.ttf b/webinterface/static/fonts/fira-mono/FiraMono-Bold.ttf new file mode 100644 index 0000000..db6f63f Binary files /dev/null and b/webinterface/static/fonts/fira-mono/FiraMono-Bold.ttf differ diff --git a/webinterface/static/fonts/fira-mono/FiraMono-Medium.ttf b/webinterface/static/fonts/fira-mono/FiraMono-Medium.ttf new file mode 100644 index 0000000..892c124 Binary files /dev/null and b/webinterface/static/fonts/fira-mono/FiraMono-Medium.ttf differ diff --git a/webinterface/static/fonts/fira-mono/FiraMono-Regular.ttf b/webinterface/static/fonts/fira-mono/FiraMono-Regular.ttf new file mode 100644 index 0000000..3910f17 Binary files /dev/null and b/webinterface/static/fonts/fira-mono/FiraMono-Regular.ttf differ diff --git a/webinterface/static/fonts/fira-mono/OFL.txt b/webinterface/static/fonts/fira-mono/OFL.txt new file mode 100644 index 0000000..1ba1596 --- /dev/null +++ b/webinterface/static/fonts/fira-mono/OFL.txt @@ -0,0 +1,93 @@ +Copyright (c) 2012-2013, The Mozilla Corporation and Telefonica S.A. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/webinterface/templates/index.html b/webinterface/templates/index.html new file mode 100644 index 0000000..2a4cf68 --- /dev/null +++ b/webinterface/templates/index.html @@ -0,0 +1,350 @@ + + + + + + + Tree(s) sort(ed) + + + +
+

Tree(s) sort(ed)

+

{{ file }}

+ +

{{ description }}

+ ↻ Load another fragment. +
+ + + + + \ No newline at end of file