cortex-ai-memory 2.2.1__tar.gz → 2.3.0__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.
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/Cargo.lock +10 -5
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/PKG-INFO +1 -1
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/Cargo.toml +1 -1
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/lib.rs +14 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/sync/merge.rs +26 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/types.rs +5 -0
- cortex_ai_memory-2.3.0/cortex-core/tests/test_reserved_namespace.rs +35 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-python/Cargo.toml +1 -1
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/pyproject.toml +1 -1
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/Cargo.toml +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/README.md +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/benches/comparison_bench.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/benches/memory_index_bench.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/belief.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/compression.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/consolidation.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/context.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/embedder.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/episode.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/events.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/export.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/inference.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/people.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/plugin.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/plugin_manager.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/plugins/mod.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/plugins/tag_classifier.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/procedural.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/relationship.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/retrieval.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/semantic.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/storage/memory_index.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/storage/mod.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/storage/sqlite.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/storage/traits.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/sync/crypto.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/sync/hlc.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/sync/mod.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/sync/oplog.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/sync/provider.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/sync/secret.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/sync/snapshot.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/sync/state.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/sync/watcher.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/src/working.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_belief.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_cache_and_perf.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_compression.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_compression_advanced.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_consolidation.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_consolidation_advanced.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_context.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_contradiction_flow.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_cortex_e2e.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_cortex_full.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_episode.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_events.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_full_privacy_chain.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_gdrive_real.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_ingest_parity.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_memory_index.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_optimizations.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_people.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_plugin.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_plugin_manager_ext.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_privacy_sync.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_procedural.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_retrieval.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_retrieval_advanced.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_semantic.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_storage.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_storage_advanced.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_sync.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_temporal_retrieval.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_traits_defaults.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_types.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_working_memory.rs +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-python/README.md +0 -0
- {cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-python/src/lib.rs +0 -0
|
@@ -573,7 +573,7 @@ dependencies = [
|
|
|
573
573
|
|
|
574
574
|
[[package]]
|
|
575
575
|
name = "cortex-core"
|
|
576
|
-
version = "2.
|
|
576
|
+
version = "2.3.0"
|
|
577
577
|
dependencies = [
|
|
578
578
|
"aes-gcm",
|
|
579
579
|
"argon2",
|
|
@@ -606,7 +606,7 @@ dependencies = [
|
|
|
606
606
|
|
|
607
607
|
[[package]]
|
|
608
608
|
name = "cortex-http"
|
|
609
|
-
version = "2.
|
|
609
|
+
version = "2.3.0"
|
|
610
610
|
dependencies = [
|
|
611
611
|
"axum",
|
|
612
612
|
"chrono",
|
|
@@ -623,8 +623,9 @@ dependencies = [
|
|
|
623
623
|
|
|
624
624
|
[[package]]
|
|
625
625
|
name = "cortex-mcp-server"
|
|
626
|
-
version = "2.
|
|
626
|
+
version = "2.3.0"
|
|
627
627
|
dependencies = [
|
|
628
|
+
"axum",
|
|
628
629
|
"chrono",
|
|
629
630
|
"clap",
|
|
630
631
|
"cortex-core",
|
|
@@ -633,6 +634,8 @@ dependencies = [
|
|
|
633
634
|
"serde",
|
|
634
635
|
"serde_json",
|
|
635
636
|
"tokio",
|
|
637
|
+
"tower",
|
|
638
|
+
"tower-http",
|
|
636
639
|
"tracing",
|
|
637
640
|
"tracing-subscriber",
|
|
638
641
|
"uuid",
|
|
@@ -640,7 +643,7 @@ dependencies = [
|
|
|
640
643
|
|
|
641
644
|
[[package]]
|
|
642
645
|
name = "cortex-python"
|
|
643
|
-
version = "2.
|
|
646
|
+
version = "2.3.0"
|
|
644
647
|
dependencies = [
|
|
645
648
|
"cortex-core",
|
|
646
649
|
"pyo3",
|
|
@@ -649,7 +652,7 @@ dependencies = [
|
|
|
649
652
|
|
|
650
653
|
[[package]]
|
|
651
654
|
name = "cortex-wasm"
|
|
652
|
-
version = "2.
|
|
655
|
+
version = "2.3.0"
|
|
653
656
|
dependencies = [
|
|
654
657
|
"chrono",
|
|
655
658
|
"js-sys",
|
|
@@ -3485,6 +3488,7 @@ dependencies = [
|
|
|
3485
3488
|
"pin-project-lite",
|
|
3486
3489
|
"sync_wrapper",
|
|
3487
3490
|
"tokio",
|
|
3491
|
+
"tokio-util",
|
|
3488
3492
|
"tower-layer",
|
|
3489
3493
|
"tower-service",
|
|
3490
3494
|
"tracing",
|
|
@@ -3503,6 +3507,7 @@ dependencies = [
|
|
|
3503
3507
|
"http-body",
|
|
3504
3508
|
"iri-string",
|
|
3505
3509
|
"pin-project-lite",
|
|
3510
|
+
"tokio",
|
|
3506
3511
|
"tower",
|
|
3507
3512
|
"tower-layer",
|
|
3508
3513
|
"tower-service",
|
|
@@ -562,7 +562,15 @@ impl Cortex {
|
|
|
562
562
|
/// Auto-generate embedding if embedder is available and none provided.
|
|
563
563
|
/// Lazily initializes the embedding model on first call.
|
|
564
564
|
#[allow(unused_variables)]
|
|
565
|
+
/// Embed `text` with the local model, or `None` when embeddings are compiled out,
|
|
566
|
+
/// disabled via `CORTEX_NO_EMBEDDINGS`, or the model failed to load.
|
|
567
|
+
pub fn embed_query(&self, text: &str) -> Option<Vec<f32>> {
|
|
568
|
+
self.auto_embed(text, None)
|
|
569
|
+
}
|
|
570
|
+
|
|
565
571
|
fn auto_embed(&self, text: &str, embedding: Option<Vec<f32>>) -> Option<Vec<f32>> {
|
|
572
|
+
#[cfg(not(feature = "embeddings"))]
|
|
573
|
+
let _ = text;
|
|
566
574
|
if embedding.is_some() {
|
|
567
575
|
return embedding;
|
|
568
576
|
}
|
|
@@ -721,6 +729,12 @@ impl Cortex {
|
|
|
721
729
|
people: &PeopleGraph<'_>,
|
|
722
730
|
pending_hashes: &[String],
|
|
723
731
|
) -> Result<PrepareOutcome, CortexError> {
|
|
732
|
+
if namespace == Some(crate::types::MUSE_EXPORT_NAMESPACE) {
|
|
733
|
+
return Err(CortexError::InvalidInput(format!(
|
|
734
|
+
"namespace '{}' is reserved for `cortex-mcp-server gateway allow`",
|
|
735
|
+
crate::types::MUSE_EXPORT_NAMESPACE
|
|
736
|
+
)));
|
|
737
|
+
}
|
|
724
738
|
let mut source = MemSource::new(channel);
|
|
725
739
|
let embedding = self.auto_embed(text, embedding);
|
|
726
740
|
|
|
@@ -38,6 +38,12 @@ pub fn apply_op(
|
|
|
38
38
|
"Remote device attempted to sync Private memory — rejected".into(),
|
|
39
39
|
));
|
|
40
40
|
}
|
|
41
|
+
// The Muse export is local consent; a peer must never be able to add to it.
|
|
42
|
+
if memory.namespace.as_deref() == Some(crate::types::MUSE_EXPORT_NAMESPACE) {
|
|
43
|
+
return Err(CortexError::InvalidInput(
|
|
44
|
+
"Remote device attempted to write the reserved Muse export namespace — rejected".into(),
|
|
45
|
+
));
|
|
46
|
+
}
|
|
41
47
|
|
|
42
48
|
let entity_type = EntityType::Memory;
|
|
43
49
|
let entity_id = memory.id;
|
|
@@ -323,6 +329,26 @@ mod tests {
|
|
|
323
329
|
ts
|
|
324
330
|
}
|
|
325
331
|
|
|
332
|
+
#[test]
|
|
333
|
+
fn test_peer_cannot_write_muse_export_namespace() {
|
|
334
|
+
use crate::types::{MemContent, MemObjectBuilder, MemSource, MemoryTier, PrivacyLevel, MUSE_EXPORT_NAMESPACE};
|
|
335
|
+
let s = SqliteStorage::open_in_memory().unwrap();
|
|
336
|
+
let idx = MemoryIndex::new();
|
|
337
|
+
let memory = MemObjectBuilder::new(MemoryTier::Semantic, MemContent::Text("injected".into()), MemSource::new("x"))
|
|
338
|
+
.privacy(PrivacyLevel::Public)
|
|
339
|
+
.namespace(MUSE_EXPORT_NAMESPACE)
|
|
340
|
+
.build();
|
|
341
|
+
let id = memory.id;
|
|
342
|
+
let op = SyncOp {
|
|
343
|
+
op_id: Uuid::new_v4(),
|
|
344
|
+
hlc: HlcTimestamp::new(100, 0, "dev-evil"),
|
|
345
|
+
payload: SyncPayload::MemoryUpsert { memory },
|
|
346
|
+
hmac: None,
|
|
347
|
+
};
|
|
348
|
+
assert!(apply_op(&op, &s, &idx).is_err());
|
|
349
|
+
assert!(s.get_memory(id).unwrap().is_none());
|
|
350
|
+
}
|
|
351
|
+
|
|
326
352
|
#[test]
|
|
327
353
|
fn test_belief_upsert_is_idempotent() {
|
|
328
354
|
let s = SqliteStorage::open_in_memory().unwrap();
|
|
@@ -432,6 +432,11 @@ fn deserialize_arc_embedding<'de, D: serde::Deserializer<'de>>(
|
|
|
432
432
|
Ok(opt.map(Arc::new))
|
|
433
433
|
}
|
|
434
434
|
|
|
435
|
+
/// Namespace reserved for memories the user explicitly exported to the Muse gateway
|
|
436
|
+
/// (`cortex-mcp-server gateway allow`). Ordinary ingest and sync must never write into
|
|
437
|
+
/// it: membership is the user's consent to disclose to a third-party cloud agent.
|
|
438
|
+
pub const MUSE_EXPORT_NAMESPACE: &str = "muse-export";
|
|
439
|
+
|
|
435
440
|
/// Compute SHA-256 hash of memory content for deduplication.
|
|
436
441
|
pub fn compute_content_hash(content: &MemContent) -> String {
|
|
437
442
|
let text = match content {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//! The Muse export namespace is reserved: only `cortex-mcp-server gateway allow` may
|
|
2
|
+
//! write it. Every ordinary ingest path must refuse.
|
|
3
|
+
|
|
4
|
+
use cortex_core::types::{BatchIngestItem, MUSE_EXPORT_NAMESPACE};
|
|
5
|
+
use cortex_core::Cortex;
|
|
6
|
+
|
|
7
|
+
#[test]
|
|
8
|
+
fn single_ingest_into_reserved_namespace_is_rejected() {
|
|
9
|
+
let c = Cortex::in_memory().unwrap();
|
|
10
|
+
let r = c.ingest_with_options("secret", "test", None, None, None, Some(MUSE_EXPORT_NAMESPACE), None);
|
|
11
|
+
assert!(r.is_err());
|
|
12
|
+
assert!(c.list_namespaces().unwrap().iter().all(|(ns, _)| ns != MUSE_EXPORT_NAMESPACE));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#[test]
|
|
16
|
+
fn batch_ingest_never_writes_reserved_namespace() {
|
|
17
|
+
let c = Cortex::in_memory().unwrap();
|
|
18
|
+
let item = BatchIngestItem {
|
|
19
|
+
text: "secret".into(),
|
|
20
|
+
channel: "test".into(),
|
|
21
|
+
user_id: None,
|
|
22
|
+
salience_hint: None,
|
|
23
|
+
embedding: None,
|
|
24
|
+
namespace: Some(MUSE_EXPORT_NAMESPACE.into()),
|
|
25
|
+
privacy: None,
|
|
26
|
+
};
|
|
27
|
+
let _ = c.ingest_batch(vec![item]);
|
|
28
|
+
assert!(c.list_namespaces().unwrap().iter().all(|(ns, _)| ns != MUSE_EXPORT_NAMESPACE));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#[test]
|
|
32
|
+
fn other_namespaces_still_work() {
|
|
33
|
+
let c = Cortex::in_memory().unwrap();
|
|
34
|
+
assert!(c.ingest_with_options("fine", "test", None, None, None, Some("work"), None).is_ok());
|
|
35
|
+
}
|
|
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
|
{cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_compression_advanced.rs
RENAMED
|
File without changes
|
|
File without changes
|
{cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_consolidation_advanced.rs
RENAMED
|
File without changes
|
|
File without changes
|
{cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_contradiction_flow.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_full_privacy_chain.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_plugin_manager_ext.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_retrieval_advanced.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_storage_advanced.rs
RENAMED
|
File without changes
|
|
File without changes
|
{cortex_ai_memory-2.2.1 → cortex_ai_memory-2.3.0}/cortex-core/tests/test_temporal_retrieval.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|