easylink 0.1.13__tar.gz → 0.1.14__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. {easylink-0.1.13 → easylink-0.1.14}/CHANGELOG.rst +4 -0
  2. easylink-0.1.14/CONTRIBUTING.rst +12 -0
  3. {easylink-0.1.13 → easylink-0.1.14}/PKG-INFO +22 -14
  4. easylink-0.1.14/README.rst +53 -0
  5. easylink-0.1.14/docs/source/user_guide/tutorials/DAG-common-pipeline.svg +175 -0
  6. easylink-0.1.14/docs/source/user_guide/tutorials/DAG-e2e-pipeline-expanded.svg +319 -0
  7. easylink-0.1.14/docs/source/user_guide/tutorials/DAG-e2e-pipeline.svg +273 -0
  8. easylink-0.1.14/docs/source/user_guide/tutorials/getting_started.rst +388 -0
  9. {easylink-0.1.13 → easylink-0.1.14}/setup.py +4 -0
  10. easylink-0.1.14/src/easylink/_version.py +1 -0
  11. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/configuration.py +5 -5
  12. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/graph_components.py +48 -51
  13. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/implementation.py +70 -10
  14. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/pipeline.py +127 -24
  15. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/pipeline_graph.py +46 -26
  16. easylink-0.1.14/src/easylink/pipeline_schema_constants/__init__.py +30 -0
  17. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/pipeline_schema_constants/development.py +2 -23
  18. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/pipeline_schema_constants/testing.py +243 -17
  19. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/rule.py +60 -140
  20. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/runner.py +14 -9
  21. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/step.py +397 -143
  22. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/utilities/splitter_utils.py +35 -0
  23. {easylink-0.1.13 → easylink-0.1.14}/src/easylink.egg-info/PKG-INFO +22 -14
  24. {easylink-0.1.13 → easylink-0.1.14}/src/easylink.egg-info/SOURCES.txt +9 -0
  25. {easylink-0.1.13 → easylink-0.1.14}/src/easylink.egg-info/requires.txt +4 -0
  26. easylink-0.1.14/tests/conftest.py +75 -0
  27. {easylink-0.1.13 → easylink-0.1.14}/tests/e2e/test_easylink_run.py +15 -21
  28. {easylink-0.1.13 → easylink-0.1.14}/tests/e2e/test_step_types.py +22 -22
  29. easylink-0.1.14/tests/integration/test_compositions.py +210 -0
  30. {easylink-0.1.13 → easylink-0.1.14}/tests/integration/test_snakemake.py +3 -10
  31. {easylink-0.1.13 → easylink-0.1.14}/tests/integration/test_snakemake_slurm.py +6 -9
  32. {easylink-0.1.13 → easylink-0.1.14}/tests/integration/test_snakemake_spark.py +3 -9
  33. easylink-0.1.14/tests/specifications/examples/environment_slurm.yaml +9 -0
  34. easylink-0.1.14/tests/specifications/integration/embarrassingly_parallel/pipeline_hierarchical_step.yaml +9 -0
  35. easylink-0.1.14/tests/specifications/integration/embarrassingly_parallel/pipeline_loop_step.yaml +7 -0
  36. easylink-0.1.14/tests/specifications/integration/embarrassingly_parallel/pipeline_parallel_step.yaml +7 -0
  37. easylink-0.1.14/tests/unit/rule_strings/aggregation_rule.txt +23 -0
  38. easylink-0.1.14/tests/unit/rule_strings/checkpoint_rule.txt +18 -0
  39. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/rule_strings/embarrassingly_parallel_rule.txt +5 -4
  40. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/rule_strings/pipeline_local.txt +50 -50
  41. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/rule_strings/pipeline_slurm.txt +50 -50
  42. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_graph_components.py +4 -63
  43. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_pipeline_graph.py +216 -69
  44. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_pipeline_schema.py +30 -5
  45. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_rule.py +15 -41
  46. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_step.py +292 -313
  47. easylink-0.1.13/README.rst +0 -49
  48. easylink-0.1.13/docs/source/user_guide/tutorials/getting_started.rst +0 -9
  49. easylink-0.1.13/src/easylink/_version.py +0 -1
  50. easylink-0.1.13/src/easylink/pipeline_schema_constants/__init__.py +0 -26
  51. easylink-0.1.13/tests/conftest.py +0 -40
  52. easylink-0.1.13/tests/unit/rule_strings/aggregation_rule.txt +0 -23
  53. easylink-0.1.13/tests/unit/rule_strings/checkpoint_rule.txt +0 -19
  54. {easylink-0.1.13 → easylink-0.1.14}/.bandit +0 -0
  55. {easylink-0.1.13 → easylink-0.1.14}/.flake8 +0 -0
  56. {easylink-0.1.13 → easylink-0.1.14}/.github/CODEOWNERS +0 -0
  57. {easylink-0.1.13 → easylink-0.1.14}/.github/pull_request_template.md +0 -0
  58. {easylink-0.1.13 → easylink-0.1.14}/.github/workflows/deploy.yml +0 -0
  59. {easylink-0.1.13 → easylink-0.1.14}/.github/workflows/update_readme.yml +0 -0
  60. {easylink-0.1.13 → easylink-0.1.14}/.gitignore +0 -0
  61. {easylink-0.1.13 → easylink-0.1.14}/.readthedocs.yml +0 -0
  62. {easylink-0.1.13 → easylink-0.1.14}/Jenkinsfile +0 -0
  63. {easylink-0.1.13 → easylink-0.1.14}/Makefile +0 -0
  64. {easylink-0.1.13 → easylink-0.1.14}/docs/Makefile +0 -0
  65. {easylink-0.1.13 → easylink-0.1.14}/docs/nitpick-exceptions +0 -0
  66. {easylink-0.1.13 → easylink-0.1.14}/docs/source/_static/style.css +0 -0
  67. {easylink-0.1.13 → easylink-0.1.14}/docs/source/_templates/layout.html +0 -0
  68. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/cli.rst +0 -0
  69. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/configuration.rst +0 -0
  70. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/graph_components.rst +0 -0
  71. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/implementation.rst +0 -0
  72. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/index.rst +0 -0
  73. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/pipeline.rst +0 -0
  74. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/pipeline_graph.rst +0 -0
  75. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/pipeline_schema.rst +0 -0
  76. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/pipeline_schema_constants/development.rst +0 -0
  77. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/pipeline_schema_constants/index.rst +0 -0
  78. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/pipeline_schema_constants/testing.rst +0 -0
  79. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/rule.rst +0 -0
  80. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/runner.rst +0 -0
  81. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/step.rst +0 -0
  82. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/utilities/aggregator_utils.rst +0 -0
  83. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/utilities/data_utils.rst +0 -0
  84. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/utilities/general_utils.rst +0 -0
  85. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/utilities/index.rst +0 -0
  86. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/utilities/paths.rst +0 -0
  87. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/utilities/splitter_utils.rst +0 -0
  88. {easylink-0.1.13 → easylink-0.1.14}/docs/source/api_reference/utilities/validation_utils.rst +0 -0
  89. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/index.rst +0 -0
  90. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/01_step.drawio.png +0 -0
  91. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/02_default_implementation.drawio.png +0 -0
  92. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/03_slots.drawio.png +0 -0
  93. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/04_data_dependency.drawio.png +0 -0
  94. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/05_pipeline_schema.drawio.png +0 -0
  95. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/06_default_input.drawio.png +0 -0
  96. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/07_cloneable_section.drawio.png +0 -0
  97. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/08_cloneable_section_expanded.drawio.png +0 -0
  98. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/09_loopable_section.drawio.png +0 -0
  99. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/10_loopable_section_expanded.drawio.png +0 -0
  100. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/11_cloneable_section_splitter.drawio.png +0 -0
  101. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/12_cloneable_section_splitter_expanded.drawio.png +0 -0
  102. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/13_autoparallel_section.drawio.png +0 -0
  103. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/14_choice_section.drawio.png +0 -0
  104. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/15_choice_section_expanded.drawio.png +0 -0
  105. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/16_step_hierarchy.drawio.png +0 -0
  106. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/17_draws.drawio.png +0 -0
  107. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/18_schema_to_pipeline.drawio.png +0 -0
  108. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/19_schema_to_pipeline_combined.drawio.png +0 -0
  109. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/clustering_pass_sub_steps.drawio.png +0 -0
  110. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/images/entity_resolution_pipeline_schema.drawio.png +0 -0
  111. {easylink-0.1.13 → easylink-0.1.14}/docs/source/concepts/pipeline_schema/index.rst +0 -0
  112. {easylink-0.1.13 → easylink-0.1.14}/docs/source/conf.py +0 -0
  113. {easylink-0.1.13 → easylink-0.1.14}/docs/source/glossary.rst +0 -0
  114. {easylink-0.1.13 → easylink-0.1.14}/docs/source/index.rst +0 -0
  115. {easylink-0.1.13 → easylink-0.1.14}/docs/source/user_guide/cli.rst +0 -0
  116. {easylink-0.1.13 → easylink-0.1.14}/docs/source/user_guide/index.rst +0 -0
  117. {easylink-0.1.13 → easylink-0.1.14}/docs/source/user_guide/tutorials/index.rst +0 -0
  118. {easylink-0.1.13 → easylink-0.1.14}/pyproject.toml +0 -0
  119. {easylink-0.1.13 → easylink-0.1.14}/python_versions.json +0 -0
  120. {easylink-0.1.13 → easylink-0.1.14}/pytype.cfg +0 -0
  121. {easylink-0.1.13 → easylink-0.1.14}/setup.cfg +0 -0
  122. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/__about__.py +0 -0
  123. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/__init__.py +0 -0
  124. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/cli.py +0 -0
  125. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/images/spark_cluster/Dockerfile +0 -0
  126. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/images/spark_cluster/README.md +0 -0
  127. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/implementation_metadata.yaml +0 -0
  128. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/pipeline_schema.py +0 -0
  129. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/README.md +0 -0
  130. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/build-containers-local.sh +0 -0
  131. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/build-containers-remote.sh +0 -0
  132. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/input_data/create_input_files.ipynb +0 -0
  133. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/input_data/input_file_1.csv +0 -0
  134. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/input_data/input_file_1.parquet +0 -0
  135. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/input_data/input_file_2.csv +0 -0
  136. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/input_data/input_file_2.parquet +0 -0
  137. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/python_pandas/README.md +0 -0
  138. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/python_pandas/dummy_step.py +0 -0
  139. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/python_pandas/python_pandas.def +0 -0
  140. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/python_pyspark/README.md +0 -0
  141. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/python_pyspark/dummy_step.py +0 -0
  142. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/python_pyspark/python_pyspark.def +0 -0
  143. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/r/README.md +0 -0
  144. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/r/dummy_step.R +0 -0
  145. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/r/r-image.def +0 -0
  146. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/steps/dev/test.py +0 -0
  147. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/utilities/__init__.py +0 -0
  148. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/utilities/aggregator_utils.py +0 -0
  149. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/utilities/data_utils.py +0 -0
  150. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/utilities/general_utils.py +0 -0
  151. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/utilities/paths.py +0 -0
  152. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/utilities/spark.smk +0 -0
  153. {easylink-0.1.13 → easylink-0.1.14}/src/easylink/utilities/validation_utils.py +0 -0
  154. {easylink-0.1.13 → easylink-0.1.14}/src/easylink.egg-info/dependency_links.txt +0 -0
  155. {easylink-0.1.13 → easylink-0.1.14}/src/easylink.egg-info/entry_points.txt +0 -0
  156. {easylink-0.1.13 → easylink-0.1.14}/src/easylink.egg-info/not-zip-safe +0 -0
  157. {easylink-0.1.13 → easylink-0.1.14}/src/easylink.egg-info/top_level.txt +0 -0
  158. {easylink-0.1.13 → easylink-0.1.14}/tests/__init__.py +0 -0
  159. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/common/environment_local.yaml +0 -0
  160. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/common/input_data.yaml +0 -0
  161. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/common/pipeline.yaml +0 -0
  162. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/e2e/environment_slurm.yaml +0 -0
  163. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/e2e/pipeline.yaml +0 -0
  164. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/e2e/pipeline_expanded.yaml +0 -0
  165. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/integration/environment_spark_slurm.yaml +0 -0
  166. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/integration/pipeline.yaml +0 -0
  167. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/integration/pipeline_spark.yaml +0 -0
  168. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/environment_minimum.yaml +0 -0
  169. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/environment_spark_slurm.yaml +0 -0
  170. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline.yaml +0 -0
  171. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_bad_combined_implementations.yaml +0 -0
  172. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_bad_implementation.yaml +0 -0
  173. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_bad_loop_formatting.yaml +0 -0
  174. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_bad_step.yaml +0 -0
  175. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_bad_type_key.yaml +0 -0
  176. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_combine_bad_implementation_names.yaml +0 -0
  177. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_combine_bad_topology.yaml +0 -0
  178. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_combine_two_steps.yaml +0 -0
  179. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_combine_with_extra_node.yaml +0 -0
  180. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_combine_with_iteration.yaml +0 -0
  181. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_combine_with_iteration_cycle.yaml +0 -0
  182. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_combine_with_missing_node.yaml +0 -0
  183. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_combine_with_parallel.yaml +0 -0
  184. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_missing_implementation_name.yaml +0 -0
  185. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_missing_implementations.yaml +0 -0
  186. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_missing_loop_nodes.yaml +0 -0
  187. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_missing_step.yaml +0 -0
  188. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_missing_substeps.yaml +0 -0
  189. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_missing_type_key.yaml +0 -0
  190. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_nested_templated_steps.yaml +0 -0
  191. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_out_of_order.yaml +0 -0
  192. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_spark.yaml +0 -0
  193. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_type_config_mismatch.yaml +0 -0
  194. {easylink-0.1.13 → easylink-0.1.14}/tests/specifications/unit/pipeline_wrong_parallel_split_keys.yaml +0 -0
  195. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/__init__.py +0 -0
  196. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/conftest.py +0 -0
  197. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/rule_strings/implemented_rule_local.txt +0 -0
  198. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/rule_strings/implemented_rule_slurm.txt +0 -0
  199. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/rule_strings/target_rule.txt +0 -0
  200. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/rule_strings/validation_rule.txt +0 -0
  201. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_cli.py +0 -0
  202. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_config.py +0 -0
  203. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_data_utils.py +0 -0
  204. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_general_utils.py +0 -0
  205. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_implementation.py +0 -0
  206. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_pipeline.py +0 -0
  207. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_runner.py +0 -0
  208. {easylink-0.1.13 → easylink-0.1.14}/tests/unit/test_validations.py +0 -0
  209. {easylink-0.1.13 → easylink-0.1.14}/update_readme.py +0 -0
