diff --git a/package-lock.json b/package-lock.json index 9822cb629e38a5af4ca787050e0f9991e1e0136c..b27b35d195dff37546bccb6b01fed520938f9474 100755 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "hasInstallScript": true, "dependencies": { - "g1lib": "^3.5.5" + "g1lib": "^3.5.7" }, "devDependencies": { "@fortawesome/fontawesome-free": "^5.15.2", @@ -1004,9 +1004,9 @@ } }, "node_modules/g1lib": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.5.tgz", - "integrity": "sha512-3JnCfMOc2ynTgCv4MsoeEAT9gGkwYMehFULOx6kMNY0tlPu1ytMI40UtcFPjCMUxnAXhBixtUTgbf8u1UxlgMA==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.7.tgz", + "integrity": "sha512-gxCMQvn4wl8huRwUiW2zc2Bvul2ch+7VB2dHcbJkME1TLivpx/azljA3OGnhhfMJG93mGZvHoBxCFnqOqmqb1A==", "funding": { "url": "https://git.duniter.org/libs/g1lib.js" } @@ -4456,9 +4456,9 @@ "dev": true }, "g1lib": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.5.tgz", - "integrity": "sha512-3JnCfMOc2ynTgCv4MsoeEAT9gGkwYMehFULOx6kMNY0tlPu1ytMI40UtcFPjCMUxnAXhBixtUTgbf8u1UxlgMA==" + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.7.tgz", + "integrity": "sha512-gxCMQvn4wl8huRwUiW2zc2Bvul2ch+7VB2dHcbJkME1TLivpx/azljA3OGnhhfMJG93mGZvHoBxCFnqOqmqb1A==" }, "get-caller-file": { "version": "2.0.5", diff --git a/package.json b/package.json index faa6ae25e21131d114bef832a4c81a7418ceb682..cf2ebb526943a7670b10204f73cb6432af714296 100755 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "build:stylus": "stylus --include-css src/stylus/_all.styl -o generated/public/style.css" }, "dependencies": { - "g1lib": "^3.5.5" + "g1lib": "^3.5.7" }, "devDependencies": { "@fortawesome/fontawesome-free": "^5.15.2", diff --git a/src/js/logic/dico.mjs b/src/js/logic/dico.mjs index 90705ca68b0ab9014a8967b0a34c4c7f8223d7f2..bce5fce64487037287e4d334464885bf21e71156 100755 --- a/src/js/logic/dico.mjs +++ b/src/js/logic/dico.mjs @@ -2,6 +2,7 @@ import {subscribe} from "./workerManager.mjs"; import getCombiPerSec from "./speedBench.mjs"; import {Dictionary} from "g1lib/browser/dictionary.mjs"; import staticPreview from "./staticPreview.mjs"; +import {cacheScale} from "./search.mjs"; let currentDico; let lastData; @@ -52,6 +53,8 @@ export function getActualData(withSpeed = true) { accent:so.accent.value<0?undefined:so.accent.value, lowerCase:so.caps.value<0?undefined:so.caps.value, leetSpeak:0, + save:so.save.value, + cacheMax:cacheScale[so.cacheMax.value], }, previewIndex: (window.browseIndex || 0), }; diff --git a/src/js/logic/saveResume.mjs b/src/js/logic/saveResume.mjs new file mode 100644 index 0000000000000000000000000000000000000000..b451e583637fefc7ede3e6aae6febfbf1a2d5f3b --- /dev/null +++ b/src/js/logic/saveResume.mjs @@ -0,0 +1,29 @@ +import {subscribe} from "./workerManager.mjs"; +import {swapKeyValue,sleep} from "./utils.mjs"; + +export const saveScale = []; +saveScale[0]=0; +saveScale[1]=24*60*60; +saveScale[2]=2*24*60*60; +saveScale[3]=7*24*60*60; +export const revertSaveScale = swapKeyValue(saveScale); + +const MIN_COMPUTE_TIME_FOR_SAVE = 3600; + +export let saveMode=0 + +async function init(){ + await sleep(1); + subscribe('smartPreview', updateSaveMode); + window.searchOptions.save.listen('saveResume',manualUpdate); +} +init(); +function manualUpdate(mode){ + if(mode>=0) saveMode = saveScale[mode]; +} +function updateSaveMode(data){ + const smartDico = JSON.parse(data.dico); + if(smartDico.config.save<0) saveMode = smartDico.estimateDuration >= MIN_COMPUTE_TIME_FOR_SAVE ? saveScale[2] : 0; + else saveMode = saveScale[smartDico.config.save]; + window.searchOptions.save.setComputed(revertSaveScale[saveMode]); +} diff --git a/src/js/logic/search.mjs b/src/js/logic/search.mjs index 0ada2e7d409eb21c443b831d7b63fddfbfdf91a6..d71ea42d3d0859857f973a449094aeeabedc94b7 100644 --- a/src/js/logic/search.mjs +++ b/src/js/logic/search.mjs @@ -10,7 +10,9 @@ export let departTime; export let endTime; export let found; export let cacheActive = true; -export const CACHE_MAX = 1_000_000; +export const DEFAULT_CACHE_MAX = 1_000_000; +export const cacheScale = []; + const globalCache = {}; export function duplicateCount() { @@ -53,6 +55,7 @@ export function stopSearch() { function updateProgress(data) { if (data.bench) return; tested++; + if(found) endSearchTest(); if (data.publicKey === pubKey) { endSearchTest(data); } else { @@ -61,9 +64,9 @@ function updateProgress(data) { if (!globalCache[cacheKey]) globalCache[cacheKey] = {}; globalCache[cacheKey][data.index] = true; } - if (Object.keys(globalCache).length > CACHE_MAX) cacheActive = false; + if (Object.keys(globalCache).length > getDico().config.cacheMax) cacheActive = false; } - if (tested >= getDico().length) endSearchTest() + if (tested >= getDico().length) endSearchTest(); } function endSearchTest(somethingFound = undefined) { diff --git a/src/js/logic/utils.mjs b/src/js/logic/utils.mjs new file mode 100644 index 0000000000000000000000000000000000000000..8139f094085a459723bd451e3244f2db6d5f6401 --- /dev/null +++ b/src/js/logic/utils.mjs @@ -0,0 +1,10 @@ +export function swapKeyValue(object) { + const result = {}; + for (const key in object) { + result[object[key]] = key; + } + return result; +} +export async function sleep(ms) { + return new Promise((resolve, reject) => setTimeout(resolve, ms)); +} diff --git a/src/js/logic/workerManager.mjs b/src/js/logic/workerManager.mjs index 64462bf30e464c9265b65d5502cfa19abe13b861..2a16ab87a734606ee4daad1f1f1a88cacbeadaff 100644 --- a/src/js/logic/workerManager.mjs +++ b/src/js/logic/workerManager.mjs @@ -1,3 +1,5 @@ +import {sleep} from "./utils.mjs"; + const workers = []; const MAX_ALLOWED_IN_QUEUE = 5; const subscriptionList = {}; @@ -56,6 +58,3 @@ export function unSubscribe(action,registeredFunc){ const index = subscriptionList[action].indexOf(registeredFunc); subscriptionList[action].splice(index, 1); } -async function sleep(ms) { - return new Promise((resolve, reject) => setTimeout(resolve, ms)); -} diff --git a/src/js/ux/1_pubKey.mjs b/src/js/ux/1_pubKey.mjs index eec4f61ec3c612e0025f0473ab4e780cc307c042..443e956425399243b8a7060e7b8f24eca44cbdff 100644 --- a/src/js/ux/1_pubKey.mjs +++ b/src/js/ux/1_pubKey.mjs @@ -14,8 +14,10 @@ export default function focus_1_pubKey(){ export let pubKey; export function updatePubKey(){ const pubKeyInputNode = document.getElementById('pubKey'); - if(location.hash.match(/pubkey=/i) !== null) - pubKeyInputNode.value = location.hash.split('=')[1]; + if(location.hash.match(/pubkey=/i) !== null){ + pubKeyInputNode.value = location.hash.split('=')[1]; + return location.hash = location.hash.split('=')[0]; + } pubKey = pubKeyInputNode.value; const nextBtn = document.querySelector('.step_1_pubKey a.button'); const errorArea = document.querySelector('.step_1_pubKey .warning'); diff --git a/src/js/ux/2_inputSecrets.mjs b/src/js/ux/2_inputSecrets.mjs index 97d63b57818e55d42ddcf52ac71c2060e058cd50..8aba54a506e7109e5c0ae2c385713cf7e2b20dff 100755 --- a/src/js/ux/2_inputSecrets.mjs +++ b/src/js/ux/2_inputSecrets.mjs @@ -4,6 +4,9 @@ import {timeUnitStrings} from "pretty-ms"; import {sendToWorker, subscribe} from "../logic/workerManager.mjs"; import {getActualData} from "../logic/dico.mjs"; import RangeOption from "./rangeOption.mjs"; +import {cacheScale, DEFAULT_CACHE_MAX} from "../logic/search.mjs"; +import {saveScale} from "../logic/saveResume.mjs"; +import {swapKeyValue} from "../logic/utils.mjs"; const regexDesc = { '-1': 'Syntaxe : auto-sélection', @@ -28,6 +31,36 @@ const capsDesc = { '1': `Majuscules : classiques`, '2': `Majuscules : fluctuantes`, } + + +const saveDesc = { + '-1': `Reprendre : auto-sélection`, + '0': `Reprendre : désactivé par sécurité`, + '1': `Reprendre : possible pendant 24h`, + '2': `Reprendre : possible pendant 48h`, + '3': `Reprendre : possible pendant 7j`, +} +cacheScale[-1]=DEFAULT_CACHE_MAX; +cacheScale[0]=0; +cacheScale[1]=10_000; +cacheScale[2]=100_000; +cacheScale[3]=1_000_000; +cacheScale[4]=10_000_000; +cacheScale[5]=100_000_000; +cacheScale[6]=1_000_000_000; +const revertCacheScale = swapKeyValue(cacheScale.filter((v,i)=> i>=0 )); + +const cacheMaxDesc = { + '-1': `Cache : auto-sélection`, + '0': `Cache : désactivé`, + '1': `Cache : ${cacheScale[1].toLocaleString('fr-FR')}`, + '2': `Cache : ${cacheScale[2].toLocaleString('fr-FR')}`, + '3': `Cache : ${cacheScale[3].toLocaleString('fr-FR')}`, + '4': `Cache : ${cacheScale[4].toLocaleString('fr-FR')}`, + '5': `Cache : ${cacheScale[5].toLocaleString('fr-FR')}`, + '6': `Cache : ${cacheScale[6].toLocaleString('fr-FR')}`, +// '6': `Cache : ${new Intl.NumberFormat().format(cacheScale[6])}`, +} export function init() { const secretsInputNode = document.getElementById('secrets'); secretsInputNode.addEventListener('keyup', askPreview); @@ -38,7 +71,8 @@ export function init() { 'mirror': new RangeOption('mirror', -1, mirrorDesc, askPreview), 'accent': new RangeOption('accent', -1, accentDesc, askPreview), 'caps': new RangeOption('caps', -1, capsDesc, askPreview), - //TODO: AutoSave & resume + 'save': new RangeOption('save', -1, saveDesc, askPreview), + 'cacheMax': new RangeOption('cacheMax', -1, cacheMaxDesc, askPreview), }; subscribe('fastPreview',updateFastPreviewDisplay); subscribe('smartPreview', updateSmartPreviewDisplay); @@ -93,6 +127,7 @@ function updateSmartPreviewDisplay(data){ so.accent.setComputed(sdc.accent || 0); so.caps.setComputed(sdc.lowerCase || 0); so.accent.setComputed(sdc.accent || 0); + so.cacheMax.setComputed(revertCacheScale[sdc.cacheMax]); try{window.displayBrowsePreview();}catch (e){} } diff --git a/src/js/ux/3_inProgress.mjs b/src/js/ux/3_inProgress.mjs index e954879fa36a8f6e0b8c171c33b4e727ced374dd..294624d4cb4b306d9678555443e85c281aeca80c 100644 --- a/src/js/ux/3_inProgress.mjs +++ b/src/js/ux/3_inProgress.mjs @@ -8,7 +8,7 @@ export default function init(){ setInterval(showProgress,200); } init(); -const progressColor = getComputedStyle(document.getElementById('startSearch')).color; +const progressColor = getComputedStyle(document.querySelector('.success h3')).color; const progressBar = document.getElementById('progress_bar'); const bgColor = getComputedStyle(progressBar).backgroundColor; const timing = []; diff --git a/src/js/ux/4_result.mjs b/src/js/ux/4_result.mjs index 97d8157048862a525561a36be5b2a0a105b09f4e..381f5aba9a297a976aa60d2f021496e558e96551 100644 --- a/src/js/ux/4_result.mjs +++ b/src/js/ux/4_result.mjs @@ -21,8 +21,13 @@ export default function showResult(){ document.getElementById('resSpent').innerHTML = timeFormat(timeSpent); document.getElementById('resSpeed').innerHTML = (1000*tested/timeSpent).toFixed(1); const duplicates = duplicateCount(); - document.getElementById('resDuplicate').innerHTML = duplicates; - document.getElementById('resDupRatio').innerHTML = (100 * duplicates / tested).toPrecision(3); + if (duplicates) { + document.getElementById('resDup').classList.remove('hidden'); + document.getElementById('resDuplicate').innerHTML = duplicates; + document.getElementById('resDupRatio').innerHTML = (100 * duplicates / tested).toPrecision(3); + } else { + document.getElementById('resDup').classList.add('hidden'); + } } function timeFormat(milliseconds) { return prettyMilliseconds(Math.trunc(milliseconds / 1000)*1000, { diff --git a/src/js/ux/nav.mjs b/src/js/ux/nav.mjs index 2be619d147c57aa76bee7947ec84dc6a18ccbcd4..4fbc8fd0da9475e1e56fad03a3a03755f0a573a5 100644 --- a/src/js/ux/nav.mjs +++ b/src/js/ux/nav.mjs @@ -16,6 +16,14 @@ const setFocus = [ ()=>0, showResult, ]; + +const pages = [ + 'page_0_home', + 'page_1_pubKey', + 'page_2_inputSecrets', + 'page_3_inProgress', + 'page_4_result', +]; init(); // internal navigation @@ -25,8 +33,8 @@ function showPageFromHash(){ const pageNumber = parseInt(window.location.hash.split('_')[1]); if(isNaN(pageNumber)) return window.location = '#page_0_home'; if(pageNumber<2 || pubKey){ - document.body.className = window.location.hash.slice(1) - } else window.location = '#page_0_home'; + document.body.className = pages[pageNumber] + } else return window.location = '#page_0_home'; setFocus[pageNumber](); if(pageNumber!==3) stopSearch(); } catch (e){ diff --git a/src/js/ux/rangeOption.mjs b/src/js/ux/rangeOption.mjs index fc6e4d18c2bc48886aa15f3a550940d105f6010f..78839f73128b3eea5ad14da57ea2f18974c5b092 100644 --- a/src/js/ux/rangeOption.mjs +++ b/src/js/ux/rangeOption.mjs @@ -78,6 +78,7 @@ export default function RangeOption(fieldId, initialValue, descArray, uiListener Object.keys(self.listeners).forEach(k=>self.listeners[k](mode)); } checkBoxNode.addEventListener('change', ()=>uiChanged(hiddenNode.value = checkBoxNode.checked?-1:(rangeNode.value || 0))); + rangeNode.addEventListener('input', ()=>descLabel.innerHTML = descArray[rangeNode.value]); rangeNode.addEventListener('change', ()=>uiChanged(hiddenNode.value = rangeNode.value)); if(typeof uiListener !== 'undefined') self.listen('default',uiListener) if(initialValue) self.setUserChoice(initialValue); diff --git a/src/pages/fragments/browse.ejs b/src/pages/fragments/browse.ejs index 9ef4f7b5ba7e929c6b126c313e0211e16dc9b237..d3dc5c6803fca449e685f5ecbb8f57103f0e8118 100644 --- a/src/pages/fragments/browse.ejs +++ b/src/pages/fragments/browse.ejs @@ -135,11 +135,14 @@ return (index + staticDico.length) % staticDico.length; } function updateBrowseIndex(e){ - if(e && e.key === "ArrowUp") return browseUp(); - if(e && e.key === "ArrowDown") return browseDown(); + if(e && e.key && e.key === "ArrowUp") return browseUp(); + if(e && e.key && e.key === "ArrowDown") return browseDown(); + if(e && e.deltaY && e.deltaY >0) return browseDown(); + if(e && e.deltaY && e.deltaY <0) return browseUp(); window.browseIndex = parseInt(document.querySelector('.currentIndex input').value); displayBrowsePreview(); } document.querySelector('.currentIndex input').addEventListener('keyup',updateBrowseIndex); + document.querySelector('.browse tbody').addEventListener('wheel',updateBrowseIndex); </script> </section> diff --git a/src/pages/steps/1_pubKey.ejs b/src/pages/steps/1_pubKey.ejs index 3c8d497612402afc6d61378bc4a3faecc44e1d43..e8b5c7680e376b3c14258835e7ba2050881099f7 100644 --- a/src/pages/steps/1_pubKey.ejs +++ b/src/pages/steps/1_pubKey.ejs @@ -11,4 +11,13 @@ <a href="#page_2_inputSecrets" class="button"> Suivant <i class="fas fa-long-arrow-alt-right"></i> </a> + <div class="notice"> + Vous êtes juste là pour tester, sans compte à récupérer ? + Voici une clef publique valide utilisable comme exemple : + <a href="#page_1_pubKey=BCHERdQbh3HhyDSoqHdXTyGQZLZvDA9b6DBABcMAPdDW">BCHERdQbh3HhyDSoqHdXTyGQZLZvDA9b6DBABcMAPdDW</a> + <!-- + idSec : "Ça me serait pas venu à l'idée !" + mdp : " MOI NON PLUS " + --> + </div> </section> diff --git a/src/pages/steps/2_inputSecrets.ejs b/src/pages/steps/2_inputSecrets.ejs index 1bbd0a28e8caf47db254b7fd8c1b3e4c7d997b1c..e3306449b03633bc931adc641d8c5606e5773b87 100755 --- a/src/pages/steps/2_inputSecrets.ejs +++ b/src/pages/steps/2_inputSecrets.ejs @@ -15,11 +15,8 @@ <a id="startSearch" class="button" href="#page_3_inProgress">Valider</a> </div> <div class="inputArea"> - <textarea id="secrets"> -un exemple -un autre -le 3ème - </textarea> + <textarea id="secrets">ça (|ne )me serait pas venu[e]{0,1} à l'idée ! + moi non plus[ ]</textarea> <%- include('../fragments/browse.ejs'); %> </div> <div class="tabs"> diff --git a/src/pages/steps/4_result.ejs b/src/pages/steps/4_result.ejs index 341b7f73a95121def848a9773cd78e8489860df3..3593442ae1f9978b48903f654bf035468b32b9c0 100644 --- a/src/pages/steps/4_result.ejs +++ b/src/pages/steps/4_result.ejs @@ -18,7 +18,7 @@ </div> <div class="stats"> <div><span id="resTested"></span> combinaisons testées en <span id="resSpent"></span> (soit <span id="resSpeed"></span>/s)</div> - <div><span id="resDuplicate"></span> doublons évités soit <span id="resDupRatio"></span>% des combinaisons testées</div> + <div id="resDup"><span id="resDuplicate"></span> doublons évités soit <span id="resDupRatio"></span>% des combinaisons testées</div> </div> <div class="success"> <div class="gift notice">