Files
meguri/static/generation-map.html
T

29 lines
10 KiB
HTML
Raw Normal View History

2026-10-07 15:30:31 +01:00
<dialog class="generation-map" x-ref="generationMap" @cancel.prevent="mapProbe?mapProbeClose():closeGenerationMap()" @click="if($event.target===$el){const r=$el.getBoundingClientRect();if($event.clientX<r.left || $event.clientX>r.right || $event.clientY<r.top || $event.clientY>r.bottom)closeGenerationMap()}">
2026-09-24 14:35:05 +03:00
<header class="map-heading"><div><h2 x-text="t('map_title')"></h2><p x-text="t('map_hint')"></p></div><button type="button" @click="closeGenerationMap()" :aria-label="t('close_dialog_7b2902')" x-text="t('map_close')"></button></header>
<div class="map-toolbar"><span class="map-status" :class="{'map-status-error':mapSnapshot?.report.issues.length}" x-text="mapBusy?t('cover_checking'):mapSnapshot?.report.issues.length?t('diagnostics_count',{count:mapSnapshot.report.issues.length}):t('generation_checked')"></span><button @click="refreshGenerationMap()" :disabled="mapBusy" x-text="t('map_refresh')"></button><div class="grow"></div><button @click="mapZoom(.8)" :aria-label="t('map_zoom_out')" x-text="t('map_minus')"></button><button @click="mapZoom(1.25)" :aria-label="t('map_zoom_in')" x-text="t('map_plus')"></button><button @click="mapFit()" x-text="t('map_fit')"></button></div>
<p class="validation-error" x-show="mapError" x-text="mapError"></p>
<div class="map-layout"><div class="map-canvas" x-ref="generationCanvas" :aria-label="t('map_title')"></div><aside class="map-inspector">
<label><span x-text="t('map_selected')"></span><select :aria-label="t('map_selected')" :value="mapSelected" @change="mapSelect($event.target.value)"><template x-for="n in mapNodes" :key="n.id"><option :value="n.id" x-text="n.title"></option></template></select></label>
<template x-if="mapCurrent()"><div><h3 x-text="mapCurrent()?.title"></h3><p class="muted" x-text="mapCurrent()?.subtitle"></p><div class="actions"><button x-show="mapCurrent()?.iteration" @click="mapToggle()" x-text="mapExpanded[mapCurrent()?.rule]?t('map_collapse'):t('map_expand')"></button><button @click="mapEdit()" x-text="t('map_edit')"></button></div>
<label x-show="mapRows().length"><span x-text="t('map_pass')"></span><select :aria-label="t('map_pass')" x-model="mapRow"><option value="all" x-text="t('map_all')"></option><template x-for="(row,index) in mapRows()" :key="index"><option :value="String(index)" x-text="mapRowLabel(row,index)"></option></template></select></label>
<details class="map-inputs" open><summary x-text="t('map_inputs')"></summary><div class="map-input-content"><template x-if="mapRow==='all'"><div class="map-source-list"><p class="muted" x-show="!mapInputSources().length" x-text="t('map_no_sources')"></p><template x-for="source in mapInputSources()" :key="source.id"><div class="map-source-card"><div class="map-source-title"><span class="badge" x-text="(source.generated?t('generated_symbol')+' ':'')+source.type"></span><button class="map-value-link" type="button" :style="{color:mapColor(source.id)}" @click="mapExplore({rule:mapCurrent()?.rule,binding:source.id.startsWith('v:')?{kind:'variable',variable:source.id.slice(2)}:source.id.startsWith('o:')?{kind:'output',output:source.id.slice(2)}:{kind:'literal',value:source.id.slice(6)},title:source.name,value:source.id.startsWith('v:')?sampleNode(mapSnapshot.payload.variables.find(v=>v.id===source.id.slice(2)).node):source.name},$event)" x-text="source.name"></button><small x-show="source.count>1" x-text="source.count"></small></div><div class="map-source-addresses"><template x-for="address in source.addresses" :key="address"><code class="map-address"><span><span x-text="t('symbol_brace_open')"></span> </span><template x-for="(part,partIndex) in mapAddressParts(address)" :key="partIndex"><span><span x-show="part.dot" x-text="part.text"></span><button x-show="!part.dot" type="button" :style="{color:part.color}" @click="mapExploreAddressPart(address,partIndex,$event)" x-text="part.text"></button></span></template><span> <span x-text="t('symbol_brace_close')"></span></span></code></template></div><button class="text" x-show="source.target && source.target!==mapSelected" @click="mapSelect(source.target)" x-text="t('map_view_source')"></button></div></template><p class="muted" x-show="mapRows().length" x-text="t('map_choose_pass_values')"></p></div></template><div x-show="mapRow!=='all'"><p class="muted" x-show="!mapInputSections().length" x-text="t('map_no_inputs')"></p><template x-for="(section,sectionIndex) in mapInputSections()" :key="sectionIndex"><section class="map-input-section"><h4 x-text="section.title"></h4><template x-for="(input,inputIndex) in section.rows" :key="inputIndex"><div class="map-input-field"><div class="map-input-label"><span x-text="input.label"></span><small x-show="input.values.length>1" x-text="t('map_distinct_values',{count:input.values.length})"></small></div><template x-for="(value,valueIndex) in input.values" :key="valueIndex"><div class="map-input-value"><template x-for="(token,tokenIndex) in mapInputTokens(value)" :key="tokenIndex"><div class="map-input-token" :class="{'map-reference':token.kind}"><small x-show="token.path" x-text="token.path"></small><span class="map-reference-kind" x-show="token.kind" x-text="(token.generated?t('generated_symbol')+' ':'')+(token.kind||'')"></span><button type="button" class="map-value-link" :style="{color:mapColor(input.label+':'+token.path)}" @click="mapExplore({rule:mapCurrent()?.rule,row:Number(mapRow),binding:input.binding,title:input.label,value},$event)" x-text="token.text"></button></div></template></div></template></div></template></section></template></div></div></details>
2026-09-24 14:35:05 +03:00
<div class="map-issues"><template x-for="(issue,index) in mapIssues()" :key="index"><p class="validation-error" x-text="l(issue.message)"></p></template></div>
2026-10-07 15:30:31 +01:00
<h4 x-text="t(mapCurrent()?.manual?'map_manual_resources':'map_generated_resources',{count:mapResources().length})"></h4><p class="muted" x-show="!mapResources().length" x-text="mapSnapshot?.report.issues.length?t('map_unverified'):t('map_empty')"></p>
<template x-for="r in mapResources()" :key="r.id"><details class="map-resource"><summary><span class="badge" x-text="label(r.kind)"></span><strong class="map-resource-name"><template x-for="(part,index) in mapNameParts(r)" :key="index"><button type="button" :style="{color:part.color}" @click.stop.prevent="mapExplore(part.origin,$event)" x-text="part.text"></button></template></strong></summary><div class="map-resource-fields"><template x-for="(field,fieldIndex) in mapResourceFields(r)" :key="fieldIndex"><div class="map-input-field"><div class="map-input-label" x-text="field.label"></div><small class="map-field-hint" x-show="field.hint" x-text="field.hint"></small><template x-for="(token,tokenIndex) in mapInputTokens(field.value)" :key="tokenIndex"><div class="map-input-token" :class="{'map-reference':token.kind}"><small x-show="token.path" x-text="token.path"></small><span class="map-reference-kind" x-show="token.kind" x-text="(token.generated?t('generated_symbol')+' ':'')+(token.kind||'')"></span><button type="button" class="map-value-link" :style="{color:mapColor(r.block+':'+field.key+':'+token.path)}" @click="mapExploreToken(r,field,token,$event)" x-text="token.text"></button></div></template></div></template></div></details></template>
2026-09-24 14:35:05 +03:00
</div></template></aside></div>
2026-10-07 15:30:31 +01:00
<footer class="map-legend"><span class="map-legend-variable" x-text="t('map_variables')"></span><span class="map-legend-rule" x-text="t('map_generators')"></span><span class="map-legend-iteration" x-text="t('map_resource_lane')"></span><span x-text="t('map_readonly')"></span></footer>
<section class="map-probe" popover="manual" x-ref="mapProbe" :style="mapProbeStyle" role="region" :aria-label="t('map_explore')" @keydown.escape.stop.prevent="mapProbeClose()" @click.outside="if(mapProbe &amp;&amp; !$event.target.closest('.map-address,.map-value-link,.map-resource-name'))mapProbeClose()">
<template x-if="mapProbe"><div><div class="section-line"><h3 x-text="t('map_explore')"></h3><button type="button" @click="mapProbeClose()" x-text="t('done_e9b450')"></button></div>
<button type="button" x-show="mapProbeHistory.length" @click="mapProbeBack()" x-text="t('map_explore_back')"></button>
<p class="muted" x-text="mapProbe.title"></p><code class="map-address"><span><span x-text="t('symbol_brace_open')"></span> </span><template x-for="(part,index) in mapAddressParts(mapProbeAddress())" :key="index"><span :style="part.dot?{}:{color:part.color}" x-text="part.text"></span></template><span> <span x-text="t('symbol_brace_close')"></span></span></code>
2026-10-07 15:30:31 +01:00
<h4 x-text="t('map_source_chain')"></h4><ol class="map-probe-chain">
<template x-for="(parent,index) in mapProbeParents()" :key="'parent:'+index"><li><button type="button" @click="mapProbeFollow(parent,$event)" x-text="bindingAddress(parent.binding,0,mapSnapshot.payload.rules.find(r=>r.id===mapProbe.rule)?.iterations||[])"></button></li></template>
<template x-for="(stage,index) in mapProbeStages()" :key="'stage:'+index"><li><button type="button" :class="{'active':mapProbe.stage===index}" :aria-current="mapProbe.stage===index?'step':null" @click="mapProbe.stage=index" x-text="stage.path.length?stage.path[stage.path.length-1]:bindingAddress({...mapProbe.binding,path:[],prefix:'',suffix:''},0,mapSnapshot.payload.rules.find(r=>r.id===mapProbe.rule)?.iterations||[])"></button></li></template>
<li x-show="mapProbe.traces.length"><button type="button" :class="{'active':mapProbe.stage==null}" :aria-current="mapProbe.stage==null?'step':null" @click="mapProbe.stage=null" x-text="t('map_resolved_value')"></button></li></ol>
<div x-show="mapProbeOutputSources().length"><h4 x-text="t('map_source_fields')"></h4><div class="map-probe-fields"><template x-for="(source,index) in mapProbeOutputSources()" :key="index"><button type="button" @click="mapExplore(source,$event)" x-text="source.title"></button></template></div></div>
<h4 x-text="t('map_value_examples')"></h4><template x-for="(sample,index) in mapProbeValues()" :key="index"><div class="map-probe-example"><small x-text="sample.label"></small><p class="validation-error" x-show="sample.error" x-text="l(sample.error||'')"></p><template x-for="(token,tokenIndex) in mapInputTokens(sample.value)" :key="tokenIndex"><div class="map-input-token"><small x-text="token.path"></small><span class="badge" x-show="token.kind" x-text="token.kind"></span><strong x-text="token.text"></strong></div></template></div></template>
<p class="muted" x-show="mapProbe.traces.length>20" x-text="t('map_examples_limited')"></p><footer class="map-probe-actions" x-show="mapProbeTarget()"><button type="button" @click="mapSelect(mapProbeTarget());mapProbeClose()" x-text="t('map_view_source')"></button></footer></div></template>
</section>
2026-09-24 14:35:05 +03:00
</dialog>