sunholo 0.99.6__tar.gz → 0.99.8__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 (160) hide show
  1. {sunholo-0.99.6 → sunholo-0.99.8}/PKG-INFO +2 -2
  2. {sunholo-0.99.6 → sunholo-0.99.8}/setup.py +1 -1
  3. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/discovery_engine/discovery_engine_client.py +2 -2
  4. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/discovery_engine/get_ai_search_chunks.py +2 -1
  5. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/genai/process_funcs_cls.py +13 -7
  6. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo.egg-info/PKG-INFO +2 -2
  7. {sunholo-0.99.6 → sunholo-0.99.8}/LICENSE.txt +0 -0
  8. {sunholo-0.99.6 → sunholo-0.99.8}/MANIFEST.in +0 -0
  9. {sunholo-0.99.6 → sunholo-0.99.8}/README.md +0 -0
  10. {sunholo-0.99.6 → sunholo-0.99.8}/setup.cfg +0 -0
  11. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/__init__.py +0 -0
  12. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/__init__.py +0 -0
  13. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/chat_history.py +0 -0
  14. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/dispatch_to_qa.py +0 -0
  15. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/fastapi/__init__.py +0 -0
  16. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/fastapi/base.py +0 -0
  17. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/fastapi/qna_routes.py +0 -0
  18. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/flask/__init__.py +0 -0
  19. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/flask/base.py +0 -0
  20. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/flask/qna_routes.py +0 -0
  21. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/flask/vac_routes.py +0 -0
  22. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/langserve.py +0 -0
  23. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/pubsub.py +0 -0
  24. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/route.py +0 -0
  25. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/special_commands.py +0 -0
  26. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/agents/swagger.py +0 -0
  27. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/archive/__init__.py +0 -0
  28. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/archive/archive.py +0 -0
  29. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/auth/__init__.py +0 -0
  30. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/auth/gcloud.py +0 -0
  31. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/auth/refresh.py +0 -0
  32. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/auth/run.py +0 -0
  33. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/azure/__init__.py +0 -0
  34. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/azure/auth.py +0 -0
  35. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/azure/blobs.py +0 -0
  36. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/azure/event_grid.py +0 -0
  37. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/bots/__init__.py +0 -0
  38. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/bots/discord.py +0 -0
  39. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/bots/github_webhook.py +0 -0
  40. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/bots/webapp.py +0 -0
  41. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/__init__.py +0 -0
  42. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/azure.py +0 -0
  43. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/doc_handling.py +0 -0
  44. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/encode_metadata.py +0 -0
  45. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/images.py +0 -0
  46. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/loaders.py +0 -0
  47. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/message_data.py +0 -0
  48. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/pdfs.py +0 -0
  49. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/process_chunker_data.py +0 -0
  50. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/publish.py +0 -0
  51. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/pubsub.py +0 -0
  52. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/chunker/splitter.py +0 -0
  53. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/__init__.py +0 -0
  54. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/chat_vac.py +0 -0
  55. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/cli.py +0 -0
  56. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/cli_init.py +0 -0
  57. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/configs.py +0 -0
  58. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/deploy.py +0 -0
  59. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/embedder.py +0 -0
  60. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/merge_texts.py +0 -0
  61. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/run_proxy.py +0 -0
  62. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/sun_rich.py +0 -0
  63. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/swagger.py +0 -0
  64. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/cli/vertex.py +0 -0
  65. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/components/__init__.py +0 -0
  66. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/components/llm.py +0 -0
  67. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/components/retriever.py +0 -0
  68. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/components/vectorstore.py +0 -0
  69. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/custom_logging.py +0 -0
  70. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/__init__.py +0 -0
  71. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/alloydb.py +0 -0
  72. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/alloydb_client.py +0 -0
  73. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/database.py +0 -0
  74. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/lancedb.py +0 -0
  75. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/sql/sb/create_function.sql +0 -0
  76. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/sql/sb/create_function_time.sql +0 -0
  77. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/sql/sb/create_table.sql +0 -0
  78. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/sql/sb/delete_source_row.sql +0 -0
  79. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/sql/sb/return_sources.sql +0 -0
  80. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/sql/sb/setup.sql +0 -0
  81. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/static_dbs.py +0 -0
  82. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/database/uuid.py +0 -0
  83. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/discovery_engine/__init__.py +0 -0
  84. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/discovery_engine/chunker_handler.py +0 -0
  85. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/discovery_engine/create_new.py +0 -0
  86. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/embedder/__init__.py +0 -0
  87. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/embedder/embed_chunk.py +0 -0
  88. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/excel/__init__.py +0 -0
  89. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/excel/plugin.py +0 -0
  90. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/gcs/__init__.py +0 -0
  91. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/gcs/add_file.py +0 -0
  92. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/gcs/download_folder.py +0 -0
  93. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/gcs/download_url.py +0 -0
  94. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/gcs/metadata.py +0 -0
  95. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/genai/__init__.py +0 -0
  96. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/genai/init.py +0 -0
  97. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/genai/safety.py +0 -0
  98. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/invoke/__init__.py +0 -0
  99. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/invoke/async_class.py +0 -0
  100. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/invoke/direct_vac_func.py +0 -0
  101. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/invoke/invoke_vac_utils.py +0 -0
  102. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/langfuse/__init__.py +0 -0
  103. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/langfuse/callback.py +0 -0
  104. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/langfuse/evals.py +0 -0
  105. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/langfuse/prompts.py +0 -0
  106. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/llamaindex/__init__.py +0 -0
  107. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/llamaindex/get_files.py +0 -0
  108. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/llamaindex/import_files.py +0 -0
  109. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/llamaindex/llamaindex_class.py +0 -0
  110. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/llamaindex/user_history.py +0 -0
  111. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/lookup/__init__.py +0 -0
  112. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/lookup/model_lookup.yaml +0 -0
  113. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/patches/__init__.py +0 -0
  114. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/patches/langchain/__init__.py +0 -0
  115. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/patches/langchain/lancedb.py +0 -0
  116. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/patches/langchain/vertexai.py +0 -0
  117. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/pubsub/__init__.py +0 -0
  118. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/pubsub/process_pubsub.py +0 -0
  119. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/pubsub/pubsub_manager.py +0 -0
  120. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/qna/__init__.py +0 -0
  121. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/qna/parsers.py +0 -0
  122. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/qna/retry.py +0 -0
  123. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/streaming/__init__.py +0 -0
  124. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/streaming/content_buffer.py +0 -0
  125. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/streaming/langserve.py +0 -0
  126. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/streaming/stream_lookup.py +0 -0
  127. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/streaming/streaming.py +0 -0
  128. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/summarise/__init__.py +0 -0
  129. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/summarise/summarise.py +0 -0
  130. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/terraform/__init__.py +0 -0
  131. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/terraform/tfvars_editor.py +0 -0
  132. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/tools/__init__.py +0 -0
  133. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/tools/web_browser.py +0 -0
  134. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/__init__.py +0 -0
  135. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/api_key.py +0 -0
  136. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/big_context.py +0 -0
  137. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/config.py +0 -0
  138. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/config_class.py +0 -0
  139. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/config_schema.py +0 -0
  140. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/gcp.py +0 -0
  141. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/gcp_project.py +0 -0
  142. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/parsers.py +0 -0
  143. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/timedelta.py +0 -0
  144. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/user_ids.py +0 -0
  145. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/utils/version.py +0 -0
  146. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/vertex/__init__.py +0 -0
  147. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/vertex/extensions_call.py +0 -0
  148. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/vertex/extensions_class.py +0 -0
  149. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/vertex/genai_functions.py +0 -0
  150. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/vertex/init.py +0 -0
  151. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/vertex/memory_tools.py +0 -0
  152. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/vertex/safety.py +0 -0
  153. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo/vertex/type_dict_to_json.py +0 -0
  154. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo.egg-info/SOURCES.txt +0 -0
  155. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo.egg-info/dependency_links.txt +0 -0
  156. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo.egg-info/entry_points.txt +0 -0
  157. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo.egg-info/requires.txt +0 -0
  158. {sunholo-0.99.6 → sunholo-0.99.8}/sunholo.egg-info/top_level.txt +0 -0
  159. {sunholo-0.99.6 → sunholo-0.99.8}/tests/test_chat_history.py +0 -0
  160. {sunholo-0.99.6 → sunholo-0.99.8}/tests/test_config.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.99.6
