1. Fix RU_TO_EN keyboard map in keyboardLayout.ts:
- ч was mapped to 'c' (wrong), now correctly 'x'
- с was mapped to 'v' (wrong), now correctly 'c'
- ю was mapped to '.' (wrong), now correctly ','
- Full rewrite with standard QWERTY/ЙЦУКЕН positional mapping
- Examples: dthcnfr→верстак, руддщ→hello, цщкдв→world all correct now
2. Root cause of search breaking after 3-4 chars:
Old map had ч:'c', с:'v' swapped. So dthcnfr → 'верчиак' (wrong).
Each character was mapped to wrong Cyrillic equivalent.
3. Add unit tests: keyboardLayout.test.js (39 tests, node-runner):
- EN→RU: dthcnfr, ghbdtn, ntcn
- RU→EN: руддщ, цщкдв, ышеш
- Unicode safety: Latin c (U+0063) ≠ Cyrillic с (U+0441)
- expandKeyboardVariants for mixed inputs
- Edge cases: empty, single char, mixed case, numbers
4. InternalLinkPicker type tabs → filters (not search modes):
- Store rawResults (all) + filtered results by activeType
- Switching type tab no longer clears query or triggers new search
- Just filters existing rawResults by selected type
- Shows 'Нет результатов для этого типа' when filtered empty
5. Both GlobalSearch and InternalLinkPicker use same expandKeyboardVariants()
All tests PASS, full build OK.
Replace broken ObjectPickerModal and manual modal with proper
InternalLinkPicker component:
- Search field with debounced SearchNodes API calls
- Type tabs: Дело, Заметка, Файл, Секрет (disabled)
- Results list showing title + path, keyboard navigation
- Inserts [Title](verstak://type/id) at cursor position
- No layout breakage — picker is a normal modal via position:fixed
- Escape/Cancel close picker cleanly
- bind:this on NoteEditorPanel → MarkdownEditor.insertText()
Also:
- MarkdownEditor: added public insertText() method + bind:this
- NoteEditorPanel: added bind:this on MarkdownEditor + public insertText()
- Removed manual modal, insertInternalLinkMarkdown(), document.querySelector