feat: ж/д слой + cant_swim в скоринг + профили вне модели

Определение специфических рекомендаций (матрица профилей §8):

1. Ж/д слой (закрыт мёртвый railway ×2.5 у РАС):
   - /api/v1/water/{case_id} отдаёт railway=rail как LineString
     (без service/industrial/military веток), кэш общий v2;
   - railway_warning «перекрыть/проверить немедленно» по профилям;
   - SearchMap: Polyline слой ж/д (тёмно-красный), счётчики 💧/🚂.

2. cant_swim → профиль не_умеет_плавать (water ×3.0, без изменения
   радиуса, critical_warning «обследовать водоёмы НЕМЕДЛЕННО»):
   - раньше чекбокс влиял только на текст, в скоринге был пробел;
   - derive в analyze._derive_profiles — работает и для closed_cases.

3. unmodeled_profiles: ДЦП/слабое зрение/слух — честная пометка
   «вне поведенческой модели» с пояснением (vector_tasks B12:
   профили без аналога не выдавать за учтённые); блок на фронте
   в карточке здоровья.

Площадь воды: сферический эксцесс, проверен на квадрате 53° (744017 м²
vs 743272 точного). Тесты: 202 passed (новый test_cant_swim_profile).
This commit is contained in:
2026-09-09 13:12:55 +03:00
parent 98e8e58023
commit f20080305d
2069 changed files with 803865 additions and 97 deletions
@@ -0,0 +1,87 @@
"""
pygments.lexers.ampl
~~~~~~~~~~~~~~~~~~~~
Lexers for the AMPL language.
:copyright: Copyright 2006-present by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from pygments.lexer import RegexLexer, bygroups, using, this, words
from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
Number, Punctuation, Whitespace
__all__ = ['AmplLexer']
class AmplLexer(RegexLexer):
"""
For AMPL source code.
"""
name = 'Ampl'
url = 'http://ampl.com/'
aliases = ['ampl']
filenames = ['*.run']
version_added = '2.2'
tokens = {
'root': [
(r'\n', Text),
(r'\s+', Whitespace),
(r'#.*?\n', Comment.Single),
(r'/[*][\s\S]*?[*]/', Comment.Multiline),
(words((
'call', 'cd', 'close', 'commands', 'data', 'delete', 'display',
'drop', 'end', 'environ', 'exit', 'expand', 'include', 'load',
'model', 'objective', 'option', 'problem', 'purge', 'quit',
'redeclare', 'reload', 'remove', 'reset', 'restore', 'shell',
'show', 'solexpand', 'solution', 'solve', 'update', 'unload',
'xref', 'coeff', 'coef', 'cover', 'obj', 'interval', 'default',
'from', 'to', 'to_come', 'net_in', 'net_out', 'dimen',
'dimension', 'check', 'complements', 'write', 'function',
'pipe', 'format', 'if', 'then', 'else', 'in', 'while', 'repeat',
'for'), suffix=r'\b'), Keyword.Reserved),
(r'(integer|binary|symbolic|ordered|circular|reversed|INOUT|IN|OUT|LOCAL)',
Keyword.Type),
(r'\".*?\"', String.Double),
(r'\'.*?\'', String.Single),
(r'[()\[\]{},;:]+', Punctuation),
(r'\b(\w+)(\.)(astatus|init0|init|lb0|lb1|lb2|lb|lrc|'
r'lslack|rc|relax|slack|sstatus|status|ub0|ub1|ub2|'
r'ub|urc|uslack|val)',
bygroups(Name.Variable, Punctuation, Keyword.Reserved)),
(r'(set|param|var|arc|minimize|maximize|subject to|s\.t\.|subj to|'
r'node|table|suffix|read table|write table)(\s+)(\w+)',
bygroups(Keyword.Declaration, Whitespace, Name.Variable)),
(r'(param)(\s*)(:)(\s*)(\w+)(\s*)(:)(\s*)((\w|\s)+)',
bygroups(Keyword.Declaration, Whitespace, Punctuation, Whitespace,
Name.Variable, Whitespace, Punctuation, Whitespace, Name.Variable)),
(r'(let|fix|unfix)(\s*)((?:\{.*\})?)(\s*)(\w+)',
bygroups(Keyword.Declaration, Whitespace, using(this), Whitespace,
Name.Variable)),
(words((
'abs', 'acos', 'acosh', 'alias', 'asin', 'asinh', 'atan', 'atan2',
'atanh', 'ceil', 'ctime', 'cos', 'exp', 'floor', 'log', 'log10',
'max', 'min', 'precision', 'round', 'sin', 'sinh', 'sqrt', 'tan',
'tanh', 'time', 'trunc', 'Beta', 'Cauchy', 'Exponential', 'Gamma',
'Irand224', 'Normal', 'Normal01', 'Poisson', 'Uniform', 'Uniform01',
'num', 'num0', 'ichar', 'char', 'length', 'substr', 'sprintf',
'match', 'sub', 'gsub', 'print', 'printf', 'next', 'nextw', 'prev',
'prevw', 'first', 'last', 'ord', 'ord0', 'card', 'arity',
'indexarity'), prefix=r'\b', suffix=r'\b'), Name.Builtin),
(r'(\+|\-|\*|/|\*\*|=|<=|>=|==|\||\^|<|>|\!|\.\.|:=|\&|\!=|<<|>>)',
Operator),
(words((
'or', 'exists', 'forall', 'and', 'in', 'not', 'within', 'union',
'diff', 'difference', 'symdiff', 'inter', 'intersect',
'intersection', 'cross', 'setof', 'by', 'less', 'sum', 'prod',
'product', 'div', 'mod'), suffix=r'\b'),
Keyword.Reserved), # Operator.Name but not enough emphasized with that
(r'(\d+\.(?!\.)\d*|\.(?!.)\d+)([eE][+-]?\d+)?', Number.Float),
(r'\d+([eE][+-]?\d+)?', Number.Integer),
(r'[+-]?Infinity', Number.Integer),
(r'(\w+|(\.(?!\.)))', Text)
]
}