3
+ Version: 0.99.8
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Home-page: https://github.com/sunholo-data/sunholo-py
6
- Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.99.6.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.99.8.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -1,6 +1,6 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
- version = '0.99.6'
3
+ version = '0.99.8'
4
4
 
5
5
  setup(
6
6
  name='sunholo',
@@ -288,7 +288,7 @@ class DiscoveryEngineClient:
288
288
 
289
289
  log.info(f"Discovery engine async request: {search_request=}")
290
290
  search_response = await self.async_search_client.search(search_request)
291
-
291
+ log.info(f"Discovery engine async response: {search_response=}")
292
292
  if parse_chunks_to_string:
293
293
 
294
294
  big_string = await self.async_process_chunks(search_response)
@@ -345,7 +345,7 @@ class DiscoveryEngineClient:
345
345
  raise ValueError(f'No results found in response: {response=}')
346
346
 
347
347
  # Iterate through each result in the response
348
- async for result in response.results:
348
+ for result in response.results:
349
349
  chunk = result.chunk
350
350
  chunk_metadata = chunk.ChunkMetadata
351
351
 
@@ -3,6 +3,7 @@ from ..utils.gcp_project import get_gcp_project
3
3
  from ..custom_logging import log
4
4
  from .discovery_engine_client import DiscoveryEngineClient
5
5
  from ..components import load_memories
6
+ import traceback
6
7
 
7
8
  def get_all_chunks(question:str, config:ConfigManager):
8
9
  """
@@ -98,4 +99,4 @@ async def async_get_chunks(question, vector_name, num_chunks):
98
99
  try:
99
100
  return await de.async_get_chunks(question, num_previous_chunks=num_chunks, num_next_chunks=num_chunks)
100
101
  except Exception as err:
101
- log.error(f"No discovery engine chunks found: {str(err)}")
102
+ log.error(f"No discovery engine chunks found: {str(err)} {traceback.format_exc()}")
@@ -269,9 +269,9 @@ class GenAIFunctionProcessor:
269
269
  traceback_details = traceback.format_exc()
270
270
  log.warning(f"{error_message}\nTraceback: {traceback_details}")
271
271
  result = [f"{error_message}\n{traceback_details}"]
272
-
272
+ clean_result = self.remove_invisible_characters(result)
273
273
  api_requests_and_responses.append(
274
- [function_name, params, result]
274
+ [function_name, params, clean_result]
275
275
  )
276
276
  else:
277
277
  log.error(f"Function {function_name} is not recognized")
@@ -350,6 +350,12 @@ class GenAIFunctionProcessor:
350
350
  except Exception as err:
351
351
  log.error(f"Error initializing model: {str(err)}")
352
352
  return None
353
+
354
+ def remove_invisible_characters(self, string:str):
355
+ clean = string.encode('utf-8').decode('unicode_escape')
356
+ log.info(f"Cleaning:\n{string}\n > to >\n{clean}")
357
+
358
+ return clean
353
359
 
354
360
  def run_agent_loop(self, chat, content, callback, guardrail_max=10, loop_return=3):
355
361
  """
@@ -484,11 +490,11 @@ class GenAIFunctionProcessor:
484
490
  if fn_result_json:
485
491
  log.info(f"{fn_result_json} dict parsing")
486
492
  if fn_result_json.get('stdout'):
487
- text = fn_result_json.get('stdout').encode('utf-8').decode('unicode_escape')
488
- token += text
493
+ text = fn_result_json.get('stdout')
494
+ token += self.remove_invisible_characters(text)
489
495
  if fn_result_json.get('stderr'):
490
- text = fn_result_json.get('stdout').encode('utf-8').decode('unicode_escape')
491
- token += text
496
+ text = fn_result_json.get('stdout')
497
+ token += self.remove_invisible_characters(text)
492
498
  # If neither 'stdout' nor 'stderr' is present, dump the entire JSON
493
499
  if 'stdout' not in fn_result_json and 'stderr' not in fn_result_json:
494
500
  log.info(f"No recognised keys ('stdout' or 'stderr') in dict: {fn_result_json=} - dumping it all")
@@ -496,7 +502,7 @@ class GenAIFunctionProcessor:
496
502
  else:
497
503
  # probably a string, just return it
498
504
  log.info(f"{fn_result_json} non-dict (String?) parsing")
499
- token += f"{fn_result}\n--- end ---\n"
505
+ token += f"{self.remove_invisible_characters(fn_result)}\n--- end ---\n"
500
506
 
501
507
  this_text += token
502
508
  token_queue.append(token)
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.99.6
3
+ Version: 0.99.8
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Home-page: https://github.com/sunholo-data/sunholo-py
6
- Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.99.6.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.99.8.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes