initial commit
This commit is contained in:
commit
0b0e08bcb0
49
index.html
Normal file
49
index.html
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Kcalculator</title>
|
||||||
|
<link href="style.css" type="text/css" rel="stylesheet">
|
||||||
|
|
||||||
|
<script src="jst.js"></script>
|
||||||
|
<script src="utils.js"></script>
|
||||||
|
<script src="data.js"></script>
|
||||||
|
<script defer src="main.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>Kcalculator</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<datalist id="food-list"></datalist>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div id="food-search-container">
|
||||||
|
<input type="search" list="food-list" id="food-search" name="food-search" placeholder="Lebensmittel">
|
||||||
|
|
||||||
|
<div id="search-entries">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="food-menu">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="summary">
|
||||||
|
<span class="summary-name">Gesamt</span>
|
||||||
|
|
||||||
|
<a class="summary-delete-icon"><span class="material-icons">delete</span></a>
|
||||||
|
<div class="summary-amount-container">
|
||||||
|
<div class="summary-kcal">123</div>
|
||||||
|
<span class="summary-kcal-unit">kcal</span><span class="summary-kcal-unit-sep">/</span><input class="summary-amount" type="number" pattern="[0-9]+"><span class="summary-unit">g</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
76
jst.js
Normal file
76
jst.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
const JST = {
|
||||||
|
|
||||||
|
_cachedTemplates: {},
|
||||||
|
|
||||||
|
_fetchTemplate: (name) => {
|
||||||
|
if (JST._cachedTemplates[name] !== undefined) {
|
||||||
|
return new Promise(resolve => resolve(JST._cachedTemplates[name]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch(`/templates/${name}.html`).then(resp => resp.text()).then(resp => {
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.innerHTML = resp;
|
||||||
|
const template = div.querySelector("template");
|
||||||
|
JST._cachedTemplates[name] = template;
|
||||||
|
return template;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// load returns a Promise for the template node
|
||||||
|
load: (templateName, visitedTemplates) => {
|
||||||
|
visitedTemplates = visitedTemplates ?? [];
|
||||||
|
|
||||||
|
const visited = visitedTemplates.includes(templateName);
|
||||||
|
visitedTemplates.push(templateName);
|
||||||
|
if (visited) {
|
||||||
|
const errorMsg = document.createElement("span");
|
||||||
|
errorMsg.textContent = `recursive templates: ${visitedTemplates.join(" → ")}`;
|
||||||
|
errorMsg.style.color = "red";
|
||||||
|
return new Promise(resolve => resolve(errorMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
return JST._fetchTemplate(templateName).then(template => {
|
||||||
|
const c = template.content.cloneNode(true);
|
||||||
|
JST.init(c, visitedTemplates);
|
||||||
|
return c;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// replaceElement replaces the given element with the template node
|
||||||
|
replaceElement: async (templateName, element) => {
|
||||||
|
await JST._replaceElement(templateName, element, []);
|
||||||
|
},
|
||||||
|
|
||||||
|
_replaceElement: async (templateName, element, visitedTemplates) => {
|
||||||
|
element.textContent = "";
|
||||||
|
await JST.load(templateName, visitedTemplates).then(node => element.replaceWith(node))
|
||||||
|
},
|
||||||
|
|
||||||
|
// replaceChildren removes all children in element and adds the template node
|
||||||
|
replaceChildren: async (templateName, element) => {
|
||||||
|
element = element ?? document.querySelector("main");
|
||||||
|
|
||||||
|
const node = await JST.load(templateName);
|
||||||
|
|
||||||
|
while (element.hasChildNodes()) {
|
||||||
|
element.removeChild(element.firstChild);
|
||||||
|
}
|
||||||
|
element.appendChild(node);
|
||||||
|
},
|
||||||
|
|
||||||
|
// append appends the template node to elements childrens
|
||||||
|
append: async (templateName, element) => {
|
||||||
|
element = element ?? document.querySelector("main");
|
||||||
|
const node = await JST.load(templateName);
|
||||||
|
element.appendChild(node);
|
||||||
|
},
|
||||||
|
|
||||||
|
init: (element, visitedTemplates) => {
|
||||||
|
element = element ?? document;
|
||||||
|
visitedTemplates = visitedTemplates ?? [];
|
||||||
|
element.querySelectorAll("jst-template").forEach(element => JST._replaceElement(element.textContent, element, visitedTemplates));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", () => JST.init());
|
129
main.js
Normal file
129
main.js
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
const foodSearch = document.querySelector("#food-search");
|
||||||
|
const searchEntries = document.querySelector("#search-entries");
|
||||||
|
const foodMenu = document.querySelector("#food-menu");
|
||||||
|
const summary = document.querySelector("#summary");
|
||||||
|
const summaryKcal = document.querySelector("#summary .summary-kcal");
|
||||||
|
|
||||||
|
updateSummary();
|
||||||
|
initFoodList();
|
||||||
|
foodSearch.addEventListener("input", onFoodSearched);
|
||||||
|
if (foodSearch.value != "") onFoodSearched();
|
||||||
|
|
||||||
|
function initFoodList() {
|
||||||
|
const dataList = document.querySelector("#food-list");
|
||||||
|
|
||||||
|
for (let food of foods) {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.setAttribute("value", food.name);
|
||||||
|
dataList.appendChild(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFoodSearched() {
|
||||||
|
const food = foodSearch.value;
|
||||||
|
const foodLC = food.toLowerCase();
|
||||||
|
|
||||||
|
if (food == "") {
|
||||||
|
createSearchEntries([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const foodsCopy = structuredClone(foods);
|
||||||
|
|
||||||
|
foodsCopy.sort((a, b) => {
|
||||||
|
const aNameLC = a.name.toLowerCase();
|
||||||
|
const bNameLC = b.name.toLowerCase();
|
||||||
|
|
||||||
|
const ainc = aNameLC.includes(foodLC);
|
||||||
|
const binc = bNameLC.includes(foodLC);
|
||||||
|
if (ainc && binc) {
|
||||||
|
return 0;
|
||||||
|
} else if (ainc) {
|
||||||
|
return -1;
|
||||||
|
} else if (binc) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const distA = levenshtein(foodLC, aNameLC);
|
||||||
|
const distB = levenshtein(foodLC, bNameLC);
|
||||||
|
return distA - distB;
|
||||||
|
})
|
||||||
|
|
||||||
|
const maxDist = 10;
|
||||||
|
let maxAmount = 10;
|
||||||
|
let amount = 0;
|
||||||
|
for (let f of foodsCopy) {
|
||||||
|
const fnameLC = f.name.toLowerCase();
|
||||||
|
if (fnameLC.includes(foodLC)) {
|
||||||
|
amount++;
|
||||||
|
maxAmount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const dist = levenshtein(foodLC, fnameLC);
|
||||||
|
if (dist >= maxDist) break;
|
||||||
|
amount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
createSearchEntries(foodsCopy.slice(0, Math.min(amount, maxAmount, 30)));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createSearchEntries(foods) {
|
||||||
|
const nodes = [];
|
||||||
|
for (let food of foods) {
|
||||||
|
const node = await JST.load("search-entry");
|
||||||
|
node.querySelector(".search-entry-name").textContent = food.name;
|
||||||
|
node.querySelector(".search-entry").addEventListener("click", () => addMenuItem(food));
|
||||||
|
nodes.push(node);
|
||||||
|
}
|
||||||
|
searchEntries.replaceChildren(...nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addMenuItem(food) {
|
||||||
|
const alreadyAddedMenuItem = document.querySelector(`#food-menu .menu-item[data-food-name="${food.name}"]`);
|
||||||
|
if (alreadyAddedMenuItem !== null) {
|
||||||
|
alreadyAddedMenuItem.style.animation = "highlight 0.25s linear";
|
||||||
|
setTimeout(() => alreadyAddedMenuItem.style.animation = "", 250);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const node = await JST.load("menu-item");
|
||||||
|
const nodeRoot = node.querySelector(".menu-item");
|
||||||
|
const itemAmount = node.querySelector(".menu-item-amount");
|
||||||
|
const kcalAmount = node.querySelector(".menu-item-kcal-for-amount");
|
||||||
|
nodeRoot.setAttribute("data-food-name", food.name);
|
||||||
|
node.querySelector(".menu-item-name").textContent = food.name;
|
||||||
|
node.querySelector(".menu-item-kcal").textContent = `${food.kcal} kcal/100${food.unit}`;
|
||||||
|
node.querySelector(".menu-item-unit").textContent = food.unit;
|
||||||
|
node.querySelector(".delete-menu-item").addEventListener("click", () => {
|
||||||
|
foodMenu.removeChild(nodeRoot);
|
||||||
|
updateSummary();
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateKcalAmount = () => {
|
||||||
|
if (!/[0-9]+/.test(itemAmount.value)) {
|
||||||
|
console.log("no match");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const amount = parseInt(itemAmount.value);
|
||||||
|
kcalAmount.textContent = parseInt(Math.round(food.kcal / 100 * amount));
|
||||||
|
updateSummary();
|
||||||
|
}
|
||||||
|
|
||||||
|
itemAmount.value = 100;
|
||||||
|
itemAmount.addEventListener("input", updateKcalAmount);
|
||||||
|
|
||||||
|
updateKcalAmount();
|
||||||
|
foodMenu.appendChild(node);
|
||||||
|
updateSummary();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSummary() {
|
||||||
|
let sum = 0;
|
||||||
|
|
||||||
|
for (let menuItem of foodMenu.querySelectorAll(".menu-item")) {
|
||||||
|
sum += parseInt(menuItem.querySelector(".menu-item-kcal-for-amount").textContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
summaryKcal.textContent = sum;
|
||||||
|
summary.style.display = sum > 0 ? "block" : "none";
|
||||||
|
}
|
223
style.css
Normal file
223
style.css
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Material Icons';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url("/icons.ttf");
|
||||||
|
src: local('Material Icons'),
|
||||||
|
local('MaterialIcons-Regular'),
|
||||||
|
url("/icons.ttf") format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
transform: translateY(0.1em);
|
||||||
|
font-family: 'Material Icons';
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 1em; /* Preferred icon size */
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 1;
|
||||||
|
text-transform: none;
|
||||||
|
letter-spacing: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
white-space: nowrap;
|
||||||
|
direction: ltr;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
/* Support for all WebKit browsers. */
|
||||||
|
|
||||||
|
/* Support for Safari and Chrome. */
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
|
||||||
|
/* Support for Firefox. */
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
|
/* Support for IE. */
|
||||||
|
font-feature-settings: 'liga';
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
min-height: 100vh;
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
line-height: 5em;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #add8e6;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
#food-search-container {
|
||||||
|
margin: 1em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#food-search {
|
||||||
|
margin-bottom: 0.25em;
|
||||||
|
border: 1px solid darkgray;
|
||||||
|
border-radius: 0.15em;
|
||||||
|
padding: 0.25em;
|
||||||
|
outline: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 20rem;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-entries {
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.25em;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-entry {
|
||||||
|
background-color: #eee;
|
||||||
|
border: 1px solid darkgray;
|
||||||
|
padding: 0.15em;
|
||||||
|
border-radius: 0.15em;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.25s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-entry:hover {
|
||||||
|
background-color: #ddd;
|
||||||
|
transition: all 0.25s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#food-menu,
|
||||||
|
#summary {
|
||||||
|
width: 60em;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
padding: 0.5em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item:not(:last-child) {
|
||||||
|
border-bottom: 1px solid lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-menu-item,
|
||||||
|
.summary-delete-icon {
|
||||||
|
display: block;
|
||||||
|
float: right;
|
||||||
|
color: #cc3d3d;
|
||||||
|
width: 1.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.25s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-menu-item:hover,
|
||||||
|
.delete-menu-item:focus {
|
||||||
|
scale: 1.5;
|
||||||
|
transition: all 0.25s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-kcal {
|
||||||
|
color: darkgray;
|
||||||
|
font-size: 0.65em;
|
||||||
|
transform: translateY(-0.15em);
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-amount-container,
|
||||||
|
.summary-amount-container {
|
||||||
|
float: right;
|
||||||
|
margin-right: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-amount,
|
||||||
|
.summary-amount {
|
||||||
|
font-size: 1rem;
|
||||||
|
border: 1px solid lightgray;
|
||||||
|
box-sizing: border-box;
|
||||||
|
outline: 0;
|
||||||
|
width: 3em;
|
||||||
|
text-align: right;
|
||||||
|
margin-left: 0.3em;
|
||||||
|
border-radius: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-unit,
|
||||||
|
.summary-unit {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 0.2em;
|
||||||
|
min-width: 1.5em;
|
||||||
|
transform: translateX(-0.1em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-amount:hover,
|
||||||
|
.menu-item-amount:focus {
|
||||||
|
border: 1px solid darkgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-amount:invalid {
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Chrome, Safari, Edge, Opera */
|
||||||
|
input::-webkit-outer-spin-button,
|
||||||
|
input::-webkit-inner-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Firefox */
|
||||||
|
input[type=number] {
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes highlight {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-kcal-unit,
|
||||||
|
.summary-kcal-unit {
|
||||||
|
margin-right: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-kcal-for-amount,
|
||||||
|
.menu-item-kcal-unit {
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summary {
|
||||||
|
border-top: 1px solid black;
|
||||||
|
padding: 0.5em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-amount,
|
||||||
|
.summary-unit,
|
||||||
|
.summary-delete-icon,
|
||||||
|
.summary-kcal-unit-sep {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-kcal,
|
||||||
|
.summary-kcal-unit,
|
||||||
|
.summary-name {
|
||||||
|
display: inline;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
13
templates/menu-item.html
Normal file
13
templates/menu-item.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div class="menu-item">
|
||||||
|
<span class="menu-item-name"></span>
|
||||||
|
<span class="menu-item-kcal"></span>
|
||||||
|
|
||||||
|
<a class="delete-menu-item"><span class="material-icons">delete</span></a>
|
||||||
|
|
||||||
|
<div class="menu-item-amount-container">
|
||||||
|
<span class="menu-item-kcal-for-amount">123</span>
|
||||||
|
<span class="menu-item-kcal-unit">kcal</span>/<input class="menu-item-amount" type="number" pattern="[0-9]+"><span class="menu-item-unit"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
5
templates/search-entry.html
Normal file
5
templates/search-entry.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<div class="search-entry">
|
||||||
|
<span class="search-entry-name"></span>
|
||||||
|
</div>
|
||||||
|
</template>
|
96
utils.js
Normal file
96
utils.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
function levenshtein(s, t) {
|
||||||
|
if (s === t) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var n = s.length, m = t.length;
|
||||||
|
if (n === 0 || m === 0) {
|
||||||
|
return n + m;
|
||||||
|
}
|
||||||
|
var x = 0, y, a, b, c, d, g, h;
|
||||||
|
var p = new Uint16Array(n);
|
||||||
|
var u = new Uint32Array(n);
|
||||||
|
for (y = 0; y < n;) {
|
||||||
|
u[y] = s.charCodeAt(y);
|
||||||
|
p[y] = ++y;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; (x + 3) < m; x += 4) {
|
||||||
|
var e1 = t.charCodeAt(x);
|
||||||
|
var e2 = t.charCodeAt(x + 1);
|
||||||
|
var e3 = t.charCodeAt(x + 2);
|
||||||
|
var e4 = t.charCodeAt(x + 3);
|
||||||
|
c = x;
|
||||||
|
b = x + 1;
|
||||||
|
d = x + 2;
|
||||||
|
g = x + 3;
|
||||||
|
h = x + 4;
|
||||||
|
for (y = 0; y < n; y++) {
|
||||||
|
a = p[y];
|
||||||
|
if (a < c || b < c) {
|
||||||
|
c = (a > b ? b + 1 : a + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (e1 !== u[y]) {
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c < b || d < b) {
|
||||||
|
b = (c > d ? d + 1 : c + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (e2 !== u[y]) {
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b < d || g < d) {
|
||||||
|
d = (b > g ? g + 1 : b + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (e3 !== u[y]) {
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d < g || h < g) {
|
||||||
|
g = (d > h ? h + 1 : d + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (e4 !== u[y]) {
|
||||||
|
g++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p[y] = h = g;
|
||||||
|
g = d;
|
||||||
|
d = b;
|
||||||
|
b = c;
|
||||||
|
c = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; x < m;) {
|
||||||
|
var e = t.charCodeAt(x);
|
||||||
|
c = x;
|
||||||
|
d = ++x;
|
||||||
|
for (y = 0; y < n; y++) {
|
||||||
|
a = p[y];
|
||||||
|
if (a < c || d < c) {
|
||||||
|
d = (a > d ? d + 1 : a + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (e !== u[y]) {
|
||||||
|
d = c + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
d = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p[y] = d;
|
||||||
|
c = a;
|
||||||
|
}
|
||||||
|
h = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user