s3dgraphy 1.6.0.dev44__tar.gz → 1.6.0.dev46__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 (546) hide show
  1. {s3dgraphy-1.6.0.dev44/src/s3dgraphy.egg-info → s3dgraphy-1.6.0.dev46}/PKG-INFO +1 -1
  2. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/pyproject.toml +1 -1
  3. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/s3Dgraphy_node_datamodel.json +11 -3
  4. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/__init__.py +1 -1
  5. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/api.py +65 -6
  6. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/crdt.py +4 -2
  7. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/emjson_exporter.py +18 -0
  8. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/graph.py +3 -0
  9. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/hdto.py +227 -14
  10. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/emjson_importer.py +56 -0
  11. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/import_graphml.py +10 -0
  12. s3dgraphy-1.6.0.dev46/src/s3dgraphy/links.py +189 -0
  13. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/emdb/generic_specialfind_mapping.json +1 -1
  14. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/emdb/site_properties_mapping.json +1 -1
  15. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/emdb/usm_mapping.json +1 -1
  16. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/generic/excel_to_graphml_mapping.json +1 -1
  17. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/pyarchinit/pyarchinit_us_mapping.json +1 -1
  18. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/source_list/em_sourcelist_it.json +1 -1
  19. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/source_list/source_list_mapping.json +1 -1
  20. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/template_emdb_mapping.json +1 -1
  21. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/template_pyarchinit_mapping.json +1 -1
  22. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/paradata_view.py +9 -2
  23. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/spatiotemporal.py +82 -0
  24. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/study.py +12 -6
  25. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/graph_projector.py +103 -16
  26. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/graphml_writer.py +50 -16
  27. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46/src/s3dgraphy.egg-info}/PKG-INFO +1 -1
  28. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy.egg-info/SOURCES.txt +3 -0
  29. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dev29_graphml_without_a_database.py +5 -2
  30. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_edge_outside_graph.py +4 -4
  31. s3dgraphy-1.6.0.dev46/tests/test_graph_header_code.py +114 -0
  32. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_hdto_study.py +30 -10
  33. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_resource_file_node.py +1 -1
  34. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_spatiotemporal_entities.py +63 -1
  35. s3dgraphy-1.6.0.dev46/tests/test_stable_study_code.py +305 -0
  36. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/LICENSE +0 -0
  37. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/MANIFEST.in +0 -0
  38. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/README.md +0 -0
  39. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/setup.cfg +0 -0
  40. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/acquisition_descriptor.schema.json +0 -0
  41. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/acquisition_mappings/ercolano.json +0 -0
  42. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/acquisition_mappings/fs.json +0 -0
  43. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/acquisition_mappings/uri.json +0 -0
  44. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/datamodel_translations.json +0 -0
  45. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/em.ttl +0 -0
  46. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/em_document_types.json +0 -0
  47. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/em_extractor_types.json +0 -0
  48. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/em_palette_icons.json +0 -0
  49. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/em_qualia_types.json +0 -0
  50. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/em_qualia_types_additions.json +0 -0
  51. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/em_state_symbols.json +0 -0
  52. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/em_visual_rules.json +0 -0
  53. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/hdto_extension.ttl +0 -0
  54. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/new_qualia_template.json +0 -0
  55. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/node_registry.generated.json +0 -0
  56. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/outdated_s3dgraphy.ttl +0 -0
  57. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/outdated_s3dgraphy_nomapping.ttl +0 -0
  58. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json +0 -0
  59. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json.v155.bak +0 -0
  60. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/ActivityNodeGroup.svg +0 -0
  61. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/EMNarrative.png +0 -0
  62. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/EMNarrative.svg +0 -0
  63. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/EpochNode.svg +0 -0
  64. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/ParadataNodeGroup.svg +0 -0
  65. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/RSF.png +0 -0
  66. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/RSF.svg +0 -0
  67. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/SE.svg +0 -0
  68. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/SE_old.png +0 -0
  69. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/SE_old.svg +0 -0
  70. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/SF.png +0 -0
  71. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/SF.svg +0 -0
  72. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/TSU.png +0 -0
  73. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/US.png +0 -0
  74. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/US.svg +0 -0
  75. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/USD.png +0 -0
  76. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/USD.svg +0 -0
  77. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/USVn.png +0 -0
  78. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/USVn.svg +0 -0
  79. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/USVs.png +0 -0
  80. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/USVs.svg +0 -0
  81. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/UTR.svg +0 -0
  82. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/VSF.png +0 -0
  83. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/VSF.svg +0 -0
  84. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/author.png +0 -0
  85. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/author.svg +0 -0
  86. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/author_ai.png +0 -0
  87. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/author_ai.svg +0 -0
  88. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/combiner.png +0 -0
  89. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/combiner.svg +0 -0
  90. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/container.svg +0 -0
  91. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/continuity.png +0 -0
  92. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/continuity.svg +0 -0
  93. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/document.png +0 -0
  94. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/document.svg +0 -0
  95. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/00_transformation.svg +0 -0
  96. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/01_topographicnetwork.svg +0 -0
  97. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/02_pointcloud.svg +0 -0
  98. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/03_mesh.svg +0 -0
  99. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/04_points.svg +0 -0
  100. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/05_lines.svg +0 -0
  101. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/06_polygons.svg +0 -0
  102. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/07_DEM.svg +0 -0
  103. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/08_ortophoto.svg +0 -0
  104. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/09_photos.svg +0 -0
  105. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/10_laserscanner.svg +0 -0
  106. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device.svg +0 -0
  107. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_computer.svg +0 -0
  108. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_drone.svg +0 -0
  109. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_gnss.svg +0 -0
  110. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_optical.svg +0 -0
  111. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_scanner.svg +0 -0
  112. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_sensor.svg +0 -0
  113. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/11_device_station.svg +0 -0
  114. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/12_gnss_survey.svg +0 -0
  115. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/13_field_drawing.svg +0 -0
  116. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/14_recording_sheet.svg +0 -0
  117. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/15_decimation.svg +0 -0
  118. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/16_georeferencing.svg +0 -0
  119. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/17_format_conversion.svg +0 -0
  120. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/18_classification.svg +0 -0
  121. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/dtc/19_vectorization.svg +0 -0
  122. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/embargo.png +0 -0
  123. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/embargo.svg +0 -0
  124. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/extractor.png +0 -0
  125. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/extractor.svg +0 -0
  126. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/gcp_set.svg +0 -0
  127. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/generic_node.svg +0 -0
  128. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/geo_position.svg +0 -0
  129. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/graph.svg +0 -0
  130. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/license.png +0 -0
  131. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/license.svg +0 -0
  132. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/link.svg +0 -0
  133. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/narrative.png +0 -0
  134. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/narrative.svg +0 -0
  135. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/play.svg +0 -0
  136. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/property.png +0 -0
  137. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/property.svg +0 -0
  138. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/proxy.svg +0 -0
  139. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/registration_transform.svg +0 -0
  140. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/representation_model.svg +0 -0
  141. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/representation_model_doc.svg +0 -0
  142. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/representation_model_sf.svg +0 -0
  143. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/resource_file.svg +0 -0
  144. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/semantic_shape.svg +0 -0
  145. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/serSU.png +0 -0
  146. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/serSU.svg +0 -0
  147. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/serUSD.png +0 -0
  148. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/serUSV.png +0 -0
  149. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/serUSVn.svg +0 -0
  150. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/serUSVs.svg +0 -0
  151. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/tileset.svg +0 -0
  152. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/version_gltf.svg +0 -0
  153. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/version_mesh.svg +0 -0
  154. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/version_scene.svg +0 -0
  155. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/2D/version_tiles.svg +0 -0
  156. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/RSF.glb +0 -0
  157. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/SF.glb +0 -0
  158. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/TSU.glb +0 -0
  159. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/US.glb +0 -0
  160. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/USD.glb +0 -0
  161. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/USVn.glb +0 -0
  162. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/USVs.glb +0 -0
  163. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/VSF.glb +0 -0
  164. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/combiner.glb +0 -0
  165. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/continuity.glb +0 -0
  166. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/document.glb +0 -0
  167. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/extractor.glb +0 -0
  168. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/property.glb +0 -0
  169. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/serSU.glb +0 -0
  170. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/serUSD.glb +0 -0
  171. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/src/3D/serUSV.glb +0 -0
  172. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/JSON_config/version_for_cases.json +0 -0
  173. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/acquisition/__init__.py +0 -0
  174. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/acquisition/acquire.py +0 -0
  175. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/acquisition/descriptor.py +0 -0
  176. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/acquisition/mapping.py +0 -0
  177. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/ai_validation.py +0 -0
  178. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/annotation/__init__.py +0 -0
  179. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/annotation/migrate_reading.py +0 -0
  180. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/annotation/paradata.py +0 -0
  181. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/annotation/reading.py +0 -0
  182. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/authorities/__init__.py +0 -0
  183. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/authorities/resolver.py +0 -0
  184. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/authorities/snapshots/LICENSE +0 -0
  185. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/authorities/snapshots/chronontology.jsonld +0 -0
  186. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/authorities/snapshots/getty_aat.jsonld +0 -0
  187. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/authorities/snapshots/getty_tgn.jsonld +0 -0
  188. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/authorities/snapshots/periodo.jsonld +0 -0
  189. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/authorities/snapshots/provenance.json +0 -0
  190. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/classification.py +0 -0
  191. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/container.py +0 -0
  192. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/contract/__init__.py +0 -0
  193. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/contract/connector.py +0 -0
  194. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/contract/consumer.py +0 -0
  195. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/contract/core.py +0 -0
  196. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/contract/reference.py +0 -0
  197. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/data/StratiMiner_Extraction_Prompt.md +0 -0
  198. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/datamodel.py +0 -0
  199. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/diagnostics.py +0 -0
  200. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/dissemination.py +0 -0
  201. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/dtc/__init__.py +0 -0
  202. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/dtc/capture.py +0 -0
  203. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/dtc/corpus.py +0 -0
  204. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/dtc/devices.py +0 -0
  205. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/dtc/ingest.py +0 -0
  206. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/dtc/neighbourhood.py +0 -0
  207. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/dtc/residency.py +0 -0
  208. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/edges/__init__.py +0 -0
  209. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/edges/connection_resolver.py +0 -0
  210. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/edges/connections_loader.py +0 -0
  211. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/edges/edge.py +0 -0
  212. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/editorial.py +0 -0
  213. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/__init__.py +0 -0
  214. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/docx_exporter.py +0 -0
  215. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/__init__.py +0 -0
  216. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/canvas_generator.py +0 -0
  217. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/edge_generator.py +0 -0
  218. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/epoch_generator.py +0 -0
  219. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/graphml_exporter.py +0 -0
  220. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/graphml_patcher.py +0 -0
  221. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/group_node_generator.py +0 -0
  222. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/node_generator.py +0 -0
  223. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/node_registry.py +0 -0
  224. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/palette_resources.py +0 -0
  225. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/paradata_generator.py +0 -0
  226. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/paradata_image_generator.py +0 -0
  227. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/paradata_node_generators.py +0 -0
  228. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/table_node_generator.py +0 -0
  229. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/graphml/utils.py +0 -0
  230. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/html_exporter.py +0 -0
  231. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/ipynb_exporter.py +0 -0
  232. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/json_exporter.py +0 -0
  233. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/latex_exporter.py +0 -0
  234. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/rdf_exporter.py +0 -0
  235. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/exporter/unified_xlsx_exporter.py +0 -0
  236. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/geometry/__init__.py +0 -0
  237. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/geometry/aton.py +0 -0
  238. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/geometry/gltf.py +0 -0
  239. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/geometry/migrate.py +0 -0
  240. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/geometry/proxy.py +0 -0
  241. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/geometry/reading_glb.py +0 -0
  242. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/geometry/store_backed.py +0 -0
  243. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/geometry/wkt.py +0 -0
  244. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/iiif.py +0 -0
  245. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/__init__.py +0 -0
  246. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/base_importer.py +0 -0
  247. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/csv_importer.py +0 -0
  248. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/fmpxml_importer.py +0 -0
  249. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/mapped_xlsx_importer.py +0 -0
  250. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/metashape_project.py +0 -0
  251. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/pyarchinit_importer.py +0 -0
  252. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/qualia_importer.py +0 -0
  253. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/rdf_importer.py +0 -0
  254. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/sheet_header.py +0 -0
  255. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/source_text.py +0 -0
  256. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/unified_xlsx_importer.py +0 -0
  257. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/xlsx_importer.py +0 -0
  258. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/importer/xml_importer.py +0 -0
  259. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/indices.py +0 -0
  260. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/labels.py +0 -0
  261. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/language.py +0 -0
  262. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/__init__.py +0 -0
  263. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/authoring.py +0 -0
  264. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/mappings/registry.py +0 -0
  265. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/merge/__init__.py +0 -0
  266. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/merge/graph_merger.py +0 -0
  267. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/multigraph/__init__.py +0 -0
  268. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/multigraph/multigraph.py +0 -0
  269. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/narrative/__init__.py +0 -0
  270. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/narrative/bake.py +0 -0
  271. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/narrative/generation.py +0 -0
  272. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/narrative/query.py +0 -0
  273. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/narrative/registry.py +0 -0
  274. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/narrative/site_story.py +0 -0
  275. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/__init__.py +0 -0
  276. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/annotation_region_node.py +0 -0
  277. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/author_node.py +0 -0
  278. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/base_node.py +0 -0
  279. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/combiner_node.py +0 -0
  280. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/document_node.py +0 -0
  281. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/dtc_acquisition_node.py +0 -0
  282. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/dtc_device_node.py +0 -0
  283. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/dtc_node.py +0 -0
  284. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/dtc_process_node.py +0 -0
  285. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/embargo_node.py +0 -0
  286. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/epoch_node.py +0 -0
  287. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/extractor_node.py +0 -0
  288. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/geo_position_node.py +0 -0
  289. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/georeferencing_node.py +0 -0
  290. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/graph_node.py +0 -0
  291. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/group_node.py +0 -0
  292. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/hdt_node.py +0 -0
  293. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/heritage_entity_node.py +0 -0
  294. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/license_node.py +0 -0
  295. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/narrative_node.py +0 -0
  296. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/paradata_node.py +0 -0
  297. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/project_node.py +0 -0
  298. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/property_node.py +0 -0
  299. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/representation_node.py +0 -0
  300. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/resource_file_node.py +0 -0
  301. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/resource_node.py +0 -0
  302. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/semantic_shape_node.py +0 -0
  303. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/stratigraphic_node.py +0 -0
  304. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/study_node.py +0 -0
  305. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/nodes/translation_node.py +0 -0
  306. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/ownership.py +0 -0
  307. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/photogrammetry/__init__.py +0 -0
  308. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/photogrammetry/delta.py +0 -0
  309. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/project_tree.py +0 -0
  310. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/property_source.py +0 -0
  311. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/publication.py +0 -0
  312. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/rapporti.py +0 -0
  313. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resolvers/__init__.py +0 -0
  314. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resolvers/builtin_rules.py +0 -0
  315. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resolvers/property_resolver.py +0 -0
  316. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resources/__init__.py +0 -0
  317. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resources/addresses.py +0 -0
  318. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resources/files.py +0 -0
  319. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resources/fs_backend.py +0 -0
  320. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resources/locate.py +0 -0
  321. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resources/minio_backend.py +0 -0
  322. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resources/resolver.py +0 -0
  323. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resources/tiles3tz.py +0 -0
  324. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/resources/versions.py +0 -0
  325. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/rights.py +0 -0
  326. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/shelf/__init__.py +0 -0
  327. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/shelf/core.py +0 -0
  328. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/stamp/__init__.py +0 -0
  329. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/stamp/absorb.py +0 -0
  330. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/stamp/emit.py +0 -0
  331. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/stamp/hints.py +0 -0
  332. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/stamp/identity.py +0 -0
  333. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/__init__.py +0 -0
  334. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/_db_handle.py +0 -0
  335. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/_legacy_paradata_svgs.py +0 -0
  336. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/_workspace.py +0 -0
  337. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/conflict_resolver.py +0 -0
  338. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/edge_registry.py +0 -0
  339. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/graph_ingestor.py +0 -0
  340. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/group_projector.py +0 -0
  341. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/group_store.py +0 -0
  342. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/ingest_result.py +0 -0
  343. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/paradata_store.py +0 -0
  344. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/pyarchinit_pg_importer.py +0 -0
  345. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/rapporti.py +0 -0
  346. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/uuid7.py +0 -0
  347. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/vocab_provider_core.py +0 -0
  348. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/vocab_types.py +0 -0
  349. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/yed_classifier.py +0 -0
  350. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/yed_detector.py +0 -0
  351. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/yed_group_walker.py +0 -0
  352. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/yed_import_pipeline.py +0 -0
  353. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/yed_rapporti_policy.py +0 -0
  354. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/sync/yed_table_parser.py +0 -0
  355. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/templates/em_data_template.xlsx +0 -0
  356. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/templates/em_palette_template.graphml +0 -0
  357. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/temporal/__init__.py +0 -0
  358. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/temporal/inference_engine.py +0 -0
  359. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/tools/__init__.py +0 -0
  360. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/tools/consumer_drift.py +0 -0
  361. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/tools/datamodel_i18n.py +0 -0
  362. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/tools/deliverable_report.py +0 -0
  363. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/tools/glyph_sheet.py +0 -0
  364. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/tools/glyphs_from_svg.py +0 -0
  365. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/tools/node_finder.py +0 -0
  366. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/tools/sync_node_datamodel.py +0 -0
  367. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/tools/wheel_drift.py +0 -0
  368. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/transforms/__init__.py +0 -0
  369. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/transforms/aux_tracking.py +0 -0
  370. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/transforms/compact.py +0 -0
  371. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/transforms/materialize_continuity.py +0 -0
  372. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/translation.py +0 -0
  373. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/utils/__init__.py +0 -0
  374. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/utils/utils.py +0 -0
  375. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/utils/visual_layout.py +0 -0
  376. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy/zero_hour.py +0 -0
  377. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy.egg-info/dependency_links.txt +0 -0
  378. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy.egg-info/requires.txt +0 -0
  379. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/src/s3dgraphy.egg-info/top_level.txt +0 -0
  380. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_acquisition.py +0 -0
  381. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_acquisition_fs.py +0 -0
  382. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_add_resource.py +0 -0
  383. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_ai_validation_nodes.py +0 -0
  384. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_alternative_labels.py +0 -0
  385. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_api_surface.py +0 -0
  386. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_asset_dtc_protocol.py +0 -0
  387. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_asset_versions.py +0 -0
  388. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_aton_shapes.py +0 -0
  389. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_attach_only.py +0 -0
  390. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_authority_projection.py +0 -0
  391. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_authority_resolver.py +0 -0
  392. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_blend_locator.py +0 -0
  393. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_canonical_document_rename.py +0 -0
  394. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_canvas_metadata_import.py +0 -0
  395. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_capture_acquisition.py +0 -0
  396. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_capture_rdf_class.py +0 -0
  397. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_chronology_on_request.py +0 -0
  398. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_coating_unit.py +0 -0
  399. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_composite_node_name.py +0 -0
  400. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_connection_resolver.py +0 -0
  401. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_consumer_drift.py +0 -0
  402. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_container.py +0 -0
  403. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_container_layouts.py +0 -0
  404. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_containment_tpq.py +0 -0
  405. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_contract.py +0 -0
  406. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_contract_consumer.py +0 -0
  407. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_convert_command.py +0 -0
  408. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_crdt.py +0 -0
  409. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_cycle_message_is_cheap.py +0 -0
  410. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_datamodel_fingerprint.py +0 -0
  411. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_datamodel_i18n.py +0 -0
  412. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_deterministic_ids.py +0 -0
  413. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dev29_em_sourcelist.py +0 -0
  414. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dev29_file_set_stamp.py +0 -0
  415. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dev29_image_set_texturing.py +0 -0
  416. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dev29_not_georeferenced.py +0 -0
  417. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dev29_one_act_n_outputs.py +0 -0
  418. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dev29_ttl_round_trip.py +0 -0
  419. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dev30_decisions.py +0 -0
  420. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_devices.py +0 -0
  421. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dissemination_tombstones.py +0 -0
  422. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dove_sta_il_testo.py +0 -0
  423. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dtc_corpus.py +0 -0
  424. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dtc_ingest.py +0 -0
  425. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dtc_neighbourhood.py +0 -0
  426. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dtc_projection.py +0 -0
  427. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_dtc_residency.py +0 -0
  428. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_edge_ui_phrases.py +0 -0
  429. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_editorial.py +0 -0
  430. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_em_ttl_matches_the_datamodels.py +0 -0
  431. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_emjson_no_drawing_keys.py +0 -0
  432. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_emjson_roundtrip.py +0 -0
  433. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_emjson_schema_version.py +0 -0
  434. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_epoch_properties_and_sub_epochs.py +0 -0
  435. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_epoch_undated_import.py +0 -0
  436. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_explicit_node_type_marker.py +0 -0
  437. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_extracted_from_unit.py +0 -0
  438. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_filtered_import.py +0 -0
  439. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_fmpxml_importer.py +0 -0
  440. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_fs_backend.py +0 -0
  441. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_functional_units.py +0 -0
  442. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_georeference_scene.py +0 -0
  443. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_gltf_stitch.py +0 -0
  444. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_glyph_paths.py +0 -0
  445. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_graph_helpers_indexed.py +0 -0
  446. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_graph_indices_alive.py +0 -0
  447. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_graph_indices_edges.py +0 -0
  448. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_graph_scope_migration.py +0 -0
  449. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_hdto_projection.py +0 -0
  450. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_header_key_aliases.py +0 -0
  451. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_i_generi_dei_passi.py +0 -0
  452. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_iiif.py +0 -0
  453. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_il_modo_d_accesso.py +0 -0
  454. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_il_modo_dal_relay.py +0 -0
  455. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_il_proprietario_si_legge.py +0 -0
  456. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_il_riallineamento.py +0 -0
  457. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_importer_edge_hygiene.py +0 -0
  458. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_ipynb_exporter.py +0 -0
  459. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_issue27_small_points.py +0 -0
  460. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_la_lingua_alla_nascita.py +0 -0
  461. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_la_lingua_dei_dati.py +0 -0
  462. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_la_lingua_nell_op.py +0 -0
  463. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_la_riga_d_intestazione.py +0 -0
  464. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_latex_exporter.py +0 -0
  465. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_le_traduzioni.py +0 -0
  466. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_lod_levels.py +0 -0
  467. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_lossless_roundtrip.py +0 -0
  468. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_mapping_authoring.py +0 -0
  469. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_mapping_csv_and_relations.py +0 -0
  470. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_masonry_unit.py +0 -0
  471. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_material_color.py +0 -0
  472. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_merge_conflicts.py +0 -0
  473. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_metashape_project.py +0 -0
  474. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_migrate_legacy_proxy.py +0 -0
  475. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_minio_backend.py +0 -0
  476. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_narrative_authorship.py +0 -0
  477. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_narrative_bake_docx.py +0 -0
  478. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_narrative_figures.py +0 -0
  479. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_narrative_generation.py +0 -0
  480. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_narrative_mentions.py +0 -0
  481. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_narrative_node.py +0 -0
  482. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_narrative_query.py +0 -0
  483. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_narrative_scaffolder.py +0 -0
  484. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_narrative_site_place.py +0 -0
  485. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_narrative_unvalidated_export.py +0 -0
  486. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_node_datamodel_registry.py +0 -0
  487. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_node_finder.py +0 -0
  488. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_node_type_map_integrity.py +0 -0
  489. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_one_resolver.py +0 -0
  490. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_one_spelling_writers.py +0 -0
  491. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_op_vocabulary.py +0 -0
  492. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_pg_importer.py +0 -0
  493. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_photogrammetry_delta.py +0 -0
  494. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_physical_relation_spellings.py +0 -0
  495. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_piu_indirizzi.py +0 -0
  496. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_promotion.py +0 -0
  497. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_property_as_source.py +0 -0
  498. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_property_owners.py +0 -0
  499. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_proxy_resource.py +0 -0
  500. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_proxy_retype.py +0 -0
  501. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_psx_locator.py +0 -0
  502. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_pyarchinit_tier2.py +0 -0
  503. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_qualia_dai_d7_d8.py +0 -0
  504. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_rdf_embedding.py +0 -0
  505. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_rdf_reverse_edges.py +0 -0
  506. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_rdf_roundtrip.py +0 -0
  507. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_reading_coords.py +0 -0
  508. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_reading_glb.py +0 -0
  509. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_reading_migration.py +0 -0
  510. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_reading_place.py +0 -0
  511. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_reading_rdf.py +0 -0
  512. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_recompute_warnings.py +0 -0
  513. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_release.py +0 -0
  514. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_reproject.py +0 -0
  515. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_resource_files_implicit.py +0 -0
  516. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_resource_layer.py +0 -0
  517. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_resource_representations.py +0 -0
  518. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_resource_revision.py +0 -0
  519. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_resource_tier.py +0 -0
  520. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_reverse_edges.py +0 -0
  521. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_rm_container_node_group.py +0 -0
  522. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_semantic_purity.py +0 -0
  523. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_shelf.py +0 -0
  524. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_shelf_facets.py +0 -0
  525. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_shelf_hatting.py +0 -0
  526. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_shelf_role_uri_table.py +0 -0
  527. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_shipped_mappings.py +0 -0
  528. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_source_list_mapping.py +0 -0
  529. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_source_text.py +0 -0
  530. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_stamp.py +0 -0
  531. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_stamp_hints.py +0 -0
  532. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_stamp_title_description.py +0 -0
  533. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_store_backed_geometry.py +0 -0
  534. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_stratiminer_api.py +0 -0
  535. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_study_metadata.py +0 -0
  536. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_tileset_resource.py +0 -0
  537. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_ttl_roundtrip.py +0 -0
  538. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_unit_definition.py +0 -0
  539. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_verifica_provenance.py +0 -0
  540. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_version_for.py +0 -0
  541. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_visual_assets.py +0 -0
  542. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_wheel_drift.py +0 -0
  543. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_xlsx_containment_and_unknown_bounds.py +0 -0
  544. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_xlsx_importer_graph_init.py +0 -0
  545. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_xlsx_source_column.py +0 -0
  546. {s3dgraphy-1.6.0.dev44 → s3dgraphy-1.6.0.dev46}/tests/test_zero_hour.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: s3dgraphy
3
- Version: 1.6.0.dev44
3
+ Version: 1.6.0.dev46
4
4
  Summary: 3D Stratigraphic Graph Management Library for archaeological and heritage applications
5
5
  Author-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
6
6
  Maintainer-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "s3dgraphy"
7
- version = "1.6.0.dev44"
7
+ version = "1.6.0.dev46"
8
8
  description = "3D Stratigraphic Graph Management Library for archaeological and heritage applications"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,6 +1,6 @@
1
1
  {
2
- "s3Dgraphy_data_model_version": "1.6.29",
3
- "description": "v1.6.29 (giro dell'11 ottobre, decided by E.D. 2026-10-11): the code of a graph is the code of its STUDY — StudyNode.code replaces the graph-self node's retired «EM-ID» (GraphNode.data.em_id, never a field of this datamodel): a file that has one keeps it and s3dgraphy.hdto.migrate_em_id carries it to the study's code only when the study exists and has none. A saggio is a study AND a place: its LocationNodeGroup (kind study) is in the site (is_in_location), the study took place at it. Descriptions only, no field added. v1.6.28 (MICRO lo studio usabile, decided by E.D. 2026-10-10: the stratigraphic trench is a STUDY, the site is TOPOGRAPHY, HC1 is heritage only where recognised): StudyNode gains `study_kind` (stratigraphic_excavation | survey | documentation | other) — a stratigraphic_excavation is ALSO a crmarchaeo:A9_Archaeological_Excavation, declared per value in the field (`subclass_of_by_value`, the same subclass_of form the classes use) and emitted by the RDF exporter as a second rdf:type — and `code` (the short name of the study, e.g. GT16: what the source gives, or what the user writes; never derived; the label prefix reads it). HC9 Study is aligned to crm:E65_Creation (was crm:E7_Activity; E65 ⊑ E7), HC1 Heritage Entity to crm:E70_Thing (was crm:E1_CRM_Entity), as the official HDT-O RDFS says (HDT_v2.0.1.rdf, ECHOES D7.1). The study reaches its place with study_took_place_at (crm:P7_took_place_at, connections 1.6.39). v1.6.27 (MICRO le entità spaziotemporali, decided by E.D. 2026-10-10): DocumentNode and AuthorNode (with AuthorAINode) are SPATIOTEMPORAL ENTITIES like the stratigraphic units — the top-level block `spatiotemporal_entities` names the three classes and what they share: a start and an end (absolute_time_start / absolute_time_end, read with the label of their owner: a person is born and dies, a model is released and retired), the lane of the matrix where they begin (has_first_epoch) and the ones they last through (survive_in_epoch), their place in the sequence (is_after, has_same_time), an activity. The edges are widened in connections 1.6.38; the chronology dates the three with the same rules (Graph.CHRONOLOGY_TYPES). AuthorNode and DocumentNode gain a `spatiotemporal` element saying how their time reads; no field of theirs changes. v1.6.26 (H4, decided by E.D. 5 Oct 2026, «Heriverse legge l'em.json e sceglie la versione»): ResourceNode.use admits two more uses, heriverse and aton — a version made FOR a viewer, the package on disk that Heriverse or another ATON app opens offline (EM Tools makes it with «Prepare for a use…», as is: no optimisation of its own); a viewer asks heriverse, aton, web, realtime in that order (s3dgraphy.resources.versions.choose_version). v1.6.25 (D1, MICRO un solo vocabolario, decided by E.D. 4 Oct 2026): GeoPositionNode.rotation_reference = 'grid' (D2: the rotation is measured from the GRID north of the CRS). ResourceNode.lod_level (em:lodLevel, computed from the chain, written only on export and checked at load), ResourceNode.use (em:use, a list of analysis | realtime | web | mobile_ar | print | render | preview) and seven measures of a version (em:trisPerM2, em:texelDensityDD, em:textureCount, em:textureSidePx, em:uvRatio, em:reductionFromLod0, em:geometricErrorM). v1.6.24 (dev30, decided by E.D. 2026-10-02 on the dev29 report): DTCAcquisitionNode.retrieved_from — where a retrieved object came from, a DOI or a URL (em:retrievedFrom, D1; optional, validate warns «download without origin»). ResourceNode.members_digest names em:membersDigest, the digest of a file_set with a predicate of its own beside em:checksum + em:digestCovers (D4; not a second field). ResourceNode.packaging carries its vocabulary with values and labels, translated in datamodel_translations.json (packagings; A3). ResourceNode.content_digest also holds the digest of the data of a master inside another file — a Metashape model's mesh.ply — compared, never verified by downloading (D7). GCPSetNode gains data.control (ground_control_points | camera_positions) and data.accuracy_m: a chunk referenced only by its cameras' GPS is absolute with the control said for what it is, and validate warns «georeferenced only by camera GPS» (D7). Node.properties.lang states the one explicit exception to the AI marker: a recognised language confirmed by a person is data.lang only (U5). CRMem 1.6.14. v1.6.23 (dev29, 2026-10-02, measured on San Pietro): seven properties that the round trip em.json → TTL → em.json lost now leave and come back — ResourceNode packaging / tier / digest_covers / content_digest (em:packaging, em:tier, em:digestCovers, em:contentDigest) and the declared fields of a DTC step, technique / parameters / software (em:technique, em:parameters, em:software, the last two as rdf:JSON). digest_covers admits members (a file_set). The blend:// locator stays out of RDF on purpose: it is a private path. v1.6.22 (dev28, 2026-11-01, decided by E.D. 2026-10-01 on the dev27 report): the access mode of a signature (created_auth / modified_auth / validated_auth) admits a third mode, 'declared' — an iD typed in a tool's preferences and checked by nobody (EMStudio's declared identity, EM Tools' local identity), with no attested_by; through a relay the mode is the relay's, read from the token (crdt.stamp_auth), not the client's declaration. The language a node is born in travels in the add_node op (crdt.make_op requires it of the producer, 'und' when unknown); the study's language is read only for old ops, said and counted. CRMem 1.6.12. v1.6.21 (dev27, 2026-10-31, decided by E.D. 2026-10-01, «il testo, la risorsa e la selezione» and «l'accesso sul campo»): ResourceNode.properties gains lang — on a resource the language(s) of its CONTENT, one tag or a sorted list, leaving as dcterms:language and outside the cascade of the texts — addresses (several addresses of ONE resource, same digest: em:hasAddress with em:locator, em:residency, em:checkedAt, em:reachable) and checksum_at (a dated digest, em:checksumAt). Node.properties gains created_auth / modified_auth / validated_auth: how the hand of a signature had entered, {mode: orcid | node_password, attested_by} (em:createdVia / em:modifiedVia / em:validatedVia, em:authMode, em:attestedBy). data.lang is written at birth (s3dgraphy.language.stamp_birth_language), also when equal to the study's. v1.6.20 (MICRO le traduzioni, 2026-10-29, decided by E.D. 2026-10-01, «Le traduzioni»): NEW TranslationNode (TRANSL, crm:E33_Linguistic_Object) — ONE translation of one text field of one node. The original stays a string in its field (data.lang on the node, else the study's), never overwritten; each translation is a node reached by has_translation (crm:P73_has_translation, connections 1.6.34) with data.lang (arrival), data.from_lang (departure, written because the original can change), data.field (CRDT vocabulary: description | data.<key>; a PropertyNode's value is data.value; never name), data.text, data.method (manual | ai | edition), data.source_digest (sha256 of the original translated: a different digest = «da riallineare») and data.review_requested («da rivedere»). Who: has_author; AI: data.ai_assisted, unverified until validated_by; an edition: extracted_from → the DocumentNode. RDF (em.ttl 1.6.10): Node.properties.lang names em:originalLanguage — the node's own data.lang leaves as that literal whenever it is declared, equal to the study's too, so a reader tells the original literal from the translations that share its predicate and the round trip gives data.lang back exactly where it was (the D.1 limit of 1.6.19 is closed); the TranslationNode's fields name em:sourceLanguage, em:translatedField, em:translationMethod, em:sourceDigest, em:reviewRequested. v1.6.19 (MICRO la lingua dei dati, 2026-10-27, decided by E.D. 2026-09-28): Node.properties.description becomes an object {cidoc: P3_has_note, natural_language: true, note} — the MARKER that says the description is text in a natural language and leaves in RDF with its language tag; declared once on the base class and inherited by every node type. name is NOT marked: names are invariant identities. No field added, no node element, no graph change: the em.json is the same; only the RDF literal gains its tag. v1.6.18 (MICRO i termini di em.ttl nel datamodel, 2026-10-26, decided by E.D. 2026-10-01 — the datamodel JSON is the truth, so every em: term of em.ttl is cited by a datamodel or is a written exception): the em: predicates the RDF exporter already writes are now NAMED in properties, as plain-string mapping notes (no field added, no node element, no graph change). Node (inherited by every class): the last-hand stamps created_by em:createdBy / modified_by em:lastEditedBy / modified_at em:modifiedAt (created_at prov:generatedAtTime), the tombstone removed.ts em:removedAt / removed.by em:removedBy, the AI marker ai_assisted.by em:aiAssistedBy / .model em:aiModel / .prompt_ref em:aiPromptRef / .fields em:aiAssistedField and the verification validated_by em:validatedBy / validated_at em:validatedAt (properties_note). ResourceNode: checksum em:checksum, scope em:resourceScope, residency em:residency. SemanticShapeNode: convexshapes em:convexShape, spheres em:sphere. AnnotationRegionNode: crs em:crs, coords.frame_iri em:LocalSceneFrame. AuthorNode and AuthorAINode: verified em:orcidVerified (AuthorAINode also names orcid P48, which the exporter writes for both). LocationNodeGroup.propagation.mapping: uri em:propagation. THREE ENTRIES CORRECTED TO WHAT THE CODE WRITES (measured in rdf_exporter.py): PropertyNode.property_type was P2_has_type, is em:hasQualiaType; AuthorAINode model / prompt_reference were P3_has_note, are em:modelIdentifier / em:promptReference; ResourceFileNode.checksum was P1_is_identified_by, is em:checksum; and LocationNodeGroup.propagation said 'not serialized to triplestore' while the exporter has written the non-default value as em:propagation since c1a702c (2026-08-12). v1.6.17 (MICRO la risorsa e i suoi file, 2026-10-18, decided by E.D. 2026-09-30): NEW ResourceFileNode (FILE, crmdig:D1_Digital_Object) — the ResourceNode is the set, the ResourceFileNode is each file, reached by has_file (connections 1.6.30) with role and relative path on the edge. With one file the node is implicit (url and checksum stay on the ResourceNode, as today). ResourceNode.PACKAGINGS += file_set (a few files that call each other: obj → mtl → textures, gltf → bin, shp and companions) and datablock (one object inside a file, a blend:// locator). Representations of the same thing are sibling ResourceNodes tied by dtc_derived_from and chosen by tier and packaging. ADDITIVE: nothing narrowed, no graph changes. v1.6.16 (MICRO le annotazioni ATON sull'asset, 2026-10-15, decided by E.D.): AnnotationRegionNode gains geometry_kind 'volume' — an annotation that encloses a part of a 3D model (ATON / Hathor convex hulls and spheres) and is the proxy of no unit. The region carries no vertices: it reaches a SemanticShapeNode (convexshapes, spheres) with has_semantic_shape and the model with is_on_resource. geometry.aton.import_aton_scene makes one for every semantic id no EM node is named after (a stratigraphic unit only with an explicit create_type); api.promote_region_to_proxy turns it into the proxy of a unit later. RDF: P2_has_type 'volume', no selector, no WKT; the shape travels as itself. Additive. v1.6.15 (MICRO la geometria per origine, 2026-10-11, decided by E.D. 2026-09-30): AnnotationRegionNode's point / line / polyline keep their vertices IN THE NODE, data.coords [[x, y, z], ...] (scene-local, glTF Y-up, metres) with crs and, for a line or a polyline, length and unit — no .glb and no SemanticShape for a reading. New block coords (inline_max_vertices 500: above it the vertices go to a .glb resource via has_linked_resource, with a warning). RDF: geo:hasGeometry -> <region>/geometry geo:asWKT (POINT Z / LINESTRING Z, GeoSPARQL). The readings/<id>.glb of 2026-10-06 are migrated on opening. v1.6.14 (MICRO la cattura in RDF, 2026-09-30): DTCAcquisitionNode.mapping.by_kind — its D12 is the class of a retrieval; a capture takes the class its kind declares in em_visual_rules 1.6.24 (D2 / D11 / E65). Mapping text only, no field changed. v1.6.13 (MICRO i generi delle US, 2026-09-30, decided by E.D. the same day): stratigraphic_kind gains 'coating' — the USR (rivestimento) and its English translation USS (surface): plaster, floors, revetments — with `labels`, `codes` and `default_code` per kind; new node element `source_code` (data.source_code) keeps the code a unit came in with when it is not its kind's default, so the way back to pyArchInit gives the same code. A legacy node_type 'USR' / 'USS' opens as US + coating. v1.6.12 (MICRO la cattura nel DTC e le murature, 2026-09-30): StratigraphicUnit (US) gains the node element `stratigraphic_kind` (em.json data.stratigraphic_kind; today one value, 'masonry'): a USM is a US + masonry, and the legacy node_type 'USM' — never a type of this datamodel — opens as that. DTCAcquisitionNode's description names the two families of the acquisition axis (em_visual_rules 1.6.22: capture / retrieval). v1.6.11 (MICRO la misura in RDF, 2026-10-07): AnnotationRegionNode.properties says how the fields left unprojected by 1.6.10 now travel — the quote of a passage as oa:TextQuoteSelector, the length of a line/polyline as crm:E54_Dimension (P90 value, P91 QUDT unit, em:crs), vertex_count as em:vertexCount. CRMem (em.ttl) 1.6.5 -> 1.6.6. Mapping text only, no field changed. v1.6.10 (MICRO la geometria della lettura, 2026-10-06, decided by E.D. on 2026-09-29): AnnotationRegionNode becomes the node of THE PLACE A READING LOOKED AT, with a new field geometry_kind: region2d (default, every older region), passage (start, end, text), point, line, polyline. The three 3D kinds keep their coordinates in a .glb (glTF POINTS / LINES / LINE_STRIP) linked with has_semantic_shape exactly like a proxy's payload, never in the em.json; the node keeps vertex_count and, for line/polyline, length + unit + crs (api.measure). See the entry's geometry_kinds and glb_payload. Paired with connections 1.6.27 (is_on_resource.target += the representation models). Additive: a region without geometry_kind reads as region2d. v1.6.9 (MICRO la definizione dell'unita', 2026-10-20, decided by E.D. on 2026-09-27): StratigraphicNode.properties gains `definition`, the DEFINIZIONE of the US sheet, as an element of the node like name and description and NOT a qualia. Value = a controlled-vocabulary concept {concept, label}; em.json carries it as data.definition (CRDT field 'data.definition', no change to the frozen em.json v1 node shape); inherited by every stratigraphic subtype. The RDF projection is declared in the entry itself (`rdf`): crm:P2_has_type -> crm:E55_Type when a concept URI is present, nothing when only a label is (`label_only: null`). CRMem 1.6.4 -> 1.6.5 for the companion em:hasDefinition (subproperty of crm:P2_has_type, declared, not emitted by default). Additive only. v1.6.7 (CRMem WIRING, 2026-09-24): rimosso il campo legacy `cidoc_s3d` da tutte le mapping. Non era letto da nessuna parte del codice e portava quattro nomi di classe senza namespace, mai dichiarati e mai emessi: EpochNode = StratigraphicTimeframe; ActivityNodeGroup = StratigraphicActivity; ParadataNodeGroup = ParadataCollection; ResourceNode = ExternalResourceReference. Il prefisso CIDOC-S3D non esiste piu' in nessuno dei due datamodel. v1.6.6 (CIDOC REPAIR, 2026-09-21): classes that pointed at IRIs nobody declares. Checked by parsing the official releases, not from memory. crm:E78_Collection is gone from CIDOC CRM 7.1.3 — renamed E78_Curated_Holding — and E.D. decided NOT to follow the rename, because E78_Curated_Holding is a subclass of E24 Physical Human-Made Thing and a group of nodes is not a physical thing. The three classes that carried it therefore split, each to the class it actually is: GroupNode and RepresentationModelNodeGroup to crm:E73_Information_Object (a conceptual set, and an E90 Symbolic Object, which is what the P106i membership edge needs at both ends), ParadataNodeGroup to crm:E89_Propositional_Object — which is what a gathered body of reasoning IS and what the range of crm:P129i_is_subject_of demands, that being the predicate has_paradata_nodegroup takes in connections 1.6.17 the same day; it stays an E90 through em:NodeGroup, so the membership edge does not break. SemanticShapeNode leaves crmgeo:SP5_Geometric_Place_Expression for crm:E73_Information_Object, PROVVISORIAMENTE: SP5 is not declared at the crmgeo namespace this datamodel emits, crmgeo:SP6_Declarative_Place is the better candidate, and the decision is rinviata da E.D. — E73 commits to nothing meanwhile. crm:P131_is_identified_by, deprecated in CRM 7.x together with E82 Actor Appellation, becomes crm:P1_is_identified_by on AuthorNode (name, surname) and AuthorAINode (name). «CRMs3D» is renamed «CRMem», in components and in referenced_ontology_versions alike: the companion ontology is em.ttl and its namespace is em:, so the old name pointed at nothing anyone could look up. CRMsci moves 3.1 -> 3.2 (latest release). The eight em: terms this file and the connections datamodel cite but em.ttl never defined are now declared there (em:FunctionalUnit, em:GCPSet, em:Narrative, em:NeutralSU, em:RegistrationTransform, em:RepresentationModelNodeGroup, em:hasSubEpoch, em:validatedBy), with domain, range and superclass read off these datamodels and nothing invented. NOT TOUCHED: the `alternative` and legacy `cidoc_s3d` prose fields, which still discuss E78 as an option — prose, not a projection, and rewording them is modelling rather than repair. v1.6.5 (EM16-RMNG, 2026-09-10): adds RepresentationModelNodeGroup, the RM container as a first-class group of the graph — sixth subtype of GroupNode, keeping the parent's E78 Collection because a container IS a curatorial set. Paired with connections datamodel 1.6.14, which adds the is_in_representation_model_group membership edge and widens has_representation_model.target to accept the group. Additive only: no existing entry changed. s3Dgraphy nodes datamodel including node types with CIDOC-CRM mappings. v1.6.4 adds the ADDITIVE georeferencing_nodes section (GCPSetNode = em:GCPSet, RegistrationTransformNode = em:RegistrationTransform, both subclasses of crm:E73_Information_Object with their own extension URIs so the RDF projection stays bijective): the CONTROL and the SOLUTION that place a produced model in the world, introduced with the photogrammetry processing connector. The two modes of that connector are the SHAPE of the graph (a transform with a CRS that has_gcp_set points at = absolute; a transform with crs=null and no control set = a site-local frame; no transform at all = nobody placed it), never a flag. No existing family changed. v1.6.3 re-reads SemanticShapeNode as a PAYLOAD carrier: the proxy of a unit is now a PropertyNode of qualia type 'geometry' that points at the shape (has_semantic_shape), so the proxy inherits the paradata chain it never had. Breaking for consumers that read the proxy as a standalone SemanticShape. v1.6.2 adds AnnotationRegionNode (em:AnnotationRegion, subclass of crm:E36_Visual_Item): the geometry of a 2D annotation in NORMALISED image space, distinct from SemanticShapeNode (3D scene geometry, crmgeo:SP5) - the semantics of the 2D annotator, defined before any canvas exists. v1.6.0 inaugurates a systematic CIDOC-CRM mapping revision: complete audit of all node types against CIDOC-CRM, CRMarchaeo, CRMinf, CRMdig, CRMsci, CRMgeo; replacement of legacy 'cidoc_s3d' pseudo-class names (invented strings without IRI or superclass declaration) with formal em:/s3d: IRIs declared as proper subclasses of CRM classes; introduction of CRMinf as primary (not alternative) for the paradata chain (ParadataNode, PropertyNode interpretive case, ExtractorNode, CombinerNode); introduction of PROV-O for AuthorNode to cover both human and AI agents; alignment with the Heritage Digital Twin Ontology (HDT-O) for containment / granularity properties; LocationNodeGroup (v1.5.3) adopted as the reference pattern (CIDOC-native composition via P2_has_type → E55 Type instances, with explicit extension_status and rationale). Companion deliverables: em.ttl (formal EM extension ontology, dereferenceable via w3id.org/em/) and hdto_extension.ttl (HDT-O granularity properties: contains_HDT, contains_SU, isPrimary). v1.5.4 added RSF (Reused Special Find — spolia) as a stratigraphic subtype, octagon with red border, family=real, is_series=false. Originating DP: DP-26 (spolia project, last DP before the EM 1.5 cut). v1.5.3 added LocationNodeGroup (E53 Place + E55 Type) for spatial / locational membership orthogonal to ActivityNodeGroup (intention) and EpochNode (time). v1.5.2 added family + is_series classification metadata on stratigraphic subtypes.",
2
+ "s3Dgraphy_data_model_version": "1.6.30",
3
+ "description": "v1.6.30 (giro dell'11 ottobre (2), decided by E.D. 2026-10-11, «il codice di studio è stabile»): StudyNode.code is STABLE — once a study has one it never changes by itself (import, export, migration, projection): it is what Blender re-attaches the proxies by (GT16.1.USM100). Read: the study's code, else the GraphML header ID (graph_code), else the retired em_id (read only). A GraphML's header ID is written on the study at import. When there is none, s3dgraphy.hdto.propose_study_code writes ONE proposal (site initials + the year of the study's date, -2/-3 against the other codes of the container) and marks it with the new field `code_proposed` until the user confirms it. v1.6.29 (giro dell'11 ottobre, decided by E.D. 2026-10-11): the code of a graph is the code of its STUDY — StudyNode.code replaces the graph-self node's retired «EM-ID» (GraphNode.data.em_id, never a field of this datamodel): a file that has one keeps it and s3dgraphy.hdto.migrate_em_id carries it to the study's code only when the study exists and has none. A saggio is a study AND a place: its LocationNodeGroup (kind study) is in the site (is_in_location), the study took place at it. Descriptions only, no field added. v1.6.28 (MICRO lo studio usabile, decided by E.D. 2026-10-10: the stratigraphic trench is a STUDY, the site is TOPOGRAPHY, HC1 is heritage only where recognised): StudyNode gains `study_kind` (stratigraphic_excavation | survey | documentation | other) — a stratigraphic_excavation is ALSO a crmarchaeo:A9_Archaeological_Excavation, declared per value in the field (`subclass_of_by_value`, the same subclass_of form the classes use) and emitted by the RDF exporter as a second rdf:type — and `code` (the short name of the study, e.g. GT16: what the source gives, or what the user writes; never derived; the label prefix reads it). HC9 Study is aligned to crm:E65_Creation (was crm:E7_Activity; E65 ⊑ E7), HC1 Heritage Entity to crm:E70_Thing (was crm:E1_CRM_Entity), as the official HDT-O RDFS says (HDT_v2.0.1.rdf, ECHOES D7.1). The study reaches its place with study_took_place_at (crm:P7_took_place_at, connections 1.6.39). v1.6.27 (MICRO le entità spaziotemporali, decided by E.D. 2026-10-10): DocumentNode and AuthorNode (with AuthorAINode) are SPATIOTEMPORAL ENTITIES like the stratigraphic units — the top-level block `spatiotemporal_entities` names the three classes and what they share: a start and an end (absolute_time_start / absolute_time_end, read with the label of their owner: a person is born and dies, a model is released and retired), the lane of the matrix where they begin (has_first_epoch) and the ones they last through (survive_in_epoch), their place in the sequence (is_after, has_same_time), an activity. The edges are widened in connections 1.6.38; the chronology dates the three with the same rules (Graph.CHRONOLOGY_TYPES). AuthorNode and DocumentNode gain a `spatiotemporal` element saying how their time reads; no field of theirs changes. v1.6.26 (H4, decided by E.D. 5 Oct 2026, «Heriverse legge l'em.json e sceglie la versione»): ResourceNode.use admits two more uses, heriverse and aton — a version made FOR a viewer, the package on disk that Heriverse or another ATON app opens offline (EM Tools makes it with «Prepare for a use…», as is: no optimisation of its own); a viewer asks heriverse, aton, web, realtime in that order (s3dgraphy.resources.versions.choose_version). v1.6.25 (D1, MICRO un solo vocabolario, decided by E.D. 4 Oct 2026): GeoPositionNode.rotation_reference = 'grid' (D2: the rotation is measured from the GRID north of the CRS). ResourceNode.lod_level (em:lodLevel, computed from the chain, written only on export and checked at load), ResourceNode.use (em:use, a list of analysis | realtime | web | mobile_ar | print | render | preview) and seven measures of a version (em:trisPerM2, em:texelDensityDD, em:textureCount, em:textureSidePx, em:uvRatio, em:reductionFromLod0, em:geometricErrorM). v1.6.24 (dev30, decided by E.D. 2026-10-02 on the dev29 report): DTCAcquisitionNode.retrieved_from — where a retrieved object came from, a DOI or a URL (em:retrievedFrom, D1; optional, validate warns «download without origin»). ResourceNode.members_digest names em:membersDigest, the digest of a file_set with a predicate of its own beside em:checksum + em:digestCovers (D4; not a second field). ResourceNode.packaging carries its vocabulary with values and labels, translated in datamodel_translations.json (packagings; A3). ResourceNode.content_digest also holds the digest of the data of a master inside another file — a Metashape model's mesh.ply — compared, never verified by downloading (D7). GCPSetNode gains data.control (ground_control_points | camera_positions) and data.accuracy_m: a chunk referenced only by its cameras' GPS is absolute with the control said for what it is, and validate warns «georeferenced only by camera GPS» (D7). Node.properties.lang states the one explicit exception to the AI marker: a recognised language confirmed by a person is data.lang only (U5). CRMem 1.6.14. v1.6.23 (dev29, 2026-10-02, measured on San Pietro): seven properties that the round trip em.json → TTL → em.json lost now leave and come back — ResourceNode packaging / tier / digest_covers / content_digest (em:packaging, em:tier, em:digestCovers, em:contentDigest) and the declared fields of a DTC step, technique / parameters / software (em:technique, em:parameters, em:software, the last two as rdf:JSON). digest_covers admits members (a file_set). The blend:// locator stays out of RDF on purpose: it is a private path. v1.6.22 (dev28, 2026-11-01, decided by E.D. 2026-10-01 on the dev27 report): the access mode of a signature (created_auth / modified_auth / validated_auth) admits a third mode, 'declared' — an iD typed in a tool's preferences and checked by nobody (EMStudio's declared identity, EM Tools' local identity), with no attested_by; through a relay the mode is the relay's, read from the token (crdt.stamp_auth), not the client's declaration. The language a node is born in travels in the add_node op (crdt.make_op requires it of the producer, 'und' when unknown); the study's language is read only for old ops, said and counted. CRMem 1.6.12. v1.6.21 (dev27, 2026-10-31, decided by E.D. 2026-10-01, «il testo, la risorsa e la selezione» and «l'accesso sul campo»): ResourceNode.properties gains lang — on a resource the language(s) of its CONTENT, one tag or a sorted list, leaving as dcterms:language and outside the cascade of the texts — addresses (several addresses of ONE resource, same digest: em:hasAddress with em:locator, em:residency, em:checkedAt, em:reachable) and checksum_at (a dated digest, em:checksumAt). Node.properties gains created_auth / modified_auth / validated_auth: how the hand of a signature had entered, {mode: orcid | node_password, attested_by} (em:createdVia / em:modifiedVia / em:validatedVia, em:authMode, em:attestedBy). data.lang is written at birth (s3dgraphy.language.stamp_birth_language), also when equal to the study's. v1.6.20 (MICRO le traduzioni, 2026-10-29, decided by E.D. 2026-10-01, «Le traduzioni»): NEW TranslationNode (TRANSL, crm:E33_Linguistic_Object) — ONE translation of one text field of one node. The original stays a string in its field (data.lang on the node, else the study's), never overwritten; each translation is a node reached by has_translation (crm:P73_has_translation, connections 1.6.34) with data.lang (arrival), data.from_lang (departure, written because the original can change), data.field (CRDT vocabulary: description | data.<key>; a PropertyNode's value is data.value; never name), data.text, data.method (manual | ai | edition), data.source_digest (sha256 of the original translated: a different digest = «da riallineare») and data.review_requested («da rivedere»). Who: has_author; AI: data.ai_assisted, unverified until validated_by; an edition: extracted_from → the DocumentNode. RDF (em.ttl 1.6.10): Node.properties.lang names em:originalLanguage — the node's own data.lang leaves as that literal whenever it is declared, equal to the study's too, so a reader tells the original literal from the translations that share its predicate and the round trip gives data.lang back exactly where it was (the D.1 limit of 1.6.19 is closed); the TranslationNode's fields name em:sourceLanguage, em:translatedField, em:translationMethod, em:sourceDigest, em:reviewRequested. v1.6.19 (MICRO la lingua dei dati, 2026-10-27, decided by E.D. 2026-09-28): Node.properties.description becomes an object {cidoc: P3_has_note, natural_language: true, note} — the MARKER that says the description is text in a natural language and leaves in RDF with its language tag; declared once on the base class and inherited by every node type. name is NOT marked: names are invariant identities. No field added, no node element, no graph change: the em.json is the same; only the RDF literal gains its tag. v1.6.18 (MICRO i termini di em.ttl nel datamodel, 2026-10-26, decided by E.D. 2026-10-01 — the datamodel JSON is the truth, so every em: term of em.ttl is cited by a datamodel or is a written exception): the em: predicates the RDF exporter already writes are now NAMED in properties, as plain-string mapping notes (no field added, no node element, no graph change). Node (inherited by every class): the last-hand stamps created_by em:createdBy / modified_by em:lastEditedBy / modified_at em:modifiedAt (created_at prov:generatedAtTime), the tombstone removed.ts em:removedAt / removed.by em:removedBy, the AI marker ai_assisted.by em:aiAssistedBy / .model em:aiModel / .prompt_ref em:aiPromptRef / .fields em:aiAssistedField and the verification validated_by em:validatedBy / validated_at em:validatedAt (properties_note). ResourceNode: checksum em:checksum, scope em:resourceScope, residency em:residency. SemanticShapeNode: convexshapes em:convexShape, spheres em:sphere. AnnotationRegionNode: crs em:crs, coords.frame_iri em:LocalSceneFrame. AuthorNode and AuthorAINode: verified em:orcidVerified (AuthorAINode also names orcid P48, which the exporter writes for both). LocationNodeGroup.propagation.mapping: uri em:propagation. THREE ENTRIES CORRECTED TO WHAT THE CODE WRITES (measured in rdf_exporter.py): PropertyNode.property_type was P2_has_type, is em:hasQualiaType; AuthorAINode model / prompt_reference were P3_has_note, are em:modelIdentifier / em:promptReference; ResourceFileNode.checksum was P1_is_identified_by, is em:checksum; and LocationNodeGroup.propagation said 'not serialized to triplestore' while the exporter has written the non-default value as em:propagation since c1a702c (2026-08-12). v1.6.17 (MICRO la risorsa e i suoi file, 2026-10-18, decided by E.D. 2026-09-30): NEW ResourceFileNode (FILE, crmdig:D1_Digital_Object) — the ResourceNode is the set, the ResourceFileNode is each file, reached by has_file (connections 1.6.30) with role and relative path on the edge. With one file the node is implicit (url and checksum stay on the ResourceNode, as today). ResourceNode.PACKAGINGS += file_set (a few files that call each other: obj → mtl → textures, gltf → bin, shp and companions) and datablock (one object inside a file, a blend:// locator). Representations of the same thing are sibling ResourceNodes tied by dtc_derived_from and chosen by tier and packaging. ADDITIVE: nothing narrowed, no graph changes. v1.6.16 (MICRO le annotazioni ATON sull'asset, 2026-10-15, decided by E.D.): AnnotationRegionNode gains geometry_kind 'volume' — an annotation that encloses a part of a 3D model (ATON / Hathor convex hulls and spheres) and is the proxy of no unit. The region carries no vertices: it reaches a SemanticShapeNode (convexshapes, spheres) with has_semantic_shape and the model with is_on_resource. geometry.aton.import_aton_scene makes one for every semantic id no EM node is named after (a stratigraphic unit only with an explicit create_type); api.promote_region_to_proxy turns it into the proxy of a unit later. RDF: P2_has_type 'volume', no selector, no WKT; the shape travels as itself. Additive. v1.6.15 (MICRO la geometria per origine, 2026-10-11, decided by E.D. 2026-09-30): AnnotationRegionNode's point / line / polyline keep their vertices IN THE NODE, data.coords [[x, y, z], ...] (scene-local, glTF Y-up, metres) with crs and, for a line or a polyline, length and unit — no .glb and no SemanticShape for a reading. New block coords (inline_max_vertices 500: above it the vertices go to a .glb resource via has_linked_resource, with a warning). RDF: geo:hasGeometry -> <region>/geometry geo:asWKT (POINT Z / LINESTRING Z, GeoSPARQL). The readings/<id>.glb of 2026-10-06 are migrated on opening. v1.6.14 (MICRO la cattura in RDF, 2026-09-30): DTCAcquisitionNode.mapping.by_kind — its D12 is the class of a retrieval; a capture takes the class its kind declares in em_visual_rules 1.6.24 (D2 / D11 / E65). Mapping text only, no field changed. v1.6.13 (MICRO i generi delle US, 2026-09-30, decided by E.D. the same day): stratigraphic_kind gains 'coating' — the USR (rivestimento) and its English translation USS (surface): plaster, floors, revetments — with `labels`, `codes` and `default_code` per kind; new node element `source_code` (data.source_code) keeps the code a unit came in with when it is not its kind's default, so the way back to pyArchInit gives the same code. A legacy node_type 'USR' / 'USS' opens as US + coating. v1.6.12 (MICRO la cattura nel DTC e le murature, 2026-09-30): StratigraphicUnit (US) gains the node element `stratigraphic_kind` (em.json data.stratigraphic_kind; today one value, 'masonry'): a USM is a US + masonry, and the legacy node_type 'USM' — never a type of this datamodel — opens as that. DTCAcquisitionNode's description names the two families of the acquisition axis (em_visual_rules 1.6.22: capture / retrieval). v1.6.11 (MICRO la misura in RDF, 2026-10-07): AnnotationRegionNode.properties says how the fields left unprojected by 1.6.10 now travel — the quote of a passage as oa:TextQuoteSelector, the length of a line/polyline as crm:E54_Dimension (P90 value, P91 QUDT unit, em:crs), vertex_count as em:vertexCount. CRMem (em.ttl) 1.6.5 -> 1.6.6. Mapping text only, no field changed. v1.6.10 (MICRO la geometria della lettura, 2026-10-06, decided by E.D. on 2026-09-29): AnnotationRegionNode becomes the node of THE PLACE A READING LOOKED AT, with a new field geometry_kind: region2d (default, every older region), passage (start, end, text), point, line, polyline. The three 3D kinds keep their coordinates in a .glb (glTF POINTS / LINES / LINE_STRIP) linked with has_semantic_shape exactly like a proxy's payload, never in the em.json; the node keeps vertex_count and, for line/polyline, length + unit + crs (api.measure). See the entry's geometry_kinds and glb_payload. Paired with connections 1.6.27 (is_on_resource.target += the representation models). Additive: a region without geometry_kind reads as region2d. v1.6.9 (MICRO la definizione dell'unita', 2026-10-20, decided by E.D. on 2026-09-27): StratigraphicNode.properties gains `definition`, the DEFINIZIONE of the US sheet, as an element of the node like name and description and NOT a qualia. Value = a controlled-vocabulary concept {concept, label}; em.json carries it as data.definition (CRDT field 'data.definition', no change to the frozen em.json v1 node shape); inherited by every stratigraphic subtype. The RDF projection is declared in the entry itself (`rdf`): crm:P2_has_type -> crm:E55_Type when a concept URI is present, nothing when only a label is (`label_only: null`). CRMem 1.6.4 -> 1.6.5 for the companion em:hasDefinition (subproperty of crm:P2_has_type, declared, not emitted by default). Additive only. v1.6.7 (CRMem WIRING, 2026-09-24): rimosso il campo legacy `cidoc_s3d` da tutte le mapping. Non era letto da nessuna parte del codice e portava quattro nomi di classe senza namespace, mai dichiarati e mai emessi: EpochNode = StratigraphicTimeframe; ActivityNodeGroup = StratigraphicActivity; ParadataNodeGroup = ParadataCollection; ResourceNode = ExternalResourceReference. Il prefisso CIDOC-S3D non esiste piu' in nessuno dei due datamodel. v1.6.6 (CIDOC REPAIR, 2026-09-21): classes that pointed at IRIs nobody declares. Checked by parsing the official releases, not from memory. crm:E78_Collection is gone from CIDOC CRM 7.1.3 — renamed E78_Curated_Holding — and E.D. decided NOT to follow the rename, because E78_Curated_Holding is a subclass of E24 Physical Human-Made Thing and a group of nodes is not a physical thing. The three classes that carried it therefore split, each to the class it actually is: GroupNode and RepresentationModelNodeGroup to crm:E73_Information_Object (a conceptual set, and an E90 Symbolic Object, which is what the P106i membership edge needs at both ends), ParadataNodeGroup to crm:E89_Propositional_Object — which is what a gathered body of reasoning IS and what the range of crm:P129i_is_subject_of demands, that being the predicate has_paradata_nodegroup takes in connections 1.6.17 the same day; it stays an E90 through em:NodeGroup, so the membership edge does not break. SemanticShapeNode leaves crmgeo:SP5_Geometric_Place_Expression for crm:E73_Information_Object, PROVVISORIAMENTE: SP5 is not declared at the crmgeo namespace this datamodel emits, crmgeo:SP6_Declarative_Place is the better candidate, and the decision is rinviata da E.D. — E73 commits to nothing meanwhile. crm:P131_is_identified_by, deprecated in CRM 7.x together with E82 Actor Appellation, becomes crm:P1_is_identified_by on AuthorNode (name, surname) and AuthorAINode (name). «CRMs3D» is renamed «CRMem», in components and in referenced_ontology_versions alike: the companion ontology is em.ttl and its namespace is em:, so the old name pointed at nothing anyone could look up. CRMsci moves 3.1 -> 3.2 (latest release). The eight em: terms this file and the connections datamodel cite but em.ttl never defined are now declared there (em:FunctionalUnit, em:GCPSet, em:Narrative, em:NeutralSU, em:RegistrationTransform, em:RepresentationModelNodeGroup, em:hasSubEpoch, em:validatedBy), with domain, range and superclass read off these datamodels and nothing invented. NOT TOUCHED: the `alternative` and legacy `cidoc_s3d` prose fields, which still discuss E78 as an option — prose, not a projection, and rewording them is modelling rather than repair. v1.6.5 (EM16-RMNG, 2026-09-10): adds RepresentationModelNodeGroup, the RM container as a first-class group of the graph — sixth subtype of GroupNode, keeping the parent's E78 Collection because a container IS a curatorial set. Paired with connections datamodel 1.6.14, which adds the is_in_representation_model_group membership edge and widens has_representation_model.target to accept the group. Additive only: no existing entry changed. s3Dgraphy nodes datamodel including node types with CIDOC-CRM mappings. v1.6.4 adds the ADDITIVE georeferencing_nodes section (GCPSetNode = em:GCPSet, RegistrationTransformNode = em:RegistrationTransform, both subclasses of crm:E73_Information_Object with their own extension URIs so the RDF projection stays bijective): the CONTROL and the SOLUTION that place a produced model in the world, introduced with the photogrammetry processing connector. The two modes of that connector are the SHAPE of the graph (a transform with a CRS that has_gcp_set points at = absolute; a transform with crs=null and no control set = a site-local frame; no transform at all = nobody placed it), never a flag. No existing family changed. v1.6.3 re-reads SemanticShapeNode as a PAYLOAD carrier: the proxy of a unit is now a PropertyNode of qualia type 'geometry' that points at the shape (has_semantic_shape), so the proxy inherits the paradata chain it never had. Breaking for consumers that read the proxy as a standalone SemanticShape. v1.6.2 adds AnnotationRegionNode (em:AnnotationRegion, subclass of crm:E36_Visual_Item): the geometry of a 2D annotation in NORMALISED image space, distinct from SemanticShapeNode (3D scene geometry, crmgeo:SP5) - the semantics of the 2D annotator, defined before any canvas exists. v1.6.0 inaugurates a systematic CIDOC-CRM mapping revision: complete audit of all node types against CIDOC-CRM, CRMarchaeo, CRMinf, CRMdig, CRMsci, CRMgeo; replacement of legacy 'cidoc_s3d' pseudo-class names (invented strings without IRI or superclass declaration) with formal em:/s3d: IRIs declared as proper subclasses of CRM classes; introduction of CRMinf as primary (not alternative) for the paradata chain (ParadataNode, PropertyNode interpretive case, ExtractorNode, CombinerNode); introduction of PROV-O for AuthorNode to cover both human and AI agents; alignment with the Heritage Digital Twin Ontology (HDT-O) for containment / granularity properties; LocationNodeGroup (v1.5.3) adopted as the reference pattern (CIDOC-native composition via P2_has_type → E55 Type instances, with explicit extension_status and rationale). Companion deliverables: em.ttl (formal EM extension ontology, dereferenceable via w3id.org/em/) and hdto_extension.ttl (HDT-O granularity properties: contains_HDT, contains_SU, isPrimary). v1.5.4 added RSF (Reused Special Find — spolia) as a stratigraphic subtype, octagon with red border, family=real, is_series=false. Originating DP: DP-26 (spolia project, last DP before the EM 1.5 cut). v1.5.3 added LocationNodeGroup (E53 Place + E55 Type) for spatial / locational membership orthogonal to ActivityNodeGroup (intention) and EpochNode (time). v1.5.2 added family + is_series classification metadata on stratigraphic subtypes.",
4
4
  "components": [
5
5
  "CIDOC-CRM",
6
6
  "CRMarchaeo",
@@ -1713,11 +1713,19 @@
1713
1713
  "code": {
1714
1714
  "type": "string",
1715
1715
  "required": false,
1716
- "description": "The short name of the study (GT16, TM16): the one the source gives (pyArchInit), or the one the user writes in EM — never derived. The code of the graph is this one (E.D., 11 Oct 2026): it replaces the graph-self node's retired «EM-ID» (GraphNode.data.em_id), which a file keeps and s3dgraphy.hdto.migrate_em_id carries here only when the study has no code. The label prefix of the units reads it (s3dgraphy.hdto.study_code); graph.attributes['graph_code'] of a GraphML is read only when no study says one, the em_id never.",
1716
+ "description": "The short name of the study (GT16, TM16), STABLE (E.D., 11 Oct 2026): the prefix Blender re-attaches the proxies by (GT16.1.USM100), so once written it never changes by itself — import, export, migration, projection. Sources, in order: the code the source gives (pyArchInit); the GraphML header ID, reused as it is (written here at import, and still kept in graph.attributes['graph_code'] and GraphNode.data.em_id); a file's retired em_id (s3dgraphy.hdto.migrate_em_id; s3dgraphy.hdto.study_code reads it as a fallback without writing). When none exists, a proposal is written ONCE (s3dgraphy.hdto.propose_study_code) and marked with code_proposed until the user confirms it.",
1717
1717
  "mapping": {
1718
1718
  "cidoc": "P1_is_identified_by"
1719
1719
  }
1720
1720
  },
1721
+ "code_proposed": {
1722
+ "type": "boolean",
1723
+ "required": false,
1724
+ "description": "True while the study's code is a PROPOSAL of the system (E.D., 11 Oct 2026: Blender needs unique proxy names, so a study without a code gets one — the site's initials and the year, unique in the container). Written once with the code and never recomputed; it goes away when the user confirms the code (s3dgraphy.hdto.confirm_study_code), who may then also replace the proposal. Absent = the code was given, not proposed.",
1725
+ "mapping": {
1726
+ "cidoc": null
1727
+ }
1728
+ },
1721
1729
  "disciplinary_focus": {
1722
1730
  "type": "string",
1723
1731
  "required": false,
@@ -1,4 +1,4 @@
1
- __version__ = "1.6.0.dev44"
1
+ __version__ = "1.6.0.dev46"
2
2
  __datamodel_version__ = "1.5.5" # s3Dgraphy connections datamodel version
3
3
 
4
4
  # s3Dgraphy/__init__.py
@@ -322,6 +322,15 @@ def is_spatiotemporal(node) -> bool:
322
322
  return _is(node)
323
323
 
324
324
 
325
+ def entity_epoch(graph: Graph, node_id: str) -> Optional[str]:
326
+ """The epoch an entity stands in: the narrowest holding its own date (start,
327
+ else end), else its ``has_first_epoch``, else the nearest to its date
328
+ (MICRO autori nel tempo, 11 Oct 2026). See
329
+ :func:`s3dgraphy.spatiotemporal.entity_epoch`."""
330
+ from .spatiotemporal import entity_epoch as _epoch
331
+ return _epoch(graph, node_id)
332
+
333
+
325
334
  def view_instances(graph: Graph, group_id: str) -> List[Dict[str, Any]]:
326
335
  """The instances a client draws inside the paradata group ``group_id``:
327
336
  every master (document or property) outside the group that a reader of the
@@ -673,12 +682,35 @@ def graphs_about(container, entity) -> List[str]:
673
682
 
674
683
 
675
684
  def study_code(graph: Graph) -> Optional[str]:
676
- """The study's short name (GT16): ``StudyNode.data.code``, else the
677
- GraphML's header ID, never invented."""
685
+ """The study's short name (GT16), stable: ``StudyNode.data.code``, else the
686
+ GraphML's header ID, else the retired em_id (read only). Never writes,
687
+ never proposes. See :func:`s3dgraphy.hdto.study_code`."""
678
688
  from .hdto import study_code as _code
679
689
  return _code(graph)
680
690
 
681
691
 
692
+ def propose_study_code(graph: Graph, container=None) -> Dict[str, Any]:
693
+ """Give the study a code when it has none — once, marked
694
+ ``data.code_proposed`` until :func:`confirm_study_code`; never recomputed.
695
+ ``container`` avoids the codes of its other graphs. See
696
+ :func:`s3dgraphy.hdto.propose_study_code`."""
697
+ from .hdto import propose_study_code as _propose
698
+ return _propose(graph, container)
699
+
700
+
701
+ def is_code_proposed(graph: Graph) -> bool:
702
+ """Whether the study's code is a proposal not yet confirmed."""
703
+ from .hdto import is_code_proposed as _is
704
+ return _is(graph)
705
+
706
+
707
+ def confirm_study_code(graph: Graph, code: Optional[str] = None) -> Optional[str]:
708
+ """The user confirms the proposed code (or replaces the PROPOSAL with
709
+ ``code``); a confirmed code is not changed by confirming."""
710
+ from .hdto import confirm_study_code as _confirm
711
+ return _confirm(graph, code)
712
+
713
+
682
714
  def migrate_em_id(graph: Graph) -> Dict[str, Any]:
683
715
  """The retired ``GraphNode.data.em_id`` → ``StudyNode.data.code``, only
684
716
  when the study exists and has no code; the em_id is kept, nothing is
@@ -687,11 +719,38 @@ def migrate_em_id(graph: Graph) -> Dict[str, Any]:
687
719
  return _migrate(graph)
688
720
 
689
721
 
690
- def unit_label(graph: Graph, name: str, separator: str = ".") -> str:
691
- """A unit's name with the study's code as prefix, or as it is when the
692
- study has none."""
722
+ def unit_label(graph: Graph, name: str, separator: str = ".", *,
723
+ container=None, propose: bool = True) -> str:
724
+ """A unit's name with the study's code as prefix (GT16.US001). Without a
725
+ code, one is proposed and written first (once); ``propose=False`` gives
726
+ the name as it is."""
693
727
  from .hdto import unit_label as _label
694
- return _label(graph, name, separator)
728
+ return _label(graph, name, separator, container=container, propose=propose)
729
+
730
+
731
+ # ── rapporti between the graphs of one em.json (11 Oct 2026) ─────────────────
732
+ def add_link(container, source, target, edge_type: str, *,
733
+ link_id: Optional[str] = None,
734
+ attributes: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
735
+ """A rapporto from ``(graph_id, node_id)`` to ``(graph_id, node_id)`` of
736
+ another graph of ``container``. See :mod:`s3dgraphy.links`."""
737
+ from .links import add_link as _add
738
+ return _add(container, source, target, edge_type, link_id=link_id,
739
+ attributes=attributes)
740
+
741
+
742
+ def links_of(container, graph_id: str,
743
+ node_id: Optional[str] = None) -> List[Dict[str, Any]]:
744
+ """Every rapporto touching a graph (or one of its nodes), both ways, with
745
+ the address of the other end to navigate to."""
746
+ from .links import links_of as _of
747
+ return _of(container, graph_id, node_id)
748
+
749
+
750
+ def linked_graphs(container, graph_id: str) -> List[str]:
751
+ """The other graphs ``graph_id`` has rapporti with."""
752
+ from .links import linked_graphs as _linked
753
+ return _linked(container, graph_id)
695
754
 
696
755
 
697
756
  # ── editorial stamps (last hand) ──────────────────────────────────────────────
@@ -1010,7 +1010,8 @@ def edge_outside_graph(has_node, source: Any, target: Any,
1010
1010
 
1011
1011
  **The rule: an end that is a node of ANOTHER graph of the study refuses the
1012
1012
  edge.** An edge lives in the section of one graph and joins two nodes of it;
1013
- a link between graphs of one study (I-4, graph + UUID) does not exist yet.
1013
+ a rapporto between graphs of one study (I-4, graph + UUID) is a LINK of
1014
+ the graph of its source, not an edge — :mod:`s3dgraphy.links`.
1014
1015
  Until 5 Oct 2026 the CRDT took such an edge and the reader then dropped it:
1015
1016
  a room accepted what its own file threw away.
1016
1017
 
@@ -1032,7 +1033,8 @@ def edge_outside_graph(has_node, source: Any, target: Any,
1032
1033
  if other:
1033
1034
  return (f"the node '{node_id}' is in the graph '{other}', not in "
1034
1035
  f"this one: an edge joins two nodes of the same graph, and "
1035
- f"a link between graphs does not exist yet")
1036
+ f"a rapporto between graphs is a link (graph + node), "
1037
+ f"not an edge")
1036
1038
  return None
1037
1039
 
1038
1040
 
@@ -240,6 +240,24 @@ def build_emjson(graph: Graph, layout: Optional[Dict[str, Any]] = None) -> Dict[
240
240
  "nodes": nodes,
241
241
  "edges": edges,
242
242
  }
243
+ # the HEADER of the graph (E.D., 11 Oct 2026): its stable id and the
244
+ # study's code side by side, readable without walking the nodes. The code
245
+ # is a MIRROR of StudyNode.data.code — written here, checked on import,
246
+ # and the study wins — or, when the study has none, what study_code reads
247
+ # (the GraphML header's ID, the retired em_id), so an old file's code is
248
+ # no longer lost at its first em.json. Written only when there is a code.
249
+ from ..hdto import is_code_proposed, study_code
250
+ code = study_code(graph)
251
+ if code:
252
+ graph_section["code"] = code
253
+ if is_code_proposed(graph):
254
+ graph_section["code_proposed"] = True
255
+ # the rapporti towards other graphs of the container (s3dgraphy.links):
256
+ # written only when there are some, so a graph without stays as it was
257
+ links = [dict(l) for l in (getattr(graph, "links", None) or [])
258
+ if isinstance(l, dict)]
259
+ if links:
260
+ graph_section["links"] = links
243
261
  gname = _to_text(getattr(graph, "name", None))
244
262
  if gname:
245
263
  graph_section["name"] = gname
@@ -64,6 +64,9 @@ class Graph:
64
64
  #: ``warnings`` alone, because nothing here knows what it points at.
65
65
  self.warning_records = []
66
66
  self.attributes = {}
67
+ #: the rapporti towards nodes of OTHER graphs of the container — see
68
+ #: :mod:`s3dgraphy.links` (E.D., 11 Oct 2026)
69
+ self.links = []
67
70
 
68
71
  # Initialize graph indices
69
72
  self._indices = None
@@ -21,8 +21,16 @@ Giro dell'11 ottobre (E.D., 11 Oct 2026):
21
21
  export with several saggi is one graph per saggio in a Container
22
22
  (``GraphProjector.populate_container``);
23
23
  * **the code is the study's**: the graph's «EM-ID» (``GraphNode.data.em_id``)
24
- is retired; :func:`study_code` never reads it and :func:`migrate_em_id`
25
- carries it to ``StudyNode.data.code`` only when the study has none.
24
+ is retired; :func:`migrate_em_id` carries it to ``StudyNode.data.code`` only
25
+ when the study has none.
26
+
27
+ Giro dell'11 ottobre (2) (E.D., 11 Oct 2026):
28
+
29
+ * **the code is stable**: it is what Blender re-attaches the proxies by
30
+ (``GT16.1.USM100``), so once written it never changes by itself.
31
+ :func:`study_code` reads the study's code, then the GraphML header ID, then
32
+ the em_id (read only); :func:`propose_study_code` writes ONE proposal when
33
+ there is none, marked ``code_proposed`` until :func:`confirm_study_code`.
26
34
 
27
35
  The writer follows EMStudio's ``applyHdto`` (frontend/src/model.ts) for every
28
36
  role EMStudio already writes — the same roles in ``data.hdto_role``, one node
@@ -300,7 +308,10 @@ def declare_hdto(graph, *, study=None, place=None, about=None, parent=None,
300
308
  if study_s.get(key) is not None:
301
309
  d[key] = study_s[key]
302
310
  if _text(study_s.get("code")):
311
+ # a code GIVEN is a person's (or the source's): it is no longer a
312
+ # proposal, whatever was written before (E.D., 11 Oct 2026)
303
313
  d["code"] = _text(study_s["code"])
314
+ d.pop("code_proposed", None)
304
315
  _ensure_edge(graph, study_node, proposition_set,
305
316
  "study_produced_proposition_set")
306
317
  if study_node is not None and hc1 is not None and has_about:
@@ -411,21 +422,216 @@ def read_hdto(graph) -> Dict[str, Any]:
411
422
  # ── the code of the study ───────────────────────────────────────────────────
412
423
 
413
424
  def study_code(graph) -> Optional[str]:
414
- """The short name of the study (GT16), or ``None``.
415
-
416
- ONE source: ``StudyNode.data.code``. A GraphML's header ID
417
- (``graph.attributes['graph_code']``) is read only when no study says a
418
- code — it is what the source gave — and never its ``MISSINGCODE``
419
- placeholder. Nothing is derived (E.D., 10 Oct 2026). The retired
420
- ``GraphNode.data.em_id`` is NEVER read here (E.D., 11 Oct 2026): it
421
- becomes the study's code through :func:`migrate_em_id`, explicitly.
425
+ """The short name of the study (GT16), or ``None``. It is the name Blender
426
+ re-attaches the proxies by (``GT16.1.USM100``), so once a study has a code
427
+ it never changes by itself (E.D., 11 Oct 2026, «il codice di studio è
428
+ stabile»). Read, in order:
429
+
430
+ 1. ``StudyNode.data.code`` — the code the source gave, the GraphML header's
431
+ ID carried on import, a migrated em_id, or a proposal already written
432
+ (:func:`propose_study_code`, ``data.code_proposed``);
433
+ 2. the GraphML header ID (``graph.attributes['graph_code']``), never its
434
+ ``MISSINGCODE`` placeholder — a graph read by an older importer;
435
+ 3. the retired ``GraphNode.data.em_id``, read only, as a fallback: the
436
+ file is not changed (:func:`migrate_em_id` writes it to the study).
437
+
438
+ Nothing is proposed here: reading never writes. :func:`unit_label` and
439
+ :func:`ensure_study_code` propose, once, when all three are missing.
422
440
  """
423
441
  study = _role_node(graph, "study")
424
442
  code = _text(_get(study, "code")) if study is not None else ""
425
443
  if code:
426
444
  return code
427
445
  legacy = _text((getattr(graph, "attributes", None) or {}).get("graph_code"))
428
- return legacy if legacy not in _NO_CODE else None
446
+ if legacy not in _NO_CODE:
447
+ return legacy
448
+ return legacy_em_id(graph)
449
+
450
+
451
+ def is_code_proposed(graph) -> bool:
452
+ """Whether the study's code is a proposal nobody confirmed yet."""
453
+ study = _role_node(graph, "study")
454
+ return bool(study is not None and _text(_get(study, "code"))
455
+ and _get(study, "code_proposed") is True)
456
+
457
+
458
+ def confirm_study_code(graph, code: Optional[str] = None) -> Optional[str]:
459
+ """The user confirms the study's code: ``data.code_proposed`` goes away.
460
+
461
+ ``code`` given and different from the proposal: the user's code replaces
462
+ the PROPOSAL — the one case a written code changes, and only by a person.
463
+ A confirmed code is never replaced here: changing it is the user's edit
464
+ of ``StudyNode.data.code``, not a confirmation. Returns the code."""
465
+ study = _role_node(graph, "study")
466
+ if study is None:
467
+ return None
468
+ d = _data(study)
469
+ current = _text(d.get("code"))
470
+ wanted = _text(code)
471
+ if wanted and wanted != current:
472
+ if current and d.get("code_proposed") is not True:
473
+ raise ValueError(f"the study's code is {current!r}, confirmed: "
474
+ f"confirming does not change it")
475
+ d["code"] = wanted
476
+ d.pop("code_proposed", None)
477
+ return _text(d.get("code")) or None
478
+
479
+
480
+ #: words that are not initials (Grotta di Tiberio → GT)
481
+ _NOT_INITIALS = {"di", "de", "del", "della", "dei", "delle", "degli", "da",
482
+ "la", "le", "il", "lo", "gli", "i", "l", "d", "e", "ed",
483
+ "of", "the", "and", "a", "an", "von", "der", "des", "du"}
484
+
485
+
486
+ def _site_name_of(graph) -> str:
487
+ """The name of the site the study took place at: the place itself when it
488
+ is a site, else the first site up its ``is_in_location`` chain, else the
489
+ place (a saggio not under a site)."""
490
+ study = _role_node(graph, "study")
491
+ for place in _out(graph, study, "study_took_place_at"):
492
+ chain = _place_chain(graph, place)
493
+ for p in chain:
494
+ if _get(p, "level") == "sito" and _text(p.name):
495
+ return _text(p.name)
496
+ if _text(place.name):
497
+ return _text(place.name)
498
+ return ""
499
+
500
+
501
+ #: a name nobody gave (EMStudio's and EM-tools' defaults): no initials
502
+ _PLACEHOLDER_WORDS = {"untitled", "graph", "grafo", "new", "nuovo", "senza",
503
+ "titolo", "empty", "slot", "proposition", "set"}
504
+
505
+
506
+ def _initials(name: str) -> str:
507
+ import re
508
+ import unicodedata
509
+ plain = unicodedata.normalize("NFKD", name)
510
+ plain = "".join(c for c in plain if not unicodedata.combining(c))
511
+ words = [w for w in re.split(r"[^A-Za-z0-9]+", plain) if w]
512
+ if words and all(w.lower() in _PLACEHOLDER_WORDS for w in words):
513
+ return ""
514
+ words = [w for w in words if w.lower() not in _NOT_INITIALS] or words
515
+ if not words:
516
+ return ""
517
+ if len(words) == 1:
518
+ return words[0][:2].upper()
519
+ return "".join(w[0] for w in words[:4]).upper()
520
+
521
+
522
+ def _year_of(value: Any) -> str:
523
+ import re
524
+ found = re.search(r"(1[89]|20)(\d\d)", _text(value))
525
+ return found.group(2) if found else ""
526
+
527
+
528
+ def _codes_in(container, besides=None) -> set:
529
+ taken = set()
530
+ if container is None:
531
+ return taken
532
+ for _gid, other in _member_graphs(container):
533
+ if other is besides:
534
+ continue
535
+ code = study_code(other)
536
+ if code:
537
+ taken.add(code.upper())
538
+ return taken
539
+
540
+
541
+ def proposal_for(graph, container=None) -> str:
542
+ """The code the system would propose for ``graph`` — computed, not
543
+ written. The rule (E.D., 11 Oct 2026, measured and written in the referto
544
+ of the giro):
545
+
546
+ * the letters: the initials of the site the study took place at (words of
547
+ two or more: ``Grotta di Tiberio`` → ``GT``, the particles left out;
548
+ one word: its first two letters, ``Volterra`` → ``VO``); without a site,
549
+ of the study's name; without that, of the graph's name; else ``ST``;
550
+ * the year: the last two digits of the first year in the study's
551
+ ``date`` (``2016`` → ``16``), when there is one;
552
+ * a collision with a code of another graph of the container (case
553
+ insensitive) takes ``-2``, ``-3``…: never a ``.``, which is the
554
+ separator of the proxies' names.
555
+ """
556
+ study = _role_node(graph, "study")
557
+ letters = (_initials(_site_name_of(graph))
558
+ or _initials(_text(getattr(study, "name", "")) if study is not None else "")
559
+ or _initials(_text(_to_name(getattr(graph, "name", None))))
560
+ or "ST")
561
+ year = _year_of(_get(study, "date")) if study is not None else ""
562
+ base = f"{letters}{year}"
563
+ taken = _codes_in(container, besides=graph)
564
+ code, n = base, 1
565
+ while code.upper() in taken:
566
+ n += 1
567
+ code = f"{base}-{n}"
568
+ return code
569
+
570
+
571
+ def _to_name(value: Any) -> str:
572
+ if isinstance(value, dict):
573
+ return _text(value.get("default") or next(iter(value.values()), ""))
574
+ return _text(value)
575
+
576
+
577
+ def propose_study_code(graph, container=None) -> Dict[str, Any]:
578
+ """Give the study a code when it has none — ONCE: written on
579
+ ``StudyNode.data.code`` with ``data.code_proposed = True`` until the user
580
+ confirms it (:func:`confirm_study_code`), and from then on read like any
581
+ code, never recomputed (E.D., 11 Oct 2026).
582
+
583
+ * the study already has a code (proposed or not): nothing changes;
584
+ * a code without a study — the GraphML header ID, the retired em_id —
585
+ goes to the study as it is (not a proposal: the source gave it);
586
+ * nothing at all: :func:`proposal_for`, avoiding the other codes of
587
+ ``container``.
588
+
589
+ A graph without a study gets one (the code has to live somewhere, and the
590
+ code is the study's): named like the graph, no kind, no place.
591
+
592
+ Returns ``{"code", "proposed", "written", "source"}``; ``source`` is
593
+ ``"study"``, ``"graph_code"``, ``"em_id"`` or ``"proposal"``.
594
+ """
595
+ from .nodes.study_node import StudyNode
596
+ from .nodes.graph_node import GraphNode
597
+ study = _role_node(graph, "study")
598
+ code = _text(_get(study, "code")) if study is not None else ""
599
+ if code:
600
+ return {"code": code, "proposed": _get(study, "code_proposed") is True,
601
+ "written": False, "source": "study"}
602
+ legacy = _text((getattr(graph, "attributes", None) or {}).get("graph_code"))
603
+ if legacy not in _NO_CODE:
604
+ code, source = legacy, "graph_code"
605
+ elif legacy_em_id(graph):
606
+ code, source = legacy_em_id(graph), "em_id"
607
+ else:
608
+ code, source = proposal_for(graph, container), "proposal"
609
+ if study is None:
610
+ name = _to_name(getattr(graph, "name", None)) or code
611
+ if _role_node(graph, "proposition_set") is None:
612
+ pset = GraphNode(_derived_id(graph, "proposition_set"), name=name)
613
+ _data(pset)["hdto_role"] = "proposition_set"
614
+ graph.add_node(pset)
615
+ study = StudyNode(_derived_id(graph, "study"), name=name)
616
+ _data(study)["hdto_role"] = "study"
617
+ graph.add_node(study)
618
+ declare_hdto(graph, study={"name": name})
619
+ d = _data(study)
620
+ d["code"] = code
621
+ if source == "proposal":
622
+ d["code_proposed"] = True
623
+ return {"code": code, "proposed": source == "proposal", "written": True,
624
+ "source": source}
625
+
626
+
627
+ def _derived_id(graph, role: str) -> str:
628
+ """A deterministic id for a node :func:`propose_study_code` has to make:
629
+ the same graph gives the same id (a re-import does not move it)."""
630
+ return str(uuid.uuid5(uuid.NAMESPACE_URL,
631
+ f"s3dgraphy:{getattr(graph, 'graph_id', '')}:{role}"))
632
+
633
+
634
+ ensure_study_code = propose_study_code
429
635
 
430
636
 
431
637
  def legacy_em_id(graph) -> Optional[str]:
@@ -469,11 +675,18 @@ def migrate_em_id(graph) -> Dict[str, Any]:
469
675
  "migrated": reason == "migrated", "reason": reason}
470
676
 
471
677
 
472
- def unit_label(graph, name: str, separator: str = ".") -> str:
473
- """``name`` with the study's code as prefix (GT16.US001), or ``name`` as it
474
- is when the study has no code — never an invented one."""
678
+ def unit_label(graph, name: str, separator: str = ".", *, container=None,
679
+ propose: bool = True) -> str:
680
+ """``name`` with the study's code as prefix (GT16.US001).
681
+
682
+ The code is :func:`study_code`'s; when there is none and ``propose`` is
683
+ true, :func:`propose_study_code` writes one first (Blender needs unique
684
+ proxy names) — once: the next call reads it. ``propose=False``: ``name``
685
+ as it is."""
475
686
  from .utils.utils import manage_id_prefix
476
687
  code = study_code(graph)
688
+ if not code and propose:
689
+ code = propose_study_code(graph, container)["code"]
477
690
  return manage_id_prefix(name, code, "add", separator) if code else name
478
691
 
479
692