@@ -1,3 +1,7 @@
1
+ **0.1.14 - 5/1/25**
2
+
3
+ - Add support for EmbarrassinglyParallelSteps to accept sections (i.e. non-leaf steps)
4
+
1
5
  **0.1.13 - 4/21/25**
2
6
 
3
7
  - remove graphviz from doc build install
@@ -0,0 +1,12 @@
1
+ ============
2
+ Contributing
3
+ ============
4
+
5
+ To run or develop easylink tests or documentation, you can install easylink with the ``[dev]`` extra::
6
+
7
+ $ git clone git@github.com:ihmeuw/easylink.git # or git clone https://github.com/ihmeuw/easylink.git
8
+ $ cd easylink
9
+ $ pip install -e .[dev]
10
+
11
+ .. todo::
12
+ Show how to run the tests and build the documentation
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easylink
3
- Version: 0.1.13
3
+ Version: 0.1.14
4
4
  Summary: Research repository for the EasyLink ER ecosystem project.
5
5
  Home-page: https://github.com/ihmeuw/easylink
6
6
  Author: The EasyLink developers
@@ -19,11 +19,14 @@ Requires-Dist: pyarrow
19
19
  Requires-Dist: snakemake>=8.0.0
20
20
  Requires-Dist: snakemake-interface-executor-plugins<9.0.0
