diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cb742b --- /dev/null +++ b/.gitignore @@ -0,0 +1,188 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# Godot +.godot/ +*.x86_64 +*.pck + +# Godot-specific ignores +.import/ +export.cfg +export_presets.cfg + +# Imported translations (automatically generated from CSV files) +*.translation + +# Mono-specific ignores +.mono/ +data_*/ +mono_crash.*.json +.vs/ +*.import + +# Mac bs +.DS_Store + +# Random stuff +__pycache__/ +chkpts/ +figures/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bb9b409 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Peter DV + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/addons/Todo_Manager/CONTRIBUTING.md b/addons/Todo_Manager/CONTRIBUTING.md new file mode 100644 index 0000000..5969b61 --- /dev/null +++ b/addons/Todo_Manager/CONTRIBUTING.md @@ -0,0 +1,23 @@ +## Contributing to TODO Manager +Firstly, thank you for being interested in contributing to the Godot TODO Manager plugin! +TODO Manager has benefitted greatly from enthusiastic users who have suggested new features, noticed bugs, and contributed code to the plugin. + +### Code Style Guide +For the sake of clarity, TODO Manager takes advantage of GDScripts optional static typing in most circumstances. +In particular, when declaring variables use colons to infer the type where possible: + +`todo := "#TODO"` + +If the type is not obvious then explicit typing is desirable: + +`items : PoolStringArray = todo.split()` + +Typed arguments and return values for functions are required: +``` +func example(name: String, amount: int) -> Array: + # code + return array_of_names +``` + +For more info on static typing in Godot please refer to the documentation. +https://docs.godotengine.org/en/stable/getting_started/scripting/gdscript/static_typing.html diff --git a/addons/Todo_Manager/ColourPicker.gd b/addons/Todo_Manager/ColourPicker.gd new file mode 100644 index 0000000..39a3f9a --- /dev/null +++ b/addons/Todo_Manager/ColourPicker.gd @@ -0,0 +1,17 @@ +@tool +extends HBoxContainer + +var colour : Color +var title : String: + set = set_title +var index : int + +@onready var colour_picker := $TODOColourPickerButton + +func _ready() -> void: + $TODOColourPickerButton.color = colour + $Label.text = title + +func set_title(value: String) -> void: + title = value + $Label.text = value diff --git a/addons/Todo_Manager/Current.gd b/addons/Todo_Manager/Current.gd new file mode 100644 index 0000000..d3961c9 --- /dev/null +++ b/addons/Todo_Manager/Current.gd @@ -0,0 +1,44 @@ +@tool +extends Panel + +signal tree_built # used for debugging + +const Todo := preload("res://addons/Todo_Manager/todo_class.gd") +const TodoItem := preload("res://addons/Todo_Manager/todoItem_class.gd") + +var _sort_alphabetical := true + +@onready var tree := $Tree as Tree + +func build_tree(todo_item : TodoItem, patterns : Array, cased_patterns : Array[String]) -> void: + tree.clear() + var root := tree.create_item() + root.set_text(0, "Scripts") + var script := tree.create_item(root) + script.set_text(0, todo_item.get_short_path() + " -------") + script.set_metadata(0, todo_item) + for todo in todo_item.todos: + var item := tree.create_item(script) + var content_header : String = todo.content + if "\n" in todo.content: + content_header = content_header.split("\n")[0] + "..." + item.set_text(0, "(%0) - %1".format([todo.line_number, content_header], "%_")) + item.set_tooltip_text(0, todo.content) + item.set_metadata(0, todo) + for i in range(0, len(cased_patterns)): + if cased_patterns[i] == todo.pattern: + item.set_custom_color(0, patterns[i][1]) + emit_signal("tree_built") + + +func sort_alphabetical(a, b) -> bool: + if a.script_path > b.script_path: + return true + else: + return false + +func sort_backwards(a, b) -> bool: + if a.script_path < b.script_path: + return true + else: + return false diff --git a/addons/Todo_Manager/Dock.gd b/addons/Todo_Manager/Dock.gd new file mode 100644 index 0000000..c71b6b2 --- /dev/null +++ b/addons/Todo_Manager/Dock.gd @@ -0,0 +1,297 @@ +@tool +extends Control + +#signal tree_built # used for debugging +enum { CASE_INSENSITIVE, CASE_SENSITIVE } + +const Project := preload("res://addons/Todo_Manager/Project.gd") +const Current := preload("res://addons/Todo_Manager/Current.gd") + +const Todo := preload("res://addons/Todo_Manager/todo_class.gd") +const TodoItem := preload("res://addons/Todo_Manager/todoItem_class.gd") +const ColourPicker := preload("res://addons/Todo_Manager/UI/ColourPicker.tscn") +const Pattern := preload("res://addons/Todo_Manager/UI/Pattern.tscn") +const DEFAULT_PATTERNS := [["\\bTODO\\b", Color("96f1ad"), CASE_INSENSITIVE], ["\\bHACK\\b", Color("d5bc70"), CASE_INSENSITIVE], ["\\bFIXME\\b", Color("d57070"), CASE_INSENSITIVE]] +const DEFAULT_SCRIPT_COLOUR := Color("ccced3") +const DEFAULT_SCRIPT_NAME := false +const DEFAULT_SORT := true + +var plugin : EditorPlugin + +var todo_items : Array + +var script_colour := Color("ccced3") +var ignore_paths : Array[String] = [] +var full_path := false +var auto_refresh := true +var builtin_enabled := false +var _sort_alphabetical := true + +var patterns := [["\\bTODO\\b", Color("96f1ad"), CASE_INSENSITIVE], ["\\bHACK\\b", Color("d5bc70"), CASE_INSENSITIVE], ["\\bFIXME\\b", Color("d57070"), CASE_INSENSITIVE]] + + +@onready var tabs := $VBoxContainer/TabContainer as TabContainer +@onready var project := $VBoxContainer/TabContainer/Project as Project +@onready var current := $VBoxContainer/TabContainer/Current as Current +@onready var project_tree := $VBoxContainer/TabContainer/Project/Tree as Tree +@onready var current_tree := $VBoxContainer/TabContainer/Current/Tree as Tree +@onready var settings_panel := $VBoxContainer/TabContainer/Settings as Panel +@onready var colours_container := $VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer3/Colours as VBoxContainer +@onready var pattern_container := $VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4/Patterns as VBoxContainer +@onready var ignore_textbox := $VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/IgnorePaths/TextEdit as LineEdit +@onready var auto_refresh_button := $VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns/RefreshCheckButton as CheckButton + +func _ready() -> void: + load_config() + populate_settings() + + +func build_tree() -> void: + if tabs: + match tabs.current_tab: + 0: + project.build_tree(todo_items, ignore_paths, patterns, plugin.cased_patterns, _sort_alphabetical, full_path) + create_config_file() + 1: + current.build_tree(get_active_script(), patterns, plugin.cased_patterns) + create_config_file() + 2: + pass + _: + pass + + +func get_active_script() -> TodoItem: + var current_script : Script = plugin.get_editor_interface().get_script_editor().get_current_script() + if current_script: + var script_path = current_script.resource_path + for todo_item in todo_items: + if todo_item.script_path == script_path: + return todo_item + + # nothing found + var todo_item := TodoItem.new(script_path, []) + return todo_item + else: + # not a script + var todo_item := TodoItem.new("res://Documentation", []) + return todo_item + + +func go_to_script(script_path: String, line_number : int = 0) -> void: + if plugin.get_editor_interface().get_editor_settings().get_setting("text_editor/external/use_external_editor"): + var exec_path = plugin.get_editor_interface().get_editor_settings().get_setting("text_editor/external/exec_path") + var args := get_exec_flags(exec_path, script_path, line_number) + OS.execute(exec_path, args) + else: + var script := load(script_path) + plugin.get_editor_interface().edit_resource(script) + plugin.get_editor_interface().get_script_editor().goto_line(line_number - 1) + +func get_exec_flags(editor_path : String, script_path : String, line_number : int) -> PackedStringArray: + var args : PackedStringArray + var script_global_path = ProjectSettings.globalize_path(script_path) + + if editor_path.ends_with("code.cmd") or editor_path.ends_with("code"): ## VS Code + args.append(ProjectSettings.globalize_path("res://")) + args.append("--goto") + args.append(script_global_path + ":" + str(line_number)) + + elif editor_path.ends_with("rider64.exe") or editor_path.ends_with("rider"): ## Rider + args.append("--line") + args.append(str(line_number)) + args.append(script_global_path) + + else: ## Atom / Sublime + args.append(script_global_path + ":" + str(line_number)) + + return args + +func sort_alphabetical(a, b) -> bool: + if a.script_path > b.script_path: + return true + else: + return false + +func sort_backwards(a, b) -> bool: + if a.script_path < b.script_path: + return true + else: + return false + + +func populate_settings() -> void: + for i in patterns.size(): + ## Create Colour Pickers + var colour_picker: Variant = ColourPicker.instantiate() + colour_picker.colour = patterns[i][1] + colour_picker.title = patterns[i][0] + colour_picker.index = i + colours_container.add_child(colour_picker) + colour_picker.colour_picker.color_changed.connect(change_colour.bind(i)) + + ## Create Patterns + var pattern_edit: Variant = Pattern.instantiate() + pattern_edit.text = patterns[i][0] + pattern_edit.index = i + pattern_container.add_child(pattern_edit) + pattern_edit.line_edit.text_changed.connect(change_pattern.bind(i, + colour_picker)) + pattern_edit.remove_button.pressed.connect(remove_pattern.bind(i, + pattern_edit, colour_picker)) + pattern_edit.case_checkbox.button_pressed = patterns[i][2] + pattern_edit.case_checkbox.toggled.connect(case_sensitive_pattern.bind(i)) + + var pattern_button := $VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4/Patterns/AddPatternButton + $VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4/Patterns.move_child(pattern_button, 0) + + # path filtering + var ignore_paths_field := ignore_textbox + if not ignore_paths_field.is_connected("text_changed", _on_ignore_paths_changed): + ignore_paths_field.connect("text_changed", _on_ignore_paths_changed) + var ignore_paths_text := "" + for path in ignore_paths: + ignore_paths_text += path + ", " + ignore_paths_text = ignore_paths_text.trim_suffix(", ") + ignore_paths_field.text = ignore_paths_text + + auto_refresh_button.button_pressed = auto_refresh + + +func rebuild_settings() -> void: + for node in colours_container.get_children(): + node.queue_free() + for node in pattern_container.get_children(): + if node is Button: + continue + node.queue_free() + populate_settings() + + +#### CONFIG FILE #### +func create_config_file() -> void: + var config = ConfigFile.new() + config.set_value("scripts", "full_path", full_path) + config.set_value("scripts", "sort_alphabetical", _sort_alphabetical) + config.set_value("scripts", "script_colour", script_colour) + config.set_value("scripts", "ignore_paths", ignore_paths) + + config.set_value("patterns", "patterns", patterns) + + config.set_value("config", "auto_refresh", auto_refresh) + config.set_value("config", "builtin_enabled", builtin_enabled) + + var err = config.save("res://addons/Todo_Manager/todo.cfg") + + +func load_config() -> void: + var config := ConfigFile.new() + if config.load("res://addons/Todo_Manager/todo.cfg") == OK: + full_path = config.get_value("scripts", "full_path", DEFAULT_SCRIPT_NAME) + _sort_alphabetical = config.get_value("scripts", "sort_alphabetical", DEFAULT_SORT) + script_colour = config.get_value("scripts", "script_colour", DEFAULT_SCRIPT_COLOUR) + ignore_paths = config.get_value("scripts", "ignore_paths", [] as Array[String]) + patterns = config.get_value("patterns", "patterns", DEFAULT_PATTERNS) + auto_refresh = config.get_value("config", "auto_refresh", true) + builtin_enabled = config.get_value("config", "builtin_enabled", false) + else: + create_config_file() + + +#### Events #### +func _on_SettingsButton_toggled(button_pressed: bool) -> void: + settings_panel.visible = button_pressed + if button_pressed == false: + create_config_file() +# plugin.find_tokens_from_path(plugin.script_cache) + if auto_refresh: + plugin.rescan_files(true) + +func _on_Tree_item_activated() -> void: + var item : TreeItem + match tabs.current_tab: + 0: + item = project_tree.get_selected() + 1: + item = current_tree.get_selected() + if item.get_metadata(0) is Todo: + var todo : Todo = item.get_metadata(0) + call_deferred("go_to_script", todo.script_path, todo.line_number) + else: + var todo_item = item.get_metadata(0) + call_deferred("go_to_script", todo_item.script_path) + +func _on_FullPathCheckBox_toggled(button_pressed: bool) -> void: + full_path = button_pressed + +func _on_ScriptColourPickerButton_color_changed(color: Color) -> void: + script_colour = color + +func _on_RescanButton_pressed() -> void: + plugin.rescan_files(true) + +func change_colour(colour: Color, index: int) -> void: + patterns[index][1] = colour + +func change_pattern(value: String, index: int, this_colour: Node) -> void: + patterns[index][0] = value + this_colour.title = value + plugin.rescan_files(true) + +func remove_pattern(index: int, this: Node, this_colour: Node) -> void: + patterns.remove_at(index) + this.queue_free() + this_colour.queue_free() + plugin.rescan_files(true) + +func case_sensitive_pattern(active: bool, index: int) -> void: + if active: + patterns[index][2] = CASE_SENSITIVE + else: + patterns[index][2] = CASE_INSENSITIVE + plugin.rescan_files(true) + +func _on_DefaultButton_pressed() -> void: + patterns = DEFAULT_PATTERNS.duplicate(true) + _sort_alphabetical = DEFAULT_SORT + script_colour = DEFAULT_SCRIPT_COLOUR + full_path = DEFAULT_SCRIPT_NAME + rebuild_settings() + plugin.rescan_files(true) + +func _on_AlphSortCheckBox_toggled(button_pressed: bool) -> void: + _sort_alphabetical = button_pressed + plugin.rescan_files(true) + +func _on_AddPatternButton_pressed() -> void: + patterns.append(["\\bplaceholder\\b", Color.WHITE, CASE_INSENSITIVE]) + rebuild_settings() + +func _on_RefreshCheckButton_toggled(button_pressed: bool) -> void: + auto_refresh = button_pressed + +func _on_Timer_timeout() -> void: + plugin.refresh_lock = false + +func _on_ignore_paths_changed(new_text: String) -> void: + var text = ignore_textbox.text + var split: Array = text.split(',') + ignore_paths.clear() + for elem in split: + if elem == " " || elem == "": + continue + ignore_paths.push_front(elem.lstrip(' ').rstrip(' ')) + # validate so no empty string slips through (all paths ignored) + var i := 0 + for path in ignore_paths: + if (path == "" || path == " "): + ignore_paths.remove_at(i) + i += 1 + plugin.rescan_files(true) + +func _on_TabContainer_tab_changed(tab: int) -> void: + build_tree() + +func _on_BuiltInCheckButton_toggled(button_pressed: bool) -> void: + builtin_enabled = button_pressed + plugin.rescan_files(true) diff --git a/addons/Todo_Manager/Pattern.gd b/addons/Todo_Manager/Pattern.gd new file mode 100644 index 0000000..4e610af --- /dev/null +++ b/addons/Todo_Manager/Pattern.gd @@ -0,0 +1,21 @@ +@tool +extends HBoxContainer + + +var text : String : set = set_text +var disabled : bool +var index : int + +@onready var line_edit := $LineEdit as LineEdit +@onready var remove_button := $RemoveButton as Button +@onready var case_checkbox := %CaseSensativeCheckbox as CheckBox + +func _ready() -> void: + line_edit.text = text + remove_button.disabled = disabled + + +func set_text(value: String) -> void: + text = value + if line_edit: + line_edit.text = value diff --git a/addons/Todo_Manager/Project.gd b/addons/Todo_Manager/Project.gd new file mode 100644 index 0000000..4af0847 --- /dev/null +++ b/addons/Todo_Manager/Project.gd @@ -0,0 +1,73 @@ +@tool +extends Panel + +signal tree_built # used for debugging + +const Todo := preload("res://addons/Todo_Manager/todo_class.gd") + +var _sort_alphabetical := true +var _full_path := false + +@onready var tree := $Tree as Tree + +func build_tree(todo_items : Array, ignore_paths : Array, patterns : Array, cased_patterns: Array[String], sort_alphabetical : bool, full_path : bool) -> void: + _full_path = full_path + tree.clear() + if sort_alphabetical: + todo_items.sort_custom(Callable(self, "sort_alphabetical")) + else: + todo_items.sort_custom(Callable(self, "sort_backwards")) + var root := tree.create_item() + root.set_text(0, "Scripts") + for todo_item in todo_items: + var ignore := false + for ignore_path in ignore_paths: + var script_path : String = todo_item.script_path + if script_path.begins_with(ignore_path) or script_path.begins_with("res://" + ignore_path) or script_path.begins_with("res:///" + ignore_path): + ignore = true + break + if ignore: + continue + var script := tree.create_item(root) + if full_path: + script.set_text(0, todo_item.script_path + " -------") + else: + script.set_text(0, todo_item.get_short_path() + " -------") + script.set_metadata(0, todo_item) + for todo in todo_item.todos: + var item := tree.create_item(script) + var content_header : String = todo.content + if "\n" in todo.content: + content_header = content_header.split("\n")[0] + "..." + item.set_text(0, "(%0) - %1".format([todo.line_number, content_header], "%_")) + item.set_tooltip_text(0, todo.content) + item.set_metadata(0, todo) + for i in range(0, len(cased_patterns)): + if cased_patterns[i] == todo.pattern: + item.set_custom_color(0, patterns[i][1]) + emit_signal("tree_built") + + +func sort_alphabetical(a, b) -> bool: + if _full_path: + if a.script_path < b.script_path: + return true + else: + return false + else: + if a.get_short_path() < b.get_short_path(): + return true + else: + return false + +func sort_backwards(a, b) -> bool: + if _full_path: + if a.script_path > b.script_path: + return true + else: + return false + else: + if a.get_short_path() > b.get_short_path(): + return true + else: + return false diff --git a/addons/Todo_Manager/README.md b/addons/Todo_Manager/README.md new file mode 100644 index 0000000..b723248 --- /dev/null +++ b/addons/Todo_Manager/README.md @@ -0,0 +1,60 @@ + +### Localised READMEs + - [简体中文](READMECN.md) (Simplified Chinese) + + +# TODO Manager + +![example_image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/example1.png) + +## Simple and flexible + +- Supports GDScript, C# and GDNative +- Seamlessly integrated into the Godot dock +- Lenient syntax. Write TODOs that suit your style +- Quickly jump to lines and launch external editors + +## Customizable + +![settings_example](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/example2.png) + +- Add your own RegEx patterns +- Set colours to your liking + +## Installation + +### Method 1 (Godot Asset Library) + +The most simple way to get started using TODO Manager is to use Godot's inbuilt Asset Library to install the plugin into your project. + +#### Step 1 + +Find TODO Manager in the Godot Asset Library. +![AssetLib image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/Instruct1.png) + +#### Step 2 + +Install the package. You may want to untick the /doc folder at this point as it is not necessary for the functions of the plugin. +![Filestrcture image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/Instruct3.png) + +#### Step 4 + +Enable the plugin in the project settings. +![Project image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/Instruct4.png) + +### Method 2 (GitHub) + +#### Step 1 + +Click Download ZIP from the 'Code' dropdown. +![GitHub image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/Instruct5.png) + +#### Step 2 + +- Unzip the file and add it into your project folder. Make sure 'addons' is a subdirectory of res:// +- DO NOT change the name of the 'addons' or 'Todo_Manager' folders as this will break the saving and loading of your settings. + +#### Step 3 + +Enable the plugin in the project settings. +![Project image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/Instruct4.png) diff --git a/addons/Todo_Manager/READMECN.md b/addons/Todo_Manager/READMECN.md new file mode 100644 index 0000000..7a248c8 --- /dev/null +++ b/addons/Todo_Manager/READMECN.md @@ -0,0 +1,56 @@ +# TODO Manager + + ![example_image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/example1.png) + +## 简单而灵活 + +- 支持 GDScript,C# 和 GDNative。 +- 无缝集成到 Godot dock 栏。 +- 宽松的语法,用适合你自己的风格写TODOs。 +- 快速跳转到某一行并启用外部编辑器。 + +## 可定制 + +![settings_example](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/example2.png) + +- 添加你自己的正则表达式。 +- 设置你喜欢的颜色。 + +## 安装 + +### 方法一 (Godot Asset Library) + +最简单的使用 TODO Manager 的方法,使用 Godot 内置的资源商店(Asset Library)来安装这个插件到你的项目。 + +#### 第一步 + +在资源商店搜索 TODO Manager。 +![AssetLib image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/Instruct1.png) + +#### 第二步 + +安装下载的插件,你可能需要取消勾选 /doc 文件夹,因为插件的功能不需要。 +![Filestrcture image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/Instruct3.png) + +#### 第三步 + +在项目设置里启用插件。 +![Project image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/Instruct4.png) + +### 方法二 (GitHub) + +#### 第一步 + +点击 Download ZIP。 +![GitHub image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/Instruct5.png) + +#### 第二步 + +- 解压文件并且放到你的项目文件夹。确保 “addons” 是 res:// 的子文件夹。 +- DO NOT change the name of the 'addons' or 'Todo_Manager' folders as this will break the saving and loading of your settings. +- 不要更改 “addons” 或 “Todo_Manager” 文件夹的名称,因为这会打破预设的保存和加载。 + +#### 第三步 + +在项目设置里启用这个插件。 +![Project image](https://github.com/OrigamiDev-Pete/TODO_Manager/blob/main/addons/Todo_Manager/doc/images/Instruct4.png) diff --git a/addons/Todo_Manager/UI/ColourPicker.tscn b/addons/Todo_Manager/UI/ColourPicker.tscn new file mode 100644 index 0000000..650899f --- /dev/null +++ b/addons/Todo_Manager/UI/ColourPicker.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=2 format=3 uid="uid://bie1xn8v1kd66"] + +[ext_resource type="Script" path="res://addons/Todo_Manager/ColourPicker.gd" id="1"] + +[node name="TODOColour" type="HBoxContainer"] +offset_right = 105.0 +offset_bottom = 31.0 +script = ExtResource("1") +metadata/_edit_use_custom_anchors = false + +[node name="Label" type="Label" parent="."] +offset_top = 4.0 +offset_right = 1.0 +offset_bottom = 27.0 + +[node name="TODOColourPickerButton" type="ColorPickerButton" parent="."] +custom_minimum_size = Vector2(40, 0) +offset_left = 65.0 +offset_right = 105.0 +offset_bottom = 31.0 +size_flags_horizontal = 10 diff --git a/addons/Todo_Manager/UI/Dock.tscn b/addons/Todo_Manager/UI/Dock.tscn new file mode 100644 index 0000000..096662a --- /dev/null +++ b/addons/Todo_Manager/UI/Dock.tscn @@ -0,0 +1,315 @@ +[gd_scene load_steps=6 format=3 uid="uid://b6k0dtftankcx"] + +[ext_resource type="Script" path="res://addons/Todo_Manager/Dock.gd" id="1"] +[ext_resource type="Script" path="res://addons/Todo_Manager/Project.gd" id="2"] +[ext_resource type="Script" path="res://addons/Todo_Manager/Current.gd" id="3"] + +[sub_resource type="ButtonGroup" id="ButtonGroup_kqxcu"] + +[sub_resource type="ButtonGroup" id="ButtonGroup_kltg3"] + +[node name="Dock" type="Control"] +custom_minimum_size = Vector2(0, 200) +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 3 +script = ExtResource("1") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = 4.0 +grow_horizontal = 2 +grow_vertical = 2 +metadata/_edit_layout_mode = 1 + +[node name="Header" type="HBoxContainer" parent="VBoxContainer"] +visible = false +layout_mode = 2 + +[node name="HeaderLeft" type="HBoxContainer" parent="VBoxContainer/Header"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Title" type="Label" parent="VBoxContainer/Header/HeaderLeft"] +layout_mode = 2 +text = "Todo Dock:" + +[node name="HeaderRight" type="HBoxContainer" parent="VBoxContainer/Header"] +layout_mode = 2 +size_flags_horizontal = 3 +alignment = 2 + +[node name="SettingsButton" type="Button" parent="VBoxContainer/Header/HeaderRight"] +visible = false +layout_mode = 2 +toggle_mode = true +text = "Settings" + +[node name="TabContainer" type="TabContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Project" type="Panel" parent="VBoxContainer/TabContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("2") + +[node name="Tree" type="Tree" parent="VBoxContainer/TabContainer/Project"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +hide_root = true + +[node name="Current" type="Panel" parent="VBoxContainer/TabContainer"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("3") + +[node name="Tree" type="Tree" parent="VBoxContainer/TabContainer/Current"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +hide_folding = true +hide_root = true + +[node name="Settings" type="Panel" parent="VBoxContainer/TabContainer"] +visible = false +layout_mode = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer/TabContainer/Settings"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="Scripts" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Scripts"] +layout_mode = 2 +text = "Scripts:" + +[node name="HSeparator" type="HSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Scripts"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 5 + +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer"] +layout_mode = 2 + +[node name="VSeparator" type="VSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2"] +layout_mode = 2 + +[node name="Scripts" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2"] +layout_mode = 2 + +[node name="ScriptName" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptName"] +layout_mode = 2 +text = "Script Name:" + +[node name="FullPathCheckBox" type="CheckBox" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptName"] +layout_mode = 2 +button_group = SubResource("ButtonGroup_kqxcu") +text = "Full path" + +[node name="ShortNameCheckBox" type="CheckBox" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptName"] +layout_mode = 2 +button_pressed = true +button_group = SubResource("ButtonGroup_kqxcu") +text = "Short name" + +[node name="ScriptSort" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptSort"] +layout_mode = 2 +text = "Sort Order:" + +[node name="AlphSortCheckBox" type="CheckBox" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptSort"] +layout_mode = 2 +button_pressed = true +button_group = SubResource("ButtonGroup_kltg3") +text = "Alphabetical" + +[node name="RAlphSortCheckBox" type="CheckBox" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptSort"] +layout_mode = 2 +button_group = SubResource("ButtonGroup_kltg3") +text = "Reverse Alphabetical" + +[node name="ScriptColour" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptColour"] +layout_mode = 2 +text = "Script Colour:" + +[node name="ScriptColourPickerButton" type="ColorPickerButton" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptColour"] +custom_minimum_size = Vector2(40, 0) +layout_mode = 2 +color = Color(0.8, 0.807843, 0.827451, 1) + +[node name="IgnorePaths" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/IgnorePaths"] +layout_mode = 2 +text = "Ignore Paths:" + +[node name="TextEdit" type="LineEdit" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/IgnorePaths"] +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +expand_to_text_length = true + +[node name="Label3" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/IgnorePaths"] +layout_mode = 2 +text = "(Separated by commas)" + +[node name="TODOColours" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/TODOColours"] +layout_mode = 2 +text = "TODO Colours:" + +[node name="HSeparator" type="HSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/TODOColours"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="HBoxContainer3" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="VSeparator" type="VSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer3"] +layout_mode = 2 + +[node name="Colours" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer3"] +layout_mode = 2 + +[node name="Patterns" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Patterns"] +layout_mode = 2 +text = "Patterns:" + +[node name="HSeparator" type="HSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Patterns"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="HBoxContainer4" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="VSeparator" type="VSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4"] +layout_mode = 2 + +[node name="Patterns" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="AddPatternButton" type="Button" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4/Patterns"] +layout_mode = 2 +size_flags_horizontal = 0 +text = "Add" + +[node name="Config" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Config"] +layout_mode = 2 +text = "Config:" + +[node name="HSeparator" type="HSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Config"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="HBoxContainer5" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="VSeparator" type="VSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5"] +layout_mode = 2 + +[node name="Patterns" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5"] +layout_mode = 2 + +[node name="RefreshCheckButton" type="CheckButton" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns"] +layout_mode = 2 +size_flags_horizontal = 0 +button_pressed = true +text = "Auto Refresh" + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns"] +layout_mode = 2 + +[node name="BuiltInCheckButton" type="CheckButton" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns/HBoxContainer"] +layout_mode = 2 +text = "Scan Built-in Scripts" + +[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns/HBoxContainer"] +layout_mode = 2 + +[node name="DefaultButton" type="Button" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns"] +layout_mode = 2 +size_flags_horizontal = 0 +text = "Reset to default" + +[node name="Timer" type="Timer" parent="."] +one_shot = true + +[node name="RescanButton" type="Button" parent="."] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -102.0 +offset_top = 3.0 +offset_bottom = 34.0 +grow_horizontal = 0 +text = "Rescan Files" +flat = true + +[connection signal="toggled" from="VBoxContainer/Header/HeaderRight/SettingsButton" to="." method="_on_SettingsButton_toggled"] +[connection signal="tab_changed" from="VBoxContainer/TabContainer" to="." method="_on_TabContainer_tab_changed"] +[connection signal="item_activated" from="VBoxContainer/TabContainer/Project/Tree" to="." method="_on_Tree_item_activated"] +[connection signal="item_activated" from="VBoxContainer/TabContainer/Current/Tree" to="." method="_on_Tree_item_activated"] +[connection signal="toggled" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptName/FullPathCheckBox" to="." method="_on_FullPathCheckBox_toggled"] +[connection signal="toggled" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptSort/AlphSortCheckBox" to="." method="_on_AlphSortCheckBox_toggled"] +[connection signal="color_changed" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptColour/ScriptColourPickerButton" to="." method="_on_ScriptColourPickerButton_color_changed"] +[connection signal="pressed" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4/Patterns/AddPatternButton" to="." method="_on_AddPatternButton_pressed"] +[connection signal="toggled" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns/RefreshCheckButton" to="." method="_on_RefreshCheckButton_toggled"] +[connection signal="toggled" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns/HBoxContainer/BuiltInCheckButton" to="." method="_on_BuiltInCheckButton_toggled"] +[connection signal="pressed" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns/DefaultButton" to="." method="_on_DefaultButton_pressed"] +[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"] +[connection signal="pressed" from="RescanButton" to="." method="_on_RescanButton_pressed"] diff --git a/addons/Todo_Manager/UI/Pattern.tscn b/addons/Todo_Manager/UI/Pattern.tscn new file mode 100644 index 0000000..fb45615 --- /dev/null +++ b/addons/Todo_Manager/UI/Pattern.tscn @@ -0,0 +1,26 @@ +[gd_scene load_steps=2 format=3 uid="uid://bx11sel2q5wli"] + +[ext_resource type="Script" path="res://addons/Todo_Manager/Pattern.gd" id="1"] + +[node name="Pattern" type="HBoxContainer"] +script = ExtResource("1") + +[node name="LineEdit" type="LineEdit" parent="."] +layout_mode = 2 +size_flags_horizontal = 0 +expand_to_text_length = true + +[node name="RemoveButton" type="Button" parent="."] +layout_mode = 2 +text = "-" + +[node name="MarginContainer" type="MarginContainer" parent="."] +custom_minimum_size = Vector2(20, 0) +layout_mode = 2 +size_flags_horizontal = 0 + +[node name="CaseSensativeCheckbox" type="CheckBox" parent="."] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 0 +text = "Case Sensitive" diff --git a/addons/Todo_Manager/doc/example.gd b/addons/Todo_Manager/doc/example.gd new file mode 100644 index 0000000..859bbba --- /dev/null +++ b/addons/Todo_Manager/doc/example.gd @@ -0,0 +1,7 @@ +extends Node + +# TODO: this is a TODO +# HACK: this is a HACK +# FIXME: this is a FIXME +# TODO this works too +#Hack any format will do diff --git a/addons/Todo_Manager/doc/images/Instruct1.png b/addons/Todo_Manager/doc/images/Instruct1.png new file mode 100644 index 0000000..99a8db0 Binary files /dev/null and b/addons/Todo_Manager/doc/images/Instruct1.png differ diff --git a/addons/Todo_Manager/doc/images/Instruct2.png b/addons/Todo_Manager/doc/images/Instruct2.png new file mode 100644 index 0000000..83798f9 Binary files /dev/null and b/addons/Todo_Manager/doc/images/Instruct2.png differ diff --git a/addons/Todo_Manager/doc/images/Instruct3.png b/addons/Todo_Manager/doc/images/Instruct3.png new file mode 100644 index 0000000..283c604 Binary files /dev/null and b/addons/Todo_Manager/doc/images/Instruct3.png differ diff --git a/addons/Todo_Manager/doc/images/Instruct4.png b/addons/Todo_Manager/doc/images/Instruct4.png new file mode 100644 index 0000000..66ef1c9 Binary files /dev/null and b/addons/Todo_Manager/doc/images/Instruct4.png differ diff --git a/addons/Todo_Manager/doc/images/Instruct5.png b/addons/Todo_Manager/doc/images/Instruct5.png new file mode 100644 index 0000000..d418faf Binary files /dev/null and b/addons/Todo_Manager/doc/images/Instruct5.png differ diff --git a/addons/Todo_Manager/doc/images/TODO_Manager_Logo.png b/addons/Todo_Manager/doc/images/TODO_Manager_Logo.png new file mode 100644 index 0000000..6d19fee Binary files /dev/null and b/addons/Todo_Manager/doc/images/TODO_Manager_Logo.png differ diff --git a/addons/Todo_Manager/doc/images/TodoExternal.gif b/addons/Todo_Manager/doc/images/TodoExternal.gif new file mode 100644 index 0000000..25d0850 Binary files /dev/null and b/addons/Todo_Manager/doc/images/TodoExternal.gif differ diff --git a/addons/Todo_Manager/doc/images/example1.png b/addons/Todo_Manager/doc/images/example1.png new file mode 100644 index 0000000..786bd15 Binary files /dev/null and b/addons/Todo_Manager/doc/images/example1.png differ diff --git a/addons/Todo_Manager/doc/images/example2.png b/addons/Todo_Manager/doc/images/example2.png new file mode 100644 index 0000000..256d754 Binary files /dev/null and b/addons/Todo_Manager/doc/images/example2.png differ diff --git a/addons/Todo_Manager/plugin.cfg b/addons/Todo_Manager/plugin.cfg new file mode 100644 index 0000000..256be46 --- /dev/null +++ b/addons/Todo_Manager/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Todo Manager" +description="Dock for housing TODO messages." +author="Peter de Vroom" +version="2.3.1" +script="plugin.gd" diff --git a/addons/Todo_Manager/plugin.gd b/addons/Todo_Manager/plugin.gd new file mode 100644 index 0000000..511458d --- /dev/null +++ b/addons/Todo_Manager/plugin.gd @@ -0,0 +1,286 @@ +@tool +extends EditorPlugin + +const DockScene := preload("res://addons/Todo_Manager/UI/Dock.tscn") +const Dock := preload("res://addons/Todo_Manager/Dock.gd") +const Todo := preload("res://addons/Todo_Manager/todo_class.gd") +const TodoItem := preload("res://addons/Todo_Manager/todoItem_class.gd") + +var _dockUI : Dock + +class TodoCacheValue: + var todos: Array + var last_modified_time: int + + func _init(todos: Array, last_modified_time: int): + self.todos = todos + self.last_modified_time = last_modified_time + +var todo_cache : Dictionary # { key: script_path, value: TodoCacheValue } +var remove_queue : Array +var combined_pattern : String +var cased_patterns : Array[String] + +var refresh_lock := false # makes sure _on_filesystem_changed only triggers once + + +func _enter_tree() -> void: + _dockUI = DockScene.instantiate() as Control + add_control_to_bottom_panel(_dockUI, "TODO") + get_editor_interface().get_resource_filesystem().connect("filesystem_changed", + _on_filesystem_changed) + get_editor_interface().get_file_system_dock().connect("file_removed", queue_remove) + get_editor_interface().get_script_editor().connect("editor_script_changed", + _on_active_script_changed) + _dockUI.plugin = self + + combined_pattern = combine_patterns(_dockUI.patterns) + find_tokens_from_path(find_scripts()) + _dockUI.build_tree() + + +func _exit_tree() -> void: + _dockUI.create_config_file() + remove_control_from_bottom_panel(_dockUI) + _dockUI.free() + + +func queue_remove(file: String): + for i in _dockUI.todo_items.size() - 1: + if _dockUI.todo_items[i].script_path == file: + _dockUI.todo_items.remove_at(i) + + +func find_tokens_from_path(scripts: Array[String]) -> void: + for script_path in scripts: + var file := FileAccess.open(script_path, FileAccess.READ) + var contents := file.get_as_text() + if script_path.ends_with(".tscn"): + handle_built_in_scripts(contents, script_path) + else: + find_tokens(contents, script_path) + + +func handle_built_in_scripts(contents: String, resource_path: String): + var s := contents.split("sub_resource type=\"GDScript\"") + if s.size() <= 1: + return + for i in range(1, s.size()): + var script_components := s[i].split("script/source") + var script_name = script_components[0].substr(5, 14) + find_tokens(script_components[1], resource_path + "::" + script_name) + + +func find_tokens(text: String, script_path: String) -> void: + var cached_todos = get_cached_todos(script_path) + if cached_todos.size() != 0: +# var i := 0 +# for todo_item in _dockUI.todo_items: +# if todo_item.script_path == script_path: +# _dockUI.todo_items.remove_at(i) +# i += 1 + var todo_item := TodoItem.new(script_path, cached_todos) + _dockUI.todo_items.append(todo_item) + else: + var regex = RegEx.new() + # if regex.compile("#\\s*\\bTODO\\b.*|#\\s*\\bHACK\\b.*") == OK: + if regex.compile(combined_pattern) == OK: + var result : Array[RegExMatch] = regex.search_all(text) + if result.is_empty(): + for i in _dockUI.todo_items.size(): + if _dockUI.todo_items[i].script_path == script_path: + _dockUI.todo_items.remove_at(i) + return # No tokens found + var match_found : bool + var i := 0 + for todo_item in _dockUI.todo_items: + if todo_item.script_path == script_path: + match_found = true + var updated_todo_item := update_todo_item(todo_item, result, text, script_path) + _dockUI.todo_items.remove_at(i) + _dockUI.todo_items.insert(i, updated_todo_item) + break + i += 1 + if !match_found: + _dockUI.todo_items.append(create_todo_item(result, text, script_path)) + + +func create_todo_item(regex_results: Array[RegExMatch], text: String, script_path: String) -> TodoItem: + var todo_item = TodoItem.new(script_path, []) + todo_item.script_path = script_path + var last_line_number := 0 + var lines := text.split("\n") + for r in regex_results: + var new_todo : Todo = create_todo(r.get_string(), script_path) + new_todo.line_number = get_line_number(r.get_string(), text, last_line_number) + # GD Multiline comment + var trailing_line := new_todo.line_number + var should_break = false + while trailing_line < lines.size() and lines[trailing_line].dedent().begins_with("#"): + for other_r in regex_results: + if lines[trailing_line] in other_r.get_string(): + should_break = true + break + if should_break: + break + + new_todo.content += "\n" + lines[trailing_line] + trailing_line += 1 + + last_line_number = new_todo.line_number + todo_item.todos.append(new_todo) + cache_todos(todo_item.todos, script_path) + return todo_item + + +func update_todo_item(todo_item: TodoItem, regex_results: Array[RegExMatch], text: String, script_path: String) -> TodoItem: + todo_item.todos.clear() + var lines := text.split("\n") + for r in regex_results: + var new_todo : Todo = create_todo(r.get_string(), script_path) + new_todo.line_number = get_line_number(r.get_string(), text) + # GD Multiline comment + var trailing_line := new_todo.line_number + var should_break = false + while trailing_line < lines.size() and lines[trailing_line].dedent().begins_with("#"): + for other_r in regex_results: + if lines[trailing_line] in other_r.get_string(): + should_break = true + break + if should_break: + break + + new_todo.content += "\n" + lines[trailing_line] + trailing_line += 1 + todo_item.todos.append(new_todo) + return todo_item + + +func get_line_number(what: String, from: String, start := 0) -> int: + what = what.split('\n')[0] # Match first line of multiline C# comments + var temp_array := from.split('\n') + var lines := Array(temp_array) + var line_number# = lines.find(what) + 1 + for i in range(start, lines.size()): + if what in lines[i]: + line_number = i + 1 # +1 to account of 0-based array vs 1-based line numbers + break + else: + line_number = 0 # This is an error + return line_number + + +func _on_filesystem_changed() -> void: + if !refresh_lock: + if _dockUI.auto_refresh: + refresh_lock = true + _dockUI.get_node("Timer").start() + rescan_files(false) + + +func find_scripts() -> Array[String]: + var scripts : Array[String] + var directory_queue : Array[String] + var dir := DirAccess.open("res://") + if dir.get_open_error() == OK: + get_dir_contents(dir, scripts, directory_queue) + else: + printerr("TODO_Manager: There was an error during find_scripts()") + + while not directory_queue.is_empty(): + if dir.change_dir(directory_queue[0]) == OK: + get_dir_contents(dir, scripts, directory_queue) + else: + printerr("TODO_Manager: There was an error at: " + directory_queue[0]) + directory_queue.pop_front() + + return scripts + + +func cache_todos(todos: Array, script_path: String) -> void: + var last_modified_time = FileAccess.get_modified_time(script_path) + todo_cache[script_path] = TodoCacheValue.new(todos, last_modified_time) + + +func get_cached_todos(script_path: String) -> Array: + if todo_cache.has(script_path) and !script_path.contains("tscn::"): + var cached_value: TodoCacheValue = todo_cache[script_path] + if cached_value.last_modified_time == FileAccess.get_modified_time(script_path): + + return cached_value.todos + return [] + +func get_dir_contents(dir: DirAccess, scripts: Array[String], directory_queue: Array[String]) -> void: + dir.include_navigational = false + dir.include_hidden = false + dir.list_dir_begin() + var file_name : String = dir.get_next() + + while file_name != "": + if dir.current_is_dir(): + if file_name == ".import" or file_name == ".mono": # Skip .import folder which should never have scripts + pass + else: + directory_queue.append(dir.get_current_dir().path_join(file_name)) + else: + if file_name.ends_with(".gd") or file_name.ends_with(".cs") \ + or file_name.ends_with(".c") or file_name.ends_with(".cpp") or file_name.ends_with(".h") \ + or ((file_name.ends_with(".tscn") and _dockUI.builtin_enabled)): + scripts.append(dir.get_current_dir().path_join(file_name)) + file_name = dir.get_next() + + +func rescan_files(clear_cache: bool) -> void: + _dockUI.todo_items.clear() + if clear_cache: + todo_cache.clear() + combined_pattern = combine_patterns(_dockUI.patterns) + find_tokens_from_path(find_scripts()) + _dockUI.build_tree() + + +func combine_patterns(patterns: Array) -> String: + # Case Sensitivity + cased_patterns = [] + for pattern in patterns: + if pattern[2] == _dockUI.CASE_INSENSITIVE: + cased_patterns.append(pattern[0].insert(0, "((?i)") + ")") + else: + cased_patterns.append("(" + pattern[0] + ")") + + if patterns.size() == 1: + return cased_patterns[0] + else: + var pattern_string := "((\\/\\*)|(#|\\/\\/))\\s*(" + for i in range(patterns.size()): + if i == 0: + pattern_string += cased_patterns[i] + else: + pattern_string += "|" + cased_patterns[i] + pattern_string += ")(?(2)[\\s\\S]*?\\*\\/|.*)" + return pattern_string + + +func create_todo(todo_string: String, script_path: String) -> Todo: + var todo := Todo.new() + var regex = RegEx.new() + for pattern in cased_patterns: + if regex.compile(pattern) == OK: + var result : RegExMatch = regex.search(todo_string) + if result: + todo.pattern = pattern + todo.title = result.strings[0] + else: + continue + else: + printerr("Error compiling " + pattern) + + todo.content = todo_string + todo.script_path = script_path + return todo + + +func _on_active_script_changed(script) -> void: + if _dockUI: + if _dockUI.tabs.current_tab == 1: + _dockUI.build_tree() diff --git a/addons/Todo_Manager/todo.cfg b/addons/Todo_Manager/todo.cfg new file mode 100644 index 0000000..acef3bc --- /dev/null +++ b/addons/Todo_Manager/todo.cfg @@ -0,0 +1,15 @@ +[scripts] + +full_path=false +sort_alphabetical=true +script_colour=Color(0.8, 0.807843, 0.827451, 1) +ignore_paths=Array[String]([]) + +[patterns] + +patterns=[["\\bTODO\\b", Color(0.588235, 0.945098, 0.678431, 1), 0], ["\\bHACK\\b", Color(0.835294, 0.737255, 0.439216, 1), 0], ["\\bFIXME\\b", Color(0.835294, 0.439216, 0.439216, 1), 0]] + +[config] + +auto_refresh=true +builtin_enabled=false diff --git a/addons/Todo_Manager/todoItem_class.gd b/addons/Todo_Manager/todoItem_class.gd new file mode 100644 index 0000000..9bcb000 --- /dev/null +++ b/addons/Todo_Manager/todoItem_class.gd @@ -0,0 +1,18 @@ +@tool +extends RefCounted + +var script_path : String +var todos : Array + +func _init(script_path: String, todos: Array): + self.script_path = script_path + self.todos = todos + +func get_short_path() -> String: + var temp_array := script_path.rsplit('/', false, 1) + var short_path : String + if not temp_array.size() > 1: + short_path = "(!)" + temp_array[0] + else: + short_path = temp_array[1] + return short_path diff --git a/addons/Todo_Manager/todo_class.gd b/addons/Todo_Manager/todo_class.gd new file mode 100644 index 0000000..af6b26b --- /dev/null +++ b/addons/Todo_Manager/todo_class.gd @@ -0,0 +1,9 @@ +@tool +extends RefCounted + + +var pattern : String +var title : String +var content : String +var script_path : String +var line_number : int diff --git a/addons/godot_rl_agents/controller/ai_controller_2d.gd b/addons/godot_rl_agents/controller/ai_controller_2d.gd new file mode 100644 index 0000000..0a32a64 --- /dev/null +++ b/addons/godot_rl_agents/controller/ai_controller_2d.gd @@ -0,0 +1,119 @@ +extends Node2D +class_name AIController2D + +enum ControlModes { INHERIT_FROM_SYNC, HUMAN, TRAINING, ONNX_INFERENCE, RECORD_EXPERT_DEMOS } +@export var control_mode: ControlModes = ControlModes.INHERIT_FROM_SYNC +@export var onnx_model_path := "" +@export var reset_after := 1000 + +@export_group("Record expert demos mode options") +## Path where the demos will be saved. The file can later be used for imitation learning. +@export var expert_demo_save_path: String +## The action that erases the last recorded episode from the currently recorded data. +@export var remove_last_episode_key: InputEvent +## Action will be repeated for n frames. Will introduce control lag if larger than 1. +## Can be used to ensure that action_repeat on inference and training matches +## the recorded demonstrations. +@export var action_repeat: int = 1 + +@export_group("Multi-policy mode options") +## Allows you to set certain agents to use different policies. +## Changing has no effect with default SB3 training. Works with Rllib example. +## Tutorial: https://github.com/edbeeching/godot_rl_agents/blob/main/docs/TRAINING_MULTIPLE_POLICIES.md +@export var policy_name: String = "shared_policy" + +var onnx_model: ONNXModel + +var heuristic := "human" +var done := false +var reward := 0.0 +var n_steps := 0 +var needs_reset := false + +var _player: Node2D + + +func _ready(): + add_to_group("AGENT") + + +func init(player: Node2D): + _player = player + + +#-- Methods that need implementing using the "extend script" option in Godot --# +func get_obs() -> Dictionary: + assert(false, "the get_obs method is not implemented when extending from ai_controller") + return {"obs": []} + + +func get_reward() -> float: + assert(false, "the get_reward method is not implemented when extending from ai_controller") + return 0.0 + + +func get_action_space() -> Dictionary: + assert( + false, + "the get get_action_space method is not implemented when extending from ai_controller" + ) + return { + "example_actions_continous": {"size": 2, "action_type": "continuous"}, + "example_actions_discrete": {"size": 2, "action_type": "discrete"}, + } + + +func set_action(action) -> void: + assert(false, "the set_action method is not implemented when extending from ai_controller") + + +#-----------------------------------------------------------------------------# + + +#-- Methods that sometimes need implementing using the "extend script" option in Godot --# +# Only needed if you are recording expert demos with this AIController +func get_action() -> Array: + assert(false, "the get_action method is not implemented in extended AIController but demo_recorder is used") + return [] + +# -----------------------------------------------------------------------------# + +func _physics_process(delta): + n_steps += 1 + if n_steps > reset_after: + needs_reset = true + + +func get_obs_space(): + # may need overriding if the obs space is complex + var obs = get_obs() + return { + "obs": {"size": [len(obs["obs"])], "space": "box"}, + } + + +func reset(): + n_steps = 0 + needs_reset = false + + +func reset_if_done(): + if done: + reset() + + +func set_heuristic(h): + # sets the heuristic from "human" or "model" nothing to change here + heuristic = h + + +func get_done(): + return done + + +func set_done_false(): + done = false + + +func zero_reward(): + reward = 0.0 diff --git a/addons/godot_rl_agents/controller/ai_controller_3d.gd b/addons/godot_rl_agents/controller/ai_controller_3d.gd new file mode 100644 index 0000000..c77d9e0 --- /dev/null +++ b/addons/godot_rl_agents/controller/ai_controller_3d.gd @@ -0,0 +1,120 @@ +extends Node3D +class_name AIController3D + +enum ControlModes { INHERIT_FROM_SYNC, HUMAN, TRAINING, ONNX_INFERENCE, RECORD_EXPERT_DEMOS } +@export var control_mode: ControlModes = ControlModes.INHERIT_FROM_SYNC +@export var onnx_model_path := "" +@export var reset_after := 1000 + +@export_group("Record expert demos mode options") +## Path where the demos will be saved. The file can later be used for imitation learning. +@export var expert_demo_save_path: String +## The action that erases the last recorded episode from the currently recorded data. +@export var remove_last_episode_key: InputEvent +## Action will be repeated for n frames. Will introduce control lag if larger than 1. +## Can be used to ensure that action_repeat on inference and training matches +## the recorded demonstrations. +@export var action_repeat: int = 1 + +@export_group("Multi-policy mode options") +## Allows you to set certain agents to use different policies. +## Changing has no effect with default SB3 training. Works with Rllib example. +## Tutorial: https://github.com/edbeeching/godot_rl_agents/blob/main/docs/TRAINING_MULTIPLE_POLICIES.md +@export var policy_name: String = "shared_policy" + +var onnx_model: ONNXModel + +var heuristic := "human" +var done := false +var reward := 0.0 +var n_steps := 0 +var needs_reset := false + +var _player: Node3D + + +func _ready(): + add_to_group("AGENT") + + +func init(player: Node3D): + _player = player + + +#-- Methods that need implementing using the "extend script" option in Godot --# +func get_obs() -> Dictionary: + assert(false, "the get_obs method is not implemented when extending from ai_controller") + return {"obs": []} + + +func get_reward() -> float: + assert(false, "the get_reward method is not implemented when extending from ai_controller") + return 0.0 + + +func get_action_space() -> Dictionary: + assert( + false, + "the get_action_space method is not implemented when extending from ai_controller" + ) + return { + "example_actions_continous": {"size": 2, "action_type": "continuous"}, + "example_actions_discrete": {"size": 2, "action_type": "discrete"}, + } + + +func set_action(action) -> void: + assert(false, "the set_action method is not implemented when extending from ai_controller") + + +#-----------------------------------------------------------------------------# + + +#-- Methods that sometimes need implementing using the "extend script" option in Godot --# +# Only needed if you are recording expert demos with this AIController +func get_action() -> Array: + assert(false, "the get_action method is not implemented in extended AIController but demo_recorder is used") + return [] + +# -----------------------------------------------------------------------------# + + +func _physics_process(delta): + n_steps += 1 + if n_steps > reset_after: + needs_reset = true + + +func get_obs_space(): + # may need overriding if the obs space is complex + var obs = get_obs() + return { + "obs": {"size": [len(obs["obs"])], "space": "box"}, + } + + +func reset(): + n_steps = 0 + needs_reset = false + + +func reset_if_done(): + if done: + reset() + + +func set_heuristic(h): + # sets the heuristic from "human" or "model" nothing to change here + heuristic = h + + +func get_done(): + return done + + +func set_done_false(): + done = false + + +func zero_reward(): + reward = 0.0 diff --git a/addons/godot_rl_agents/godot_rl_agents.gd b/addons/godot_rl_agents/godot_rl_agents.gd new file mode 100644 index 0000000..e4fe136 --- /dev/null +++ b/addons/godot_rl_agents/godot_rl_agents.gd @@ -0,0 +1,16 @@ +@tool +extends EditorPlugin + + +func _enter_tree(): + # Initialization of the plugin goes here. + # Add the new type with a name, a parent type, a script and an icon. + add_custom_type("Sync", "Node", preload("sync.gd"), preload("icon.png")) + #add_custom_type("RaycastSensor2D2", "Node", preload("raycast_sensor_2d.gd"), preload("icon.png")) + + +func _exit_tree(): + # Clean-up of the plugin goes here. + # Always remember to remove it from the engine when deactivated. + remove_custom_type("Sync") + #remove_custom_type("RaycastSensor2D2") diff --git a/addons/godot_rl_agents/icon.png b/addons/godot_rl_agents/icon.png new file mode 100644 index 0000000..fd8190e Binary files /dev/null and b/addons/godot_rl_agents/icon.png differ diff --git a/addons/godot_rl_agents/onnx/csharp/ONNXInference.cs b/addons/godot_rl_agents/onnx/csharp/ONNXInference.cs new file mode 100644 index 0000000..6dcfa18 --- /dev/null +++ b/addons/godot_rl_agents/onnx/csharp/ONNXInference.cs @@ -0,0 +1,109 @@ +using Godot; +using Microsoft.ML.OnnxRuntime; +using Microsoft.ML.OnnxRuntime.Tensors; +using System.Collections.Generic; +using System.Linq; + +namespace GodotONNX +{ + /// + public partial class ONNXInference : GodotObject + { + + private InferenceSession session; + /// + /// Path to the ONNX model. Use Initialize to change it. + /// + private string modelPath; + private int batchSize; + + private SessionOptions SessionOpt; + + /// + /// init function + /// + /// + /// + /// Returns the output size of the model + public int Initialize(string Path, int BatchSize) + { + modelPath = Path; + batchSize = BatchSize; + SessionOpt = SessionConfigurator.MakeConfiguredSessionOptions(); + session = LoadModel(modelPath); + return session.OutputMetadata["output"].Dimensions[1]; + } + + + /// + public Godot.Collections.Dictionary> RunInference(Godot.Collections.Array obs, int state_ins) + { + //Current model: Any (Godot Rl Agents) + //Expects a tensor of shape [batch_size, input_size] type float named obs and a tensor of shape [batch_size] type float named state_ins + + //Fill the input tensors + // create span from inputSize + var span = new float[obs.Count]; //There's probably a better way to do this + for (int i = 0; i < obs.Count; i++) + { + span[i] = obs[i]; + } + + IReadOnlyCollection inputs = new List + { + NamedOnnxValue.CreateFromTensor("obs", new DenseTensor(span, new int[] { batchSize, obs.Count })), + NamedOnnxValue.CreateFromTensor("state_ins", new DenseTensor(new float[] { state_ins }, new int[] { batchSize })) + }; + IReadOnlyCollection outputNames = new List { "output", "state_outs" }; //ONNX is sensible to these names, as well as the input names + + IDisposableReadOnlyCollection results; + //We do not use "using" here so we get a better exception explaination later + try + { + results = session.Run(inputs, outputNames); + } + catch (OnnxRuntimeException e) + { + //This error usually means that the model is not compatible with the input, beacause of the input shape (size) + GD.Print("Error at inference: ", e); + return null; + } + //Can't convert IEnumerable to Variant, so we have to convert it to an array or something + Godot.Collections.Dictionary> output = new Godot.Collections.Dictionary>(); + DisposableNamedOnnxValue output1 = results.First(); + DisposableNamedOnnxValue output2 = results.Last(); + Godot.Collections.Array output1Array = new Godot.Collections.Array(); + Godot.Collections.Array output2Array = new Godot.Collections.Array(); + + foreach (float f in output1.AsEnumerable()) + { + output1Array.Add(f); + } + + foreach (float f in output2.AsEnumerable()) + { + output2Array.Add(f); + } + + output.Add(output1.Name, output1Array); + output.Add(output2.Name, output2Array); + + //Output is a dictionary of arrays, ex: { "output" : [0.1, 0.2, 0.3, 0.4, ...], "state_outs" : [0.5, ...]} + results.Dispose(); + return output; + } + /// + public InferenceSession LoadModel(string Path) + { + using Godot.FileAccess file = FileAccess.Open(Path, Godot.FileAccess.ModeFlags.Read); + byte[] model = file.GetBuffer((int)file.GetLength()); + //file.Close(); file.Dispose(); //Close the file, then dispose the reference. + return new InferenceSession(model, SessionOpt); //Load the model + } + public void FreeDisposables() + { + session.Dispose(); + SessionOpt.Dispose(); + } + } +} diff --git a/addons/godot_rl_agents/onnx/csharp/SessionConfigurator.cs b/addons/godot_rl_agents/onnx/csharp/SessionConfigurator.cs new file mode 100644 index 0000000..ad7a41c --- /dev/null +++ b/addons/godot_rl_agents/onnx/csharp/SessionConfigurator.cs @@ -0,0 +1,131 @@ +using Godot; +using Microsoft.ML.OnnxRuntime; + +namespace GodotONNX +{ + /// + + public static class SessionConfigurator + { + public enum ComputeName + { + CUDA, + ROCm, + DirectML, + CoreML, + CPU + } + + /// + public static SessionOptions MakeConfiguredSessionOptions() + { + SessionOptions sessionOptions = new(); + SetOptions(sessionOptions); + return sessionOptions; + } + + private static void SetOptions(SessionOptions sessionOptions) + { + sessionOptions.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_WARNING; + ApplySystemSpecificOptions(sessionOptions); + } + + /// + static public void ApplySystemSpecificOptions(SessionOptions sessionOptions) + { + //Most code for this function is verbose only, the only reason it exists is to track + //implementation progress of the different compute APIs. + + //December 2022: CUDA is not working. + + string OSName = OS.GetName(); //Get OS Name + + //ComputeName ComputeAPI = ComputeCheck(); //Get Compute API + // //TODO: Get CPU architecture + + //Linux can use OpenVINO (C#) on x64 and ROCm on x86 (GDNative/C++) + //Windows can use OpenVINO (C#) on x64 + //TODO: try TensorRT instead of CUDA + //TODO: Use OpenVINO for Intel Graphics + + // Temporarily using CPU on all platforms to avoid errors detected with DML + ComputeName ComputeAPI = ComputeName.CPU; + + //match OS and Compute API + GD.Print($"OS: {OSName} Compute API: {ComputeAPI}"); + + // CPU is set by default without appending necessary + // sessionOptions.AppendExecutionProvider_CPU(0); + + /* + switch (OSName) + { + case "Windows": //Can use CUDA, DirectML + if (ComputeAPI is ComputeName.CUDA) + { + //CUDA + //sessionOptions.AppendExecutionProvider_CUDA(0); + //sessionOptions.AppendExecutionProvider_DML(0); + } + else if (ComputeAPI is ComputeName.DirectML) + { + //DirectML + //sessionOptions.AppendExecutionProvider_DML(0); + } + break; + case "X11": //Can use CUDA, ROCm + if (ComputeAPI is ComputeName.CUDA) + { + //CUDA + //sessionOptions.AppendExecutionProvider_CUDA(0); + } + if (ComputeAPI is ComputeName.ROCm) + { + //ROCm, only works on x86 + //Research indicates that this has to be compiled as a GDNative plugin + //GD.Print("ROCm not supported yet, using CPU."); + //sessionOptions.AppendExecutionProvider_CPU(0); + } + break; + case "macOS": //Can use CoreML + if (ComputeAPI is ComputeName.CoreML) + { //CoreML + //TODO: Needs testing + //sessionOptions.AppendExecutionProvider_CoreML(0); + //CoreML on ARM64, out of the box, on x64 needs .tar file from GitHub + } + break; + default: + GD.Print("OS not Supported."); + break; + } + */ + } + + + /// + public static ComputeName ComputeCheck() + { + string adapterName = Godot.RenderingServer.GetVideoAdapterName(); + //string adapterVendor = Godot.RenderingServer.GetVideoAdapterVendor(); + adapterName = adapterName.ToUpper(new System.Globalization.CultureInfo("")); + //TODO: GPU vendors for MacOS, what do they even use these days? + + if (adapterName.Contains("INTEL")) + { + return ComputeName.DirectML; + } + if (adapterName.Contains("AMD") || adapterName.Contains("RADEON")) + { + return ComputeName.DirectML; + } + if (adapterName.Contains("NVIDIA")) + { + return ComputeName.CUDA; + } + + GD.Print("Graphics Card not recognized."); //Should use CPU + return ComputeName.CPU; + } + } +} diff --git a/addons/godot_rl_agents/onnx/csharp/docs/ONNXInference.xml b/addons/godot_rl_agents/onnx/csharp/docs/ONNXInference.xml new file mode 100644 index 0000000..91b07d6 --- /dev/null +++ b/addons/godot_rl_agents/onnx/csharp/docs/ONNXInference.xml @@ -0,0 +1,31 @@ + + + + + The main ONNXInference Class that handles the inference process. + + + + + Starts the inference process. + + Path to the ONNX model, expects a path inside resources. + How many observations will the model recieve. + + + + Runs the given input through the model and returns the output. + + Dictionary containing all observations. + How many different agents are creating these observations. + A Dictionary of arrays, containing instructions based on the observations. + + + + Loads the given model into the inference process, using the best Execution provider available. + + Path to the ONNX model, expects a path inside resources. + InferenceSession ready to run. + + + \ No newline at end of file diff --git a/addons/godot_rl_agents/onnx/csharp/docs/SessionConfigurator.xml b/addons/godot_rl_agents/onnx/csharp/docs/SessionConfigurator.xml new file mode 100644 index 0000000..f160c02 --- /dev/null +++ b/addons/godot_rl_agents/onnx/csharp/docs/SessionConfigurator.xml @@ -0,0 +1,29 @@ + + + + + The main SessionConfigurator Class that handles the execution options and providers for the inference process. + + + + + Creates a SessionOptions with all available execution providers. + + SessionOptions with all available execution providers. + + + + Appends any execution provider available in the current system. + + + This function is mainly verbose for tracking implementation progress of different compute APIs. + + + + + Checks for available GPUs. + + An integer identifier for each compute platform. + + + \ No newline at end of file diff --git a/addons/godot_rl_agents/onnx/wrapper/ONNX_wrapper.gd b/addons/godot_rl_agents/onnx/wrapper/ONNX_wrapper.gd new file mode 100644 index 0000000..e27f2c3 --- /dev/null +++ b/addons/godot_rl_agents/onnx/wrapper/ONNX_wrapper.gd @@ -0,0 +1,51 @@ +extends Resource +class_name ONNXModel +var inferencer_script = load("res://addons/godot_rl_agents/onnx/csharp/ONNXInference.cs") + +var inferencer = null + +## How many action values the model outputs +var action_output_size: int + +## Used to differentiate models +## that only output continuous action mean (e.g. sb3, cleanrl export) +## versus models that output mean and logstd (e.g. rllib export) +var action_means_only: bool + +## Whether action_means_value has been set already for this model +var action_means_only_set: bool + +# Must provide the path to the model and the batch size +func _init(model_path, batch_size): + inferencer = inferencer_script.new() + action_output_size = inferencer.Initialize(model_path, batch_size) + +# This function is the one that will be called from the game, +# requires the observation as an array and the state_ins as an int +# returns an Array containing the action the model takes. +func run_inference(obs: Array, state_ins: int) -> Dictionary: + if inferencer == null: + printerr("Inferencer not initialized") + return {} + return inferencer.RunInference(obs, state_ins) + + +func _notification(what): + if what == NOTIFICATION_PREDELETE: + inferencer.FreeDisposables() + inferencer.free() + +# Check whether agent uses a continuous actions model with only action means or not +func set_action_means_only(agent_action_space): + action_means_only_set = true + var continuous_only: bool = true + var continuous_actions: int + for action in agent_action_space: + if not agent_action_space[action]["action_type"] == "continuous": + continuous_only = false + break + else: + continuous_actions += agent_action_space[action]["size"] + if continuous_only: + if continuous_actions == action_output_size: + action_means_only = true diff --git a/addons/godot_rl_agents/plugin.cfg b/addons/godot_rl_agents/plugin.cfg new file mode 100644 index 0000000..b1bc988 --- /dev/null +++ b/addons/godot_rl_agents/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="GodotRLAgents" +description="Custom nodes for the godot rl agents toolkit " +author="Edward Beeching" +version="0.1" +script="godot_rl_agents.gd" diff --git a/addons/godot_rl_agents/sensors/sensors_2d/ExampleRaycastSensor2D.tscn b/addons/godot_rl_agents/sensors/sensors_2d/ExampleRaycastSensor2D.tscn new file mode 100644 index 0000000..5edb6c7 --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_2d/ExampleRaycastSensor2D.tscn @@ -0,0 +1,48 @@ +[gd_scene load_steps=5 format=3 uid="uid://ddeq7mn1ealyc"] + +[ext_resource type="Script" path="res://addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.gd" id="1"] + +[sub_resource type="GDScript" id="2"] +script/source = "extends Node2D + + + +func _physics_process(delta: float) -> void: + print(\"step start\") + +" + +[sub_resource type="GDScript" id="1"] +script/source = "extends RayCast2D + +var steps = 1 + +func _physics_process(delta: float) -> void: + print(\"processing raycast\") + steps += 1 + if steps % 2: + force_raycast_update() + + print(is_colliding()) +" + +[sub_resource type="CircleShape2D" id="3"] + +[node name="ExampleRaycastSensor2D" type="Node2D"] +script = SubResource("2") + +[node name="ExampleAgent" type="Node2D" parent="."] +position = Vector2(573, 314) +rotation = 0.286234 + +[node name="RaycastSensor2D" type="Node2D" parent="ExampleAgent"] +script = ExtResource("1") + +[node name="TestRayCast2D" type="RayCast2D" parent="."] +script = SubResource("1") + +[node name="StaticBody2D" type="StaticBody2D" parent="."] +position = Vector2(1, 52) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="StaticBody2D"] +shape = SubResource("3") diff --git a/addons/godot_rl_agents/sensors/sensors_2d/GridSensor2D.gd b/addons/godot_rl_agents/sensors/sensors_2d/GridSensor2D.gd new file mode 100644 index 0000000..da170ba --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_2d/GridSensor2D.gd @@ -0,0 +1,235 @@ +@tool +extends ISensor2D +class_name GridSensor2D + +@export var debug_view := false: + get: + return debug_view + set(value): + debug_view = value + _update() + +@export_flags_2d_physics var detection_mask := 0: + get: + return detection_mask + set(value): + detection_mask = value + _update() + +@export var collide_with_areas := false: + get: + return collide_with_areas + set(value): + collide_with_areas = value + _update() + +@export var collide_with_bodies := true: + get: + return collide_with_bodies + set(value): + collide_with_bodies = value + _update() + +@export_range(1, 200, 0.1) var cell_width := 20.0: + get: + return cell_width + set(value): + cell_width = value + _update() + +@export_range(1, 200, 0.1) var cell_height := 20.0: + get: + return cell_height + set(value): + cell_height = value + _update() + +@export_range(1, 21, 2, "or_greater") var grid_size_x := 3: + get: + return grid_size_x + set(value): + grid_size_x = value + _update() + +@export_range(1, 21, 2, "or_greater") var grid_size_y := 3: + get: + return grid_size_y + set(value): + grid_size_y = value + _update() + +var _obs_buffer: PackedFloat64Array +var _rectangle_shape: RectangleShape2D +var _collision_mapping: Dictionary +var _n_layers_per_cell: int + +var _highlighted_cell_color: Color +var _standard_cell_color: Color + + +func get_observation(): + return _obs_buffer + + +func _update(): + if Engine.is_editor_hint(): + if is_node_ready(): + _spawn_nodes() + + +func _ready() -> void: + _set_colors() + + if Engine.is_editor_hint(): + if get_child_count() == 0: + _spawn_nodes() + else: + _spawn_nodes() + + +func _set_colors() -> void: + _standard_cell_color = Color(100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0) + _highlighted_cell_color = Color(255.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0) + + +func _get_collision_mapping() -> Dictionary: + # defines which layer is mapped to which cell obs index + var total_bits = 0 + var collision_mapping = {} + for i in 32: + var bit_mask = 2 ** i + if (detection_mask & bit_mask) > 0: + collision_mapping[i] = total_bits + total_bits += 1 + + return collision_mapping + + +func _spawn_nodes(): + for cell in get_children(): + cell.name = "_%s" % cell.name # Otherwise naming below will fail + cell.queue_free() + + _collision_mapping = _get_collision_mapping() + #prints("collision_mapping", _collision_mapping, len(_collision_mapping)) + # allocate memory for the observations + _n_layers_per_cell = len(_collision_mapping) + _obs_buffer = PackedFloat64Array() + _obs_buffer.resize(grid_size_x * grid_size_y * _n_layers_per_cell) + _obs_buffer.fill(0) + #prints(len(_obs_buffer), _obs_buffer ) + + _rectangle_shape = RectangleShape2D.new() + _rectangle_shape.set_size(Vector2(cell_width, cell_height)) + + var shift := Vector2( + -(grid_size_x / 2) * cell_width, + -(grid_size_y / 2) * cell_height, + ) + + for i in grid_size_x: + for j in grid_size_y: + var cell_position = Vector2(i * cell_width, j * cell_height) + shift + _create_cell(i, j, cell_position) + + +func _create_cell(i: int, j: int, position: Vector2): + var cell := Area2D.new() + cell.position = position + cell.name = "GridCell %s %s" % [i, j] + cell.modulate = _standard_cell_color + + if collide_with_areas: + cell.area_entered.connect(_on_cell_area_entered.bind(i, j)) + cell.area_exited.connect(_on_cell_area_exited.bind(i, j)) + + if collide_with_bodies: + cell.body_entered.connect(_on_cell_body_entered.bind(i, j)) + cell.body_exited.connect(_on_cell_body_exited.bind(i, j)) + + cell.collision_layer = 0 + cell.collision_mask = detection_mask + cell.monitorable = true + add_child(cell) + cell.set_owner(get_tree().edited_scene_root) + + var col_shape := CollisionShape2D.new() + col_shape.shape = _rectangle_shape + col_shape.name = "CollisionShape2D" + cell.add_child(col_shape) + col_shape.set_owner(get_tree().edited_scene_root) + + if debug_view: + var quad = MeshInstance2D.new() + quad.name = "MeshInstance2D" + var quad_mesh = QuadMesh.new() + + quad_mesh.set_size(Vector2(cell_width, cell_height)) + + quad.mesh = quad_mesh + cell.add_child(quad) + quad.set_owner(get_tree().edited_scene_root) + + +func _update_obs(cell_i: int, cell_j: int, collision_layer: int, entered: bool): + for key in _collision_mapping: + var bit_mask = 2 ** key + if (collision_layer & bit_mask) > 0: + var collison_map_index = _collision_mapping[key] + + var obs_index = ( + (cell_i * grid_size_x * _n_layers_per_cell) + + (cell_j * _n_layers_per_cell) + + collison_map_index + ) + #prints(obs_index, cell_i, cell_j) + if entered: + _obs_buffer[obs_index] += 1 + else: + _obs_buffer[obs_index] -= 1 + + +func _toggle_cell(cell_i: int, cell_j: int): + var cell = get_node_or_null("GridCell %s %s" % [cell_i, cell_j]) + + if cell == null: + print("cell not found, returning") + + var n_hits = 0 + var start_index = (cell_i * grid_size_x * _n_layers_per_cell) + (cell_j * _n_layers_per_cell) + for i in _n_layers_per_cell: + n_hits += _obs_buffer[start_index + i] + + if n_hits > 0: + cell.modulate = _highlighted_cell_color + else: + cell.modulate = _standard_cell_color + + +func _on_cell_area_entered(area: Area2D, cell_i: int, cell_j: int): + #prints("_on_cell_area_entered", cell_i, cell_j) + _update_obs(cell_i, cell_j, area.collision_layer, true) + if debug_view: + _toggle_cell(cell_i, cell_j) + #print(_obs_buffer) + + +func _on_cell_area_exited(area: Area2D, cell_i: int, cell_j: int): + #prints("_on_cell_area_exited", cell_i, cell_j) + _update_obs(cell_i, cell_j, area.collision_layer, false) + if debug_view: + _toggle_cell(cell_i, cell_j) + + +func _on_cell_body_entered(body: Node2D, cell_i: int, cell_j: int): + #prints("_on_cell_body_entered", cell_i, cell_j) + _update_obs(cell_i, cell_j, body.collision_layer, true) + if debug_view: + _toggle_cell(cell_i, cell_j) + + +func _on_cell_body_exited(body: Node2D, cell_i: int, cell_j: int): + #prints("_on_cell_body_exited", cell_i, cell_j) + _update_obs(cell_i, cell_j, body.collision_layer, false) + if debug_view: + _toggle_cell(cell_i, cell_j) diff --git a/addons/godot_rl_agents/sensors/sensors_2d/ISensor2D.gd b/addons/godot_rl_agents/sensors/sensors_2d/ISensor2D.gd new file mode 100644 index 0000000..67669a1 --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_2d/ISensor2D.gd @@ -0,0 +1,25 @@ +extends Node2D +class_name ISensor2D + +var _obs: Array = [] +var _active := false + + +func get_observation(): + pass + + +func activate(): + _active = true + + +func deactivate(): + _active = false + + +func _update_observation(): + pass + + +func reset(): + pass diff --git a/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.gd b/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.gd new file mode 100644 index 0000000..9bb54ed --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.gd @@ -0,0 +1,118 @@ +@tool +extends ISensor2D +class_name RaycastSensor2D + +@export_flags_2d_physics var collision_mask := 1: + get: + return collision_mask + set(value): + collision_mask = value + _update() + +@export var collide_with_areas := false: + get: + return collide_with_areas + set(value): + collide_with_areas = value + _update() + +@export var collide_with_bodies := true: + get: + return collide_with_bodies + set(value): + collide_with_bodies = value + _update() + +@export var n_rays := 16.0: + get: + return n_rays + set(value): + n_rays = value + _update() + +@export_range(5, 3000, 5.0) var ray_length := 200: + get: + return ray_length + set(value): + ray_length = value + _update() +@export_range(5, 360, 5.0) var cone_width := 360.0: + get: + return cone_width + set(value): + cone_width = value + _update() + +@export var debug_draw := true: + get: + return debug_draw + set(value): + debug_draw = value + _update() + +var _angles = [] +var rays := [] + + +func _update(): + if Engine.is_editor_hint(): + if debug_draw: + _spawn_nodes() + else: + for ray in get_children(): + if ray is RayCast2D: + remove_child(ray) + + +func _ready() -> void: + _spawn_nodes() + + +func _spawn_nodes(): + for ray in rays: + ray.queue_free() + rays = [] + + _angles = [] + var step = cone_width / (n_rays) + var start = step / 2 - cone_width / 2 + + for i in n_rays: + var angle = start + i * step + var ray = RayCast2D.new() + ray.set_target_position( + Vector2(ray_length * cos(deg_to_rad(angle)), ray_length * sin(deg_to_rad(angle))) + ) + ray.set_name("node_" + str(i)) + ray.enabled = false + ray.collide_with_areas = collide_with_areas + ray.collide_with_bodies = collide_with_bodies + ray.collision_mask = collision_mask + add_child(ray) + rays.append(ray) + + _angles.append(start + i * step) + + +func get_observation() -> Array: + return self.calculate_raycasts() + + +func calculate_raycasts() -> Array: + var result = [] + for ray in rays: + ray.enabled = true + ray.force_raycast_update() + var distance = _get_raycast_distance(ray) + result.append(distance) + ray.enabled = false + return result + + +func _get_raycast_distance(ray: RayCast2D) -> float: + if !ray.is_colliding(): + return 0.0 + + var distance = (global_position - ray.get_collision_point()).length() + distance = clamp(distance, 0.0, ray_length) + return (ray_length - distance) / ray_length diff --git a/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.tscn b/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.tscn new file mode 100644 index 0000000..5ca402c --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.tscn @@ -0,0 +1,7 @@ +[gd_scene load_steps=2 format=3 uid="uid://drvfihk5esgmv"] + +[ext_resource type="Script" path="res://addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.gd" id="1"] + +[node name="RaycastSensor2D" type="Node2D"] +script = ExtResource("1") +n_rays = 17.0 diff --git a/addons/godot_rl_agents/sensors/sensors_3d/ExampleRaycastSensor3D.tscn b/addons/godot_rl_agents/sensors/sensors_3d/ExampleRaycastSensor3D.tscn new file mode 100644 index 0000000..a8057c7 --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_3d/ExampleRaycastSensor3D.tscn @@ -0,0 +1,6 @@ +[gd_scene format=3 uid="uid://biu787qh4woik"] + +[node name="ExampleRaycastSensor3D" type="Node3D"] + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.804183, 0, 2.70146) diff --git a/addons/godot_rl_agents/sensors/sensors_3d/GridSensor3D.gd b/addons/godot_rl_agents/sensors/sensors_3d/GridSensor3D.gd new file mode 100644 index 0000000..03593cc --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_3d/GridSensor3D.gd @@ -0,0 +1,258 @@ +@tool +extends ISensor3D +class_name GridSensor3D + +@export var debug_view := false: + get: + return debug_view + set(value): + debug_view = value + _update() + +@export_flags_3d_physics var detection_mask := 0: + get: + return detection_mask + set(value): + detection_mask = value + _update() + +@export var collide_with_areas := false: + get: + return collide_with_areas + set(value): + collide_with_areas = value + _update() + +@export var collide_with_bodies := false: + # NOTE! The sensor will not detect StaticBody3D, add an area to static bodies to detect them + get: + return collide_with_bodies + set(value): + collide_with_bodies = value + _update() + +@export_range(0.1, 2, 0.1) var cell_width := 1.0: + get: + return cell_width + set(value): + cell_width = value + _update() + +@export_range(0.1, 2, 0.1) var cell_height := 1.0: + get: + return cell_height + set(value): + cell_height = value + _update() + +@export_range(1, 21, 2, "or_greater") var grid_size_x := 3: + get: + return grid_size_x + set(value): + grid_size_x = value + _update() + +@export_range(1, 21, 2, "or_greater") var grid_size_z := 3: + get: + return grid_size_z + set(value): + grid_size_z = value + _update() + +var _obs_buffer: PackedFloat64Array +var _box_shape: BoxShape3D +var _collision_mapping: Dictionary +var _n_layers_per_cell: int + +var _highlighted_box_material: StandardMaterial3D +var _standard_box_material: StandardMaterial3D + + +func get_observation(): + return _obs_buffer + + +func reset(): + _obs_buffer.fill(0) + + +func _update(): + if Engine.is_editor_hint(): + if is_node_ready(): + _spawn_nodes() + + +func _ready() -> void: + _make_materials() + + if Engine.is_editor_hint(): + if get_child_count() == 0: + _spawn_nodes() + else: + _spawn_nodes() + + +func _make_materials() -> void: + if _highlighted_box_material != null and _standard_box_material != null: + return + + _standard_box_material = StandardMaterial3D.new() + _standard_box_material.set_transparency(1) # ALPHA + _standard_box_material.albedo_color = Color( + 100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0 + ) + + _highlighted_box_material = StandardMaterial3D.new() + _highlighted_box_material.set_transparency(1) # ALPHA + _highlighted_box_material.albedo_color = Color( + 255.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0 + ) + + +func _get_collision_mapping() -> Dictionary: + # defines which layer is mapped to which cell obs index + var total_bits = 0 + var collision_mapping = {} + for i in 32: + var bit_mask = 2 ** i + if (detection_mask & bit_mask) > 0: + collision_mapping[i] = total_bits + total_bits += 1 + + return collision_mapping + + +func _spawn_nodes(): + for cell in get_children(): + cell.name = "_%s" % cell.name # Otherwise naming below will fail + cell.queue_free() + + _collision_mapping = _get_collision_mapping() + #prints("collision_mapping", _collision_mapping, len(_collision_mapping)) + # allocate memory for the observations + _n_layers_per_cell = len(_collision_mapping) + _obs_buffer = PackedFloat64Array() + _obs_buffer.resize(grid_size_x * grid_size_z * _n_layers_per_cell) + _obs_buffer.fill(0) + #prints(len(_obs_buffer), _obs_buffer ) + + _box_shape = BoxShape3D.new() + _box_shape.set_size(Vector3(cell_width, cell_height, cell_width)) + + var shift := Vector3( + -(grid_size_x / 2) * cell_width, + 0, + -(grid_size_z / 2) * cell_width, + ) + + for i in grid_size_x: + for j in grid_size_z: + var cell_position = Vector3(i * cell_width, 0.0, j * cell_width) + shift + _create_cell(i, j, cell_position) + + +func _create_cell(i: int, j: int, position: Vector3): + var cell := Area3D.new() + cell.position = position + cell.name = "GridCell %s %s" % [i, j] + + if collide_with_areas: + cell.area_entered.connect(_on_cell_area_entered.bind(i, j)) + cell.area_exited.connect(_on_cell_area_exited.bind(i, j)) + + if collide_with_bodies: + cell.body_entered.connect(_on_cell_body_entered.bind(i, j)) + cell.body_exited.connect(_on_cell_body_exited.bind(i, j)) + +# cell.body_shape_entered.connect(_on_cell_body_shape_entered.bind(i, j)) +# cell.body_shape_exited.connect(_on_cell_body_shape_exited.bind(i, j)) + + cell.collision_layer = 0 + cell.collision_mask = detection_mask + cell.monitorable = true + cell.input_ray_pickable = false + add_child(cell) + cell.set_owner(get_tree().edited_scene_root) + + var col_shape := CollisionShape3D.new() + col_shape.shape = _box_shape + col_shape.name = "CollisionShape3D" + cell.add_child(col_shape) + col_shape.set_owner(get_tree().edited_scene_root) + + if debug_view: + var box = MeshInstance3D.new() + box.name = "MeshInstance3D" + var box_mesh = BoxMesh.new() + + box_mesh.set_size(Vector3(cell_width, cell_height, cell_width)) + box_mesh.material = _standard_box_material + + box.mesh = box_mesh + cell.add_child(box) + box.set_owner(get_tree().edited_scene_root) + + +func _update_obs(cell_i: int, cell_j: int, collision_layer: int, entered: bool): + for key in _collision_mapping: + var bit_mask = 2 ** key + if (collision_layer & bit_mask) > 0: + var collison_map_index = _collision_mapping[key] + + var obs_index = ( + (cell_i * grid_size_x * _n_layers_per_cell) + + (cell_j * _n_layers_per_cell) + + collison_map_index + ) + #prints(obs_index, cell_i, cell_j) + if entered: + _obs_buffer[obs_index] += 1 + else: + _obs_buffer[obs_index] -= 1 + + +func _toggle_cell(cell_i: int, cell_j: int): + var cell = get_node_or_null("GridCell %s %s" % [cell_i, cell_j]) + + if cell == null: + print("cell not found, returning") + + var n_hits = 0 + var start_index = (cell_i * grid_size_x * _n_layers_per_cell) + (cell_j * _n_layers_per_cell) + for i in _n_layers_per_cell: + n_hits += _obs_buffer[start_index + i] + + var cell_mesh = cell.get_node_or_null("MeshInstance3D") + if n_hits > 0: + cell_mesh.mesh.material = _highlighted_box_material + else: + cell_mesh.mesh.material = _standard_box_material + + +func _on_cell_area_entered(area: Area3D, cell_i: int, cell_j: int): + #prints("_on_cell_area_entered", cell_i, cell_j) + _update_obs(cell_i, cell_j, area.collision_layer, true) + if debug_view: + _toggle_cell(cell_i, cell_j) + #print(_obs_buffer) + + +func _on_cell_area_exited(area: Area3D, cell_i: int, cell_j: int): + #prints("_on_cell_area_exited", cell_i, cell_j) + _update_obs(cell_i, cell_j, area.collision_layer, false) + if debug_view: + _toggle_cell(cell_i, cell_j) + + +func _on_cell_body_entered(body: Node3D, cell_i: int, cell_j: int): + #prints("_on_cell_body_entered", cell_i, cell_j) + _update_obs(cell_i, cell_j, body.collision_layer, true) + if debug_view: + _toggle_cell(cell_i, cell_j) + + +func _on_cell_body_exited(body: Node3D, cell_i: int, cell_j: int): + #prints("_on_cell_body_exited", cell_i, cell_j) + _update_obs(cell_i, cell_j, body.collision_layer, false) + if debug_view: + _toggle_cell(cell_i, cell_j) diff --git a/addons/godot_rl_agents/sensors/sensors_3d/ISensor3D.gd b/addons/godot_rl_agents/sensors/sensors_3d/ISensor3D.gd new file mode 100644 index 0000000..aca3c2d --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_3d/ISensor3D.gd @@ -0,0 +1,25 @@ +extends Node3D +class_name ISensor3D + +var _obs: Array = [] +var _active := false + + +func get_observation(): + pass + + +func activate(): + _active = true + + +func deactivate(): + _active = false + + +func _update_observation(): + pass + + +func reset(): + pass diff --git a/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.gd b/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.gd new file mode 100644 index 0000000..1037e97 --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.gd @@ -0,0 +1,21 @@ +extends Node3D +class_name RGBCameraSensor3D +var camera_pixels = null + +@onready var camera_texture := $Control/TextureRect/CameraTexture as Sprite2D +@onready var sub_viewport := $SubViewport as SubViewport + + +func get_camera_pixel_encoding(): + return camera_texture.get_texture().get_image().get_data().hex_encode() + + +func get_camera_shape() -> Array: + assert( + sub_viewport.size.x >= 36 and sub_viewport.size.y >= 36, + "SubViewport size must be 36x36 or larger." + ) + if sub_viewport.transparent_bg: + return [4, sub_viewport.size.y, sub_viewport.size.x] + else: + return [3, sub_viewport.size.y, sub_viewport.size.x] diff --git a/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.tscn b/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.tscn new file mode 100644 index 0000000..052b557 --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=3 format=3 uid="uid://baaywi3arsl2m"] + +[ext_resource type="Script" path="res://addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.gd" id="1"] + +[sub_resource type="ViewportTexture" id="1"] +viewport_path = NodePath("SubViewport") + +[node name="RGBCameraSensor3D" type="Node3D"] +script = ExtResource("1") + +[node name="RemoteTransform3D" type="RemoteTransform3D" parent="."] +remote_path = NodePath("../SubViewport/Camera3D") + +[node name="SubViewport" type="SubViewport" parent="."] +size = Vector2i(32, 32) +render_target_update_mode = 3 + +[node name="Camera3D" type="Camera3D" parent="SubViewport"] +near = 0.5 + +[node name="Control" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="TextureRect" type="ColorRect" parent="Control"] +layout_mode = 0 +offset_left = 1096.0 +offset_top = 534.0 +offset_right = 1114.0 +offset_bottom = 552.0 +scale = Vector2(10, 10) +color = Color(0.00784314, 0.00784314, 0.00784314, 1) + +[node name="CameraTexture" type="Sprite2D" parent="Control/TextureRect"] +texture = SubResource("1") +offset = Vector2(9, 9) +flip_v = true diff --git a/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.gd b/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.gd new file mode 100644 index 0000000..1357529 --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.gd @@ -0,0 +1,185 @@ +@tool +extends ISensor3D +class_name RayCastSensor3D +@export_flags_3d_physics var collision_mask = 1: + get: + return collision_mask + set(value): + collision_mask = value + _update() +@export_flags_3d_physics var boolean_class_mask = 1: + get: + return boolean_class_mask + set(value): + boolean_class_mask = value + _update() + +@export var n_rays_width := 6.0: + get: + return n_rays_width + set(value): + n_rays_width = value + _update() + +@export var n_rays_height := 6.0: + get: + return n_rays_height + set(value): + n_rays_height = value + _update() + +@export var ray_length := 10.0: + get: + return ray_length + set(value): + ray_length = value + _update() + +@export var cone_width := 60.0: + get: + return cone_width + set(value): + cone_width = value + _update() + +@export var cone_height := 60.0: + get: + return cone_height + set(value): + cone_height = value + _update() + +@export var collide_with_areas := false: + get: + return collide_with_areas + set(value): + collide_with_areas = value + _update() + +@export var collide_with_bodies := true: + get: + return collide_with_bodies + set(value): + collide_with_bodies = value + _update() + +@export var class_sensor := false + +var rays := [] +var geo = null + + +func _update(): + if Engine.is_editor_hint(): + if is_node_ready(): + _spawn_nodes() + + +func _ready() -> void: + if Engine.is_editor_hint(): + if get_child_count() == 0: + _spawn_nodes() + else: + _spawn_nodes() + + +func _spawn_nodes(): + print("spawning nodes") + for ray in get_children(): + ray.queue_free() + if geo: + geo.clear() + #$Lines.remove_points() + rays = [] + + var horizontal_step = cone_width / (n_rays_width) + var vertical_step = cone_height / (n_rays_height) + + var horizontal_start = horizontal_step / 2 - cone_width / 2 + var vertical_start = vertical_step / 2 - cone_height / 2 + + var points = [] + + for i in n_rays_width: + for j in n_rays_height: + var angle_w = horizontal_start + i * horizontal_step + var angle_h = vertical_start + j * vertical_step + #angle_h = 0.0 + var ray = RayCast3D.new() + var cast_to = to_spherical_coords(ray_length, angle_w, angle_h) + ray.set_target_position(cast_to) + + points.append(cast_to) + + ray.set_name("node_" + str(i) + " " + str(j)) + ray.enabled = true + ray.collide_with_bodies = collide_with_bodies + ray.collide_with_areas = collide_with_areas + ray.collision_mask = collision_mask + add_child(ray) + ray.set_owner(get_tree().edited_scene_root) + rays.append(ray) + ray.force_raycast_update() + + +# if Engine.editor_hint: +# _create_debug_lines(points) + + +func _create_debug_lines(points): + if not geo: + geo = ImmediateMesh.new() + add_child(geo) + + geo.clear() + geo.begin(Mesh.PRIMITIVE_LINES) + for point in points: + geo.set_color(Color.AQUA) + geo.add_vertex(Vector3.ZERO) + geo.add_vertex(point) + geo.end() + + +func display(): + if geo: + geo.display() + + +func to_spherical_coords(r, inc, azimuth) -> Vector3: + return Vector3( + r * sin(deg_to_rad(inc)) * cos(deg_to_rad(azimuth)), + r * sin(deg_to_rad(azimuth)), + r * cos(deg_to_rad(inc)) * cos(deg_to_rad(azimuth)) + ) + + +func get_observation() -> Array: + return self.calculate_raycasts() + + +func calculate_raycasts() -> Array: + var result = [] + for ray in rays: + ray.set_enabled(true) + ray.force_raycast_update() + var distance = _get_raycast_distance(ray) + + result.append(distance) + if class_sensor: + var hit_class: float = 0 + if ray.get_collider(): + var hit_collision_layer = ray.get_collider().collision_layer + hit_collision_layer = hit_collision_layer & collision_mask + hit_class = (hit_collision_layer & boolean_class_mask) > 0 + result.append(float(hit_class)) + ray.set_enabled(false) + return result + + +func _get_raycast_distance(ray: RayCast3D) -> float: + if !ray.is_colliding(): + return 0.0 + + var distance = (global_transform.origin - ray.get_collision_point()).length() + distance = clamp(distance, 0.0, ray_length) + return (ray_length - distance) / ray_length diff --git a/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.tscn b/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.tscn new file mode 100644 index 0000000..35f9796 --- /dev/null +++ b/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.tscn @@ -0,0 +1,27 @@ +[gd_scene load_steps=2 format=3 uid="uid://b803cbh1fmy66"] + +[ext_resource type="Script" path="res://addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.gd" id="1"] + +[node name="RaycastSensor3D" type="Node3D"] +script = ExtResource("1") +n_rays_width = 4.0 +n_rays_height = 2.0 +ray_length = 11.0 + +[node name="node_1 0" type="RayCast3D" parent="."] +target_position = Vector3(-1.38686, -2.84701, 10.5343) + +[node name="node_1 1" type="RayCast3D" parent="."] +target_position = Vector3(-1.38686, 2.84701, 10.5343) + +[node name="node_2 0" type="RayCast3D" parent="."] +target_position = Vector3(1.38686, -2.84701, 10.5343) + +[node name="node_2 1" type="RayCast3D" parent="."] +target_position = Vector3(1.38686, 2.84701, 10.5343) + +[node name="node_3 0" type="RayCast3D" parent="."] +target_position = Vector3(4.06608, -2.84701, 9.81639) + +[node name="node_3 1" type="RayCast3D" parent="."] +target_position = Vector3(4.06608, 2.84701, 9.81639) diff --git a/addons/godot_rl_agents/sync.gd b/addons/godot_rl_agents/sync.gd new file mode 100644 index 0000000..889127a --- /dev/null +++ b/addons/godot_rl_agents/sync.gd @@ -0,0 +1,579 @@ +extends Node + +# --fixed-fps 2000 --disable-render-loop + +enum ControlModes { HUMAN, TRAINING, ONNX_INFERENCE } +@export var control_mode: ControlModes = ControlModes.TRAINING +@export_range(1, 10, 1, "or_greater") var action_repeat := 8 +@export_range(0, 10, 0.1, "or_greater") var speed_up := 1.0 +@export var onnx_model_path := "" + +# Onnx model stored for each requested path +var onnx_models: Dictionary + +@onready var start_time = Time.get_ticks_msec() + +const MAJOR_VERSION := "0" +const MINOR_VERSION := "7" +const DEFAULT_PORT := "11008" +const DEFAULT_SEED := "1" +var stream: StreamPeerTCP = null +var connected = false +var message_center +var should_connect = true + +var all_agents: Array +var agents_training: Array +## Policy name of each agent, for use with multi-policy multi-agent RL cases +var agents_training_policy_names: Array[String] = ["shared_policy"] +var agents_inference: Array +var agents_heuristic: Array + +## For recording expert demos +var agent_demo_record: Node +## File path for writing recorded trajectories +var expert_demo_save_path: String +## Stores recorded trajectories +var demo_trajectories: Array +## A trajectory includes obs: Array, acts: Array, terminal (set in Python env instead) +var current_demo_trajectory: Array + +var need_to_send_obs = false +var args = null +var initialized = false +var just_reset = false +var onnx_model = null +var n_action_steps = 0 + +var _action_space_training: Array[Dictionary] = [] +var _action_space_inference: Array[Dictionary] = [] +var _obs_space_training: Array[Dictionary] = [] + +# Called when the node enters the scene tree for the first time. +func _ready(): + await get_tree().root.ready + get_tree().set_pause(true) + _initialize() + await get_tree().create_timer(1.0).timeout + get_tree().set_pause(false) + + +func _initialize(): + _get_agents() + args = _get_args() + Engine.physics_ticks_per_second = _get_speedup() * 60 # Replace with function body. + Engine.time_scale = _get_speedup() * 1.0 + prints( + "physics ticks", + Engine.physics_ticks_per_second, + Engine.time_scale, + _get_speedup(), + speed_up + ) + + _set_heuristic("human", all_agents) + + _initialize_training_agents() + _initialize_inference_agents() + _initialize_demo_recording() + + _set_seed() + _set_action_repeat() + initialized = true + + +func _initialize_training_agents(): + if agents_training.size() > 0: + _obs_space_training.resize(agents_training.size()) + _action_space_training.resize(agents_training.size()) + for agent_idx in range(0, agents_training.size()): + _obs_space_training[agent_idx] = agents_training[agent_idx].get_obs_space() + _action_space_training[agent_idx] = agents_training[agent_idx].get_action_space() + connected = connect_to_server() + if connected: + _set_heuristic("model", agents_training) + _handshake() + _send_env_info() + else: + push_warning( + "Couldn't connect to Python server, using human controls instead. ", + "Did you start the training server using e.g. `gdrl` from the console?" + ) + + +func _initialize_inference_agents(): + if agents_inference.size() > 0: + if control_mode == ControlModes.ONNX_INFERENCE: + assert( + FileAccess.file_exists(onnx_model_path), + "Onnx Model Path set on Sync node does not exist: %s" % onnx_model_path + ) + onnx_models[onnx_model_path] = ONNXModel.new(onnx_model_path, 1) + + for agent in agents_inference: + var action_space = agent.get_action_space() + _action_space_inference.append(action_space) + + var agent_onnx_model: ONNXModel + if agent.onnx_model_path.is_empty(): + assert( + onnx_models.has(onnx_model_path), + ( + "Node %s has no onnx model path set " % agent.get_path() + + "and sync node's control mode is not set to OnnxInference. " + + "Either add the path to the AIController, " + + "or if you want to use the path set on sync node instead, " + + "set control mode to OnnxInference." + ) + ) + prints( + "Info: AIController %s" % agent.get_path(), + "has no onnx model path set.", + "Using path set on the sync node instead." + ) + agent_onnx_model = onnx_models[onnx_model_path] + else: + if not onnx_models.has(agent.onnx_model_path): + assert( + FileAccess.file_exists(agent.onnx_model_path), + ( + "Onnx Model Path set on %s node does not exist: %s" + % [agent.get_path(), agent.onnx_model_path] + ) + ) + onnx_models[agent.onnx_model_path] = ONNXModel.new(agent.onnx_model_path, 1) + agent_onnx_model = onnx_models[agent.onnx_model_path] + + agent.onnx_model = agent_onnx_model + if not agent_onnx_model.action_means_only_set: + agent_onnx_model.set_action_means_only(action_space) + + _set_heuristic("model", agents_inference) + + +func _initialize_demo_recording(): + if agent_demo_record: + expert_demo_save_path = agent_demo_record.expert_demo_save_path + assert( + not expert_demo_save_path.is_empty(), + "Expert demo save path set in %s is empty." % agent_demo_record.get_path() + ) + + InputMap.add_action("RemoveLastDemoEpisode") + InputMap.action_add_event( + "RemoveLastDemoEpisode", agent_demo_record.remove_last_episode_key + ) + current_demo_trajectory.resize(2) + current_demo_trajectory[0] = [] + current_demo_trajectory[1] = [] + agent_demo_record.heuristic = "demo_record" + + +func _physics_process(_delta): + # two modes, human control, agent control + # pause tree, send obs, get actions, set actions, unpause tree + + _demo_record_process() + + if n_action_steps % action_repeat != 0: + n_action_steps += 1 + return + + n_action_steps += 1 + + _training_process() + _inference_process() + _heuristic_process() + + +func _training_process(): + if connected: + get_tree().set_pause(true) + + if just_reset: + just_reset = false + var obs = _get_obs_from_agents(agents_training) + + var reply = {"type": "reset", "obs": obs} + _send_dict_as_json_message(reply) + # this should go straight to getting the action and setting it checked the agent, no need to perform one phyics tick + get_tree().set_pause(false) + return + + if need_to_send_obs: + need_to_send_obs = false + var reward = _get_reward_from_agents() + var done = _get_done_from_agents() + #_reset_agents_if_done() # this ensures the new observation is from the next env instance : NEEDS REFACTOR + + var obs = _get_obs_from_agents(agents_training) + + var reply = {"type": "step", "obs": obs, "reward": reward, "done": done} + _send_dict_as_json_message(reply) + + var handled = handle_message() + + +func _inference_process(): + if agents_inference.size() > 0: + var obs: Array = _get_obs_from_agents(agents_inference) + var actions = [] + + for agent_id in range(0, agents_inference.size()): + var model: ONNXModel = agents_inference[agent_id].onnx_model + var action = model.run_inference( + obs[agent_id]["obs"], 1.0 + ) + var action_dict = _extract_action_dict( + action["output"], _action_space_inference[agent_id], model.action_means_only + ) + actions.append(action_dict) + + _set_agent_actions(actions, agents_inference) + _reset_agents_if_done(agents_inference) + get_tree().set_pause(false) + + +func _demo_record_process(): + if not agent_demo_record: + return + + if Input.is_action_just_pressed("RemoveLastDemoEpisode"): + print("[Sync script][Demo recorder] Removing last recorded episode.") + demo_trajectories.remove_at(demo_trajectories.size() - 1) + print("Remaining episode count: %d" % demo_trajectories.size()) + + if n_action_steps % agent_demo_record.action_repeat != 0: + return + + var obs_dict: Dictionary = agent_demo_record.get_obs() + + # Get the current obs from the agent + assert( + obs_dict.has("obs"), + "Demo recorder needs an 'obs' key in get_obs() returned dictionary to record obs from." + ) + current_demo_trajectory[0].append(obs_dict.obs) + + # Get the action applied for the current obs from the agent + agent_demo_record.set_action() + var acts = agent_demo_record.get_action() + + var terminal = agent_demo_record.get_done() + # Record actions only for non-terminal states + if terminal: + agent_demo_record.set_done_false() + else: + current_demo_trajectory[1].append(acts) + + if terminal: + #current_demo_trajectory[2].append(true) + demo_trajectories.append(current_demo_trajectory.duplicate(true)) + print("[Sync script][Demo recorder] Recorded episode count: %d" % demo_trajectories.size()) + current_demo_trajectory[0].clear() + current_demo_trajectory[1].clear() + + +func _heuristic_process(): + for agent in agents_heuristic: + _reset_agents_if_done(agents_heuristic) + + +func _extract_action_dict(action_array: Array, action_space: Dictionary, action_means_only: bool): + var index = 0 + var result = {} + for key in action_space.keys(): + var size = action_space[key]["size"] + var action_type = action_space[key]["action_type"] + if action_type == "discrete": + var largest_logit: float # Value of the largest logit for this action in the actions array + var largest_logit_idx: int # Index of the largest logit for this action in the actions array + for logit_idx in range(0, size): + var logit_value = action_array[index + logit_idx] + if logit_value > largest_logit: + largest_logit = logit_value + largest_logit_idx = logit_idx + result[key] = largest_logit_idx # Index of the largest logit is the discrete action value + index += size + elif action_type == "continuous": + # For continous actions, we only take the action mean values + result[key] = clamp_array(action_array.slice(index, index + size), -1.0, 1.0) + if action_means_only: + index += size # model only outputs action means, so we move index by size + else: + index += size * 2 # model outputs logstd after action mean, we skip the logstd part + + else: + assert(false, 'Only "discrete" and "continuous" action types supported. Found: %s action type set.' % action_type) + + + return result + + +## For AIControllers that inherit mode from sync, sets the correct mode. +func _set_agent_mode(agent: Node): + var agent_inherits_mode: bool = agent.control_mode == agent.ControlModes.INHERIT_FROM_SYNC + + if agent_inherits_mode: + match control_mode: + ControlModes.HUMAN: + agent.control_mode = agent.ControlModes.HUMAN + ControlModes.TRAINING: + agent.control_mode = agent.ControlModes.TRAINING + ControlModes.ONNX_INFERENCE: + agent.control_mode = agent.ControlModes.ONNX_INFERENCE + + +func _get_agents(): + all_agents = get_tree().get_nodes_in_group("AGENT") + for agent in all_agents: + _set_agent_mode(agent) + + if agent.control_mode == agent.ControlModes.TRAINING: + agents_training.append(agent) + elif agent.control_mode == agent.ControlModes.ONNX_INFERENCE: + agents_inference.append(agent) + elif agent.control_mode == agent.ControlModes.HUMAN: + agents_heuristic.append(agent) + elif agent.control_mode == agent.ControlModes.RECORD_EXPERT_DEMOS: + assert( + not agent_demo_record, + "Currently only a single AIController can be used for recording expert demos." + ) + agent_demo_record = agent + + var training_agent_count = agents_training.size() + agents_training_policy_names.resize(training_agent_count) + for i in range(0, training_agent_count): + agents_training_policy_names[i] = agents_training[i].policy_name + + +func _set_heuristic(heuristic, agents: Array): + for agent in agents: + agent.set_heuristic(heuristic) + + +func _handshake(): + print("performing handshake") + + var json_dict = _get_dict_json_message() + assert(json_dict["type"] == "handshake") + var major_version = json_dict["major_version"] + var minor_version = json_dict["minor_version"] + if major_version != MAJOR_VERSION: + print("WARNING: major verison mismatch ", major_version, " ", MAJOR_VERSION) + if minor_version != MINOR_VERSION: + print("WARNING: minor verison mismatch ", minor_version, " ", MINOR_VERSION) + + print("handshake complete") + + +func _get_dict_json_message(): + # returns a dictionary from of the most recent message + # this is not waiting + while stream.get_available_bytes() == 0: + stream.poll() + if stream.get_status() != 2: + print("server disconnected status, closing") + get_tree().quit() + return null + + OS.delay_usec(10) + + var message = stream.get_string() + var json_data = JSON.parse_string(message) + + return json_data + + +func _send_dict_as_json_message(dict): + stream.put_string(JSON.stringify(dict, "", false)) + + +func _send_env_info(): + var json_dict = _get_dict_json_message() + assert(json_dict["type"] == "env_info") + + var message = { + "type": "env_info", + "observation_space": _obs_space_training, + "action_space": _action_space_training, + "n_agents": len(agents_training), + "agent_policy_names": agents_training_policy_names + } + _send_dict_as_json_message(message) + + +func connect_to_server(): + print("Waiting for one second to allow server to start") + OS.delay_msec(1000) + print("trying to connect to server") + stream = StreamPeerTCP.new() + + # "localhost" was not working on windows VM, had to use the IP + var ip = "127.0.0.1" + var port = _get_port() + var connect = stream.connect_to_host(ip, port) + stream.set_no_delay(true) # TODO check if this improves performance or not + stream.poll() + # Fetch the status until it is either connected (2) or failed to connect (3) + while stream.get_status() < 2: + stream.poll() + return stream.get_status() == 2 + + +func _get_args(): + print("getting command line arguments") + var arguments = {} + for argument in OS.get_cmdline_args(): + print(argument) + if argument.find("=") > -1: + var key_value = argument.split("=") + arguments[key_value[0].lstrip("--")] = key_value[1] + else: + # Options without an argument will be present in the dictionary, + # with the value set to an empty string. + arguments[argument.lstrip("--")] = "" + + return arguments + + +func _get_speedup(): + print(args) + return args.get("speedup", str(speed_up)).to_float() + + +func _get_port(): + return args.get("port", DEFAULT_PORT).to_int() + + +func _set_seed(): + var _seed = args.get("env_seed", DEFAULT_SEED).to_int() + seed(_seed) + + +func _set_action_repeat(): + action_repeat = args.get("action_repeat", str(action_repeat)).to_int() + + +func disconnect_from_server(): + stream.disconnect_from_host() + + +func handle_message() -> bool: + # get json message: reset, step, close + var message = _get_dict_json_message() + if message["type"] == "close": + print("received close message, closing game") + get_tree().quit() + get_tree().set_pause(false) + return true + + if message["type"] == "reset": + print("resetting all agents") + _reset_agents() + just_reset = true + get_tree().set_pause(false) + #print("resetting forcing draw") +# RenderingServer.force_draw() +# var obs = _get_obs_from_agents() +# print("obs ", obs) +# var reply = { +# "type": "reset", +# "obs": obs +# } +# _send_dict_as_json_message(reply) + return true + + if message["type"] == "call": + var method = message["method"] + var returns = _call_method_on_agents(method) + var reply = {"type": "call", "returns": returns} + print("calling method from Python") + _send_dict_as_json_message(reply) + return handle_message() + + if message["type"] == "action": + var action = message["action"] + _set_agent_actions(action, agents_training) + need_to_send_obs = true + get_tree().set_pause(false) + return true + + print("message was not handled") + return false + + +func _call_method_on_agents(method): + var returns = [] + for agent in all_agents: + returns.append(agent.call(method)) + + return returns + + +func _reset_agents_if_done(agents = all_agents): + for agent in agents: + if agent.get_done(): + agent.set_done_false() + + +func _reset_agents(agents = all_agents): + for agent in agents: + agent.needs_reset = true + #agent.reset() + + +func _get_obs_from_agents(agents: Array = all_agents): + var obs = [] + for agent in agents: + obs.append(agent.get_obs()) + return obs + + +func _get_reward_from_agents(agents: Array = agents_training): + var rewards = [] + for agent in agents: + rewards.append(agent.get_reward()) + agent.zero_reward() + return rewards + + +func _get_done_from_agents(agents: Array = agents_training): + var dones = [] + for agent in agents: + var done = agent.get_done() + if done: + agent.set_done_false() + dones.append(done) + return dones + + +func _set_agent_actions(actions, agents: Array = all_agents): + for i in range(len(actions)): + agents[i].set_action(actions[i]) + + +func clamp_array(arr: Array, min: float, max: float): + var output: Array = [] + for a in arr: + output.append(clamp(a, min, max)) + return output + + +## Save recorded export demos on window exit (Close game window instead of "Stop" button in Godot Editor) +func _notification(what): + if demo_trajectories.size() == 0 or expert_demo_save_path.is_empty(): + return + + if what == NOTIFICATION_PREDELETE: + var json_string = JSON.stringify(demo_trajectories, "", false) + var file = FileAccess.open(expert_demo_save_path, FileAccess.WRITE) + + if not file: + var error: Error = FileAccess.get_open_error() + assert(not error, "There was an error opening the file: %d" % error) + + file.store_line(json_string) + var error = file.get_error() + assert(not error, "There was an error after trying to write to the file: %d" % error) diff --git a/agent.py b/agent.py new file mode 100644 index 0000000..a7aa494 --- /dev/null +++ b/agent.py @@ -0,0 +1,159 @@ +import args +import os +import pathlib + +import torch as T +import torch.nn as nn + +from typing import Callable + +from stable_baselines3 import PPO +from stable_baselines3.common.callbacks import CheckpointCallback +from stable_baselines3.common.vec_env.vec_monitor import VecMonitor + +from godot_rl.core.utils import can_import +from godot_rl.wrappers.onnx.stable_baselines_export import export_ppo_model_as_onnx +from godot_rl.wrappers.stable_baselines_wrapper import StableBaselinesGodotEnv + +def main(policy_name=None, policy=None, parseargs=None): + if can_import("ray"): + print("WARNING: SB3 and ray[rllib] are not compatible.") + + args, extras = parseargs + # args, extras = args.parse_args() + + def handle_onnx_export(): + ''' + Enforces the onnx and zip extentions when saving models. + This avoids potential conflicts in case of identical names and extentions + ''' + if args.onnx_export_path is not None: + path_onnx = pathlib.Path(args.onnx_export_path).with_suffix(".onnx") + print(f"Exporting onnx to: {os.path.abspath(path_onnx)}") + export_ppo_model_as_onnx(model, str(path_onnx)) + + def handle_model_save(): + if args.save_model_path is not None: + zip_save_path = pathlib.Path(Args.save_model_path).with_suffix(".zip") + print(f"Saving model to: {os.path.abspath(zip_save_path)}") + model.save(zip_save_path) + + def close_env(): + try: + print("Closing env...") + env.close() + except Exception as e: + print(f"Exception while closing env: {e}") + + if policy_name is None: + path_checkpoint = os.path.join(args.exper_dir, f"{args.exper_name}_checkpoints") + else: + path_checkpoint = os.path.join(args.exper_dir, f"{policy_name}_checkpoints") + + abs_path_checkpoint = os.path.abspath(path_checkpoint) + + if args.save_checkpoint_frequency is not None and os.path.isdir(path_checkpoint): + raise RuntimeError( + f"{abs_path_checkpoint} already exists." + "Use a different directory or different name." + "If you want to override previous checkpoints you have to delete them manually." + ) + + if args.inference and args.resume_model_path is None: + raise parser.error( + "Using --inference requires --resume_model_path to be set." + ) + + if args.env_path is None and args.viz: + print("Info: using --viz without --env_path set has no effect.") + print("\nIn editor training will always render.") + + env = StableBaselinesGodotEnv( + env_path=args.env_path, + show_window=args.viz, + seed=args.seed, + n_parallel=args.n_parallel, + speedup=args.speedup + ) + env = VecMonitor(env) + + # LR schedule code snippet from: + # https://stable-baselines3.readthedocs.io/en/master/guide/examples.html#learning-rate-schedule + def linear_schedule(initial_value: float) -> Callable[[float], float]: + """ + Linear learning rate schedule. + + :param initial_value: Initial learning rate. + :return: schedule that computes + current learning rate depending on remaining progress + """ + + def func(progress_remaining: float) -> float: + """ + Progress will decrease from 1 (beginning) to 0. + + :param progress_remaining: + :return: current learning rate + """ + return progress_remaining * initial_value + + return func + + if args.resume_model_path is None: + if not args.linear_lr_schedule: + learning_rate = 0.0003 + else: + linear_schedule(0.0003) + + model: PPO = PPO( + # 'MultiInputPolicy' serves as an alias for MultiInputActorCriticPolicy + "MultiInputPolicy", + env, + batch_size=64, + ent_coef=0.01, + verbose=2, + n_steps=256, + tensorboard_log=args.exper_dir, + learning_rate=learning_rate, + policy_kwargs=policy, + ) + else: + path_zip = pathlib.Path(args.resume_model_path) + print(f"Loading model: {os.path.abspath(pathzip)}") + model: PPO = PPO.load( + path_zip, + env=env, + tensorboard_log=args.exper_dir + ) + + if args.inference: + obs = env.reset() + for i in range(args.timesteps): + action, _state = model.predict(obs, deterministic=True) + obs, reward, done, info = env.step(action) + else: + learn_arguments = dict( + total_timesteps=args.timesteps, + tb_log_name=policy_name + ) + if args.save_checkpoint_frequency: + print("Checkpoint saving enabled.") + print(f"\nCheckpoints will be saved to {abs_path_checkpoint}") + checkpoint_callback = CheckpointCallback( + save_freq=(args.save_checkpoint_frequency // env.num_envs), + save_path=path_checkpoint, + name_prefix=policy_name + ) + learn_arguments["callback"] = checkpoint_callback + try: + model.learn(**learn_arguments) + except KeyboardInterrupt: + print( + """ + Training interrupted by user. Will save if --save_model_path was set and/or export if --onnx_export was set. + """ + ) + + close_env() + handle_onnx_export() + handle_model_save() diff --git a/args.py b/args.py new file mode 100644 index 0000000..78a3483 --- /dev/null +++ b/args.py @@ -0,0 +1,109 @@ +import argparse + +def parse_args(): + + parser = argparse.ArgumentParser( + prog='Pneuma', + allow_abbrev=False, + description='A Reinforcement Learning platform made with Godot', + ) + parser.add_argument( + "--env_path", + default=None, + type=str, + help="The Godot binary to use, do not include for in editor training", + ) + parser.add_argument( + "--exper_dir", + default="logs/sb3", + type=str, + help="The name of the experiment directory, in which the tensorboard logs and checkpoints (if enabled) are " + "getting stored.", + ) + parser.add_argument( + "--exper_name", + default="experiment", + type=str, + help="The name of the experiment, which will be displayed in tensorboard and " + "for checkpoint directory and name (if enabled).", + ) + parser.add_argument( + "--seed", + type=int, + default=1, + help="seed of the experiment" + ) + parser.add_argument( + "--resume_model_path", + default=None, + type=str, + help="The path to a model file previously saved using --save_model_path or a checkpoint saved using " + "--save_checkpoints_frequency. Use this to resume training or infer from a saved model.", + ) + parser.add_argument( + "--save_model_path", + default=None, + type=str, + help="The path to use for saving the trained sb3 model after training is complete. Saved model can be used later " + "to resume training. Extension will be set to .zip", + ) + parser.add_argument( + "--save_checkpoint_frequency", + default=None, + type=int, + help=( + "If set, will save checkpoints every 'frequency' environment steps. " + "Requires a unique --experiment_name or --experiment_dir for each run. " + "Does not need --save_model_path to be set. " + ), + ) + parser.add_argument( + "--onnx_export_path", + default=None, + type=str, + help="If included, will export onnx file after training to the path specified.", + ) + parser.add_argument( + "--timesteps", + default=1_000_000, + type=int, + help="The number of environment steps to train for, default is 1_000_000. If resuming from a saved model, " + "it will continue training for this amount of steps from the saved state without counting previously trained " + "steps", + ) + parser.add_argument( + "--inference", + default=False, + action="store_true", + help="Instead of training, it will run inference on a loaded model for --timesteps steps. " + "Requires --resume_model_path to be set.", + ) + parser.add_argument( + "--linear_lr_schedule", + default=False, + action="store_true", + help="Use a linear LR schedule for training. If set, learning rate will decrease until it reaches 0 at " + "--timesteps" + "value. Note: On resuming training, the schedule will reset. If disabled, constant LR will be used.", + ) + parser.add_argument( + "--viz", + action="store_true", + help="If set, the simulation will be displayed in a window during training. Otherwise " + "training will run without rendering the simulation. This setting does not apply to in-editor training.", + default=False, + ) + parser.add_argument( + "--speedup", + default=1, + type=int, + help="Whether to speed up the physics in the env" + ) + parser.add_argument( + "--n_parallel", + default=1, + type=int, + help="How many instances of the environment executable to " "launch - requires --env_path to be set if > 1.", + ) + + return parser.parse_known_args() diff --git a/assets/audio/Fire.wav b/assets/audio/Fire.wav new file mode 100644 index 0000000..97bb0e4 Binary files /dev/null and b/assets/audio/Fire.wav differ diff --git a/assets/audio/attack/claw.wav b/assets/audio/attack/claw.wav new file mode 100644 index 0000000..1a98889 Binary files /dev/null and b/assets/audio/attack/claw.wav differ diff --git a/assets/audio/attack/fireball.wav b/assets/audio/attack/fireball.wav new file mode 100644 index 0000000..dc2c852 Binary files /dev/null and b/assets/audio/attack/fireball.wav differ diff --git a/assets/audio/attack/slash.wav b/assets/audio/attack/slash.wav new file mode 100644 index 0000000..942aeb0 Binary files /dev/null and b/assets/audio/attack/slash.wav differ diff --git a/assets/audio/death.wav b/assets/audio/death.wav new file mode 100644 index 0000000..ef03ab1 Binary files /dev/null and b/assets/audio/death.wav differ diff --git a/assets/audio/heal.wav b/assets/audio/heal.wav new file mode 100644 index 0000000..e94bab0 Binary files /dev/null and b/assets/audio/heal.wav differ diff --git a/assets/audio/hit.wav b/assets/audio/hit.wav new file mode 100644 index 0000000..435b317 Binary files /dev/null and b/assets/audio/hit.wav differ diff --git a/assets/audio/main.ogg b/assets/audio/main.ogg new file mode 100644 index 0000000..da5d252 Binary files /dev/null and b/assets/audio/main.ogg differ diff --git a/assets/audio/sword.wav b/assets/audio/sword.wav new file mode 100644 index 0000000..2e962d0 Binary files /dev/null and b/assets/audio/sword.wav differ diff --git a/assets/graphics/font/joystix.ttf b/assets/graphics/font/joystix.ttf new file mode 100644 index 0000000..5fd36a5 Binary files /dev/null and b/assets/graphics/font/joystix.ttf differ diff --git a/assets/graphics/grass/grass_1.png b/assets/graphics/grass/grass_1.png new file mode 100644 index 0000000..e59c1d4 Binary files /dev/null and b/assets/graphics/grass/grass_1.png differ diff --git a/assets/graphics/grass/grass_2.png b/assets/graphics/grass/grass_2.png new file mode 100644 index 0000000..74c656a Binary files /dev/null and b/assets/graphics/grass/grass_2.png differ diff --git a/assets/graphics/grass/grass_3.png b/assets/graphics/grass/grass_3.png new file mode 100644 index 0000000..da65a05 Binary files /dev/null and b/assets/graphics/grass/grass_3.png differ diff --git a/assets/graphics/monsters/bamboo/attack/0.png b/assets/graphics/monsters/bamboo/attack/0.png new file mode 100644 index 0000000..c14d75b Binary files /dev/null and b/assets/graphics/monsters/bamboo/attack/0.png differ diff --git a/assets/graphics/monsters/bamboo/idle/0.png b/assets/graphics/monsters/bamboo/idle/0.png new file mode 100644 index 0000000..c14d75b Binary files /dev/null and b/assets/graphics/monsters/bamboo/idle/0.png differ diff --git a/assets/graphics/monsters/bamboo/idle/1.png b/assets/graphics/monsters/bamboo/idle/1.png new file mode 100644 index 0000000..9dd1acc Binary files /dev/null and b/assets/graphics/monsters/bamboo/idle/1.png differ diff --git a/assets/graphics/monsters/bamboo/idle/2.png b/assets/graphics/monsters/bamboo/idle/2.png new file mode 100644 index 0000000..c14d75b Binary files /dev/null and b/assets/graphics/monsters/bamboo/idle/2.png differ diff --git a/assets/graphics/monsters/bamboo/idle/3.png b/assets/graphics/monsters/bamboo/idle/3.png new file mode 100644 index 0000000..6411298 Binary files /dev/null and b/assets/graphics/monsters/bamboo/idle/3.png differ diff --git a/assets/graphics/monsters/bamboo/move/0.png b/assets/graphics/monsters/bamboo/move/0.png new file mode 100644 index 0000000..c14d75b Binary files /dev/null and b/assets/graphics/monsters/bamboo/move/0.png differ diff --git a/assets/graphics/monsters/bamboo/move/1.png b/assets/graphics/monsters/bamboo/move/1.png new file mode 100644 index 0000000..9dd1acc Binary files /dev/null and b/assets/graphics/monsters/bamboo/move/1.png differ diff --git a/assets/graphics/monsters/bamboo/move/2.png b/assets/graphics/monsters/bamboo/move/2.png new file mode 100644 index 0000000..c14d75b Binary files /dev/null and b/assets/graphics/monsters/bamboo/move/2.png differ diff --git a/assets/graphics/monsters/bamboo/move/3.png b/assets/graphics/monsters/bamboo/move/3.png new file mode 100644 index 0000000..6411298 Binary files /dev/null and b/assets/graphics/monsters/bamboo/move/3.png differ diff --git a/assets/graphics/monsters/raccoon/attack/0.png b/assets/graphics/monsters/raccoon/attack/0.png new file mode 100644 index 0000000..2e53f25 Binary files /dev/null and b/assets/graphics/monsters/raccoon/attack/0.png differ diff --git a/assets/graphics/monsters/raccoon/attack/1.png b/assets/graphics/monsters/raccoon/attack/1.png new file mode 100644 index 0000000..21c4d49 Binary files /dev/null and b/assets/graphics/monsters/raccoon/attack/1.png differ diff --git a/assets/graphics/monsters/raccoon/attack/2.png b/assets/graphics/monsters/raccoon/attack/2.png new file mode 100644 index 0000000..3319c79 Binary files /dev/null and b/assets/graphics/monsters/raccoon/attack/2.png differ diff --git a/assets/graphics/monsters/raccoon/attack/3.png b/assets/graphics/monsters/raccoon/attack/3.png new file mode 100644 index 0000000..aa2d58f Binary files /dev/null and b/assets/graphics/monsters/raccoon/attack/3.png differ diff --git a/assets/graphics/monsters/raccoon/idle/0.png b/assets/graphics/monsters/raccoon/idle/0.png new file mode 100644 index 0000000..cf0fb7f Binary files /dev/null and b/assets/graphics/monsters/raccoon/idle/0.png differ diff --git a/assets/graphics/monsters/raccoon/idle/1.png b/assets/graphics/monsters/raccoon/idle/1.png new file mode 100644 index 0000000..cf0fb7f Binary files /dev/null and b/assets/graphics/monsters/raccoon/idle/1.png differ diff --git a/assets/graphics/monsters/raccoon/idle/2.png b/assets/graphics/monsters/raccoon/idle/2.png new file mode 100644 index 0000000..8d16e08 Binary files /dev/null and b/assets/graphics/monsters/raccoon/idle/2.png differ diff --git a/assets/graphics/monsters/raccoon/idle/3.png b/assets/graphics/monsters/raccoon/idle/3.png new file mode 100644 index 0000000..dc57a96 Binary files /dev/null and b/assets/graphics/monsters/raccoon/idle/3.png differ diff --git a/assets/graphics/monsters/raccoon/idle/4.png b/assets/graphics/monsters/raccoon/idle/4.png new file mode 100644 index 0000000..fb12e6c Binary files /dev/null and b/assets/graphics/monsters/raccoon/idle/4.png differ diff --git a/assets/graphics/monsters/raccoon/idle/5.png b/assets/graphics/monsters/raccoon/idle/5.png new file mode 100644 index 0000000..c0ede56 Binary files /dev/null and b/assets/graphics/monsters/raccoon/idle/5.png differ diff --git a/assets/graphics/monsters/raccoon/move/0.png b/assets/graphics/monsters/raccoon/move/0.png new file mode 100644 index 0000000..a60b9d0 Binary files /dev/null and b/assets/graphics/monsters/raccoon/move/0.png differ diff --git a/assets/graphics/monsters/raccoon/move/1.png b/assets/graphics/monsters/raccoon/move/1.png new file mode 100644 index 0000000..34410ca Binary files /dev/null and b/assets/graphics/monsters/raccoon/move/1.png differ diff --git a/assets/graphics/monsters/raccoon/move/2.png b/assets/graphics/monsters/raccoon/move/2.png new file mode 100644 index 0000000..c299286 Binary files /dev/null and b/assets/graphics/monsters/raccoon/move/2.png differ diff --git a/assets/graphics/monsters/raccoon/move/3.png b/assets/graphics/monsters/raccoon/move/3.png new file mode 100644 index 0000000..7d9ee77 Binary files /dev/null and b/assets/graphics/monsters/raccoon/move/3.png differ diff --git a/assets/graphics/monsters/raccoon/move/4.png b/assets/graphics/monsters/raccoon/move/4.png new file mode 100644 index 0000000..656981c Binary files /dev/null and b/assets/graphics/monsters/raccoon/move/4.png differ diff --git a/assets/graphics/monsters/spirit/attack/0.png b/assets/graphics/monsters/spirit/attack/0.png new file mode 100644 index 0000000..0afa8f1 Binary files /dev/null and b/assets/graphics/monsters/spirit/attack/0.png differ diff --git a/assets/graphics/monsters/spirit/idle/0.png b/assets/graphics/monsters/spirit/idle/0.png new file mode 100644 index 0000000..0aee4b5 Binary files /dev/null and b/assets/graphics/monsters/spirit/idle/0.png differ diff --git a/assets/graphics/monsters/spirit/idle/1.png b/assets/graphics/monsters/spirit/idle/1.png new file mode 100644 index 0000000..efe735c Binary files /dev/null and b/assets/graphics/monsters/spirit/idle/1.png differ diff --git a/assets/graphics/monsters/spirit/idle/2.png b/assets/graphics/monsters/spirit/idle/2.png new file mode 100644 index 0000000..a46d5e2 Binary files /dev/null and b/assets/graphics/monsters/spirit/idle/2.png differ diff --git a/assets/graphics/monsters/spirit/idle/3.png b/assets/graphics/monsters/spirit/idle/3.png new file mode 100644 index 0000000..15e5d4c Binary files /dev/null and b/assets/graphics/monsters/spirit/idle/3.png differ diff --git a/assets/graphics/monsters/spirit/move/0.png b/assets/graphics/monsters/spirit/move/0.png new file mode 100644 index 0000000..0afa8f1 Binary files /dev/null and b/assets/graphics/monsters/spirit/move/0.png differ diff --git a/assets/graphics/monsters/spirit/move/1.png b/assets/graphics/monsters/spirit/move/1.png new file mode 100644 index 0000000..bf8f85b Binary files /dev/null and b/assets/graphics/monsters/spirit/move/1.png differ diff --git a/assets/graphics/monsters/spirit/move/2.png b/assets/graphics/monsters/spirit/move/2.png new file mode 100644 index 0000000..809ebc2 Binary files /dev/null and b/assets/graphics/monsters/spirit/move/2.png differ diff --git a/assets/graphics/monsters/spirit/move/3.png b/assets/graphics/monsters/spirit/move/3.png new file mode 100644 index 0000000..463875f Binary files /dev/null and b/assets/graphics/monsters/spirit/move/3.png differ diff --git a/assets/graphics/monsters/squid/attack/0 - Copy (2).png b/assets/graphics/monsters/squid/attack/0 - Copy (2).png new file mode 100644 index 0000000..644197e Binary files /dev/null and b/assets/graphics/monsters/squid/attack/0 - Copy (2).png differ diff --git a/assets/graphics/monsters/squid/attack/0 - Copy (3).png b/assets/graphics/monsters/squid/attack/0 - Copy (3).png new file mode 100644 index 0000000..644197e Binary files /dev/null and b/assets/graphics/monsters/squid/attack/0 - Copy (3).png differ diff --git a/assets/graphics/monsters/squid/attack/0 - Copy.png b/assets/graphics/monsters/squid/attack/0 - Copy.png new file mode 100644 index 0000000..644197e Binary files /dev/null and b/assets/graphics/monsters/squid/attack/0 - Copy.png differ diff --git a/assets/graphics/monsters/squid/attack/0.png b/assets/graphics/monsters/squid/attack/0.png new file mode 100644 index 0000000..644197e Binary files /dev/null and b/assets/graphics/monsters/squid/attack/0.png differ diff --git a/assets/graphics/monsters/squid/idle/0.png b/assets/graphics/monsters/squid/idle/0.png new file mode 100644 index 0000000..a9beba8 Binary files /dev/null and b/assets/graphics/monsters/squid/idle/0.png differ diff --git a/assets/graphics/monsters/squid/idle/1.png b/assets/graphics/monsters/squid/idle/1.png new file mode 100644 index 0000000..f854919 Binary files /dev/null and b/assets/graphics/monsters/squid/idle/1.png differ diff --git a/assets/graphics/monsters/squid/idle/2.png b/assets/graphics/monsters/squid/idle/2.png new file mode 100644 index 0000000..a9beba8 Binary files /dev/null and b/assets/graphics/monsters/squid/idle/2.png differ diff --git a/assets/graphics/monsters/squid/idle/3.png b/assets/graphics/monsters/squid/idle/3.png new file mode 100644 index 0000000..9c588e1 Binary files /dev/null and b/assets/graphics/monsters/squid/idle/3.png differ diff --git a/assets/graphics/monsters/squid/idle/4.png b/assets/graphics/monsters/squid/idle/4.png new file mode 100644 index 0000000..9c588e1 Binary files /dev/null and b/assets/graphics/monsters/squid/idle/4.png differ diff --git a/assets/graphics/monsters/squid/move/0.png b/assets/graphics/monsters/squid/move/0.png new file mode 100644 index 0000000..a9beba8 Binary files /dev/null and b/assets/graphics/monsters/squid/move/0.png differ diff --git a/assets/graphics/monsters/squid/move/1.png b/assets/graphics/monsters/squid/move/1.png new file mode 100644 index 0000000..f854919 Binary files /dev/null and b/assets/graphics/monsters/squid/move/1.png differ diff --git a/assets/graphics/monsters/squid/move/2.png b/assets/graphics/monsters/squid/move/2.png new file mode 100644 index 0000000..9c588e1 Binary files /dev/null and b/assets/graphics/monsters/squid/move/2.png differ diff --git a/assets/graphics/monsters/squid/move/3.png b/assets/graphics/monsters/squid/move/3.png new file mode 100644 index 0000000..9c588e1 Binary files /dev/null and b/assets/graphics/monsters/squid/move/3.png differ diff --git a/assets/graphics/objects/0.png b/assets/graphics/objects/0.png new file mode 100644 index 0000000..05fc485 Binary files /dev/null and b/assets/graphics/objects/0.png differ diff --git a/assets/graphics/objects/01.png b/assets/graphics/objects/01.png new file mode 100644 index 0000000..3fa3af9 Binary files /dev/null and b/assets/graphics/objects/01.png differ diff --git a/assets/graphics/objects/02.png b/assets/graphics/objects/02.png new file mode 100644 index 0000000..c91ceec Binary files /dev/null and b/assets/graphics/objects/02.png differ diff --git a/assets/graphics/objects/03.png b/assets/graphics/objects/03.png new file mode 100644 index 0000000..186ff45 Binary files /dev/null and b/assets/graphics/objects/03.png differ diff --git a/assets/graphics/objects/04.png b/assets/graphics/objects/04.png new file mode 100644 index 0000000..f3a3e7a Binary files /dev/null and b/assets/graphics/objects/04.png differ diff --git a/assets/graphics/objects/05.png b/assets/graphics/objects/05.png new file mode 100644 index 0000000..eab8994 Binary files /dev/null and b/assets/graphics/objects/05.png differ diff --git a/assets/graphics/objects/06.png b/assets/graphics/objects/06.png new file mode 100644 index 0000000..a7859b7 Binary files /dev/null and b/assets/graphics/objects/06.png differ diff --git a/assets/graphics/objects/07.png b/assets/graphics/objects/07.png new file mode 100644 index 0000000..a436b83 Binary files /dev/null and b/assets/graphics/objects/07.png differ diff --git a/assets/graphics/objects/08.png b/assets/graphics/objects/08.png new file mode 100644 index 0000000..7fde04e Binary files /dev/null and b/assets/graphics/objects/08.png differ diff --git a/assets/graphics/objects/09.png b/assets/graphics/objects/09.png new file mode 100644 index 0000000..fbd0ebb Binary files /dev/null and b/assets/graphics/objects/09.png differ diff --git a/assets/graphics/objects/10.png b/assets/graphics/objects/10.png new file mode 100644 index 0000000..067a503 Binary files /dev/null and b/assets/graphics/objects/10.png differ diff --git a/assets/graphics/objects/11.png b/assets/graphics/objects/11.png new file mode 100644 index 0000000..37edc1e Binary files /dev/null and b/assets/graphics/objects/11.png differ diff --git a/assets/graphics/objects/12.png b/assets/graphics/objects/12.png new file mode 100644 index 0000000..d1967c2 Binary files /dev/null and b/assets/graphics/objects/12.png differ diff --git a/assets/graphics/objects/13.png b/assets/graphics/objects/13.png new file mode 100644 index 0000000..f01d839 Binary files /dev/null and b/assets/graphics/objects/13.png differ diff --git a/assets/graphics/objects/14.png b/assets/graphics/objects/14.png new file mode 100644 index 0000000..6a7b4bc Binary files /dev/null and b/assets/graphics/objects/14.png differ diff --git a/assets/graphics/objects/15.png b/assets/graphics/objects/15.png new file mode 100644 index 0000000..783c417 Binary files /dev/null and b/assets/graphics/objects/15.png differ diff --git a/assets/graphics/objects/16.png b/assets/graphics/objects/16.png new file mode 100644 index 0000000..69b3119 Binary files /dev/null and b/assets/graphics/objects/16.png differ diff --git a/assets/graphics/objects/17.png b/assets/graphics/objects/17.png new file mode 100644 index 0000000..23cfa85 Binary files /dev/null and b/assets/graphics/objects/17.png differ diff --git a/assets/graphics/objects/18.png b/assets/graphics/objects/18.png new file mode 100644 index 0000000..8497695 Binary files /dev/null and b/assets/graphics/objects/18.png differ diff --git a/assets/graphics/objects/19.png b/assets/graphics/objects/19.png new file mode 100644 index 0000000..425d16f Binary files /dev/null and b/assets/graphics/objects/19.png differ diff --git a/assets/graphics/objects/20.png b/assets/graphics/objects/20.png new file mode 100644 index 0000000..7028a89 Binary files /dev/null and b/assets/graphics/objects/20.png differ diff --git a/assets/graphics/particles/aura/0.png b/assets/graphics/particles/aura/0.png new file mode 100644 index 0000000..ca3080c Binary files /dev/null and b/assets/graphics/particles/aura/0.png differ diff --git a/assets/graphics/particles/aura/1.png b/assets/graphics/particles/aura/1.png new file mode 100644 index 0000000..587df6e Binary files /dev/null and b/assets/graphics/particles/aura/1.png differ diff --git a/assets/graphics/particles/aura/2.png b/assets/graphics/particles/aura/2.png new file mode 100644 index 0000000..345b25a Binary files /dev/null and b/assets/graphics/particles/aura/2.png differ diff --git a/assets/graphics/particles/aura/3.png b/assets/graphics/particles/aura/3.png new file mode 100644 index 0000000..f5aa4c5 Binary files /dev/null and b/assets/graphics/particles/aura/3.png differ diff --git a/assets/graphics/particles/bamboo/0.png b/assets/graphics/particles/bamboo/0.png new file mode 100644 index 0000000..a28b25a Binary files /dev/null and b/assets/graphics/particles/bamboo/0.png differ diff --git a/assets/graphics/particles/bamboo/1.png b/assets/graphics/particles/bamboo/1.png new file mode 100644 index 0000000..234355a Binary files /dev/null and b/assets/graphics/particles/bamboo/1.png differ diff --git a/assets/graphics/particles/claw/0.png b/assets/graphics/particles/claw/0.png new file mode 100644 index 0000000..b9af05a Binary files /dev/null and b/assets/graphics/particles/claw/0.png differ diff --git a/assets/graphics/particles/claw/1.png b/assets/graphics/particles/claw/1.png new file mode 100644 index 0000000..60ab800 Binary files /dev/null and b/assets/graphics/particles/claw/1.png differ diff --git a/assets/graphics/particles/claw/2.png b/assets/graphics/particles/claw/2.png new file mode 100644 index 0000000..e3c239b Binary files /dev/null and b/assets/graphics/particles/claw/2.png differ diff --git a/assets/graphics/particles/claw/3.png b/assets/graphics/particles/claw/3.png new file mode 100644 index 0000000..2a579b7 Binary files /dev/null and b/assets/graphics/particles/claw/3.png differ diff --git a/assets/graphics/particles/flame/fire.png b/assets/graphics/particles/flame/fire.png new file mode 100644 index 0000000..2fb9ffc Binary files /dev/null and b/assets/graphics/particles/flame/fire.png differ diff --git a/assets/graphics/particles/flame/frames/0.png b/assets/graphics/particles/flame/frames/0.png new file mode 100644 index 0000000..fe33ae5 Binary files /dev/null and b/assets/graphics/particles/flame/frames/0.png differ diff --git a/assets/graphics/particles/flame/frames/01.png b/assets/graphics/particles/flame/frames/01.png new file mode 100644 index 0000000..734a74f Binary files /dev/null and b/assets/graphics/particles/flame/frames/01.png differ diff --git a/assets/graphics/particles/flame/frames/02.png b/assets/graphics/particles/flame/frames/02.png new file mode 100644 index 0000000..63536a7 Binary files /dev/null and b/assets/graphics/particles/flame/frames/02.png differ diff --git a/assets/graphics/particles/flame/frames/03.png b/assets/graphics/particles/flame/frames/03.png new file mode 100644 index 0000000..49c4995 Binary files /dev/null and b/assets/graphics/particles/flame/frames/03.png differ diff --git a/assets/graphics/particles/flame/frames/04.png b/assets/graphics/particles/flame/frames/04.png new file mode 100644 index 0000000..77e0474 Binary files /dev/null and b/assets/graphics/particles/flame/frames/04.png differ diff --git a/assets/graphics/particles/flame/frames/05.png b/assets/graphics/particles/flame/frames/05.png new file mode 100644 index 0000000..04691a5 Binary files /dev/null and b/assets/graphics/particles/flame/frames/05.png differ diff --git a/assets/graphics/particles/flame/frames/06.png b/assets/graphics/particles/flame/frames/06.png new file mode 100644 index 0000000..4738aa7 Binary files /dev/null and b/assets/graphics/particles/flame/frames/06.png differ diff --git a/assets/graphics/particles/flame/frames/07.png b/assets/graphics/particles/flame/frames/07.png new file mode 100644 index 0000000..1faa1d3 Binary files /dev/null and b/assets/graphics/particles/flame/frames/07.png differ diff --git a/assets/graphics/particles/flame/frames/08.png b/assets/graphics/particles/flame/frames/08.png new file mode 100644 index 0000000..44b7e28 Binary files /dev/null and b/assets/graphics/particles/flame/frames/08.png differ diff --git a/assets/graphics/particles/flame/frames/09.png b/assets/graphics/particles/flame/frames/09.png new file mode 100644 index 0000000..cd35c03 Binary files /dev/null and b/assets/graphics/particles/flame/frames/09.png differ diff --git a/assets/graphics/particles/flame/frames/10.png b/assets/graphics/particles/flame/frames/10.png new file mode 100644 index 0000000..7164544 Binary files /dev/null and b/assets/graphics/particles/flame/frames/10.png differ diff --git a/assets/graphics/particles/flame/frames/11.png b/assets/graphics/particles/flame/frames/11.png new file mode 100644 index 0000000..5555377 Binary files /dev/null and b/assets/graphics/particles/flame/frames/11.png differ diff --git a/assets/graphics/particles/heal/frames/0.png b/assets/graphics/particles/heal/frames/0.png new file mode 100644 index 0000000..cd93684 Binary files /dev/null and b/assets/graphics/particles/heal/frames/0.png differ diff --git a/assets/graphics/particles/heal/frames/1.png b/assets/graphics/particles/heal/frames/1.png new file mode 100644 index 0000000..83b4cf1 Binary files /dev/null and b/assets/graphics/particles/heal/frames/1.png differ diff --git a/assets/graphics/particles/heal/frames/2.png b/assets/graphics/particles/heal/frames/2.png new file mode 100644 index 0000000..de0b9bd Binary files /dev/null and b/assets/graphics/particles/heal/frames/2.png differ diff --git a/assets/graphics/particles/heal/frames/3.png b/assets/graphics/particles/heal/frames/3.png new file mode 100644 index 0000000..d5ab576 Binary files /dev/null and b/assets/graphics/particles/heal/frames/3.png differ diff --git a/assets/graphics/particles/heal/frames/4.png b/assets/graphics/particles/heal/frames/4.png new file mode 100644 index 0000000..e26afd3 Binary files /dev/null and b/assets/graphics/particles/heal/frames/4.png differ diff --git a/assets/graphics/particles/heal/heal.png b/assets/graphics/particles/heal/heal.png new file mode 100644 index 0000000..ad7de97 Binary files /dev/null and b/assets/graphics/particles/heal/heal.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00000.png b/assets/graphics/particles/leaf1/leaf1_00000.png new file mode 100644 index 0000000..b3d34ea Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00000.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00001.png b/assets/graphics/particles/leaf1/leaf1_00001.png new file mode 100644 index 0000000..22fce58 Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00001.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00002.png b/assets/graphics/particles/leaf1/leaf1_00002.png new file mode 100644 index 0000000..f8d2b65 Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00002.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00003.png b/assets/graphics/particles/leaf1/leaf1_00003.png new file mode 100644 index 0000000..e3e59b6 Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00003.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00004.png b/assets/graphics/particles/leaf1/leaf1_00004.png new file mode 100644 index 0000000..a703f36 Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00004.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00005.png b/assets/graphics/particles/leaf1/leaf1_00005.png new file mode 100644 index 0000000..39e159a Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00005.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00006.png b/assets/graphics/particles/leaf1/leaf1_00006.png new file mode 100644 index 0000000..a83b3d0 Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00006.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00007.png b/assets/graphics/particles/leaf1/leaf1_00007.png new file mode 100644 index 0000000..ed3fca8 Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00007.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00008.png b/assets/graphics/particles/leaf1/leaf1_00008.png new file mode 100644 index 0000000..f6bf4c9 Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00008.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00009.png b/assets/graphics/particles/leaf1/leaf1_00009.png new file mode 100644 index 0000000..1e27176 Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00009.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00010.png b/assets/graphics/particles/leaf1/leaf1_00010.png new file mode 100644 index 0000000..4be9658 Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00010.png differ diff --git a/assets/graphics/particles/leaf1/leaf1_00011.png b/assets/graphics/particles/leaf1/leaf1_00011.png new file mode 100644 index 0000000..57f0d06 Binary files /dev/null and b/assets/graphics/particles/leaf1/leaf1_00011.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00000.png b/assets/graphics/particles/leaf2/leaf1_00000.png new file mode 100644 index 0000000..bd43308 Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00000.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00001.png b/assets/graphics/particles/leaf2/leaf1_00001.png new file mode 100644 index 0000000..3013b91 Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00001.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00002.png b/assets/graphics/particles/leaf2/leaf1_00002.png new file mode 100644 index 0000000..30300af Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00002.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00003.png b/assets/graphics/particles/leaf2/leaf1_00003.png new file mode 100644 index 0000000..8f0b661 Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00003.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00004.png b/assets/graphics/particles/leaf2/leaf1_00004.png new file mode 100644 index 0000000..8248fba Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00004.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00005.png b/assets/graphics/particles/leaf2/leaf1_00005.png new file mode 100644 index 0000000..ecf4ffa Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00005.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00006.png b/assets/graphics/particles/leaf2/leaf1_00006.png new file mode 100644 index 0000000..ece22b8 Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00006.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00007.png b/assets/graphics/particles/leaf2/leaf1_00007.png new file mode 100644 index 0000000..1f1f7ee Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00007.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00008.png b/assets/graphics/particles/leaf2/leaf1_00008.png new file mode 100644 index 0000000..33f28bd Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00008.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00009.png b/assets/graphics/particles/leaf2/leaf1_00009.png new file mode 100644 index 0000000..6d6ff48 Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00009.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00010.png b/assets/graphics/particles/leaf2/leaf1_00010.png new file mode 100644 index 0000000..d1a770e Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00010.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00011.png b/assets/graphics/particles/leaf2/leaf1_00011.png new file mode 100644 index 0000000..0435cea Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00011.png differ diff --git a/assets/graphics/particles/leaf2/leaf1_00012.png b/assets/graphics/particles/leaf2/leaf1_00012.png new file mode 100644 index 0000000..3848e8d Binary files /dev/null and b/assets/graphics/particles/leaf2/leaf1_00012.png differ diff --git a/assets/graphics/particles/leaf3/leaf1_00000.png b/assets/graphics/particles/leaf3/leaf1_00000.png new file mode 100644 index 0000000..c31c69f Binary files /dev/null and b/assets/graphics/particles/leaf3/leaf1_00000.png differ diff --git a/assets/graphics/particles/leaf3/leaf1_00001.png b/assets/graphics/particles/leaf3/leaf1_00001.png new file mode 100644 index 0000000..ad36fe5 Binary files /dev/null and b/assets/graphics/particles/leaf3/leaf1_00001.png differ diff --git a/assets/graphics/particles/leaf3/leaf1_00002.png b/assets/graphics/particles/leaf3/leaf1_00002.png new file mode 100644 index 0000000..8338ffd Binary files /dev/null and b/assets/graphics/particles/leaf3/leaf1_00002.png differ diff --git a/assets/graphics/particles/leaf3/leaf1_00003.png b/assets/graphics/particles/leaf3/leaf1_00003.png new file mode 100644 index 0000000..444a0e1 Binary files /dev/null and b/assets/graphics/particles/leaf3/leaf1_00003.png differ diff --git a/assets/graphics/particles/leaf3/leaf1_00004.png b/assets/graphics/particles/leaf3/leaf1_00004.png new file mode 100644 index 0000000..4f62188 Binary files /dev/null and b/assets/graphics/particles/leaf3/leaf1_00004.png differ diff --git a/assets/graphics/particles/leaf3/leaf1_00005.png b/assets/graphics/particles/leaf3/leaf1_00005.png new file mode 100644 index 0000000..99dc366 Binary files /dev/null and b/assets/graphics/particles/leaf3/leaf1_00005.png differ diff --git a/assets/graphics/particles/leaf3/leaf1_00006.png b/assets/graphics/particles/leaf3/leaf1_00006.png new file mode 100644 index 0000000..50c0d9a Binary files /dev/null and b/assets/graphics/particles/leaf3/leaf1_00006.png differ diff --git a/assets/graphics/particles/leaf3/leaf1_00007.png b/assets/graphics/particles/leaf3/leaf1_00007.png new file mode 100644 index 0000000..d7a7a37 Binary files /dev/null and b/assets/graphics/particles/leaf3/leaf1_00007.png differ diff --git a/assets/graphics/particles/leaf3/leaf1_00008.png b/assets/graphics/particles/leaf3/leaf1_00008.png new file mode 100644 index 0000000..8df60d4 Binary files /dev/null and b/assets/graphics/particles/leaf3/leaf1_00008.png differ diff --git a/assets/graphics/particles/leaf3/leaf1_00009.png b/assets/graphics/particles/leaf3/leaf1_00009.png new file mode 100644 index 0000000..d14ee99 Binary files /dev/null and b/assets/graphics/particles/leaf3/leaf1_00009.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00000.png b/assets/graphics/particles/leaf4/leaf1_00000.png new file mode 100644 index 0000000..a6309fe Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00000.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00001.png b/assets/graphics/particles/leaf4/leaf1_00001.png new file mode 100644 index 0000000..3d31420 Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00001.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00002.png b/assets/graphics/particles/leaf4/leaf1_00002.png new file mode 100644 index 0000000..cfcc565 Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00002.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00003.png b/assets/graphics/particles/leaf4/leaf1_00003.png new file mode 100644 index 0000000..af077e3 Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00003.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00004.png b/assets/graphics/particles/leaf4/leaf1_00004.png new file mode 100644 index 0000000..7b0be93 Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00004.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00005.png b/assets/graphics/particles/leaf4/leaf1_00005.png new file mode 100644 index 0000000..7b5ac2a Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00005.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00006.png b/assets/graphics/particles/leaf4/leaf1_00006.png new file mode 100644 index 0000000..8229334 Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00006.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00007.png b/assets/graphics/particles/leaf4/leaf1_00007.png new file mode 100644 index 0000000..1915fab Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00007.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00008.png b/assets/graphics/particles/leaf4/leaf1_00008.png new file mode 100644 index 0000000..157a04a Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00008.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00009.png b/assets/graphics/particles/leaf4/leaf1_00009.png new file mode 100644 index 0000000..27fb1fd Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00009.png differ diff --git a/assets/graphics/particles/leaf4/leaf1_00010.png b/assets/graphics/particles/leaf4/leaf1_00010.png new file mode 100644 index 0000000..5030b8c Binary files /dev/null and b/assets/graphics/particles/leaf4/leaf1_00010.png differ diff --git a/assets/graphics/particles/leaf5/leaf1_00000.png b/assets/graphics/particles/leaf5/leaf1_00000.png new file mode 100644 index 0000000..b0e81b0 Binary files /dev/null and b/assets/graphics/particles/leaf5/leaf1_00000.png differ diff --git a/assets/graphics/particles/leaf5/leaf1_00001.png b/assets/graphics/particles/leaf5/leaf1_00001.png new file mode 100644 index 0000000..b7828b6 Binary files /dev/null and b/assets/graphics/particles/leaf5/leaf1_00001.png differ diff --git a/assets/graphics/particles/leaf5/leaf1_00002.png b/assets/graphics/particles/leaf5/leaf1_00002.png new file mode 100644 index 0000000..ccc2714 Binary files /dev/null and b/assets/graphics/particles/leaf5/leaf1_00002.png differ diff --git a/assets/graphics/particles/leaf5/leaf1_00003.png b/assets/graphics/particles/leaf5/leaf1_00003.png new file mode 100644 index 0000000..f1fd9b1 Binary files /dev/null and b/assets/graphics/particles/leaf5/leaf1_00003.png differ diff --git a/assets/graphics/particles/leaf5/leaf1_00004.png b/assets/graphics/particles/leaf5/leaf1_00004.png new file mode 100644 index 0000000..de90457 Binary files /dev/null and b/assets/graphics/particles/leaf5/leaf1_00004.png differ diff --git a/assets/graphics/particles/leaf5/leaf1_00005.png b/assets/graphics/particles/leaf5/leaf1_00005.png new file mode 100644 index 0000000..661a16a Binary files /dev/null and b/assets/graphics/particles/leaf5/leaf1_00005.png differ diff --git a/assets/graphics/particles/leaf5/leaf1_00006.png b/assets/graphics/particles/leaf5/leaf1_00006.png new file mode 100644 index 0000000..996ed74 Binary files /dev/null and b/assets/graphics/particles/leaf5/leaf1_00006.png differ diff --git a/assets/graphics/particles/leaf5/leaf1_00007.png b/assets/graphics/particles/leaf5/leaf1_00007.png new file mode 100644 index 0000000..bc0ab50 Binary files /dev/null and b/assets/graphics/particles/leaf5/leaf1_00007.png differ diff --git a/assets/graphics/particles/leaf5/leaf1_00008.png b/assets/graphics/particles/leaf5/leaf1_00008.png new file mode 100644 index 0000000..9de760e Binary files /dev/null and b/assets/graphics/particles/leaf5/leaf1_00008.png differ diff --git a/assets/graphics/particles/leaf5/leaf1_00009.png b/assets/graphics/particles/leaf5/leaf1_00009.png new file mode 100644 index 0000000..ec73497 Binary files /dev/null and b/assets/graphics/particles/leaf5/leaf1_00009.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00000.png b/assets/graphics/particles/leaf6/leaf1_00000.png new file mode 100644 index 0000000..4969977 Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00000.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00001.png b/assets/graphics/particles/leaf6/leaf1_00001.png new file mode 100644 index 0000000..4212765 Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00001.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00002.png b/assets/graphics/particles/leaf6/leaf1_00002.png new file mode 100644 index 0000000..7237076 Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00002.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00003.png b/assets/graphics/particles/leaf6/leaf1_00003.png new file mode 100644 index 0000000..a03d0fe Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00003.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00004.png b/assets/graphics/particles/leaf6/leaf1_00004.png new file mode 100644 index 0000000..e585fb4 Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00004.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00005.png b/assets/graphics/particles/leaf6/leaf1_00005.png new file mode 100644 index 0000000..13d8d55 Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00005.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00006.png b/assets/graphics/particles/leaf6/leaf1_00006.png new file mode 100644 index 0000000..8b153dc Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00006.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00007.png b/assets/graphics/particles/leaf6/leaf1_00007.png new file mode 100644 index 0000000..aab3b60 Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00007.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00008.png b/assets/graphics/particles/leaf6/leaf1_00008.png new file mode 100644 index 0000000..9d32aa9 Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00008.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00009.png b/assets/graphics/particles/leaf6/leaf1_00009.png new file mode 100644 index 0000000..1f87666 Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00009.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00010.png b/assets/graphics/particles/leaf6/leaf1_00010.png new file mode 100644 index 0000000..c54c793 Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00010.png differ diff --git a/assets/graphics/particles/leaf6/leaf1_00011.png b/assets/graphics/particles/leaf6/leaf1_00011.png new file mode 100644 index 0000000..3659600 Binary files /dev/null and b/assets/graphics/particles/leaf6/leaf1_00011.png differ diff --git a/assets/graphics/particles/leaf_attack/0.png b/assets/graphics/particles/leaf_attack/0.png new file mode 100644 index 0000000..a9dc64d Binary files /dev/null and b/assets/graphics/particles/leaf_attack/0.png differ diff --git a/assets/graphics/particles/leaf_attack/1.png b/assets/graphics/particles/leaf_attack/1.png new file mode 100644 index 0000000..2cfe1a5 Binary files /dev/null and b/assets/graphics/particles/leaf_attack/1.png differ diff --git a/assets/graphics/particles/leaf_attack/2.png b/assets/graphics/particles/leaf_attack/2.png new file mode 100644 index 0000000..19eabbd Binary files /dev/null and b/assets/graphics/particles/leaf_attack/2.png differ diff --git a/assets/graphics/particles/leaf_attack/3.png b/assets/graphics/particles/leaf_attack/3.png new file mode 100644 index 0000000..b7c453f Binary files /dev/null and b/assets/graphics/particles/leaf_attack/3.png differ diff --git a/assets/graphics/particles/leaf_attack/4.png b/assets/graphics/particles/leaf_attack/4.png new file mode 100644 index 0000000..d26d38e Binary files /dev/null and b/assets/graphics/particles/leaf_attack/4.png differ diff --git a/assets/graphics/particles/leaf_attack/5.png b/assets/graphics/particles/leaf_attack/5.png new file mode 100644 index 0000000..73c1f4f Binary files /dev/null and b/assets/graphics/particles/leaf_attack/5.png differ diff --git a/assets/graphics/particles/leaf_attack/6.png b/assets/graphics/particles/leaf_attack/6.png new file mode 100644 index 0000000..d68a09d Binary files /dev/null and b/assets/graphics/particles/leaf_attack/6.png differ diff --git a/assets/graphics/particles/nova/0.png b/assets/graphics/particles/nova/0.png new file mode 100644 index 0000000..fdcc423 Binary files /dev/null and b/assets/graphics/particles/nova/0.png differ diff --git a/assets/graphics/particles/nova/1.png b/assets/graphics/particles/nova/1.png new file mode 100644 index 0000000..320b930 Binary files /dev/null and b/assets/graphics/particles/nova/1.png differ diff --git a/assets/graphics/particles/nova/2.png b/assets/graphics/particles/nova/2.png new file mode 100644 index 0000000..91766d8 Binary files /dev/null and b/assets/graphics/particles/nova/2.png differ diff --git a/assets/graphics/particles/nova/3.png b/assets/graphics/particles/nova/3.png new file mode 100644 index 0000000..98371b1 Binary files /dev/null and b/assets/graphics/particles/nova/3.png differ diff --git a/assets/graphics/particles/nova/4.png b/assets/graphics/particles/nova/4.png new file mode 100644 index 0000000..26924ab Binary files /dev/null and b/assets/graphics/particles/nova/4.png differ diff --git a/assets/graphics/particles/nova/5.png b/assets/graphics/particles/nova/5.png new file mode 100644 index 0000000..f6aae60 Binary files /dev/null and b/assets/graphics/particles/nova/5.png differ diff --git a/assets/graphics/particles/raccoon/0.png b/assets/graphics/particles/raccoon/0.png new file mode 100644 index 0000000..cc1a9eb Binary files /dev/null and b/assets/graphics/particles/raccoon/0.png differ diff --git a/assets/graphics/particles/raccoon/1.png b/assets/graphics/particles/raccoon/1.png new file mode 100644 index 0000000..7385737 Binary files /dev/null and b/assets/graphics/particles/raccoon/1.png differ diff --git a/assets/graphics/particles/raccoon/2.png b/assets/graphics/particles/raccoon/2.png new file mode 100644 index 0000000..8b384be Binary files /dev/null and b/assets/graphics/particles/raccoon/2.png differ diff --git a/assets/graphics/particles/raccoon/3.png b/assets/graphics/particles/raccoon/3.png new file mode 100644 index 0000000..d6feaf3 Binary files /dev/null and b/assets/graphics/particles/raccoon/3.png differ diff --git a/assets/graphics/particles/raccoon/4.png b/assets/graphics/particles/raccoon/4.png new file mode 100644 index 0000000..e550c15 Binary files /dev/null and b/assets/graphics/particles/raccoon/4.png differ diff --git a/assets/graphics/particles/raccoon/5.png b/assets/graphics/particles/raccoon/5.png new file mode 100644 index 0000000..13797ad Binary files /dev/null and b/assets/graphics/particles/raccoon/5.png differ diff --git a/assets/graphics/particles/slash/0.png b/assets/graphics/particles/slash/0.png new file mode 100644 index 0000000..75b73d5 Binary files /dev/null and b/assets/graphics/particles/slash/0.png differ diff --git a/assets/graphics/particles/slash/1.png b/assets/graphics/particles/slash/1.png new file mode 100644 index 0000000..011e4a9 Binary files /dev/null and b/assets/graphics/particles/slash/1.png differ diff --git a/assets/graphics/particles/slash/2.png b/assets/graphics/particles/slash/2.png new file mode 100644 index 0000000..922e970 Binary files /dev/null and b/assets/graphics/particles/slash/2.png differ diff --git a/assets/graphics/particles/slash/3.png b/assets/graphics/particles/slash/3.png new file mode 100644 index 0000000..58821d9 Binary files /dev/null and b/assets/graphics/particles/slash/3.png differ diff --git a/assets/graphics/particles/smoke/0.png b/assets/graphics/particles/smoke/0.png new file mode 100644 index 0000000..73e9a59 Binary files /dev/null and b/assets/graphics/particles/smoke/0.png differ diff --git a/assets/graphics/particles/smoke/1.png b/assets/graphics/particles/smoke/1.png new file mode 100644 index 0000000..f21e130 Binary files /dev/null and b/assets/graphics/particles/smoke/1.png differ diff --git a/assets/graphics/particles/smoke/2.png b/assets/graphics/particles/smoke/2.png new file mode 100644 index 0000000..8e2ecb9 Binary files /dev/null and b/assets/graphics/particles/smoke/2.png differ diff --git a/assets/graphics/particles/smoke/3.png b/assets/graphics/particles/smoke/3.png new file mode 100644 index 0000000..244b1a1 Binary files /dev/null and b/assets/graphics/particles/smoke/3.png differ diff --git a/assets/graphics/particles/smoke/4.png b/assets/graphics/particles/smoke/4.png new file mode 100644 index 0000000..e60a29b Binary files /dev/null and b/assets/graphics/particles/smoke/4.png differ diff --git a/assets/graphics/particles/smoke/5.png b/assets/graphics/particles/smoke/5.png new file mode 100644 index 0000000..6475ce3 Binary files /dev/null and b/assets/graphics/particles/smoke/5.png differ diff --git a/assets/graphics/particles/smoke2/0.png b/assets/graphics/particles/smoke2/0.png new file mode 100644 index 0000000..c3267c0 Binary files /dev/null and b/assets/graphics/particles/smoke2/0.png differ diff --git a/assets/graphics/particles/smoke2/1.png b/assets/graphics/particles/smoke2/1.png new file mode 100644 index 0000000..f392845 Binary files /dev/null and b/assets/graphics/particles/smoke2/1.png differ diff --git a/assets/graphics/particles/smoke2/2.png b/assets/graphics/particles/smoke2/2.png new file mode 100644 index 0000000..d611b6f Binary files /dev/null and b/assets/graphics/particles/smoke2/2.png differ diff --git a/assets/graphics/particles/smoke2/3.png b/assets/graphics/particles/smoke2/3.png new file mode 100644 index 0000000..c817380 Binary files /dev/null and b/assets/graphics/particles/smoke2/3.png differ diff --git a/assets/graphics/particles/smoke2/4.png b/assets/graphics/particles/smoke2/4.png new file mode 100644 index 0000000..abd4af8 Binary files /dev/null and b/assets/graphics/particles/smoke2/4.png differ diff --git a/assets/graphics/particles/smoke2/5.png b/assets/graphics/particles/smoke2/5.png new file mode 100644 index 0000000..c89158a Binary files /dev/null and b/assets/graphics/particles/smoke2/5.png differ diff --git a/assets/graphics/particles/smoke_orange/0.png b/assets/graphics/particles/smoke_orange/0.png new file mode 100644 index 0000000..e4baa13 Binary files /dev/null and b/assets/graphics/particles/smoke_orange/0.png differ diff --git a/assets/graphics/particles/smoke_orange/1.png b/assets/graphics/particles/smoke_orange/1.png new file mode 100644 index 0000000..7cce227 Binary files /dev/null and b/assets/graphics/particles/smoke_orange/1.png differ diff --git a/assets/graphics/particles/smoke_orange/2.png b/assets/graphics/particles/smoke_orange/2.png new file mode 100644 index 0000000..4425e33 Binary files /dev/null and b/assets/graphics/particles/smoke_orange/2.png differ diff --git a/assets/graphics/particles/smoke_orange/3.png b/assets/graphics/particles/smoke_orange/3.png new file mode 100644 index 0000000..a817e8d Binary files /dev/null and b/assets/graphics/particles/smoke_orange/3.png differ diff --git a/assets/graphics/particles/smoke_orange/4.png b/assets/graphics/particles/smoke_orange/4.png new file mode 100644 index 0000000..b6ff7a5 Binary files /dev/null and b/assets/graphics/particles/smoke_orange/4.png differ diff --git a/assets/graphics/particles/smoke_orange/5.png b/assets/graphics/particles/smoke_orange/5.png new file mode 100644 index 0000000..3dfab88 Binary files /dev/null and b/assets/graphics/particles/smoke_orange/5.png differ diff --git a/assets/graphics/particles/sparkle/0.png b/assets/graphics/particles/sparkle/0.png new file mode 100644 index 0000000..2bc0bf2 Binary files /dev/null and b/assets/graphics/particles/sparkle/0.png differ diff --git a/assets/graphics/particles/sparkle/1.png b/assets/graphics/particles/sparkle/1.png new file mode 100644 index 0000000..5b3a810 Binary files /dev/null and b/assets/graphics/particles/sparkle/1.png differ diff --git a/assets/graphics/particles/sparkle/2.png b/assets/graphics/particles/sparkle/2.png new file mode 100644 index 0000000..d13930a Binary files /dev/null and b/assets/graphics/particles/sparkle/2.png differ diff --git a/assets/graphics/particles/sparkle/3.png b/assets/graphics/particles/sparkle/3.png new file mode 100644 index 0000000..8384774 Binary files /dev/null and b/assets/graphics/particles/sparkle/3.png differ diff --git a/assets/graphics/particles/sparkle/4.png b/assets/graphics/particles/sparkle/4.png new file mode 100644 index 0000000..b07148f Binary files /dev/null and b/assets/graphics/particles/sparkle/4.png differ diff --git a/assets/graphics/particles/thunder/0.png b/assets/graphics/particles/thunder/0.png new file mode 100644 index 0000000..781f52b Binary files /dev/null and b/assets/graphics/particles/thunder/0.png differ diff --git a/assets/graphics/particles/thunder/1.png b/assets/graphics/particles/thunder/1.png new file mode 100644 index 0000000..ac1fa39 Binary files /dev/null and b/assets/graphics/particles/thunder/1.png differ diff --git a/assets/graphics/particles/thunder/2.png b/assets/graphics/particles/thunder/2.png new file mode 100644 index 0000000..c4bb34b Binary files /dev/null and b/assets/graphics/particles/thunder/2.png differ diff --git a/assets/graphics/particles/thunder/3.png b/assets/graphics/particles/thunder/3.png new file mode 100644 index 0000000..91c92a3 Binary files /dev/null and b/assets/graphics/particles/thunder/3.png differ diff --git a/assets/graphics/particles/thunder/4.png b/assets/graphics/particles/thunder/4.png new file mode 100644 index 0000000..0d51893 Binary files /dev/null and b/assets/graphics/particles/thunder/4.png differ diff --git a/assets/graphics/particles/thunder/5.png b/assets/graphics/particles/thunder/5.png new file mode 100644 index 0000000..55d2698 Binary files /dev/null and b/assets/graphics/particles/thunder/5.png differ diff --git a/assets/graphics/particles/thunder/6.png b/assets/graphics/particles/thunder/6.png new file mode 100644 index 0000000..4d79092 Binary files /dev/null and b/assets/graphics/particles/thunder/6.png differ diff --git a/assets/graphics/particles/thunder/7.png b/assets/graphics/particles/thunder/7.png new file mode 100644 index 0000000..0b8b41c Binary files /dev/null and b/assets/graphics/particles/thunder/7.png differ diff --git a/assets/graphics/player/down/down_0.png b/assets/graphics/player/down/down_0.png new file mode 100644 index 0000000..dbbe852 Binary files /dev/null and b/assets/graphics/player/down/down_0.png differ diff --git a/assets/graphics/player/down/down_1.png b/assets/graphics/player/down/down_1.png new file mode 100644 index 0000000..8545561 Binary files /dev/null and b/assets/graphics/player/down/down_1.png differ diff --git a/assets/graphics/player/down/down_2.png b/assets/graphics/player/down/down_2.png new file mode 100644 index 0000000..dbbe852 Binary files /dev/null and b/assets/graphics/player/down/down_2.png differ diff --git a/assets/graphics/player/down/down_3.png b/assets/graphics/player/down/down_3.png new file mode 100644 index 0000000..eb692a2 Binary files /dev/null and b/assets/graphics/player/down/down_3.png differ diff --git a/assets/graphics/player/down_attack/attack_down.png b/assets/graphics/player/down_attack/attack_down.png new file mode 100644 index 0000000..0ecc144 Binary files /dev/null and b/assets/graphics/player/down_attack/attack_down.png differ diff --git a/assets/graphics/player/down_idle/idle_down.png b/assets/graphics/player/down_idle/idle_down.png new file mode 100644 index 0000000..dbbe852 Binary files /dev/null and b/assets/graphics/player/down_idle/idle_down.png differ diff --git a/assets/graphics/player/left/left_0.png b/assets/graphics/player/left/left_0.png new file mode 100644 index 0000000..dafb10b Binary files /dev/null and b/assets/graphics/player/left/left_0.png differ diff --git a/assets/graphics/player/left/left_1.png b/assets/graphics/player/left/left_1.png new file mode 100644 index 0000000..b84ec9c Binary files /dev/null and b/assets/graphics/player/left/left_1.png differ diff --git a/assets/graphics/player/left/left_2.png b/assets/graphics/player/left/left_2.png new file mode 100644 index 0000000..0e22f2e Binary files /dev/null and b/assets/graphics/player/left/left_2.png differ diff --git a/assets/graphics/player/left/left_3.png b/assets/graphics/player/left/left_3.png new file mode 100644 index 0000000..b771463 Binary files /dev/null and b/assets/graphics/player/left/left_3.png differ diff --git a/assets/graphics/player/left_attack/attack_left.png b/assets/graphics/player/left_attack/attack_left.png new file mode 100644 index 0000000..0b6c05a Binary files /dev/null and b/assets/graphics/player/left_attack/attack_left.png differ diff --git a/assets/graphics/player/left_idle/idle_left.png b/assets/graphics/player/left_idle/idle_left.png new file mode 100644 index 0000000..dafb10b Binary files /dev/null and b/assets/graphics/player/left_idle/idle_left.png differ diff --git a/assets/graphics/player/right/right_0.png b/assets/graphics/player/right/right_0.png new file mode 100644 index 0000000..fe82409 Binary files /dev/null and b/assets/graphics/player/right/right_0.png differ diff --git a/assets/graphics/player/right/right_1.png b/assets/graphics/player/right/right_1.png new file mode 100644 index 0000000..983fbc9 Binary files /dev/null and b/assets/graphics/player/right/right_1.png differ diff --git a/assets/graphics/player/right/right_2.png b/assets/graphics/player/right/right_2.png new file mode 100644 index 0000000..8fcb491 Binary files /dev/null and b/assets/graphics/player/right/right_2.png differ diff --git a/assets/graphics/player/right/right_3.png b/assets/graphics/player/right/right_3.png new file mode 100644 index 0000000..0a7a454 Binary files /dev/null and b/assets/graphics/player/right/right_3.png differ diff --git a/assets/graphics/player/right_attack/attack_right.png b/assets/graphics/player/right_attack/attack_right.png new file mode 100644 index 0000000..9fa1657 Binary files /dev/null and b/assets/graphics/player/right_attack/attack_right.png differ diff --git a/assets/graphics/player/right_idle/idle_right.png b/assets/graphics/player/right_idle/idle_right.png new file mode 100644 index 0000000..fe82409 Binary files /dev/null and b/assets/graphics/player/right_idle/idle_right.png differ diff --git a/assets/graphics/player/up/up_0.png b/assets/graphics/player/up/up_0.png new file mode 100644 index 0000000..d0dae1c Binary files /dev/null and b/assets/graphics/player/up/up_0.png differ diff --git a/assets/graphics/player/up/up_1.png b/assets/graphics/player/up/up_1.png new file mode 100644 index 0000000..2b0de88 Binary files /dev/null and b/assets/graphics/player/up/up_1.png differ diff --git a/assets/graphics/player/up/up_2.png b/assets/graphics/player/up/up_2.png new file mode 100644 index 0000000..d0dae1c Binary files /dev/null and b/assets/graphics/player/up/up_2.png differ diff --git a/assets/graphics/player/up/up_3.png b/assets/graphics/player/up/up_3.png new file mode 100644 index 0000000..b6ebf56 Binary files /dev/null and b/assets/graphics/player/up/up_3.png differ diff --git a/assets/graphics/player/up_attack/attack_up.png b/assets/graphics/player/up_attack/attack_up.png new file mode 100644 index 0000000..d165d7c Binary files /dev/null and b/assets/graphics/player/up_attack/attack_up.png differ diff --git a/assets/graphics/player/up_idle/idle_up.png b/assets/graphics/player/up_idle/idle_up.png new file mode 100644 index 0000000..d0dae1c Binary files /dev/null and b/assets/graphics/player/up_idle/idle_up.png differ diff --git a/assets/graphics/test/player.png b/assets/graphics/test/player.png new file mode 100644 index 0000000..dbbe852 Binary files /dev/null and b/assets/graphics/test/player.png differ diff --git a/assets/graphics/test/rock.png b/assets/graphics/test/rock.png new file mode 100644 index 0000000..30a74e5 Binary files /dev/null and b/assets/graphics/test/rock.png differ diff --git a/assets/graphics/tilemap/Floor.png b/assets/graphics/tilemap/Floor.png new file mode 100644 index 0000000..2971cdd Binary files /dev/null and b/assets/graphics/tilemap/Floor.png differ diff --git a/assets/graphics/tilemap/details.png b/assets/graphics/tilemap/details.png new file mode 100644 index 0000000..8e43aaa Binary files /dev/null and b/assets/graphics/tilemap/details.png differ diff --git a/assets/graphics/tilemap/ground.png b/assets/graphics/tilemap/ground.png new file mode 100644 index 0000000..548b57f Binary files /dev/null and b/assets/graphics/tilemap/ground.png differ diff --git a/assets/graphics/weapons/axe/down.png b/assets/graphics/weapons/axe/down.png new file mode 100644 index 0000000..66761cd Binary files /dev/null and b/assets/graphics/weapons/axe/down.png differ diff --git a/assets/graphics/weapons/axe/full.png b/assets/graphics/weapons/axe/full.png new file mode 100644 index 0000000..99f0318 Binary files /dev/null and b/assets/graphics/weapons/axe/full.png differ diff --git a/assets/graphics/weapons/axe/left.png b/assets/graphics/weapons/axe/left.png new file mode 100644 index 0000000..fbd9b02 Binary files /dev/null and b/assets/graphics/weapons/axe/left.png differ diff --git a/assets/graphics/weapons/axe/right.png b/assets/graphics/weapons/axe/right.png new file mode 100644 index 0000000..72c1d42 Binary files /dev/null and b/assets/graphics/weapons/axe/right.png differ diff --git a/assets/graphics/weapons/axe/up.png b/assets/graphics/weapons/axe/up.png new file mode 100644 index 0000000..5f49b89 Binary files /dev/null and b/assets/graphics/weapons/axe/up.png differ diff --git a/assets/graphics/weapons/lance/down.png b/assets/graphics/weapons/lance/down.png new file mode 100644 index 0000000..f58aeba Binary files /dev/null and b/assets/graphics/weapons/lance/down.png differ diff --git a/assets/graphics/weapons/lance/full.png b/assets/graphics/weapons/lance/full.png new file mode 100644 index 0000000..76ce170 Binary files /dev/null and b/assets/graphics/weapons/lance/full.png differ diff --git a/assets/graphics/weapons/lance/left.png b/assets/graphics/weapons/lance/left.png new file mode 100644 index 0000000..b961b43 Binary files /dev/null and b/assets/graphics/weapons/lance/left.png differ diff --git a/assets/graphics/weapons/lance/right.png b/assets/graphics/weapons/lance/right.png new file mode 100644 index 0000000..af7fd12 Binary files /dev/null and b/assets/graphics/weapons/lance/right.png differ diff --git a/assets/graphics/weapons/lance/up.png b/assets/graphics/weapons/lance/up.png new file mode 100644 index 0000000..96040e5 Binary files /dev/null and b/assets/graphics/weapons/lance/up.png differ diff --git a/assets/graphics/weapons/rapier/down.png b/assets/graphics/weapons/rapier/down.png new file mode 100644 index 0000000..dd103a5 Binary files /dev/null and b/assets/graphics/weapons/rapier/down.png differ diff --git a/assets/graphics/weapons/rapier/full.png b/assets/graphics/weapons/rapier/full.png new file mode 100644 index 0000000..a5f2835 Binary files /dev/null and b/assets/graphics/weapons/rapier/full.png differ diff --git a/assets/graphics/weapons/rapier/left.png b/assets/graphics/weapons/rapier/left.png new file mode 100644 index 0000000..31f5b8b Binary files /dev/null and b/assets/graphics/weapons/rapier/left.png differ diff --git a/assets/graphics/weapons/rapier/right.png b/assets/graphics/weapons/rapier/right.png new file mode 100644 index 0000000..30910a2 Binary files /dev/null and b/assets/graphics/weapons/rapier/right.png differ diff --git a/assets/graphics/weapons/rapier/up.png b/assets/graphics/weapons/rapier/up.png new file mode 100644 index 0000000..5839792 Binary files /dev/null and b/assets/graphics/weapons/rapier/up.png differ diff --git a/assets/graphics/weapons/sai/down.png b/assets/graphics/weapons/sai/down.png new file mode 100644 index 0000000..bda7e15 Binary files /dev/null and b/assets/graphics/weapons/sai/down.png differ diff --git a/assets/graphics/weapons/sai/full.png b/assets/graphics/weapons/sai/full.png new file mode 100644 index 0000000..6f752d6 Binary files /dev/null and b/assets/graphics/weapons/sai/full.png differ diff --git a/assets/graphics/weapons/sai/left.png b/assets/graphics/weapons/sai/left.png new file mode 100644 index 0000000..c9847e2 Binary files /dev/null and b/assets/graphics/weapons/sai/left.png differ diff --git a/assets/graphics/weapons/sai/right.png b/assets/graphics/weapons/sai/right.png new file mode 100644 index 0000000..0631803 Binary files /dev/null and b/assets/graphics/weapons/sai/right.png differ diff --git a/assets/graphics/weapons/sai/up.png b/assets/graphics/weapons/sai/up.png new file mode 100644 index 0000000..366e70b Binary files /dev/null and b/assets/graphics/weapons/sai/up.png differ diff --git a/assets/graphics/weapons/sword/down.png b/assets/graphics/weapons/sword/down.png new file mode 100644 index 0000000..ebcfa93 Binary files /dev/null and b/assets/graphics/weapons/sword/down.png differ diff --git a/assets/graphics/weapons/sword/full.png b/assets/graphics/weapons/sword/full.png new file mode 100644 index 0000000..3b395d8 Binary files /dev/null and b/assets/graphics/weapons/sword/full.png differ diff --git a/assets/graphics/weapons/sword/left.png b/assets/graphics/weapons/sword/left.png new file mode 100644 index 0000000..34abbfa Binary files /dev/null and b/assets/graphics/weapons/sword/left.png differ diff --git a/assets/graphics/weapons/sword/right.png b/assets/graphics/weapons/sword/right.png new file mode 100644 index 0000000..fd96c2c Binary files /dev/null and b/assets/graphics/weapons/sword/right.png differ diff --git a/assets/graphics/weapons/sword/up.png b/assets/graphics/weapons/sword/up.png new file mode 100644 index 0000000..5cac8d4 Binary files /dev/null and b/assets/graphics/weapons/sword/up.png differ diff --git a/code/AIController2D.gd b/code/AIController2D.gd new file mode 100644 index 0000000..efbd446 --- /dev/null +++ b/code/AIController2D.gd @@ -0,0 +1,53 @@ +extends AIController2D + +# meta-name: AI Controller Logic +# meta-description: Methods that need implementing for AI controllers +# meta-default: true + +#-- Methods that need implementing using the "extend script" option in Godot --# + +@onready var player = $".." +@onready var bamboos = $"../../../Bamboos" +@onready var move: int + +func get_obs() -> Dictionary: + var dict = {"obs":[ + player.position.x, + player.position.y, + player.health, + player.experience, + ]} + for bamboo in bamboos.get_children(): + dict["obs"].append(bamboo.position.x) + dict["obs"].append(bamboo.position.y) + dict["obs"].append(bamboo.health) + dict["obs"].append(bamboo.position.direction_to(player.position).x) + dict["obs"].append(bamboo.position.direction_to(player.position).y) + return dict + +func get_reward() -> float: + return reward + +func get_action_space() -> Dictionary: + return { + "move" : { + "size": 5, + "action_type": "discrete" + } + } + +func set_action(action) -> void: + move = action["move"] +# -----------------------------------------------------------------------------# + +#-- Methods that can be overridden if needed --# + +#func get_obs_space() -> Dictionary: +# May need overriding if the obs space is complex +# var obs = get_obs() +# return { +# "obs": { +# "size": [len(obs["obs"])], +# "space": "box" +# }, +# } diff --git a/code/bamboo.gd b/code/bamboo.gd new file mode 100644 index 0000000..3c44d52 --- /dev/null +++ b/code/bamboo.gd @@ -0,0 +1,98 @@ +extends CharacterBody2D + +const SPEED = 150 +const DAMAGE = 7 +const EXP_AMOUNT = 1 + +@onready var knockback_timer = $KnockbackTimer +@onready var attack_timer = $AttackTimer +@onready var notice = $Notice +@onready var attack = $Attack + +@onready var animation_player = $AnimationPlayer + +@export var health = 100 + +var knockback = Vector2.ZERO +var near_player = false +var is_attacking = false +var is_knocked = false +var is_dead = false +var can_move = true + +signal death + + +func change_hp(dmg): + if not is_dead: + health += dmg + if health <= 0: + health = 0 + for body in attack.get_overlapping_bodies(): + body.change_hp(DAMAGE) + body.add_exp(EXP_AMOUNT) + is_dead = true + death.emit() + +func _on_notice_body_entered(body): + near_player = true + body.ai_controller.reward += 1 + + +func _on_notice_body_exited(body): + near_player = false + +func _on_attack_body_entered(body): + is_attacking = false + body.ai_controller.reward += 1 + +func _on_attack_body_exited(body): + is_attacking = true + +func _physics_process(delta): + if near_player and not is_dead: + if not is_knocked: + for body in notice.get_overlapping_bodies(): + if self.to_local(body.global_position).x > 30: + velocity.x = SPEED + elif self.to_local(body.global_position).x < -30: + velocity.x = -SPEED + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + + if self.to_local(body.global_position).y > 30: + velocity.y = SPEED + elif self.to_local(body.global_position).y < -30: + velocity.y = -SPEED + else: + velocity.y = move_toward(velocity.y, 0, SPEED) + + if not is_attacking: + for enemy in attack.get_overlapping_bodies(): + enemy.change_hp(-DAMAGE) + attack_timer.start() + is_attacking = true + + + else: + if can_move: + self.velocity = knockback + knockback_timer.start() + can_move = false + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + velocity.y = move_toward(velocity.y, 0, SPEED) + + move_and_slide() + + +func _on_attack_timer_timeout(): + is_attacking = false + +func _on_knockback_timer_timeout(): + knockback = Vector2.ZERO + is_knocked = false + can_move = true + +func _on_death(): + animation_player.play("death") diff --git a/code/exp.gd b/code/exp.gd new file mode 100644 index 0000000..2bf741f --- /dev/null +++ b/code/exp.gd @@ -0,0 +1,3 @@ +extends Label + + diff --git a/code/killzone.gd b/code/killzone.gd new file mode 100644 index 0000000..65bb34d --- /dev/null +++ b/code/killzone.gd @@ -0,0 +1,4 @@ +extends Area2D + +func _on_body_entered(body): + body.death.emit() diff --git a/code/main.gd b/code/main.gd new file mode 100644 index 0000000..8d0814e --- /dev/null +++ b/code/main.gd @@ -0,0 +1,62 @@ +extends Node2D + +@onready var main_camera = %Overworld +@onready var timer = %WorldTimer + +@onready var players = $Players +#TODO: Fix camera +@onready var player_camera = $Players/Player/Camera +@onready var bamboos = $Bamboos + +@onready var player_starting_pos = [] +@onready var bamboo_starting_pos = [] + + + +# Called when the node enters the scene tree for the first time. +func _ready(): + main_camera.make_current() + for player in players.get_children(): + player_starting_pos.append(player.position) + for bamboo in bamboos.get_children(): + bamboo_starting_pos.append(bamboo.position) + timer.start() + +func _input(event): + if event.is_action_pressed("reset_camera"): + main_camera.make_current() + player_camera.visible = false + +func _process(delta): + var dead_state = 0 + var i=0 + + for bamboo in bamboos.get_children(): + if bamboo.is_dead: + dead_state += 1 + + if dead_state == bamboos.get_children().size(): + for player in players.get_children(): + player.change_hp(-1000) + +func _on_player_death(): + var i = 0 + for player in players.get_children(): + player.position = player_starting_pos[i] + player.health = 100 + player.ai_controller.done = true + player.ai_controller.reset() + i += 1 + var j = 0 + for bamboo in bamboos.get_children(): + bamboo.position = bamboo_starting_pos[j] + bamboo.health = 40 + bamboo.is_dead = false + bamboo.animation_player.play("RESET") + j += 1 + +func _on_timer_timeout(): + for player in players.get_children(): + player.change_hp(-1000) + timer.start() + diff --git a/code/player.gd b/code/player.gd new file mode 100644 index 0000000..783ae3a --- /dev/null +++ b/code/player.gd @@ -0,0 +1,190 @@ +extends CharacterBody2D + +const SPEED = 300.0 + +var is_attacking = false +var last_action = 0 +var cooldown_start = false + +var zoomed_in = false + +var starting_position = self.position + +signal death + +@onready var ai_controller = $AIController2D + +@onready var animated_sprite = $AnimatedSprite2D + +@onready var overworld = %Overworld + +@onready var camera = $Camera +@onready var exp_label = $Camera/ExpPanel/ExpLabel +@onready var hp_label = $Camera/HPPanel/HPLabel + +@onready var attack_timer = $AttackTimer +@onready var weapon = $Weapon +@onready var weapon_player = $Weapon/AnimationPlayer + + +@export var health = 100 +@export var experience = 0 + + +func _ready(): + exp_label.text = "Experience\n"+str(experience) + hp_label.text = "Health\n"+str(health) + +func add_exp(exp_amount): + experience += exp_amount + ai_controller.reward = experience + exp_label.text = "Experience\n"+str(experience) + + +func change_hp(dmg): + health += dmg + #ai_controller.reward += dmg/10 + if health <= 0: + health = 0 + add_exp(-1) + death.emit() + hp_label.text = "Health\n"+str(health) + +func move_left(): + last_action = 1 + velocity.x = -SPEED +func move_right(): + last_action = 3 + velocity.x = SPEED +func move_up(): + last_action = 2 + velocity.y = -SPEED +func move_down(): + last_action = 0 + velocity.y = SPEED + +func _physics_process(_delta): + velocity.x = move_toward(velocity.x, 0, SPEED) + velocity.y = move_toward(velocity.y, 0, SPEED) + + # Get the input direction and handle the movement/deceleration. + if not is_attacking: + # Handle and movement + ## X Axis + if Input.is_action_pressed("move_right") or ai_controller.move == 3: + move_right() + if Input.is_action_pressed("move_left") or ai_controller.move == 1: + move_left() + + ## Y Axis + if Input.is_action_pressed("move_up") or ai_controller.move == 2: + move_up() + if Input.is_action_pressed("move_down") or ai_controller.move == 0: + move_down() + + # Handle animations + if velocity.x > 0: + animated_sprite.play("move_right") + elif velocity.x < 0: + animated_sprite.play("move_left") + elif velocity.y > 0 : + animated_sprite.play("move_down") + elif velocity.y < 0: + animated_sprite.play("move_up") + + # Stop movement or change direction (left/right or up/down) + if Input.is_action_just_released("move_right"): + if Input.is_action_pressed("move_left"): + move_left() + else: + last_action = 3 + velocity.x = move_toward(velocity.x, 0, SPEED) + animated_sprite.play("idle_right") + if Input.is_action_just_released("move_left"): + if Input.is_action_pressed("move_right"): + move_right() + else: + last_action = 1 + velocity.x = move_toward(velocity.x, 0, SPEED) + animated_sprite.play("idle_left") + + if Input.is_action_just_released("move_up"): + if Input.is_action_pressed("move_down"): + move_down() + else: + last_action = 2 + velocity.y = move_toward(velocity.y, 0, SPEED) + animated_sprite.play("idle_up") + if Input.is_action_just_released("move_down"): + if Input.is_action_pressed("move_up"): + move_up() + else: + last_action = 0 + velocity.y = move_toward(velocity.y, 0, SPEED) + animated_sprite.play("idle_down") + + # Handle attacking and magic + if Input.is_action_just_pressed("attack") or ai_controller.move == 4: + + is_attacking = true + if last_action == 1: + weapon.position = Vector2i(-54,14) + weapon.rotation_degrees = 90*last_action + animated_sprite.play("attack_left") + weapon_player.play("attack") + elif last_action == 2: + weapon.position = Vector2i(8,-44) + animated_sprite.play("attack_up") + weapon.rotation_degrees = 90*last_action + weapon_player.play("attack") + elif last_action == 3: + weapon.rotation_degrees = 90*last_action + weapon.position = Vector2i(54,14) + animated_sprite.play("attack_right") + weapon_player.play("attack") + else: + weapon.position = Vector2i(-12,52) + animated_sprite.play("attack_down") + weapon.rotation_degrees = 90*last_action + weapon_player.play("attack") +# + ## TODO: Fix magic + #elif Input.is_action_just_pressed("cast_magic"): + #is_attacking = true + #velocity.x = move_toward(velocity.x, 0, SPEED) + #velocity.y = move_toward(velocity.y, 0, SPEED) + #if last_action == 1: + #animated_sprite.play("attack_right") + #elif last_action == 2: + #animated_sprite.play("attack_left") + #elif last_action == 3: + #animated_sprite.play("attack_up") + #else: + #animated_sprite.play("attack_down") + + move_and_slide() + + else: + attack_cooldown() + +func attack_cooldown(): + if cooldown_start == false: + attack_timer.start() + cooldown_start = true + +# TODO: Find more elegant way to go back +func _on_button_pressed(): + if not zoomed_in: + camera.visible = true + camera.make_current() + zoomed_in = true + else: + camera.visible = false + overworld.make_current() + zoomed_in = false + + +func _on_attack_timer_timeout(): + is_attacking = false + cooldown_start = false + weapon_player.play("RESET") diff --git a/code/weapon.gd b/code/weapon.gd new file mode 100644 index 0000000..7151c3b --- /dev/null +++ b/code/weapon.gd @@ -0,0 +1,12 @@ +extends Area2D + +const DAMAGE = 20 +const KNOCKBACK_STR = 120 + +func _on_body_entered(body): + var direction = self.global_position.direction_to(body.global_position) + var knockback_force = direction * KNOCKBACK_STR + if not body.is_dead: + body.change_hp(-DAMAGE) + body.knockback = knockback_force + body.is_knocked = true diff --git a/default_bus_layout.tres b/default_bus_layout.tres new file mode 100644 index 0000000..23bf494 --- /dev/null +++ b/default_bus_layout.tres @@ -0,0 +1,9 @@ +[gd_resource type="AudioBusLayout" format=3 uid="uid://crne71jxj5jib"] + +[resource] +bus/1/name = &"SFX" +bus/1/solo = false +bus/1/mute = false +bus/1/bypass_fx = false +bus/1/volume_db = -5.32994 +bus/1/send = &"Master" diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..fcfa04a --- /dev/null +++ b/icon.svg @@ -0,0 +1,43 @@ + + + +Created with Fabric.js 5.2.4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/logs/sb3/policy_big_1/events.out.tfevents.1716226582.valanixos.22227.8 b/logs/sb3/policy_big_1/events.out.tfevents.1716226582.valanixos.22227.8 new file mode 100644 index 0000000..d32669a Binary files /dev/null and b/logs/sb3/policy_big_1/events.out.tfevents.1716226582.valanixos.22227.8 differ diff --git a/logs/sb3/policy_big_optim_1/events.out.tfevents.1716291894.valanixos.22227.9 b/logs/sb3/policy_big_optim_1/events.out.tfevents.1716291894.valanixos.22227.9 new file mode 100644 index 0000000..3dfbeac Binary files /dev/null and b/logs/sb3/policy_big_optim_1/events.out.tfevents.1716291894.valanixos.22227.9 differ diff --git a/logs/sb3/policy_mid_1/events.out.tfevents.1716201050.valanixos.22227.4 b/logs/sb3/policy_mid_1/events.out.tfevents.1716201050.valanixos.22227.4 new file mode 100644 index 0000000..afaeb24 Binary files /dev/null and b/logs/sb3/policy_mid_1/events.out.tfevents.1716201050.valanixos.22227.4 differ diff --git a/logs/sb3/policy_mid_optim_1/events.out.tfevents.1716207305.valanixos.22227.5 b/logs/sb3/policy_mid_optim_1/events.out.tfevents.1716207305.valanixos.22227.5 new file mode 100644 index 0000000..c5e528f Binary files /dev/null and b/logs/sb3/policy_mid_optim_1/events.out.tfevents.1716207305.valanixos.22227.5 differ diff --git a/logs/sb3/policy_mid_optim_tanh_1/events.out.tfevents.1716220373.valanixos.22227.7 b/logs/sb3/policy_mid_optim_tanh_1/events.out.tfevents.1716220373.valanixos.22227.7 new file mode 100644 index 0000000..fbb210e Binary files /dev/null and b/logs/sb3/policy_mid_optim_tanh_1/events.out.tfevents.1716220373.valanixos.22227.7 differ diff --git a/logs/sb3/policy_mid_tanh_1/events.out.tfevents.1716213770.valanixos.22227.6 b/logs/sb3/policy_mid_tanh_1/events.out.tfevents.1716213770.valanixos.22227.6 new file mode 100644 index 0000000..993f5d3 Binary files /dev/null and b/logs/sb3/policy_mid_tanh_1/events.out.tfevents.1716213770.valanixos.22227.6 differ diff --git a/logs/sb3/policy_small_1/events.out.tfevents.1716193022.valanixos.22227.0 b/logs/sb3/policy_small_1/events.out.tfevents.1716193022.valanixos.22227.0 new file mode 100644 index 0000000..18c4c86 Binary files /dev/null and b/logs/sb3/policy_small_1/events.out.tfevents.1716193022.valanixos.22227.0 differ diff --git a/logs/sb3/policy_small_optim_1/events.out.tfevents.1716195018.valanixos.22227.1 b/logs/sb3/policy_small_optim_1/events.out.tfevents.1716195018.valanixos.22227.1 new file mode 100644 index 0000000..28a07a4 Binary files /dev/null and b/logs/sb3/policy_small_optim_1/events.out.tfevents.1716195018.valanixos.22227.1 differ diff --git a/logs/sb3/policy_small_optim_tanh_1/events.out.tfevents.1716199031.valanixos.22227.3 b/logs/sb3/policy_small_optim_tanh_1/events.out.tfevents.1716199031.valanixos.22227.3 new file mode 100644 index 0000000..895f529 Binary files /dev/null and b/logs/sb3/policy_small_optim_tanh_1/events.out.tfevents.1716199031.valanixos.22227.3 differ diff --git a/logs/sb3/policy_small_tanh_1/events.out.tfevents.1716197041.valanixos.22227.2 b/logs/sb3/policy_small_tanh_1/events.out.tfevents.1716197041.valanixos.22227.2 new file mode 100644 index 0000000..eb2779e Binary files /dev/null and b/logs/sb3/policy_small_tanh_1/events.out.tfevents.1716197041.valanixos.22227.2 differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..ead1e90 --- /dev/null +++ b/main.py @@ -0,0 +1,6 @@ +from policy import policies +from agent import main +import args + +for policy_name, policy in policies.items(): + main(policy_name=policy_name, policy=policy, parseargs=args.parse_args()) diff --git a/old_logs/basic_sb3/events.out.tfevents.1716039274.valanixos.5296.0 b/old_logs/basic_sb3/events.out.tfevents.1716039274.valanixos.5296.0 new file mode 100644 index 0000000..36f9f80 Binary files /dev/null and b/old_logs/basic_sb3/events.out.tfevents.1716039274.valanixos.5296.0 differ diff --git a/old_logs/experiment_1/events.out.tfevents.1716072142.valanixos.132214.0 b/old_logs/experiment_1/events.out.tfevents.1716072142.valanixos.132214.0 new file mode 100644 index 0000000..f9ffd02 Binary files /dev/null and b/old_logs/experiment_1/events.out.tfevents.1716072142.valanixos.132214.0 differ diff --git a/old_logs/experiment_2/events.out.tfevents.1716141463.valanixos.1153942.0 b/old_logs/experiment_2/events.out.tfevents.1716141463.valanixos.1153942.0 new file mode 100644 index 0000000..339b7cc Binary files /dev/null and b/old_logs/experiment_2/events.out.tfevents.1716141463.valanixos.1153942.0 differ diff --git a/old_logs/sb3_bigger_net/events.out.tfevents.1716047196.valanixos.40801.0 b/old_logs/sb3_bigger_net/events.out.tfevents.1716047196.valanixos.40801.0 new file mode 100644 index 0000000..54e8f5f Binary files /dev/null and b/old_logs/sb3_bigger_net/events.out.tfevents.1716047196.valanixos.40801.0 differ diff --git a/old_logs/sb3_bigger_net_tanh/events.out.tfevents.1716062748.valanixos.97391.0 b/old_logs/sb3_bigger_net_tanh/events.out.tfevents.1716062748.valanixos.97391.0 new file mode 100644 index 0000000..ef34e74 Binary files /dev/null and b/old_logs/sb3_bigger_net_tanh/events.out.tfevents.1716062748.valanixos.97391.0 differ diff --git a/pneuma.sh b/pneuma.sh new file mode 100755 index 0000000..f448f3b --- /dev/null +++ b/pneuma.sh @@ -0,0 +1,4 @@ +#!/bin/sh +echo -ne '\033c\033]0;Pneuma\a' +base_path="$(dirname "$(realpath "$0")")" +"$base_path/pneuma.x86_64" "$@" diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..cd5ded8 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,2207 @@ +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "absl-py" +version = "2.1.0" +description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py." +optional = false +python-versions = ">=3.7" +files = [ + {file = "absl-py-2.1.0.tar.gz", hash = "sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff"}, + {file = "absl_py-2.1.0-py3-none-any.whl", hash = "sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308"}, +] + +[[package]] +name = "certifi" +version = "2024.2.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "cloudpickle" +version = "3.0.0" +description = "Pickler class to extend the standard pickle.Pickler functionality" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cloudpickle-3.0.0-py3-none-any.whl", hash = "sha256:246ee7d0c295602a036e86369c77fecda4ab17b506496730f2f576d9016fd9c7"}, + {file = "cloudpickle-3.0.0.tar.gz", hash = "sha256:996d9a482c6fb4f33c1a35335cf8afd065d2a56e973270364840712d9131a882"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "coloredlogs" +version = "15.0.1" +description = "Colored terminal output for Python's logging module" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934"}, + {file = "coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0"}, +] + +[package.dependencies] +humanfriendly = ">=9.1" + +[package.extras] +cron = ["capturer (>=2.4)"] + +[[package]] +name = "contourpy" +version = "1.2.1" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.9" +files = [ + {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, + {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, + {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, + {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, + {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, + {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, + {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, + {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, + {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, + {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, + {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, + {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, + {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, + {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, + {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, + {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, + {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, + {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, + {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, + {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, + {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, + {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, + {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, +] + +[package.dependencies] +numpy = ">=1.20" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] + +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "dm-tree" +version = "0.1.8" +description = "Tree is a library for working with nested data structures." +optional = false +python-versions = "*" +files = [ + {file = "dm-tree-0.1.8.tar.gz", hash = "sha256:0fcaabbb14e7980377439e7140bd05552739ca5e515ecb3119f234acee4b9430"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:35cc164a79336bfcfafb47e5f297898359123bbd3330c1967f0c4994f9cf9f60"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39070ba268c0491af9fe7a58644d99e8b4f2cde6e5884ba3380bddc84ed43d5f"}, + {file = "dm_tree-0.1.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2869228d9c619074de501a3c10dc7f07c75422f8fab36ecdcb859b6f1b1ec3ef"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d20f2faa3672b52e5013f4077117bfb99c4cfc0b445d3bde1584c34032b57436"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5483dca4d7eb1a0d65fe86d3b6a53ae717face83c1f17e0887b1a4a64ae5c410"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d7c26e431fc93cc7e0cba867eb000db6a05f6f2b25af11ac4e9dada88fc5bca"}, + {file = "dm_tree-0.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d714371bb08839e4e5e29024fc95832d9affe129825ef38836b143028bd144"}, + {file = "dm_tree-0.1.8-cp310-cp310-win_amd64.whl", hash = "sha256:d40fa4106ca6edc66760246a08f500ec0c85ef55c762fb4a363f6ee739ba02ee"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad16ceba90a56ec47cf45b21856d14962ac314787975ef786efb5e6e9ca75ec7"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:803bfc53b4659f447ac694dbd04235f94a73ef7c1fd1e0df7c84ac41e0bc963b"}, + {file = "dm_tree-0.1.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:378cc8ad93c5fe3590f405a309980721f021c790ca1bdf9b15bb1d59daec57f5"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1607ce49aa42f010d1e5e616d92ce899d66835d4d8bea49679582435285515de"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343a4a4ebaa127451ff971254a4be4084eb4bdc0b2513c32b46f6f728fd03f9e"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa42a605d099ee7d41ba2b5fb75e21423951fd26e5d50583a00471238fb3021d"}, + {file = "dm_tree-0.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b7764de0d855338abefc6e3ee9fe40d301668310aa3baea3f778ff051f4393"}, + {file = "dm_tree-0.1.8-cp311-cp311-win_amd64.whl", hash = "sha256:a5d819c38c03f0bb5b3b3703c60e4b170355a0fc6b5819325bf3d4ceb3ae7e80"}, + {file = "dm_tree-0.1.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ea9e59e0451e7d29aece402d9f908f2e2a80922bcde2ebfd5dcb07750fcbfee8"}, + {file = "dm_tree-0.1.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:94d3f0826311f45ee19b75f5b48c99466e4218a0489e81c0f0167bda50cacf22"}, + {file = "dm_tree-0.1.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:435227cf3c5dc63f4de054cf3d00183790bd9ead4c3623138c74dde7f67f521b"}, + {file = "dm_tree-0.1.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09964470f76a5201aff2e8f9b26842976de7889300676f927930f6285e256760"}, + {file = "dm_tree-0.1.8-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75c5d528bb992981c20793b6b453e91560784215dffb8a5440ba999753c14ceb"}, + {file = "dm_tree-0.1.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0a94aba18a35457a1b5cd716fd7b46c5dafdc4cf7869b4bae665b91c4682a8e"}, + {file = "dm_tree-0.1.8-cp312-cp312-win_amd64.whl", hash = "sha256:96a548a406a6fb15fe58f6a30a57ff2f2aafbf25f05afab00c8f5e5977b6c715"}, + {file = "dm_tree-0.1.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8c60a7eadab64c2278861f56bca320b2720f163dca9d7558103c3b77f2416571"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af4b3d372f2477dcd89a6e717e4a575ca35ccc20cc4454a8a4b6f8838a00672d"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de287fabc464b8734be251e46e06aa9aa1001f34198da2b6ce07bd197172b9cb"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:054b461f8176f4bce7a21f7b1870f873a1ced3bdbe1282c816c550bb43c71fa6"}, + {file = "dm_tree-0.1.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f7915660f59c09068e428613c480150180df1060561fd0d1470684ae7007bd1"}, + {file = "dm_tree-0.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:b9f89a454e98806b44fe9d40ec9eee61f848388f7e79ac2371a55679bd5a3ac6"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0e9620ccf06393eb6b613b5e366469304622d4ea96ae6540b28a33840e6c89cf"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b095ba4f8ca1ba19350fd53cf1f8f3eb0bd406aa28af64a6dfc86707b32a810a"}, + {file = "dm_tree-0.1.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b9bd9b9ccb59409d33d51d84b7668010c04c2af7d4a371632874c1ca356cff3d"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d3172394079a86c3a759179c65f64c48d1a42b89495fcf38976d11cc3bb952c"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1612fcaecd79023dbc6a6ae48d51a80beb5c385d6f3f6d71688e57bc8d07de8"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5c8c12e3fda754ef6af94161bacdaeda816d941995fac415d6855c6c386af68"}, + {file = "dm_tree-0.1.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:694c3654cfd2a81552c08ec66bb5c4a3d48fa292b9a181880fb081c36c5b9134"}, + {file = "dm_tree-0.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:bb2d109f42190225112da899b9f3d46d0d5f26aef501c61e43529fe9322530b5"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d16e1f2a073604cfcc09f7131ae8d534674f43c3aef4c25742eae295bc60d04f"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:250b692fb75f45f02e2f58fbef9ab338904ef334b90557565621fa251df267cf"}, + {file = "dm_tree-0.1.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81fce77f22a302d7a5968aebdf4efafef4def7ce96528719a354e6990dcd49c7"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7ac31b9aecccb2c6e1ab29706f6ded3eba0c2c69c770322c9c685929c3d6afb"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fe962015b2fe1282892b28ebe962faed53c7f98d942da9a4625cbf27baef913"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c52cbf4f8b3dbd0beaedf44f69fa85eec5e9dede612e08035e06ada6ec9426"}, + {file = "dm_tree-0.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:181c35521d480d0365f39300542cb6cd7fd2b77351bb43d7acfda15aef63b317"}, + {file = "dm_tree-0.1.8-cp39-cp39-win_amd64.whl", hash = "sha256:8ed3564abed97c806db122c2d3e1a2b64c74a63debe9903aad795167cc301368"}, +] + +[[package]] +name = "farama-notifications" +version = "0.0.4" +description = "Notifications for all Farama Foundation maintained libraries." +optional = false +python-versions = "*" +files = [ + {file = "Farama-Notifications-0.0.4.tar.gz", hash = "sha256:13fceff2d14314cf80703c8266462ebf3733c7d165336eee998fc58e545efd18"}, + {file = "Farama_Notifications-0.0.4-py3-none-any.whl", hash = "sha256:14de931035a41961f7c056361dc7f980762a143d05791ef5794a751a2caf05ae"}, +] + +[[package]] +name = "filelock" +version = "3.14.0" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "filelock-3.14.0-py3-none-any.whl", hash = "sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f"}, + {file = "filelock-3.14.0.tar.gz", hash = "sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] + +[[package]] +name = "flatbuffers" +version = "24.3.25" +description = "The FlatBuffers serialization format for Python" +optional = false +python-versions = "*" +files = [ + {file = "flatbuffers-24.3.25-py2.py3-none-any.whl", hash = "sha256:8dbdec58f935f3765e4f7f3cf635ac3a77f83568138d6a2311f524ec96364812"}, + {file = "flatbuffers-24.3.25.tar.gz", hash = "sha256:de2ec5b203f21441716617f38443e0a8ebf3d25bf0d9c0bb0ce68fa00ad546a4"}, +] + +[[package]] +name = "fonttools" +version = "4.51.0" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.51.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:84d7751f4468dd8cdd03ddada18b8b0857a5beec80bce9f435742abc9a851a74"}, + {file = "fonttools-4.51.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8b4850fa2ef2cfbc1d1f689bc159ef0f45d8d83298c1425838095bf53ef46308"}, + {file = "fonttools-4.51.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5b48a1121117047d82695d276c2af2ee3a24ffe0f502ed581acc2673ecf1037"}, + {file = "fonttools-4.51.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:180194c7fe60c989bb627d7ed5011f2bef1c4d36ecf3ec64daec8302f1ae0716"}, + {file = "fonttools-4.51.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:96a48e137c36be55e68845fc4284533bda2980f8d6f835e26bca79d7e2006438"}, + {file = "fonttools-4.51.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:806e7912c32a657fa39d2d6eb1d3012d35f841387c8fc6cf349ed70b7c340039"}, + {file = "fonttools-4.51.0-cp310-cp310-win32.whl", hash = "sha256:32b17504696f605e9e960647c5f64b35704782a502cc26a37b800b4d69ff3c77"}, + {file = "fonttools-4.51.0-cp310-cp310-win_amd64.whl", hash = "sha256:c7e91abdfae1b5c9e3a543f48ce96013f9a08c6c9668f1e6be0beabf0a569c1b"}, + {file = "fonttools-4.51.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a8feca65bab31479d795b0d16c9a9852902e3a3c0630678efb0b2b7941ea9c74"}, + {file = "fonttools-4.51.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ac27f436e8af7779f0bb4d5425aa3535270494d3bc5459ed27de3f03151e4c2"}, + {file = "fonttools-4.51.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e19bd9e9964a09cd2433a4b100ca7f34e34731e0758e13ba9a1ed6e5468cc0f"}, + {file = "fonttools-4.51.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2b92381f37b39ba2fc98c3a45a9d6383bfc9916a87d66ccb6553f7bdd129097"}, + {file = "fonttools-4.51.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5f6bc991d1610f5c3bbe997b0233cbc234b8e82fa99fc0b2932dc1ca5e5afec0"}, + {file = "fonttools-4.51.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9696fe9f3f0c32e9a321d5268208a7cc9205a52f99b89479d1b035ed54c923f1"}, + {file = "fonttools-4.51.0-cp311-cp311-win32.whl", hash = "sha256:3bee3f3bd9fa1d5ee616ccfd13b27ca605c2b4270e45715bd2883e9504735034"}, + {file = "fonttools-4.51.0-cp311-cp311-win_amd64.whl", hash = "sha256:0f08c901d3866a8905363619e3741c33f0a83a680d92a9f0e575985c2634fcc1"}, + {file = "fonttools-4.51.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4060acc2bfa2d8e98117828a238889f13b6f69d59f4f2d5857eece5277b829ba"}, + {file = "fonttools-4.51.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1250e818b5f8a679ad79660855528120a8f0288f8f30ec88b83db51515411fcc"}, + {file = "fonttools-4.51.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76f1777d8b3386479ffb4a282e74318e730014d86ce60f016908d9801af9ca2a"}, + {file = "fonttools-4.51.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b5ad456813d93b9c4b7ee55302208db2b45324315129d85275c01f5cb7e61a2"}, + {file = "fonttools-4.51.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:68b3fb7775a923be73e739f92f7e8a72725fd333eab24834041365d2278c3671"}, + {file = "fonttools-4.51.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8e2f1a4499e3b5ee82c19b5ee57f0294673125c65b0a1ff3764ea1f9db2f9ef5"}, + {file = "fonttools-4.51.0-cp312-cp312-win32.whl", hash = "sha256:278e50f6b003c6aed19bae2242b364e575bcb16304b53f2b64f6551b9c000e15"}, + {file = "fonttools-4.51.0-cp312-cp312-win_amd64.whl", hash = "sha256:b3c61423f22165541b9403ee39874dcae84cd57a9078b82e1dce8cb06b07fa2e"}, + {file = "fonttools-4.51.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1621ee57da887c17312acc4b0e7ac30d3a4fb0fec6174b2e3754a74c26bbed1e"}, + {file = "fonttools-4.51.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d9298be7a05bb4801f558522adbe2feea1b0b103d5294ebf24a92dd49b78e5"}, + {file = "fonttools-4.51.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee1af4be1c5afe4c96ca23badd368d8dc75f611887fb0c0dac9f71ee5d6f110e"}, + {file = "fonttools-4.51.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c18b49adc721a7d0b8dfe7c3130c89b8704baf599fb396396d07d4aa69b824a1"}, + {file = "fonttools-4.51.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:de7c29bdbdd35811f14493ffd2534b88f0ce1b9065316433b22d63ca1cd21f14"}, + {file = "fonttools-4.51.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cadf4e12a608ef1d13e039864f484c8a968840afa0258b0b843a0556497ea9ed"}, + {file = "fonttools-4.51.0-cp38-cp38-win32.whl", hash = "sha256:aefa011207ed36cd280babfaa8510b8176f1a77261833e895a9d96e57e44802f"}, + {file = "fonttools-4.51.0-cp38-cp38-win_amd64.whl", hash = "sha256:865a58b6e60b0938874af0968cd0553bcd88e0b2cb6e588727117bd099eef836"}, + {file = "fonttools-4.51.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:60a3409c9112aec02d5fb546f557bca6efa773dcb32ac147c6baf5f742e6258b"}, + {file = "fonttools-4.51.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f7e89853d8bea103c8e3514b9f9dc86b5b4120afb4583b57eb10dfa5afbe0936"}, + {file = "fonttools-4.51.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56fc244f2585d6c00b9bcc59e6593e646cf095a96fe68d62cd4da53dd1287b55"}, + {file = "fonttools-4.51.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d145976194a5242fdd22df18a1b451481a88071feadf251221af110ca8f00ce"}, + {file = "fonttools-4.51.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5b8cab0c137ca229433570151b5c1fc6af212680b58b15abd797dcdd9dd5051"}, + {file = "fonttools-4.51.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:54dcf21a2f2d06ded676e3c3f9f74b2bafded3a8ff12f0983160b13e9f2fb4a7"}, + {file = "fonttools-4.51.0-cp39-cp39-win32.whl", hash = "sha256:0118ef998a0699a96c7b28457f15546815015a2710a1b23a7bf6c1be60c01636"}, + {file = "fonttools-4.51.0-cp39-cp39-win_amd64.whl", hash = "sha256:599bdb75e220241cedc6faebfafedd7670335d2e29620d207dd0378a4e9ccc5a"}, + {file = "fonttools-4.51.0-py3-none-any.whl", hash = "sha256:15c94eeef6b095831067f72c825eb0e2d48bb4cea0647c1b05c981ecba2bf39f"}, + {file = "fonttools-4.51.0.tar.gz", hash = "sha256:dc0673361331566d7a663d7ce0f6fdcbfbdc1f59c6e3ed1165ad7202ca183c68"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.1.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + +[[package]] +name = "fsspec" +version = "2024.3.1" +description = "File-system specification" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fsspec-2024.3.1-py3-none-any.whl", hash = "sha256:918d18d41bf73f0e2b261824baeb1b124bcf771767e3a26425cd7dec3332f512"}, + {file = "fsspec-2024.3.1.tar.gz", hash = "sha256:f39780e282d7d117ffb42bb96992f8a90795e4d0fb0f661a70ca39fe9c43ded9"}, +] + +[package.extras] +abfs = ["adlfs"] +adl = ["adlfs"] +arrow = ["pyarrow (>=1)"] +dask = ["dask", "distributed"] +devel = ["pytest", "pytest-cov"] +dropbox = ["dropbox", "dropboxdrivefs", "requests"] +full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] +fuse = ["fusepy"] +gcs = ["gcsfs"] +git = ["pygit2"] +github = ["requests"] +gs = ["gcsfs"] +gui = ["panel"] +hdfs = ["pyarrow (>=1)"] +http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"] +libarchive = ["libarchive-c"] +oci = ["ocifs"] +s3 = ["s3fs"] +sftp = ["paramiko"] +smb = ["smbprotocol"] +ssh = ["paramiko"] +tqdm = ["tqdm"] + +[[package]] +name = "godot_rl" +version = "0.7.0" +description = "A Deep Reinforcement Learning package for the Godot game engine" +optional = false +python-versions = ">=3.7" +files = [ + {file = "main.zip", hash = "sha256:06fb53a2d74205f67c3bd46337727f382ceef7781aff37b50d13e685e0e4e6e9"}, +] + +[package.dependencies] +gymnasium = "*" +huggingface-hub = ">=0.10" +huggingface-sb3 = "*" +numpy = "*" +onnx = "*" +onnxruntime = "*" +stable-baselines3 = ">=2.0.0" +tensorboard = "*" +wget = "*" + +[package.extras] +cleanrl = ["wandb"] +dev = ["black", "flake8", "isort", "pytest (>=6.0)", "pytest-xdist", "pyyaml (>=5.3.1)"] +rllib = ["ray[rllib]"] +sf = ["sample-factory"] +test = ["pytest (>=6.0)", "pytest-xdist"] + +[package.source] +type = "url" +url = "https://github.com/edbeeching/godot_rl_agents/archive/refs/heads/main.zip" + +[[package]] +name = "grpcio" +version = "1.63.0" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.8" +files = [ + {file = "grpcio-1.63.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:2e93aca840c29d4ab5db93f94ed0a0ca899e241f2e8aec6334ab3575dc46125c"}, + {file = "grpcio-1.63.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:91b73d3f1340fefa1e1716c8c1ec9930c676d6b10a3513ab6c26004cb02d8b3f"}, + {file = "grpcio-1.63.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:b3afbd9d6827fa6f475a4f91db55e441113f6d3eb9b7ebb8fb806e5bb6d6bd0d"}, + {file = "grpcio-1.63.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f3f6883ce54a7a5f47db43289a0a4c776487912de1a0e2cc83fdaec9685cc9f"}, + {file = "grpcio-1.63.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf8dae9cc0412cb86c8de5a8f3be395c5119a370f3ce2e69c8b7d46bb9872c8d"}, + {file = "grpcio-1.63.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:08e1559fd3b3b4468486b26b0af64a3904a8dbc78d8d936af9c1cf9636eb3e8b"}, + {file = "grpcio-1.63.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5c039ef01516039fa39da8a8a43a95b64e288f79f42a17e6c2904a02a319b357"}, + {file = "grpcio-1.63.0-cp310-cp310-win32.whl", hash = "sha256:ad2ac8903b2eae071055a927ef74121ed52d69468e91d9bcbd028bd0e554be6d"}, + {file = "grpcio-1.63.0-cp310-cp310-win_amd64.whl", hash = "sha256:b2e44f59316716532a993ca2966636df6fbe7be4ab6f099de6815570ebe4383a"}, + {file = "grpcio-1.63.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:f28f8b2db7b86c77916829d64ab21ff49a9d8289ea1564a2b2a3a8ed9ffcccd3"}, + {file = "grpcio-1.63.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:65bf975639a1f93bee63ca60d2e4951f1b543f498d581869922910a476ead2f5"}, + {file = "grpcio-1.63.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:b5194775fec7dc3dbd6a935102bb156cd2c35efe1685b0a46c67b927c74f0cfb"}, + {file = "grpcio-1.63.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4cbb2100ee46d024c45920d16e888ee5d3cf47c66e316210bc236d5bebc42b3"}, + {file = "grpcio-1.63.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ff737cf29b5b801619f10e59b581869e32f400159e8b12d7a97e7e3bdeee6a2"}, + {file = "grpcio-1.63.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cd1e68776262dd44dedd7381b1a0ad09d9930ffb405f737d64f505eb7f77d6c7"}, + {file = "grpcio-1.63.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:93f45f27f516548e23e4ec3fbab21b060416007dbe768a111fc4611464cc773f"}, + {file = "grpcio-1.63.0-cp311-cp311-win32.whl", hash = "sha256:878b1d88d0137df60e6b09b74cdb73db123f9579232c8456f53e9abc4f62eb3c"}, + {file = "grpcio-1.63.0-cp311-cp311-win_amd64.whl", hash = "sha256:756fed02dacd24e8f488f295a913f250b56b98fb793f41d5b2de6c44fb762434"}, + {file = "grpcio-1.63.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:93a46794cc96c3a674cdfb59ef9ce84d46185fe9421baf2268ccb556f8f81f57"}, + {file = "grpcio-1.63.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a7b19dfc74d0be7032ca1eda0ed545e582ee46cd65c162f9e9fc6b26ef827dc6"}, + {file = "grpcio-1.63.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:8064d986d3a64ba21e498b9a376cbc5d6ab2e8ab0e288d39f266f0fca169b90d"}, + {file = "grpcio-1.63.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:219bb1848cd2c90348c79ed0a6b0ea51866bc7e72fa6e205e459fedab5770172"}, + {file = "grpcio-1.63.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2d60cd1d58817bc5985fae6168d8b5655c4981d448d0f5b6194bbcc038090d2"}, + {file = "grpcio-1.63.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9e350cb096e5c67832e9b6e018cf8a0d2a53b2a958f6251615173165269a91b0"}, + {file = "grpcio-1.63.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:56cdf96ff82e3cc90dbe8bac260352993f23e8e256e063c327b6cf9c88daf7a9"}, + {file = "grpcio-1.63.0-cp312-cp312-win32.whl", hash = "sha256:3a6d1f9ea965e750db7b4ee6f9fdef5fdf135abe8a249e75d84b0a3e0c668a1b"}, + {file = "grpcio-1.63.0-cp312-cp312-win_amd64.whl", hash = "sha256:d2497769895bb03efe3187fb1888fc20e98a5f18b3d14b606167dacda5789434"}, + {file = "grpcio-1.63.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:fdf348ae69c6ff484402cfdb14e18c1b0054ac2420079d575c53a60b9b2853ae"}, + {file = "grpcio-1.63.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a3abfe0b0f6798dedd2e9e92e881d9acd0fdb62ae27dcbbfa7654a57e24060c0"}, + {file = "grpcio-1.63.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:6ef0ad92873672a2a3767cb827b64741c363ebaa27e7f21659e4e31f4d750280"}, + {file = "grpcio-1.63.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b416252ac5588d9dfb8a30a191451adbf534e9ce5f56bb02cd193f12d8845b7f"}, + {file = "grpcio-1.63.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3b77eaefc74d7eb861d3ffbdf91b50a1bb1639514ebe764c47773b833fa2d91"}, + {file = "grpcio-1.63.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b005292369d9c1f80bf70c1db1c17c6c342da7576f1c689e8eee4fb0c256af85"}, + {file = "grpcio-1.63.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cdcda1156dcc41e042d1e899ba1f5c2e9f3cd7625b3d6ebfa619806a4c1aadda"}, + {file = "grpcio-1.63.0-cp38-cp38-win32.whl", hash = "sha256:01799e8649f9e94ba7db1aeb3452188048b0019dc37696b0f5ce212c87c560c3"}, + {file = "grpcio-1.63.0-cp38-cp38-win_amd64.whl", hash = "sha256:6a1a3642d76f887aa4009d92f71eb37809abceb3b7b5a1eec9c554a246f20e3a"}, + {file = "grpcio-1.63.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:75f701ff645858a2b16bc8c9fc68af215a8bb2d5a9b647448129de6e85d52bce"}, + {file = "grpcio-1.63.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cacdef0348a08e475a721967f48206a2254a1b26ee7637638d9e081761a5ba86"}, + {file = "grpcio-1.63.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:0697563d1d84d6985e40ec5ec596ff41b52abb3fd91ec240e8cb44a63b895094"}, + {file = "grpcio-1.63.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6426e1fb92d006e47476d42b8f240c1d916a6d4423c5258ccc5b105e43438f61"}, + {file = "grpcio-1.63.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48cee31bc5f5a31fb2f3b573764bd563aaa5472342860edcc7039525b53e46a"}, + {file = "grpcio-1.63.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:50344663068041b34a992c19c600236e7abb42d6ec32567916b87b4c8b8833b3"}, + {file = "grpcio-1.63.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:259e11932230d70ef24a21b9fb5bb947eb4703f57865a404054400ee92f42f5d"}, + {file = "grpcio-1.63.0-cp39-cp39-win32.whl", hash = "sha256:a44624aad77bf8ca198c55af811fd28f2b3eaf0a50ec5b57b06c034416ef2d0a"}, + {file = "grpcio-1.63.0-cp39-cp39-win_amd64.whl", hash = "sha256:166e5c460e5d7d4656ff9e63b13e1f6029b122104c1633d5f37eaea348d7356d"}, + {file = "grpcio-1.63.0.tar.gz", hash = "sha256:f3023e14805c61bc439fb40ca545ac3d5740ce66120a678a3c6c2c55b70343d1"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.63.0)"] + +[[package]] +name = "gymnasium" +version = "0.28.1" +description = "A standard API for reinforcement learning and a diverse set of reference environments (formerly Gym)." +optional = false +python-versions = ">=3.7" +files = [ + {file = "gymnasium-0.28.1-py3-none-any.whl", hash = "sha256:7bc9a5bce1022f997d1dbc152fc91d1ac977bad9cc7794cdc25437010867cabf"}, + {file = "gymnasium-0.28.1.tar.gz", hash = "sha256:4c2c745808792c8f45c6e88ad0a5504774394e0c126f6e3db555e720d3da6f24"}, +] + +[package.dependencies] +cloudpickle = ">=1.2.0" +farama-notifications = ">=0.0.1" +jax-jumpy = ">=1.0.0" +numpy = ">=1.21.0" +typing-extensions = ">=4.3.0" + +[package.extras] +accept-rom-license = ["autorom[accept-rom-license] (>=0.4.2,<0.5.0)"] +all = ["box2d-py (==2.3.5)", "imageio (>=2.14.1)", "jax (==0.3.24)", "jaxlib (==0.3.24)", "lz4 (>=3.1.0)", "matplotlib (>=3.0)", "moviepy (>=1.0.0)", "mujoco (>=2.3.2)", "mujoco-py (>=2.1,<2.2)", "opencv-python (>=3.0)", "pygame (==2.1.3)", "shimmy[atari] (>=0.1.0,<1.0)", "swig (==4.*)", "torch (>=1.0.0)"] +atari = ["shimmy[atari] (>=0.1.0,<1.0)"] +box2d = ["box2d-py (==2.3.5)", "pygame (==2.1.3)", "swig (==4.*)"] +classic-control = ["pygame (==2.1.3)", "pygame (==2.1.3)"] +jax = ["jax (==0.3.24)", "jaxlib (==0.3.24)"] +mujoco = ["imageio (>=2.14.1)", "mujoco (>=2.3.2)"] +mujoco-py = ["mujoco-py (>=2.1,<2.2)", "mujoco-py (>=2.1,<2.2)"] +other = ["lz4 (>=3.1.0)", "matplotlib (>=3.0)", "moviepy (>=1.0.0)", "opencv-python (>=3.0)", "torch (>=1.0.0)"] +testing = ["pytest (==7.1.3)", "scipy (==1.7.3)"] +toy-text = ["pygame (==2.1.3)", "pygame (==2.1.3)"] + +[[package]] +name = "huggingface-hub" +version = "0.23.0" +description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "huggingface_hub-0.23.0-py3-none-any.whl", hash = "sha256:075c30d48ee7db2bba779190dc526d2c11d422aed6f9044c5e2fdc2c432fdb91"}, + {file = "huggingface_hub-0.23.0.tar.gz", hash = "sha256:7126dedd10a4c6fac796ced4d87a8cf004efc722a5125c2c09299017fa366fa9"}, +] + +[package.dependencies] +filelock = "*" +fsspec = ">=2023.5.0" +packaging = ">=20.9" +pyyaml = ">=5.1" +requests = "*" +tqdm = ">=4.42.1" +typing-extensions = ">=3.7.4.3" + +[package.extras] +all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.3.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] +cli = ["InquirerPy (==0.3.4)"] +dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.3.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] +fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"] +hf-transfer = ["hf-transfer (>=0.1.4)"] +inference = ["aiohttp", "minijinja (>=1.0)"] +quality = ["mypy (==1.5.1)", "ruff (>=0.3.0)"] +tensorflow = ["graphviz", "pydot", "tensorflow"] +tensorflow-testing = ["keras (<3.0)", "tensorflow"] +testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "numpy", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] +torch = ["safetensors", "torch"] +typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"] + +[[package]] +name = "huggingface-sb3" +version = "3.0" +description = "Additional code for Stable-baselines3 to load and upload models from the Hub." +optional = false +python-versions = "*" +files = [ + {file = "huggingface_sb3-3.0-py3-none-any.whl", hash = "sha256:f543f1e5d840425044b9f83cd6915da77cc308c1a7dd4585208f17efad1e8321"}, + {file = "huggingface_sb3-3.0.tar.gz", hash = "sha256:abaf901808dc5827976e3029646e463da65536068d910cd8ef4a8e985087d515"}, +] + +[package.dependencies] +cloudpickle = ">=1.6" +huggingface-hub = ">=0.8,<1.0" +numpy = "*" +pyyaml = ">=6.0,<7.0" +wasabi = "*" + +[package.extras] +quality = ["black (>=22.0,<23.0)", "flake8 (>=3.8.3)", "isort (>=5.5.4)"] + +[[package]] +name = "humanfriendly" +version = "10.0" +description = "Human friendly output for text interfaces using Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477"}, + {file = "humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"}, +] + +[package.dependencies] +pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_version >= \"3.8\""} + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "imageio" +version = "2.34.1" +description = "Library for reading and writing a wide range of image, video, scientific, and volumetric data formats." +optional = false +python-versions = ">=3.8" +files = [ + {file = "imageio-2.34.1-py3-none-any.whl", hash = "sha256:408c1d4d62f72c9e8347e7d1ca9bc11d8673328af3913868db3b828e28b40a4c"}, + {file = "imageio-2.34.1.tar.gz", hash = "sha256:f13eb76e4922f936ac4a7fec77ce8a783e63b93543d4ea3e40793a6cabd9ac7d"}, +] + +[package.dependencies] +numpy = "*" +pillow = ">=8.3.2" + +[package.extras] +all-plugins = ["astropy", "av", "imageio-ffmpeg", "pillow-heif", "psutil", "tifffile"] +all-plugins-pypy = ["av", "imageio-ffmpeg", "pillow-heif", "psutil", "tifffile"] +build = ["wheel"] +dev = ["black", "flake8", "fsspec[github]", "pytest", "pytest-cov"] +docs = ["numpydoc", "pydata-sphinx-theme", "sphinx (<6)"] +ffmpeg = ["imageio-ffmpeg", "psutil"] +fits = ["astropy"] +full = ["astropy", "av", "black", "flake8", "fsspec[github]", "gdal", "imageio-ffmpeg", "itk", "numpydoc", "pillow-heif", "psutil", "pydata-sphinx-theme", "pytest", "pytest-cov", "sphinx (<6)", "tifffile", "wheel"] +gdal = ["gdal"] +itk = ["itk"] +linting = ["black", "flake8"] +pillow-heif = ["pillow-heif"] +pyav = ["av"] +test = ["fsspec[github]", "pytest", "pytest-cov"] +tifffile = ["tifffile"] + +[[package]] +name = "intel-openmp" +version = "2021.4.0" +description = "Intel OpenMP* Runtime Library" +optional = false +python-versions = "*" +files = [ + {file = "intel_openmp-2021.4.0-py2.py3-none-macosx_10_15_x86_64.macosx_11_0_x86_64.whl", hash = "sha256:41c01e266a7fdb631a7609191709322da2bbf24b252ba763f125dd651bcc7675"}, + {file = "intel_openmp-2021.4.0-py2.py3-none-manylinux1_i686.whl", hash = "sha256:3b921236a38384e2016f0f3d65af6732cf2c12918087128a9163225451e776f2"}, + {file = "intel_openmp-2021.4.0-py2.py3-none-manylinux1_x86_64.whl", hash = "sha256:e2240ab8d01472fed04f3544a878cda5da16c26232b7ea1b59132dbfb48b186e"}, + {file = "intel_openmp-2021.4.0-py2.py3-none-win32.whl", hash = "sha256:6e863d8fd3d7e8ef389d52cf97a50fe2afe1a19247e8c0d168ce021546f96fc9"}, + {file = "intel_openmp-2021.4.0-py2.py3-none-win_amd64.whl", hash = "sha256:eef4c8bcc8acefd7f5cd3b9384dbf73d59e2c99fc56545712ded913f43c4a94f"}, +] + +[[package]] +name = "jax-jumpy" +version = "1.0.0" +description = "Common backend for Jax or Numpy." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jax-jumpy-1.0.0.tar.gz", hash = "sha256:195fb955cc4c2b7f0b1453e3cb1fb1c414a51a407ffac7a51e69a73cb30d59ad"}, + {file = "jax_jumpy-1.0.0-py3-none-any.whl", hash = "sha256:ab7e01454bba462de3c4d098e3e585c302a8f06bc36d9182ab4e7e4aa7067c5e"}, +] + +[package.dependencies] +numpy = ">=1.18.0" + +[package.extras] +jax = ["jax (>=0.3.24)", "jaxlib (>=0.3.24)"] +testing = ["pytest (==7.1.3)"] + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "kiwisolver" +version = "1.4.5" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.7" +files = [ + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, + {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, +] + +[[package]] +name = "lazy-loader" +version = "0.4" +description = "Makes it easy to load subpackages and functions on demand." +optional = false +python-versions = ">=3.7" +files = [ + {file = "lazy_loader-0.4-py3-none-any.whl", hash = "sha256:342aa8e14d543a154047afb4ba8ef17f5563baad3fc610d7b15b213b0f119efc"}, + {file = "lazy_loader-0.4.tar.gz", hash = "sha256:47c75182589b91a4e1a85a136c074285a5ad4d9f39c63e0d7fb76391c4574cd1"}, +] + +[package.dependencies] +packaging = "*" + +[package.extras] +dev = ["changelist (==0.5)"] +lint = ["pre-commit (==3.7.0)"] +test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"] + +[[package]] +name = "lz4" +version = "4.3.3" +description = "LZ4 Bindings for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "lz4-4.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b891880c187e96339474af2a3b2bfb11a8e4732ff5034be919aa9029484cd201"}, + {file = "lz4-4.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:222a7e35137d7539c9c33bb53fcbb26510c5748779364014235afc62b0ec797f"}, + {file = "lz4-4.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f76176492ff082657ada0d0f10c794b6da5800249ef1692b35cf49b1e93e8ef7"}, + {file = "lz4-4.3.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1d18718f9d78182c6b60f568c9a9cec8a7204d7cb6fad4e511a2ef279e4cb05"}, + {file = "lz4-4.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6cdc60e21ec70266947a48839b437d46025076eb4b12c76bd47f8e5eb8a75dcc"}, + {file = "lz4-4.3.3-cp310-cp310-win32.whl", hash = "sha256:c81703b12475da73a5d66618856d04b1307e43428a7e59d98cfe5a5d608a74c6"}, + {file = "lz4-4.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:43cf03059c0f941b772c8aeb42a0813d68d7081c009542301637e5782f8a33e2"}, + {file = "lz4-4.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:30e8c20b8857adef7be045c65f47ab1e2c4fabba86a9fa9a997d7674a31ea6b6"}, + {file = "lz4-4.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2f7b1839f795315e480fb87d9bc60b186a98e3e5d17203c6e757611ef7dcef61"}, + {file = "lz4-4.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edfd858985c23523f4e5a7526ca6ee65ff930207a7ec8a8f57a01eae506aaee7"}, + {file = "lz4-4.3.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e9c410b11a31dbdc94c05ac3c480cb4b222460faf9231f12538d0074e56c563"}, + {file = "lz4-4.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2507ee9c99dbddd191c86f0e0c8b724c76d26b0602db9ea23232304382e1f21"}, + {file = "lz4-4.3.3-cp311-cp311-win32.whl", hash = "sha256:f180904f33bdd1e92967923a43c22899e303906d19b2cf8bb547db6653ea6e7d"}, + {file = "lz4-4.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:b14d948e6dce389f9a7afc666d60dd1e35fa2138a8ec5306d30cd2e30d36b40c"}, + {file = "lz4-4.3.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e36cd7b9d4d920d3bfc2369840da506fa68258f7bb176b8743189793c055e43d"}, + {file = "lz4-4.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:31ea4be9d0059c00b2572d700bf2c1bc82f241f2c3282034a759c9a4d6ca4dc2"}, + {file = "lz4-4.3.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33c9a6fd20767ccaf70649982f8f3eeb0884035c150c0b818ea660152cf3c809"}, + {file = "lz4-4.3.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca8fccc15e3add173da91be8f34121578dc777711ffd98d399be35487c934bf"}, + {file = "lz4-4.3.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d84b479ddf39fe3ea05387f10b779155fc0990125f4fb35d636114e1c63a2e"}, + {file = "lz4-4.3.3-cp312-cp312-win32.whl", hash = "sha256:337cb94488a1b060ef1685187d6ad4ba8bc61d26d631d7ba909ee984ea736be1"}, + {file = "lz4-4.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:5d35533bf2cee56f38ced91f766cd0038b6abf46f438a80d50c52750088be93f"}, + {file = "lz4-4.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:363ab65bf31338eb364062a15f302fc0fab0a49426051429866d71c793c23394"}, + {file = "lz4-4.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0a136e44a16fc98b1abc404fbabf7f1fada2bdab6a7e970974fb81cf55b636d0"}, + {file = "lz4-4.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abc197e4aca8b63f5ae200af03eb95fb4b5055a8f990079b5bdf042f568469dd"}, + {file = "lz4-4.3.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56f4fe9c6327adb97406f27a66420b22ce02d71a5c365c48d6b656b4aaeb7775"}, + {file = "lz4-4.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0e822cd7644995d9ba248cb4b67859701748a93e2ab7fc9bc18c599a52e4604"}, + {file = "lz4-4.3.3-cp38-cp38-win32.whl", hash = "sha256:24b3206de56b7a537eda3a8123c644a2b7bf111f0af53bc14bed90ce5562d1aa"}, + {file = "lz4-4.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:b47839b53956e2737229d70714f1d75f33e8ac26e52c267f0197b3189ca6de24"}, + {file = "lz4-4.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6756212507405f270b66b3ff7f564618de0606395c0fe10a7ae2ffcbbe0b1fba"}, + {file = "lz4-4.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee9ff50557a942d187ec85462bb0960207e7ec5b19b3b48949263993771c6205"}, + {file = "lz4-4.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b901c7784caac9a1ded4555258207d9e9697e746cc8532129f150ffe1f6ba0d"}, + {file = "lz4-4.3.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d9ec061b9eca86e4dcc003d93334b95d53909afd5a32c6e4f222157b50c071"}, + {file = "lz4-4.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4c7bf687303ca47d69f9f0133274958fd672efaa33fb5bcde467862d6c621f0"}, + {file = "lz4-4.3.3-cp39-cp39-win32.whl", hash = "sha256:054b4631a355606e99a42396f5db4d22046a3397ffc3269a348ec41eaebd69d2"}, + {file = "lz4-4.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:eac9af361e0d98335a02ff12fb56caeb7ea1196cf1a49dbf6f17828a131da807"}, + {file = "lz4-4.3.3.tar.gz", hash = "sha256:01fe674ef2889dbb9899d8a67361e0c4a2c833af5aeb37dd505727cf5d2a131e"}, +] + +[package.extras] +docs = ["sphinx (>=1.6.0)", "sphinx-bootstrap-theme"] +flake8 = ["flake8"] +tests = ["psutil", "pytest (!=3.3.0)", "pytest-cov"] + +[[package]] +name = "markdown" +version = "3.6" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, + {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, +] + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "matplotlib" +version = "3.8.4" +description = "Python plotting package" +optional = false +python-versions = ">=3.9" +files = [ + {file = "matplotlib-3.8.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:abc9d838f93583650c35eca41cfcec65b2e7cb50fd486da6f0c49b5e1ed23014"}, + {file = "matplotlib-3.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f65c9f002d281a6e904976007b2d46a1ee2bcea3a68a8c12dda24709ddc9106"}, + {file = "matplotlib-3.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce1edd9f5383b504dbc26eeea404ed0a00656c526638129028b758fd43fc5f10"}, + {file = "matplotlib-3.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecd79298550cba13a43c340581a3ec9c707bd895a6a061a78fa2524660482fc0"}, + {file = "matplotlib-3.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:90df07db7b599fe7035d2f74ab7e438b656528c68ba6bb59b7dc46af39ee48ef"}, + {file = "matplotlib-3.8.4-cp310-cp310-win_amd64.whl", hash = "sha256:ac24233e8f2939ac4fd2919eed1e9c0871eac8057666070e94cbf0b33dd9c338"}, + {file = "matplotlib-3.8.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:72f9322712e4562e792b2961971891b9fbbb0e525011e09ea0d1f416c4645661"}, + {file = "matplotlib-3.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:232ce322bfd020a434caaffbd9a95333f7c2491e59cfc014041d95e38ab90d1c"}, + {file = "matplotlib-3.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6addbd5b488aedb7f9bc19f91cd87ea476206f45d7116fcfe3d31416702a82fa"}, + {file = "matplotlib-3.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc4ccdc64e3039fc303defd119658148f2349239871db72cd74e2eeaa9b80b71"}, + {file = "matplotlib-3.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b7a2a253d3b36d90c8993b4620183b55665a429da8357a4f621e78cd48b2b30b"}, + {file = "matplotlib-3.8.4-cp311-cp311-win_amd64.whl", hash = "sha256:8080d5081a86e690d7688ffa542532e87f224c38a6ed71f8fbed34dd1d9fedae"}, + {file = "matplotlib-3.8.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6485ac1f2e84676cff22e693eaa4fbed50ef5dc37173ce1f023daef4687df616"}, + {file = "matplotlib-3.8.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c89ee9314ef48c72fe92ce55c4e95f2f39d70208f9f1d9db4e64079420d8d732"}, + {file = "matplotlib-3.8.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50bac6e4d77e4262c4340d7a985c30912054745ec99756ce213bfbc3cb3808eb"}, + {file = "matplotlib-3.8.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f51c4c869d4b60d769f7b4406eec39596648d9d70246428745a681c327a8ad30"}, + {file = "matplotlib-3.8.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b12ba985837e4899b762b81f5b2845bd1a28f4fdd1a126d9ace64e9c4eb2fb25"}, + {file = "matplotlib-3.8.4-cp312-cp312-win_amd64.whl", hash = "sha256:7a6769f58ce51791b4cb8b4d7642489df347697cd3e23d88266aaaee93b41d9a"}, + {file = "matplotlib-3.8.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:843cbde2f0946dadd8c5c11c6d91847abd18ec76859dc319362a0964493f0ba6"}, + {file = "matplotlib-3.8.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c13f041a7178f9780fb61cc3a2b10423d5e125480e4be51beaf62b172413b67"}, + {file = "matplotlib-3.8.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb44f53af0a62dc80bba4443d9b27f2fde6acfdac281d95bc872dc148a6509cc"}, + {file = "matplotlib-3.8.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:606e3b90897554c989b1e38a258c626d46c873523de432b1462f295db13de6f9"}, + {file = "matplotlib-3.8.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9bb0189011785ea794ee827b68777db3ca3f93f3e339ea4d920315a0e5a78d54"}, + {file = "matplotlib-3.8.4-cp39-cp39-win_amd64.whl", hash = "sha256:6209e5c9aaccc056e63b547a8152661324404dd92340a6e479b3a7f24b42a5d0"}, + {file = "matplotlib-3.8.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c7064120a59ce6f64103c9cefba8ffe6fba87f2c61d67c401186423c9a20fd35"}, + {file = "matplotlib-3.8.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0e47eda4eb2614300fc7bb4657fced3e83d6334d03da2173b09e447418d499f"}, + {file = "matplotlib-3.8.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:493e9f6aa5819156b58fce42b296ea31969f2aab71c5b680b4ea7a3cb5c07d94"}, + {file = "matplotlib-3.8.4.tar.gz", hash = "sha256:8aac397d5e9ec158960e31c381c5ffc52ddd52bd9a47717e2a694038167dffea"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.3.1" +numpy = ">=1.21" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "mkl" +version = "2021.4.0" +description = "Intel® oneAPI Math Kernel Library" +optional = false +python-versions = "*" +files = [ + {file = "mkl-2021.4.0-py2.py3-none-macosx_10_15_x86_64.macosx_11_0_x86_64.whl", hash = "sha256:67460f5cd7e30e405b54d70d1ed3ca78118370b65f7327d495e9c8847705e2fb"}, + {file = "mkl-2021.4.0-py2.py3-none-manylinux1_i686.whl", hash = "sha256:636d07d90e68ccc9630c654d47ce9fdeb036bb46e2b193b3a9ac8cfea683cce5"}, + {file = "mkl-2021.4.0-py2.py3-none-manylinux1_x86_64.whl", hash = "sha256:398dbf2b0d12acaf54117a5210e8f191827f373d362d796091d161f610c1ebfb"}, + {file = "mkl-2021.4.0-py2.py3-none-win32.whl", hash = "sha256:439c640b269a5668134e3dcbcea4350459c4a8bc46469669b2d67e07e3d330e8"}, + {file = "mkl-2021.4.0-py2.py3-none-win_amd64.whl", hash = "sha256:ceef3cafce4c009dd25f65d7ad0d833a0fbadc3d8903991ec92351fe5de1e718"}, +] + +[package.dependencies] +intel-openmp = "==2021.*" +tbb = "==2021.*" + +[[package]] +name = "mpmath" +version = "1.3.0" +description = "Python library for arbitrary-precision floating-point arithmetic" +optional = false +python-versions = "*" +files = [ + {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, + {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, +] + +[package.extras] +develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"] +docs = ["sphinx"] +gmpy = ["gmpy2 (>=2.1.0a4)"] +tests = ["pytest (>=4.6)"] + +[[package]] +name = "networkx" +version = "3.3" +description = "Python package for creating and manipulating graphs and networks" +optional = false +python-versions = ">=3.10" +files = [ + {file = "networkx-3.3-py3-none-any.whl", hash = "sha256:28575580c6ebdaf4505b22c6256a2b9de86b316dc63ba9e93abde3d78dfdbcf2"}, + {file = "networkx-3.3.tar.gz", hash = "sha256:0c127d8b2f4865f59ae9cb8aafcd60b5c70f3241ebd66f7defad7c4ab90126c9"}, +] + +[package.extras] +default = ["matplotlib (>=3.6)", "numpy (>=1.23)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.5)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["myst-nb (>=1.0)", "numpydoc (>=1.7)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=2.0)", "pygraphviz (>=1.12)", "sympy (>=1.10)"] +test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "nvidia-cublas-cu12" +version = "12.1.3.1" +description = "CUBLAS native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:ee53ccca76a6fc08fb9701aa95b6ceb242cdaab118c3bb152af4e579af792728"}, + {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-win_amd64.whl", hash = "sha256:2b964d60e8cf11b5e1073d179d85fa340c120e99b3067558f3cf98dd69d02906"}, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.1.105" +description = "CUDA profiling tools runtime libs." +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:e54fde3983165c624cb79254ae9818a456eb6e87a7fd4d56a2352c24ee542d7e"}, + {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:bea8236d13a0ac7190bd2919c3e8e6ce1e402104276e6f9694479e48bb0eb2a4"}, +] + +[[package]] +name = "nvidia-cuda-nvrtc-cu12" +version = "12.1.105" +description = "NVRTC native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:339b385f50c309763ca65456ec75e17bbefcbbf2893f462cb8b90584cd27a1c2"}, + {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:0a98a522d9ff138b96c010a65e145dc1b4850e9ecb75a0172371793752fd46ed"}, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.1.105" +description = "CUDA Runtime native Libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:6e258468ddf5796e25f1dc591a31029fa317d97a0a94ed93468fc86301d61e40"}, + {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:dfb46ef84d73fababab44cf03e3b83f80700d27ca300e537f85f636fac474344"}, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "8.9.2.26" +description = "cuDNN runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cudnn_cu12-8.9.2.26-py3-none-manylinux1_x86_64.whl", hash = "sha256:5ccb288774fdfb07a7e7025ffec286971c06d8d7b4fb162525334616d7629ff9"}, +] + +[package.dependencies] +nvidia-cublas-cu12 = "*" + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.0.2.54" +description = "CUFFT native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl", hash = "sha256:794e3948a1aa71fd817c3775866943936774d1c14e7628c74f6f7417224cdf56"}, + {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-win_amd64.whl", hash = "sha256:d9ac353f78ff89951da4af698f80870b1534ed69993f10a4cf1d96f21357e253"}, +] + +[[package]] +name = "nvidia-curand-cu12" +version = "10.3.2.106" +description = "CURAND native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:9d264c5036dde4e64f1de8c50ae753237c12e0b1348738169cd0f8a536c0e1e0"}, + {file = "nvidia_curand_cu12-10.3.2.106-py3-none-win_amd64.whl", hash = "sha256:75b6b0c574c0037839121317e17fd01f8a69fd2ef8e25853d826fec30bdba74a"}, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.4.5.107" +description = "CUDA solver native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl", hash = "sha256:8a7ec542f0412294b15072fa7dab71d31334014a69f953004ea7a118206fe0dd"}, + {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-win_amd64.whl", hash = "sha256:74e0c3a24c78612192a74fcd90dd117f1cf21dea4822e66d89e8ea80e3cd2da5"}, +] + +[package.dependencies] +nvidia-cublas-cu12 = "*" +nvidia-cusparse-cu12 = "*" +nvidia-nvjitlink-cu12 = "*" + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.1.0.106" +description = "CUSPARSE native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:f3b50f42cf363f86ab21f720998517a659a48131e8d538dc02f8768237bd884c"}, + {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-win_amd64.whl", hash = "sha256:b798237e81b9719373e8fae8d4f091b70a0cf09d9d85c95a557e11df2d8e9a5a"}, +] + +[package.dependencies] +nvidia-nvjitlink-cu12 = "*" + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.20.5" +description = "NVIDIA Collective Communication Library (NCCL) Runtime" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_aarch64.whl", hash = "sha256:1fc150d5c3250b170b29410ba682384b14581db722b2531b0d8d33c595f33d01"}, + {file = "nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_x86_64.whl", hash = "sha256:057f6bf9685f75215d0c53bf3ac4a10b3e6578351de307abad9e18a99182af56"}, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.4.127" +description = "Nvidia JIT LTO Library" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:06b3b9b25bf3f8af351d664978ca26a16d2c5127dbd53c0497e28d1fb9611d57"}, + {file = "nvidia_nvjitlink_cu12-12.4.127-py3-none-win_amd64.whl", hash = "sha256:fd9020c501d27d135f983c6d3e244b197a7ccad769e34df53a42e276b0e25fa1"}, +] + +[[package]] +name = "nvidia-nvtx-cu12" +version = "12.1.105" +description = "NVIDIA Tools Extension" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:dc21cf308ca5691e7c04d962e213f8a4aa9bbfa23d95412f452254c2caeb09e5"}, + {file = "nvidia_nvtx_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:65f4d98982b31b60026e0e6de73fbdfc09d08a96f4656dd3665ca616a11e1e82"}, +] + +[[package]] +name = "onnx" +version = "1.16.0" +description = "Open Neural Network Exchange" +optional = false +python-versions = ">=3.8" +files = [ + {file = "onnx-1.16.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:9eadbdce25b19d6216f426d6d99b8bc877a65ed92cbef9707751c6669190ba4f"}, + {file = "onnx-1.16.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:034ae21a2aaa2e9c14119a840d2926d213c27aad29e5e3edaa30145a745048e1"}, + {file = "onnx-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec22a43d74eb1f2303373e2fbe7fbcaa45fb225f4eb146edfed1356ada7a9aea"}, + {file = "onnx-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298f28a2b5ac09145fa958513d3d1e6b349ccf86a877dbdcccad57713fe360b3"}, + {file = "onnx-1.16.0-cp310-cp310-win32.whl", hash = "sha256:66300197b52beca08bc6262d43c103289c5d45fde43fb51922ed1eb83658cf0c"}, + {file = "onnx-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:ae0029f5e47bf70a1a62e7f88c80bca4ef39b844a89910039184221775df5e43"}, + {file = "onnx-1.16.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:f51179d4af3372b4f3800c558d204b592c61e4b4a18b8f61e0eea7f46211221a"}, + {file = "onnx-1.16.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:5202559070afec5144332db216c20f2fff8323cf7f6512b0ca11b215eacc5bf3"}, + {file = "onnx-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77579e7c15b4df39d29465b216639a5f9b74026bdd9e4b6306cd19a32dcfe67c"}, + {file = "onnx-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e60ca76ac24b65c25860d0f2d2cdd96d6320d062a01dd8ce87c5743603789b8"}, + {file = "onnx-1.16.0-cp311-cp311-win32.whl", hash = "sha256:81b4ee01bc554e8a2b11ac6439882508a5377a1c6b452acd69a1eebb83571117"}, + {file = "onnx-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:7449241e70b847b9c3eb8dae622df8c1b456d11032a9d7e26e0ee8a698d5bf86"}, + {file = "onnx-1.16.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:03a627488b1a9975d95d6a55582af3e14c7f3bb87444725b999935ddd271d352"}, + {file = "onnx-1.16.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:c392faeabd9283ee344ccb4b067d1fea9dfc614fa1f0de7c47589efd79e15e78"}, + {file = "onnx-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0efeb46985de08f0efe758cb54ad3457e821a05c2eaf5ba2ccb8cd1602c08084"}, + {file = "onnx-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddf14a3d32234f23e44abb73a755cb96a423fac7f004e8f046f36b10214151ee"}, + {file = "onnx-1.16.0-cp312-cp312-win32.whl", hash = "sha256:62a2e27ae8ba5fc9b4a2620301446a517b5ffaaf8566611de7a7c2160f5bcf4c"}, + {file = "onnx-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:3e0860fea94efde777e81a6f68f65761ed5e5f3adea2e050d7fbe373a9ae05b3"}, + {file = "onnx-1.16.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:70a90649318f3470985439ea078277c9fb2a2e6e2fd7c8f3f2b279402ad6c7e6"}, + {file = "onnx-1.16.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:71839546b7f93be4fa807995b182ab4b4414c9dbf049fee11eaaced16fcf8df2"}, + {file = "onnx-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7665217c45a61eb44718c8e9349d2ad004efa0cb9fbc4be5c6d5e18b9fe12b52"}, + {file = "onnx-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5752bbbd5717304a7643643dba383a2fb31e8eb0682f4e7b7d141206328a73b"}, + {file = "onnx-1.16.0-cp38-cp38-win32.whl", hash = "sha256:257858cbcb2055284f09fa2ae2b1cfd64f5850367da388d6e7e7b05920a40c90"}, + {file = "onnx-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:209fe84995a28038e29ae8369edd35f33e0ef1ebc3bddbf6584629823469deb1"}, + {file = "onnx-1.16.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:8cf3e518b1b1b960be542e7c62bed4e5219e04c85d540817b7027029537dec92"}, + {file = "onnx-1.16.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:30f02beaf081c7d9fa3a8c566a912fc4408e28fc33b1452d58f890851691d364"}, + {file = "onnx-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fb29a9a692b522deef1f6b8f2145da62c0c43ea1ed5b4c0f66f827fdc28847d"}, + {file = "onnx-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7755cbd5f4e47952e37276ea5978a46fc8346684392315902b5ed4a719d87d06"}, + {file = "onnx-1.16.0-cp39-cp39-win32.whl", hash = "sha256:7532343dc5b8b5e7c3e3efa441a3100552f7600155c4db9120acd7574f64ffbf"}, + {file = "onnx-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:d7886c05aa6d583ec42f6287678923c1e343afc4350e49d5b36a0023772ffa22"}, + {file = "onnx-1.16.0.tar.gz", hash = "sha256:237c6987c6c59d9f44b6136f5819af79574f8d96a760a1fa843bede11f3822f7"}, +] + +[package.dependencies] +numpy = ">=1.20" +protobuf = ">=3.20.2" + +[package.extras] +reference = ["Pillow", "google-re2"] + +[[package]] +name = "onnxruntime" +version = "1.17.3" +description = "ONNX Runtime is a runtime accelerator for Machine Learning models" +optional = false +python-versions = "*" +files = [ + {file = "onnxruntime-1.17.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:d86dde9c0bb435d709e51bd25991c9fe5b9a5b168df45ce119769edc4d198b15"}, + {file = "onnxruntime-1.17.3-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9d87b68bf931ac527b2d3c094ead66bb4381bac4298b65f46c54fe4d1e255865"}, + {file = "onnxruntime-1.17.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:26e950cf0333cf114a155f9142e71da344d2b08dfe202763a403ae81cc02ebd1"}, + {file = "onnxruntime-1.17.3-cp310-cp310-win32.whl", hash = "sha256:0962a4d0f5acebf62e1f0bf69b6e0adf16649115d8de854c1460e79972324d68"}, + {file = "onnxruntime-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:468ccb8a0faa25c681a41787b1594bf4448b0252d3efc8b62fd8b2411754340f"}, + {file = "onnxruntime-1.17.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e8cd90c1c17d13d47b89ab076471e07fb85467c01dcd87a8b8b5cdfbcb40aa51"}, + {file = "onnxruntime-1.17.3-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a058b39801baefe454eeb8acf3ada298c55a06a4896fafc224c02d79e9037f60"}, + {file = "onnxruntime-1.17.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f823d5eb4807007f3da7b27ca972263df6a1836e6f327384eb266274c53d05d"}, + {file = "onnxruntime-1.17.3-cp311-cp311-win32.whl", hash = "sha256:b66b23f9109e78ff2791628627a26f65cd335dcc5fbd67ff60162733a2f7aded"}, + {file = "onnxruntime-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:570760ca53a74cdd751ee49f13de70d1384dcf73d9888b8deac0917023ccda6d"}, + {file = "onnxruntime-1.17.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:77c318178d9c16e9beadd9a4070d8aaa9f57382c3f509b01709f0f010e583b99"}, + {file = "onnxruntime-1.17.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23da8469049b9759082e22c41a444f44a520a9c874b084711b6343672879f50b"}, + {file = "onnxruntime-1.17.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2949730215af3f9289008b2e31e9bbef952012a77035b911c4977edea06f3f9e"}, + {file = "onnxruntime-1.17.3-cp312-cp312-win32.whl", hash = "sha256:6c7555a49008f403fb3b19204671efb94187c5085976ae526cb625f6ede317bc"}, + {file = "onnxruntime-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:58672cf20293a1b8a277a5c6c55383359fcdf6119b2f14df6ce3b140f5001c39"}, + {file = "onnxruntime-1.17.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:4395ba86e3c1e93c794a00619ef1aec597ab78f5a5039f3c6d2e9d0695c0a734"}, + {file = "onnxruntime-1.17.3-cp38-cp38-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdf354c04344ec38564fc22394e1fe08aa6d70d790df00159205a0055c4a4d3f"}, + {file = "onnxruntime-1.17.3-cp38-cp38-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a94b600b7af50e922d44b95a57981e3e35103c6e3693241a03d3ca204740bbda"}, + {file = "onnxruntime-1.17.3-cp38-cp38-win32.whl", hash = "sha256:5a335c76f9c002a8586c7f38bc20fe4b3725ced21f8ead835c3e4e507e42b2ab"}, + {file = "onnxruntime-1.17.3-cp38-cp38-win_amd64.whl", hash = "sha256:8f56a86fbd0ddc8f22696ddeda0677b041381f4168a2ca06f712ef6ec6050d6d"}, + {file = "onnxruntime-1.17.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:e0ae39f5452278cd349520c296e7de3e90d62dc5b0157c6868e2748d7f28b871"}, + {file = "onnxruntime-1.17.3-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ff2dc012bd930578aff5232afd2905bf16620815f36783a941aafabf94b3702"}, + {file = "onnxruntime-1.17.3-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf6c37483782e4785019b56e26224a25e9b9a35b849d0169ce69189867a22bb1"}, + {file = "onnxruntime-1.17.3-cp39-cp39-win32.whl", hash = "sha256:351bf5a1140dcc43bfb8d3d1a230928ee61fcd54b0ea664c8e9a889a8e3aa515"}, + {file = "onnxruntime-1.17.3-cp39-cp39-win_amd64.whl", hash = "sha256:57a3de15778da8d6cc43fbf6cf038e1e746146300b5f0b1fbf01f6f795dc6440"}, +] + +[package.dependencies] +coloredlogs = "*" +flatbuffers = "*" +numpy = ">=1.21.6" +packaging = "*" +protobuf = "*" +sympy = "*" + +[[package]] +name = "packaging" +version = "24.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, +] + +[[package]] +name = "pandas" +version = "2.2.2" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"}, + {file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"}, + {file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"}, + {file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"}, + {file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"}, + {file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"}, + {file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"}, + {file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"}, + {file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"}, + {file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"}, + {file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"}, + {file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"}, + {file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"}, + {file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"}, + {file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"}, + {file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"}, + {file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"}, + {file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] +python-dateutil = ">=2.8.2" +pytz = ">=2020.1" +tzdata = ">=2022.7" + +[package.extras] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] +aws = ["s3fs (>=2022.11.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] +compression = ["zstandard (>=0.19.0)"] +computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] +feather = ["pyarrow (>=10.0.1)"] +fss = ["fsspec (>=2022.11.0)"] +gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] +hdf5 = ["tables (>=3.8.0)"] +html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] +mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=10.0.1)"] +performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] +plot = ["matplotlib (>=3.6.3)"] +postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] +pyarrow = ["pyarrow (>=10.0.1)"] +spss = ["pyreadstat (>=1.2.0)"] +sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.9.2)"] + +[[package]] +name = "pettingzoo" +version = "1.24.3" +description = "Gymnasium for multi-agent reinforcement learning." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pettingzoo-1.24.3-py3-none-any.whl", hash = "sha256:23ed90517d2e8a7098bdaf5e31234b3a7f7b73ca578d70d1ca7b9d0cb0e37982"}, + {file = "pettingzoo-1.24.3.tar.gz", hash = "sha256:91f9094f18e06fb74b98f4099cd22e8ae4396125e51719d50b30c9f1c7ab07e6"}, +] + +[package.dependencies] +gymnasium = ">=0.28.0" +numpy = ">=1.21.0" + +[package.extras] +all = ["box2d-py (==2.3.5)", "chess (==1.9.4)", "multi-agent-ale-py (==0.1.11)", "pillow (>=8.0.1)", "pygame (==2.3.0)", "pymunk (==6.2.0)", "rlcard (==1.0.5)", "scipy (>=1.4.1)", "shimmy[openspiel] (>=1.2.0)"] +atari = ["multi-agent-ale-py (==0.1.11)", "pygame (==2.3.0)"] +butterfly = ["pygame (==2.3.0)", "pymunk (==6.2.0)"] +classic = ["chess (==1.9.4)", "pygame (==2.3.0)", "rlcard (==1.0.5)", "shimmy[openspiel] (>=1.2.0)"] +mpe = ["pygame (==2.3.0)"] +other = ["pillow (>=8.0.1)"] +sisl = ["box2d-py (==2.3.5)", "pygame (==2.3.0)", "pymunk (==6.2.0)", "scipy (>=1.4.1)"] +testing = ["AutoROM", "pre-commit", "pynput", "pytest", "pytest-cov", "pytest-markdown-docs", "pytest-xdist"] + +[[package]] +name = "pillow" +version = "10.3.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, + {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, + {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, + {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, + {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, + {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, + {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, + {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, + {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, + {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, + {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, + {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, + {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, + {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, + {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, + {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, + {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, + {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, + {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, + {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, + {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, + {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, + {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, + {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, + {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, + {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, + {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, + {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, + {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, + {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, + {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, + {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, + {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, + {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, + {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] + +[[package]] +name = "protobuf" +version = "5.26.1" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "protobuf-5.26.1-cp310-abi3-win32.whl", hash = "sha256:3c388ea6ddfe735f8cf69e3f7dc7611e73107b60bdfcf5d0f024c3ccd3794e23"}, + {file = "protobuf-5.26.1-cp310-abi3-win_amd64.whl", hash = "sha256:e6039957449cb918f331d32ffafa8eb9255769c96aa0560d9a5bf0b4e00a2a33"}, + {file = "protobuf-5.26.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:38aa5f535721d5bb99861166c445c4105c4e285c765fbb2ac10f116e32dcd46d"}, + {file = "protobuf-5.26.1-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:fbfe61e7ee8c1860855696e3ac6cfd1b01af5498facc6834fcc345c9684fb2ca"}, + {file = "protobuf-5.26.1-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:f7417703f841167e5a27d48be13389d52ad705ec09eade63dfc3180a959215d7"}, + {file = "protobuf-5.26.1-cp38-cp38-win32.whl", hash = "sha256:d693d2504ca96750d92d9de8a103102dd648fda04540495535f0fec7577ed8fc"}, + {file = "protobuf-5.26.1-cp38-cp38-win_amd64.whl", hash = "sha256:9b557c317ebe6836835ec4ef74ec3e994ad0894ea424314ad3552bc6e8835b4e"}, + {file = "protobuf-5.26.1-cp39-cp39-win32.whl", hash = "sha256:b9ba3ca83c2e31219ffbeb9d76b63aad35a3eb1544170c55336993d7a18ae72c"}, + {file = "protobuf-5.26.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ee014c2c87582e101d6b54260af03b6596728505c79f17c8586e7523aaa8f8c"}, + {file = "protobuf-5.26.1-py3-none-any.whl", hash = "sha256:da612f2720c0183417194eeaa2523215c4fcc1a1949772dc65f05047e08d5932"}, + {file = "protobuf-5.26.1.tar.gz", hash = "sha256:8ca2a1d97c290ec7b16e4e5dff2e5ae150cc1582f55b5ab300d45cb0dfa90e51"}, +] + +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pyparsing" +version = "3.1.2" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pyreadline3" +version = "3.4.1" +description = "A python implementation of GNU readline." +optional = false +python-versions = "*" +files = [ + {file = "pyreadline3-3.4.1-py3-none-any.whl", hash = "sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb"}, + {file = "pyreadline3-3.4.1.tar.gz", hash = "sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae"}, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "rich" +version = "13.7.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, + {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + +[[package]] +name = "scikit-image" +version = "0.23.2" +description = "Image processing in Python" +optional = false +python-versions = ">=3.10" +files = [ + {file = "scikit_image-0.23.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9a8db6c52f8d0e1474ea8320d7b8db442b4d6baa29dd0acbd02f8a49572f18a"}, + {file = "scikit_image-0.23.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:524b51a7440e46ed2ebbde7bc288bf2dde1dee2caafdd9513b2aca38a48223b7"}, + {file = "scikit_image-0.23.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b335c229170d787b3fb8c60d220f72049ccf862d5191a3cfda6ac84b995ac4e"}, + {file = "scikit_image-0.23.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08b10781efbd6b084f3c847ff4049b657241ea866b9e331b14bf791dcb3e6661"}, + {file = "scikit_image-0.23.2-cp310-cp310-win_amd64.whl", hash = "sha256:a207352e9a1956dda1424bbe872c7795345187138118e8be6a421aef3b988c2a"}, + {file = "scikit_image-0.23.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ee83fdb1843ee938eabdfeb9498623282935ea30aa20dffc5d5d16698efb4b2a"}, + {file = "scikit_image-0.23.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:a158f50d3df4867bbd1c698520ede8bc493e430ad83f54ac1f0d8f57b328779b"}, + {file = "scikit_image-0.23.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55de3326be124334b89314e9e04c8971ad98d6681e11a243f71bfb85ef9554b0"}, + {file = "scikit_image-0.23.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fce619a6d84fe40c1208fa579b646e93ce13ef0afc3652a23e9782b2c183291a"}, + {file = "scikit_image-0.23.2-cp311-cp311-win_amd64.whl", hash = "sha256:ee65669aa586e110346f567ed5c92d1bd63799a19e951cb83da3f54b0caf7c52"}, + {file = "scikit_image-0.23.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:15bfb4e8d7bd90a967e6a3c3ab6be678063fc45e950b730684a8db46a02ff892"}, + {file = "scikit_image-0.23.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:5736e66d01b11cd90988ec24ab929c80a03af28f690189c951886891ebf63154"}, + {file = "scikit_image-0.23.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3597ac5d8f51dafbcb7433ef1fdefdefb535f50745b2002ae0a5d651df4f063b"}, + {file = "scikit_image-0.23.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1978be2abe3c3c3189a99a411d48bbb1306f7c2debb3aefbf426e23947f26623"}, + {file = "scikit_image-0.23.2-cp312-cp312-win_amd64.whl", hash = "sha256:ae32bf0cb02b672ed74d28880ca6f88928ae8dd794d67e04fa3ff4836feb9bd6"}, + {file = "scikit_image-0.23.2.tar.gz", hash = "sha256:c9da4b2c3117e3e30364a3d14496ee5c72b09eb1a4ab1292b302416faa360590"}, +] + +[package.dependencies] +imageio = ">=2.33" +lazy-loader = ">=0.4" +networkx = ">=2.8" +numpy = ">=1.23" +packaging = ">=21" +pillow = ">=9.1" +scipy = ">=1.9" +tifffile = ">=2022.8.12" + +[package.extras] +build = ["Cython (>=3.0.4)", "build", "meson-python (>=0.15)", "ninja", "numpy (>=2.0.0rc1)", "packaging (>=21)", "pythran", "setuptools (>=67)", "spin (==0.8)", "wheel"] +data = ["pooch (>=1.6.0)"] +developer = ["ipython", "pre-commit", "tomli"] +docs = ["PyWavelets (>=1.1.1)", "dask[array] (>=2022.9.2)", "ipykernel", "ipywidgets", "kaleido", "matplotlib (>=3.6)", "myst-parser", "numpydoc (>=1.7)", "pandas (>=1.5)", "plotly (>=5.10)", "pooch (>=1.6)", "pydata-sphinx-theme (>=0.15.2)", "pytest-doctestplus", "pytest-runner", "scikit-learn (>=1.1)", "seaborn (>=0.11)", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-gallery (>=0.14)", "sphinx_design (>=0.5)", "tifffile (>=2022.8.12)"] +optional = ["PyWavelets (>=1.1.1)", "SimpleITK", "astropy (>=5.0)", "cloudpickle (>=0.2.1)", "dask[array] (>=2021.1.0)", "matplotlib (>=3.6)", "pooch (>=1.6.0)", "pyamg", "scikit-learn (>=1.1)"] +test = ["asv", "numpydoc (>=1.7)", "pooch (>=1.6.0)", "pytest (>=7.0)", "pytest-cov (>=2.11.0)", "pytest-doctestplus", "pytest-faulthandler", "pytest-localserver"] + +[[package]] +name = "scipy" +version = "1.13.0" +description = "Fundamental algorithms for scientific computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "scipy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba419578ab343a4e0a77c0ef82f088238a93eef141b2b8017e46149776dfad4d"}, + {file = "scipy-1.13.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:22789b56a999265431c417d462e5b7f2b487e831ca7bef5edeb56efe4c93f86e"}, + {file = "scipy-1.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05f1432ba070e90d42d7fd836462c50bf98bd08bed0aa616c359eed8a04e3922"}, + {file = "scipy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8434f6f3fa49f631fae84afee424e2483289dfc30a47755b4b4e6b07b2633a4"}, + {file = "scipy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:dcbb9ea49b0167de4167c40eeee6e167caeef11effb0670b554d10b1e693a8b9"}, + {file = "scipy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:1d2f7bb14c178f8b13ebae93f67e42b0a6b0fc50eba1cd8021c9b6e08e8fb1cd"}, + {file = "scipy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fbcf8abaf5aa2dc8d6400566c1a727aed338b5fe880cde64907596a89d576fa"}, + {file = "scipy-1.13.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5e4a756355522eb60fcd61f8372ac2549073c8788f6114449b37e9e8104f15a5"}, + {file = "scipy-1.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5acd8e1dbd8dbe38d0004b1497019b2dbbc3d70691e65d69615f8a7292865d7"}, + {file = "scipy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ff7dad5d24a8045d836671e082a490848e8639cabb3dbdacb29f943a678683d"}, + {file = "scipy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4dca18c3ffee287ddd3bc8f1dabaf45f5305c5afc9f8ab9cbfab855e70b2df5c"}, + {file = "scipy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:a2f471de4d01200718b2b8927f7d76b5d9bde18047ea0fa8bd15c5ba3f26a1d6"}, + {file = "scipy-1.13.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d0de696f589681c2802f9090fff730c218f7c51ff49bf252b6a97ec4a5d19e8b"}, + {file = "scipy-1.13.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:b2a3ff461ec4756b7e8e42e1c681077349a038f0686132d623fa404c0bee2551"}, + {file = "scipy-1.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf9fe63e7a4bf01d3645b13ff2aa6dea023d38993f42aaac81a18b1bda7a82a"}, + {file = "scipy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e7626dfd91cdea5714f343ce1176b6c4745155d234f1033584154f60ef1ff42"}, + {file = "scipy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:109d391d720fcebf2fbe008621952b08e52907cf4c8c7efc7376822151820820"}, + {file = "scipy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:8930ae3ea371d6b91c203b1032b9600d69c568e537b7988a3073dfe4d4774f21"}, + {file = "scipy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5407708195cb38d70fd2d6bb04b1b9dd5c92297d86e9f9daae1576bd9e06f602"}, + {file = "scipy-1.13.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ac38c4c92951ac0f729c4c48c9e13eb3675d9986cc0c83943784d7390d540c78"}, + {file = "scipy-1.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c74543c4fbeb67af6ce457f6a6a28e5d3739a87f62412e4a16e46f164f0ae5"}, + {file = "scipy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28e286bf9ac422d6beb559bc61312c348ca9b0f0dae0d7c5afde7f722d6ea13d"}, + {file = "scipy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:33fde20efc380bd23a78a4d26d59fc8704e9b5fd9b08841693eb46716ba13d86"}, + {file = "scipy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:45c08bec71d3546d606989ba6e7daa6f0992918171e2a6f7fbedfa7361c2de1e"}, + {file = "scipy-1.13.0.tar.gz", hash = "sha256:58569af537ea29d3f78e5abd18398459f195546bb3be23d16677fb26616cc11e"}, +] + +[package.dependencies] +numpy = ">=1.22.4,<2.3" + +[package.extras] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] +test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "setuptools" +version = "69.5.1" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"}, + {file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "shellingham" +version = "1.5.4" +description = "Tool to Detect Surrounding Shell" +optional = false +python-versions = ">=3.7" +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "stable-baselines3" +version = "2.3.2" +description = "Pytorch version of Stable Baselines, implementations of reinforcement learning algorithms." +optional = false +python-versions = ">=3.8" +files = [ + {file = "stable_baselines3-2.3.2-py3-none-any.whl", hash = "sha256:a1cafff6ec23bd4e8f4f20dd829008dc1af58ec2d5d8fc0cd0929b4b4544c9b2"}, + {file = "stable_baselines3-2.3.2.tar.gz", hash = "sha256:2f8188916e607571c4c24f88a9ff6f84edafb2cf22d5d24f9c199563c12ff168"}, +] + +[package.dependencies] +cloudpickle = "*" +gymnasium = ">=0.28.1,<0.30" +matplotlib = "*" +numpy = ">=1.20" +pandas = "*" +torch = ">=1.13" + +[package.extras] +docs = ["sphinx (>=5,<8)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-rtd-theme (>=1.3.0)", "sphinxcontrib.spelling"] +extra = ["autorom[accept-rom-license] (>=0.6.1,<0.7.0)", "opencv-python", "pillow", "psutil", "pygame", "rich", "shimmy[atari] (>=1.3.0,<1.4.0)", "tensorboard (>=2.9.1)", "tqdm"] +extra-no-roms = ["opencv-python", "pillow", "psutil", "pygame", "rich", "shimmy[atari] (>=1.3.0,<1.4.0)", "tensorboard (>=2.9.1)", "tqdm"] +tests = ["black (>=24.2.0,<25)", "mypy", "pytest", "pytest-cov", "pytest-env", "pytest-xdist", "ruff (>=0.3.1)"] + +[[package]] +name = "sympy" +version = "1.12" +description = "Computer algebra system (CAS) in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"}, + {file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8"}, +] + +[package.dependencies] +mpmath = ">=0.19" + +[[package]] +name = "tbb" +version = "2021.12.0" +description = "Intel® oneAPI Threading Building Blocks (oneTBB)" +optional = false +python-versions = "*" +files = [ + {file = "tbb-2021.12.0-py2.py3-none-manylinux1_i686.whl", hash = "sha256:f2cc9a7f8ababaa506cbff796ce97c3bf91062ba521e15054394f773375d81d8"}, + {file = "tbb-2021.12.0-py2.py3-none-manylinux1_x86_64.whl", hash = "sha256:a925e9a7c77d3a46ae31c34b0bb7f801c4118e857d137b68f68a8e458fcf2bd7"}, + {file = "tbb-2021.12.0-py3-none-win32.whl", hash = "sha256:b1725b30c174048edc8be70bd43bb95473f396ce895d91151a474d0fa9f450a8"}, + {file = "tbb-2021.12.0-py3-none-win_amd64.whl", hash = "sha256:fc2772d850229f2f3df85f1109c4844c495a2db7433d38200959ee9265b34789"}, +] + +[[package]] +name = "tensorboard" +version = "2.16.2" +description = "TensorBoard lets you watch Tensors Flow" +optional = false +python-versions = ">=3.9" +files = [ + {file = "tensorboard-2.16.2-py3-none-any.whl", hash = "sha256:9f2b4e7dad86667615c0e5cd072f1ea8403fc032a299f0072d6f74855775cc45"}, +] + +[package.dependencies] +absl-py = ">=0.4" +grpcio = ">=1.48.2" +markdown = ">=2.6.8" +numpy = ">=1.12.0" +protobuf = ">=3.19.6,<4.24.0 || >4.24.0" +setuptools = ">=41.0.0" +six = ">1.9" +tensorboard-data-server = ">=0.7.0,<0.8.0" +werkzeug = ">=1.0.1" + +[[package]] +name = "tensorboard-data-server" +version = "0.7.2" +description = "Fast data loading for TensorBoard" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tensorboard_data_server-0.7.2-py3-none-any.whl", hash = "sha256:7e0610d205889588983836ec05dc098e80f97b7e7bbff7e994ebb78f578d0ddb"}, + {file = "tensorboard_data_server-0.7.2-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:9fe5d24221b29625dbc7328b0436ca7fc1c23de4acf4d272f1180856e32f9f60"}, + {file = "tensorboard_data_server-0.7.2-py3-none-manylinux_2_31_x86_64.whl", hash = "sha256:ef687163c24185ae9754ed5650eb5bc4d84ff257aabdc33f0cc6f74d8ba54530"}, +] + +[[package]] +name = "tifffile" +version = "2024.5.10" +description = "Read and write TIFF files" +optional = false +python-versions = ">=3.9" +files = [ + {file = "tifffile-2024.5.10-py3-none-any.whl", hash = "sha256:4154f091aa24d4e75bfad9ab2d5424a68c70e67b8220188066dc61946d4551bd"}, + {file = "tifffile-2024.5.10.tar.gz", hash = "sha256:aa1e1b12be952ab20717d6848bd6d4a5ee88d2aa319f1152bff4354ad728ec86"}, +] + +[package.dependencies] +numpy = "*" + +[package.extras] +all = ["defusedxml", "fsspec", "imagecodecs (>=2023.8.12)", "lxml", "matplotlib", "zarr"] + +[[package]] +name = "torch" +version = "2.3.0" +description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "torch-2.3.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:d8ea5a465dbfd8501f33c937d1f693176c9aef9d1c1b0ca1d44ed7b0a18c52ac"}, + {file = "torch-2.3.0-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:09c81c5859a5b819956c6925a405ef1cdda393c9d8a01ce3851453f699d3358c"}, + {file = "torch-2.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:1bf023aa20902586f614f7682fedfa463e773e26c58820b74158a72470259459"}, + {file = "torch-2.3.0-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:758ef938de87a2653bba74b91f703458c15569f1562bf4b6c63c62d9c5a0c1f5"}, + {file = "torch-2.3.0-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:493d54ee2f9df100b5ce1d18c96dbb8d14908721f76351e908c9d2622773a788"}, + {file = "torch-2.3.0-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:bce43af735c3da16cc14c7de2be7ad038e2fbf75654c2e274e575c6c05772ace"}, + {file = "torch-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:729804e97b7cf19ae9ab4181f91f5e612af07956f35c8b2c8e9d9f3596a8e877"}, + {file = "torch-2.3.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:d24e328226d8e2af7cf80fcb1d2f1d108e0de32777fab4aaa2b37b9765d8be73"}, + {file = "torch-2.3.0-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:b0de2bdc0486ea7b14fc47ff805172df44e421a7318b7c4d92ef589a75d27410"}, + {file = "torch-2.3.0-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:a306c87a3eead1ed47457822c01dfbd459fe2920f2d38cbdf90de18f23f72542"}, + {file = "torch-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:f9b98bf1a3c8af2d4c41f0bf1433920900896c446d1ddc128290ff146d1eb4bd"}, + {file = "torch-2.3.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:dca986214267b34065a79000cee54232e62b41dff1ec2cab9abc3fc8b3dee0ad"}, + {file = "torch-2.3.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:20572f426965dd8a04e92a473d7e445fa579e09943cc0354f3e6fef6130ce061"}, + {file = "torch-2.3.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:e65ba85ae292909cde0dde6369826d51165a3fc8823dc1854cd9432d7f79b932"}, + {file = "torch-2.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:5515503a193781fd1b3f5c474e89c9dfa2faaa782b2795cc4a7ab7e67de923f6"}, + {file = "torch-2.3.0-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:6ae9f64b09516baa4ef890af0672dc981c20b1f0d829ce115d4420a247e88fba"}, + {file = "torch-2.3.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cd0dc498b961ab19cb3f8dbf0c6c50e244f2f37dbfa05754ab44ea057c944ef9"}, + {file = "torch-2.3.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:e05f836559251e4096f3786ee99f4a8cbe67bc7fbedba8ad5e799681e47c5e80"}, + {file = "torch-2.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:4fb27b35dbb32303c2927da86e27b54a92209ddfb7234afb1949ea2b3effffea"}, + {file = "torch-2.3.0-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:760f8bedff506ce9e6e103498f9b1e9e15809e008368594c3a66bf74a8a51380"}, +] + +[package.dependencies] +filelock = "*" +fsspec = "*" +jinja2 = "*" +mkl = {version = ">=2021.1.1,<=2021.4.0", markers = "platform_system == \"Windows\""} +networkx = "*" +nvidia-cublas-cu12 = {version = "12.1.3.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-cupti-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-nvrtc-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-runtime-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cudnn-cu12 = {version = "8.9.2.26", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cufft-cu12 = {version = "11.0.2.54", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-curand-cu12 = {version = "10.3.2.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cusolver-cu12 = {version = "11.4.5.107", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cusparse-cu12 = {version = "12.1.0.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-nccl-cu12 = {version = "2.20.5", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-nvtx-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +sympy = "*" +triton = {version = "2.3.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\" and python_version < \"3.12\""} +typing-extensions = ">=4.8.0" + +[package.extras] +opt-einsum = ["opt-einsum (>=3.3)"] +optree = ["optree (>=0.9.1)"] + +[[package]] +name = "tqdm" +version = "4.66.4" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.66.4-py3-none-any.whl", hash = "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644"}, + {file = "tqdm-4.66.4.tar.gz", hash = "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "triton" +version = "2.3.0" +description = "A language and compiler for custom Deep Learning operations" +optional = false +python-versions = "*" +files = [ + {file = "triton-2.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ce4b8ff70c48e47274c66f269cce8861cf1dc347ceeb7a67414ca151b1822d8"}, + {file = "triton-2.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c3d9607f85103afdb279938fc1dd2a66e4f5999a58eb48a346bd42738f986dd"}, + {file = "triton-2.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:218d742e67480d9581bafb73ed598416cc8a56f6316152e5562ee65e33de01c0"}, + {file = "triton-2.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:381ec6b3dac06922d3e4099cfc943ef032893b25415de295e82b1a82b0359d2c"}, + {file = "triton-2.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038e06a09c06a164fef9c48de3af1e13a63dc1ba3c792871e61a8e79720ea440"}, + {file = "triton-2.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d8f636e0341ac348899a47a057c3daea99ea7db31528a225a3ba4ded28ccc65"}, +] + +[package.dependencies] +filelock = "*" + +[package.extras] +build = ["cmake (>=3.20)", "lit"] +tests = ["autopep8", "flake8", "isort", "numpy", "pytest", "scipy (>=1.7.1)", "torch"] +tutorials = ["matplotlib", "pandas", "tabulate", "torch"] + +[[package]] +name = "typer" +version = "0.12.3" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.7" +files = [ + {file = "typer-0.12.3-py3-none-any.whl", hash = "sha256:070d7ca53f785acbccba8e7d28b08dcd88f79f1fbda035ade0aecec71ca5c914"}, + {file = "typer-0.12.3.tar.gz", hash = "sha256:49e73131481d804288ef62598d97a1ceef3058905aa536a1134f90891ba35482"}, +] + +[package.dependencies] +click = ">=8.0.0" +rich = ">=10.11.0" +shellingham = ">=1.3.0" +typing-extensions = ">=3.7.4.3" + +[[package]] +name = "typing-extensions" +version = "4.11.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, + {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, +] + +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "urllib3" +version = "2.2.1" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "wasabi" +version = "1.1.2" +description = "A lightweight console printing and formatting toolkit" +optional = false +python-versions = ">=3.6" +files = [ + {file = "wasabi-1.1.2-py3-none-any.whl", hash = "sha256:0a3f933c4bf0ed3f93071132c1b87549733256d6c8de6473c5f7ed2e171b5cf9"}, + {file = "wasabi-1.1.2.tar.gz", hash = "sha256:1aaef3aceaa32edb9c91330d29d3936c0c39fdb965743549c173cb54b16c30b5"}, +] + +[package.dependencies] +colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\" and python_version >= \"3.7\""} + +[[package]] +name = "werkzeug" +version = "3.0.3" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "werkzeug-3.0.3-py3-none-any.whl", hash = "sha256:fc9645dc43e03e4d630d23143a04a7f947a9a3b5727cd535fdfe155a17cc48c8"}, + {file = "werkzeug-3.0.3.tar.gz", hash = "sha256:097e5bfda9f0aba8da6b8545146def481d06aa7d3266e7448e2cccf67dd8bd18"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + +[[package]] +name = "wget" +version = "3.2" +description = "pure python download utility" +optional = false +python-versions = "*" +files = [ + {file = "wget-3.2.zip", hash = "sha256:35e630eca2aa50ce998b9b1a127bb26b30dfee573702782aa982f875e3f16061"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "2d575ca622be4eb61953716f1811accd9330cdbd4ad0ceee31700058e486e7e6" diff --git a/policy.py b/policy.py new file mode 100644 index 0000000..de39514 --- /dev/null +++ b/policy.py @@ -0,0 +1,131 @@ +import torch as T +import torch.nn as nn + +policy_small=dict( + net_arch=dict( + pi=[256], + vf=[256] + ) +) + +policy_small_optim=dict( + net_arch=dict( + pi=[256], + vf=[256] + ), + optimizer_kwargs=dict( + betas=(0.9, 0.9), + eps=1e-5, + ), +) + +policy_small_tanh=dict( + activation_fn=nn.Tanh, + net_arch=dict( + pi=[256], + vf=[256] + ) +) + +policy_small_optim_tanh=dict( + net_arch=dict( + pi=[256], + vf=[256] + ), + optimizer_class=T.optim.Adam, + optimizer_kwargs=dict( + betas=(0.9, 0.9), + eps=1e-5, + ), +) + +policy_mid=dict( + net_arch=dict( + pi=[512], + vf=[2048, 2048] + ) +) + +policy_mid_tanh=dict( + activation_fn=nn.Tanh, + net_arch=dict( + pi=[512], + vf=[2048, 2048] + ) +) + +policy_mid_optim=dict( + net_arch=dict( + pi=[512], + vf=[2048, 2048] + ), + optimizer_kwargs=dict( + betas=(0.9,0.9), + eps=1e-5 + ) +) + +policy_mid_optim_tanh=dict( + activation_fn=nn.Tanh, + net_arch=dict( + pi=[512], + vf=[2048, 2048] + ), + optimizer_kwargs=dict( + betas=(0.9,0.9), + eps=1e-5 + ) +) + +policy_big=dict( + net_arch=dict( + pi=[1024, 1024], + vf=[4096, 4096, 4096, 4096] + ) +) + +policy_big_tanh=dict( + activation_fn=nn.Tanh, + net_arch=dict( + pi=[1024, 1024], + vf=[4096, 4096, 4096, 4096] + ) +) + +policy_big_optim=dict( + net_arch=dict( + pi=[1024, 1024], + vf=[4096, 4096, 4096, 4096] + ), + optimizer_kwargs=dict( + betas=(0.9, 0.9), + eps=1e-5, + ), +) + +policy_big_optim_tanh = dict( + activation_fn=nn.Tanh, + net_arch=dict( + pi=[1024, 1024], + vf=[4096, 4096, 4096, 4096], + ), + optimizer_kwargs=dict( + betas=(0.9, 0.9), + eps=1e-5, + ), +) + +policies={ + "policy_small": policy_small, + "policy_small_optim": policy_small_optim, + "policy_small_tanh": policy_small_tanh, + "policy_small_optim_tanh": policy_small_optim_tanh, + "policy_mid": policy_mid, + "policy_mid_optim": policy_mid_optim, + "policy_mid_tanh": policy_mid_tanh, + "policy_mid_optim_tanh": policy_mid_optim_tanh, + "policy_big": policy_big, + "policy_big_optim": policy_big_optim, + "policy_big_tanh": policy_big_tanh, + "policy_big_optim_tanh": policy_big_optim_tanh, +} diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..896b36d --- /dev/null +++ b/project.godot @@ -0,0 +1,70 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Pneuma" +run/main_scene="res://scenes/main.tscn" +config/features=PackedStringArray("4.2", "Forward Plus") +config/icon="res://icon.svg" + +[dotnet] + +project/assembly_name="Pneuma" + +[editor_plugins] + +enabled=PackedStringArray("res://addons/Todo_Manager/plugin.cfg", "res://addons/godot_rl_agents/plugin.cfg") + +[input] + +move_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} +move_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} +move_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} +move_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} +attack={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"echo":false,"script":null) +] +} +cast_magic={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"echo":false,"script":null) +] +} +reset_camera={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} + +[rendering] + +textures/canvas_textures/default_texture_filter=0 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..d49e673 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,22 @@ +[tool.poetry] +name = "pneumarl" +version = "0.1.0" +description = "Godot training env for MARL" +authors = ["Vasilis Valatsos "] +readme = "README.md" +package-mode = false + +[tool.poetry.dependencies] +python = "^3.11" +dm-tree = "^0.1.8" +typer = "^0.12.3" +scikit-image = "^0.23.2" +lz4 = "^4.3.3" +godot-rl = {url = "https://github.com/edbeeching/godot_rl_agents/archive/refs/heads/main.zip"} +pettingzoo = "^1.24.3" +tensorboard = "^2.16.2" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/rllib_config.yaml b/rllib_config.yaml new file mode 100644 index 0000000..c105612 --- /dev/null +++ b/rllib_config.yaml @@ -0,0 +1,60 @@ +algorithm: PPO + +# Multi-agent-env setting: +# If true: +# - Any AIController with done = true will receive zeroes as action values until all AIControllers are done, an episode ends at that point. +# - ai_controller.needs_reset will also be set to true every time a new episode begins (but you can ignore it in your env if needed). +# If false: +# - AIControllers auto-reset in Godot and will receive actions after setting done = true. +# - Each AIController has its own episodes that can end/reset at any point. +# Set to false if you have a single policy name for all agents set in AIControllers +env_is_multiagent: false + +checkpoint_frequency: 20 + +# You can set one or more stopping criteria +stop: + #episode_reward_mean: 0 + #training_iteration: 1000 + #timesteps_total: 10000 + time_total_s: 10000000 + +config: + env: godot + env_config: + env_path: '/home/valapeos/Projects/pneumarl/pneuma.x86_64' # Set your env path here (exported executable from Godot) - e.g. env_path: 'env_path.exe' on Windows + action_repeat: null # Doesn't need to be set here, you can set this in sync node in Godot editor as well + show_window: true # Displays game window while training. Might be faster when false in some cases, turning off also reduces GPU usage if you don't need rendering. + speedup: 30 # Speeds up Godot physics + + framework: torch # ONNX models exported with torch are compatible with the current Godot RL Agents Plugin + + lr: 0.0003 + lambda: 0.95 + gamma: 0.99 + + vf_loss_coeff: 0.5 + vf_clip_param: .inf + #clip_param: 0.2 + entropy_coeff: 0.0001 + entropy_coeff_schedule: null + #grad_clip: 0.5 + + normalize_actions: False + clip_actions: True # During onnx inference we simply clip the actions to [-1.0, 1.0] range, set here to match + + rollout_fragment_length: 32 + sgd_minibatch_size: 128 + num_workers: 4 + num_envs_per_worker: 1 # This will be set automatically if not multi-agent. If multi-agent, changing this changes how many envs to launch per worker. + # The value below needs changing per env + # Basic calculation for this value can be rollout_fragment_length * num_workers * num_envs_per_worker (how many AIControllers you have if not multi_agent, otherwise the value you set) + train_batch_size: 2048 + + num_sgd_iter: 4 + batch_mode: truncate_episodes + + num_gpus: 0 + model: + vf_share_layers: False + fcnet_hiddens: [64, 64] diff --git a/run_tests.sh b/run_tests.sh new file mode 100755 index 0000000..e6597f2 --- /dev/null +++ b/run_tests.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +python main.py --env_path="/home/valapeos/Projects/thesis/Godot/pneuma.x86_64" --speedup=200 --n_parallel=4 --exper_dir="logs/sb3_full_1" && + +python main.py --env_path="/home/valapeos/Projects/thesis/Godot/pneuma.x86_64" --speedup=200 --n_parallel=4 --exper_dir="logs/sb3_full_2" && + +python main.py --env_path="/home/valapeos/Projects/thesis/Godot/pneuma.x86_64" --speedup=200 --n_parallel=4 --exper_dir="logs/sb3_full_3" && + +python main.py --env_path="/home/valapeos/Projects/thesis/Godot/pneuma.x86_64" --speedup=200 --n_parallel=4 --exper_dir="logs/sb3_full_4" diff --git a/scenes/attack.tscn b/scenes/attack.tscn new file mode 100644 index 0000000..616dc07 --- /dev/null +++ b/scenes/attack.tscn @@ -0,0 +1,4 @@ +[gd_scene format=3 uid="uid://c1i0nirxfagfh"] + +[node name="Attack" type="Area2D"] +collision_mask = 2 diff --git a/scenes/bamboo.tscn b/scenes/bamboo.tscn new file mode 100644 index 0000000..348bf2c --- /dev/null +++ b/scenes/bamboo.tscn @@ -0,0 +1,249 @@ +[gd_scene load_steps=20 format=3 uid="uid://bsjy4oejfrg81"] + +[ext_resource type="Texture2D" uid="uid://d4d34das0e3j0" path="res://assets/graphics/monsters/bamboo/idle/0.png" id="1_em175"] +[ext_resource type="Texture2D" uid="uid://l0bk7j8xiqur" path="res://assets/graphics/monsters/bamboo/idle/1.png" id="2_i1h6v"] +[ext_resource type="Texture2D" uid="uid://bwe7pi6shcc2x" path="res://assets/graphics/monsters/bamboo/attack/0.png" id="2_tihvn"] +[ext_resource type="Texture2D" uid="uid://damt0mr2bvcjv" path="res://assets/graphics/monsters/bamboo/idle/2.png" id="3_5ekod"] +[ext_resource type="Texture2D" uid="uid://b11yb3x6h5oas" path="res://assets/graphics/monsters/bamboo/idle/3.png" id="4_0fhpn"] +[ext_resource type="Script" path="res://code/bamboo.gd" id="5_ib85v"] +[ext_resource type="Texture2D" uid="uid://q8yev438ec6r" path="res://assets/graphics/monsters/bamboo/move/0.png" id="7_8n247"] +[ext_resource type="Texture2D" uid="uid://dqr075ilm3tu8" path="res://assets/graphics/monsters/bamboo/move/1.png" id="8_c5akp"] +[ext_resource type="Texture2D" uid="uid://hcm2s3v12pkw" path="res://assets/graphics/monsters/bamboo/move/2.png" id="9_t18yx"] +[ext_resource type="Texture2D" uid="uid://dqa5hvprf3kdp" path="res://assets/graphics/monsters/bamboo/move/3.png" id="10_gsrg3"] +[ext_resource type="PackedScene" uid="uid://dxwjan054vgw0" path="res://scenes/notice.tscn" id="11_d502u"] +[ext_resource type="PackedScene" uid="uid://c1i0nirxfagfh" path="res://scenes/attack.tscn" id="12_27c4n"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_iyhjt"] +size = Vector2(24, 50) + +[sub_resource type="CircleShape2D" id="CircleShape2D_wx6w8"] +radius = 300.0 + +[sub_resource type="CircleShape2D" id="CircleShape2D_crbjt"] +radius = 40.0 + +[sub_resource type="SpriteFrames" id="SpriteFrames_2w0pn"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("2_tihvn") +}], +"loop": true, +"name": &"attack", +"speed": 7.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("1_em175") +}, { +"duration": 1.0, +"texture": ExtResource("2_i1h6v") +}, { +"duration": 1.0, +"texture": ExtResource("3_5ekod") +}, { +"duration": 1.0, +"texture": ExtResource("4_0fhpn") +}], +"loop": true, +"name": &"idle", +"speed": 7.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("7_8n247") +}, { +"duration": 1.0, +"texture": ExtResource("8_c5akp") +}, { +"duration": 1.0, +"texture": ExtResource("9_t18yx") +}, { +"duration": 1.0, +"texture": ExtResource("10_gsrg3") +}], +"loop": true, +"name": &"move", +"speed": 7.0 +}] + +[sub_resource type="Animation" id="Animation_lrur3"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("CollisionShape2D:disabled") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".:visible") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Attack:monitoring") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Notice:monitoring") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath(".:collision_mask") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [6] +} + +[sub_resource type="Animation" id="Animation_3xlxe"] +resource_name = "death" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("CollisionShape2D:disabled") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".:visible") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Attack:monitoring") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Notice:monitoring") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath(".:collision_mask") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_ftwl3"] +_data = { +"RESET": SubResource("Animation_lrur3"), +"death": SubResource("Animation_3xlxe") +} + +[node name="Bamboo" type="CharacterBody2D"] +z_index = 5 +y_sort_enabled = true +position = Vector2(0, -33) +collision_layer = 4 +collision_mask = 6 +script = ExtResource("5_ib85v") +health = 40 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(0, 2) +shape = SubResource("RectangleShape2D_iyhjt") + +[node name="Notice" parent="." instance=ExtResource("11_d502u")] +position = Vector2(0, 7) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Notice"] +shape = SubResource("CircleShape2D_wx6w8") + +[node name="Attack" parent="." instance=ExtResource("12_27c4n")] +position = Vector2(0, 5) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Attack"] +shape = SubResource("CircleShape2D_crbjt") + +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] +sprite_frames = SubResource("SpriteFrames_2w0pn") +animation = &"idle" +autoplay = "idle" + +[node name="AttackTimer" type="Timer" parent="."] + +[node name="KnockbackTimer" type="Timer" parent="."] +wait_time = 0.5 +one_shot = true + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_ftwl3") +} + +[connection signal="death" from="." to="." method="_on_death"] +[connection signal="body_entered" from="Notice" to="." method="_on_notice_body_entered"] +[connection signal="body_exited" from="Notice" to="." method="_on_notice_body_exited"] +[connection signal="body_entered" from="Attack" to="." method="_on_attack_body_entered"] +[connection signal="body_exited" from="Attack" to="." method="_on_attack_body_exited"] +[connection signal="timeout" from="AttackTimer" to="." method="_on_attack_timer_timeout"] +[connection signal="timeout" from="KnockbackTimer" to="." method="_on_knockback_timer_timeout"] diff --git a/scenes/camera.tscn b/scenes/camera.tscn new file mode 100644 index 0000000..5526776 --- /dev/null +++ b/scenes/camera.tscn @@ -0,0 +1,51 @@ +[gd_scene load_steps=3 format=3 uid="uid://bj4ap7bw0imhy"] + +[ext_resource type="FontFile" uid="uid://bbe5csaxy5g3c" path="res://assets/graphics/font/joystix.ttf" id="1_kqyoj"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0lqnv"] +bg_color = Color(0, 0, 0, 1) +border_width_left = 4 +border_width_top = 4 +border_width_right = 4 +border_width_bottom = 4 +border_color = Color(1, 1, 1, 1) + +[node name="Camera" type="Camera2D"] + +[node name="ExpPanel" type="PanelContainer" parent="."] +offset_left = 187.0 +offset_top = 227.0 +offset_right = 568.0 +offset_bottom = 316.0 +theme_override_styles/panel = SubResource("StyleBoxFlat_0lqnv") + +[node name="ExpLabel" type="Label" parent="ExpPanel"] +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 8 +theme_override_fonts/font = ExtResource("1_kqyoj") +theme_override_font_sizes/font_size = 32 +text = "EXP POINTS + " +horizontal_alignment = 1 +vertical_alignment = 1 +max_lines_visible = 2 + +[node name="HPPanel" type="PanelContainer" parent="."] +offset_left = -569.0 +offset_top = 223.0 +offset_right = -188.0 +offset_bottom = 318.0 +theme_override_styles/panel = SubResource("StyleBoxFlat_0lqnv") + +[node name="HPLabel" type="Label" parent="HPPanel"] +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 8 +theme_override_fonts/font = ExtResource("1_kqyoj") +theme_override_font_sizes/font_size = 32 +text = "HEALTH +" +horizontal_alignment = 1 +vertical_alignment = 1 +max_lines_visible = 2 diff --git a/scenes/killzone.tscn b/scenes/killzone.tscn new file mode 100644 index 0000000..d88fa05 --- /dev/null +++ b/scenes/killzone.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=2 format=3 uid="uid://cuvs5tobahf0x"] + +[ext_resource type="Script" path="res://code/killzone.gd" id="1_nmw5v"] + +[node name="Killzone" type="Area2D"] +script = ExtResource("1_nmw5v") + +[node name="Timer" type="Timer" parent="."] +wait_time = 0.6 +one_shot = true + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] +[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"] diff --git a/scenes/main.tscn b/scenes/main.tscn new file mode 100644 index 0000000..c7acd44 --- /dev/null +++ b/scenes/main.tscn @@ -0,0 +1,1406 @@ +[gd_scene load_steps=16 format=3 uid="uid://ldrqgub8ip13"] + +[ext_resource type="Script" path="res://code/main.gd" id="1_l8nqt"] +[ext_resource type="PackedScene" uid="uid://c7rps714eqdg5" path="res://scenes/player.tscn" id="1_ykwem"] +[ext_resource type="Texture2D" uid="uid://bd03f5p0dd3em" path="res://assets/graphics/tilemap/Floor.png" id="2_2lxw0"] +[ext_resource type="Texture2D" uid="uid://b5qncrso5bd14" path="res://assets/graphics/tilemap/details.png" id="3_72u1m"] +[ext_resource type="PackedScene" uid="uid://bsjy4oejfrg81" path="res://scenes/bamboo.tscn" id="4_8jerw"] +[ext_resource type="PackedScene" uid="uid://cuvs5tobahf0x" path="res://scenes/killzone.tscn" id="5_3xrri"] +[ext_resource type="Script" path="res://addons/godot_rl_agents/sync.gd" id="7_c27o5"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_auqfk"] +texture = ExtResource("2_2lxw0") +texture_region_size = Vector2i(64, 64) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +1:0/0 = 0 +1:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:0/0/physics_layer_0/angular_velocity = 0.0 +2:0/0 = 0 +2:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:0/0/physics_layer_0/angular_velocity = 0.0 +3:0/0 = 0 +3:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:0/0/physics_layer_0/angular_velocity = 0.0 +4:0/0 = 0 +4:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:0/0/physics_layer_0/angular_velocity = 0.0 +5:0/0 = 0 +5:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:0/0/physics_layer_0/angular_velocity = 0.0 +6:0/0 = 0 +6:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:0/0/physics_layer_0/angular_velocity = 0.0 +7:0/0 = 0 +7:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:0/0/physics_layer_0/angular_velocity = 0.0 +8:0/0 = 0 +8:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:0/0/physics_layer_0/angular_velocity = 0.0 +9:0/0 = 0 +9:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:0/0/physics_layer_0/angular_velocity = 0.0 +11:0/0 = 0 +11:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:0/0/physics_layer_0/angular_velocity = 0.0 +11:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +12:0/0 = 0 +12:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:0/0/physics_layer_0/angular_velocity = 0.0 +12:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +13:0/0 = 0 +13:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:0/0/physics_layer_0/angular_velocity = 0.0 +13:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +14:0/0 = 0 +14:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:0/0/physics_layer_0/angular_velocity = 0.0 +15:0/0 = 0 +15:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:0/0/physics_layer_0/angular_velocity = 0.0 +16:0/0 = 0 +16:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:0/0/physics_layer_0/angular_velocity = 0.0 +17:0/0 = 0 +17:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:0/0/physics_layer_0/angular_velocity = 0.0 +18:0/0 = 0 +18:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:0/0/physics_layer_0/angular_velocity = 0.0 +19:0/0 = 0 +19:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:0/0/physics_layer_0/angular_velocity = 0.0 +20:0/0 = 0 +20:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:0/0/physics_layer_0/angular_velocity = 0.0 +0:1/0 = 0 +0:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:1/0/physics_layer_0/angular_velocity = 0.0 +1:1/0 = 0 +1:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:1/0/physics_layer_0/angular_velocity = 0.0 +2:1/0 = 0 +2:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:1/0/physics_layer_0/angular_velocity = 0.0 +3:1/0 = 0 +3:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:1/0/physics_layer_0/angular_velocity = 0.0 +4:1/0 = 0 +4:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:1/0/physics_layer_0/angular_velocity = 0.0 +5:1/0 = 0 +5:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:1/0/physics_layer_0/angular_velocity = 0.0 +6:1/0 = 0 +6:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:1/0/physics_layer_0/angular_velocity = 0.0 +7:1/0 = 0 +7:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:1/0/physics_layer_0/angular_velocity = 0.0 +8:1/0 = 0 +8:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:1/0/physics_layer_0/angular_velocity = 0.0 +9:1/0 = 0 +9:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:1/0/physics_layer_0/angular_velocity = 0.0 +11:1/0 = 0 +11:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:1/0/physics_layer_0/angular_velocity = 0.0 +11:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +12:1/0 = 0 +12:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:1/0/physics_layer_0/angular_velocity = 0.0 +13:1/0 = 0 +13:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:1/0/physics_layer_0/angular_velocity = 0.0 +13:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +14:1/0 = 0 +14:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:1/0/physics_layer_0/angular_velocity = 0.0 +15:1/0 = 0 +15:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:1/0/physics_layer_0/angular_velocity = 0.0 +16:1/0 = 0 +16:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:1/0/physics_layer_0/angular_velocity = 0.0 +16:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +17:1/0 = 0 +17:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:1/0/physics_layer_0/angular_velocity = 0.0 +17:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +18:1/0 = 0 +18:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:1/0/physics_layer_0/angular_velocity = 0.0 +19:1/0 = 0 +19:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:1/0/physics_layer_0/angular_velocity = 0.0 +20:1/0 = 0 +20:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:1/0/physics_layer_0/angular_velocity = 0.0 +0:2/0 = 0 +0:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:2/0/physics_layer_0/angular_velocity = 0.0 +1:2/0 = 0 +1:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:2/0/physics_layer_0/angular_velocity = 0.0 +2:2/0 = 0 +2:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:2/0/physics_layer_0/angular_velocity = 0.0 +3:2/0 = 0 +3:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:2/0/physics_layer_0/angular_velocity = 0.0 +4:2/0 = 0 +4:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:2/0/physics_layer_0/angular_velocity = 0.0 +5:2/0 = 0 +5:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:2/0/physics_layer_0/angular_velocity = 0.0 +6:2/0 = 0 +6:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:2/0/physics_layer_0/angular_velocity = 0.0 +7:2/0 = 0 +7:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:2/0/physics_layer_0/angular_velocity = 0.0 +8:2/0 = 0 +8:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:2/0/physics_layer_0/angular_velocity = 0.0 +9:2/0 = 0 +9:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:2/0/physics_layer_0/angular_velocity = 0.0 +10:2/0 = 0 +10:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:2/0/physics_layer_0/angular_velocity = 0.0 +11:2/0 = 0 +11:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:2/0/physics_layer_0/angular_velocity = 0.0 +11:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +12:2/0 = 0 +12:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:2/0/physics_layer_0/angular_velocity = 0.0 +12:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +13:2/0 = 0 +13:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:2/0/physics_layer_0/angular_velocity = 0.0 +13:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +14:2/0 = 0 +14:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:2/0/physics_layer_0/angular_velocity = 0.0 +15:2/0 = 0 +15:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:2/0/physics_layer_0/angular_velocity = 0.0 +16:2/0 = 0 +16:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:2/0/physics_layer_0/angular_velocity = 0.0 +16:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +17:2/0 = 0 +17:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:2/0/physics_layer_0/angular_velocity = 0.0 +17:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +18:2/0 = 0 +18:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:2/0/physics_layer_0/angular_velocity = 0.0 +19:2/0 = 0 +19:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:2/0/physics_layer_0/angular_velocity = 0.0 +20:2/0 = 0 +20:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:2/0/physics_layer_0/angular_velocity = 0.0 +21:2/0 = 0 +21:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:2/0/physics_layer_0/angular_velocity = 0.0 +0:3/0 = 0 +0:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:3/0/physics_layer_0/angular_velocity = 0.0 +1:3/0 = 0 +1:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:3/0/physics_layer_0/angular_velocity = 0.0 +2:3/0 = 0 +2:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:3/0/physics_layer_0/angular_velocity = 0.0 +3:3/0 = 0 +3:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:3/0/physics_layer_0/angular_velocity = 0.0 +4:3/0 = 0 +4:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:3/0/physics_layer_0/angular_velocity = 0.0 +5:3/0 = 0 +5:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:3/0/physics_layer_0/angular_velocity = 0.0 +6:3/0 = 0 +6:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:3/0/physics_layer_0/angular_velocity = 0.0 +7:3/0 = 0 +7:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:3/0/physics_layer_0/angular_velocity = 0.0 +8:3/0 = 0 +8:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:3/0/physics_layer_0/angular_velocity = 0.0 +9:3/0 = 0 +9:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:3/0/physics_layer_0/angular_velocity = 0.0 +10:3/0 = 0 +10:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:3/0/physics_layer_0/angular_velocity = 0.0 +11:3/0 = 0 +11:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:3/0/physics_layer_0/angular_velocity = 0.0 +12:3/0 = 0 +12:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:3/0/physics_layer_0/angular_velocity = 0.0 +13:3/0 = 0 +13:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:3/0/physics_layer_0/angular_velocity = 0.0 +14:3/0 = 0 +14:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:3/0/physics_layer_0/angular_velocity = 0.0 +15:3/0 = 0 +15:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:3/0/physics_layer_0/angular_velocity = 0.0 +16:3/0 = 0 +16:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:3/0/physics_layer_0/angular_velocity = 0.0 +17:3/0 = 0 +17:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:3/0/physics_layer_0/angular_velocity = 0.0 +18:3/0 = 0 +18:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:3/0/physics_layer_0/angular_velocity = 0.0 +19:3/0 = 0 +19:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:3/0/physics_layer_0/angular_velocity = 0.0 +20:3/0 = 0 +20:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:3/0/physics_layer_0/angular_velocity = 0.0 +21:3/0 = 0 +21:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:3/0/physics_layer_0/angular_velocity = 0.0 +0:4/0 = 0 +0:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:4/0/physics_layer_0/angular_velocity = 0.0 +1:4/0 = 0 +1:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:4/0/physics_layer_0/angular_velocity = 0.0 +4:4/0 = 0 +4:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:4/0/physics_layer_0/angular_velocity = 0.0 +5:4/0 = 0 +5:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:4/0/physics_layer_0/angular_velocity = 0.0 +6:4/0 = 0 +6:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:4/0/physics_layer_0/angular_velocity = 0.0 +7:4/0 = 0 +7:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:4/0/physics_layer_0/angular_velocity = 0.0 +8:4/0 = 0 +8:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:4/0/physics_layer_0/angular_velocity = 0.0 +15:4/0 = 0 +15:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:4/0/physics_layer_0/angular_velocity = 0.0 +16:4/0 = 0 +16:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:4/0/physics_layer_0/angular_velocity = 0.0 +17:4/0 = 0 +17:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:4/0/physics_layer_0/angular_velocity = 0.0 +18:4/0 = 0 +18:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:4/0/physics_layer_0/angular_velocity = 0.0 +19:4/0 = 0 +19:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:4/0/physics_layer_0/angular_velocity = 0.0 +0:5/0 = 0 +0:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:5/0/physics_layer_0/angular_velocity = 0.0 +1:5/0 = 0 +1:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:5/0/physics_layer_0/angular_velocity = 0.0 +2:5/0 = 0 +2:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:5/0/physics_layer_0/angular_velocity = 0.0 +3:5/0 = 0 +3:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:5/0/physics_layer_0/angular_velocity = 0.0 +4:5/0 = 0 +4:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:5/0/physics_layer_0/angular_velocity = 0.0 +11:5/0 = 0 +11:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:5/0/physics_layer_0/angular_velocity = 0.0 +0:6/0 = 0 +0:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:6/0/physics_layer_0/angular_velocity = 0.0 +1:6/0 = 0 +1:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:6/0/physics_layer_0/angular_velocity = 0.0 +2:6/0 = 0 +2:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:6/0/physics_layer_0/angular_velocity = 0.0 +3:6/0 = 0 +3:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:6/0/physics_layer_0/angular_velocity = 0.0 +4:6/0 = 0 +4:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:6/0/physics_layer_0/angular_velocity = 0.0 +5:6/0 = 0 +5:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:6/0/physics_layer_0/angular_velocity = 0.0 +11:6/0 = 0 +11:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:6/0/physics_layer_0/angular_velocity = 0.0 +11:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +12:6/0 = 0 +12:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:6/0/physics_layer_0/angular_velocity = 0.0 +12:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +13:6/0 = 0 +13:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:6/0/physics_layer_0/angular_velocity = 0.0 +13:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +14:6/0 = 0 +14:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:6/0/physics_layer_0/angular_velocity = 0.0 +15:6/0 = 0 +15:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:6/0/physics_layer_0/angular_velocity = 0.0 +16:6/0 = 0 +16:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:6/0/physics_layer_0/angular_velocity = 0.0 +17:6/0 = 0 +17:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:6/0/physics_layer_0/angular_velocity = 0.0 +18:6/0 = 0 +18:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:6/0/physics_layer_0/angular_velocity = 0.0 +19:6/0 = 0 +19:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:6/0/physics_layer_0/angular_velocity = 0.0 +20:6/0 = 0 +20:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:6/0/physics_layer_0/angular_velocity = 0.0 +0:7/0 = 0 +0:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:7/0/physics_layer_0/angular_velocity = 0.0 +1:7/0 = 0 +1:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:7/0/physics_layer_0/angular_velocity = 0.0 +2:7/0 = 0 +2:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:7/0/physics_layer_0/angular_velocity = 0.0 +3:7/0 = 0 +3:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:7/0/physics_layer_0/angular_velocity = 0.0 +4:7/0 = 0 +4:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:7/0/physics_layer_0/angular_velocity = 0.0 +5:7/0 = 0 +5:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:7/0/physics_layer_0/angular_velocity = 0.0 +6:7/0 = 0 +6:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:7/0/physics_layer_0/angular_velocity = 0.0 +7:7/0 = 0 +7:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:7/0/physics_layer_0/angular_velocity = 0.0 +8:7/0 = 0 +8:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:7/0/physics_layer_0/angular_velocity = 0.0 +9:7/0 = 0 +9:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:7/0/physics_layer_0/angular_velocity = 0.0 +11:7/0 = 0 +11:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:7/0/physics_layer_0/angular_velocity = 0.0 +11:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +12:7/0 = 0 +12:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:7/0/physics_layer_0/angular_velocity = 0.0 +13:7/0 = 0 +13:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:7/0/physics_layer_0/angular_velocity = 0.0 +13:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +14:7/0 = 0 +14:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:7/0/physics_layer_0/angular_velocity = 0.0 +15:7/0 = 0 +15:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:7/0/physics_layer_0/angular_velocity = 0.0 +16:7/0 = 0 +16:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:7/0/physics_layer_0/angular_velocity = 0.0 +16:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +17:7/0 = 0 +17:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:7/0/physics_layer_0/angular_velocity = 0.0 +17:7/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +18:7/0 = 0 +18:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:7/0/physics_layer_0/angular_velocity = 0.0 +19:7/0 = 0 +19:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:7/0/physics_layer_0/angular_velocity = 0.0 +20:7/0 = 0 +20:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:7/0/physics_layer_0/angular_velocity = 0.0 +0:8/0 = 0 +0:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:8/0/physics_layer_0/angular_velocity = 0.0 +1:8/0 = 0 +1:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:8/0/physics_layer_0/angular_velocity = 0.0 +2:8/0 = 0 +2:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:8/0/physics_layer_0/angular_velocity = 0.0 +3:8/0 = 0 +3:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:8/0/physics_layer_0/angular_velocity = 0.0 +4:8/0 = 0 +4:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:8/0/physics_layer_0/angular_velocity = 0.0 +5:8/0 = 0 +5:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:8/0/physics_layer_0/angular_velocity = 0.0 +6:8/0 = 0 +6:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:8/0/physics_layer_0/angular_velocity = 0.0 +7:8/0 = 0 +7:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:8/0/physics_layer_0/angular_velocity = 0.0 +8:8/0 = 0 +8:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:8/0/physics_layer_0/angular_velocity = 0.0 +9:8/0 = 0 +9:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:8/0/physics_layer_0/angular_velocity = 0.0 +11:8/0 = 0 +11:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:8/0/physics_layer_0/angular_velocity = 0.0 +11:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +12:8/0 = 0 +12:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:8/0/physics_layer_0/angular_velocity = 0.0 +12:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +13:8/0 = 0 +13:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:8/0/physics_layer_0/angular_velocity = 0.0 +13:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +14:8/0 = 0 +14:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:8/0/physics_layer_0/angular_velocity = 0.0 +15:8/0 = 0 +15:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:8/0/physics_layer_0/angular_velocity = 0.0 +16:8/0 = 0 +16:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:8/0/physics_layer_0/angular_velocity = 0.0 +16:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +17:8/0 = 0 +17:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:8/0/physics_layer_0/angular_velocity = 0.0 +17:8/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +18:8/0 = 0 +18:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:8/0/physics_layer_0/angular_velocity = 0.0 +19:8/0 = 0 +19:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:8/0/physics_layer_0/angular_velocity = 0.0 +20:8/0 = 0 +20:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:8/0/physics_layer_0/angular_velocity = 0.0 +21:8/0 = 0 +21:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:8/0/physics_layer_0/angular_velocity = 0.0 +0:9/0 = 0 +0:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:9/0/physics_layer_0/angular_velocity = 0.0 +1:9/0 = 0 +1:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:9/0/physics_layer_0/angular_velocity = 0.0 +2:9/0 = 0 +2:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:9/0/physics_layer_0/angular_velocity = 0.0 +3:9/0 = 0 +3:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:9/0/physics_layer_0/angular_velocity = 0.0 +4:9/0 = 0 +4:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:9/0/physics_layer_0/angular_velocity = 0.0 +5:9/0 = 0 +5:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:9/0/physics_layer_0/angular_velocity = 0.0 +6:9/0 = 0 +6:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:9/0/physics_layer_0/angular_velocity = 0.0 +7:9/0 = 0 +7:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:9/0/physics_layer_0/angular_velocity = 0.0 +8:9/0 = 0 +8:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:9/0/physics_layer_0/angular_velocity = 0.0 +9:9/0 = 0 +9:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:9/0/physics_layer_0/angular_velocity = 0.0 +10:9/0 = 0 +10:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:9/0/physics_layer_0/angular_velocity = 0.0 +11:9/0 = 0 +11:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:9/0/physics_layer_0/angular_velocity = 0.0 +12:9/0 = 0 +12:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:9/0/physics_layer_0/angular_velocity = 0.0 +13:9/0 = 0 +13:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:9/0/physics_layer_0/angular_velocity = 0.0 +14:9/0 = 0 +14:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:9/0/physics_layer_0/angular_velocity = 0.0 +15:9/0 = 0 +15:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:9/0/physics_layer_0/angular_velocity = 0.0 +16:9/0 = 0 +16:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:9/0/physics_layer_0/angular_velocity = 0.0 +17:9/0 = 0 +17:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:9/0/physics_layer_0/angular_velocity = 0.0 +18:9/0 = 0 +18:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:9/0/physics_layer_0/angular_velocity = 0.0 +19:9/0 = 0 +19:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:9/0/physics_layer_0/angular_velocity = 0.0 +20:9/0 = 0 +20:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:9/0/physics_layer_0/angular_velocity = 0.0 +21:9/0 = 0 +21:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:9/0/physics_layer_0/angular_velocity = 0.0 +0:10/0 = 0 +0:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:10/0/physics_layer_0/angular_velocity = 0.0 +1:10/0 = 0 +1:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:10/0/physics_layer_0/angular_velocity = 0.0 +2:10/0 = 0 +2:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:10/0/physics_layer_0/angular_velocity = 0.0 +3:10/0 = 0 +3:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:10/0/physics_layer_0/angular_velocity = 0.0 +4:10/0 = 0 +4:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:10/0/physics_layer_0/angular_velocity = 0.0 +5:10/0 = 0 +5:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:10/0/physics_layer_0/angular_velocity = 0.0 +6:10/0 = 0 +6:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:10/0/physics_layer_0/angular_velocity = 0.0 +7:10/0 = 0 +7:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:10/0/physics_layer_0/angular_velocity = 0.0 +8:10/0 = 0 +8:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:10/0/physics_layer_0/angular_velocity = 0.0 +9:10/0 = 0 +9:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:10/0/physics_layer_0/angular_velocity = 0.0 +10:10/0 = 0 +10:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:10/0/physics_layer_0/angular_velocity = 0.0 +15:10/0 = 0 +15:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:10/0/physics_layer_0/angular_velocity = 0.0 +16:10/0 = 0 +16:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:10/0/physics_layer_0/angular_velocity = 0.0 +17:10/0 = 0 +17:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:10/0/physics_layer_0/angular_velocity = 0.0 +18:10/0 = 0 +18:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:10/0/physics_layer_0/angular_velocity = 0.0 +19:10/0 = 0 +19:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:10/0/physics_layer_0/angular_velocity = 0.0 +0:11/0 = 0 +0:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:11/0/physics_layer_0/angular_velocity = 0.0 +1:11/0 = 0 +1:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:11/0/physics_layer_0/angular_velocity = 0.0 +2:11/0 = 0 +2:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:11/0/physics_layer_0/angular_velocity = 0.0 +3:11/0 = 0 +3:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:11/0/physics_layer_0/angular_velocity = 0.0 +4:11/0 = 0 +4:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:11/0/physics_layer_0/angular_velocity = 0.0 +5:11/0 = 0 +5:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:11/0/physics_layer_0/angular_velocity = 0.0 +6:11/0 = 0 +6:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:11/0/physics_layer_0/angular_velocity = 0.0 +7:11/0 = 0 +7:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:11/0/physics_layer_0/angular_velocity = 0.0 +8:11/0 = 0 +8:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:11/0/physics_layer_0/angular_velocity = 0.0 +9:11/0 = 0 +9:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:11/0/physics_layer_0/angular_velocity = 0.0 +10:11/0 = 0 +10:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:11/0/physics_layer_0/angular_velocity = 0.0 +19:11/0 = 0 +19:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:11/0/physics_layer_0/angular_velocity = 0.0 +20:11/0 = 0 +20:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:11/0/physics_layer_0/angular_velocity = 0.0 +21:11/0 = 0 +21:11/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:11/0/physics_layer_0/angular_velocity = 0.0 +0:12/0 = 0 +0:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:12/0/physics_layer_0/angular_velocity = 0.0 +1:12/0 = 0 +1:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:12/0/physics_layer_0/angular_velocity = 0.0 +2:12/0 = 0 +2:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:12/0/physics_layer_0/angular_velocity = 0.0 +3:12/0 = 0 +3:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:12/0/physics_layer_0/angular_velocity = 0.0 +4:12/0 = 0 +4:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:12/0/physics_layer_0/angular_velocity = 0.0 +6:12/0 = 0 +6:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:12/0/physics_layer_0/angular_velocity = 0.0 +7:12/0 = 0 +7:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:12/0/physics_layer_0/angular_velocity = 0.0 +8:12/0 = 0 +8:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:12/0/physics_layer_0/angular_velocity = 0.0 +9:12/0 = 0 +9:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:12/0/physics_layer_0/angular_velocity = 0.0 +10:12/0 = 0 +10:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:12/0/physics_layer_0/angular_velocity = 0.0 +19:12/0 = 0 +19:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:12/0/physics_layer_0/angular_velocity = 0.0 +20:12/0 = 0 +20:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:12/0/physics_layer_0/angular_velocity = 0.0 +21:12/0 = 0 +21:12/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:12/0/physics_layer_0/angular_velocity = 0.0 +0:13/0 = 0 +0:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:13/0/physics_layer_0/angular_velocity = 0.0 +0:13/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, -20.5, -32, -20, 32, -32, 32) +1:13/0 = 0 +1:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:13/0/physics_layer_0/angular_velocity = 0.0 +2:13/0 = 0 +2:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:13/0/physics_layer_0/angular_velocity = 0.0 +2:13/0/physics_layer_0/polygon_0/points = PackedVector2Array(20.5, -32, 32, -32, 32, 32, 20.5, 32) +3:13/0 = 0 +3:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:13/0/physics_layer_0/angular_velocity = 0.0 +4:13/0 = 0 +4:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:13/0/physics_layer_0/angular_velocity = 0.0 +5:13/0 = 0 +5:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:13/0/physics_layer_0/angular_velocity = 0.0 +6:13/0 = 0 +6:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:13/0/physics_layer_0/angular_velocity = 0.0 +7:13/0 = 0 +7:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:13/0/physics_layer_0/angular_velocity = 0.0 +8:13/0 = 0 +8:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:13/0/physics_layer_0/angular_velocity = 0.0 +9:13/0 = 0 +9:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:13/0/physics_layer_0/angular_velocity = 0.0 +19:13/0 = 0 +19:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:13/0/physics_layer_0/angular_velocity = 0.0 +20:13/0 = 0 +20:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:13/0/physics_layer_0/angular_velocity = 0.0 +21:13/0 = 0 +21:13/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:13/0/physics_layer_0/angular_velocity = 0.0 +0:14/0 = 0 +0:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:14/0/physics_layer_0/angular_velocity = 0.0 +0:14/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, -20.5, -32, -20, 32, -32, 32) +1:14/0 = 0 +1:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:14/0/physics_layer_0/angular_velocity = 0.0 +2:14/0 = 0 +2:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:14/0/physics_layer_0/angular_velocity = 0.0 +2:14/0/physics_layer_0/polygon_0/points = PackedVector2Array(20.5, -32, 32, -32, 32, 32, 20.5, 32) +3:14/0 = 0 +3:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:14/0/physics_layer_0/angular_velocity = 0.0 +4:14/0 = 0 +4:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:14/0/physics_layer_0/angular_velocity = 0.0 +5:14/0 = 0 +5:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:14/0/physics_layer_0/angular_velocity = 0.0 +6:14/0 = 0 +6:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:14/0/physics_layer_0/angular_velocity = 0.0 +7:14/0 = 0 +7:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:14/0/physics_layer_0/angular_velocity = 0.0 +8:14/0 = 0 +8:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:14/0/physics_layer_0/angular_velocity = 0.0 +9:14/0 = 0 +9:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:14/0/physics_layer_0/angular_velocity = 0.0 +19:14/0 = 0 +19:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:14/0/physics_layer_0/angular_velocity = 0.0 +20:14/0 = 0 +20:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:14/0/physics_layer_0/angular_velocity = 0.0 +21:14/0 = 0 +21:14/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:14/0/physics_layer_0/angular_velocity = 0.0 +0:15/0 = 0 +0:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:15/0/physics_layer_0/angular_velocity = 0.0 +0:15/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, -20.5, -32, -20, 32, -32, 32) +1:15/0 = 0 +1:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:15/0/physics_layer_0/angular_velocity = 0.0 +2:15/0 = 0 +2:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:15/0/physics_layer_0/angular_velocity = 0.0 +2:15/0/physics_layer_0/polygon_0/points = PackedVector2Array(20.5, -32, 32, -32, 32, 32, 20.5, 32) +3:15/0 = 0 +3:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:15/0/physics_layer_0/angular_velocity = 0.0 +4:15/0 = 0 +4:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:15/0/physics_layer_0/angular_velocity = 0.0 +5:15/0 = 0 +5:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:15/0/physics_layer_0/angular_velocity = 0.0 +6:15/0 = 0 +6:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:15/0/physics_layer_0/angular_velocity = 0.0 +7:15/0 = 0 +7:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:15/0/physics_layer_0/angular_velocity = 0.0 +8:15/0 = 0 +8:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:15/0/physics_layer_0/angular_velocity = 0.0 +9:15/0 = 0 +9:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:15/0/physics_layer_0/angular_velocity = 0.0 +10:15/0 = 0 +10:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:15/0/physics_layer_0/angular_velocity = 0.0 +19:15/0 = 0 +19:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:15/0/physics_layer_0/angular_velocity = 0.0 +20:15/0 = 0 +20:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:15/0/physics_layer_0/angular_velocity = 0.0 +21:15/0 = 0 +21:15/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:15/0/physics_layer_0/angular_velocity = 0.0 +0:16/0 = 0 +0:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:16/0/physics_layer_0/angular_velocity = 0.0 +1:16/0 = 0 +1:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:16/0/physics_layer_0/angular_velocity = 0.0 +2:16/0 = 0 +2:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:16/0/physics_layer_0/angular_velocity = 0.0 +3:16/0 = 0 +3:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:16/0/physics_layer_0/angular_velocity = 0.0 +4:16/0 = 0 +4:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:16/0/physics_layer_0/angular_velocity = 0.0 +5:16/0 = 0 +5:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:16/0/physics_layer_0/angular_velocity = 0.0 +6:16/0 = 0 +6:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:16/0/physics_layer_0/angular_velocity = 0.0 +7:16/0 = 0 +7:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:16/0/physics_layer_0/angular_velocity = 0.0 +8:16/0 = 0 +8:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:16/0/physics_layer_0/angular_velocity = 0.0 +9:16/0 = 0 +9:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:16/0/physics_layer_0/angular_velocity = 0.0 +10:16/0 = 0 +10:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:16/0/physics_layer_0/angular_velocity = 0.0 +19:16/0 = 0 +19:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:16/0/physics_layer_0/angular_velocity = 0.0 +20:16/0 = 0 +20:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:16/0/physics_layer_0/angular_velocity = 0.0 +21:16/0 = 0 +21:16/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:16/0/physics_layer_0/angular_velocity = 0.0 +0:17/0 = 0 +0:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:17/0/physics_layer_0/angular_velocity = 0.0 +1:17/0 = 0 +1:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:17/0/physics_layer_0/angular_velocity = 0.0 +2:17/0 = 0 +2:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:17/0/physics_layer_0/angular_velocity = 0.0 +3:17/0 = 0 +3:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:17/0/physics_layer_0/angular_velocity = 0.0 +4:17/0 = 0 +4:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:17/0/physics_layer_0/angular_velocity = 0.0 +5:17/0 = 0 +5:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:17/0/physics_layer_0/angular_velocity = 0.0 +6:17/0 = 0 +6:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:17/0/physics_layer_0/angular_velocity = 0.0 +7:17/0 = 0 +7:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:17/0/physics_layer_0/angular_velocity = 0.0 +8:17/0 = 0 +8:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:17/0/physics_layer_0/angular_velocity = 0.0 +16:17/0 = 0 +16:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:17/0/physics_layer_0/angular_velocity = 0.0 +17:17/0 = 0 +17:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:17/0/physics_layer_0/angular_velocity = 0.0 +18:17/0 = 0 +18:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:17/0/physics_layer_0/angular_velocity = 0.0 +19:17/0 = 0 +19:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:17/0/physics_layer_0/angular_velocity = 0.0 +20:17/0 = 0 +20:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:17/0/physics_layer_0/angular_velocity = 0.0 +21:17/0 = 0 +21:17/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:17/0/physics_layer_0/angular_velocity = 0.0 +0:18/0 = 0 +0:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:18/0/physics_layer_0/angular_velocity = 0.0 +1:18/0 = 0 +1:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:18/0/physics_layer_0/angular_velocity = 0.0 +2:18/0 = 0 +2:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:18/0/physics_layer_0/angular_velocity = 0.0 +3:18/0 = 0 +3:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:18/0/physics_layer_0/angular_velocity = 0.0 +4:18/0 = 0 +4:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:18/0/physics_layer_0/angular_velocity = 0.0 +5:18/0 = 0 +5:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:18/0/physics_layer_0/angular_velocity = 0.0 +6:18/0 = 0 +6:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:18/0/physics_layer_0/angular_velocity = 0.0 +7:18/0 = 0 +7:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:18/0/physics_layer_0/angular_velocity = 0.0 +8:18/0 = 0 +8:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:18/0/physics_layer_0/angular_velocity = 0.0 +9:18/0 = 0 +9:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:18/0/physics_layer_0/angular_velocity = 0.0 +13:18/0 = 0 +13:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:18/0/physics_layer_0/angular_velocity = 0.0 +14:18/0 = 0 +14:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:18/0/physics_layer_0/angular_velocity = 0.0 +14:18/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +15:18/0 = 0 +15:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:18/0/physics_layer_0/angular_velocity = 0.0 +15:18/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +16:18/0 = 0 +16:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:18/0/physics_layer_0/angular_velocity = 0.0 +16:18/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +17:18/0 = 0 +17:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:18/0/physics_layer_0/angular_velocity = 0.0 +17:18/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +18:18/0 = 0 +18:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:18/0/physics_layer_0/angular_velocity = 0.0 +18:18/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +19:18/0 = 0 +19:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:18/0/physics_layer_0/angular_velocity = 0.0 +19:18/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +20:18/0 = 0 +20:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:18/0/physics_layer_0/angular_velocity = 0.0 +21:18/0 = 0 +21:18/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:18/0/physics_layer_0/angular_velocity = 0.0 +21:18/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +0:19/0 = 0 +0:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:19/0/physics_layer_0/angular_velocity = 0.0 +1:19/0 = 0 +1:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:19/0/physics_layer_0/angular_velocity = 0.0 +2:19/0 = 0 +2:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:19/0/physics_layer_0/angular_velocity = 0.0 +3:19/0 = 0 +3:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:19/0/physics_layer_0/angular_velocity = 0.0 +4:19/0 = 0 +4:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:19/0/physics_layer_0/angular_velocity = 0.0 +5:19/0 = 0 +5:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:19/0/physics_layer_0/angular_velocity = 0.0 +6:19/0 = 0 +6:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:19/0/physics_layer_0/angular_velocity = 0.0 +7:19/0 = 0 +7:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:19/0/physics_layer_0/angular_velocity = 0.0 +8:19/0 = 0 +8:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:19/0/physics_layer_0/angular_velocity = 0.0 +9:19/0 = 0 +9:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:19/0/physics_layer_0/angular_velocity = 0.0 +13:19/0 = 0 +13:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:19/0/physics_layer_0/angular_velocity = 0.0 +14:19/0 = 0 +14:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:19/0/physics_layer_0/angular_velocity = 0.0 +14:19/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +15:19/0 = 0 +15:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:19/0/physics_layer_0/angular_velocity = 0.0 +16:19/0 = 0 +16:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:19/0/physics_layer_0/angular_velocity = 0.0 +16:19/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +17:19/0 = 0 +17:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:19/0/physics_layer_0/angular_velocity = 0.0 +17:19/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +18:19/0 = 0 +18:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:19/0/physics_layer_0/angular_velocity = 0.0 +18:19/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +19:19/0 = 0 +19:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:19/0/physics_layer_0/angular_velocity = 0.0 +19:19/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +20:19/0 = 0 +20:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:19/0/physics_layer_0/angular_velocity = 0.0 +21:19/0 = 0 +21:19/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:19/0/physics_layer_0/angular_velocity = 0.0 +21:19/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +0:20/0 = 0 +0:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:20/0/physics_layer_0/angular_velocity = 0.0 +1:20/0 = 0 +1:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:20/0/physics_layer_0/angular_velocity = 0.0 +2:20/0 = 0 +2:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:20/0/physics_layer_0/angular_velocity = 0.0 +3:20/0 = 0 +3:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:20/0/physics_layer_0/angular_velocity = 0.0 +4:20/0 = 0 +4:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:20/0/physics_layer_0/angular_velocity = 0.0 +5:20/0 = 0 +5:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:20/0/physics_layer_0/angular_velocity = 0.0 +6:20/0 = 0 +6:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:20/0/physics_layer_0/angular_velocity = 0.0 +7:20/0 = 0 +7:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:20/0/physics_layer_0/angular_velocity = 0.0 +8:20/0 = 0 +8:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:20/0/physics_layer_0/angular_velocity = 0.0 +9:20/0 = 0 +9:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:20/0/physics_layer_0/angular_velocity = 0.0 +10:20/0 = 0 +10:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:20/0/physics_layer_0/angular_velocity = 0.0 +13:20/0 = 0 +13:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:20/0/physics_layer_0/angular_velocity = 0.0 +14:20/0 = 0 +14:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:20/0/physics_layer_0/angular_velocity = 0.0 +14:20/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +15:20/0 = 0 +15:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:20/0/physics_layer_0/angular_velocity = 0.0 +15:20/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +16:20/0 = 0 +16:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:20/0/physics_layer_0/angular_velocity = 0.0 +16:20/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +17:20/0 = 0 +17:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:20/0/physics_layer_0/angular_velocity = 0.0 +17:20/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +18:20/0 = 0 +18:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:20/0/physics_layer_0/angular_velocity = 0.0 +18:20/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +19:20/0 = 0 +19:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:20/0/physics_layer_0/angular_velocity = 0.0 +19:20/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +20:20/0 = 0 +20:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +20:20/0/physics_layer_0/angular_velocity = 0.0 +21:20/0 = 0 +21:20/0/physics_layer_0/linear_velocity = Vector2(0, 0) +21:20/0/physics_layer_0/angular_velocity = 0.0 +21:20/0/physics_layer_0/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +0:21/0 = 0 +0:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:21/0/physics_layer_0/angular_velocity = 0.0 +1:21/0 = 0 +1:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:21/0/physics_layer_0/angular_velocity = 0.0 +2:21/0 = 0 +2:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:21/0/physics_layer_0/angular_velocity = 0.0 +3:21/0 = 0 +3:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:21/0/physics_layer_0/angular_velocity = 0.0 +4:21/0 = 0 +4:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:21/0/physics_layer_0/angular_velocity = 0.0 +5:21/0 = 0 +5:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:21/0/physics_layer_0/angular_velocity = 0.0 +6:21/0 = 0 +6:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:21/0/physics_layer_0/angular_velocity = 0.0 +7:21/0 = 0 +7:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:21/0/physics_layer_0/angular_velocity = 0.0 +8:21/0 = 0 +8:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:21/0/physics_layer_0/angular_velocity = 0.0 +9:21/0 = 0 +9:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:21/0/physics_layer_0/angular_velocity = 0.0 +10:21/0 = 0 +10:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:21/0/physics_layer_0/angular_velocity = 0.0 +13:21/0 = 0 +13:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:21/0/physics_layer_0/angular_velocity = 0.0 +14:21/0 = 0 +14:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:21/0/physics_layer_0/angular_velocity = 0.0 +15:21/0 = 0 +15:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:21/0/physics_layer_0/angular_velocity = 0.0 +16:21/0 = 0 +16:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:21/0/physics_layer_0/angular_velocity = 0.0 +17:21/0 = 0 +17:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:21/0/physics_layer_0/angular_velocity = 0.0 +18:21/0 = 0 +18:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:21/0/physics_layer_0/angular_velocity = 0.0 +19:21/0 = 0 +19:21/0/physics_layer_0/linear_velocity = Vector2(0, 0) +19:21/0/physics_layer_0/angular_velocity = 0.0 +0:22/0 = 0 +0:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:22/0/physics_layer_0/angular_velocity = 0.0 +1:22/0 = 0 +1:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:22/0/physics_layer_0/angular_velocity = 0.0 +3:22/0 = 0 +3:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:22/0/physics_layer_0/angular_velocity = 0.0 +4:22/0 = 0 +4:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:22/0/physics_layer_0/angular_velocity = 0.0 +5:22/0 = 0 +5:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:22/0/physics_layer_0/angular_velocity = 0.0 +6:22/0 = 0 +6:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:22/0/physics_layer_0/angular_velocity = 0.0 +7:22/0 = 0 +7:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:22/0/physics_layer_0/angular_velocity = 0.0 +8:22/0 = 0 +8:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:22/0/physics_layer_0/angular_velocity = 0.0 +13:22/0 = 0 +13:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:22/0/physics_layer_0/angular_velocity = 0.0 +14:22/0 = 0 +14:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:22/0/physics_layer_0/angular_velocity = 0.0 +15:22/0 = 0 +15:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:22/0/physics_layer_0/angular_velocity = 0.0 +16:22/0 = 0 +16:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:22/0/physics_layer_0/angular_velocity = 0.0 +17:22/0 = 0 +17:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:22/0/physics_layer_0/angular_velocity = 0.0 +18:22/0 = 0 +18:22/0/physics_layer_0/linear_velocity = Vector2(0, 0) +18:22/0/physics_layer_0/angular_velocity = 0.0 +0:23/0 = 0 +0:23/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:23/0/physics_layer_0/angular_velocity = 0.0 +1:23/0 = 0 +1:23/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:23/0/physics_layer_0/angular_velocity = 0.0 +2:23/0 = 0 +2:23/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:23/0/physics_layer_0/angular_velocity = 0.0 +3:23/0 = 0 +3:23/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:23/0/physics_layer_0/angular_velocity = 0.0 +4:23/0 = 0 +4:23/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:23/0/physics_layer_0/angular_velocity = 0.0 +0:24/0 = 0 +0:24/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:24/0/physics_layer_0/angular_velocity = 0.0 +1:24/0 = 0 +1:24/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:24/0/physics_layer_0/angular_velocity = 0.0 +2:24/0 = 0 +2:24/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:24/0/physics_layer_0/angular_velocity = 0.0 +3:24/0 = 0 +3:24/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:24/0/physics_layer_0/angular_velocity = 0.0 +4:24/0 = 0 +4:24/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:24/0/physics_layer_0/angular_velocity = 0.0 +5:24/0 = 0 +5:24/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:24/0/physics_layer_0/angular_velocity = 0.0 + +[sub_resource type="TileSet" id="TileSet_xdu0j"] +tile_size = Vector2i(64, 64) +physics_layer_0/collision_layer = 1 +physics_layer_0/collision_mask = 6 +sources/0 = SubResource("TileSetAtlasSource_auqfk") + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_m24ei"] +texture = ExtResource("3_72u1m") +texture_region_size = Vector2i(64, 64) +0:3/0 = 0 +1:3/0 = 0 +2:3/0 = 0 +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +6:3/0 = 0 +7:3/0 = 0 +7:2/0 = 0 +6:2/0 = 0 +5:2/0 = 0 +4:2/0 = 0 +3:2/0 = 0 +2:2/0 = 0 +1:2/0 = 0 +0:2/0 = 0 +0:1/0 = 0 +0:0/0 = 0 +1:0/0 = 0 +2:0/0 = 0 +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +8:0/0 = 0 +9:0/0 = 0 +10:0/0 = 0 +11:0/0 = 0 +12:0/0 = 0 +13:0/0 = 0 +14:0/0 = 0 +15:0/0 = 0 + +[sub_resource type="TileSet" id="TileSet_orc4v"] +tile_size = Vector2i(64, 64) +sources/0 = SubResource("TileSetAtlasSource_m24ei") + +[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_5dw0q"] +distance = -250.0 + +[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_7ioaa"] +normal = Vector2(-1, 0) +distance = -1724.0 + +[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_fq7i5"] +normal = Vector2(0, 1) +distance = -1727.0 + +[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_kp00i"] +normal = Vector2(1, 0) +distance = -1921.0 + +[node name="Main" type="Node2D"] +script = ExtResource("1_l8nqt") + +[node name="Map" type="Node" parent="."] + +[node name="Terrain" type="TileMap" parent="Map"] +position = Vector2(0, 1) +tile_set = SubResource("TileSet_xdu0j") +rendering_quadrant_size = 64 +format = 2 +layer_0/tile_data = PackedInt32Array(458760, 131072, 13, 458759, 0, 13, 524295, 0, 14, 589831, 0, 14, 655367, 0, 14, 720903, 0, 15, 720904, 131072, 15, 655368, 131072, 14, 589832, 131072, 14, 524296, 131072, 14, 720900, 1048576, 1, 655372, 1048576, 1, 851971, 1048576, 1, 917506, 1048576, 1, 983041, 1048576, 1, 851972, 851968, 2, 720908, 851968, 2, 655374, 851968, 2, 589840, 851968, 2, 720901, 786432, 2, 720902, 786432, 2, 720905, 786432, 2, 720906, 786432, 2, 720907, 786432, 2, 655373, 786432, 2, 589839, 786432, 2, 786436, 851968, 1, 917507, 851968, 2, 983042, 851968, 2, 1048577, 851968, 2, 1114112, 851968, 2, 1048576, 1048576, 1, 1179647, 1048576, 1, 1245183, 851968, 1, 1310719, 1048576, 2, 1245184, 786432, 0, 1245185, 786432, 0, 1245186, 786432, 0, 1245187, 786432, 0, 1245188, 851968, 0, 1310725, 786432, 0, 1310726, 786432, 0, 1310724, 1048576, 2, 1310727, 1114112, 2, 1245191, 720896, 0, 1245192, 786432, 0, 1245193, 851968, 0, 1310729, 1048576, 2, 1310730, 786432, 0, 1310731, 786432, 0, 1310732, 786432, 0, 1310733, 786432, 0, 1310734, 786432, 0, 1310735, 786432, 0, 1310736, 786432, 0, 1310737, 851968, 0, 1376273, 1048576, 2, 1376274, 786432, 0, 1376275, 1114112, 2, 1310739, 720896, 0, 1310740, 1114112, 2, 1245204, 720896, 1, 1179668, 720896, 0, 1179669, 1114112, 2, 1114133, 720896, 1, 1048597, 720896, 1, 983061, 720896, 0, 983062, 1114112, 2, 917526, 720896, 1, 851990, 720896, 1, 720917, 720896, 1, 655381, 720896, 1, 589845, 720896, 1, 524309, 720896, 1, 458773, 720896, 1, 393237, 720896, 1, 786453, 720896, 2, 786454, 1114112, 1, 327701, 1114112, 1, 327700, 786432, 2, 327699, 1048576, 1, 393234, 1048576, 1, 458769, 1048576, 1, 524304, 1048576, 1, 589838, 1048576, 1, 524305, 851968, 2, 458770, 851968, 2, 393235, 851968, 2, 1245206, 655360, 11, 1245205, 655360, 12, 1310741, 655360, 12, 1376277, 655360, 12, 1441813, 655360, 12, 1441814, 655360, 12, 1441815, 655360, 12, 1441816, 655360, 12, 1441817, 655360, 12, 1441818, 655360, 12, 1376282, 655360, 12, 1310746, 655360, 12, 1245210, 655360, 12, 1179674, 655360, 12, 1048602, 655360, 12, 983066, 655360, 12, 917530, 655360, 12, 786458, 655360, 12, 720922, 655360, 12, 524314, 655360, 12, 458778, 655360, 12, 327706, 655360, 12, 262170, 655360, 12, 196634, 655360, 12, 65562, 655360, 12, -65510, 655360, 12, -131046, 655360, 12, -196582, 655360, 12, -262118, 655360, 12, -327654, 655360, 12, -393190, 655360, 12, -524262, 655360, 12, -589798, 655360, 12, -655334, 655360, 12, -720870, 589824, 12, -786406, 655360, 12, -851942, 655360, 12, -917478, 655360, 12, -983014, 655360, 12, -1179622, 655360, 12, -1441766, 655360, 12, -1507302, 655360, 12, -1703910, 655360, 12, -1769446, 655360, 12, -1769447, 655360, 12, -1769448, 655360, 12, -1769449, 655360, 12, -1769450, 655360, 12, -1769451, 655360, 12, -1769452, 655360, 12, -1769453, 655360, 12, -1769454, 655360, 12, -1769455, 655360, 12, -1769456, 655360, 12, -1769457, 655360, 12, -1769458, 655360, 12, -1769459, 655360, 12, -1769460, 655360, 12, -1769461, 655360, 12, -1769462, 655360, 12, -1769463, 458752, 12, -1769464, 655360, 12, -1769465, 458752, 12, -1769466, 655360, 12, -1769467, 655360, 12, -1638374, 655360, 12, -1572838, 655360, 12, -1376230, 655360, 12, -1310694, 655360, 12, -1245158, 655360, 12, -1048550, 655360, 12, -1114086, 655360, 12, -458726, 655360, 12, 26, 589824, 12, 131098, 655360, 12, 393242, 655360, 12, 589850, 655360, 12, 655386, 655360, 12, 851994, 655360, 12, 1114138, 655360, 12, 1441812, 655360, 12, 1441811, 655360, 12, 1441810, 655360, 12, 1441809, 458752, 12, 1441808, 655360, 12, 1441807, 655360, 12, 1441806, 655360, 12, 1441805, 655360, 12, 1441804, 655360, 12, 1441803, 655360, 12, 1441802, 655360, 12, 1441801, 655360, 12, 1441800, 655360, 12, 1441799, 655360, 12, 1441798, 655360, 12, 1441797, 458752, 12, 1441796, 655360, 12, 1441795, 655360, 12, 1441794, 655360, 12, 1441793, 655360, 12, 1507324, 655360, 12, 1507325, 655360, 12, 1507326, 655360, 12, 1507327, 655360, 12, 1441792, 655360, 12, 1507322, 655360, 12, 1507321, 655360, 12, 1507320, 655360, 12, 1507319, 655360, 12, 1507318, 655360, 12, 1507317, 589824, 12, 1507316, 655360, 12, 1507315, 655360, 12, 1507314, 655360, 12, 1507313, 655360, 12, 1507312, 655360, 12, 1507311, 655360, 12, 1507310, 589824, 12, 1507309, 655360, 12, 1507308, 655360, 12, 1507307, 655360, 12, 1507306, 655360, 12, 1507305, 655360, 12, 1507304, 655360, 12, 1507303, 655360, 12, 1507302, 655360, 12, 1507301, 655360, 12, 1507300, 655360, 12, 1507299, 655360, 12, 1507298, 655360, 12, 1441762, 655360, 12, 1376226, 655360, 12, 1310690, 655360, 12, 1245154, 655360, 12, 1179618, 655360, 12, 1114082, 655360, 12, 1048546, 655360, 12, 983010, 655360, 12, 917474, 655360, 12, 851938, 655360, 12, 786402, 655360, 12, 720866, 655360, 12, 655330, 655360, 12, 589794, 655360, 12, 524258, 655360, 12, 458722, 655360, 12, 393186, 655360, 12, 327650, 655360, 12, 262114, 655360, 12, 196578, 655360, 12, 131042, 655360, 12, 65506, 655360, 12, -30, 589824, 12, -65566, 655360, 12, -131102, 655360, 12, -196638, 655360, 12, -262174, 655360, 12, -327710, 655360, 12, -393246, 655360, 12, -458782, 655360, 12, -524318, 655360, 12, -589854, 655360, 12, -655390, 655360, 12, -720926, 655360, 12, -786462, 655360, 12, -851998, 655360, 12, -917534, 655360, 12, -983070, 655360, 12, -1048606, 655360, 12, -1114142, 655360, 12, -1179678, 655360, 12, -1245214, 655360, 12, -1310750, 655360, 12, -1376286, 655360, 12, -1441822, 655360, 12, -1507358, 458752, 12, -1572894, 655360, 12, -1638430, 655360, 12, -1703966, 655360, 12, -1703965, 655360, 12, -1703964, 655360, 12, -1703963, 655360, 12, -1703962, 655360, 12, -1703961, 655360, 12, -1703960, 655360, 12, -1703959, 655360, 12, -1703958, 655360, 12, -1703957, 655360, 12, -1703956, 655360, 12, -1703955, 655360, 12, -1703954, 655360, 12, -1703953, 655360, 12, -1703952, 655360, 12, -1703951, 655360, 12, -1703949, 655360, 12, -1703948, 655360, 12, -1703947, 655360, 12, -1703946, 655360, 12, -1703945, 655360, 12, -1703944, 655360, 12, -1703943, 655360, 12, -1703942, 655360, 12, -1703941, 655360, 12, -1703940, 655360, 12, -1703939, 655360, 12, -1703938, 655360, 12, -1703937, 655360, 12, -1769472, 655360, 12, -1769470, 655360, 12, -1769469, 655360, 12, -1769468, 655360, 12, 917517, 720896, 5, 851981, 720896, 5, 786445, 720896, 5, 720909, 720896, 5, 720910, 720896, 5, 786446, 720896, 5, 851982, 720896, 5, 917518, 327680, 1, 983054, 131072, 2, 983053, 65536, 2, 983052, 327680, 1, 917516, 720896, 5, 851980, 720896, 5, 786444, 720896, 5, 786443, 720896, 5, 786442, 393216, 1, 786441, 0, 2, 786440, 262144, 5, 786439, 131072, 5, 786438, 131072, 2, 786437, 327680, 1, 851973, 131072, 1, 917509, 131072, 1, 917508, 720896, 5, 983044, 720896, 5, 983043, 720896, 5, 1048579, 720896, 5, 1048578, 720896, 5, 1114114, 720896, 5, 1114113, 720896, 5, 1179649, 720896, 5, 1179648, 720896, 5, 1179650, 720896, 5, 1179651, 720896, 5, 1114115, 720896, 5, 1114116, 720896, 5, 1048580, 720896, 5, 1048581, 720896, 5, 983045, 327680, 2, 983046, 131072, 0, 917510, 0, 5, 851974, 131072, 5, 851975, 0, 5, 917511, 65536, 5, 983047, 262144, 5, 1048583, 65536, 0, 1048582, 327680, 2, 1114118, 720896, 5, 1114117, 720896, 5, 1179653, 720896, 5, 1179652, 720896, 5, 1245189, 720896, 5, 1245190, 720896, 5, 1179654, 720896, 5, 1179655, 720896, 5, 1114119, 720896, 5, 1114120, 720896, 5, 1048584, 393216, 2, 983048, 0, 0, 917512, 0, 5, 851976, 196608, 5, 851977, 0, 5, 917513, 0, 0, 983049, 393216, 2, 1048585, 720896, 5, 1114121, 720896, 5, 1179657, 720896, 5, 1179656, 720896, 5, 1179658, 720896, 5, 1114122, 720896, 5, 1048586, 720896, 5, 983050, 720896, 5, 917514, 393216, 2, 851978, 0, 1, 851979, 720896, 5, 917515, 720896, 5, 983051, 720896, 5, 1048587, 720896, 5, 1114123, 720896, 5, 1179659, 720896, 5, 1245195, 720896, 5, 1245194, 720896, 5, 1245196, 720896, 5, 1179660, 720896, 5, 1114124, 327680, 2, 1048588, 131072, 1, 1048589, 0, 5, 1114125, 131072, 0, 1179661, 327680, 2, 1245197, 720896, 5, 1245198, 720896, 5, 1179662, 65536, 0, 1114126, 0, 5, 1048590, 131072, 5, 1048591, 262144, 5, 983055, 0, 5, 917519, 65536, 2, 851983, 720896, 5, 786447, 720896, 5, 720911, 720896, 5, 655375, 720896, 5, 655376, 720896, 5, 720912, 720896, 5, 786448, 720896, 5, 851984, 720896, 5, 917520, 65536, 2, 983056, 262144, 5, 1048592, 262144, 5, 1114128, 65536, 5, 1114127, 131072, 5, 1179663, 65536, 0, 1245199, 720896, 5, 1245200, 720896, 5, 1179664, 65536, 0, 1179665, 393216, 2, 1114129, 0, 0, 1048593, 131072, 5, 983057, 0, 2, 917521, 393216, 1, 851985, 720896, 5, 786449, 720896, 5, 720913, 720896, 5, 655377, 720896, 5, 589841, 720896, 5, 589842, 720896, 5, 524306, 720896, 5, 524307, 720896, 5, 458771, 720896, 5, 458772, 720896, 5, 393236, 720896, 5, 524308, 720896, 5, 589844, 720896, 5, 589843, 720896, 5, 655379, 720896, 5, 655378, 720896, 5, 720914, 720896, 5, 786450, 720896, 5, 851986, 720896, 5, 917522, 720896, 5, 983058, 393216, 1, 1048594, 0, 1, 1114130, 393216, 2, 1179666, 720896, 5, 1245202, 720896, 5, 1245201, 720896, 5, 1310738, 720896, 5, 1245203, 720896, 5, 1179667, 720896, 5, 1114131, 720896, 5, 1048595, 720896, 5, 983059, 720896, 5, 917523, 720896, 5, 851987, 720896, 5, 786451, 720896, 5, 720915, 720896, 5, 720916, 720896, 5, 655380, 720896, 5, 786452, 720896, 5, 851988, 720896, 5, 917524, 720896, 5, 983060, 720896, 5, 1048596, 720896, 5, 1114132, 720896, 5, 917525, 720896, 5, 851989, 720896, 5, 1376263, 655360, 11, 1376245, 655360, 11, 655364, 655360, 11, 524299, 655360, 11, 589847, 655360, 11, 65557, 655360, 11, -786415, 655360, 11, 1441782, 655360, 12, 1441783, 655360, 12, 1441784, 655360, 12, 1441785, 655360, 12, 1441786, 655360, 12, 1441787, 655360, 12, 1441788, 655360, 12, 1441789, 655360, 12, 1441790, 655360, 12, 1441791, 655360, 12, 1376256, 655360, 12, 1376257, 655360, 12, 1376258, 655360, 12, 1376259, 655360, 12, 1376260, 655360, 12, 1376261, 589824, 12, 1376262, 655360, 12, 1376264, 655360, 12, 1376265, 655360, 12, 1376266, 655360, 12, 1376267, 655360, 12, 1376268, 655360, 12, 1376269, 655360, 12, 1376270, 655360, 12, 1376271, 655360, 12, 1376272, 655360, 12, 1376276, 655360, 12, 1376278, 655360, 12, 1376279, 655360, 12, 1376280, 655360, 12, 1376281, 655360, 12, 1310745, 655360, 12, 1245209, 655360, 12, 1179673, 655360, 12, 1114137, 655360, 12, 1048601, 655360, 12, 983065, 655360, 12, 917529, 655360, 12, 851993, 655360, 12, 786457, 655360, 12, 720921, 655360, 12, 655385, 655360, 12, 589849, 655360, 12, 524313, 655360, 12, 458777, 655360, 12, 393241, 655360, 12, 327705, 655360, 12, 262169, 655360, 12, 196633, 655360, 12, 131097, 655360, 12, -983040, 1310720, 13, -983039, 1310720, 13, -1048575, 1310720, 12, -1048576, 1310720, 12, -1114112, 1310720, 11, -1114111, 1310720, 11, -1048577, 1245184, 18, -983041, 1245184, 19, -917505, 1245184, 20, -1048578, 1179648, 18, -983042, 1179648, 19, -917506, 1179648, 20, -1048579, 1179648, 18, -983043, 1179648, 19, -917507, 1179648, 20, -1048580, 1179648, 18, -983044, 1179648, 19, -917508, 1179648, 20, -1048581, 1179648, 18, -983045, 1179648, 19, -917509, 1179648, 20, -1048582, 1179648, 18, -983046, 1179648, 19, -917510, 1179648, 20, -1048583, 1179648, 18, -983047, 1179648, 19, -917511, 1179648, 20, -1114109, 1179648, 18, -1048573, 1179648, 19, -983037, 1179648, 20, -1114108, 1179648, 18, -1048572, 1179648, 19, -983036, 1179648, 20, -1114107, 1179648, 18, -1048571, 1179648, 19, -983035, 1179648, 20, -1114106, 1179648, 18, -1048570, 1179648, 19, -983034, 1179648, 20, -1114105, 1179648, 18, -1048569, 1179648, 19, -983033, 1179648, 20, -1114104, 1179648, 18, -1048568, 1179648, 19, -983032, 1179648, 20, -1114103, 1245184, 18, -1048567, 1245184, 19, -983031, 1245184, 20, -1048584, 1114112, 18, -983048, 1114112, 19, -917512, 1114112, 20, -1114110, 1114112, 18, -1048574, 1114112, 19, -983038, 1114112, 20, -1114120, 917504, 19, -1179656, 917504, 19, -1245192, 917504, 19, -1310728, 917504, 19, -1376264, 917504, 19, -1441800, 917504, 19, -1507336, 917504, 18, -1572871, 917504, 18, -1638406, 917504, 18, -1703936, 1048576, 18, -1638397, 1048576, 18, -1572860, 1048576, 18, -1507321, 1048576, 18, -1441783, 1048576, 18, -1441784, 983040, 18, -1507323, 983040, 18, -1507322, 983040, 18, -1638398, 983040, 18, -1638399, 983040, 18, -1638401, 983040, 18, -1638402, 983040, 18, -1638403, 983040, 18, -1638404, 983040, 18, -1638405, 983040, 18, -1507335, 851968, 21, -1572870, 851968, 21, -1638400, 917504, 21, -1572861, 917504, 21, -1507324, 917504, 21, -1441785, 917504, 21, -1376247, 1048576, 19, -1310711, 1048576, 19, -1245175, 1048576, 19, -1179639, 1048576, 19, -1310718, 65536, 20, -1376254, 65536, 19, -1441790, 65536, 19, -1507326, 327680, 20, -1572862, 131072, 18, -1572863, 65536, 18, -1572864, 65536, 18, -1507329, 327680, 20, -1572865, 131072, 18, -1572866, 65536, 18, -1572867, 65536, 18, -1572868, 65536, 18, -1572869, 0, 18, -1507333, 393216, 20, -1507334, 0, 18, -1441798, 393216, 20, -1441799, 0, 18, -1376263, 0, 19, -1310727, 0, 19, -1245191, 0, 20, -1179655, 0, 23, -1114119, 131072, 23, -1114118, 0, 23, -1179654, 0, 20, -1245190, 393216, 19, -1310726, 65536, 19, -1376262, 65536, 19, -1376261, 65536, 19, -1441797, 65536, 19, -1441796, 65536, 19, -1507332, 65536, 19, -1507331, 65536, 19, -1441795, 65536, 19, -1376259, 65536, 19, -1376260, 65536, 19, -1310724, 65536, 19, -1310725, 65536, 19, -1245189, 65536, 19, -1179653, 65536, 20, -1114117, 0, 23, -1114116, 0, 23, -1179652, 65536, 20, -1245188, 65536, 19, -1245187, 65536, 19, -1310723, 65536, 22, -1310722, 65536, 19, -1376258, 65536, 19, -1441794, 65536, 19, -1507330, 65536, 19, -1441793, 65536, 19, -1376257, 65536, 19, -1310721, 65536, 19, -1245185, 65536, 19, -1245186, 65536, 19, -1179650, 65536, 20, -1179651, 65536, 20, -1114115, 0, 23, -1114114, 0, 23, -1114113, 0, 23, -1179649, 65536, 20, -1245184, 65536, 20, -1310720, 65536, 19, -1376256, 65536, 19, -1441792, 65536, 19, -1507328, 65536, 19, -1507327, 65536, 19, -1441791, 65536, 19, -1376255, 65536, 19, -1310719, 327680, 19, -1245183, 131072, 20, -1179647, 196608, 23, -1179648, 0, 23, -1179646, 0, 23, -1245182, 0, 23, -1245181, 0, 23, -1310717, 65536, 20, -1376253, 65536, 19, -1441789, 327680, 20, -1507325, 131072, 18, -1441788, 65536, 18, -1376252, 65536, 19, -1310716, 65536, 20, -1245180, 262144, 23, -1179644, 0, 23, -1179645, 0, 23, -1179643, 0, 23, -1245179, 0, 23, -1310715, 131072, 20, -1376251, 131072, 19, -1441787, 131072, 18, -1441786, 262144, 23, -1376250, 0, 23, -1310714, 0, 23, -1245178, 0, 23, -1179642, 0, 23, -1179641, 0, 23, -1245177, 0, 23, -1310713, 65536, 23, -1376249, 0, 23, -1376248, 0, 23, -1310712, 0, 23, -1245176, 196608, 23, -1179640, 0, 23, -917513, 786432, 8, -917514, 786432, 8, -917515, 786432, 8, -917516, 786432, 8, -917517, 720896, 8, -983053, 720896, 7, -1048589, 720896, 6, -1048588, 1114112, 8, -1114124, 720896, 6, -1114123, 1114112, 8, -1179659, 720896, 7, -1245195, 720896, 7, -1310731, 720896, 7, -1376267, 1114112, 7, -1376268, 720896, 8, -1441804, 720896, 7, -1507340, 1114112, 7, -1507341, 786432, 8, -1507342, 786432, 8, -1507343, 720896, 8, -1572879, 1114112, 7, -1572880, 786432, 8, -1572881, 786432, 8, -1507347, 786432, 8, -1441813, 786432, 8, -1441814, 786432, 8, -1441815, 786432, 8, -1441816, 786432, 8, -720917, 786432, 8, -589806, 786432, 8, -983025, 786432, 8, -983026, 786432, 8, -983027, 786432, 8, -983028, 786432, 8, -983029, 786432, 8, -983030, 786432, 8, -983024, 1114112, 7, -589805, 1114112, 7, -655343, 1114112, 7, -720880, 1114112, 7, -1572882, 1048576, 7, -1507348, 1048576, 7, -1441817, 1048576, 7, -851988, 1048576, 7, -720918, 1048576, 7, -589847, 1048576, 7, -458776, 1048576, 7, -393241, 1048576, 7, -262170, 1048576, 7, -917488, 1114112, 8, -65517, 1114112, 8, 131090, 1114112, 8, 196625, 1114112, 8, 262160, 1114112, 8, 327694, 1114112, 8, 393229, 1114112, 8, 458764, 1114112, 8, 524292, 1114112, 8, 589826, 1114112, 8, 655361, 1114112, 8, 786432, 1114112, 8, 917503, 1114112, 8, 983038, 1114112, 8, 1114107, 1114112, 8, -1376281, 851968, 7, -1310745, 851968, 7, -917523, 851968, 7, -786452, 851968, 7, -655382, 851968, 7, -524311, 851968, 7, -196634, 851968, 7, -131098, 851968, 7, -65562, 851968, 7, -26, 851968, 7, 65510, 851968, 7, -327705, 851968, 7, 196583, 851968, 7, 262119, 851968, 7, 327655, 851968, 7, 720879, 851968, 7, 786415, 851968, 7, 851951, 851968, 7, 1048571, 720896, 7, 720896, 720896, 7, 18, 720896, 7, 65554, 720896, 7, -131053, 720896, 7, -196589, 720896, 7, -262125, 720896, 7, -327661, 720896, 7, -393197, 720896, 7, -458733, 720896, 7, -524269, 720896, 7, -786417, 720896, 7, -851953, 720896, 7, -720881, 0, 12, -655344, 720896, 8, -589807, 720896, 8, -917489, 720896, 6, -65518, 720896, 6, 131089, 720896, 6, 196624, 720896, 6, 262158, 720896, 6, 327693, 720896, 6, 393228, 720896, 6, 458756, 720896, 6, 524290, 720896, 6, 589825, 720896, 6, 655360, 720896, 6, 851967, 720896, 6, 917502, 720896, 6, 983035, 720896, 6, 983036, 786432, 6, 983037, 786432, 6, 655342, 786432, 6, 1114099, 786432, 6, 1114100, 786432, 6, 1114101, 786432, 6, 1114102, 786432, 6, 1114103, 786432, 6, 1114104, 786432, 6, 1114105, 786432, 6, 1114106, 786432, 6, 393192, 786432, 6, -1179671, 786432, 6, -1179670, 786432, 6, -1245209, 1048576, 8, -1179672, 1048576, 8, 131046, 1048576, 8, 393191, 1048576, 8, 458729, 1048576, 8, 524266, 1048576, 8, 589803, 1048576, 8, 655341, 1048576, 8, 917487, 1048576, 8, 1114098, 1048576, 8, 1048561, 1048576, 8, 983024, 1048576, 8, 589804, 786432, 6, 589805, 851968, 6, 655343, 851968, 6, 393193, 851968, 6, 458730, 851968, 6, 524267, 851968, 6, 131047, 851968, 6, -1179669, 851968, 6, -1114132, 851968, 6, -983059, 851968, 6, -1048596, 851968, 7, -1114133, 1048576, 8, -983060, 1048576, 8, -1245208, 851968, 6, -1441812, 851968, 8, -1507346, 851968, 8, 458757, 786432, 6, 458758, 786432, 6, 458761, 786432, 6, 458762, 786432, 6, 458763, 786432, 6, 262159, 786432, 6, 524291, 786432, 6, 983025, 851968, 6, 1048562, 851968, 6, 917488, 851968, 6, 393205, 131072, 11, 327669, 262144, 10, 262133, 196608, 8, 196597, 196608, 8, 131061, 196608, 8, 65525, 196608, 8, -11, 196608, 8, -65547, 196608, 8, -131083, 196608, 8, -196619, 196608, 8, -262155, 262144, 7, -327691, 131072, 12, -393227, 262144, 12, -458763, 262144, 12, -524299, 131072, 11, -589835, 0, 12, -655371, 262144, 12, -720907, 196608, 12, -786443, 131072, 11, -851979, 196608, 11, -851980, 196608, 11, -851981, 196608, 11, -851982, 131072, 11, -917518, 196608, 11, -983054, 262144, 12, -1048590, 262144, 12, -1114126, 196608, 11, -1179662, 196608, 11, -1245198, 262144, 12, -1310734, 262144, 12, -1376270, 131072, 11, -1441806, 65536, 12, -1441807, 131072, 12, -1441808, 262144, 12, -1507344, 196608, 11, -1507345, 262144, 12, -1441809, 262144, 12, -1441810, 262144, 12, -1441811, 65536, 12, -1376275, 262144, 12, -1376276, 262144, 12, -1376277, 196608, 12, -1376278, 131072, 11, -1376279, 262144, 12, -1376280, 196608, 12, -1310744, 131072, 12, -1310743, 262144, 12, -1245207, 196608, 12, -1245206, 131072, 12, -1310742, 262144, 12, -1310741, 262144, 12, -1245205, 262144, 12, -1245204, 196608, 12, -1310740, 65536, 12, -1310739, 131072, 11, -1245203, 196608, 12, -1179667, 131072, 11, -1179668, 131072, 12, -1114131, 131072, 11, -1048595, 196608, 11, -1048594, 131072, 12, -1114130, 65536, 12, -1179666, 131072, 12, -1245202, 196608, 12, -1310738, 262144, 12, -1376274, 196608, 12, -1376273, 131072, 11, -1310737, 131072, 11, -1245201, 196608, 11, -1179665, 262144, 12, -1114129, 0, 12, -1048593, 262144, 12, -983057, 262144, 12, -983058, 131072, 11, -917522, 196608, 11, -851986, 196608, 11, -851987, 851968, 8, -786451, 196608, 11, -720915, 262144, 12, -720916, 851968, 8, -655380, 131072, 11, -655381, 65536, 12, -589845, 65536, 12, -589846, 851968, 8, -524310, 262144, 12, -458774, 196608, 12, -458775, 851968, 8, -393239, 262144, 12, -393240, 851968, 8, -327704, 131072, 12, -262168, 196608, 11, -262169, 851968, 8, -196633, 262144, 12, -131097, 196608, 12, -65561, 65536, 12, -25, 196608, 11, 65511, 196608, 11, 65512, 0, 12, -24, 196608, 11, -65560, 262144, 12, -131096, 196608, 11, -196632, 196608, 11, -196631, 131072, 12, -262167, 262144, 12, -327703, 196608, 11, -327702, 65536, 12, -393238, 131072, 12, -393237, 196608, 11, -458773, 196608, 11, -524309, 196608, 11, -524308, 196608, 12, -589844, 65536, 12, -589843, 262144, 12, -655379, 131072, 12, -655378, 196608, 12, -720914, 0, 12, -786450, 262144, 12, -786449, 131072, 12, -851985, 196608, 11, -917521, 131072, 12, -917520, 262144, 12, -983056, 196608, 11, -1048592, 262144, 12, -1114128, 131072, 12, -1179664, 196608, 11, -1245200, 131072, 11, -1310736, 196608, 11, -1376272, 65536, 12, -1376271, 0, 12, -1310735, 0, 12, -1245199, 262144, 12, -1179663, 131072, 12, -1114127, 262144, 12, -1048591, 131072, 11, -983055, 0, 12, -917519, 0, 12, -851983, 262144, 12, -851984, 262144, 12, -786448, 131072, 11, -720912, 65536, 12, -720913, 196608, 11, -655377, 262144, 12, -589841, 262144, 12, -589842, 262144, 12, -524306, 262144, 12, -524307, 262144, 12, -458771, 131072, 11, -458772, 196608, 12, -393236, 196608, 11, -327700, 0, 12, -327701, 131072, 12, -262165, 196608, 11, -262166, 0, 12, -196630, 65536, 12, -131094, 131072, 12, -131095, 0, 12, -65559, 131072, 12, -23, 262144, 12, 65513, 131072, 11, 131049, 131072, 11, 131048, 196608, 12, 196584, 196608, 12, 262120, 196608, 11, 327656, 262144, 12, 327657, 196608, 11, 262121, 196608, 12, 196585, 262144, 12, 196586, 262144, 12, 131050, 131072, 11, 65514, 131072, 12, -22, 196608, 11, -65558, 262144, 12, -65557, 0, 12, -131093, 262144, 12, -196629, 0, 12, -196628, 65536, 12, -262164, 131072, 11, -262163, 262144, 12, -327699, 0, 12, -393235, 131072, 11, -393234, 65536, 12, -458770, 262144, 12, -458769, 0, 12, -524305, 0, 12, -524304, 196608, 11, -589840, 0, 12, -655376, 131072, 11, -655375, 196608, 11, -720911, 131072, 11, -786447, 196608, 11, -786446, 196608, 11, -720910, 196608, 11, -655374, 262144, 12, -589838, 196608, 11, -589839, 262144, 12, -524303, 131072, 12, -458767, 262144, 12, -458768, 262144, 12, -393232, 262144, 12, -393233, 131072, 11, -327697, 262144, 12, -327698, 196608, 12, -262162, 131072, 12, -196626, 196608, 12, -196627, 262144, 12, -131091, 262144, 12, -131092, 196608, 11, -65556, 196608, 11, -20, 262144, 12, -21, 131072, 11, 65515, 65536, 12, 131051, 131072, 11, 196587, 262144, 12, 262123, 131072, 11, 262122, 196608, 11, 327658, 0, 12, 393194, 262144, 12, 393195, 262144, 12, 327659, 262144, 12, 327660, 262144, 12, 262124, 65536, 12, 196588, 262144, 12, 131052, 0, 12, 65516, 196608, 11, 65517, 196608, 11, -19, 262144, 12, -65555, 262144, 12, -65554, 0, 12, -131090, 131072, 11, -131089, 196608, 11, -196625, 262144, 12, -262161, 196608, 12, -262160, 131072, 11, -327696, 65536, 12, -327695, 196608, 12, -393231, 196608, 11, -393230, 0, 12, -458766, 65536, 12, -524302, 65536, 12, -524301, 65536, 12, -589837, 65536, 12, -655373, 131072, 11, -720909, 131072, 11, -786445, 131072, 12, -786444, 131072, 12, -720908, 196608, 11, -655372, 196608, 11, -589836, 196608, 12, -524300, 196608, 11, -458764, 131072, 11, -458765, 196608, 11, -393229, 196608, 12, -327693, 131072, 12, -327694, 196608, 12, -262158, 196608, 12, -262159, 131072, 11, -196623, 131072, 12, -196624, 196608, 12, -131088, 0, 12, -65552, 131072, 11, -65553, 262144, 12, -17, 131072, 12, -18, 196608, 11, 65518, 131072, 12, 131054, 0, 12, 131053, 262144, 12, 196589, 196608, 12, 262125, 131072, 12, 327661, 0, 12, 393197, 131072, 11, 393196, 196608, 11, 458732, 196608, 11, 458731, 131072, 11, 524268, 196608, 11, 524269, 196608, 11, 458733, 131072, 12, 458734, 262144, 12, 393198, 196608, 11, 327662, 196608, 11, 262126, 0, 12, 196590, 196608, 12, 196591, 262144, 12, 131055, 262144, 12, 65519, 0, 12, 65520, 196608, 12, -16, 196608, 12, -15, 262144, 12, -65551, 0, 12, -131087, 131072, 12, -131086, 0, 12, -196622, 262144, 12, -196621, 0, 12, -262157, 262144, 12, -262156, 131072, 12, -327692, 196608, 11, -393228, 196608, 11, -196620, 65536, 12, -131084, 262144, 12, -131085, 131072, 12, -65549, 0, 12, -65550, 262144, 12, -14, 65536, 12, 65522, 65536, 12, 65521, 65536, 12, 131057, 131072, 12, 131056, 196608, 11, 196592, 262144, 12, 262128, 131072, 12, 262127, 196608, 12, 327663, 262144, 12, 393199, 262144, 12, 458735, 65536, 12, 524271, 131072, 12, 524270, 262144, 12, 589806, 131072, 11, 589807, 262144, 12, 589808, 196608, 12, 524272, 196608, 11, 458736, 262144, 12, 393200, 131072, 11, 327664, 262144, 12, 327665, 131072, 11, 262129, 262144, 12, 196593, 65536, 12, 196594, 262144, 12, 131058, 196608, 11, 131059, 0, 12, 65523, 131072, 11, -13, 262144, 12, -12, 196608, 12, -65548, 196608, 11, 65524, 196608, 12, 131060, 65536, 12, 196596, 196608, 11, 196595, 131072, 11, 262131, 131072, 12, 262130, 65536, 12, 327666, 262144, 12, 393202, 131072, 11, 393201, 196608, 11, 458737, 0, 12, 524273, 196608, 11, 589809, 65536, 12, 655345, 131072, 11, 655344, 262144, 12, 720880, 131072, 11, 786416, 196608, 11, 851952, 0, 12, 851953, 0, 12, 786417, 262144, 12, 720881, 131072, 12, 720882, 196608, 11, 655346, 131072, 11, 589810, 196608, 11, 524274, 0, 12, 458738, 131072, 12, 458739, 131072, 12, 393203, 262144, 12, 327667, 262144, 12, 327668, 131072, 12, 262132, 196608, 11, 393204, 262144, 12, 458740, 0, 12, 524276, 196608, 11, 524275, 196608, 12, 589811, 262144, 12, 655347, 0, 12, 720883, 196608, 11, 786419, 0, 12, 786418, 262144, 12, 851954, 262144, 12, 917490, 131072, 11, 917489, 0, 12, 983026, 0, 12, 983027, 196608, 12, 917491, 131072, 12, 851955, 131072, 11, 851956, 131072, 11, 786420, 262144, 12, 720884, 262144, 12, 655348, 0, 12, 589812, 0, 12, 589813, 0, 12, 524277, 0, 12, 458741, 65536, 12, 458742, 0, 12, 393206, 196608, 12, 327670, 131072, 10, 262134, 262144, 12, 196598, 0, 12, 131062, 196608, 12, 65526, 262144, 12, -10, 131072, 11, -65546, 262144, 12, -131082, 196608, 11, -196618, 262144, 12, -262154, 458752, 10, -327690, 196608, 8, -393226, 262144, 7, -458762, 196608, 11, -524298, 131072, 11, -589834, 262144, 12, -655370, 131072, 12, -720906, 262144, 12, -786442, 65536, 12, -851978, 196608, 11, -851977, 131072, 12, -786441, 131072, 12, -720905, 196608, 12, -655369, 262144, 12, -589833, 196608, 12, -524297, 0, 12, -458761, 262144, 12, -393225, 65536, 10, -327689, 262144, 12, -262153, 65536, 12, -196617, 131072, 11, -131081, 131072, 12, -65545, 131072, 11, -9, 262144, 12, 65527, 262144, 12, 131063, 131072, 12, 196599, 262144, 12, 262135, 262144, 12, 327671, 196608, 11, 393207, 262144, 12, 458743, 131072, 11, 524279, 262144, 12, 524278, 262144, 12, 589814, 131072, 11, 655350, 131072, 11, 655349, 196608, 11, 720885, 0, 12, 786421, 65536, 12, 851957, 131072, 12, 917493, 65536, 12, 917492, 131072, 12, 983028, 131072, 11, 1048564, 131072, 11, 1048563, 0, 12, 1048565, 262144, 12, 983029, 131072, 12, 983030, 0, 12, 917494, 0, 12, 851958, 196608, 12, 786422, 262144, 12, 720886, 0, 12, 720887, 65536, 12, 655351, 196608, 11, 589815, 65536, 12, 589816, 131072, 12, 524280, 262144, 12, 458744, 196608, 12, 393208, 262144, 12, 327672, 131072, 12, 262136, 0, 12, 196600, 131072, 11, 131064, 262144, 12, 65528, 196608, 11, -8, 262144, 12, -65544, 262144, 12, -131080, 196608, 12, -196616, 131072, 12, -262152, 196608, 11, -327688, 65536, 12, -393224, 65536, 10, -458760, 196608, 11, -524296, 65536, 12, -589832, 131072, 11, -655368, 196608, 11, -720904, 196608, 11, -786440, 262144, 12, -851976, 131072, 11, -851975, 0, 12, -786439, 65536, 12, -720903, 131072, 11, -655367, 0, 12, -589831, 262144, 12, -524295, 131072, 12, -458759, 65536, 12, -393223, 65536, 10, -327687, 0, 12, -262151, 196608, 11, -196615, 262144, 12, -131079, 131072, 12, -65543, 196608, 11, -7, 65536, 12, 65529, 65536, 12, 131065, 196608, 12, 196601, 131072, 11, 262137, 131072, 11, 327673, 65536, 12, 393209, 262144, 12, 458745, 196608, 12, 524281, 262144, 12, 589817, 262144, 12, 655353, 0, 12, 655352, 262144, 12, 720888, 0, 12, 786424, 196608, 12, 786423, 196608, 11, 851959, 65536, 12, 917495, 196608, 11, 983031, 196608, 11, 1048567, 131072, 12, 1048566, 196608, 11, 1048568, 0, 12, 983032, 65536, 12, 917496, 0, 12, 851960, 196608, 12, 851961, 0, 12, 786425, 196608, 12, 720889, 0, 12, 720890, 131072, 12, 655354, 131072, 11, 589818, 131072, 12, 524282, 262144, 12, 458746, 65536, 12, 393210, 262144, 12, 327674, 196608, 11, 262138, 262144, 12, 196602, 65536, 12, 131066, 262144, 12, 65530, 0, 12, -6, 131072, 11, -65542, 196608, 12, -131078, 196608, 11, -196614, 196608, 12, -262150, 131072, 12, -327686, 262144, 12, -393222, 65536, 10, -458758, 65536, 12, -524294, 196608, 11, -589830, 262144, 12, -655366, 262144, 12, -720902, 262144, 12, -786438, 131072, 11, -851974, 131072, 12, -851973, 262144, 12, -786437, 196608, 11, -720901, 131072, 12, -655365, 65536, 12, -589829, 262144, 12, -524293, 262144, 12, -458757, 131072, 12, -393221, 65536, 10, -327685, 196608, 12, -262149, 131072, 12, -196613, 131072, 11, -131077, 196608, 12, -65541, 262144, 12, -5, 0, 12, 65531, 131072, 12, 131067, 65536, 12, 196603, 262144, 12, 262139, 262144, 12, 327675, 196608, 11, 393211, 262144, 12, 458747, 262144, 12, 524283, 131072, 11, 589819, 65536, 12, 655355, 262144, 12, 720891, 0, 12, 786427, 0, 12, 786426, 262144, 12, 851962, 0, 12, 917498, 262144, 12, 917497, 65536, 12, 983033, 196608, 12, 1048569, 65536, 12, 1048570, 131072, 12, 983034, 196608, 12, 917499, 262144, 12, 851963, 262144, 12, 851964, 0, 12, 786428, 262144, 12, 720892, 0, 12, 655356, 196608, 12, 589820, 131072, 11, 524284, 196608, 12, 458748, 131072, 11, 393212, 196608, 11, 327676, 0, 12, 262140, 196608, 12, 196604, 196608, 12, 131068, 262144, 12, 65532, 196608, 11, -4, 262144, 12, -65540, 65536, 12, -131076, 65536, 12, -196612, 262144, 12, -262148, 262144, 12, -327684, 196608, 11, -393220, 65536, 10, -458756, 0, 12, -524292, 65536, 12, -589828, 0, 12, -655364, 262144, 12, -720900, 196608, 11, -786436, 0, 12, -851972, 131072, 11, -851971, 262144, 12, -786435, 131072, 11, -720899, 262144, 12, -655363, 196608, 12, -589827, 131072, 12, -524291, 0, 12, -458755, 131072, 11, -393219, 65536, 10, -327683, 131072, 11, -262147, 131072, 12, -196611, 262144, 12, -131075, 262144, 12, -65539, 196608, 11, -3, 131072, 12, 65533, 262144, 12, 131069, 196608, 11, 196605, 65536, 12, 262141, 0, 12, 327677, 196608, 11, 393213, 131072, 11, 458749, 262144, 12, 524285, 262144, 12, 589821, 262144, 12, 655357, 262144, 12, 720893, 131072, 11, 786429, 65536, 12, 851965, 65536, 12, 917501, 196608, 11, 917500, 196608, 12, 851966, 131072, 12, 786430, 65536, 12, 720894, 0, 12, 655358, 131072, 11, 589822, 65536, 12, 524286, 131072, 12, 458750, 196608, 11, 393214, 131072, 12, 327678, 131072, 12, 262142, 196608, 11, 196606, 262144, 12, 131070, 196608, 11, 65534, 0, 12, -2, 196608, 12, -65538, 196608, 12, -131074, 65536, 12, -196610, 262144, 12, -262146, 131072, 12, -327682, 196608, 11, -393218, 65536, 10, -458754, 262144, 12, -524290, 262144, 12, -589826, 262144, 12, -655362, 262144, 12, -720898, 131072, 12, -786434, 0, 12, -851970, 65536, 12, -851969, 196608, 11, -786433, 196608, 12, -720897, 131072, 11, -655361, 65536, 12, -589825, 262144, 12, -524289, 65536, 12, -458753, 262144, 12, -393217, 65536, 10, -327681, 196608, 11, -262145, 196608, 12, -196609, 0, 12, -131073, 196608, 12, -65537, 262144, 12, -1, 262144, 12, 65535, 0, 12, 131071, 131072, 12, 196607, 196608, 11, 262143, 65536, 12, 327679, 131072, 11, 393215, 0, 12, 458751, 131072, 11, 524287, 131072, 12, 589823, 131072, 11, 655359, 131072, 12, 720895, 196608, 11, 786431, 131072, 12, 589824, 196608, 11, 524288, 0, 12, 458752, 131072, 11, 393216, 196608, 12, 327680, 196608, 12, 262144, 131072, 11, 196608, 262144, 12, 131072, 131072, 11, 65536, 0, 12, 0, 196608, 12, -65536, 196608, 11, -131072, 131072, 11, -196608, 131072, 11, -262144, 0, 9, -327680, 0, 8, -393216, 0, 8, -458752, 393216, 11, -524288, 0, 8, -589824, 0, 8, -655360, 0, 8, -720896, 0, 8, -786432, 0, 8, -851968, 0, 8, -917504, 0, 7, -917503, 131072, 7, -851967, 131072, 8, -786431, 131072, 8, -720895, 131072, 8, -655359, 131072, 8, -589823, 131072, 8, -524287, 131072, 8, -458751, 131072, 8, -393215, 131072, 8, -327679, 327680, 9, -262143, 65536, 9, -196607, 262144, 12, -131071, 131072, 12, -65535, 196608, 12, 1, 262144, 12, 65537, 196608, 11, 131073, 131072, 11, 196609, 196608, 11, 262145, 131072, 11, 327681, 262144, 12, 393217, 131072, 11, 458753, 196608, 11, 524289, 262144, 12, 458754, 65536, 12, 393218, 196608, 12, 327682, 131072, 12, 262146, 262144, 12, 196610, 262144, 12, 131074, 196608, 11, 65538, 65536, 12, 2, 65536, 12, -65534, 65536, 12, -131070, 262144, 12, -196606, 262144, 12, -262142, 65536, 9, -327678, 65536, 7, -393214, 196608, 11, -458750, 131072, 11, -524286, 65536, 12, -589822, 131072, 12, -655358, 65536, 12, -720894, 262144, 12, -786430, 262144, 12, -851966, 196608, 11, -917502, 65536, 12, -917501, 262144, 12, -851965, 196608, 11, -786429, 65536, 12, -720893, 196608, 12, -655357, 196608, 12, -589821, 196608, 11, -524285, 196608, 11, -458749, 262144, 12, -393213, 65536, 12, -327677, 65536, 7, -262141, 65536, 9, -196605, 196608, 12, -131069, 262144, 12, -65533, 262144, 12, 3, 262144, 12, 65539, 131072, 11, 131075, 196608, 12, 196611, 262144, 12, 262147, 196608, 11, 327683, 65536, 12, 393219, 131072, 12, 458755, 262144, 12, 393220, 196608, 11, 327684, 262144, 12, 262148, 196608, 11, 196612, 0, 12, 131076, 65536, 12, 65540, 131072, 12, 4, 196608, 11, -65532, 131072, 11, -131068, 262144, 12, -196604, 262144, 12, -262140, 65536, 9, -327676, 65536, 7, -393212, 196608, 11, -458748, 262144, 12, -524284, 196608, 11, -589820, 131072, 12, -655356, 262144, 12, -720892, 196608, 11, -786428, 65536, 12, -851964, 262144, 12, -917500, 262144, 12, -917499, 0, 12, -851963, 196608, 11, -786427, 131072, 12, -720891, 0, 12, -655355, 0, 12, -589819, 196608, 11, -524283, 262144, 12, -458747, 0, 12, -393211, 0, 12, -327675, 65536, 7, -262139, 393216, 8, -196603, 0, 8, -131067, 0, 8, -65531, 0, 8, 5, 0, 8, 65541, 0, 9, 131077, 65536, 12, 196613, 262144, 12, 262149, 262144, 12, 327685, 131072, 11, 393221, 131072, 11, 393222, 131072, 12, 327686, 262144, 12, 262150, 262144, 12, 196614, 0, 12, 131078, 131072, 11, 65542, 65536, 9, 6, 327680, 9, -65530, 131072, 8, -131066, 131072, 8, -196602, 131072, 8, -262138, 131072, 8, -327674, 131072, 7, -393210, 0, 12, -458746, 262144, 12, -524282, 262144, 12, -589818, 131072, 12, -655354, 262144, 12, -720890, 131072, 11, -786426, 131072, 11, -851962, 262144, 12, -917498, 196608, 11, -917497, 262144, 12, -851961, 0, 12, -786425, 196608, 12, -720889, 65536, 12, -655353, 262144, 12, -589817, 0, 12, -524281, 131072, 11, -458745, 262144, 12, -393209, 131072, 11, -327673, 131072, 11, -262137, 0, 12, -196601, 262144, 12, -131065, 196608, 11, -65529, 196608, 11, 7, 65536, 7, 65543, 393216, 8, 131079, 0, 8, 196615, 0, 8, 262151, 0, 8, 327687, 0, 8, 393223, 0, 9, 393224, 131072, 9, 327688, 131072, 8, 262152, 131072, 8, 196616, 131072, 8, 131080, 131072, 8, 65544, 131072, 8, 8, 131072, 7, -65528, 196608, 11, -131064, 65536, 12, -196600, 131072, 12, -262136, 196608, 12, -327672, 196608, 11, -393208, 262144, 12, -458744, 262144, 12, -524280, 0, 12, -589816, 262144, 12, -655352, 0, 12, -720888, 65536, 12, -786424, 131072, 11, -851960, 196608, 11, -917496, 196608, 11, -917495, 131072, 12, -851959, 131072, 11, -786423, 196608, 12, -720887, 131072, 11, -655351, 196608, 12, -589815, 196608, 11, -524279, 0, 12, -458743, 196608, 11, -393207, 65536, 12, -327671, 196608, 11, -262135, 131072, 11, -196599, 196608, 12, -131063, 65536, 12, -65527, 65536, 12, 9, 262144, 12, 65545, 196608, 12, 131081, 262144, 12, 196617, 262144, 12, 262153, 131072, 12, 327689, 262144, 12, 393225, 131072, 11, 393226, 196608, 11, 327690, 131072, 11, 262154, 196608, 11, 196618, 196608, 11, 131082, 131072, 12, 65546, 262144, 12, 10, 131072, 11, -65526, 196608, 11, -131062, 196608, 11, -196598, 262144, 12, -262134, 0, 12, -327670, 0, 12, -393206, 131072, 12, -458742, 131072, 12, -524278, 65536, 12, -589814, 131072, 11, -655350, 262144, 12, -720886, 131072, 11, -786422, 0, 12, -851958, 262144, 12, -917494, 131072, 11, -917493, 131072, 12, -851957, 196608, 11, -786421, 131072, 12, -720885, 196608, 11, -655349, 262144, 12, -589813, 131072, 12, -524277, 0, 12, -458741, 196608, 11, -393205, 131072, 11, -327669, 131072, 12, -262133, 196608, 12, -196597, 262144, 12, -131061, 65536, 12, -65525, 262144, 12, 11, 262144, 12, 65547, 262144, 12, 131083, 262144, 12, 196619, 196608, 11, 262155, 131072, 12, 327691, 131072, 12, 393227, 65536, 12, 327692, 196608, 11, 262156, 131072, 11, 196620, 131072, 12, 131084, 131072, 11, 65548, 131072, 12, 12, 262144, 12, -65524, 262144, 12, -131060, 131072, 12, -196596, 196608, 11, -262132, 131072, 11, -327668, 262144, 12, -393204, 196608, 11, -458740, 262144, 12, -524276, 0, 12, -589812, 262144, 12, -655348, 65536, 12, -720884, 65536, 12, -786420, 0, 12, -851956, 131072, 11, -917492, 65536, 12, -917491, 262144, 12, -851955, 0, 12, -786419, 0, 12, -720883, 65536, 12, -655347, 262144, 12, -589811, 262144, 12, -524275, 262144, 12, -458739, 196608, 11, -393203, 196608, 11, -327667, 65536, 12, -262131, 262144, 12, -196595, 196608, 11, -131059, 131072, 12, -65523, 262144, 12, 13, 0, 12, 65549, 131072, 12, 131085, 131072, 12, 196621, 196608, 11, 262157, 131072, 11, 196622, 65536, 12, 131086, 65536, 12, 65550, 131072, 11, 14, 131072, 12, -65522, 131072, 11, -131058, 196608, 12, -196594, 262144, 12, -262130, 196608, 11, -327666, 131072, 11, -393202, 131072, 12, -458738, 0, 12, -524274, 196608, 11, -589810, 0, 12, -655346, 262144, 12, -720882, 196608, 11, -786418, 131072, 12, -851954, 196608, 12, -917490, 196608, 11, -655345, 0, 12, -589809, 0, 12, -524273, 262144, 12, -458737, 131072, 11, -393201, 262144, 12, -327665, 196608, 11, -262129, 196608, 12, -196593, 262144, 12, -131057, 196608, 11, -65521, 262144, 12, 15, 262144, 12, 65551, 131072, 11, 131087, 196608, 11, 196623, 65536, 12, 131088, 196608, 12, 65552, 0, 12, 16, 65536, 12, -65520, 196608, 11, -131056, 131072, 11, -196592, 262144, 12, -262128, 131072, 12, -327664, 65536, 12, -393200, 262144, 12, -458736, 65536, 12, -524272, 196608, 11, -589808, 0, 12, -524271, 262144, 12, -458735, 262144, 12, -393199, 262144, 12, -327663, 262144, 12, -262127, 196608, 11, -196591, 65536, 12, -131055, 196608, 12, -65519, 131072, 12, 17, 262144, 12, 65553, 196608, 11, -131054, 131072, 12, -196590, 65536, 12, -262126, 131072, 11, -327662, 262144, 12, -393198, 0, 12, -458734, 196608, 11, -524270, 262144, 12, -1441805, 262144, 12, -1376269, 131072, 11, -1310733, 262144, 12, -1245197, 262144, 12, -1179661, 262144, 12, -1114125, 262144, 12, -1179660, 0, 12, -1245196, 262144, 12, -1310732, 262144, 12, 917480, 655360, 12, 851944, 655360, 12, 786408, 655360, 12, 720872, 655360, 12, 655336, 655360, 12, 589800, 655360, 12, 524264, 655360, 12, 458728, 655360, 12, 458727, 655360, 12, 458726, 655360, 12, 393190, 655360, 12, 327654, 655360, 12, 262118, 655360, 12, 196582, 655360, 12, 196581, 655360, 12, 131045, 655360, 12, 65509, 655360, 12, -27, 655360, 12, -65563, 655360, 12, -131099, 655360, 12, -196635, 655360, 12, -262171, 655360, 12, -327707, 655360, 12, -393243, 655360, 12, -458779, 655360, 12, -524315, 655360, 12, -589851, 655360, 12, -655387, 655360, 12, -720923, 655360, 12, -786459, 655360, 12, -851995, 655360, 12, -917531, 655360, 12, -983067, 655360, 12, -1048603, 655360, 12, -1114139, 655360, 12, -1179675, 655360, 12, -1245211, 655360, 12, -1310747, 655360, 12, -1376283, 655360, 12, -1441819, 655360, 12, -1507355, 655360, 12, -1572891, 655360, 12, -1638427, 655360, 12, -1638428, 655360, 12, -1638429, 655360, 12, -1572893, 655360, 12, -1507357, 655360, 12, -1441821, 655360, 12, -1376285, 655360, 12, -1310749, 655360, 12, -1245213, 655360, 12, -1179677, 655360, 12, -1114141, 655360, 12, -1048605, 655360, 12, -983069, 655360, 12, -917533, 655360, 12, -851997, 655360, 12, -786461, 655360, 12, -720925, 655360, 12, -655389, 589824, 12, -589853, 655360, 12, -524317, 655360, 12, -458781, 458752, 12, -393245, 655360, 12, -327709, 655360, 12, -262173, 655360, 12, -196637, 655360, 12, -131101, 655360, 12, -65565, 655360, 12, -29, 655360, 12, 65507, 655360, 12, 131043, 655360, 12, 196579, 655360, 12, 262115, 655360, 12, 327651, 655360, 12, 393187, 655360, 12, 458723, 589824, 12, 524259, 655360, 12, 589795, 458752, 12, 655331, 655360, 12, 720867, 655360, 12, 786403, 655360, 12, 851939, 655360, 12, 917475, 655360, 12, 983011, 655360, 12, 1048547, 655360, 12, 1114083, 655360, 12, 1179619, 655360, 12, 1245155, 589824, 12, 1310691, 655360, 12, 1376227, 655360, 12, 1441763, 655360, 12, 1441764, 458752, 12, 1376228, 589824, 12, 1310692, 589824, 12, 1245156, 655360, 12, 1179620, 655360, 12, 1114084, 655360, 12, 1048548, 655360, 12, 983012, 655360, 12, 917476, 655360, 12, 851940, 655360, 12, 786404, 655360, 12, 720868, 655360, 12, 655332, 655360, 12, 589796, 655360, 12, 524260, 655360, 12, 458724, 655360, 12, 393188, 655360, 12, 327652, 655360, 12, 262116, 655360, 12, 196580, 655360, 12, 131044, 655360, 12, 65508, 655360, 12, -28, 655360, 12, -65564, 655360, 12, -131100, 655360, 12, -196636, 655360, 12, -262172, 655360, 12, -327708, 655360, 12, -393244, 655360, 12, -458780, 655360, 12, -524316, 655360, 12, -589852, 655360, 12, -655388, 655360, 12, -720924, 655360, 12, -786460, 655360, 12, -851996, 655360, 12, -917532, 655360, 12, -983068, 655360, 12, -1048604, 655360, 12, -1114140, 655360, 12, -1179676, 655360, 12, -1245212, 655360, 12, -1310748, 655360, 12, -1376284, 655360, 12, -1441820, 655360, 12, -1507356, 655360, 12, -1572892, 655360, 12, 262117, 655360, 12, 327653, 655360, 12, 393189, 655360, 12, 458725, 655360, 12, 524261, 458752, 12, 589797, 655360, 12, 655333, 655360, 12, 720869, 655360, 12, 786405, 655360, 12, 851941, 655360, 12, 917477, 655360, 12, 983013, 655360, 12, 1048549, 655360, 12, 1114085, 655360, 12, 1179621, 655360, 12, 1245157, 655360, 12, 1310693, 655360, 12, 1376229, 655360, 12, 1441765, 655360, 12, 1441766, 655360, 12, 1376230, 458752, 12, 1310694, 655360, 12, 1245158, 655360, 12, 1179622, 655360, 12, 1114086, 655360, 12, 1048550, 655360, 12, 983014, 655360, 12, 917478, 655360, 12, 851942, 655360, 12, 786406, 655360, 12, 720870, 655360, 12, 655334, 655360, 12, 589798, 655360, 12, 524262, 655360, 12, 524263, 655360, 12, 589799, 655360, 12, 655335, 655360, 12, 720871, 655360, 12, 786407, 655360, 12, 851943, 655360, 12, 917479, 655360, 12, 983015, 655360, 12, 1048551, 655360, 12, 1114087, 655360, 12, 1179623, 655360, 12, 1245159, 655360, 12, 1310695, 655360, 12, 1376231, 655360, 12, 1441767, 655360, 12, 1441768, 655360, 12, 1376232, 655360, 12, 1310696, 655360, 12, 1245160, 655360, 12, 1179624, 655360, 12, 1114088, 458752, 12, 1048552, 655360, 12, 983016, 655360, 12, 983017, 655360, 12, 917481, 655360, 12, 851945, 655360, 12, 786409, 655360, 12, 720873, 655360, 12, 655337, 655360, 12, 589801, 655360, 12, 524265, 655360, 12, 589802, 589824, 12, 655338, 655360, 12, 720874, 655360, 12, 786410, 655360, 12, 851946, 655360, 12, 917482, 655360, 12, 983018, 655360, 12, 1048554, 655360, 12, 1048553, 655360, 12, 1114089, 589824, 12, 1179625, 655360, 12, 1245161, 655360, 12, 1310697, 655360, 12, 1376233, 655360, 12, 1441769, 655360, 12, 1441770, 655360, 12, 1376234, 655360, 12, 1310698, 655360, 12, 1245162, 655360, 12, 1179626, 655360, 12, 1114090, 655360, 12, 1114091, 655360, 12, 1048555, 655360, 12, 983019, 655360, 12, 917483, 655360, 12, 851947, 655360, 12, 786411, 655360, 12, 720875, 655360, 12, 655339, 655360, 12, 655340, 458752, 12, 720876, 655360, 12, 786412, 655360, 12, 851948, 655360, 12, 917484, 655360, 12, 983020, 655360, 12, 1048556, 655360, 12, 1114092, 655360, 12, 1179628, 655360, 12, 1179627, 655360, 12, 1245163, 655360, 12, 1310699, 655360, 12, 1376235, 655360, 12, 1441771, 655360, 12, 1441772, 655360, 12, 1376236, 655360, 12, 1310700, 655360, 12, 1245164, 655360, 12, 1245165, 655360, 12, 1179629, 655360, 12, 1114093, 655360, 12, 1048557, 655360, 12, 983021, 655360, 12, 917485, 655360, 12, 851949, 655360, 12, 786413, 655360, 12, 720877, 655360, 12, 720878, 655360, 12, 786414, 655360, 12, 851950, 655360, 12, 917486, 655360, 12, 983022, 655360, 12, 1048558, 655360, 12, 1114094, 655360, 12, 1179630, 655360, 12, 1245166, 655360, 12, 1310702, 655360, 12, 1310701, 655360, 12, 1376237, 655360, 12, 1441773, 655360, 12, 1441774, 655360, 12, 1376238, 655360, 12, 1376239, 655360, 12, 1310703, 655360, 12, 1245167, 655360, 12, 1179631, 655360, 12, 1114095, 655360, 12, 1048559, 655360, 12, 983023, 655360, 12, 1048560, 655360, 12, 1114096, 589824, 12, 1179632, 655360, 12, 1245168, 655360, 12, 1310704, 655360, 12, 1376240, 655360, 12, 1441776, 655360, 12, 1441775, 655360, 12, 1441777, 655360, 12, 1376241, 655360, 12, 1310705, 655360, 12, 1245169, 589824, 12, 1179633, 655360, 12, 1114097, 655360, 12, 1179634, 655360, 12, 1245170, 655360, 12, 1310706, 655360, 12, 1376242, 589824, 12, 1441778, 655360, 12, 1441779, 655360, 12, 1376243, 655360, 12, 1310707, 655360, 12, 1245171, 655360, 12, 1179635, 655360, 12, 1179636, 655360, 12, 1245172, 655360, 12, 1310708, 655360, 12, 1376244, 655360, 12, 1441780, 655360, 12, 1441781, 655360, 12, 1310709, 655360, 12, 1245173, 655360, 12, 1179637, 655360, 12, 1179638, 655360, 12, 1245174, 655360, 12, 1310710, 655360, 12, 1376246, 655360, 12, 1376247, 655360, 12, 1310711, 589824, 12, 1245175, 655360, 12, 1179639, 655360, 12, 1179640, 655360, 12, 1245176, 655360, 12, 1310712, 655360, 12, 1376248, 655360, 12, 1376249, 655360, 12, 1310713, 655360, 12, 1245177, 655360, 12, 1179641, 655360, 12, 1179642, 655360, 12, 1245178, 655360, 12, 1310714, 655360, 12, 1376250, 655360, 12, 1376251, 655360, 12, 1310715, 655360, 12, 1245179, 655360, 12, 1179643, 655360, 12, 1179644, 655360, 12, 1114108, 655360, 12, 1048572, 655360, 12, 1048573, 655360, 12, 1114109, 655360, 12, 1179645, 655360, 12, 1245181, 655360, 12, 1245180, 589824, 12, 1310716, 589824, 12, 1376252, 655360, 12, 1376253, 655360, 12, 1310717, 655360, 12, 1310718, 655360, 12, 1245182, 655360, 12, 1179646, 655360, 12, 1114110, 655360, 12, 1048574, 655360, 12, 1048575, 655360, 12, 983039, 655360, 12, 917504, 655360, 12, 851968, 655360, 12, 851969, 655360, 12, 786433, 655360, 12, 720897, 655360, 12, 720898, 655360, 12, 655362, 589824, 12, 655363, 655360, 12, 589827, 655360, 12, 589828, 655360, 12, 589829, 655360, 12, 524293, 655360, 12, 524294, 589824, 12, 589830, 655360, 12, 655366, 655360, 12, 655365, 655360, 12, 720899, 655360, 12, 786435, 655360, 12, 786434, 655360, 12, 851970, 655360, 12, 917505, 655360, 12, 983040, 655360, 12, 1114111, 655360, 12, 1376254, 655360, 12, 1376255, 458752, 12, 1310720, 655360, 12, 1310721, 655360, 12, 1310722, 655360, 12, 1310723, 655360, 12, -1638426, 655360, 12, -1572890, 655360, 12, -1507354, 655360, 12, -1441818, 655360, 12, -1376282, 655360, 12, -1310746, 655360, 12, -1245210, 458752, 12, -1179674, 655360, 12, -1114138, 655360, 12, -1048602, 655360, 12, -983066, 655360, 12, -917530, 655360, 12, -851994, 655360, 12, -786458, 655360, 12, -720922, 655360, 12, -655386, 655360, 12, -589850, 655360, 12, -524314, 655360, 12, -458778, 655360, 12, -393242, 655360, 12, -327706, 655360, 12, -458777, 655360, 12, -524313, 655360, 12, -589849, 655360, 12, -655385, 655360, 12, -720921, 655360, 12, -786457, 655360, 12, -851993, 655360, 12, -917529, 458752, 12, -983065, 655360, 12, -1048601, 655360, 12, -1114137, 655360, 12, -1179673, 655360, 12, -1114136, 655360, 12, -1048600, 655360, 12, -983064, 655360, 12, -917528, 655360, 12, -851992, 655360, 12, -786456, 655360, 12, -720920, 655360, 12, -655384, 655360, 12, -589848, 655360, 12, -524312, 655360, 12, -655383, 655360, 12, -720919, 655360, 12, -786455, 655360, 12, -851991, 655360, 12, -917527, 655360, 12, -983063, 655360, 12, -1048599, 655360, 12, -1114135, 655360, 12, -1114134, 655360, 12, -1048598, 655360, 12, -983062, 655360, 12, -917526, 655360, 12, -851990, 458752, 12, -786454, 655360, 12, -786453, 655360, 12, -851989, 655360, 12, -917525, 655360, 12, -983061, 655360, 12, -1048597, 655360, 12, -917524, 655360, 12, -1507353, 655360, 12, -1572889, 655360, 12, -1638425, 655360, 12, -1638424, 655360, 12, -1572888, 655360, 12, -1507352, 655360, 12, -1507351, 655360, 12, -1572887, 655360, 12, -1638423, 655360, 12, -1638422, 655360, 12, -1572886, 655360, 12, -1507350, 655360, 12, -1507349, 458752, 12, -1572885, 655360, 12, -1638421, 655360, 12, -1638420, 655360, 12, -1572884, 655360, 12, -1572883, 655360, 12, -1638419, 655360, 12, -1638418, 655360, 12, -1638417, 655360, 12, -1638416, 655360, 12, -1638415, 655360, 12, -1638414, 655360, 12, -1703950, 655360, 12, -1572878, 655360, 12, -1572877, 655360, 12, -1638413, 655360, 12, -1638412, 655360, 12, -1572876, 655360, 12, -1572875, 655360, 12, -1638411, 655360, 12, -1638410, 655360, 12, -1572874, 655360, 12, -1507338, 655360, 12, -1507339, 458752, 12, -1441803, 655360, 12, -1441802, 655360, 12, -1376266, 655360, 12, -1310730, 655360, 12, -1245194, 655360, 12, -1179658, 655360, 12, -1114122, 655360, 12, -1048586, 655360, 12, -1048587, 655360, 12, -983051, 655360, 12, -983052, 655360, 12, -983050, 655360, 12, -983049, 655360, 12, -1048585, 655360, 12, -1114121, 655360, 12, -1179657, 655360, 12, -1245193, 655360, 12, -1310729, 655360, 12, -1376265, 655360, 12, -1441801, 655360, 12, -1507337, 655360, 12, -1572873, 655360, 12, -1638409, 655360, 12, -1638408, 655360, 12, -1572872, 655360, 12, -1638407, 655360, 12, -524266, 589824, 12, -589802, 655360, 12, -655338, 655360, 12, -720874, 655360, 12, -786410, 655360, 12, -851946, 655360, 12, -917482, 655360, 12, -983018, 655360, 12, -1048554, 655360, 12, -1114090, 655360, 12, -1179626, 655360, 12, -1245162, 655360, 12, -1310698, 655360, 12, -1376234, 589824, 12, -1441770, 655360, 12, -1507306, 655360, 12, -1572842, 655360, 12, -1638378, 655360, 12, -1703914, 655360, 12, -1703915, 655360, 12, -1703916, 655360, 12, -1703917, 655360, 12, -1703918, 589824, 12, -1703919, 655360, 12, -1703920, 655360, 12, -1703921, 655360, 12, -1703922, 655360, 12, -1703923, 655360, 12, -1703924, 458752, 12, -1703925, 655360, 12, -1703926, 458752, 12, -1703927, 655360, 12, -1703928, 655360, 12, -1703929, 655360, 12, -1703930, 655360, 12, -1703931, 655360, 12, -1703932, 655360, 12, -1703933, 655360, 12, -1703934, 655360, 12, -1703935, 655360, 12, -1769471, 655360, 12, -1638396, 655360, 12, -1638395, 655360, 12, -1572859, 655360, 12, -1572858, 655360, 12, -1638394, 655360, 12, -1638393, 655360, 12, -1572857, 655360, 12, -1572856, 655360, 12, -1638392, 655360, 12, -1638391, 655360, 12, -1572855, 655360, 12, -1507319, 655360, 12, -1507320, 655360, 12, -1507318, 655360, 12, -1572854, 655360, 12, -1638390, 655360, 12, -1638389, 655360, 12, -1572853, 655360, 12, -1507317, 655360, 12, -1441781, 655360, 12, -1441782, 655360, 12, -1376246, 655360, 12, -1310710, 655360, 12, -1245174, 655360, 12, -1179638, 655360, 12, -1114102, 655360, 12, -1048566, 655360, 12, -1048565, 655360, 12, -1114101, 655360, 12, -1179637, 655360, 12, -1245173, 655360, 12, -1310709, 655360, 12, -1376245, 655360, 12, -1376244, 655360, 12, -1441780, 655360, 12, -1507316, 655360, 12, -1572852, 655360, 12, -1638388, 655360, 12, -1638387, 655360, 12, -1572851, 655360, 12, -1507315, 655360, 12, -1441779, 655360, 12, -1376243, 655360, 12, -1310707, 655360, 12, -1310708, 655360, 12, -1245172, 655360, 12, -1179636, 655360, 12, -1114100, 655360, 12, -1048564, 655360, 12, -1048563, 655360, 12, -1114099, 655360, 12, -1179635, 655360, 12, -1245171, 655360, 12, -1245170, 655360, 12, -1310706, 655360, 12, -1376242, 655360, 12, -1441778, 655360, 12, -1507314, 655360, 12, -1572850, 655360, 12, -1638386, 655360, 12, -1638385, 655360, 12, -1572849, 655360, 12, -1507313, 655360, 12, -1441777, 655360, 12, -1376241, 655360, 12, -1310705, 655360, 12, -1245169, 655360, 12, -1179633, 655360, 12, -1179634, 655360, 12, -1114098, 655360, 12, -1048562, 589824, 12, -1048561, 655360, 12, -1114097, 655360, 12, -1114096, 655360, 12, -1179632, 655360, 12, -1245168, 655360, 12, -1310704, 655360, 12, -1376240, 655360, 12, -1441776, 655360, 12, -1507312, 655360, 12, -1572848, 655360, 12, -1638384, 655360, 12, -1638383, 655360, 12, -1572847, 655360, 12, -1507311, 655360, 12, -1441775, 655360, 12, -1376239, 655360, 12, -1310703, 655360, 12, -1245167, 655360, 12, -1179631, 655360, 12, -1114095, 655360, 12, -1048559, 655360, 12, -1048560, 655360, 12, -983023, 655360, 12, -917487, 655360, 12, -851951, 655360, 12, -851952, 655360, 12, -786416, 655360, 12, -851950, 589824, 12, -917486, 655360, 12, -983022, 655360, 12, -1048558, 655360, 12, -1114094, 655360, 12, -1179630, 655360, 12, -1245166, 655360, 12, -1310702, 655360, 12, -1376238, 589824, 12, -1441774, 655360, 12, -1507310, 655360, 12, -1572846, 655360, 12, -1638382, 655360, 12, -1638381, 655360, 12, -1572845, 655360, 12, -1507309, 655360, 12, -1441773, 655360, 12, -1376237, 655360, 12, -1310701, 655360, 12, -1245165, 655360, 12, -1179629, 655360, 12, -1114093, 655360, 12, -1048557, 655360, 12, -983021, 655360, 12, -917485, 655360, 12, -851949, 655360, 12, -786413, 655360, 12, -786414, 655360, 12, -720878, 655360, 12, -720879, 655360, 12, -655342, 655360, 12, -655341, 655360, 12, -720877, 655360, 12, -720876, 655360, 12, -786412, 655360, 12, -851948, 655360, 12, -917484, 655360, 12, -983020, 655360, 12, -1048556, 655360, 12, -1114092, 655360, 12, -1179628, 655360, 12, -1245164, 655360, 12, -1310700, 655360, 12, -1376236, 655360, 12, -1441772, 655360, 12, -1507308, 655360, 12, -1572844, 655360, 12, -1638380, 655360, 12, -1638379, 655360, 12, -1572843, 655360, 12, -1507307, 655360, 12, -1441771, 655360, 12, -1376235, 655360, 12, -1310699, 655360, 12, -1245163, 655360, 12, -1179627, 655360, 12, -1114091, 655360, 12, -1048555, 655360, 12, -983019, 655360, 12, -917483, 655360, 12, -851947, 589824, 12, -786411, 655360, 12, -720875, 655360, 12, -655339, 589824, 12, -655340, 655360, 12, -589804, 655360, 12, -524268, 655360, 12, -458732, 655360, 12, -393196, 655360, 12, -327660, 655360, 12, -262124, 655360, 12, -196588, 655360, 12, -131052, 655360, 12, -65516, 458752, 12, 20, 655360, 12, 19, 589824, 12, 65555, 655360, 12, 131091, 655360, 12, 196627, 655360, 12, 196626, 655360, 12, 262162, 655360, 12, 262161, 655360, 12, 327697, 458752, 12, 327696, 655360, 12, 327695, 655360, 12, 393231, 655360, 12, 393230, 655360, 12, 458766, 655360, 12, 458765, 655360, 12, 524301, 655360, 12, 524300, 655360, 12, 589836, 655360, 12, 589835, 655360, 12, 589834, 655360, 12, 524298, 655360, 12, 524297, 655360, 12, 589833, 655360, 12, 655369, 655360, 12, 655370, 655360, 12, 655371, 655360, 12, 589837, 655360, 12, 524302, 655360, 12, 524303, 655360, 12, 458767, 655360, 12, 458768, 655360, 12, 393232, 655360, 12, 393233, 655360, 12, 327698, 655360, 12, 262163, 655360, 12, 262164, 655360, 12, 196628, 655360, 12, 131092, 458752, 12, 65556, 655360, 12, 131093, 655360, 12, 196629, 655360, 12, 262165, 655360, 12, 262166, 655360, 12, 196630, 655360, 12, 131094, 655360, 12, 65558, 655360, 12, 22, 589824, 12, -65514, 655360, 12, -131050, 655360, 12, -196586, 655360, 12, -262122, 655360, 12, -327658, 655360, 12, -393194, 655360, 12, -458730, 655360, 12, -458731, 655360, 12, -524267, 655360, 12, -589803, 655360, 12, -393195, 655360, 12, -327659, 655360, 12, -262123, 655360, 12, -196587, 655360, 12, -131051, 655360, 12, -65515, 655360, 12, 21, 655360, 12, -458729, 655360, 12, -524265, 655360, 12, -589801, 655360, 12, -655337, 655360, 12, -720873, 655360, 12, -786409, 655360, 12, -851945, 655360, 12, -917481, 655360, 12, -983017, 655360, 12, -1048553, 655360, 12, -1114089, 655360, 12, -1179625, 655360, 12, -1245161, 655360, 12, -1310697, 655360, 12, -1376233, 655360, 12, -1441769, 655360, 12, -1507305, 655360, 12, -1572841, 655360, 12, -1638377, 655360, 12, -1703913, 655360, 12, -1703912, 655360, 12, -1638376, 655360, 12, -1572840, 655360, 12, -1507304, 458752, 12, -1441768, 655360, 12, -1376232, 655360, 12, -1310696, 655360, 12, -1245160, 655360, 12, -1179624, 655360, 12, -1114088, 655360, 12, -1048552, 655360, 12, -983016, 655360, 12, -917480, 655360, 12, -851944, 655360, 12, -786408, 655360, 12, -720872, 655360, 12, -655336, 655360, 12, -589800, 655360, 12, -524264, 655360, 12, -458728, 655360, 12, -393192, 655360, 12, -393193, 655360, 12, -327657, 655360, 12, -262121, 589824, 12, -196585, 655360, 12, -131049, 655360, 12, -65513, 589824, 12, 23, 458752, 12, 65559, 655360, 12, 131095, 655360, 12, 196631, 655360, 12, 262167, 655360, 12, 327703, 655360, 12, 327702, 655360, 12, 393238, 655360, 12, 458774, 655360, 12, 524310, 655360, 12, 589846, 655360, 12, 655382, 655360, 12, 720918, 655360, 12, 720919, 655360, 12, 655383, 655360, 12, 655384, 655360, 12, 589848, 655360, 12, 524312, 655360, 12, 458776, 655360, 12, 393240, 655360, 12, 327704, 458752, 12, 262168, 655360, 12, 196632, 655360, 12, 131096, 655360, 12, 65560, 655360, 12, 24, 655360, 12, -65512, 655360, 12, -131048, 655360, 12, -196584, 655360, 12, -262120, 655360, 12, -327656, 655360, 12, -327655, 655360, 12, -393191, 655360, 12, -458727, 655360, 12, -524263, 655360, 12, -589799, 655360, 12, -655335, 655360, 12, -720871, 655360, 12, -786407, 655360, 12, -851943, 655360, 12, -917479, 655360, 12, -983015, 655360, 12, -1048551, 655360, 12, -1114087, 655360, 12, -1179623, 655360, 12, -1245159, 655360, 12, -1310695, 655360, 12, -1376231, 655360, 12, -1441767, 655360, 12, -1507303, 655360, 12, -1572839, 655360, 12, -1638375, 655360, 12, -1703911, 655360, 12, -262119, 458752, 12, -196583, 655360, 12, -131047, 655360, 12, -65511, 655360, 12, 25, 458752, 12, 65561, 655360, 12, 393239, 655360, 12, 458775, 655360, 12, 524311, 655360, 12, 720920, 458752, 12, 786456, 655360, 12, 786455, 655360, 12, 851991, 655360, 12, 917527, 458752, 12, 983063, 655360, 12, 1048599, 655360, 12, 1048598, 655360, 12, 1114134, 655360, 12, 1179670, 655360, 12, 1179671, 655360, 12, 1114135, 655360, 12, 1114136, 655360, 12, 1048600, 655360, 12, 983064, 655360, 12, 917528, 655360, 12, 851992, 655360, 12, 1179672, 655360, 12, 1245208, 655360, 12, 1245207, 655360, 12, 1310743, 655360, 12, 1310742, 655360, 12, 1310744, 655360, 12, 1507323, 655360, 12, 1310728, 655360, 12) + +[node name="Details" type="TileMap" parent="Map"] +tile_set = SubResource("TileSet_orc4v") +format = 2 +layer_0/tile_data = PackedInt32Array(786437, 720896, 0, 1245199, 65536, 0, 983050, 65536, 0, 720916, 65536, 0, 983059, 851968, 0, 1048596, 327680, 0, 917523, 393216, 0, 983043, 393216, 0, 1114115, 458752, 0, 1179653, 524288, 0, 1114120, 262144, 0, -1114117, 393216, 3, -1179655, 327680, 3, -1179648, 65536, 3, -1179643, 327680, 3, -1638399, 196608, 3, -1507324, 0, 3, -1507322, 458752, 3, -1310712, 65536, 3, -1310714, 0, 3, -1114129, 131072, 2, -1179660, 131072, 2, -458762, 131072, 2, -65557, 131072, 2, 262126, 131072, 2, 655348, 131072, 2, 458740, 131072, 2, 917496, 131072, 2, 851964, 131072, 2, 720894, 131072, 2, -327684, 131072, 2, -720881, 131072, 2, 458737, 196608, 2, -196621, 196608, 2, 262136, 196608, 2, 917494, 196608, 2, 327676, 196608, 2, 196612, 196608, 2, 196614, 196608, 2, -786420, 196608, 2, -65554, 327680, 2, -65551, 327680, 2, 983026, 327680, 2, -524293, 327680, 2, -458755, 327680, 2, 393222, 327680, 2, 13, 327680, 2, -458747, 327680, 2, -524279, 327680, 2, -589810, 327680, 2, -917499, 0, 0, -917519, 393216, 2, -589835, 393216, 2, -851975, 393216, 2, -131088, 393216, 2, -5, 262144, 2, 589812, 393216, 2, 917489, 131072, 0, 1048563, 131072, 0, 786419, 131072, 0, 655347, 131072, 0, 720886, 131072, 0, 655350, 131072, 0, 655353, 131072, 0, 786427, 131072, 0, 851962, 131072, 0, 1048568, 131072, 0, 983030, 131072, 0, 262141, 393216, 2, -589828, 393216, 2, -655345, 393216, 2, -589809, 393216, 2, -393210, 393216, 2, 393215, 393216, 2, 720888, 458752, 2, 851961, 262144, 2, 786423, 262144, 2, 458742, 458752, 2, -262166, 458752, 2, -851961, 458752, 2, -851955, 262144, 2, 851952, 393216, 2, -1114126, 0, 2, -458769, 65536, 2, -327699, 0, 2, 131052, 65536, 2, -327692, 0, 2, -65549, 65536, 2, 65534, 0, 2, -131080, 65536, 2, 65530, 131072, 0, 65536, 131072, 0, -458760, 131072, 0, -786435, 131072, 0, -720891, 131072, 0, -524280, 131072, 0, -393211, 131072, 0, -655355, 0, 2, -786422, 0, 2, -786419, 0, 2, -589808, 65536, 2, -65537, 393216, 2, -262145, 393216, 2, -262149, 65536, 2, 262139, 65536, 2, 393211, 0, 2, 262142, 0, 2) + +[node name="Bamboos" type="Node" parent="."] + +[node name="Bamboo" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(-538, -531) + +[node name="Bamboo2" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(-724, -311) + +[node name="Bamboo3" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(-566, 124) + +[node name="Bamboo4" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(-1211, 187) + +[node name="Bamboo5" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(-1233, -351) + +[node name="Bamboo6" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(-922, -786) + +[node name="Bamboo7" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(-741, 577) + +[node name="Bamboo8" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(-164, 554) + +[node name="Bamboo9" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(758, 192) + +[node name="Bamboo10" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(763, -713) + +[node name="Bamboo11" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(-158, -96) + +[node name="Bamboo12" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(967, -238) + +[node name="Bamboo13" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(294, -594) + +[node name="Bamboo14" parent="Bamboos" instance=ExtResource("4_8jerw")] +position = Vector2(560, -141) + +[node name="Killzone" parent="." instance=ExtResource("5_3xrri")] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Killzone"] +position = Vector2(-3, 1217) +shape = SubResource("WorldBoundaryShape2D_5dw0q") + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="Killzone"] +shape = SubResource("WorldBoundaryShape2D_7ioaa") + +[node name="CollisionShape2D3" type="CollisionShape2D" parent="Killzone"] +shape = SubResource("WorldBoundaryShape2D_fq7i5") + +[node name="CollisionShape2D4" type="CollisionShape2D" parent="Killzone"] +shape = SubResource("WorldBoundaryShape2D_kp00i") + +[node name="Players" type="Node" parent="."] + +[node name="Player" parent="Players" instance=ExtResource("1_ykwem")] +position = Vector2(204, -105) +collision_mask = 7 + +[node name="Overworld" type="Camera2D" parent="."] +unique_name_in_owner = true +position = Vector2(955, -128) +zoom = Vector2(0.21, 0.21) + +[node name="Sync" type="Node" parent="."] +script = ExtResource("7_c27o5") +speed_up = 20.0 + +[node name="WorldTimer" type="Timer" parent="."] +unique_name_in_owner = true +wait_time = 1000.0 +autostart = true + +[connection signal="death" from="Players/Player" to="." method="_on_player_death"] +[connection signal="timeout" from="WorldTimer" to="." method="_on_timer_timeout"] diff --git a/scenes/notice.tscn b/scenes/notice.tscn new file mode 100644 index 0000000..852e08a --- /dev/null +++ b/scenes/notice.tscn @@ -0,0 +1,4 @@ +[gd_scene format=3 uid="uid://dxwjan054vgw0"] + +[node name="Notice" type="Area2D"] +collision_mask = 2 diff --git a/scenes/player.tscn b/scenes/player.tscn new file mode 100644 index 0000000..f75cb4b --- /dev/null +++ b/scenes/player.tscn @@ -0,0 +1,252 @@ +[gd_scene load_steps=41 format=3 uid="uid://c7rps714eqdg5"] + +[ext_resource type="Script" path="res://code/player.gd" id="1_iepw4"] +[ext_resource type="Texture2D" uid="uid://b30lhx6f0uy74" path="res://assets/graphics/player/down_attack/attack_down.png" id="2_nre2m"] +[ext_resource type="Texture2D" uid="uid://dxtdtufshr3tw" path="res://assets/graphics/player/left_attack/attack_left.png" id="3_byxsk"] +[ext_resource type="Texture2D" uid="uid://bsocx4vc2sb6s" path="res://assets/graphics/player/right_attack/attack_right.png" id="4_8jqr7"] +[ext_resource type="Texture2D" uid="uid://spquud6cue2l" path="res://assets/graphics/player/up_attack/attack_up.png" id="5_jmjp6"] +[ext_resource type="Texture2D" uid="uid://dij0wyugh24b" path="res://assets/graphics/player/down_idle/idle_down.png" id="6_1snvs"] +[ext_resource type="Texture2D" uid="uid://s31ghurbke8i" path="res://assets/graphics/player/left_idle/idle_left.png" id="7_5uysv"] +[ext_resource type="Texture2D" uid="uid://dh3tuae2rueb" path="res://assets/graphics/player/right_idle/idle_right.png" id="8_i2d7d"] +[ext_resource type="Texture2D" uid="uid://clmyffqm3bmo7" path="res://assets/graphics/player/up_idle/idle_up.png" id="9_vygid"] +[ext_resource type="Texture2D" uid="uid://cs8hfdfrcj3ym" path="res://assets/graphics/player/down/down_0.png" id="10_ix4yj"] +[ext_resource type="Texture2D" uid="uid://5sv3w4si1nrt" path="res://assets/graphics/player/down/down_1.png" id="11_n0p7r"] +[ext_resource type="Texture2D" uid="uid://bmijyqm6i1c1c" path="res://assets/graphics/player/down/down_2.png" id="12_ewi2q"] +[ext_resource type="Texture2D" uid="uid://c81kxx6dryb36" path="res://assets/graphics/player/down/down_3.png" id="13_uvjce"] +[ext_resource type="Texture2D" uid="uid://bdbd32x12d60" path="res://assets/graphics/player/left/left_0.png" id="14_1ggki"] +[ext_resource type="Texture2D" uid="uid://8jvqhpphj6np" path="res://assets/graphics/player/left/left_1.png" id="15_0b7dq"] +[ext_resource type="Texture2D" uid="uid://cam3122hb8vfa" path="res://assets/graphics/player/left/left_2.png" id="16_4yut5"] +[ext_resource type="Texture2D" uid="uid://b801fr00dpw8u" path="res://assets/graphics/player/left/left_3.png" id="17_xafwe"] +[ext_resource type="Texture2D" uid="uid://3bsrlfk4poo1" path="res://assets/graphics/player/right/right_0.png" id="18_g74n4"] +[ext_resource type="Texture2D" uid="uid://bjjcymlv4lkps" path="res://assets/graphics/player/right/right_1.png" id="19_r3xtt"] +[ext_resource type="Texture2D" uid="uid://cfo77c6bv322j" path="res://assets/graphics/player/right/right_2.png" id="20_5b8or"] +[ext_resource type="Texture2D" uid="uid://debleuxlf6kdt" path="res://assets/graphics/player/right/right_3.png" id="21_qn80v"] +[ext_resource type="Texture2D" uid="uid://cbou2pxybkt4d" path="res://assets/graphics/player/up/up_0.png" id="22_5nuot"] +[ext_resource type="Texture2D" uid="uid://o78bod3x5qss" path="res://assets/graphics/player/up/up_1.png" id="23_vkm2w"] +[ext_resource type="Texture2D" uid="uid://crspttjaijn4g" path="res://assets/graphics/player/up/up_2.png" id="24_j1lfm"] +[ext_resource type="Texture2D" uid="uid://b20c4l52ey54t" path="res://assets/graphics/player/up/up_3.png" id="25_mui4y"] +[ext_resource type="PackedScene" uid="uid://dh6xtqap2c2j4" path="res://scenes/weapon.tscn" id="26_5p1ew"] +[ext_resource type="PackedScene" uid="uid://bj4ap7bw0imhy" path="res://scenes/camera.tscn" id="27_dsoxo"] +[ext_resource type="Script" path="res://code/AIController2D.gd" id="28_cl3w8"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_n5xny"] +atlas = ExtResource("6_1snvs") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_1pcxv"] +atlas = ExtResource("10_ix4yj") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_hc3sy"] +atlas = ExtResource("11_n0p7r") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ae5o2"] +atlas = ExtResource("12_ewi2q") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_dvqaa"] +atlas = ExtResource("13_uvjce") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_i6fhi"] +atlas = ExtResource("14_1ggki") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_b6l7h"] +atlas = ExtResource("22_5nuot") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_43afb"] +atlas = ExtResource("23_vkm2w") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_kib0g"] +atlas = ExtResource("24_j1lfm") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_3nifw"] +atlas = ExtResource("25_mui4y") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="SpriteFrames" id="SpriteFrames_bjuky"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("2_nre2m") +}], +"loop": false, +"name": &"attack_down", +"speed": 2.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("3_byxsk") +}], +"loop": false, +"name": &"attack_left", +"speed": 2.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("4_8jqr7") +}], +"loop": false, +"name": &"attack_right", +"speed": 2.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("5_jmjp6") +}], +"loop": false, +"name": &"attack_up", +"speed": 2.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_n5xny") +}], +"loop": false, +"name": &"idle_down", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("7_5uysv") +}], +"loop": false, +"name": &"idle_left", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("8_i2d7d") +}], +"loop": false, +"name": &"idle_right", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("9_vygid") +}], +"loop": false, +"name": &"idle_up", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_1pcxv") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_hc3sy") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ae5o2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_dvqaa") +}], +"loop": true, +"name": &"move_down", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_i6fhi") +}, { +"duration": 1.0, +"texture": ExtResource("15_0b7dq") +}, { +"duration": 1.0, +"texture": ExtResource("16_4yut5") +}, { +"duration": 1.0, +"texture": ExtResource("17_xafwe") +}], +"loop": true, +"name": &"move_left", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": ExtResource("18_g74n4") +}, { +"duration": 1.0, +"texture": ExtResource("19_r3xtt") +}, { +"duration": 1.0, +"texture": ExtResource("20_5b8or") +}, { +"duration": 1.0, +"texture": ExtResource("21_qn80v") +}], +"loop": true, +"name": &"move_right", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_b6l7h") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_43afb") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_kib0g") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_3nifw") +}], +"loop": true, +"name": &"move_up", +"speed": 10.0 +}] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_ilpv0"] +size = Vector2(47, 48) + +[node name="Player" type="CharacterBody2D"] +z_index = 5 +position = Vector2(0, -31) +collision_layer = 2 +collision_mask = 6 +script = ExtResource("1_iepw4") + +[node name="Button" type="Button" parent="."] +modulate = Color(1, 1, 1, 0) +self_modulate = Color(1, 1, 1, 0) +offset_left = -85.0 +offset_top = -86.0 +offset_right = 85.0 +offset_bottom = 93.0 +icon_alignment = 1 + +[node name="Weapon" parent="." instance=ExtResource("26_5p1ew")] +position = Vector2(-10, 48) + +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] +position = Vector2(0, -1) +sprite_frames = SubResource("SpriteFrames_bjuky") +animation = &"idle_down" +autoplay = "idle_down" + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(-1.5, 2) +shape = SubResource("RectangleShape2D_ilpv0") + +[node name="AttackTimer" type="Timer" parent="."] +wait_time = 0.4 +one_shot = true + +[node name="Camera" parent="." instance=ExtResource("27_dsoxo")] +visible = false +position = Vector2(-2, 18) + +[node name="AIController2D" type="Node2D" parent="."] +script = ExtResource("28_cl3w8") + +[connection signal="pressed" from="Button" to="." method="_on_button_pressed"] +[connection signal="toggled" from="Button" to="." method="_on_button_toggled"] +[connection signal="timeout" from="AttackTimer" to="." method="_on_attack_timer_timeout"] diff --git a/scenes/weapon.tscn b/scenes/weapon.tscn new file mode 100644 index 0000000..3d0463f --- /dev/null +++ b/scenes/weapon.tscn @@ -0,0 +1,100 @@ +[gd_scene load_steps=8 format=3 uid="uid://dh6xtqap2c2j4"] + +[ext_resource type="Texture2D" uid="uid://bpobfwslfc3qy" path="res://assets/graphics/weapons/sword/down.png" id="1_1yw4v"] +[ext_resource type="Script" path="res://code/weapon.gd" id="1_utwve"] + +[sub_resource type="SpriteFrames" id="SpriteFrames_4n6kd"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("1_1yw4v") +}], +"loop": true, +"name": &"down", +"speed": 5.0 +}] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_iedax"] +size = Vector2(51, 79) + +[sub_resource type="Animation" id="Animation_0n3f6"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("AnimatedSprite2D:visible") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("CollisionShape2D:disabled") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} + +[sub_resource type="Animation" id="Animation_vwacy"] +resource_name = "attack" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("AnimatedSprite2D:visible") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("CollisionShape2D:disabled") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_sb3pq"] +_data = { +"RESET": SubResource("Animation_0n3f6"), +"attack": SubResource("Animation_vwacy") +} + +[node name="Weapon" type="Area2D"] +collision_mask = 4 +script = ExtResource("1_utwve") + +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] +visible = false +sprite_frames = SubResource("SpriteFrames_4n6kd") +animation = &"down" +flip_h = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(10.5, -15.5) +shape = SubResource("RectangleShape2D_iedax") +disabled = true + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_sb3pq") +} + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/script_templates/AIController/controller_template.gd b/script_templates/AIController/controller_template.gd new file mode 100644 index 0000000..ea1ddf1 --- /dev/null +++ b/script_templates/AIController/controller_template.gd @@ -0,0 +1,43 @@ +# meta-name: AI Controller Logic +# meta-description: Methods that need implementing for AI controllers +# meta-default: true +extends _BASE_ + +#-- Methods that need implementing using the "extend script" option in Godot --# + +func get_obs() -> Dictionary: + assert(false, "the get_obs method is not implemented when extending from ai_controller") + return {"obs":[]} + +func get_reward() -> float: + assert(false, "the get_reward method is not implemented when extending from ai_controller") + return 0.0 + +func get_action_space() -> Dictionary: + assert(false, "the get get_action_space method is not implemented when extending from ai_controller") + return { + "example_actions_continous" : { + "size": 2, + "action_type": "continuous" + }, + "example_actions_discrete" : { + "size": 2, + "action_type": "discrete" + }, + } + +func set_action(action) -> void: + assert(false, "the get set_action method is not implemented when extending from ai_controller") +# -----------------------------------------------------------------------------# + +#-- Methods that can be overridden if needed --# + +#func get_obs_space() -> Dictionary: +# May need overriding if the obs space is complex +# var obs = get_obs() +# return { +# "obs": { +# "size": [len(obs["obs"])], +# "space": "box" +# }, +# } diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..f655597 --- /dev/null +++ b/shell.nix @@ -0,0 +1,11 @@ +with import {}; + +mkShell { + NIX_LD_LIBRARY_PATH = lib.makeLibraryPath [ + stdenv.cc.cc + ]; + NIX_LD = lib.fileContents "${stdenv.cc}/nix-support/dynamic-linker"; + shellHook = '' + export LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH + ''; +} diff --git a/stable_baselines3_example.py b/stable_baselines3_example.py new file mode 100644 index 0000000..4697ab9 --- /dev/null +++ b/stable_baselines3_example.py @@ -0,0 +1,225 @@ +import argparse +import os +import pathlib +from typing import Callable + +from stable_baselines3 import PPO +from stable_baselines3.common.callbacks import CheckpointCallback +from stable_baselines3.common.vec_env.vec_monitor import VecMonitor + +from godot_rl.core.utils import can_import +from godot_rl.wrappers.onnx.stable_baselines_export import export_ppo_model_as_onnx +from godot_rl.wrappers.stable_baselines_wrapper import StableBaselinesGodotEnv + +# To download the env source and binary: +# 1. gdrl.env_from_hub -r edbeeching/godot_rl_BallChase +# 2. chmod +x examples/godot_rl_BallChase/bin/BallChase.x86_64 +if can_import("ray"): + print("WARNING, stable baselines and ray[rllib] are not compatible") + +parser = argparse.ArgumentParser(allow_abbrev=False) +parser.add_argument( + "--env_path", + default=None, + type=str, + help="The Godot binary to use, do not include for in editor training", +) +parser.add_argument( + "--experiment_dir", + default="logs/sb3", + type=str, + help="The name of the experiment directory, in which the tensorboard logs and checkpoints (if enabled) are " + "getting stored.", +) +parser.add_argument( + "--experiment_name", + default="experiment", + type=str, + help="The name of the experiment, which will be displayed in tensorboard and " + "for checkpoint directory and name (if enabled).", +) +parser.add_argument("--seed", type=int, default=0, help="seed of the experiment") +parser.add_argument( + "--resume_model_path", + default=None, + type=str, + help="The path to a model file previously saved using --save_model_path or a checkpoint saved using " + "--save_checkpoints_frequency. Use this to resume training or infer from a saved model.", +) +parser.add_argument( + "--save_model_path", + default=None, + type=str, + help="The path to use for saving the trained sb3 model after training is complete. Saved model can be used later " + "to resume training. Extension will be set to .zip", +) +parser.add_argument( + "--save_checkpoint_frequency", + default=None, + type=int, + help=( + "If set, will save checkpoints every 'frequency' environment steps. " + "Requires a unique --experiment_name or --experiment_dir for each run. " + "Does not need --save_model_path to be set. " + ), +) +parser.add_argument( + "--onnx_export_path", + default=None, + type=str, + help="If included, will export onnx file after training to the path specified.", +) +parser.add_argument( + "--timesteps", + default=1_000_000, + type=int, + help="The number of environment steps to train for, default is 1_000_000. If resuming from a saved model, " + "it will continue training for this amount of steps from the saved state without counting previously trained " + "steps", +) +parser.add_argument( + "--inference", + default=False, + action="store_true", + help="Instead of training, it will run inference on a loaded model for --timesteps steps. " + "Requires --resume_model_path to be set.", +) +parser.add_argument( + "--linear_lr_schedule", + default=False, + action="store_true", + help="Use a linear LR schedule for training. If set, learning rate will decrease until it reaches 0 at " + "--timesteps" + "value. Note: On resuming training, the schedule will reset. If disabled, constant LR will be used.", +) +parser.add_argument( + "--viz", + action="store_true", + help="If set, the simulation will be displayed in a window during training. Otherwise " + "training will run without rendering the simulation. This setting does not apply to in-editor training.", + default=False, +) +parser.add_argument("--speedup", default=1, type=int, help="Whether to speed up the physics in the env") +parser.add_argument( + "--n_parallel", + default=1, + type=int, + help="How many instances of the environment executable to " "launch - requires --env_path to be set if > 1.", +) +args, extras = parser.parse_known_args() + + +def handle_onnx_export(): + # Enforce the extension of onnx and zip when saving model to avoid potential conflicts in case of same name + # and extension used for both + if args.onnx_export_path is not None: + path_onnx = pathlib.Path(args.onnx_export_path).with_suffix(".onnx") + print("Exporting onnx to: " + os.path.abspath(path_onnx)) + export_ppo_model_as_onnx(model, str(path_onnx)) + + +def handle_model_save(): + if args.save_model_path is not None: + zip_save_path = pathlib.Path(args.save_model_path).with_suffix(".zip") + print("Saving model to: " + os.path.abspath(zip_save_path)) + model.save(zip_save_path) + + +def close_env(): + try: + print("closing env") + env.close() + except Exception as e: + print("Exception while closing env: ", e) + + +path_checkpoint = os.path.join(args.experiment_dir, args.experiment_name + "_checkpoints") +abs_path_checkpoint = os.path.abspath(path_checkpoint) + +# Prevent overwriting existing checkpoints when starting a new experiment if checkpoint saving is enabled +if args.save_checkpoint_frequency is not None and os.path.isdir(path_checkpoint): + raise RuntimeError( + abs_path_checkpoint + " folder already exists. " + "Use a different --experiment_dir, or --experiment_name," + "or if previous checkpoints are not needed anymore, " + "remove the folder containing the checkpoints. " + ) + +if args.inference and args.resume_model_path is None: + raise parser.error("Using --inference requires --resume_model_path to be set.") + +if args.env_path is None and args.viz: + print("Info: Using --viz without --env_path set has no effect, in-editor training will always render.") + +env = StableBaselinesGodotEnv( + env_path=args.env_path, show_window=args.viz, seed=args.seed, n_parallel=args.n_parallel, speedup=args.speedup +) +env = VecMonitor(env) + + +# LR schedule code snippet from: +# https://stable-baselines3.readthedocs.io/en/master/guide/examples.html#learning-rate-schedule +def linear_schedule(initial_value: float) -> Callable[[float], float]: + """ + Linear learning rate schedule. + + :param initial_value: Initial learning rate. + :return: schedule that computes + current learning rate depending on remaining progress + """ + + def func(progress_remaining: float) -> float: + """ + Progress will decrease from 1 (beginning) to 0. + + :param progress_remaining: + :return: current learning rate + """ + return progress_remaining * initial_value + + return func + + +if args.resume_model_path is None: + learning_rate = 0.0003 if not args.linear_lr_schedule else linear_schedule(0.0003) + model: PPO = PPO( + "MultiInputPolicy", + env, + batch_size=128, + ent_coef=0.001, + verbose=2, + n_steps=32, + tensorboard_log=args.experiment_dir, + learning_rate=learning_rate, + ) +else: + path_zip = pathlib.Path(args.resume_model_path) + print("Loading model: " + os.path.abspath(path_zip)) + model = PPO.load(path_zip, env=env, tensorboard_log=args.experiment_dir) + +if args.inference: + obs = env.reset() + for i in range(args.timesteps): + action, _state = model.predict(obs, deterministic=True) + obs, reward, done, info = env.step(action) +else: + learn_arguments = dict(total_timesteps=args.timesteps, tb_log_name=args.experiment_name) + if args.save_checkpoint_frequency: + print("Checkpoint saving enabled. Checkpoints will be saved to: " + abs_path_checkpoint) + checkpoint_callback = CheckpointCallback( + save_freq=(args.save_checkpoint_frequency // env.num_envs), + save_path=path_checkpoint, + name_prefix=args.experiment_name, + ) + learn_arguments["callback"] = checkpoint_callback + try: + model.learn(**learn_arguments) + except KeyboardInterrupt: + print( + """Training interrupted by user. Will save if --save_model_path was + used and/or export if --onnx_export_path was used.""" + ) + +close_env() +handle_onnx_export() +handle_model_save()