stark-engine 4.5.2__tar.gz → 4.5.3__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.
- {stark_engine-4.5.2 → stark_engine-4.5.3}/PKG-INFO +1 -1
- {stark_engine-4.5.2 → stark_engine-4.5.3}/pyproject.toml +1 -1
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/parsing.py +50 -21
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/types/__init__.py +1 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/types/object.py +30 -2
- stark_engine-4.5.3/stark/core/types/union.py +65 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/sliding_window_parser.py +1 -1
- {stark_engine-4.5.2 → stark_engine-4.5.3}/LICENSE.md +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/README.md +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/command.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/commands_context.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/commands_context_processor.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/commands_manager.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/health_check.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/patterns/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/patterns/pattern.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/patterns/rules.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/processors/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/processors/corrections_processor.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/processors/search_processor.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/processors/spacy_ner_processor.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/types/location.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/types/slots.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/types/string.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/core/types/word.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/blockage_detector.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/cache.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/classproperty.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/dependencies.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/feature_flags.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/json_encoder.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/localisation/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/localisation/language_code.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/localisation/locale_string.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/localisation/localizable_string.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/localisation/localizer.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/general/localisation/strings.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/interfaces/gcloud.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/interfaces/microphone.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/interfaces/protocols.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/interfaces/recognizer_relay.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/interfaces/silero.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/interfaces/vosk.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/models/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/models/transcription_string.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/models/voice_transcription.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/models/voice_transcription_string.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/common/span.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/dictionary/!examples.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/dictionary/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/dictionary/dictionary.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/dictionary/models.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/dictionary/nl_dictionary_name.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/dictionary/recognizable_dictionary.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/dictionary/storage/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/dictionary/storage/storage_memory.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/dictionary/storage/storage_sqlite.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/levenshtein/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/levenshtein/levenshtein.pyi +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/levenshtein/levenshtein.pyx +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/phonetic/simplephone.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/phonetic/transcription/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/phonetic/transcription/epitran.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/phonetic/transcription/espeak.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/phonetic/transcription/ipa2lat.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/phonetic/transcription/latin_passthrough.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/phonetic/transcription/protocol.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/strtools.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/voice_assistant/__init__.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/voice_assistant/mode.py +0 -0
- {stark_engine-4.5.2 → stark_engine-4.5.3}/stark/voice_assistant/voice_assistant.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "stark-engine"
|
|
3
|
-
version = "4.5.
|
|
3
|
+
version = "4.5.3"
|
|
4
4
|
description = "S.T.A.R.K - Speech and Text Algorithmic Recognition Kit. Modern framework for creating powerfull voice assistants."
|
|
5
5
|
authors = ["MarkParker5 <mark@parker-programs.com>"]
|
|
6
6
|
license = "CC BY-NC-SA 4.0"
|
|
@@ -3,16 +3,15 @@ from __future__ import annotations
|
|
|
3
3
|
import re
|
|
4
4
|
from abc import ABC
|
|
5
5
|
from dataclasses import dataclass, field
|
|
6
|
-
from typing import AsyncGenerator
|
|
6
|
+
from typing import AsyncGenerator, NamedTuple
|
|
7
7
|
|
|
8
8
|
from stark.core.patterns.pattern import Pattern
|
|
9
9
|
from stark.core.patterns.rules import rules_list
|
|
10
10
|
from stark.core.types import Object
|
|
11
11
|
from stark.core.types.string import String
|
|
12
|
+
from stark.core.types.union import Union, _all_subclasses
|
|
12
13
|
from stark.core.types.word import Word
|
|
13
14
|
from stark.general.cache import alru_cache
|
|
14
|
-
from typing import NamedTuple
|
|
15
|
-
|
|
16
15
|
from stark.general.localisation import LanguageCode, LocaleString, Localizer
|
|
17
16
|
from stark.models.transcription_string import Correction
|
|
18
17
|
from stark.tools.common.span import Span
|
|
@@ -22,6 +21,7 @@ class CorrectionMatch(NamedTuple):
|
|
|
22
21
|
span: Span
|
|
23
22
|
correction: Correction
|
|
24
23
|
|
|
24
|
+
|
|
25
25
|
type ObjectType = type[Object]
|
|
26
26
|
|
|
27
27
|
|
|
@@ -104,6 +104,7 @@ class PatternParser:
|
|
|
104
104
|
|
|
105
105
|
def __init__(self, localizer: Localizer | None = None):
|
|
106
106
|
self.parameter_types_by_name = {}
|
|
107
|
+
self._registering: set[str] = set() # cycle guard for recursive register_parameter_type
|
|
107
108
|
self.localizer = localizer
|
|
108
109
|
self.register_parameter_type(Word)
|
|
109
110
|
self.register_parameter_type(String)
|
|
@@ -114,19 +115,38 @@ class PatternParser:
|
|
|
114
115
|
parser: ObjectParser | None = None,
|
|
115
116
|
# TODO: consider adding lang parameter
|
|
116
117
|
):
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
118
|
+
name = object_type.__name__
|
|
119
|
+
# Idempotent: skip if already registered or currently being registered (cycle guard).
|
|
120
|
+
if name in self.parameter_types_by_name or name in self._registering:
|
|
121
|
+
return
|
|
122
|
+
self._registering.add(name)
|
|
123
|
+
try:
|
|
124
|
+
assert issubclass(object_type, Object), f'Can`t add parameter type "{name}": it is not a subclass of Object'
|
|
125
|
+
# Resolve deps. Union types declare members explicitly in _types;
|
|
126
|
+
# everything else declares deps implicitly via parameter annotations in the pattern.
|
|
127
|
+
if issubclass(object_type, Union) and hasattr(object_type, "_types"):
|
|
128
|
+
deps = object_type._types
|
|
129
|
+
else:
|
|
130
|
+
# Evaluate the pattern first — it may create new classes (e.g. any_subclass calls).
|
|
131
|
+
# Build known AFTER so those new classes are visible by name.
|
|
132
|
+
pattern = object_type.pattern
|
|
133
|
+
known = {cls.__name__: cls for cls in _all_subclasses(Object)}
|
|
134
|
+
deps = [known[p.type_name] for p in pattern.parameters.values() if p.type_name in known]
|
|
135
|
+
# Register each dep before the type itself (depth-first, handles transitive deps).
|
|
136
|
+
for dep in deps:
|
|
137
|
+
self.register_parameter_type(dep)
|
|
138
|
+
exists_type = self.parameter_types_by_name.get(name)
|
|
139
|
+
assert exists_type is None, (
|
|
140
|
+
f"Duplicate parameter type: can`t add parameter type '{name}' because it already exists"
|
|
141
|
+
)
|
|
142
|
+
resolved_parser = parser or ObjectParser()
|
|
143
|
+
resolved_parser.localizer = self.localizer
|
|
144
|
+
self.parameter_types_by_name[name] = RegisteredParameterType(
|
|
145
|
+
name=name, type=object_type, parser=resolved_parser
|
|
146
|
+
)
|
|
147
|
+
self._validate_localizer_keys(object_type)
|
|
148
|
+
finally:
|
|
149
|
+
self._registering.discard(name)
|
|
130
150
|
|
|
131
151
|
def _validate_localizer_keys(self, object_type: ObjectType):
|
|
132
152
|
for pattern in object_type.patterns.values():
|
|
@@ -184,15 +204,17 @@ class PatternParser:
|
|
|
184
204
|
try:
|
|
185
205
|
substring = await self._did_parse(obj, parser, string)
|
|
186
206
|
except ParseError:
|
|
187
|
-
logger.debug(f"Failed to parse object {object_type} with parser {parser} from '{string}'")
|
|
207
|
+
logger.debug(f"Failed to parse object {object_type!r} with parser {parser!r} from '{string}'")
|
|
188
208
|
continue # skip an try the next match candidate
|
|
189
209
|
|
|
190
|
-
assert substring.strip(), ValueError(
|
|
210
|
+
assert substring.strip(), ValueError(
|
|
211
|
+
f"Parsed substring must not be empty. Object: {obj!r}, Parser: {parser!r}"
|
|
212
|
+
)
|
|
191
213
|
assert substring in string, ValueError(
|
|
192
|
-
f"Parsed substring must be a part of the original string. There is no {substring} in {string}. Object: {obj}, Parser: {parser}"
|
|
214
|
+
f"Parsed substring must be a part of the original string. There is no '{substring}' in '{string}'. Object: {obj!r}, Parser: {parser!r}"
|
|
193
215
|
)
|
|
194
216
|
assert obj.value is not None, ValueError(
|
|
195
|
-
f"Parsed object {obj} must have a `value` property set in did_parse method. Object: {obj}, Parser: {parser}"
|
|
217
|
+
f"Parsed object {obj!r} must have a `value` property set in did_parse method. Object: {obj!r}, Parser: {parser!r}"
|
|
196
218
|
)
|
|
197
219
|
|
|
198
220
|
yield ParseResult(obj, substring)
|
|
@@ -441,10 +463,17 @@ class PatternParser:
|
|
|
441
463
|
|
|
442
464
|
# parse the object
|
|
443
465
|
try:
|
|
466
|
+
from stark.core.types.union import Union
|
|
467
|
+
|
|
444
468
|
parse_result = await self.parse_object(parameter_reg_type.type, from_string=raw_param_substr)
|
|
469
|
+
parsed_obj = parse_result.obj
|
|
470
|
+
if isinstance(parsed_obj, Union) and getattr(type(parsed_obj), "_transparent", False):
|
|
471
|
+
# Transparent Unions (MakeUnion / | / any_subclass) are unwrapped to the branch.
|
|
472
|
+
# Named Union subclasses (class Foo(Union)) are kept as-is — caller uses .value.
|
|
473
|
+
parsed_obj = parsed_obj.value
|
|
445
474
|
return ParameterMatch( # take the first match (the only in most cases)
|
|
446
475
|
name=param.name,
|
|
447
|
-
parsed_obj=
|
|
476
|
+
parsed_obj=parsed_obj,
|
|
448
477
|
parsed_substr=parse_result.substring,
|
|
449
478
|
)
|
|
450
479
|
except ParseError as e:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
|
-
from abc import
|
|
4
|
+
from abc import ABCMeta
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
7
|
from stark.core.patterns.pattern import Pattern
|
|
@@ -9,9 +9,37 @@ from stark.general.classproperty import classproperty
|
|
|
9
9
|
from stark.general.localisation import LocaleString
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
class UnionMeta(ABCMeta):
|
|
13
|
+
"""Metaclass that makes | on Object subclasses produce a STARK Union subclass instead of types.UnionType."""
|
|
14
|
+
|
|
15
|
+
def __call__(cls, *args, **kwargs):
|
|
16
|
+
from stark.core.types.union import Union
|
|
17
|
+
|
|
18
|
+
if cls is Union:
|
|
19
|
+
raise TypeError("Union cannot be instantiated directly; subclass it or use | syntax or MakeUnion")
|
|
20
|
+
return super().__call__(*args, **kwargs)
|
|
21
|
+
|
|
22
|
+
def __or__(cls, other: type) -> type:
|
|
23
|
+
from stark.core.types.union import MakeUnion
|
|
24
|
+
|
|
25
|
+
if isinstance(other, type) and issubclass(other, Object):
|
|
26
|
+
return MakeUnion(cls, other)
|
|
27
|
+
return type.__or__(cls, other) # fall through to types.UnionType for X | None etc.
|
|
28
|
+
|
|
29
|
+
def __ror__(cls, other: type) -> type:
|
|
30
|
+
from stark.core.types.union import MakeUnion
|
|
31
|
+
|
|
32
|
+
if isinstance(other, type) and issubclass(other, Object):
|
|
33
|
+
return MakeUnion(other, cls)
|
|
34
|
+
return type.__ror__(cls, other)
|
|
35
|
+
|
|
36
|
+
def __format__(cls, spec) -> str:
|
|
37
|
+
return cls.__name__
|
|
38
|
+
|
|
39
|
+
|
|
12
40
|
# TODO: review programmable init vs did_parse
|
|
13
41
|
# TODO: consider storing parsing metadata here like substr and span
|
|
14
|
-
class Object[T](
|
|
42
|
+
class Object[T](metaclass=UnionMeta):
|
|
15
43
|
value: T
|
|
16
44
|
|
|
17
45
|
@classproperty
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from stark.core.patterns.pattern import Pattern
|
|
4
|
+
from stark.core.types.object import Object, UnionMeta
|
|
5
|
+
from stark.general.classproperty import classproperty
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def MakeUnion(*types: type[Object]) -> type:
|
|
9
|
+
cls = UnionMeta("_".join(t.__name__ for t in types), (Union,), {"_types": list(types)})
|
|
10
|
+
cls._transparent = True # PatternParser unwraps to branch when used as a typed parameter
|
|
11
|
+
return cls
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def any_subclass(cls: type[Object]) -> type[Union]:
|
|
15
|
+
"""Returns a Union of all current concrete subclasses of cls.
|
|
16
|
+
|
|
17
|
+
Result is cached on the base class so the same class object is returned on every call —
|
|
18
|
+
required for stable type registration (the parser keys on class name and object identity).
|
|
19
|
+
Discovered at first call time, so subclasses defined before the pattern is first accessed
|
|
20
|
+
(i.e., at parse time) are included automatically.
|
|
21
|
+
"""
|
|
22
|
+
cache_attr = f"_any_subclass_{cls.__name__}"
|
|
23
|
+
if not hasattr(cls, cache_attr):
|
|
24
|
+
u = MakeUnion(*_all_subclasses(cls))
|
|
25
|
+
u.__name__ = f"Any{cls.__name__}" # no | — Pattern syntax treats | as OR
|
|
26
|
+
setattr(cls, cache_attr, u)
|
|
27
|
+
return getattr(cls, cache_attr)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _all_subclasses(cls):
|
|
31
|
+
for sub in cls.__subclasses__():
|
|
32
|
+
yield sub
|
|
33
|
+
yield from _all_subclasses(sub)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Union(Object):
|
|
37
|
+
"""Base for union types. Use as superclass or combine with | / MakeUnion.
|
|
38
|
+
|
|
39
|
+
self.value — the matched branch Object instance
|
|
40
|
+
self.value.value — the inner parsed value
|
|
41
|
+
type(self.value) — the matched branch type
|
|
42
|
+
|
|
43
|
+
After PatternParser unwraps Union parameters, callers receive the concrete branch
|
|
44
|
+
directly — isinstance, type(), and attribute access all work against the real class.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
_types: list[type[Object]]
|
|
48
|
+
value: Object
|
|
49
|
+
|
|
50
|
+
def __init_subclass__(cls, **kwargs):
|
|
51
|
+
super().__init_subclass__(**kwargs)
|
|
52
|
+
if "pattern" in cls.__dict__ or "patterns" in cls.__dict__:
|
|
53
|
+
raise TypeError(f"{cls.__name__}: Union subclasses may not override 'pattern'")
|
|
54
|
+
|
|
55
|
+
@classproperty
|
|
56
|
+
def pattern(cls) -> Pattern:
|
|
57
|
+
return Pattern("(" + "|".join(f"$m{n}:{t.__name__}" for n, t in enumerate(cls._types, 1)) + ")")
|
|
58
|
+
|
|
59
|
+
async def did_parse(self, from_string) -> str:
|
|
60
|
+
from stark.core.parsing import ParseError
|
|
61
|
+
for k, v in self.__dict__.items():
|
|
62
|
+
if k.startswith("m") and v is not None:
|
|
63
|
+
self.value = v # branch Object, not v.value
|
|
64
|
+
return from_string
|
|
65
|
+
raise ParseError("Union: no branch matched")
|
|
@@ -131,4 +131,4 @@ async def sliding_window_parse[T](
|
|
|
131
131
|
return results
|
|
132
132
|
|
|
133
133
|
# If no valid window is found, raise an error.
|
|
134
|
-
raise ParseError(f"No valid window found using parser={parser} in phrase={phrase}")
|
|
134
|
+
raise ParseError(f"No valid window found using parser={parser!r} in phrase='{phrase}'")
|
|
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
|
{stark_engine-4.5.2 → stark_engine-4.5.3}/stark/tools/phonetic/transcription/latin_passthrough.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|