21
21
  Requires-Dist: snakemake-executor-plugin-slurm
22
+ Requires-Dist: pandas-stubs
23
+ Requires-Dist: pyarrow-stubs
22
24
  Provides-Extra: docs
23
25
  Requires-Dist: sphinx<8.2.0; extra == "docs"
24
26
  Requires-Dist: sphinx-rtd-theme; extra == "docs"
25
27
  Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
26
28
  Requires-Dist: sphinx-click; extra == "docs"
29
+ Requires-Dist: sphinx-autobuild; extra == "docs"
27
30
  Requires-Dist: typing_extensions; extra == "docs"
28
31
  Provides-Extra: test
29
32
  Requires-Dist: pytest; extra == "test"
@@ -34,6 +37,7 @@ Requires-Dist: sphinx<8.2.0; extra == "dev"
34
37
  Requires-Dist: sphinx-rtd-theme; extra == "dev"
35
38
  Requires-Dist: sphinx-autodoc-typehints; extra == "dev"
36
39
  Requires-Dist: sphinx-click; extra == "dev"
40
+ Requires-Dist: sphinx-autobuild; extra == "dev"
37
41
  Requires-Dist: typing_extensions; extra == "dev"
38
42
  Requires-Dist: pytest; extra == "dev"
39
43
  Requires-Dist: pytest-cov; extra == "dev"
