Изменения документа App

Редактировал(а) A1MTestAdmin 2026/10/19 06:56

От версии 43.1
отредактировано A1MTestAdmin
на 2026/10/19 02:16
Изменить комментарий: Imported from XAR
К версии 30.1
отредактировано superadmin
на 2026/10/17 03:25
Изменить комментарий: A1M: preserve ACL and protected code authorship after import

Сводка

Подробности

Свойства страницы
Название
... ... @@ -1,1 +1,1 @@
1 -App
1 +A1M
Автор документа
... ... @@ -1,1 +1,1 @@
1 -XWiki.A1MTestAdmin
1 +XWiki.superadmin
Скрытые
... ... @@ -1,1 +1,1 @@
1 -false
1 +true
Содержимое
... ... @@ -1,12 +8,1 @@
1 -{{velocity}}
2 -#set($discard = $xwiki.ssx.use('A1M.App'))
3 -#set($discard = $xwiki.jsx.use('A1M.App'))
4 -#if($request.getMethod() == 'GET')
5 -$services.a1mRead.render()
6 -#else
7 -
8 8  {{a1m/}}
9 -
10 -#end
11 -{{/velocity}}
12 -
A1M-wordmark-r04.svg
Автор
... ... @@ -1,1 +1,0 @@
1 -XWiki.A1MTestAdmin
Размер
... ... @@ -1,1 +1,0 @@
1 -1.5 MB
Содержимое
ATLAS-wordmark-r04.svg
Автор
... ... @@ -1,1 +1,0 @@
1 -XWiki.A1MTestAdmin
Размер
... ... @@ -1,1 +1,0 @@
1 -1.5 MB
Содержимое
GolosText-VariableFont_wght.ttf
Автор
... ... @@ -1,1 +1,0 @@
1 -XWiki.A1MTestAdmin
Размер
... ... @@ -1,1 +1,0 @@
1 -180.0 KB
Содержимое
Jost-OFL.txt
Автор
... ... @@ -1,1 +1,0 @@
1 -XWiki.A1MTestAdmin
Размер
... ... @@ -1,1 +1,0 @@
1 -4.3 KB
Содержимое
... ... @@ -1,94 +1,0 @@
1 -Copyright 2020 The Jost Project Authors (https://github.com/indestructible-type)
2 -
3 -This Font Software is licensed under the SIL Open Font License, Version 1.1.
4 -This license is copied below, and is also available with a FAQ at:
5 -http://scripts.sil.org/OFL
6 -
7 -
8 ------------------------------------------------------------
9 -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10 ------------------------------------------------------------
11 -
12 -PREAMBLE
13 -The goals of the Open Font License (OFL) are to stimulate worldwide
14 -development of collaborative font projects, to support the font creation
15 -efforts of academic and linguistic communities, and to provide a free and
16 -open framework in which fonts may be shared and improved in partnership
17 -with others.
18 -
19 -The OFL allows the licensed fonts to be used, studied, modified and
20 -redistributed freely as long as they are not sold by themselves. The
21 -fonts, including any derivative works, can be bundled, embedded,
22 -redistributed and/or sold with any software provided that any reserved
23 -names are not used by derivative works. The fonts and derivatives,
24 -however, cannot be released under any other type of license. The
25 -requirement for fonts to remain under this license does not apply
26 -to any document created using the fonts or their derivatives.
27 -
28 -DEFINITIONS
29 -"Font Software" refers to the set of files released by the Copyright
30 -Holder(s) under this license and clearly marked as such. This may
31 -include source files, build scripts and documentation.
32 -
33 -"Reserved Font Name" refers to any names specified as such after the
34 -copyright statement(s).
35 -
36 -"Original Version" refers to the collection of Font Software components as
37 -distributed by the Copyright Holder(s).
38 -
39 -"Modified Version" refers to any derivative made by adding to, deleting,
40 -or substituting -- in part or in whole -- any of the components of the
41 -Original Version, by changing formats or by porting the Font Software to a
42 -new environment.
43 -
44 -"Author" refers to any designer, engineer, programmer, technical
45 -writer or other person who contributed to the Font Software.
46 -
47 -PERMISSION & CONDITIONS
48 -Permission is hereby granted, free of charge, to any person obtaining
49 -a copy of the Font Software, to use, study, copy, merge, embed, modify,
50 -redistribute, and sell modified and unmodified copies of the Font
51 -Software, subject to the following conditions:
52 -
53 -1) Neither the Font Software nor any of its individual components,
54 -in Original or Modified Versions, may be sold by itself.
55 -
56 -2) Original or Modified Versions of the Font Software may be bundled,
57 -redistributed and/or sold with any software, provided that each copy
58 -contains the above copyright notice and this license. These can be
59 -included either as stand-alone text files, human-readable headers or
60 -in the appropriate machine-readable metadata fields within text or
61 -binary files as long as those fields can be easily viewed by the user.
62 -
63 -3) No Modified Version of the Font Software may use the Reserved Font
64 -Name(s) unless explicit written permission is granted by the corresponding
65 -Copyright Holder. This restriction only applies to the primary font name as
66 -presented to the users.
67 -
68 -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69 -Software shall not be used to promote, endorse or advertise any
70 -Modified Version, except to acknowledge the contribution(s) of the
71 -Copyright Holder(s) and the Author(s) or with their explicit written
72 -permission.
73 -
74 -5) The Font Software, modified or unmodified, in part or in whole,
75 -must be distributed entirely under this license, and must not be
76 -distributed under any other license. The requirement for fonts to
77 -remain under this license does not apply to any document created
78 -using the Font Software.
79 -
80 -TERMINATION
81 -This license becomes null and void if any of the above conditions are
82 -not met.
83 -
84 -DISCLAIMER
85 -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86 -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87 -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88 -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89 -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90 -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91 -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92 -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93 -OTHER DEALINGS IN THE FONT SOFTWARE.
94 -
Jost-VariableFont_wght.ttf
Автор
... ... @@ -1,1 +1,0 @@
1 -XWiki.A1MTestAdmin
Размер
... ... @@ -1,1 +1,0 @@
1 -131.8 KB
Содержимое
XWiki.JavaScriptExtension[0]
cache
... ... @@ -1,1 +1,0 @@
1 -default
code
... ... @@ -1,201 +1,0 @@
1 -/* A1M native JavaScript skin extension. No requests, storage or application data cache. */
2 -(() => {
3 - 'use strict';
4 - function enhance() {
5 - const shell = document.querySelector('.a1m-shell');
6 - if (!shell || shell.dataset.interfaceVersion === '1.0.1') return;
7 - shell.dataset.interfaceVersion = '1.0.1';
8 - const labels = {
9 - priority: 'По приоритету', title: 'По названию', updated: 'По дате изменения',
10 - relevance: 'По релевантности', asc: 'По возрастанию', desc: 'По убыванию'
11 - };
12 - shell.querySelectorAll('select[name=sort] option,select[name=direction] option').forEach(option => {
13 - if (labels[option.value]) option.textContent = labels[option.value];
14 - });
15 - const current = new URL(window.location.href);
16 - const section = current.searchParams.get('section') || '';
17 - shell.querySelectorAll('.side nav a').forEach(link => {
18 - const destination = new URL(link.href, window.location.href);
19 - if (destination.pathname === current.pathname && (destination.searchParams.get('section') || '') === section) {
20 - link.setAttribute('aria-current', 'page');
21 - }
22 - });
23 - // Every option was already filtered by server-side permissions. Only replace its control.
24 - const select = shell.querySelector('.filters select[name=theme][multiple]');
25 - if (select) {
26 - const originalLabel = select.closest('label');
27 - const fieldset = document.createElement('fieldset');
28 - fieldset.className = 'theme-options';
29 - const legend = document.createElement('legend');
30 - legend.textContent = 'Тематика · можно выбрать несколько';
31 - fieldset.append(legend);
32 - select.hidden = true;
33 - select.setAttribute('aria-hidden', 'true');
34 - select.tabIndex = -1;
35 - const checkboxes = [];
36 - const options = Array.from(select.options);
37 - for (const option of options.filter(item => item.value)) {
38 - const label = document.createElement('label');
39 - const checkbox = document.createElement('input');
40 - checkbox.type = 'checkbox';
41 - checkbox.checked = option.selected;
42 - checkbox.addEventListener('change', () => {
43 - option.selected = checkbox.checked;
44 - const empty = options.find(item => !item.value);
45 - if (empty) empty.selected = !checkboxes.some(item => item.checked);
46 - });
47 - checkboxes.push(checkbox);
48 - label.append(checkbox, document.createTextNode(option.textContent));
49 - fieldset.append(label);
50 - }
51 - const reset = document.createElement('button');
52 - reset.type = 'button';
53 - reset.textContent = 'Все темы';
54 - reset.addEventListener('click', () => {
55 - options.forEach(option => { option.selected = !option.value; });
56 - checkboxes.forEach(checkbox => { checkbox.checked = false; });
57 - });
58 - fieldset.append(reset, select);
59 - originalLabel.replaceWith(fieldset);
60 - }
61 - shell.querySelectorAll('.panel-head').forEach(header => {
62 - header.setAttribute('role', 'heading');
63 - header.setAttribute('aria-level', '2');
64 - });
65 - // Keep the intended destination even when a login starts directly from a record.
66 - const login = shell.querySelector('a[href*="/bin/login/"]');
67 - if (login) {
68 - const target = new URL(login.href, window.location.href);
69 - target.searchParams.set('xredirect', current.pathname + current.search);
70 - login.href = target.pathname + target.search;
71 - }
72 - }
73 - if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', enhance, { once: true });
74 - else enhance();
75 -})();
76 -
77 -/* Derived view of permission-filtered XWiki DTOs. No storage, write API or editor. */
78 -(function (root) {
79 - 'use strict';
80 - const roles={direct:'Прямой вклад',support:'Необходимая опора',context:'Смежный контекст',unassessed:'Не оценено',unjustified:'Связь не обоснована',unrelated:'Рассмотрено, не относится'};
81 - function assess(record,goal) {
82 - const a=(record.assessments||[]).find(x=>x.goal===goal.id);
83 - if(!a)return {role:'unassessed',reason:'Ручная оценка для этой цели ещё не сохранена.'};
84 - if(a.goal_revision!==goal.version||a.record_revision!==record.version)return {role:'unassessed',reason:'Оценка относится к другой редакции. Требуется пересмотр.',previous:a};
85 - return a;
86 - }
87 - function filter(records,selected,mode='any',query='') {
88 - const norm=s=>s.toLocaleLowerCase('ru').replaceAll('ё','е');
89 - return records.filter(r=>!r.goal&&!r.taxonomy_family&&(!query||norm([r.title,r.summary,r.id,r.search_text||''].join(' ')).includes(norm(query)))&&Object.entries(selected).every(([field,values])=>!values.length||(Array.isArray(r[field])?(mode==='all'?values.every(v=>r[field].includes(v)):values.some(v=>r[field].includes(v))):values.includes(String(r[field])))));
90 - }
91 - function layout(records,goal,group='kind') {
92 - const keys=[...new Set(records.map(r=>Array.isArray(r[group])?(r[group][0]||'Не указано'):r[group]||'Не указано'))].sort();
93 - const buckets=new Map(),unknown=[];
94 - records.slice().sort((a,b)=>a.id.localeCompare(b.id)).forEach(r=>{
95 - const a=assess(r,goal),ring=['direct','support','context'].indexOf(a.role);
96 - if(ring<0){unknown.push({record:r,assessment:a});return;}
97 - const sector=Array.isArray(r[group])?(r[group][0]||'Не указано'):r[group]||'Не указано';
98 - const k=ring+'|'+sector;if(!buckets.has(k))buckets.set(k,[]);buckets.get(k).push({record:r,assessment:a,ring,sector});
99 - });
100 - const nodes=[];
101 - for(const bucket of buckets.values())bucket.forEach((n,i)=>{
102 - const si=keys.indexOf(n.sector),angle=-Math.PI/2+2*Math.PI*(si+(i+1)/(bucket.length+1))/keys.length;
103 - const radius=[95,185,275][n.ring]+(i%3-1)*12;
104 - nodes.push({...n,x:350+Math.cos(angle)*radius,y:350+Math.sin(angle)*radius});
105 - });
106 - return {nodes,unknown,sectors:keys};
107 - }
108 - const api={roles,assess,filter,layout};
109 - if(typeof module!=='undefined')module.exports=api;
110 - root.A1MCentre=api;
111 - if(typeof document==='undefined')return;
112 - function element(tag,text,parent,attrs={}) {
113 - const el=document.createElement(tag);if(text)el.textContent=text;
114 - for(const [k,v] of Object.entries(attrs))el.setAttribute(k,v);
115 - if(parent)parent.append(el);return el;
116 - }
117 - function svgEl(tag,attrs,parent,text) {
118 - const el=document.createElementNS('http://www.w3.org/2000/svg',tag);
119 - for(const [k,v] of Object.entries(attrs))el.setAttribute(k,String(v));
120 - if(text)el.textContent=text;parent.append(el);return el;
121 - }
122 - function init(host) {
123 - let data;
124 - try {data=JSON.parse(host.dataset.payload);if(data.schema!=='a1m-centre/2.0')throw Error('schema');}
125 - catch {element('p','Не удалось прочитать данные. Обновите страницу; это технический сбой.',host,{role:'alert'});return;}
126 - const all=data.records,byId=new Map(all.map(r=>[r.id,r])),selected={},controls=element('div','',host,{class:'centre-filters'});
127 - const q=element('input','',element('label','Поиск',controls),{type:'search'});
128 - const mode=element('select','',element('label','Внутри семейства',controls));
129 - element('option','Любое выбранное значение',mode,{value:'any'});element('option','Все выбранные значения',mode,{value:'all'});
130 - const familyDetails=element('details','',host);element('summary','Смысловые семейства и независимые состояния',familyDetails);
131 - const familyControls=element('div','',familyDetails,{class:'centre-filters'});
132 - const fields={...data.families,kind:'Вид',state:'Редактура',whole:'Концептуальная цельность'};
133 - for(const [field,label] of Object.entries(fields)) {
134 - selected[field]=[];
135 - const values=[...new Set(all.filter(r=>!r.goal&&!r.taxonomy_family).flatMap(r=>Array.isArray(r[field])?r[field]:r[field]==null?[]:[String(r[field])]))].sort();
136 - const select=element('select','',element('label',label,familyControls),{multiple:'',size:'3','aria-label':label});
137 - if(!values.length){element('option','Пока не указано',select,{value:''});select.disabled=true;}
138 - values.forEach(v=>element('option',field==='whole'?(v==='true'?'Цельность отмечена':'Цельность не отмечена'):(byId.get(v)?.title||v),select,{value:v}));
139 - select.addEventListener('change',()=>{selected[field]=[...select.selectedOptions].map(o=>o.value);render();});
140 - select.dataset.field=field;
141 - }
142 - const active=element('div','',host,{class:'centre-active','aria-label':'Выбранные условия'});
143 - const goals=all.filter(r=>r.goal),goalSelect=element('select','',element('label','Цель карты',controls));
144 - goals.forEach(g=>element('option',g.title,goalSelect,{value:g.id}));
145 - const groupSelect=element('select','',element('label','Секторы',controls));
146 - element('option','Вид материала',groupSelect,{value:'kind'});element('option','Основное направление',groupSelect,{value:'family_direction'});
147 - const reset=element('button','Сбросить условия и вид',host,{type:'button'});
148 - reset.onclick=()=>{Object.keys(selected).forEach(k=>selected[k]=[]);familyControls.querySelectorAll('select[multiple]').forEach(s=>[...s.options].forEach(o=>o.selected=false));q.value='';groupSelect.value='kind';render();};
149 - const status=element('p','',host,{'aria-live':'polite',role:'status'});
150 - element('p','Точка — концептуальная цельность. Она не означает истинность, публикацию или завершение проекта. Кольцо — ручная оценка вклада в выбранную цель; сила связи от неё независима.',host,{class:'centre-note'});
151 - const output=element('div','',host);
152 - function render() {
153 - active.replaceChildren();
154 - for(const [field,values] of Object.entries(selected))values.forEach(v=>{
155 - const b=element('button',fields[field]+': '+(byId.get(v)?.title||v)+' ×',active,{type:'button'});
156 - b.onclick=()=>{selected[field]=selected[field].filter(x=>x!==v);familyControls.querySelectorAll('select[multiple]').forEach(s=>{if(s.dataset.field===field)[...s.options].forEach(o=>o.selected=selected[field].includes(o.value));});render();};
157 - });
158 - const rows=filter(all,selected,mode.value,q.value);output.replaceChildren();status.textContent='Доступных материалов: '+rows.length;
159 - if(!rows.length)element('p','Материалы не найдены. Измените или сбросьте условия.',output);
160 - const goal=byId.get(goalSelect.value);
161 - if(host.dataset.mode==='map'&&goal) {
162 - element('h2',goal.title,output);element('p','Критерий: '+(goal.criterion||'Не указан'),output);
163 - const map=layout(rows,goal,groupSelect.value),svg=svgEl('svg',{viewBox:'0 0 700 700',class:'centre-map',role:'img','aria-label':'Три кольца вклада и подписанные секторы; полный список с объяснениями ниже'},output);
164 - const defs=svgEl('defs',{},svg),marker=svgEl('marker',{id:'centre-arrow',viewBox:'0 0 10 10',refX:9,refY:5,markerWidth:5,markerHeight:5,orient:'auto'},defs);
165 - svgEl('path',{d:'M1 1 L9 5 L1 9',fill:'none',stroke:'#596169'},marker);
166 - [120,210,300].forEach((radius,i)=>{svgEl('circle',{cx:350,cy:350,r:radius,fill:'none',stroke:'#9aa6b2','stroke-width':1},svg);svgEl('text',{x:358,y:350-radius+18},svg,roles[['direct','support','context'][i]]);});
167 - map.sectors.forEach((key,i)=>{const angle=-Math.PI/2+i*2*Math.PI/map.sectors.length;svgEl('line',{x1:350,y1:350,x2:350+Math.cos(angle)*310,y2:350+Math.sin(angle)*310,stroke:'#ced3d8'},svg);const mid=angle+Math.PI/map.sectors.length;svgEl('text',{x:350+Math.cos(mid)*325,y:350+Math.sin(mid)*325,'text-anchor':'middle'},svg,(byId.get(key)?.title||key).slice(0,30));});
168 - element('p','Секторы: '+map.sectors.map(k=>byId.get(k)?.title||k).join(' · '),output,{class:'centre-note'});
169 - const placed=new Map(map.nodes.map(n=>[n.record.id,n]));
170 - (data.edges||[]).forEach(e=>{const a=placed.get(e.source),b=placed.get(e.target);if(!a||!b)return;const l=svgEl('line',{x1:a.x,y1:a.y,x2:b.x,y2:b.y,stroke:'#596169','stroke-width':e.strength?0.6+e.strength*.25:.6,...(e.direction==='forward'?{'marker-end':'url(#centre-arrow)'}:{})},svg);svgEl('title',{},l,e.type+' · '+(e.strength||'не оценена')+' · '+e.note);});
171 - map.nodes.forEach(n=>{
172 - const a=svgEl('a',{href:n.record.url,'aria-label':n.record.title},svg),g=svgEl('g',{transform:`translate(${n.x},${n.y})`,fill:'#fff',stroke:'#0749a9','stroke-width':1.2,class:'node-shape'},a);
173 - const kind=n.record.kind;
174 - if(kind==='Вопрос')svgEl('path',{d:'M0 -10 L10 8 L-10 8 Z'},g);
175 - else if(['Проект','План'].includes(kind))svgEl('rect',{x:-8,y:-8,width:16,height:16},g);
176 - else if(kind==='Разбор опыта')svgEl('rect',{x:-11,y:-6,width:22,height:12},g);
177 - else if(['Источник','Ресурс'].includes(kind))svgEl('path',{d:'M0 -10 L10 0 L0 10 L-10 0 Z'},g);
178 - else svgEl('circle',{cx:0,cy:0,r:9},g);
179 - if(n.record.whole)svgEl('circle',{cx:0,cy:0,r:2,fill:'#1a1a1a',stroke:'none'},g);
180 - svgEl('title',{},a,n.record.title+' · '+roles[n.assessment.role]+' · '+n.assessment.reason);
181 - svgEl('text',{x:n.x+13,y:n.y+4},a,n.record.id);
182 - });
183 - element('p','Сектор направления использует первое указанное направление; остальные сохраняются в фильтрах. Полные названия и объяснения доступны в списке. При плотной карте пользуйтесь фильтрами.',output,{class:'centre-note'});
184 - element('h3','Оценённые материалы',output);renderList(map.nodes.map(n=>n.record),goal);
185 - element('h3','Вне колец: не оценено / связь не обоснована / не относится',output);renderList(map.unknown.map(n=>n.record),goal);
186 - } else {
187 - if(host.dataset.mode==='map')element('p','Доступных целей нет. Создайте цель в штатном редакторе XWiki.',output);
188 - renderList(rows,null);
189 - }
190 - function renderList(items,target) {
191 - const list=element('ul','',output,{class:'centre-list'});
192 - items.forEach(r=>{const li=element('li','',list);element('a',r.title,li,{href:r.url});element('div',r.kind+' · '+r.id+' · '+(r.whole?'● Цельность отмечена':'○ Цельность не отмечена')+' · '+({draft:'Черновик',review:'На проверке',ready:'Готово к выпуску',published:'Опубликовано'}[r.state]||r.state),li,{class:'meta'});element('p',r.summary,li);if(target){const a=assess(r,target);element('p',roles[a.role]+': '+a.reason,li);} });
193 - }
194 - }
195 - [q,mode,goalSelect,groupSelect].forEach(el=>el.addEventListener('input',render));render();
196 - document.querySelectorAll('.a1m-fallback-registry').forEach(el=>el.classList.add('enhanced'));
197 - }
198 - function boot(){document.querySelectorAll('#a1m-centre:not([data-initialised])').forEach(h=>{h.dataset.initialised='true';init(h);});}
199 - if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',boot);else boot();
200 -})(typeof globalThis!=='undefined'?globalThis:this);
201 -
name
... ... @@ -1,1 +1,0 @@
1 -A1M centre 2.0
parse
... ... @@ -1,1 +1,0 @@
1 -Нет
use
... ... @@ -1,1 +1,0 @@
1 -onDemand
XWiki.StyleSheetExtension[0]
cache
... ... @@ -1,1 +1,0 @@
1 -default
code
... ... @@ -1,46 +1,0 @@
1 -/* A1M / ATLAS 2.0. Scope: author centre only. Raster marks retain source viewBox. */
2 -@font-face{font-family:"Jost";src:url(/bin/download/A1M/App/Jost-VariableFont_wght.ttf) format("truetype");font-weight:100 900;font-display:swap}
3 -@font-face{font-family:"Golos Text";src:url(/bin/download/A1M/App/GolosText-VariableFont_wght.ttf) format("truetype");font-weight:100 900;font-display:swap}
4 -
5 -.a1m-shell{--ink:#1a1a1a;--muted:#596169;--line:#ced3d8;--paper:#fff;--blue:#0749a9;--amber:#fbbd5b;color:var(--ink);background:#fafbf9;font:15px/1.65 "Golos Text",sans-serif;display:grid;grid-template-columns:224px minmax(0,1fr);min-height:100vh;text-align:left}
6 -.a1m-shell *{box-sizing:border-box}.a1m-shell a{color:inherit;text-underline-offset:4px}.a1m-shell :is(a,button,input,select,textarea,summary):focus-visible{outline:2px solid var(--blue);outline-offset:4px}.a1m-shell .side{border-right:1px solid var(--line);padding:36px 22px;background:#fff}.a1m-shell .logo{display:block;width:140px;margin-bottom:24px}.a1m-shell .logo svg{display:block;width:100%;height:auto}.a1m-shell .identity div{font-size:12px;color:var(--muted)}.a1m-shell .identity{padding-bottom:24px;border-bottom:1px solid var(--amber)}.a1m-shell nav{margin:22px 0}.a1m-shell .side nav a{display:block;padding:9px 0;text-decoration:none;min-height:44px}.a1m-shell .side nav a:hover,.a1m-shell .side nav a[aria-current=page]{color:var(--blue)}.a1m-shell small,.a1m-shell .meta,.a1m-shell .summary{color:var(--muted);font-size:12px}.a1m-shell .workspace{min-width:0}.a1m-shell .top{padding:16px 32px;display:flex;align-items:center;justify-content:space-between;gap:12px;border-bottom:1px solid var(--line);background:#fff;min-height:64px}.a1m-shell .main{max-width:1440px;margin:auto;padding:40px 36px;width:100%;min-width:0}.a1m-shell h1,.a1m-shell h2,.a1m-shell h3{font-family:Jost,sans-serif;font-weight:450;line-height:1.16;overflow-wrap:anywhere}.a1m-shell h1{font-size:clamp(30px,4vw,48px);letter-spacing:-.025em;margin:0 0 18px}.a1m-shell h2{font-size:25px;margin:20px 0 12px}.a1m-shell h3{font-size:20px}.a1m-shell .intro{max-width:64ch;color:var(--muted);margin-bottom:28px}.a1m-shell .grid{display:grid;grid-template-columns:1.5fr 1fr;gap:28px}.a1m-shell .panel{background:#fff;border:1px solid var(--line);margin-bottom:24px;min-width:0;overflow-wrap:anywhere}.a1m-shell .panel-head,.a1m-shell .row{padding:16px 20px;margin:0;border-bottom:1px solid var(--line)}.a1m-shell .panel-head{font-family:Jost;font-size:20px}.a1m-shell .row-title{font-size:20px}.a1m-shell .registry-row{display:grid;grid-template-columns:100px minmax(0,1fr) 130px;gap:20px;padding:20px;border-top:1px solid var(--line);overflow-wrap:anywhere}.a1m-shell .registry-row a{font-family:Jost;font-size:21px;text-decoration:none}.a1m-shell .registry-row .summary{margin:7px 0 0;font-size:13px}.a1m-shell .tag{font-size:12px;color:var(--muted)}.a1m-shell .filters{display:flex;flex-wrap:wrap;gap:16px;padding:20px;border-bottom:1px solid var(--line);align-items:end}.a1m-shell label{display:flex;flex-direction:column;gap:6px;font-size:12px;color:var(--muted)}.a1m-shell :is(input,select,textarea,button,.button){font:inherit;max-width:100%;min-height:44px;border:1px solid #9aa6b2;border-radius:0;padding:9px 12px;background:#fff;color:var(--ink)}.a1m-shell input[type=checkbox]{min-height:18px;width:18px}.a1m-shell select{min-width:120px}.a1m-shell button,.a1m-shell .button{cursor:pointer;text-decoration:none;font-size:14px;display:inline-flex;align-items:center;justify-content:center}.a1m-shell .primary{background:var(--blue);color:#fff;border-color:var(--blue)}.a1m-shell .actions{display:flex;flex-wrap:wrap;gap:12px;margin:20px 0}.a1m-shell .form{display:grid;gap:20px;padding:24px;max-width:80ch}.a1m-shell .form textarea{min-height:100px}.a1m-shell .reading{font-size:17px;line-height:1.8;max-width:74ch;padding:28px;background:#fff;border:1px solid var(--line);overflow-wrap:anywhere}.a1m-shell .reading :is(table,pre){display:block;max-width:100%;overflow:auto}.a1m-shell .reading img{max-width:100%;height:auto}.a1m-shell .article-toc{max-width:74ch;padding:20px;border:1px solid var(--line)}.a1m-shell .message,.a1m-shell .error{padding:20px;border-left:2px solid var(--amber);background:#fff}.a1m-shell .error{border-color:#d63031}.a1m-shell .skip{position:absolute;left:-9999px}.a1m-shell .skip:focus{left:8px;top:8px;z-index:50;background:#fff}.a1m-shell .menu,.a1m-shell .menu-toggle{display:none}.a1m-shell .centre-filters{display:grid;grid-template-columns:repeat(auto-fit,minmax(155px,1fr));gap:16px;margin:24px 0}.a1m-shell .centre-filters label{min-width:0}.a1m-shell .centre-filters select{width:100%;min-width:0}.a1m-shell .centre-active{display:flex;flex-wrap:wrap;gap:8px}.a1m-shell .centre-map{width:100%;height:auto;display:block;background:#fff}.a1m-shell .centre-map text{font:13px "Golos Text",sans-serif;fill:var(--ink)}.a1m-shell .centre-map a:focus{outline:none}.a1m-shell .centre-map a:focus .node-shape{stroke-width:3}.a1m-shell .centre-list li{margin:16px 0;overflow-wrap:anywhere}.a1m-shell .centre-note{max-width:80ch;color:var(--muted);font-size:13px}.a1m-shell .product-mark{width:155px;display:block;margin:24px 0}.a1m-shell .product-mark svg{width:100%;height:auto}.a1m-shell .a1m-fallback-registry.enhanced{display:none}
7 -body:has(.a1m-shell){margin:0}body:has(.a1m-shell) :is(#headerglobal,#footerglobal,#contentmenu,#hierarchy,#document-title,#document-info,#xdocFooter,#menuview,#hierarchy_breadcrumb,#leftPanels,#rightPanels,#leftPanelsToggle,#rightPanelsToggle){display:none}body:has(.a1m-shell:not(.a1m-native-extra)) #xwikidata{display:none}body:has(.a1m-shell) :is(#xwikimaincontainer,#xwikimaincontainerinner,#xwikicontent,#contentcontainer,#mainContentArea,#contentcolumn){padding:0!important;margin:0!important;max-width:none!important;width:100%!important;border:0;float:none}body:has(.a1m-shell) #mainContentArea>.document-header{display:none}
8 -@media(max-width:800px){.a1m-shell{display:block}.a1m-shell .side{display:none}.a1m-shell:has(#a1m-menu:checked) .side{display:block}.a1m-shell .menu{display:block;cursor:pointer}.a1m-shell .menu-toggle{display:block;position:absolute;clip-path:inset(50%);width:1px;height:1px;min-height:0}.a1m-shell:has(.menu-toggle:focus-visible) .menu{outline:2px solid var(--blue)}.a1m-shell .main{padding:24px 16px}.a1m-shell .top{padding:12px 16px}.a1m-shell .grid,.a1m-shell .registry-row{grid-template-columns:1fr}.a1m-shell .reading{padding:20px 16px}.a1m-shell :is(input,select,textarea){font-size:16px}.a1m-shell .centre-map text{font-size:15px}}
9 -@media(prefers-reduced-motion:reduce){.a1m-shell *{scroll-behavior:auto!important;animation:none!important;transition:none!important}}@media print{.a1m-shell{display:block}.a1m-shell :is(.side,.top,.filters,.actions){display:none}.a1m-shell .reading{border:0}}
10 -
11 -.a1m-shell .a1m-wordmark{display:block;width:100%;aspect-ratio:498/173;background:url("/bin/download/A1M/App/A1M-wordmark-r04.svg") center/contain no-repeat}
12 -
13 -.a1m-shell .atlas-wordmark{display:block;width:100%;aspect-ratio:776/188;background:url("/bin/download/A1M/App/ATLAS-wordmark-r04.svg") center/contain no-repeat}
14 -
15 -/* A1M fallback filter repair D1. Append to the existing A1M.App SSX code only. */
16 -.a1m-shell .a1m-fallback-registry .filters{
17 - display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,170px),1fr));
18 - gap:16px;align-items:end;min-width:0;
19 -}
20 -.a1m-shell .a1m-fallback-registry .filters>*{min-width:0;max-width:100%;margin:0}
21 -.a1m-shell .a1m-fallback-registry .filters>.query{
22 - grid-column:1/-1;width:100%;display:flex;flex-direction:column;
23 -}
24 -.a1m-shell .a1m-fallback-registry .filters>.query input{width:100%;min-width:0;box-sizing:border-box}
25 -.a1m-shell .a1m-fallback-registry .filters :is(fieldset.theme-filter,fieldset.theme-options){
26 - grid-column:1/-1;display:flex;flex-flow:row wrap;align-items:center;gap:8px 16px;
27 - width:100%;min-width:0;border:0;padding:0;margin:0;
28 -}
29 -.a1m-shell .a1m-fallback-registry .filters :is(.theme-filter,.theme-options)>legend{
30 - float:none;display:block;width:100%;max-width:100%;margin:0 0 6px;padding:0;
31 - border:0;font:inherit;color:var(--muted,#596169);line-height:1.4;
32 -}
33 -.a1m-shell .a1m-fallback-registry .filters :is(.theme-filter,.theme-options) label{
34 - display:inline-flex;flex:0 1 auto;flex-direction:row;align-items:center;gap:8px;
35 - min-width:0;max-width:100%;margin:0;overflow-wrap:anywhere;
36 -}
37 -.a1m-shell .a1m-fallback-registry .filters :is(.theme-filter,.theme-options) input[type=checkbox]{
38 - flex:0 0 18px;width:18px;height:18px;min-height:18px;margin:0;
39 -}
40 -.a1m-shell .a1m-fallback-registry .filters>label:not(.query){display:flex;flex-direction:column;width:100%}
41 -.a1m-shell .a1m-fallback-registry .filters>label select{width:100%;min-width:0;box-sizing:border-box}
42 -@media(max-width:600px){
43 - .a1m-shell .a1m-fallback-registry .filters{grid-template-columns:minmax(0,1fr);gap:14px;padding:16px}
44 - .a1m-shell .a1m-fallback-registry .filters :is(.theme-filter,.theme-options){gap:10px 16px}
45 -}
46 -
name
... ... @@ -1,1 +1,0 @@
1 -A1M centre 2.0
parse
... ... @@ -1,1 +1,0 @@
1 -Нет
use
... ... @@ -1,1 +1,0 @@
1 -onDemand