power-loop 6.46.0__tar.gz → 6.46.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.
- {power_loop-6.46.0 → power_loop-6.46.2}/PKG-INFO +1 -1
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/__init__.py +1 -1
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/engine.py +51 -6
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/spec.py +27 -2
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop.egg-info/PKG-INFO +1 -1
- {power_loop-6.46.0 → power_loop-6.46.2}/LICENSE +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/README.md +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/_vendor/__init__.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/_vendor/llm_client/__init__.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/_vendor/llm_client/anthropic_factory.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/_vendor/llm_client/capabilities.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/_vendor/llm_client/interface.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/_vendor/llm_client/llm_factory.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/_vendor/llm_client/llm_tooling.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/_vendor/llm_client/llm_utils.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/_vendor/llm_client/multimodal.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/_vendor/llm_client/proxy_fallback.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/agent/__init__.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/agent/follow_up.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/agent/sink.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/agent/stateful_loop.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/agent/system_prompt.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/agent/types.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contracts/__init__.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contracts/errors.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contracts/event_payloads.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contracts/events.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contracts/handlers.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contracts/hook_contexts.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contracts/hooks.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contracts/messages.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contracts/protocols.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contracts/tools.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contrib/__init__.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contrib/_redact.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contrib/jsonl_sink.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contrib/logging_sink.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contrib/mcp.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contrib/metrics_sink.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/contrib/otel_sink.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/core/agent_context.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/core/events.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/core/hooks.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/core/phase.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/core/pipeline.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/core/runner.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/core/state.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/py.typed +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/blackboard.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/budget.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/cancellation.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/capability_probe.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/compact.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/env.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/exec_backend.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/fold.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/fold_adapter.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/history_projector.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/history_sanitize.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/human_input.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/image_recall.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/memory.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/notes.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/provider.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/representation.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/retry.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/runtime_state.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/session_store.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/skills.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/spec.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/steer.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/stop_policy.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/__init__.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/backends/__init__.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/backends/mysql.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/backends/postgres.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/backends/sqlite.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/capabilities.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/db.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/dialect.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/factory.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/schema.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/store.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/store/types.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/structured.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/stub_provider.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/timers.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/todos.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/runtime/usage_estimate.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/tools/__init__.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/tools/blackboard.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/tools/command_policy.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/tools/command_rules.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/tools/default_manifest.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/tools/default_tools.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/tools/registry.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/tools/spawn_agent.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/__init__.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/api.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/introspect.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/journal.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/result.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/resume.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/runner.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/subprocess_executor.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/tool.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop/workflow/worker.py +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop.egg-info/SOURCES.txt +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop.egg-info/dependency_links.txt +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop.egg-info/requires.txt +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/power_loop.egg-info/top_level.txt +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/pyproject.toml +0 -0
- {power_loop-6.46.0 → power_loop-6.46.2}/setup.cfg +0 -0
|
@@ -15,7 +15,7 @@ Stability tiers
|
|
|
15
15
|
无版本承诺,可随时变更或删除。
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
__version__ = "6.46.
|
|
18
|
+
__version__ = "6.46.2"
|
|
19
19
|
|
|
20
20
|
# Public LLM contract (SDK-free) re-exported so callers (e.g. writing llm.* hooks or
|
|
21
21
|
# a custom LLMService) don't reach into the internal vendored transport package (H3.4).
|
|
@@ -31,6 +31,7 @@ import asyncio
|
|
|
31
31
|
import json
|
|
32
32
|
import logging
|
|
33
33
|
import re
|
|
34
|
+
from collections import ChainMap
|
|
34
35
|
from collections.abc import Awaitable, Callable
|
|
35
36
|
from contextvars import ContextVar
|
|
36
37
|
from dataclasses import replace
|
|
@@ -58,6 +59,37 @@ from .spec import (
|
|
|
58
59
|
#: 循环信息在 env 里的键(模板变量正则匹配不到它,不会被当成 {{变量}})
|
|
59
60
|
_LOOP_KEY = "\x00loop"
|
|
60
61
|
|
|
62
|
+
#: 当前 foreach 迭代自己的结果表(6.46.1)。body 的节点在每次迭代里 id 都一样,并行迭代共用全局结果表时,
|
|
63
|
+
#: 体内的 inputs_from / when / 循环的 until 会读到别的迭代的结果。每个迭代在自己的 task 里开一层,嵌套的迭代再往里叠一层。
|
|
64
|
+
_ITER_SCOPE: ContextVar[ChainMap[str, AgentResult] | None] = ContextVar("pl_wf_iter_scope", default=None)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class _ScopedResults(dict):
|
|
68
|
+
"""节点结果表:写的时候全局和当前迭代都写;读的时候先看当前迭代(再往外层迭代),最后看全局。
|
|
69
|
+
``dict(self)`` / ``.items()`` 拿到的是全局那份(run 结果、journal 用)。"""
|
|
70
|
+
|
|
71
|
+
def __setitem__(self, key: str, value: AgentResult) -> None:
|
|
72
|
+
super().__setitem__(key, value)
|
|
73
|
+
scope = _ITER_SCOPE.get()
|
|
74
|
+
if scope is not None:
|
|
75
|
+
scope[key] = value
|
|
76
|
+
|
|
77
|
+
def get(self, key: str, default: Any = None) -> Any:
|
|
78
|
+
scope = _ITER_SCOPE.get()
|
|
79
|
+
if scope is not None and key in scope:
|
|
80
|
+
return scope[key]
|
|
81
|
+
return super().get(key, default)
|
|
82
|
+
|
|
83
|
+
def __getitem__(self, key: str) -> AgentResult:
|
|
84
|
+
scope = _ITER_SCOPE.get()
|
|
85
|
+
if scope is not None and key in scope:
|
|
86
|
+
return scope[key]
|
|
87
|
+
return super().__getitem__(key)
|
|
88
|
+
|
|
89
|
+
def __contains__(self, key: object) -> bool:
|
|
90
|
+
scope = _ITER_SCOPE.get()
|
|
91
|
+
return (scope is not None and key in scope) or super().__contains__(key)
|
|
92
|
+
|
|
61
93
|
__all__ = ["Executor", "InProcessExecutor", "WorkflowEngine", "WorkflowRunError", "in_workflow"]
|
|
62
94
|
|
|
63
95
|
logger = logging.getLogger(__name__)
|
|
@@ -329,7 +361,8 @@ class WorkflowEngine:
|
|
|
329
361
|
# Stable id for this run; threaded into each leaf's metadata as an
|
|
330
362
|
# idempotency key so side-effecting tools can dedupe across a resume.
|
|
331
363
|
self._run_id = run_id
|
|
332
|
-
self._results: dict[str, AgentResult] =
|
|
364
|
+
self._results: dict[str, AgentResult] = _ScopedResults()
|
|
365
|
+
self._iter_broken: list[str] = []
|
|
333
366
|
self._errors: list[str] = []
|
|
334
367
|
self._last: AgentResult | None = None
|
|
335
368
|
self._budget_hit = False
|
|
@@ -403,10 +436,12 @@ class WorkflowEngine:
|
|
|
403
436
|
nid for nid, r in self._results.items()
|
|
404
437
|
if r.status not in ("completed", "skipped") and nid not in self._tolerated
|
|
405
438
|
]
|
|
439
|
+
# foreach 各路里没成功的(全局表里只留了最后写的那一路,见 _iter_broken)
|
|
440
|
+
broken += [b for b in self._iter_broken if b.rsplit(".", 1)[-1] not in self._tolerated]
|
|
406
441
|
if broken:
|
|
407
442
|
status = "failed"
|
|
408
443
|
self._errors.append(
|
|
409
|
-
"failed node(s): " + ", ".join(sorted(broken))
|
|
444
|
+
"failed node(s): " + ", ".join(sorted(set(broken)))
|
|
410
445
|
+ "(如果这些失败是可接受的,给对应节点加 continue_on_error: true)"
|
|
411
446
|
)
|
|
412
447
|
if self._leaf_cap_hit and status == "completed":
|
|
@@ -999,10 +1034,20 @@ class WorkflowEngine:
|
|
|
999
1034
|
# ITERATION_ENV_KEY:body 的所有迭代共享同一个 node_id,宿主的 FileIO 端口靠它
|
|
1000
1035
|
# 给每次迭代分不同的产出文件——不区分的话 N 个并发迭代会追加进同一个文件,互相搅乱。
|
|
1001
1036
|
child_env = {**env, node.as_var: item, ITERATION_ENV_KEY: index}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1037
|
+
outer = _ITER_SCOPE.get()
|
|
1038
|
+
scope: ChainMap[str, AgentResult] = ChainMap() if outer is None else outer.new_child()
|
|
1039
|
+
tok = _ITER_SCOPE.set(scope)
|
|
1040
|
+
try:
|
|
1041
|
+
if node.parallel:
|
|
1042
|
+
async with sem:
|
|
1043
|
+
return await self._exec(node.body, child_env, driver_sid)
|
|
1044
|
+
return await self._exec(node.body, child_env, driver_sid)
|
|
1045
|
+
finally:
|
|
1046
|
+
_ITER_SCOPE.reset(tok)
|
|
1047
|
+
# 这一路里没成功的节点(6.46.1):全局结果表里体内 id 只留最后写的那一路,run 终态要看每一路
|
|
1048
|
+
for nid, r in scope.maps[0].items():
|
|
1049
|
+
if r.status not in ("completed", "skipped") and nid not in self._tolerated:
|
|
1050
|
+
self._iter_broken.append(f"{node.id or 'foreach'}[{index}].{nid}")
|
|
1006
1051
|
|
|
1007
1052
|
# Per-iteration leaves are not journaled individually (see _emit_step);
|
|
1008
1053
|
# the aggregate below is the resume unit. Reset even if a body raises.
|
|
@@ -667,7 +667,8 @@ def _reach_pass(
|
|
|
667
667
|
if isinstance(node, ForeachNode):
|
|
668
668
|
if node.items_from:
|
|
669
669
|
_need(node.items_from, f"{path}: items_from")
|
|
670
|
-
|
|
670
|
+
# body 每次迭代自成一体:体内可以引用体内先跑完的节点,体外看不到体内
|
|
671
|
+
_reach_pass(node.body, set(available), refset | _local_ids(node.body), problems, f"{path}.body")
|
|
671
672
|
return {node.id} if node.id else set()
|
|
672
673
|
if isinstance(node, LoopNode):
|
|
673
674
|
# 循环体至少跑一轮:它产出的 id 在 until 判断时和循环之后都可用
|
|
@@ -679,6 +680,26 @@ def _reach_pass(
|
|
|
679
680
|
return set()
|
|
680
681
|
|
|
681
682
|
|
|
683
|
+
def _local_ids(node: WorkflowNode) -> set[str]:
|
|
684
|
+
"""一个(已解析的)子树里能被同层引用的 id:agent / foreach 聚合 / loop,不进更里层 foreach 的体。"""
|
|
685
|
+
out: set[str] = set()
|
|
686
|
+
if isinstance(node, AgentNode):
|
|
687
|
+
return {node.id} if node.id else out
|
|
688
|
+
if isinstance(node, ForeachNode):
|
|
689
|
+
return {node.id} if node.id else out
|
|
690
|
+
if isinstance(node, LoopNode):
|
|
691
|
+
out.add(node.id)
|
|
692
|
+
return out | _local_ids(node.body)
|
|
693
|
+
for child in (getattr(node, "steps", None) or getattr(node, "branches", None) or ()):
|
|
694
|
+
out |= _local_ids(child)
|
|
695
|
+
if isinstance(node, BranchNode):
|
|
696
|
+
for c in node.cases.values():
|
|
697
|
+
out |= _local_ids(c)
|
|
698
|
+
if node.default is not None:
|
|
699
|
+
out |= _local_ids(node.default)
|
|
700
|
+
return out
|
|
701
|
+
|
|
702
|
+
|
|
682
703
|
def _parse_node(
|
|
683
704
|
data: Any, path: str, problems: list[str], ids: set[str], body_ids: set[str]
|
|
684
705
|
) -> WorkflowNode | None:
|
|
@@ -1092,7 +1113,11 @@ def _parse_foreach(
|
|
|
1092
1113
|
if "body" not in data:
|
|
1093
1114
|
problems.append(f"{path}: foreach requires 'body'")
|
|
1094
1115
|
else:
|
|
1095
|
-
|
|
1116
|
+
# 体内的节点可以引用同一个体里的节点(6.46.1:每次迭代有自己的结果表,引擎按迭代取值,不会串);
|
|
1117
|
+
# 体外仍然只能引用 foreach 的聚合 id。更里一层 foreach 的体照旧不对这一层开放。
|
|
1118
|
+
local: set[str] = set()
|
|
1119
|
+
_collect_referenceable_ids(data["body"], local, in_body=False)
|
|
1120
|
+
body = _parse_node(data["body"], f"{path}.body", problems, ids | local, body_ids - local)
|
|
1096
1121
|
if body is None:
|
|
1097
1122
|
return None
|
|
1098
1123
|
return ForeachNode(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|