boris-behav-obs 9.5__tar.gz → 9.5.2__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 (122) hide show
  1. {boris_behav_obs-9.5/boris_behav_obs.egg-info → boris_behav_obs-9.5.2}/PKG-INFO +1 -1
  2. boris_behav_obs-9.5.2/boris/analysis_plugins/list_of_dataframe_columns.py +22 -0
  3. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/export_observation.py +2 -6
  4. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/observation_operations.py +42 -37
  5. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/version.py +2 -2
  6. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2/boris_behav_obs.egg-info}/PKG-INFO +1 -1
  7. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris_behav_obs.egg-info/SOURCES.txt +1 -0
  8. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/pyproject.toml +1 -1
  9. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/LICENSE.TXT +0 -0
  10. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/MANIFEST.in +0 -0
  11. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/README.TXT +0 -0
  12. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/README.md +0 -0
  13. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/__init__.py +0 -0
  14. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/__main__.py +0 -0
  15. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/about.py +0 -0
  16. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/add_modifier.py +0 -0
  17. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/add_modifier_ui.py +0 -0
  18. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/advanced_event_filtering.py +0 -0
  19. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/analysis_plugins/__init__.py +0 -0
  20. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/analysis_plugins/_latency.py +0 -0
  21. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/analysis_plugins/number_of_occurences.py +0 -0
  22. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +0 -0
  23. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/analysis_plugins/time_budget.py +0 -0
  24. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/behav_coding_map_creator.py +0 -0
  25. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/behavior_binary_table.py +0 -0
  26. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/behaviors_coding_map.py +0 -0
  27. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/boris_cli.py +0 -0
  28. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/cmd_arguments.py +0 -0
  29. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/coding_pad.py +0 -0
  30. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/config.py +0 -0
  31. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/config_file.py +0 -0
  32. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/connections.py +0 -0
  33. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/converters.py +0 -0
  34. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/converters_ui.py +0 -0
  35. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/cooccurence.py +0 -0
  36. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/core.py +0 -0
  37. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/core_qrc.py +0 -0
  38. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/core_ui.py +0 -0
  39. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/db_functions.py +0 -0
  40. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/dev.py +0 -0
  41. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/dialog.py +0 -0
  42. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/duration_widget.py +0 -0
  43. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/edit_event.py +0 -0
  44. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/edit_event_ui.py +0 -0
  45. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/event_operations.py +0 -0
  46. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/events_cursor.py +0 -0
  47. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/events_snapshots.py +0 -0
  48. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/exclusion_matrix.py +0 -0
  49. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/export_events.py +0 -0
  50. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/external_processes.py +0 -0
  51. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/geometric_measurement.py +0 -0
  52. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/gui_utilities.py +0 -0
  53. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/image_overlay.py +0 -0
  54. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/import_observations.py +0 -0
  55. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/irr.py +0 -0
  56. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/latency.py +0 -0
  57. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/measurement_widget.py +0 -0
  58. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/media_file.py +0 -0
  59. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/menu_options.py +0 -0
  60. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/modifier_coding_map_creator.py +0 -0
  61. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/modifiers_coding_map.py +0 -0
  62. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/mpv-1.0.3.py +0 -0
  63. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/mpv.py +0 -0
  64. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/mpv2.py +0 -0
  65. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/observation.py +0 -0
  66. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/observation_ui.py +0 -0
  67. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/observations_list.py +0 -0
  68. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/otx_parser.py +0 -0
  69. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/param_panel.py +0 -0
  70. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/param_panel_ui.py +0 -0
  71. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/player_dock_widget.py +0 -0
  72. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/plot_data_module.py +0 -0
  73. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/plot_events.py +0 -0
  74. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/plot_events_rt.py +0 -0
  75. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/plot_spectrogram_rt.py +0 -0
  76. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/plot_waveform_rt.py +0 -0
  77. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/plugins.py +0 -0
  78. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/portion/__init__.py +0 -0
  79. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/portion/const.py +0 -0
  80. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/portion/dict.py +0 -0
  81. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/portion/func.py +0 -0
  82. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/portion/interval.py +0 -0
  83. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/portion/io.py +0 -0
  84. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/preferences.py +0 -0
  85. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/preferences_ui.py +0 -0
  86. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/project.py +0 -0
  87. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/project_functions.py +0 -0
  88. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/project_import_export.py +0 -0
  89. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/project_ui.py +0 -0
  90. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/qrc_boris.py +0 -0
  91. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/qrc_boris5.py +0 -0
  92. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/select_modifiers.py +0 -0
  93. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/select_observations.py +0 -0
  94. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/select_subj_behav.py +0 -0
  95. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/state_events.py +0 -0
  96. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/subjects_pad.py +0 -0
  97. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/synthetic_time_budget.py +0 -0
  98. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/time_budget_functions.py +0 -0
  99. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/time_budget_widget.py +0 -0
  100. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/transitions.py +0 -0
  101. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/utilities.py +0 -0
  102. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/video_equalizer.py +0 -0
  103. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/video_equalizer_ui.py +0 -0
  104. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/video_operations.py +0 -0
  105. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/view_df.py +0 -0
  106. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/view_df_ui.py +0 -0
  107. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris/write_event.py +0 -0
  108. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris_behav_obs.egg-info/dependency_links.txt +0 -0
  109. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris_behav_obs.egg-info/entry_points.txt +0 -0
  110. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris_behav_obs.egg-info/requires.txt +0 -0
  111. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/boris_behav_obs.egg-info/top_level.txt +0 -0
  112. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/setup.cfg +0 -0
  113. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/tests/test_db_functions.py +0 -0
  114. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/tests/test_export_observation.py +0 -0
  115. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/tests/test_irr.py +0 -0
  116. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/tests/test_observation_gui.py +0 -0
  117. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/tests/test_otx_parser.py +0 -0
  118. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/tests/test_preferences_gui.py +0 -0
  119. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/tests/test_project_functions.py +0 -0
  120. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/tests/test_time_budget.py +0 -0
  121. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/tests/test_utilities.py +0 -0
  122. {boris_behav_obs-9.5 → boris_behav_obs-9.5.2}/tests/test_utilities2.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boris-behav-obs
3
- Version: 9.5
3
+ Version: 9.5.2
4
4
  Summary: BORIS - Behavioral Observation Research Interactive Software
5
5
  Author-email: Olivier Friard <olivier.friard@unito.it>
6
6
  License-Expression: GPL-3.0-only
@@ -0,0 +1,22 @@
1
+ """
2
+ BORIS plugin
3
+
4
+ number of occurences of behaviors
5
+ """
6
+
7
+ import pandas as pd
8
+
9
+ __version__ = "0.0.1"
10
+ __version_date__ = "2025-06-13"
11
+ __plugin_name__ = "List of dataframe columns"
12
+ __author__ = "Olivier Friard - University of Torino - Italy"
13
+
14
+
15
+ def run(df: pd.DataFrame) -> pd.DataFrame:
16
+ """
17
+ List the columns present in the dataframe
18
+ """
19
+
20
+ df_results = pd.DataFrame(df.columns, columns=["column name"])
21
+
22
+ return df_results
@@ -691,11 +691,6 @@ def export_aggregated_events(pj: dict, parameters: dict, obsId: str, force_numbe
691
691
  # obs description
692
692
  obs_description = util.eol2space(observation[cfg.DESCRIPTION])
693
693
 
694
- """
695
- obs_length = observation_operations.observation_total_length(pj[cfg.OBSERVATIONS][obsId])
696
- logging.debug(f"obs_length: {obs_length}")
697
- """
698
-
699
694
  _, _, connector = db_functions.load_aggregated_events_in_db(
700
695
  pj, parameters[cfg.SELECTED_SUBJECTS], [obsId], parameters[cfg.SELECTED_BEHAVIORS]
701
696
  )
@@ -798,6 +793,7 @@ def export_aggregated_events(pj: dict, parameters: dict, obsId: str, force_numbe
798
793
  if observation[cfg.TYPE] == cfg.MEDIA:
799
794
  observation_type = "Media file"
800
795
 
796
+ # get the media file name of the start of event
801
797
  media_file_name = observation_operations.event2media_file_name(observation, row["start"])
802
798
  if media_file_name is None:
803
799
  media_file_name = "Not found"
@@ -842,7 +838,7 @@ def export_aggregated_events(pj: dict, parameters: dict, obsId: str, force_numbe
842
838
  observation["date"].replace("T", " "),
843
839
  obs_description,
844
840
  observation_type,
845
- media_file_str,
841
+ media_file_str, # list of media used in observation
846
842
  pj[cfg.OBSERVATIONS][obsId][cfg.TIME_OFFSET],
847
843
  f"{coding_duration:.3f}" if not coding_duration.is_nan() else cfg.NA,
848
844
  media_durations_str,
@@ -1055,8 +1055,6 @@ def new_observation(self, mode: str = cfg.NEW, obsId: str = "") -> None:
1055
1055
  }
1056
1056
 
1057
1057
  if self.pj[cfg.OBSERVATIONS][new_obs_id][cfg.MEDIA_CREATION_DATE_AS_OFFSET]:
1058
- print("\n", observationWindow.media_creation_time, "\n")
1059
-
1060
1058
  self.pj[cfg.OBSERVATIONS][new_obs_id][cfg.MEDIA_INFO][cfg.MEDIA_CREATION_TIME] = observationWindow.media_creation_time
1061
1059
 
1062
1060
  try:
@@ -2423,48 +2421,55 @@ def event2media_file_name(observation: dict, timestamp: dec) -> Optional[str]:
2423
2421
  timestamp (dec): time stamp
2424
2422
 
2425
2423
  Returns:
2426
- str: name of media file containing the event
2424
+ str: path of media file containing the event
2427
2425
  """
2426
+ if observation.get(cfg.MEDIA_CREATION_DATE_AS_OFFSET, False):
2427
+ # media creation date/time was used for coding
2428
+ video_file_name = None
2429
+ for media_path in observation[cfg.MEDIA_INFO].get(cfg.MEDIA_CREATION_TIME, {}):
2430
+ start_media = observation[cfg.MEDIA_INFO][cfg.MEDIA_CREATION_TIME][media_path]
2431
+ duration = observation[cfg.MEDIA_INFO][cfg.LENGTH][media_path]
2432
+ if start_media <= timestamp <= start_media + duration:
2433
+ video_file_name = media_path
2434
+ break
2428
2435
 
2429
- cumul_media_durations: list = [dec(0)]
2430
- for media_file in observation[cfg.FILE][cfg.PLAYER1]:
2431
- try:
2432
- media_duration = observation[cfg.MEDIA_INFO][cfg.LENGTH][media_file]
2433
- # cut off media duration to 3 decimal places as that is how fine the player is
2434
- media_duration = floor(media_duration * 10**3) / dec(10**3)
2435
- cumul_media_durations.append(floor((cumul_media_durations[-1] + media_duration) * 10**3) / dec(10**3))
2436
- except KeyError:
2437
- return None
2436
+ else: # no media creation date
2437
+ cumul_media_durations: list = [dec(0)]
2438
+ for media_file in observation[cfg.FILE][cfg.PLAYER1]:
2439
+ try:
2440
+ media_duration = observation[cfg.MEDIA_INFO][cfg.LENGTH][media_file]
2441
+ # cut off media duration to 3 decimal places as that is how fine the player is
2442
+ media_duration = floor(media_duration * 10**3) / dec(10**3)
2443
+ cumul_media_durations.append(floor((cumul_media_durations[-1] + media_duration) * 10**3) / dec(10**3))
2444
+ except KeyError:
2445
+ return None
2438
2446
 
2439
- """
2440
- cumul_media_durations: list = [dec(0)]
2441
- for media_file in observation[cfg.FILE][cfg.PLAYER1]:
2442
- try:
2443
- media_duration = dec(str(observation[cfg.MEDIA_INFO][cfg.LENGTH][media_file]))
2444
- cumul_media_durations.append(round(cumul_media_durations[-1] + media_duration, 3))
2445
- except KeyError:
2446
- return None
2447
- """
2447
+ """
2448
+ cumul_media_durations: list = [dec(0)]
2449
+ for media_file in observation[cfg.FILE][cfg.PLAYER1]:
2450
+ try:
2451
+ media_duration = dec(str(observation[cfg.MEDIA_INFO][cfg.LENGTH][media_file]))
2452
+ cumul_media_durations.append(round(cumul_media_durations[-1] + media_duration, 3))
2453
+ except KeyError:
2454
+ return None
2455
+ """
2448
2456
 
2449
- cumul_media_durations.remove(dec(0))
2457
+ cumul_media_durations.remove(dec(0))
2450
2458
 
2451
- logging.debug(f"{cumul_media_durations=}")
2459
+ logging.debug(f"{cumul_media_durations=}")
2452
2460
 
2453
- # test if timestamp is at end of last media
2454
- if timestamp == cumul_media_durations[-1]:
2455
- player_idx = len(observation[cfg.FILE][cfg.PLAYER1]) - 1
2456
- else:
2457
- player_idx = -1
2458
- for idx, value in enumerate(cumul_media_durations):
2459
- start = 0 if idx == 0 else cumul_media_durations[idx - 1]
2460
- if start <= timestamp < value:
2461
- player_idx = idx
2462
- break
2461
+ # test if timestamp is at end of last media
2462
+ if timestamp == cumul_media_durations[-1]:
2463
+ player_idx = len(observation[cfg.FILE][cfg.PLAYER1]) - 1
2464
+ else:
2465
+ player_idx = None
2466
+ for idx, value in enumerate(cumul_media_durations):
2467
+ start = 0 if idx == 0 else cumul_media_durations[idx - 1]
2468
+ if start <= timestamp < value:
2469
+ player_idx = idx
2470
+ break
2463
2471
 
2464
- if player_idx != -1:
2465
- video_file_name = observation[cfg.FILE][cfg.PLAYER1][player_idx]
2466
- else:
2467
- video_file_name = None
2472
+ video_file_name = observation[cfg.FILE][cfg.PLAYER1][player_idx] if player_idx is not None else None
2468
2473
 
2469
2474
  return video_file_name
2470
2475
 
@@ -20,5 +20,5 @@ This file is part of BORIS.
20
20
 
21
21
  """
22
22
 
23
- __version__ = "9.5"
24
- __version_date__ = "2025-06-12"
23
+ __version__ = "9.5.2"
24
+ __version_date__ = "2025-07-15"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boris-behav-obs
3
- Version: 9.5
3
+ Version: 9.5.2
4
4
  Summary: BORIS - Behavioral Observation Research Interactive Software
5
5
  Author-email: Olivier Friard <olivier.friard@unito.it>
6
6
  License-Expression: GPL-3.0-only
@@ -92,6 +92,7 @@ boris/view_df_ui.py
92
92
  boris/write_event.py
93
93
  boris/analysis_plugins/__init__.py
94
94
  boris/analysis_plugins/_latency.py
95
+ boris/analysis_plugins/list_of_dataframe_columns.py
95
96
  boris/analysis_plugins/number_of_occurences.py
96
97
  boris/analysis_plugins/number_of_occurences_by_independent_variable.py
97
98
  boris/analysis_plugins/time_budget.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "boris-behav-obs"
3
- version = "9.5"
3
+ version = "9.5.2"
4
4
  description = "BORIS - Behavioral Observation Research Interactive Software"
5
5
  authors = [{ name="Olivier Friard", email="olivier.friard@unito.it" }]
6
6
  readme = "README.md"
File without changes
File without changes