@@ -14,87 +14,110 @@
14 export let inputComponents: string[] = [];
14 export let inputComponents: string[] = [];
15 export let unfocusSymbol: Function = () => {};
15 export let unfocusSymbol: Function = () => {};
17− let modes: string[] = [];
17+ let mode: string = null;
18+ let subMode: string = null;
18 let modeDef: ModeDef = undefined;
19 let modeDef: ModeDef = undefined;
20+ let unselectedSubModesExist: boolean = false;
19− let subModeDefs: ModeDefs = MODE_DEFS;
21+ let modeDefs: ModeDefs = MODE_DEFS;
22+ let plausibleModeDefs: { name: string, def: ModeDef }[] = [];
21 function showGeonSelector() {
24 function showGeonSelector() {
22− if (!symbolQuery.components.length && modes.length == 0) {
25+ if (!symbolQuery.components.length && !mode) {
23− modes = ['geon'];
26+ mode = 'geon';
27 $: symbolQuery.components, showGeonSelector();
31 $: symbolQuery.components, showGeonSelector();
29− function pushMode(mode: string) {
33+ function pushMode(newMode: string) {
30− if (modeDef?.modes) {
34+ const subModes = modeDef?.modes;
31− modes = [...modes, mode];
35+ if (subModes || subMode) {
33− modes = [...modes.slice(0, -1), mode];
38+ mode = newMode;
37 function popMode() {
43 function popMode() {
38− if (modes.length) {
44+ if (mode || subMode) {
39− if (modeDef?.modes) {
45+ mode = null;
40− modes = modes.slice(0, -1);
46+ subMode = null;
42− modes = modes.slice(0, -2);
45 unfocusSymbol();
48 unfocusSymbol();
53+ let modeResolved = false;
55+ while (!modeResolved && count < 5) {
50− modeDef = undefined;
56+ modeDef = undefined;
51− subModeDefs = MODE_DEFS;
57+ modeDefs = MODE_DEFS;
52− for (let mode of modes) {
58+ if (mode) {
53− if (modeDef && modeDef.modes) {
59+ modeDef = MODE_DEFS[mode];
54− subModeDefs = modeDef.modes;
60+ }
61+ unselectedSubModesExist = !!modeDef?.modes;
62+ if (unselectedSubModesExist) {
63+ modeDefs = modeDef.modes;
65+ if (modeDefs[subMode]) {
66+ modeDef = modeDefs[subMode];
68+ console.error(`Unknown subMode: ${subMode} of ${mode} in defs:`, modeDefs);
56− if (subModeDefs[mode]) {
73+ unselectedSubModesExist = !!modeDef?.modes;
57− modeDef = subModeDefs[mode];
74+ if (!isDefPlausible(modeDef) && mode !== 'geon') {
59− console.error(`Unknown mode: ${mode} of ${modes} in defs:`, subModeDefs);
81+ plausibleModeDefs = getPlausibleModeDefs(modeDefs);
82+ if (unselectedSubModesExist) {
83+ subMode = plausibleModeDefs[0].name;
89+ if (count >= 5 && !modeResolved) {
90+ console.error("sigil input mode resulotion failed");
62−
93+ inputComponents = [];
63− if (modeDef && modeDef.modes) {
64− subModeDefs = modeDef.modes;
67− if (modeDef?.parts?.length && !modeDef.modes) {
94+ if (modeDef?.parts?.length) {
68 inputComponents = modeDef.parts;
95 inputComponents = modeDef.parts;
69 if (!$searchSettings.allowFictionalSigils) {
96 if (!$searchSettings.allowFictionalSigils) {
70 inputComponents = symbolQuery.filterPlausibleParts(inputComponents);
97 inputComponents = symbolQuery.filterPlausibleParts(inputComponents);
73− inputComponents = [];
77− $: plausibleModes = Object.entries(subModeDefs).map(([modeName, def]) => {
102+ function isDefPlausible(def: ModeDef): boolean {
103+ if (!def) return true;
78 const deepParts = getDeepParts(def);
104 const deepParts = getDeepParts(def);
79− const plausible = $searchSettings.allowFictionalSigils || symbolQuery.arePartsPlausible(deepParts);
105+ return $searchSettings.allowFictionalSigils || symbolQuery.arePartsPlausible(deepParts);
80− if (!plausible && modeName !== 'geon') return null;
106+ }
81− const parts = filterPartsByGeon(def.displayParts || def.parts, symbolQuery.geon);
82− return { parts, modeName };
83− }).filter(mode => mode !== null);
85− $: {
108+ function getPlausibleModeDefs(modeDefs: ModeDefs) {
86− const currentMode = modes.slice(-1)[0];
109+ return Object.entries(modeDefs).map(([modeName, def]) => {
87− if (currentMode != 'geon') {
110+ const plausible = isDefPlausible(def);
88− if (plausibleModes.length === 0) {
111+ if (!plausible && modeName !== 'geon') return null;
89− popMode();
112+ const parts = filterPartsByGeon(def.displayParts || def.parts, symbolQuery.geon);
90− } else if (plausibleModes.length >= 1) {
113+ return {
91− const leafMode = modeDef && !(modeDef.modes);
114+ name: modeName,
92− const plausibleModeNames = plausibleModes.map(({ modeName }) => modeName);
115+ def: {
93− if ((modes.length == 1 && modeDef.modes) || (leafMode && !plausibleModeNames.includes(currentMode))) {
116+ ...def,
94− pushMode(plausibleModes[0].modeName);
117+ parts,
97− }
120+ }).filter(mode => mode !== null);
100 function clear() {
123 function clear() {
@@ -116,17 +139,23 @@
118<div class="mx-auto flex justify-center xs:items-center xs:flex-col">
141<div class="mx-auto flex justify-center xs:items-center xs:flex-col">
119− <SymbolInputNavButtons onDone={popMode} onClear={clear} />
142+ <SymbolInputNavButtons onDone={popMode} onClear={clear} hideClearButton={symbolQuery.components.length == 0} />
120 <div class="max-w-[15rem] h-full grid grid-cols-custom gap-1 justify-center xs:max-w-[8rem]">
143 <div class="max-w-[15rem] h-full grid grid-cols-custom gap-1 justify-center xs:max-w-[8rem]">
121− {#if modes[0] === 'geon'}
144+ {#if mode === 'geon'}
122 <GeonSelector bind:symbolQuery {popMode} />
145 <GeonSelector bind:symbolQuery {popMode} />
124− {#each plausibleModes as { modeName, parts }}
147+ {#each plausibleModeDefs as { name, def: { parts } }}
125− <SymbolInputModeSelectorButton components={parts} focused={modes.slice(-1)[0] === modeName}
148+ <SymbolInputModeSelectorButton components={parts} focused={mode === name || subMode === name}
126− on:click={() => pushMode(modeName)}
149+ on:click={() => pushMode(name)}
154+ <!-- <p class="break-all w-24">
157+ <p class="break-all w-24">