proto-sudoku-wc 0.0.689 → 0.0.691
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{index-4683daff.js → index-af8bf740.js} +15 -4
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/proto-sudoku-wc.cjs.js +2 -2
- package/dist/cjs/proto-sudoku.cjs.entry.js +352 -352
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/proto-sudoku/alert.js +2 -2
- package/dist/collection/components/proto-sudoku/alerts.js +3 -3
- package/dist/collection/components/proto-sudoku/alien.js +5 -5
- package/dist/collection/components/proto-sudoku/button.js +10 -10
- package/dist/collection/components/proto-sudoku/cell.js +20 -20
- package/dist/collection/components/proto-sudoku/eswat2-io.js +1 -1
- package/dist/collection/components/proto-sudoku/fingerprint.js +5 -5
- package/dist/collection/components/proto-sudoku/header.js +1 -1
- package/dist/collection/components/proto-sudoku/keys.js +10 -10
- package/dist/collection/components/proto-sudoku/proto-sudoku.js +62 -62
- package/dist/collection/components/proto-sudoku/spinner.js +5 -5
- package/dist/collection/components/proto-sudoku/sudoku-board.js +6 -6
- package/dist/collection/components/proto-sudoku/tool-bar.js +8 -8
- package/dist/collection/components/proto-sudoku/tw-label.js +1 -1
- package/dist/collection/utils/bag.js +23 -23
- package/dist/collection/utils/store.js +209 -209
- package/dist/collection/utils/tw.js +1 -1
- package/dist/esm/{index-3ccc3f4a.js → index-e105e4de.js} +15 -4
- package/dist/esm/loader.js +2 -2
- package/dist/esm/proto-sudoku-wc.js +3 -3
- package/dist/esm/proto-sudoku.entry.js +352 -352
- package/dist/proto-sudoku-wc/{p-4ab7e5a2.js → p-5c418b3c.js} +1 -1
- package/dist/proto-sudoku-wc/{p-4a14cce4.entry.js → p-c8bb72eb.entry.js} +1 -1
- package/dist/proto-sudoku-wc/proto-sudoku-wc.esm.js +1 -1
- package/dist/types/components/proto-sudoku/alert.d.ts +3 -3
- package/dist/types/components/proto-sudoku/button.d.ts +3 -3
- package/dist/types/components/proto-sudoku/cell.d.ts +4 -4
- package/dist/types/components/proto-sudoku/proto-sudoku.d.ts +4 -4
- package/dist/types/stencil-public-runtime.d.ts +8 -0
- package/dist/types/utils/bag.d.ts +10 -10
- package/dist/types/utils/store.d.ts +5 -5
- package/dist/types/utils/types.d.ts +33 -33
- package/package.json +5 -5
@@ -2,18 +2,18 @@
|
|
2
2
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
4
4
|
|
5
|
-
const index = require('./index-
|
5
|
+
const index = require('./index-af8bf740.js');
|
6
6
|
|
7
7
|
const Alien = props => {
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
const hex = props.hex || 'currentColor';
|
9
|
+
const klass = props.class;
|
10
|
+
const label = props.label || 'alien';
|
11
|
+
const size = props.size || 24;
|
12
|
+
return (index.h("svg", { class: klass, width: size, height: size, viewBox: "0 0 24 24", role: "img", "aria-label": "title" },
|
13
|
+
index.h("title", null, label),
|
14
|
+
index.h("g", { fill: hex },
|
15
|
+
index.h("path", { d: "M10.31 10.93C11.33 12.57 11.18 14.5 9.96 15.28C8.74 16.04 6.92 15.33\n 5.89 13.69C4.87 12.05 5.03 10.1 6.25 9.34C7.47 8.58 9.29 9.29 10.31\n 10.93M12 17.75C14 17.75 14.5 17 14.5 17C14.5 17 14 19 12 19C10 19 9.5\n 17.03 9.5 17C9.5 17 10 17.75 12 17.75M17.75 9.34C18.97 10.1 19.13 12.05\n 18.11 13.69C17.08 15.33 15.26 16.04 14.04 15.28C12.82 14.5 12.67 12.57\n 13.69 10.93C14.71 9.29 16.53 8.58 17.75 9.34M12 20C14.5 20 20 14.86 20\n 11C20 7.14 16.41 4 12 4C7.59 4 4 7.14 4 11C4 14.86 9.5 20 12 20M12 2C17.5\n 2 22 6.04 22 11C22 15.08 16.32 22 12 22C7.68 22 2 15.08 2 11C2 6.04 6.5 2\n 12 2Z" })),
|
16
|
+
index.h("path", { d: "M0 0h24v24H0z", fill: "none" })));
|
17
17
|
};
|
18
18
|
|
19
19
|
const KEY = 'proto-sudoku';
|
@@ -21,38 +21,38 @@ const DATA = `${KEY}::data`;
|
|
21
21
|
const INPUTS = `${KEY}::inputs`;
|
22
22
|
const PICK = `${KEY}::pick`;
|
23
23
|
const getForKey = (key) => {
|
24
|
-
|
25
|
-
|
24
|
+
const json = localStorage.getItem(key);
|
25
|
+
return json ? JSON.parse(json) : undefined;
|
26
26
|
};
|
27
27
|
const storeForKey = (key, value) => {
|
28
|
-
|
29
|
-
|
28
|
+
const json = JSON.stringify(value);
|
29
|
+
localStorage.setItem(key, json);
|
30
30
|
};
|
31
31
|
const bag = {
|
32
|
-
get: () => {
|
33
|
-
return getForKey(DATA);
|
34
|
-
},
|
35
|
-
store: value => {
|
36
|
-
storeForKey(DATA, value);
|
37
|
-
},
|
38
|
-
inputs: {
|
39
32
|
get: () => {
|
40
|
-
|
41
|
-
return [...line];
|
33
|
+
return getForKey(DATA);
|
42
34
|
},
|
43
|
-
store:
|
44
|
-
|
35
|
+
store: value => {
|
36
|
+
storeForKey(DATA, value);
|
45
37
|
},
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
38
|
+
inputs: {
|
39
|
+
get: () => {
|
40
|
+
const line = getForKey(INPUTS);
|
41
|
+
return [...line];
|
42
|
+
},
|
43
|
+
store: (value) => {
|
44
|
+
storeForKey(INPUTS, value.join(''));
|
45
|
+
},
|
51
46
|
},
|
52
|
-
|
53
|
-
|
47
|
+
pick: {
|
48
|
+
get: () => {
|
49
|
+
const pick = getForKey(PICK);
|
50
|
+
return pick !== null ? pick : undefined;
|
51
|
+
},
|
52
|
+
store: (value) => {
|
53
|
+
storeForKey(PICK, value >= 0 && value < 81 ? value : null);
|
54
|
+
},
|
54
55
|
},
|
55
|
-
},
|
56
56
|
};
|
57
57
|
|
58
58
|
const CHECK = 'Check ?';
|
@@ -798,452 +798,452 @@ const ky = createInstance();
|
|
798
798
|
|
799
799
|
// --------------------------------------------------------[ mutable store ]
|
800
800
|
const storeDef = {
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
801
|
+
list: [],
|
802
|
+
keys: [],
|
803
|
+
locs: [],
|
804
|
+
loading: false,
|
805
|
+
solved: false,
|
806
|
+
error: undefined,
|
807
|
+
pick: undefined,
|
808
|
+
data: undefined,
|
809
809
|
};
|
810
810
|
const { state } = createStore(storeDef);
|
811
811
|
// --------------------------------------------------------[ geometry ]
|
812
812
|
// NOTE: by using Sets here, we don't have to worry about clearing geometry...
|
813
813
|
const geometry = new Map([
|
814
|
-
|
815
|
-
|
816
|
-
|
814
|
+
['row', new Map()],
|
815
|
+
['column', new Map()],
|
816
|
+
['box', new Map()],
|
817
817
|
]);
|
818
818
|
const keyValues = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
819
819
|
const computeBox = (row, column) => {
|
820
|
-
|
821
|
-
|
822
|
-
}
|
823
|
-
else {
|
824
|
-
if (column < 6) {
|
825
|
-
return row < 3 ? 1 : row < 6 ? 4 : 7;
|
820
|
+
if (column < 3) {
|
821
|
+
return row < 3 ? 0 : row < 6 ? 3 : 6;
|
826
822
|
}
|
827
823
|
else {
|
828
|
-
|
824
|
+
if (column < 6) {
|
825
|
+
return row < 3 ? 1 : row < 6 ? 4 : 7;
|
826
|
+
}
|
827
|
+
else {
|
828
|
+
return row < 3 ? 2 : row < 6 ? 5 : 8;
|
829
|
+
}
|
829
830
|
}
|
830
|
-
}
|
831
831
|
};
|
832
832
|
const computeLocs = (index, row, column, box) => {
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
833
|
+
const data = new Map([
|
834
|
+
['row', row],
|
835
|
+
['column', column],
|
836
|
+
['box', box],
|
837
|
+
]);
|
838
|
+
const locs = new Set();
|
839
|
+
data.forEach((value, key) => {
|
840
|
+
geometry
|
841
|
+
.get(key)
|
842
|
+
.get(value)
|
843
|
+
.forEach(indx => {
|
844
|
+
indx !== index && locs.add(indx);
|
845
|
+
});
|
845
846
|
});
|
846
|
-
|
847
|
-
return Array.from(locs);
|
847
|
+
return Array.from(locs);
|
848
848
|
};
|
849
849
|
const computeKeys = locs => {
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
850
|
+
const { list } = state;
|
851
|
+
const found = new Set();
|
852
|
+
locs.map(indx => {
|
853
|
+
const { key } = list[indx];
|
854
|
+
if (key != '.') {
|
855
|
+
found.add(key);
|
856
|
+
}
|
857
|
+
});
|
858
|
+
const keys = keyValues.filter(key => !found.has(key));
|
859
|
+
return keys;
|
860
860
|
};
|
861
861
|
const updateGeometry = (index, row, column, box) => {
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
862
|
+
const data = new Map([
|
863
|
+
['row', row],
|
864
|
+
['column', column],
|
865
|
+
['box', box],
|
866
|
+
]);
|
867
|
+
data.forEach((value, key) => {
|
868
|
+
const map = geometry.get(key);
|
869
|
+
if (map.has(value)) {
|
870
|
+
// looking at the set specification, it should be sufficient to just call add
|
871
|
+
// https://tc39.es/ecma262/#sec-set.prototype.add
|
872
|
+
map.get(value).add(index);
|
873
|
+
}
|
874
|
+
else {
|
875
|
+
map.set(value, new Set([index]));
|
876
|
+
}
|
877
|
+
});
|
878
878
|
};
|
879
879
|
const updateFromInputs = list => {
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
880
|
+
const inputs = bag.inputs.get();
|
881
|
+
inputs.forEach((key, indx) => {
|
882
|
+
const cell = list[indx];
|
883
|
+
const { isClue } = cell;
|
884
|
+
if (!isClue) {
|
885
|
+
cell.key = key;
|
886
|
+
}
|
887
|
+
});
|
888
888
|
};
|
889
889
|
// --------------------------------------------------------[ process ]
|
890
890
|
const processData = (next) => {
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
891
|
+
if (next) {
|
892
|
+
const { puzzle, ref } = next;
|
893
|
+
const cells = puzzle ? [...puzzle] : [];
|
894
|
+
const line = ref ? atob(ref) : undefined; // decrypt the solution... [ base64 ]
|
895
|
+
const solution = line ? [...line] : [];
|
896
|
+
const list = cells.map((key, indx) => {
|
897
|
+
const value = solution[indx];
|
898
|
+
const isClue = key === value;
|
899
|
+
const row = Math.floor(indx / 9);
|
900
|
+
const column = indx % 9;
|
901
|
+
const box = computeBox(row, column);
|
902
|
+
updateGeometry(indx, row, column, box);
|
903
|
+
return { key, isClue, value, indx, row, column, box };
|
904
|
+
});
|
905
|
+
// NOTE: this only happens once on data change...
|
906
|
+
updateFromInputs(list);
|
907
|
+
state.data = next;
|
908
|
+
state.list = list;
|
909
|
+
}
|
910
|
+
else {
|
911
|
+
state.data = undefined;
|
912
|
+
state.list = [];
|
913
|
+
}
|
914
914
|
};
|
915
915
|
const processPick = (next) => {
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
916
|
+
if (next !== undefined && next.indx != state.pick) {
|
917
|
+
const { isClue, indx, row, column, box } = next;
|
918
|
+
const locs = computeLocs(indx, row, column, box);
|
919
|
+
const keys = isClue ? [] : computeKeys(locs);
|
920
|
+
state.pick = indx;
|
921
|
+
state.keys = keys;
|
922
|
+
state.locs = locs;
|
923
|
+
// NOTE: we could auto-pick if there's only one key...
|
924
|
+
// (keys.length === 1) && next.key = keys[0];
|
925
|
+
}
|
926
|
+
else {
|
927
|
+
state.pick = undefined;
|
928
|
+
state.keys = [];
|
929
|
+
state.locs = [];
|
930
|
+
}
|
931
|
+
savePick(state.pick);
|
932
932
|
};
|
933
933
|
// --------------------------------------------------------[ utils ]
|
934
934
|
let api = undefined;
|
935
935
|
const platformPrefix = {
|
936
|
-
|
937
|
-
|
936
|
+
netlify: '/.netlify/functions',
|
937
|
+
vercel: 'https://sudoku-rust-api.vercel.app/api',
|
938
938
|
};
|
939
939
|
const getPrefixFor = (platform) => {
|
940
|
-
|
941
|
-
|
942
|
-
|
940
|
+
const keys = Object.keys(platformPrefix);
|
941
|
+
const target = keys.includes(platform) ? platform : 'vercel';
|
942
|
+
return platformPrefix[target];
|
943
943
|
};
|
944
944
|
const initApi = (platform) => {
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
945
|
+
const prefix = getPrefixFor(platform);
|
946
|
+
api = ky.extend({
|
947
|
+
hooks: {
|
948
|
+
beforeRequest: [
|
949
|
+
request => {
|
950
|
+
request.headers.set('X-Requested-With', 'ky');
|
951
|
+
request.headers.set('X-Custom-Header', 'foobar');
|
952
|
+
},
|
953
|
+
],
|
952
954
|
},
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
timeout: 10000,
|
957
|
-
});
|
955
|
+
prefixUrl: prefix,
|
956
|
+
timeout: 10000,
|
957
|
+
});
|
958
958
|
};
|
959
959
|
const saveInputs = (inputs) => {
|
960
|
-
|
960
|
+
bag.inputs.store(inputs);
|
961
961
|
};
|
962
962
|
const savePick = (pick) => {
|
963
|
-
|
963
|
+
bag.pick.store(pick);
|
964
964
|
};
|
965
965
|
const clearStore = (loading = false) => {
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
966
|
+
state.list = [];
|
967
|
+
state.keys = [];
|
968
|
+
state.locs = [];
|
969
|
+
state.loading = loading;
|
970
|
+
state.solved = false;
|
971
|
+
state.error = undefined;
|
972
|
+
state.pick = undefined;
|
973
|
+
state.data = undefined;
|
974
974
|
};
|
975
975
|
const updateStore = (data, save = true) => {
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
976
|
+
const { puzzle, ref } = data;
|
977
|
+
if (save) {
|
978
|
+
bag.inputs.store([]);
|
979
|
+
bag.store(data);
|
980
|
+
}
|
981
|
+
processData({ puzzle, ref });
|
982
982
|
};
|
983
983
|
// --------------------------------------------------------[ actions ]
|
984
984
|
const initApp = (platform) => {
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
985
|
+
initApi(platform);
|
986
|
+
clearStore();
|
987
|
+
// this retrieves the last data we stored in the bag...
|
988
|
+
const data = bag.get();
|
989
|
+
const pick = bag.pick.get();
|
990
|
+
if (data) {
|
991
|
+
updateStore(data, false);
|
992
|
+
if (pick >= 0) {
|
993
|
+
const { list } = state;
|
994
|
+
const cell = list[pick];
|
995
|
+
processPick(cell);
|
996
|
+
}
|
996
997
|
}
|
997
|
-
}
|
998
998
|
};
|
999
999
|
const refresh = async () => {
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1000
|
+
clearStore(true);
|
1001
|
+
saveInputs([]);
|
1002
|
+
savePick(state.pick);
|
1003
|
+
try {
|
1004
|
+
// fetch a new puzzle from the api...
|
1005
|
+
const data = await api.get('puzzle').json();
|
1006
|
+
updateStore(data);
|
1007
|
+
}
|
1008
|
+
catch (err) {
|
1009
|
+
// handle error...
|
1010
|
+
const { message } = err;
|
1011
|
+
console.log('-- ', message);
|
1012
|
+
console.log(err);
|
1013
|
+
state.error = message;
|
1014
|
+
}
|
1015
|
+
finally {
|
1016
|
+
// always executed
|
1017
|
+
state.loading = false;
|
1018
|
+
}
|
1019
1019
|
};
|
1020
1020
|
const select = (cell) => {
|
1021
|
-
|
1021
|
+
processPick(cell);
|
1022
1022
|
};
|
1023
1023
|
const redraw = (list) => {
|
1024
|
-
|
1025
|
-
|
1024
|
+
state.list = [...list];
|
1025
|
+
list.length = 0;
|
1026
1026
|
};
|
1027
1027
|
const check = () => {
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1028
|
+
const { list } = state;
|
1029
|
+
const inputs = [];
|
1030
|
+
let errors = 0;
|
1031
|
+
let found = 0;
|
1032
|
+
let clues = 0;
|
1033
|
+
list.forEach(cell => {
|
1034
|
+
const { key, value, isClue } = cell;
|
1035
|
+
if (!isClue) {
|
1036
|
+
if (key !== '.') {
|
1037
|
+
if (key !== value) {
|
1038
|
+
errors = errors + 1;
|
1039
|
+
cell.key = '.';
|
1040
|
+
}
|
1041
|
+
else {
|
1042
|
+
found = found + 1;
|
1043
|
+
}
|
1044
|
+
}
|
1040
1045
|
}
|
1041
1046
|
else {
|
1042
|
-
|
1047
|
+
clues = clues + 1;
|
1043
1048
|
}
|
1044
|
-
|
1049
|
+
inputs.push(cell.key);
|
1050
|
+
});
|
1051
|
+
const total = clues + found;
|
1052
|
+
found ? saveInputs(inputs) : saveInputs([]);
|
1053
|
+
if (errors > 0) {
|
1054
|
+
redraw(list);
|
1045
1055
|
}
|
1046
1056
|
else {
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
});
|
1051
|
-
const total = clues + found;
|
1052
|
-
found ? saveInputs(inputs) : saveInputs([]);
|
1053
|
-
if (errors > 0) {
|
1054
|
-
redraw(list);
|
1055
|
-
}
|
1056
|
-
else {
|
1057
|
-
if (total === 81) {
|
1058
|
-
state.solved = true;
|
1057
|
+
if (total === 81) {
|
1058
|
+
state.solved = true;
|
1059
|
+
}
|
1059
1060
|
}
|
1060
|
-
}
|
1061
1061
|
};
|
1062
1062
|
const input = (key) => {
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1063
|
+
const { pick, list } = state;
|
1064
|
+
const cell = list[pick];
|
1065
|
+
cell.key = key;
|
1066
|
+
redraw(list);
|
1067
1067
|
};
|
1068
1068
|
const actions = {
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1069
|
+
initApp,
|
1070
|
+
refresh,
|
1071
|
+
select,
|
1072
|
+
check,
|
1073
|
+
input,
|
1074
1074
|
};
|
1075
1075
|
|
1076
1076
|
// WARNING: generated file...
|
1077
1077
|
const TW_VERSION = '3.3.5';
|
1078
1078
|
|
1079
1079
|
const tw = (...classes) => {
|
1080
|
-
|
1080
|
+
return classes.filter(Boolean).join(' ');
|
1081
1081
|
};
|
1082
1082
|
|
1083
1083
|
const Spinner = props => {
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1084
|
+
const hex = props.hex || 'currentColor';
|
1085
|
+
const klass = props.class || '';
|
1086
|
+
const label = props.label || 'loading...';
|
1087
|
+
const size = props.size || 24;
|
1088
|
+
return (index.h("svg", { class: tw(klass, 'animate-spin'), width: size, height: size, fill: "none", viewBox: "0 0 24 24", role: "img", "aria-label": "title" },
|
1089
|
+
index.h("title", null, label),
|
1090
|
+
index.h("g", null,
|
1091
|
+
index.h("circle", { class: "opacity-25", cx: "12", cy: "12", r: "10", stroke: hex, "stroke-width": "4" }),
|
1092
|
+
index.h("path", { class: "opacity-75", fill: hex, d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })),
|
1093
|
+
index.h("path", { d: "M0 0h24v24H0z", fill: "none" })));
|
1094
1094
|
};
|
1095
1095
|
|
1096
1096
|
const Alert = props => {
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1097
|
+
const { message, salute, spinner = false } = props;
|
1098
|
+
return (index.h("div", { class: "mt-5 flex h-24px flex-row items-center" },
|
1099
|
+
spinner ? index.h(Spinner, { class: "mr-2" }) : index.h(Alien, { class: "mr-2" }),
|
1100
|
+
salute ? index.h("label", { class: "mr-1 font-bold" },
|
1101
|
+
salute,
|
1102
|
+
":") : '',
|
1103
|
+
index.h("label", { class: "italic" }, message)));
|
1104
1104
|
};
|
1105
1105
|
|
1106
1106
|
const Alerts = _props => {
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1107
|
+
const { solved, loading, error } = state;
|
1108
|
+
const play = !loading && !error && !solved;
|
1109
|
+
return (index.h("div", { class: "flex flex-col" },
|
1110
|
+
play ? index.h(Alert, { message: "Welcome, are you ready to play?..." }) : '',
|
1111
|
+
loading ? index.h(Alert, { message: "Loading...", spinner: true }) : '',
|
1112
|
+
error ? index.h(Alert, { message: error, salute: "ERROR" }) : '',
|
1113
|
+
solved ? index.h(Alert, { message: "You solved the puzzle!!" }) : ''));
|
1114
1114
|
};
|
1115
1115
|
|
1116
1116
|
const Fingerprint = props => {
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1117
|
+
const hex = props.hex || 'currentColor';
|
1118
|
+
const klass = props.class;
|
1119
|
+
const label = props.label || 'fingerprint';
|
1120
|
+
const size = props.size || 24;
|
1121
|
+
return (index.h("svg", { class: klass, width: size, height: size, viewBox: "0 0 24 24", role: "img", "aria-label": "title" },
|
1122
|
+
index.h("title", null, label),
|
1123
|
+
index.h("g", { fill: hex },
|
1124
|
+
index.h("path", { d: "M17.81,4.47C17.73,4.47 17.65,4.45 17.58,4.41C15.66,3.42 14,3\n 12,3C10.03,3 8.15,3.47 6.44,4.41C6.2,4.54 5.9,4.45 5.76,4.21C5.63,3.97\n 5.72,3.66 5.96,3.53C7.82,2.5 9.86,2 12,2C14.14,2 16,2.47\n 18.04,3.5C18.29,3.65 18.38,3.95 18.25,4.19C18.16,4.37 18,4.47\n 17.81,4.47M3.5,9.72C3.4,9.72 3.3,9.69 3.21,9.63C3,9.47 2.93,9.16\n 3.09,8.93C4.08,7.53 5.34,6.43 6.84,5.66C10,4.04 14,4.03\n 17.15,5.65C18.65,6.42 19.91,7.5 20.9,8.9C21.06,9.12 21,9.44\n 20.78,9.6C20.55,9.76 20.24,9.71 20.08,9.5C19.18,8.22 18.04,7.23\n 16.69,6.54C13.82,5.07 10.15,5.07 7.29,6.55C5.93,7.25 4.79,8.25\n 3.89,9.5C3.81,9.65 3.66,9.72 3.5,9.72M9.75,21.79C9.62,21.79 9.5,21.74\n 9.4,21.64C8.53,20.77 8.06,20.21 7.39,19C6.7,17.77 6.34,16.27\n 6.34,14.66C6.34,11.69 8.88,9.27 12,9.27C15.12,9.27 17.66,11.69\n 17.66,14.66A0.5,0.5 0 0,1 17.16,15.16A0.5,0.5 0 0,1\n 16.66,14.66C16.66,12.24 14.57,10.27 12,10.27C9.43,10.27 7.34,12.24\n 7.34,14.66C7.34,16.1 7.66,17.43 8.27,18.5C8.91,19.66 9.35,20.15\n 10.12,20.93C10.31,21.13 10.31,21.44 10.12,21.64C10,21.74 9.88,21.79\n 9.75,21.79M16.92,19.94C15.73,19.94 14.68,19.64 13.82,19.05C12.33,18.04\n 11.44,16.4 11.44,14.66A0.5,0.5 0 0,1 11.94,14.16A0.5,0.5 0 0,1\n 12.44,14.66C12.44,16.07 13.16,17.4 14.38,18.22C15.09,18.7 15.92,18.93\n 16.92,18.93C17.16,18.93 17.56,18.9 17.96,18.83C18.23,18.78 18.5,18.96\n 18.54,19.24C18.59,19.5 18.41,19.77 18.13,19.82C17.56,19.93 17.06,19.94\n 16.92,19.94M14.91,22C14.87,22 14.82,22 14.78,22C13.19,21.54 12.15,20.95\n 11.06,19.88C9.66,18.5 8.89,16.64 8.89,14.66C8.89,13.04 10.27,11.72\n 11.97,11.72C13.67,11.72 15.05,13.04 15.05,14.66C15.05,15.73 16,16.6\n 17.13,16.6C18.28,16.6 19.21,15.73 19.21,14.66C19.21,10.89 15.96,7.83\n 11.96,7.83C9.12,7.83 6.5,9.41 5.35,11.86C4.96,12.67 4.76,13.62\n 4.76,14.66C4.76,15.44 4.83,16.67 5.43,18.27C5.53,18.53 5.4,18.82\n 5.14,18.91C4.88,19 4.59,18.87 4.5,18.62C4,17.31 3.77,16\n 3.77,14.66C3.77,13.46 4,12.37 4.45,11.42C5.78,8.63 8.73,6.82\n 11.96,6.82C16.5,6.82 20.21,10.33 20.21,14.65C20.21,16.27 18.83,17.59\n 17.13,17.59C15.43,17.59 14.05,16.27 14.05,14.65C14.05,13.58 13.12,12.71\n 11.97,12.71C10.82,12.71 9.89,13.58 9.89,14.65C9.89,16.36 10.55,17.96\n 11.76,19.16C12.71,20.1 13.62,20.62 15.03,21C15.3,21.08 15.45,21.36\n 15.38,21.62C15.33,21.85 15.12,22 14.91,22Z" })),
|
1125
|
+
index.h("path", { d: "M0 0h24v24H0z", fill: "none" })));
|
1126
1126
|
};
|
1127
1127
|
|
1128
1128
|
const url = 'https://eswat2.dev';
|
1129
1129
|
const who = 'eswat2';
|
1130
1130
|
const Eswat2Io = _props => {
|
1131
|
-
|
1132
|
-
|
1131
|
+
return (index.h("a", { class: "absolute right-0 top-0 text-clrs-gray hover:text-clrs-navy", href: url, "aria-label": who, target: "blank", title: who },
|
1132
|
+
index.h(Fingerprint, { label: who })));
|
1133
1133
|
};
|
1134
1134
|
|
1135
1135
|
const Header = (_props, children) => {
|
1136
|
-
|
1136
|
+
return (index.h("h1", { class: tw('text-center uppercase text-clrs-red', 'mb-11 ml-0 mr-0 mt-11', 'text-6xl font-thin') }, children));
|
1137
1137
|
};
|
1138
1138
|
|
1139
1139
|
const Button = props => {
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1140
|
+
const { label, callback, matched = false } = props;
|
1141
|
+
return (index.h("button", { class: tw('rounded-md border border-solid border-clrs-slate4 font-bold', label === CHECK
|
1142
|
+
? 'mr-2 bg-clrs-yellow px-3 py-2 text-clrs-navy'
|
1143
|
+
: label === NEW_PUZZLE
|
1144
|
+
? 'mr-2 bg-clrs-navy px-3 py-2 text-white'
|
1145
|
+
: label === DELETE
|
1146
|
+
? 'mr-1 bg-clrs-red px-2 py-1 text-white'
|
1147
|
+
: matched
|
1148
|
+
? 'mr-1 bg-clrs-slate4 px-2 py-1 text-white'
|
1149
|
+
: 'mr-1 bg-gray-50 px-2 py-1 text-clrs-navy'), onClick: callback }, label));
|
1150
1150
|
};
|
1151
1151
|
|
1152
1152
|
const Keys = _props => {
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1153
|
+
const { keys, list, pick, solved } = state;
|
1154
|
+
const genHandler = (key) => {
|
1155
|
+
return () => {
|
1156
|
+
actions.input(key);
|
1157
|
+
};
|
1157
1158
|
};
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
})));
|
1159
|
+
const values = solved ? [] : keys;
|
1160
|
+
const cell = pick != undefined ? list[pick] : undefined;
|
1161
|
+
return (index.h("div", { class: "mt-2 flex flex-row justify-end" },
|
1162
|
+
!solved && cell && !cell.isClue && cell.key != '.' ? (index.h(Button, { label: DELETE, callback: genHandler('.') })) : (''),
|
1163
|
+
values.map((key) => {
|
1164
|
+
return (index.h(Button, { label: key, callback: genHandler(key), matched: cell.key === key }));
|
1165
|
+
})));
|
1166
1166
|
};
|
1167
1167
|
|
1168
1168
|
// NOTE: building indx mapping for the border highlighting...
|
1169
1169
|
const borderRight = [
|
1170
|
-
|
1170
|
+
2, 5, 11, 14, 20, 23, 29, 32, 38, 41, 47, 50, 56, 59, 65, 68, 74, 77,
|
1171
1171
|
];
|
1172
1172
|
const borderLeft = borderRight.map(key => key + 1);
|
1173
1173
|
const borderBottom = [
|
1174
|
-
|
1174
|
+
18, 19, 20, 21, 22, 23, 24, 25, 26, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
1175
1175
|
];
|
1176
1176
|
const borderTop = borderBottom.map(key => key + 9);
|
1177
1177
|
// Functional components return JSX...
|
1178
1178
|
const Cell = props => {
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1179
|
+
const { cell, focus, selected, solved } = props;
|
1180
|
+
const { key, isClue, indx } = cell;
|
1181
|
+
const clue = key != '.' ? key : '';
|
1182
|
+
const genHandler = (cell, solved) => {
|
1183
|
+
return () => {
|
1184
|
+
if (!solved) {
|
1185
|
+
actions.select(cell);
|
1186
|
+
}
|
1187
|
+
};
|
1187
1188
|
};
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
: 'border-clrs-gray'), onClick: genHandler(cell, solved) }, clue));
|
1189
|
+
return (index.h("label", { class: tw(`cell-${indx}`, borderRight.includes(indx) ? 'border-xbr-clrs-navy' : '', borderLeft.includes(indx) ? 'border-xbl-clrs-navy' : '', borderBottom.includes(indx) ? 'border-xbb-clrs-navy' : '', borderTop.includes(indx) ? 'border-xbt-clrs-navy' : '', 'h-8 w-8 border border-solid text-center leading-8', selected
|
1190
|
+
? 'border-clrs-red bg-clrs-red-a50 text-clrs-red'
|
1191
|
+
: focus
|
1192
|
+
? 'border-clrs-gray bg-clrs-green-a50 font-bold'
|
1193
|
+
: isClue
|
1194
|
+
? 'border-clrs-gray bg-clrs-silver'
|
1195
|
+
: clue !== ''
|
1196
|
+
? 'border-clrs-gray text-clrs-red'
|
1197
|
+
: 'border-clrs-gray'), onClick: genHandler(cell, solved) }, clue));
|
1198
1198
|
};
|
1199
1199
|
|
1200
1200
|
const SudokuBoard = _props => {
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1201
|
+
const { list, pick, locs, solved } = state;
|
1202
|
+
return (index.h("div", { class: tw('flex flex-row flex-wrap', 'border border-solid border-clrs-navy', 'h-76p5 w-76p5 text-lg') }, list.map((cell, index$1) => {
|
1203
|
+
const selected = solved ? false : index$1 === pick;
|
1204
|
+
const focus = solved ? false : locs.includes(index$1);
|
1205
|
+
return (index.h(Cell, { cell: cell, focus: focus, selected: selected, solved: solved }));
|
1206
|
+
})));
|
1207
1207
|
};
|
1208
1208
|
|
1209
1209
|
const TwLabel = _props => {
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1210
|
+
return (index.h("label", { class: "ml-auto align-top text-xs italic text-clrs-slate4" },
|
1211
|
+
"Tailwind ",
|
1212
|
+
TW_VERSION));
|
1213
1213
|
};
|
1214
1214
|
|
1215
1215
|
const handleRefresh = (actions) => {
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1216
|
+
return () => {
|
1217
|
+
actions.refresh();
|
1218
|
+
};
|
1219
1219
|
};
|
1220
1220
|
const handleCheck = (actions) => {
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1221
|
+
return () => {
|
1222
|
+
actions.check();
|
1223
|
+
};
|
1224
1224
|
};
|
1225
1225
|
const ToolBar = _props => {
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1226
|
+
const { list, solved } = state;
|
1227
|
+
return (index.h("div", { class: "flex flex-row" },
|
1228
|
+
index.h(Button, { label: NEW_PUZZLE, callback: handleRefresh(actions) }),
|
1229
|
+
list.length === 81 && !solved ? (index.h(Button, { label: CHECK, callback: handleCheck(actions) })) : (''),
|
1230
|
+
index.h(TwLabel, null)));
|
1231
1231
|
};
|
1232
1232
|
|
1233
1233
|
const protoSudokuCss = "*,::before,::after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scroll-snap-strictness:proximity;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;}::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scroll-snap-strictness:proximity;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;}.ds1-main{margin:1.5rem;display:flex;flex-direction:column;font-family:ui-sans-serif,\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n 'Helvetica Neue',\n Arial,\n 'Noto Sans',\n sans-serif,\n 'Apple Color Emoji',\n 'Segoe UI Emoji',\n 'Segoe UI Symbol',\n 'Noto Color Emoji';color:var(--clrs-navy, #001f3f);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.absolute{position:absolute}.relative{position:relative}.right-0{right:0px}.top-0{top:0px}.mb-11{margin-bottom:2.75rem}.ml-0{margin-left:0px}.ml-auto{margin-left:auto}.mr-0{margin-right:0px}.mr-1{margin-right:0.25rem}.mr-2{margin-right:0.5rem}.mt-11{margin-top:2.75rem}.mt-2{margin-top:0.5rem}.mt-5{margin-top:1.25rem}.flex{display:flex}.h-24px{height:24px}.h-76p5{height:19.125rem}.h-8{height:2rem}.w-76p5{width:19.125rem}.w-8{width:2rem}.max-w-min{max-width:-moz-min-content;max-width:min-content}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-end{justify-content:flex-end}.rounded-md{border-radius:0.375rem}.border{border-width:1px}.border-solid{border-style:solid}.border-clrs-gray{border-color:var(--clrs-gray, #aaaaaa)}.border-clrs-navy{border-color:var(--clrs-navy, #001f3f)}.border-clrs-red{border-color:var(--clrs-red, #ff4136)}.border-clrs-slate4{border-color:var(--clrs-slate4, #4e5964)}.bg-clrs-green-a50{background-color:var(--clrs-green-a50, #2ecc4050)}.bg-clrs-navy{background-color:var(--clrs-navy, #001f3f)}.bg-clrs-red{background-color:var(--clrs-red, #ff4136)}.bg-clrs-red-a50{background-color:var(--clrs-red-a50, #ff413650)}.bg-clrs-silver{background-color:var(--clrs-silver, #dddddd)}.bg-clrs-slate4{background-color:var(--clrs-slate4, #4e5964)}.bg-clrs-yellow{background-color:var(--clrs-yellow, #ffdc00)}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251 / var(--tw-bg-opacity))}.p-0{padding:0px}.p-0\\.5{padding:0.125rem}.px-2{padding-left:0.5rem;padding-right:0.5rem}.px-3{padding-left:0.75rem;padding-right:0.75rem}.py-1{padding-top:0.25rem;padding-bottom:0.25rem}.py-2{padding-top:0.5rem;padding-bottom:0.5rem}.text-center{text-align:center}.align-top{vertical-align:top}.text-6xl{font-size:3.75rem;line-height:1}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-xs{font-size:0.75rem;line-height:1rem}.font-bold{font-weight:700}.font-thin{font-weight:100}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-8{line-height:2rem}.text-clrs-gray{color:var(--clrs-gray, #aaaaaa)}.text-clrs-navy{color:var(--clrs-navy, #001f3f)}.text-clrs-red{color:var(--clrs-red, #ff4136)}.text-clrs-slate4{color:var(--clrs-slate4, #4e5964)}.text-white{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity))}.opacity-25{opacity:0.25}.opacity-75{opacity:0.75}.shadow{--tw-shadow:0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),\n 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.border-xbb-clrs-navy{border-bottom:1px solid var(--clrs-navy, #001f3f) !important}.border-xbt-clrs-navy{border-top:1px solid var(--clrs-navy, #001f3f) !important}.border-xbl-clrs-navy{border-left:1px solid var(--clrs-navy, #001f3f) !important}.border-xbr-clrs-navy{border-right:1px solid var(--clrs-navy, #001f3f) !important}.hover\\:text-clrs-navy:hover{color:var(--clrs-navy, #001f3f)}";
|
1234
1234
|
|
1235
1235
|
const ProtoSudoku = class {
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1236
|
+
constructor(hostRef) {
|
1237
|
+
index.registerInstance(this, hostRef);
|
1238
|
+
this.tag = 'proto-sudoku';
|
1239
|
+
this.platform = 'vercel';
|
1240
|
+
}
|
1241
|
+
componentDidLoad() {
|
1242
|
+
actions.initApp(this.platform);
|
1243
|
+
}
|
1244
|
+
render() {
|
1245
|
+
return (index.h("div", { id: "app", class: "ds1-main relative max-w-min p-0.5" }, index.h(Eswat2Io, null), index.h(Header, null, "Sudoku"), index.h(SudokuBoard, null), index.h(Keys, null), index.h("hr", { class: "ml-0 mr-0" }), index.h(ToolBar, null), index.h(Alerts, null)));
|
1246
|
+
}
|
1247
1247
|
};
|
1248
1248
|
ProtoSudoku.style = protoSudokuCss;
|
1249
1249
|
|