@@ -71,28 +75,32 @@ Installation
71
75
 
72
76
  There are a few things to install in order to use this package:
73
77
 
74
- - Install singularity. If this is not already installed on your system, you will
75
- likely need to request it from your system admin.
76
- Refer to https://docs.sylabs.io/guides/4.1/admin-guide/installation.html
78
+ - Install singularity.
77
79
 
80
+ You may need to request it from your system admin.
81
+ Refer to https://docs.sylabs.io/guides/4.1/admin-guide/installation.html.
82
+ You can check if you already have singularity installed by running the command ``singularity --version``. For an
83
+ existing installation, your singularity version number is printed.
78
84
 
79
- - Install graphviz via:
85
+ - Install conda.
86
+
87
+ We recommend `miniforge <https://github.com/conda-forge/miniforge>`_. You can check if you already
88
+ have conda installed by running the command ``conda --version``. For an existing installation, a version
89
+ will be displayed.
80
90
 
81
- .. code-block:: console
82
-
83
- $ conda install graphviz
84
-
85
- - Install EasyLink.
91
+ - Install easylink, python and graphviz in a conda environment.
86
92
 
87
93
  Option 1 - Install from PyPI with pip::
88
94
 
95
+ $ conda create --name easylink -c conda-forge python=3.12 graphviz 'gcc<14' -y
96
+ $ conda activate easylink
89
97
  $ pip install easylink
90
98
 
91
99
  Option 2 - Build from source with pip::
92
-
93
- $ git clone git@github.com:ihmeuw/easylink.git # or git clone https://github.com/ihmeuw/easylink.git
94
- $ cd easylink
95
- $ pip install .
100
+
101
+ $ conda create --name easylink -c conda-forge python=3.12 graphviz 'gcc<14' -y
102
+ $ conda activate easylink
103
+ $ pip install git+https://github.com/ihmeuw/easylink.git
96
104
 
