followthemoney 4.2.2__py3-none-any.whl → 4.3.1__py3-none-any.whl
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.
Potentially problematic release.
This version of followthemoney might be problematic. Click here for more details.
- followthemoney/__init__.py +1 -1
- followthemoney/compare.py +19 -0
- followthemoney/helpers.py +13 -14
- followthemoney/property.py +6 -0
- followthemoney/proxy.py +4 -2
- followthemoney/schema/Company.yaml +1 -0
- followthemoney/schema/LegalEntity.yaml +11 -0
- followthemoney/schema/Person.yaml +9 -0
- followthemoney/schema/Thing.yaml +1 -1
- followthemoney/statement/entity.py +34 -7
- followthemoney/types/address.py +3 -1
- followthemoney/types/identifier.py +5 -5
- {followthemoney-4.2.2.dist-info → followthemoney-4.3.1.dist-info}/METADATA +3 -3
- {followthemoney-4.2.2.dist-info → followthemoney-4.3.1.dist-info}/RECORD +17 -17
- {followthemoney-4.2.2.dist-info → followthemoney-4.3.1.dist-info}/WHEEL +0 -0
- {followthemoney-4.2.2.dist-info → followthemoney-4.3.1.dist-info}/entry_points.txt +0 -0
- {followthemoney-4.2.2.dist-info → followthemoney-4.3.1.dist-info}/licenses/LICENSE +0 -0
followthemoney/__init__.py
CHANGED
|
@@ -9,7 +9,7 @@ from followthemoney.statement import Statement, StatementEntity, SE
|
|
|
9
9
|
from followthemoney.dataset import Dataset, DefaultDataset, DS
|
|
10
10
|
from followthemoney.util import set_model_locale
|
|
11
11
|
|
|
12
|
-
__version__ = "4.
|
|
12
|
+
__version__ = "4.3.1"
|
|
13
13
|
|
|
14
14
|
# Data model singleton
|
|
15
15
|
model = Model.instance()
|
followthemoney/compare.py
CHANGED
|
@@ -71,12 +71,31 @@ def _compare(scores: Scores, weights: Weights, n_std: int = 1) -> float:
|
|
|
71
71
|
return 1.0 / (1.0 + math.exp(-prob))
|
|
72
72
|
|
|
73
73
|
|
|
74
|
+
def entity_is_same(left: EntityProxy, right: EntityProxy) -> bool:
|
|
75
|
+
"""Check if two entities are the same apart from their ID."""
|
|
76
|
+
if left.schema != right.schema:
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
props = set(left.properties.keys()).union(right.properties.keys())
|
|
80
|
+
if 0 == len(props):
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
for prop in props:
|
|
84
|
+
left_vals = sorted(left.get(prop))
|
|
85
|
+
right_vals = sorted(right.get(prop))
|
|
86
|
+
if left_vals != right_vals:
|
|
87
|
+
return False
|
|
88
|
+
return True
|
|
89
|
+
|
|
90
|
+
|
|
74
91
|
def compare(
|
|
75
92
|
left: EntityProxy,
|
|
76
93
|
right: EntityProxy,
|
|
77
94
|
weights: Weights = COMPARE_WEIGHTS,
|
|
78
95
|
) -> float:
|
|
79
96
|
"""Compare two entities and return a match score."""
|
|
97
|
+
if entity_is_same(left, right):
|
|
98
|
+
return 1.0
|
|
80
99
|
scores = compare_scores(left, right)
|
|
81
100
|
return _compare(scores, weights)
|
|
82
101
|
|
followthemoney/helpers.py
CHANGED
|
@@ -13,8 +13,7 @@ from itertools import product
|
|
|
13
13
|
from datetime import datetime, timedelta
|
|
14
14
|
|
|
15
15
|
from followthemoney.types import registry
|
|
16
|
-
from followthemoney.proxy import E
|
|
17
|
-
from followthemoney.util import join_text
|
|
16
|
+
from followthemoney.proxy import E, EntityProxy
|
|
18
17
|
|
|
19
18
|
PROV_MIN_DATES = ("createdAt", "authoredAt", "publishedAt")
|
|
20
19
|
PROV_MAX_DATES = ("modifiedAt", "retrievedAt")
|
|
@@ -47,7 +46,7 @@ def simplify_provenance(proxy: E) -> E:
|
|
|
47
46
|
|
|
48
47
|
|
|
49
48
|
def entity_filename(
|
|
50
|
-
proxy:
|
|
49
|
+
proxy: EntityProxy, base_name: Optional[str] = None, extension: Optional[str] = None
|
|
51
50
|
) -> Optional[str]:
|
|
52
51
|
"""Derive a safe filename for the given entity."""
|
|
53
52
|
if proxy.schema.is_a("Document"):
|
|
@@ -85,7 +84,7 @@ def name_entity(entity: E) -> E:
|
|
|
85
84
|
|
|
86
85
|
|
|
87
86
|
def check_person_cutoff(
|
|
88
|
-
entity:
|
|
87
|
+
entity: EntityProxy,
|
|
89
88
|
death_cutoff: datetime = datetime(2000, 1, 1),
|
|
90
89
|
birth_cutoff: Optional[datetime] = None,
|
|
91
90
|
) -> bool:
|
|
@@ -153,17 +152,17 @@ def combine_names(entity: E) -> E:
|
|
|
153
152
|
This is of course impossible to do culturally correctly for the whole planet at
|
|
154
153
|
once, so it should be mostly used for internal-facing (e.g. matching) processes."""
|
|
155
154
|
if entity.schema.is_a("Person"):
|
|
156
|
-
first_names = entity.get("firstName")
|
|
157
|
-
second_names = entity.get("secondName") + [""]
|
|
158
|
-
middle_names = entity.get("middleName") + [""]
|
|
159
|
-
father_names = entity.get("fatherName") + [""]
|
|
160
|
-
mother_names = entity.get("motherName") + [""]
|
|
161
155
|
last_names = entity.get("lastName")
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
|
|
156
|
+
names_seq = [entity.get("firstName")]
|
|
157
|
+
names_seq.append(entity.get("secondName"))
|
|
158
|
+
names_seq.append(entity.get("middleName"))
|
|
159
|
+
names_seq.append(entity.get("fatherName"))
|
|
160
|
+
names_seq.append(entity.get("motherName"))
|
|
161
|
+
names_seq.append(last_names)
|
|
162
|
+
names_seq = [n for n in names_seq if len(n)]
|
|
163
|
+
for pairing in product(*names_seq):
|
|
164
|
+
name = squash_spaces(" ".join(pairing))
|
|
165
|
+
if len(name):
|
|
167
166
|
entity.add("alias", name)
|
|
168
167
|
|
|
169
168
|
# If no first name is given, at least add the last name:
|
followthemoney/property.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import re
|
|
2
2
|
from banal import is_mapping, as_bool
|
|
3
|
+
from rigour.ids import get_identifier_format
|
|
3
4
|
from typing import TYPE_CHECKING, Any, List, Optional, TypedDict
|
|
4
5
|
|
|
5
6
|
from followthemoney.exc import InvalidModel
|
|
@@ -157,6 +158,11 @@ class Property:
|
|
|
157
158
|
raise InvalidModel("Invalid reverse: %s" % self)
|
|
158
159
|
self.reverse = self.range._add_reverse(model, self._reverse, self)
|
|
159
160
|
|
|
161
|
+
if self.type == registry.identifier and self.format is not None:
|
|
162
|
+
format_ = get_identifier_format(self.format)
|
|
163
|
+
if format_ is None or format_.NAME != self.format:
|
|
164
|
+
raise InvalidModel("Invalid identifier format: %s" % self.format)
|
|
165
|
+
|
|
160
166
|
@property
|
|
161
167
|
def label(self) -> str:
|
|
162
168
|
"""User-facing title for this property."""
|
followthemoney/proxy.py
CHANGED
|
@@ -323,7 +323,7 @@ class EntityProxy(object):
|
|
|
323
323
|
@property
|
|
324
324
|
def countries(self) -> List[str]:
|
|
325
325
|
"""Get the set of all country-type values set of the entity."""
|
|
326
|
-
return self.get_type_values(registry.country)
|
|
326
|
+
return self.get_type_values(registry.country, matchable=True)
|
|
327
327
|
|
|
328
328
|
@property
|
|
329
329
|
def temporal_start(self) -> Optional[Tuple[Property, str]]:
|
|
@@ -386,6 +386,8 @@ class EntityProxy(object):
|
|
|
386
386
|
countries = set(self.countries)
|
|
387
387
|
if not len(countries):
|
|
388
388
|
for prop, value in self.itervalues():
|
|
389
|
+
if not prop.matchable:
|
|
390
|
+
continue
|
|
389
391
|
hint = prop.type.country_hint(value)
|
|
390
392
|
if hint is not None:
|
|
391
393
|
countries.add(hint)
|
|
@@ -460,7 +462,7 @@ class EntityProxy(object):
|
|
|
460
462
|
return self._size
|
|
461
463
|
|
|
462
464
|
def __hash__(self) -> int:
|
|
463
|
-
if
|
|
465
|
+
if self.id is None:
|
|
464
466
|
raise RuntimeError("Cannot hash entity without an ID")
|
|
465
467
|
return hash(self.id)
|
|
466
468
|
|
|
@@ -84,6 +84,7 @@ Company:
|
|
|
84
84
|
bikCode:
|
|
85
85
|
label: "BIK"
|
|
86
86
|
description: "Russian bank account code"
|
|
87
|
+
type: identifier
|
|
87
88
|
pfrNumber:
|
|
88
89
|
label: "PFR Number"
|
|
89
90
|
description: "(RU, ПФР) Pension Fund Registration number. AAA-BBB-CCCCCC, where AAA is organisation region, BBB is district, CCCCCC number at a specific branch"
|
|
@@ -102,6 +102,17 @@ LegalEntity:
|
|
|
102
102
|
bvdId:
|
|
103
103
|
label: Bureau van Dijk ID
|
|
104
104
|
type: identifier
|
|
105
|
+
sayariId:
|
|
106
|
+
label: Sayari Entity ID
|
|
107
|
+
type: identifier
|
|
108
|
+
brightQueryId:
|
|
109
|
+
label: BrightQuery ID
|
|
110
|
+
type: identifier
|
|
111
|
+
brightQueryOrgId:
|
|
112
|
+
label: BrightQuery Organization ID
|
|
113
|
+
type: identifier
|
|
114
|
+
hidden: true
|
|
115
|
+
matchable: false
|
|
105
116
|
uscCode:
|
|
106
117
|
# cf. https://en.wikipedia.org/wiki/Unified_Social_Credit_Identifier
|
|
107
118
|
label: "USCC"
|
|
@@ -31,16 +31,23 @@ Person:
|
|
|
31
31
|
# too many false positives.
|
|
32
32
|
firstName:
|
|
33
33
|
label: First name
|
|
34
|
+
description: "The part of a name that indicates the person, also often called given name or forename"
|
|
34
35
|
secondName:
|
|
35
36
|
label: Second name
|
|
37
|
+
description: "Deprecated, use one of the other more specific name properties instead."
|
|
38
|
+
deprecated: true
|
|
36
39
|
middleName:
|
|
37
40
|
label: Middle name
|
|
41
|
+
description: "The part of name written between a person's given name and family name. Often abbreviated as a middle initial."
|
|
38
42
|
fatherName:
|
|
39
43
|
label: Patronymic
|
|
44
|
+
description: "The part of a name based on the given name of one's father"
|
|
40
45
|
motherName:
|
|
41
46
|
label: Matronymic
|
|
47
|
+
description: "The part of a name based on the given name of one's mother"
|
|
42
48
|
lastName:
|
|
43
49
|
label: Last name
|
|
50
|
+
description: "The part of a name that indicates one's family, also often called surname or family name"
|
|
44
51
|
nameSuffix:
|
|
45
52
|
label: Name suffix
|
|
46
53
|
birthDate:
|
|
@@ -92,6 +99,8 @@ Person:
|
|
|
92
99
|
label: Religion
|
|
93
100
|
political:
|
|
94
101
|
label: Political association
|
|
102
|
+
profession:
|
|
103
|
+
label: Profession
|
|
95
104
|
education:
|
|
96
105
|
label: Education
|
|
97
106
|
spokenLanguage:
|
followthemoney/schema/Thing.yaml
CHANGED
|
@@ -7,6 +7,7 @@ from rigour.names.pick import pick_lang_name
|
|
|
7
7
|
|
|
8
8
|
from followthemoney.model import Model
|
|
9
9
|
from followthemoney.exc import InvalidData
|
|
10
|
+
from followthemoney.schema import Schema
|
|
10
11
|
from followthemoney.types.common import PropertyType
|
|
11
12
|
from followthemoney.property import Property
|
|
12
13
|
from followthemoney.util import gettext
|
|
@@ -477,12 +478,38 @@ class StatementEntity(EntityProxy):
|
|
|
477
478
|
dataset: Dataset,
|
|
478
479
|
statements: Iterable[Statement],
|
|
479
480
|
) -> SE:
|
|
480
|
-
|
|
481
|
+
model = Model.instance()
|
|
482
|
+
canonical_id: Optional[str] = None
|
|
483
|
+
schemata: Set[str] = set()
|
|
484
|
+
first_seens: Set[str] = set()
|
|
485
|
+
props: Dict[str, Set[Statement]] = {}
|
|
481
486
|
for stmt in statements:
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
487
|
+
schemata.add(stmt.schema)
|
|
488
|
+
canonical_id = stmt.canonical_id or canonical_id or stmt.entity_id
|
|
489
|
+
if stmt.prop == BASE_ID:
|
|
490
|
+
if stmt.first_seen is not None:
|
|
491
|
+
first_seens.add(stmt.first_seen)
|
|
492
|
+
else:
|
|
493
|
+
if stmt.prop not in props:
|
|
494
|
+
props[stmt.prop] = set()
|
|
495
|
+
props[stmt.prop].add(stmt)
|
|
496
|
+
|
|
497
|
+
schema: Optional[Schema] = None
|
|
498
|
+
for name in schemata:
|
|
499
|
+
if schema is None:
|
|
500
|
+
schema = model.get(name)
|
|
501
|
+
elif schema.name != name:
|
|
502
|
+
try:
|
|
503
|
+
schema = model.common_schema(schema, name)
|
|
504
|
+
except InvalidData as exc:
|
|
505
|
+
raise InvalidData(f"{canonical_id}: {exc}") from exc
|
|
506
|
+
|
|
507
|
+
if schema is None:
|
|
508
|
+
err = "No valid schema for entity: %s %r" % (canonical_id, schemata)
|
|
509
|
+
raise InvalidData(err)
|
|
510
|
+
|
|
511
|
+
data = {"schema": schema, "id": canonical_id}
|
|
512
|
+
obj = cls(dataset, data)
|
|
513
|
+
obj.last_change = max(first_seens, default=None)
|
|
514
|
+
obj._statements = {p: s for p, s in props.items()}
|
|
488
515
|
return obj
|
followthemoney/types/address.py
CHANGED
|
@@ -47,7 +47,9 @@ class AddressType(PropertyType):
|
|
|
47
47
|
right_norm = normalize_address(right)
|
|
48
48
|
if left_norm is None or right_norm is None:
|
|
49
49
|
return 0.0
|
|
50
|
-
|
|
50
|
+
base_len = min(len(left_norm), len(right_norm))
|
|
51
|
+
max_edits = int(base_len * 0.33)
|
|
52
|
+
return levenshtein_similarity(left_norm, right_norm, max_edits=max_edits)
|
|
51
53
|
|
|
52
54
|
def _specificity(self, value: str) -> float:
|
|
53
55
|
return dampen(10, 60, value)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import re
|
|
2
2
|
from typing import Optional, TYPE_CHECKING
|
|
3
|
-
from rigour.ids import
|
|
3
|
+
from rigour.ids import get_identifier_format
|
|
4
4
|
|
|
5
5
|
from followthemoney.types.common import PropertyType
|
|
6
6
|
from followthemoney.util import dampen, shortest, longest
|
|
@@ -35,8 +35,8 @@ class IdentifierType(PropertyType):
|
|
|
35
35
|
format: Optional[str] = None,
|
|
36
36
|
proxy: Optional["EntityProxy"] = None,
|
|
37
37
|
) -> Optional[str]:
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
format_ = get_identifier_format(format)
|
|
39
|
+
if format_ is not None:
|
|
40
40
|
return format_.normalize(text)
|
|
41
41
|
return text
|
|
42
42
|
|
|
@@ -61,7 +61,7 @@ class IdentifierType(PropertyType):
|
|
|
61
61
|
return f"id:{value}"
|
|
62
62
|
|
|
63
63
|
def caption(self, value: str, format: Optional[str] = None) -> str:
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
format_ = get_identifier_format(format)
|
|
65
|
+
if format_ is not None:
|
|
66
66
|
return format_.format(value)
|
|
67
67
|
return value
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: followthemoney
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.1
|
|
4
4
|
Summary: A data model for anti corruption data modeling and analysis.
|
|
5
5
|
Project-URL: Documentation, https://followthemoney.tech/
|
|
6
6
|
Project-URL: Repository, https://github.com/opensanctions/followthemoney.git
|
|
@@ -48,9 +48,9 @@ Requires-Dist: prefixdate<1.0.0,>=0.5.0
|
|
|
48
48
|
Requires-Dist: pydantic<3.0.0,>=2.11.0
|
|
49
49
|
Requires-Dist: pytz>=2021.1
|
|
50
50
|
Requires-Dist: pyyaml<7.0.0,>=5.0.0
|
|
51
|
-
Requires-Dist: rdflib<7.
|
|
51
|
+
Requires-Dist: rdflib<7.3.0,>=6.2.0
|
|
52
52
|
Requires-Dist: requests<3.0.0,>=2.21.0
|
|
53
|
-
Requires-Dist: rigour<2.0.0,>=1.
|
|
53
|
+
Requires-Dist: rigour<2.0.0,>=1.4.0
|
|
54
54
|
Requires-Dist: sqlalchemy[mypy]<3.0.0,>=2.0.0
|
|
55
55
|
Provides-Extra: dev
|
|
56
56
|
Requires-Dist: build; extra == 'dev'
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
followthemoney/__init__.py,sha256=
|
|
2
|
-
followthemoney/compare.py,sha256=
|
|
1
|
+
followthemoney/__init__.py,sha256=9UJzMQUcqjQ4kWQIDMF1GB0ji8ph-GQlXa3e_X2uuX4,856
|
|
2
|
+
followthemoney/compare.py,sha256=frgumsDv4Ru9UkNof62jDjKCxxpCgV1Rusfu8s20uGA,6327
|
|
3
3
|
followthemoney/entity.py,sha256=bBiX7hNquXemS3vYCUHKtWI_IqX43Z6i8RQDbZ7gXsg,3449
|
|
4
4
|
followthemoney/exc.py,sha256=GyMgwY4QVm87hLevDfV7gM1MJsDqfNCi_UQw7F_A8X8,858
|
|
5
5
|
followthemoney/graph.py,sha256=7X1CGHGvmktS2LSZqld2iXWzG7B831eCNYyBqamqEJ8,10921
|
|
6
|
-
followthemoney/helpers.py,sha256=
|
|
6
|
+
followthemoney/helpers.py,sha256=KCdv1XAE7KQEXBiXp52Kvuck7wMaeNVBM3uaFemcvb4,7873
|
|
7
7
|
followthemoney/messages.py,sha256=zUEa9CFecU8nRafIzhN6TKCh1kEihiIyIS1qr8PxY4g,806
|
|
8
8
|
followthemoney/model.py,sha256=bWFVNa-DhYzc8BdSXBZdG2ev6Nh9uHx6i4tin8DvEEU,7374
|
|
9
9
|
followthemoney/names.py,sha256=LODQqExKEHdH4z6Mmbhlm0KeKRzGcptaSWzYXZ7lONI,1120
|
|
10
10
|
followthemoney/namespace.py,sha256=utggu9IGA8bhgEYom3OUB1KxkAJR_TrMNbY5MUF_db8,4536
|
|
11
11
|
followthemoney/ontology.py,sha256=WWY_PYQGl5Ket4zZBuZglzQxD2Bh9UqHok6GJNNX7GA,3001
|
|
12
|
-
followthemoney/property.py,sha256=
|
|
13
|
-
followthemoney/proxy.py,sha256=
|
|
12
|
+
followthemoney/property.py,sha256=6FoKoUloDoQVM4XMnjjolKArlV4yBq9KOYxv8Os8WGQ,8234
|
|
13
|
+
followthemoney/proxy.py,sha256=nahd9lLZzum_-QEchqydinDa1Zg5_Ffl0fyo35BNncQ,19707
|
|
14
14
|
followthemoney/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
followthemoney/schema.py,sha256=WYnPE4Lego0pJHlojECEv0aO9Miw_YIvEb35HoDo4Zk,18087
|
|
16
16
|
followthemoney/util.py,sha256=LoCSp1iE6VwXjotCkBXFRppeQs55726GzOuNIu3CvRE,4409
|
|
@@ -54,7 +54,7 @@ followthemoney/schema/Audio.yaml,sha256=Eb1rZGUEOX7XDAj_1YIN28NCBzMvkopQBNwgHt_k
|
|
|
54
54
|
followthemoney/schema/BankAccount.yaml,sha256=60v-VD296lW1Qq7fx--CzxfPNwfCcyMV6xIl8OrSy5g,1431
|
|
55
55
|
followthemoney/schema/Call.yaml,sha256=kbVCnVxucBrEplxehXHThLSJAJjy_GhWan-IeZZjr0M,980
|
|
56
56
|
followthemoney/schema/CallForTenders.yaml,sha256=2IWonTzfSbrkynMoEWqv5fekUeFM_xDKpKIbRe1XDbo,3227
|
|
57
|
-
followthemoney/schema/Company.yaml,sha256=
|
|
57
|
+
followthemoney/schema/Company.yaml,sha256=qWhk6HoSlep6oEjviXoV9ACTnfo7WZ5DSDvAkXMaQ5M,3455
|
|
58
58
|
followthemoney/schema/Contract.yaml,sha256=aSPB64T1h-0nuLDv6krasUvvoPZgo6sWUbv60c3vmzI,1541
|
|
59
59
|
followthemoney/schema/ContractAward.yaml,sha256=b2spaZHYCaP1yR1RCsrI7mUjk-fAF7BUE3dc8Vl3cUQ,1689
|
|
60
60
|
followthemoney/schema/CourtCase.yaml,sha256=lcovnY0Ne_xcggvkqfCW_RHvsRKo8kFTCPCyovAXRtI,599
|
|
@@ -75,7 +75,7 @@ followthemoney/schema/Identification.yaml,sha256=6txjZs6-3Kn94c3G4tDeDt9Jb4FW55-
|
|
|
75
75
|
followthemoney/schema/Image.yaml,sha256=wuznboWECGiV96_GQiXq1-oKNoxO8zKisR4xyusnEn8,394
|
|
76
76
|
followthemoney/schema/Interest.yaml,sha256=VUrehmsN1WgtS1oAa5jn_JGtSkZGGYLGNahp-R5JhOQ,282
|
|
77
77
|
followthemoney/schema/Interval.yaml,sha256=8YJQ51GI-GxvbjYs3uC593kQtCepWW_7ZiNnlbPm2aM,2084
|
|
78
|
-
followthemoney/schema/LegalEntity.yaml,sha256=
|
|
78
|
+
followthemoney/schema/LegalEntity.yaml,sha256=586aA1F5CO8rwf49LG3_iobm13zM4O21gL_TONte8oM,5054
|
|
79
79
|
followthemoney/schema/License.yaml,sha256=bXESXY-JpSmc5sthZe4sssXhx50UoLPAMED9FvEUyRU,534
|
|
80
80
|
followthemoney/schema/Membership.yaml,sha256=IPmaOX4Ai2r4sGcA5ig2WmLvWHb38akdxp4smEdDWOE,710
|
|
81
81
|
followthemoney/schema/Mention.yaml,sha256=nBeulR_Jm4x75aJ7yNF0TAVhHJqXQaEzOutLIn_YU-4,1086
|
|
@@ -89,7 +89,7 @@ followthemoney/schema/Page.yaml,sha256=YjYqaH2sOry0z4xh44CsX_eyuRClD6ZS0d2o2uQXF
|
|
|
89
89
|
followthemoney/schema/Pages.yaml,sha256=KKPGZ06Ehp5mWIGnYfHUBN9jT03bk8nakw0pB5bA_7E,450
|
|
90
90
|
followthemoney/schema/Passport.yaml,sha256=rpuLC86sdXnHF-prFQM4mAqYzlSGWKvPE4Cphtn2KRw,805
|
|
91
91
|
followthemoney/schema/Payment.yaml,sha256=WRBJuj9ljsxLBs-0g9Z9UD87uR1RTtuUiYnWOnKr1qA,1757
|
|
92
|
-
followthemoney/schema/Person.yaml,sha256=
|
|
92
|
+
followthemoney/schema/Person.yaml,sha256=wS_URvex5pG_P5cv0UPafpaz3Jh9Z7CxHZjb3GwB85k,2798
|
|
93
93
|
followthemoney/schema/PlainText.yaml,sha256=hfnVi-HmQeDbqDquSpkPJax9hNm86ioXGr4hzNzyPFE,278
|
|
94
94
|
followthemoney/schema/Position.yaml,sha256=ZpxjWOLxwva_on32r9WD5ys0Ty3YxCju41mg9HG-pe0,1308
|
|
95
95
|
followthemoney/schema/Project.yaml,sha256=2svtyGJopS0UrqPiuYGpBzj30V7k3LRDX4N1U56y4yY,462
|
|
@@ -104,7 +104,7 @@ followthemoney/schema/Similar.yaml,sha256=gD8rZEaPQWzU-rEfsKdn62uEucF3KxYBcPMoSd
|
|
|
104
104
|
followthemoney/schema/Succession.yaml,sha256=RMJQqZ4Fv88N1RvWTAgjYg9BB5cELSj5CCAjM681Fpg,749
|
|
105
105
|
followthemoney/schema/Table.yaml,sha256=GcsIAgSO9t2tvObA9zU2HhxlSqTe9CePmUnagu1Z0vI,641
|
|
106
106
|
followthemoney/schema/TaxRoll.yaml,sha256=ugMzaaS7uyq2OLD50eGLcfvd6Cg0cSt65-T9GVqpRSA,746
|
|
107
|
-
followthemoney/schema/Thing.yaml,sha256=
|
|
107
|
+
followthemoney/schema/Thing.yaml,sha256=xqGtSzyfE_EWx5PrxETKftF-9NSlsTYIbXrNqhdx9jw,2721
|
|
108
108
|
followthemoney/schema/Trip.yaml,sha256=nLQD_ApmVJ8D56Czl7K700hhNZjzFV9FOQ3NBSQDLiM,771
|
|
109
109
|
followthemoney/schema/UnknownLink.yaml,sha256=lneS_HZNgeLyJxwzWnLx0ZoyY3MXt99I_K2X_o9z5g8,682
|
|
110
110
|
followthemoney/schema/UserAccount.yaml,sha256=2bbPKNtt1R3zWSSkaq_SVzRPfFzX74kAxwtIxTymHA8,840
|
|
@@ -114,7 +114,7 @@ followthemoney/schema/Vessel.yaml,sha256=zWHUfSK8g6Pz58ZyCaK0AFJ4u_UHjEIUGC4c_7o
|
|
|
114
114
|
followthemoney/schema/Video.yaml,sha256=LY3DYMWTHXiAhL0hxBCNCz50cp2sPbUlEhhig5Fbjos,327
|
|
115
115
|
followthemoney/schema/Workbook.yaml,sha256=iikWPElz4klA7SkWH7eae6xqhbkMCIP_3zdeXzFEMU0,354
|
|
116
116
|
followthemoney/statement/__init__.py,sha256=7m2VUCAuqNZXIY0WFJRFkw5UG14QuxATL4f_xbqKwhw,633
|
|
117
|
-
followthemoney/statement/entity.py,sha256=
|
|
117
|
+
followthemoney/statement/entity.py,sha256=oeudwhqfYLJKqbzxEydasMHqevkDASNyYN6s0yddW6I,18755
|
|
118
118
|
followthemoney/statement/serialize.py,sha256=9eXzQ1biR2mSxWRID5C7xDdku4b4ZImHeRJ53yLZ0yo,7225
|
|
119
119
|
followthemoney/statement/statement.py,sha256=Ae-EYuzS8S12BkaRqrvMuI1C7YwlRKa5C_pTBELyNMM,8029
|
|
120
120
|
followthemoney/statement/util.py,sha256=B-ozuRc1TWvpop52873Pqt5OPj8H6uk4KyRJLfAhr10,780
|
|
@@ -142,7 +142,7 @@ followthemoney/translations/ru/LC_MESSAGES/followthemoney.po,sha256=7SQWytOTvoAQ
|
|
|
142
142
|
followthemoney/translations/tr/LC_MESSAGES/followthemoney.mo,sha256=SC84e_ZF_oFJG1NKdyZY_W6Kb6POORZB6wdeAcEWmnE,487
|
|
143
143
|
followthemoney/translations/tr/LC_MESSAGES/followthemoney.po,sha256=AZC3marhtVVq8Ck1FOgnt4sbDMz548nX48O9GDwImbQ,89826
|
|
144
144
|
followthemoney/types/__init__.py,sha256=rWwQeiuMh2BNIuvhpMfJ4bPADDvt9Axu1eedvNFi0qY,3350
|
|
145
|
-
followthemoney/types/address.py,sha256=
|
|
145
|
+
followthemoney/types/address.py,sha256=KsKLa9H8FfSkYF8VGslRnt-miGeni1rKICS8t1rzfzo,2235
|
|
146
146
|
followthemoney/types/checksum.py,sha256=zZrU8WX4CY3Vta_vOyfgDNzIwbmtje7AaDv3O1fBMnk,823
|
|
147
147
|
followthemoney/types/common.py,sha256=4ks7zPT8rknrGSd4JFc1zRkS-TL4SX-25_ZbjcVDos0,10081
|
|
148
148
|
followthemoney/types/country.py,sha256=n8vihijDVud_3Ra-as4Ize0jf_HbcdKVR5YX3TlKZy0,1533
|
|
@@ -150,7 +150,7 @@ followthemoney/types/date.py,sha256=PjcaEyW6CBzf0-gHWKUsKjWIaD3AVBEl0zLSRQOVXxc,
|
|
|
150
150
|
followthemoney/types/email.py,sha256=L3RTYrMABlNQF7hCynXGfzoj6YNEHW5JAY_BwuhoZdA,3375
|
|
151
151
|
followthemoney/types/entity.py,sha256=oDxVEhuxyU1ScpOpebPpUm3o0I9j_p7Qrq-t5yNpluQ,2338
|
|
152
152
|
followthemoney/types/gender.py,sha256=fi9iKLbjAUxDCLBtU1MxWidxv7KgCY2eH5746FYlEGk,1725
|
|
153
|
-
followthemoney/types/identifier.py,sha256=
|
|
153
|
+
followthemoney/types/identifier.py,sha256=7YET9mdYAktMup_kTvnxLu9SJzEU7ZJgN3KImzjfT-Y,2219
|
|
154
154
|
followthemoney/types/ip.py,sha256=mMFTODFiXAJROCUYJvoLAShyIiTIWVmMBh5zT_GquYM,1300
|
|
155
155
|
followthemoney/types/json.py,sha256=V3qJD5RxJykNX51u3w1Nx9xqoNBnkulhzkJI9XMYKFo,1690
|
|
156
156
|
followthemoney/types/language.py,sha256=SXgRRH-DyPmyyrqYurSyMiG6WHB8a0Gw81XxroEGD-c,2747
|
|
@@ -161,8 +161,8 @@ followthemoney/types/phone.py,sha256=r8uRqWinS0CYnYBTs405k5gO4jeatUDgjdzzijoMKJE
|
|
|
161
161
|
followthemoney/types/string.py,sha256=fqyTauAm4mNnNaoH-yH087RBbNh-G5ZZUO3awTGQUUg,1230
|
|
162
162
|
followthemoney/types/topic.py,sha256=Mi0Gx0m3bDeTmyuvM6jdRMqv81O03U4eI99R13KGu2Y,4503
|
|
163
163
|
followthemoney/types/url.py,sha256=QFpS_JIV8unFHuh_uGv22SWUUkocBoOpzLsAJWom_gI,1455
|
|
164
|
-
followthemoney-4.
|
|
165
|
-
followthemoney-4.
|
|
166
|
-
followthemoney-4.
|
|
167
|
-
followthemoney-4.
|
|
168
|
-
followthemoney-4.
|
|
164
|
+
followthemoney-4.3.1.dist-info/METADATA,sha256=i41B2NtbZrqWsc0F26XIP9GCvbRtMZ1ZsWeRWvk4AAg,6747
|
|
165
|
+
followthemoney-4.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
166
|
+
followthemoney-4.3.1.dist-info/entry_points.txt,sha256=caoFTlf213jhg5sz3TNSofutjUTzaKtWATuSIdd9Cps,653
|
|
167
|
+
followthemoney-4.3.1.dist-info/licenses/LICENSE,sha256=H6_EVXisnJC0-18CjXIaqrBSFq_VH3OnS7u3dccOv6g,1148
|
|
168
|
+
followthemoney-4.3.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|