97
105
  .. _end_installation:
98
106
 
@@ -0,0 +1,53 @@
1
+ ========
2
+ EasyLink
3
+ ========
4
+
5
+ EasyLink is a framework that allows users to build and run highly configurable
6
+ entity resolution (ER) pipelines.
7
+
8
+ .. _python_support:
9
+
10
+ **Supported Python versions: 3.11, 3.12**
11
+
12
+ .. _end_python_support:
13
+
14
+ Installation
15
+ ============
16
+
17
+ .. _installation:
18
+
19
+ There are a few things to install in order to use this package:
20
+
21
+ - Install singularity.
22
+
23
+ You may need to request it from your system admin.
24
+ Refer to https://docs.sylabs.io/guides/4.1/admin-guide/installation.html.
25
+ You can check if you already have singularity installed by running the command ``singularity --version``. For an
26
+ existing installation, your singularity version number is printed.
27
+
28
+ - Install conda.
29
+
30
+ We recommend `miniforge <https://github.com/conda-forge/miniforge>`_. You can check if you already
31
+ have conda installed by running the command ``conda --version``. For an existing installation, a version
32
+ will be displayed.
33
+
34
+ - Install easylink, python and graphviz in a conda environment.
35
+
36
+ Option 1 - Install from PyPI with pip::
37
+
38
+ $ conda create --name easylink -c conda-forge python=3.12 graphviz 'gcc<14' -y
39
+ $ conda activate easylink
40
+ $ pip install easylink
41
+
42
+ Option 2 - Build from source with pip::
43
+
44
+ $ conda create --name easylink -c conda-forge python=3.12 graphviz 'gcc<14' -y
45
+ $ conda activate easylink
46
+ $ pip install git+https://github.com/ihmeuw/easylink.git
47
+
48
+ .. _end_installation:
49
+
50
+ Documentation
51
+ =============
52
+
53
+ You can view documentation at https://easylink.readthedocs.io/en/latest/
@@ -0,0 +1,175 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <!-- Generated by graphviz version 2.50.0 (0)
5
+ -->
6
+ <!-- Title: snakemake_dag Pages: 1 -->
7
+ <svg width="582pt" height="764pt"
8
+ viewBox="0.00 0.00 582.29 764.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
+ <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 760)">
10
+ <title>snakemake_dag</title>
11
+ <polygon fill="white" stroke="transparent" points="-4,4 -4,-760 578.29,-760 578.29,4 -4,4"/>
12
+ <!-- 0 -->
13
+ <g id="node1" class="node">
14
+ <title>0</title>
15
+ <path fill="none" stroke="#d8a456" stroke-width="2" d="M206.09,-36C206.09,-36 176.09,-36 176.09,-36 170.09,-36 164.09,-30 164.09,-24 164.09,-24 164.09,-12 164.09,-12 164.09,-6 170.09,0 176.09,0 176.09,0 206.09,0 206.09,0 212.09,0 218.09,-6 218.09,-12 218.09,-12 218.09,-24 218.09,-24 218.09,-30 212.09,-36 206.09,-36"/>
16
+ <text text-anchor="middle" x="191.09" y="-15" font-family="sans" font-size="10.00">all</text>
17
+ </g>
18
+ <!-- 1 -->
19
+ <g id="node2" class="node">
20
+ <title>1</title>
21
+ <path fill="none" stroke="#b6d856" stroke-width="2" d="M232.74,-180C232.74,-180 149.43,-180 149.43,-180 143.43,-180 137.43,-174 137.43,-168 137.43,-168 137.43,-156 137.43,-156 137.43,-150 143.43,-144 149.43,-144 149.43,-144 232.74,-144 232.74,-144 238.74,-144 244.74,-150 244.74,-156 244.74,-156 244.74,-168 244.74,-168 244.74,-174 238.74,-180 232.74,-180"/>
22
+ <text text-anchor="middle" x="191.09" y="-159" font-family="sans" font-size="10.00">step_4_python_pandas</text>
23
+ </g>
24
+ <!-- 1&#45;&gt;0 -->
25
+ <g id="edge1" class="edge">
26
+ <title>1&#45;&gt;0</title>
27
+ <path fill="none" stroke="grey" stroke-width="2" d="M179.2,-143.72C173.08,-133.76 166.24,-120.73 163.09,-108 159.24,-92.47 159.24,-87.53 163.09,-72 165.38,-62.75 169.61,-53.34 174.11,-45.07"/>
28
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="177.22,-46.68 179.2,-36.28 171.16,-43.17 177.22,-46.68"/>
29
+ </g>
30
+ <!-- 11 -->
31
+ <g id="node12" class="node">
32
+ <title>11</title>
33
+ <path fill="none" stroke="#d8cb56" stroke-width="2" d="M293.79,-108C293.79,-108 184.39,-108 184.39,-108 178.39,-108 172.39,-102 172.39,-96 172.39,-96 172.39,-84 172.39,-84 172.39,-78 178.39,-72 184.39,-72 184.39,-72 293.79,-72 293.79,-72 299.79,-72 305.79,-78 305.79,-84 305.79,-84 305.79,-96 305.79,-96 305.79,-102 299.79,-108 293.79,-108"/>
34
+ <text text-anchor="middle" x="239.09" y="-87" font-family="sans" font-size="10.00">results_main_input_validator</text>
35
+ </g>
36
+ <!-- 1&#45;&gt;11 -->
37
+ <g id="edge15" class="edge">
38
+ <title>1&#45;&gt;11</title>
39
+ <path fill="none" stroke="grey" stroke-width="2" d="M202.95,-143.7C208.59,-135.47 215.44,-125.48 221.66,-116.42"/>
40
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="224.59,-118.33 227.36,-108.1 218.82,-114.37 224.59,-118.33"/>
41
+ </g>
42
+ <!-- 2 -->
43
+ <g id="node3" class="node">
44
+ <title>2</title>
45
+ <path fill="none" stroke="#567bd8" stroke-width="2" d="M226.27,-324C226.27,-324 11.91,-324 11.91,-324 5.91,-324 -0.09,-318 -0.09,-312 -0.09,-312 -0.09,-300 -0.09,-300 -0.09,-294 5.91,-288 11.91,-288 11.91,-288 226.27,-288 226.27,-288 232.27,-288 238.27,-294 238.27,-300 238.27,-300 238.27,-312 238.27,-312 238.27,-318 232.27,-324 226.27,-324"/>
46
+ <text text-anchor="middle" x="119.09" y="-303" font-family="sans" font-size="10.00">aggregate_step_3_python_pandas_step_3_main_output</text>
47
+ </g>
48
+ <!-- 2&#45;&gt;1 -->
49
+ <g id="edge3" class="edge">
50
+ <title>2&#45;&gt;1</title>
51
+ <path fill="none" stroke="grey" stroke-width="2" d="M95.34,-287.91C84.54,-278.65 72.89,-266.2 67.09,-252 61.04,-237.19 58.27,-229.35 67.09,-216 80.8,-195.23 104.51,-182.57 127.55,-174.86"/>
52
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="128.81,-178.14 137.35,-171.86 126.76,-171.44 128.81,-178.14"/>
53
+ </g>
54
+ <!-- 10 -->
55
+ <g id="node11" class="node">
56
+ <title>10</title>
57
+ <path fill="none" stroke="#56d8b9" stroke-width="2" d="M293.95,-252C293.95,-252 88.23,-252 88.23,-252 82.23,-252 76.23,-246 76.23,-240 76.23,-240 76.23,-228 76.23,-228 76.23,-222 82.23,-216 88.23,-216 88.23,-216 293.95,-216 293.95,-216 299.95,-216 305.95,-222 305.95,-228 305.95,-228 305.95,-240 305.95,-240 305.95,-246 299.95,-252 293.95,-252"/>
58
+ <text text-anchor="middle" x="191.09" y="-231" font-family="sans" font-size="10.00">step_4_python_pandas_step_4_main_input_validator</text>
59
+ </g>
60
+ <!-- 2&#45;&gt;10 -->
61
+ <g id="edge14" class="edge">
62
+ <title>2&#45;&gt;10</title>
63
+ <path fill="none" stroke="grey" stroke-width="2" d="M136.89,-287.7C145.69,-279.14 156.47,-268.66 166.09,-259.3"/>
64
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="168.77,-261.58 173.5,-252.1 163.89,-256.57 168.77,-261.58"/>
65
+ </g>
66
+ <!-- 3 -->
67
+ <g id="node4" class="node">
68
+ <title>3</title>
69
+ <path fill="none" stroke="#56d86b" stroke-width="2" d="M212.63,-396C212.63,-396 25.55,-396 25.55,-396 19.55,-396 13.55,-390 13.55,-384 13.55,-384 13.55,-372 13.55,-372 13.55,-366 19.55,-360 25.55,-360 25.55,-360 212.63,-360 212.63,-360 218.63,-360 224.63,-366 224.63,-372 224.63,-372 224.63,-384 224.63,-384 224.63,-390 218.63,-396 212.63,-396"/>
70
+ <text text-anchor="middle" x="119.09" y="-375" font-family="sans" font-size="10.00">split_step_3_python_pandas_step_3_main_input</text>
71
+ </g>
72
+ <!-- 3&#45;&gt;2 -->
73
+ <g id="edge6" class="edge">
74
+ <title>3&#45;&gt;2</title>
75
+ <path fill="none" stroke="grey" stroke-width="2" d="M119.09,-359.7C119.09,-351.98 119.09,-342.71 119.09,-334.11"/>
76
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="122.59,-334.1 119.09,-324.1 115.59,-334.1 122.59,-334.1"/>
77
+ </g>
78
+ <!-- 4 -->
79
+ <g id="node5" class="node">
80
+ <title>4</title>
81
+ <path fill="none" stroke="#56a9d8" stroke-width="2" d="M160.74,-540C160.74,-540 77.43,-540 77.43,-540 71.43,-540 65.43,-534 65.43,-528 65.43,-528 65.43,-516 65.43,-516 65.43,-510 71.43,-504 77.43,-504 77.43,-504 160.74,-504 160.74,-504 166.74,-504 172.74,-510 172.74,-516 172.74,-516 172.74,-528 172.74,-528 172.74,-534 166.74,-540 160.74,-540"/>
82
+ <text text-anchor="middle" x="119.09" y="-519" font-family="sans" font-size="10.00">step_2_python_pandas</text>
83
+ </g>
84
+ <!-- 4&#45;&gt;3 -->
85
+ <g id="edge7" class="edge">
86
+ <title>4&#45;&gt;3</title>
87
+ <path fill="none" stroke="grey" stroke-width="2" d="M95.34,-503.91C84.54,-494.65 72.89,-482.2 67.09,-468 61.04,-453.19 61.04,-446.81 67.09,-432 71.58,-421.02 79.56,-411.08 87.94,-402.86"/>
88
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="90.32,-405.42 95.34,-396.09 85.6,-400.26 90.32,-405.42"/>
89
+ </g>
90
+ <!-- 8 -->
91
+ <g id="node9" class="node">
92
+ <title>8</title>
93
+ <path fill="none" stroke="#8fd856" stroke-width="2" d="M293.95,-468C293.95,-468 88.23,-468 88.23,-468 82.23,-468 76.23,-462 76.23,-456 76.23,-456 76.23,-444 76.23,-444 76.23,-438 82.23,-432 88.23,-432 88.23,-432 293.95,-432 293.95,-432 299.95,-432 305.95,-438 305.95,-444 305.95,-444 305.95,-456 305.95,-456 305.95,-462 299.95,-468 293.95,-468"/>
94
+ <text text-anchor="middle" x="191.09" y="-447" font-family="sans" font-size="10.00">step_3_python_pandas_step_3_main_input_validator</text>
95
+ </g>
96
+ <!-- 4&#45;&gt;8 -->
97
+ <g id="edge13" class="edge">
98
+ <title>4&#45;&gt;8</title>
99
+ <path fill="none" stroke="grey" stroke-width="2" d="M136.89,-503.7C145.69,-495.14 156.47,-484.66 166.09,-475.3"/>
100
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="168.77,-477.58 173.5,-468.1 163.89,-472.57 168.77,-477.58"/>
101
+ </g>
102
+ <!-- 5 -->
103
+ <g id="node6" class="node">
104
+ <title>5</title>
105
+ <path fill="none" stroke="#56d0d8" stroke-width="2" d="M160.74,-684C160.74,-684 77.43,-684 77.43,-684 71.43,-684 65.43,-678 65.43,-672 65.43,-672 65.43,-660 65.43,-660 65.43,-654 71.43,-648 77.43,-648 77.43,-648 160.74,-648 160.74,-648 166.74,-648 172.74,-654 172.74,-660 172.74,-660 172.74,-672 172.74,-672 172.74,-678 166.74,-684 160.74,-684"/>
106
+ <text text-anchor="middle" x="119.09" y="-663" font-family="sans" font-size="10.00">step_1_python_pandas</text>
107
+ </g>
108
+ <!-- 5&#45;&gt;4 -->
109
+ <g id="edge9" class="edge">
110
+ <title>5&#45;&gt;4</title>
111
+ <path fill="none" stroke="grey" stroke-width="2" d="M95.34,-647.91C84.54,-638.65 72.89,-626.2 67.09,-612 61.04,-597.19 61.04,-590.81 67.09,-576 71.58,-565.02 79.56,-555.08 87.94,-546.86"/>
112
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="90.32,-549.42 95.34,-540.09 85.6,-544.26 90.32,-549.42"/>
113
+ </g>
114
+ <!-- 7 -->
115
+ <g id="node8" class="node">
116
+ <title>7</title>
117
+ <path fill="none" stroke="#68d856" stroke-width="2" d="M293.95,-612C293.95,-612 88.23,-612 88.23,-612 82.23,-612 76.23,-606 76.23,-600 76.23,-600 76.23,-588 76.23,-588 76.23,-582 82.23,-576 88.23,-576 88.23,-576 293.95,-576 293.95,-576 299.95,-576 305.95,-582 305.95,-588 305.95,-588 305.95,-600 305.95,-600 305.95,-606 299.95,-612 293.95,-612"/>
118
+ <text text-anchor="middle" x="191.09" y="-591" font-family="sans" font-size="10.00">step_2_python_pandas_step_2_main_input_validator</text>
119
+ </g>
120
+ <!-- 5&#45;&gt;7 -->
121
+ <g id="edge12" class="edge">
122
+ <title>5&#45;&gt;7</title>
123
+ <path fill="none" stroke="grey" stroke-width="2" d="M136.89,-647.7C145.69,-639.14 156.47,-628.66 166.09,-619.3"/>
124
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="168.77,-621.58 173.5,-612.1 163.89,-616.57 168.77,-621.58"/>
125
+ </g>
126
+ <!-- 6 -->
127
+ <g id="node7" class="node">
128
+ <title>6</title>
129
+ <path fill="none" stroke="#d85656" stroke-width="2" d="M221.95,-756C221.95,-756 16.23,-756 16.23,-756 10.23,-756 4.23,-750 4.23,-744 4.23,-744 4.23,-732 4.23,-732 4.23,-726 10.23,-720 16.23,-720 16.23,-720 221.95,-720 221.95,-720 227.95,-720 233.95,-726 233.95,-732 233.95,-732 233.95,-744 233.95,-744 233.95,-750 227.95,-756 221.95,-756"/>
130
+ <text text-anchor="middle" x="119.09" y="-735" font-family="sans" font-size="10.00">step_1_python_pandas_step_1_main_input_validator</text>
131
+ </g>
132
+ <!-- 6&#45;&gt;5 -->
133
+ <g id="edge11" class="edge">
134
+ <title>6&#45;&gt;5</title>
135
+ <path fill="none" stroke="grey" stroke-width="2" d="M119.09,-719.7C119.09,-711.98 119.09,-702.71 119.09,-694.11"/>
136
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="122.59,-694.1 119.09,-684.1 115.59,-694.1 122.59,-694.1"/>
137
+ </g>
138
+ <!-- 7&#45;&gt;4 -->
139
+ <g id="edge10" class="edge">
140
+ <title>7&#45;&gt;4</title>
141
+ <path fill="none" stroke="grey" stroke-width="2" d="M173.29,-575.7C164.48,-567.14 153.71,-556.66 144.09,-547.3"/>
142
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="146.29,-544.57 136.68,-540.1 141.41,-549.58 146.29,-544.57"/>
143
+ </g>
144
+ <!-- 8&#45;&gt;3 -->
145
+ <g id="edge8" class="edge">
146
+ <title>8&#45;&gt;3</title>
147
+ <path fill="none" stroke="grey" stroke-width="2" d="M173.29,-431.7C164.48,-423.14 153.71,-412.66 144.09,-403.3"/>
148
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="146.29,-400.57 136.68,-396.1 141.41,-405.58 146.29,-400.57"/>
149
+ </g>
150
+ <!-- 9 -->
151
+ <g id="node10" class="node">
152
+ <title>9</title>
153
+ <path fill="none" stroke="#d87d56" stroke-width="2" d="M562.49,-252C562.49,-252 335.69,-252 335.69,-252 329.69,-252 323.69,-246 323.69,-240 323.69,-240 323.69,-228 323.69,-228 323.69,-222 329.69,-216 335.69,-216 335.69,-216 562.49,-216 562.49,-216 568.49,-216 574.49,-222 574.49,-228 574.49,-228 574.49,-240 574.49,-240 574.49,-246 568.49,-252 562.49,-252"/>
154
+ <text text-anchor="middle" x="449.09" y="-231" font-family="sans" font-size="10.00">step_4_python_pandas_step_4_secondary_input_validator</text>
155
+ </g>
156
+ <!-- 9&#45;&gt;1 -->
157
+ <g id="edge4" class="edge">
158
+ <title>9&#45;&gt;1</title>
159
+ <path fill="none" stroke="grey" stroke-width="2" d="M386.3,-215.97C346.34,-205.12 294.75,-191.13 254.64,-180.24"/>
160
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="255.54,-176.86 244.97,-177.62 253.7,-183.62 255.54,-176.86"/>
161
+ </g>
162
+ <!-- 10&#45;&gt;1 -->
163
+ <g id="edge5" class="edge">
164
+ <title>10&#45;&gt;1</title>
165
+ <path fill="none" stroke="grey" stroke-width="2" d="M191.09,-215.7C191.09,-207.98 191.09,-198.71 191.09,-190.11"/>
166
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="194.59,-190.1 191.09,-180.1 187.59,-190.1 194.59,-190.1"/>
167
+ </g>
168
+ <!-- 11&#45;&gt;0 -->
169
+ <g id="edge2" class="edge">
170
+ <title>11&#45;&gt;0</title>
171
+ <path fill="none" stroke="grey" stroke-width="2" d="M227.22,-71.7C221.59,-63.47 214.73,-53.48 208.52,-44.42"/>
172
+ <polygon fill="grey" stroke="grey" stroke-width="2" points="211.36,-42.37 202.82,-36.1 205.59,-46.33 211.36,-42.37"/>
173
+ </g>
174
+ </g>
175
+ </svg>