|
|
|
|
|
|
|
|
createForm(); |
|
|
createForm(); |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
$('#allNotesDiv').on('click', 'button', function() { |
|
|
|
|
|
console.log("Add") |
|
|
|
|
|
|
|
|
$('#allNotesDiv').on('click', 'button', async function() { |
|
|
|
|
|
// |
|
|
|
|
|
console.log("Save") |
|
|
console.log(this) |
|
|
console.log(this) |
|
|
|
|
|
// |
|
|
|
|
|
|
|
|
let buttonId = (this.id).split("_")[1]; |
|
|
let buttonId = (this.id).split("_")[1]; |
|
|
let type = (this.id).split("_")[0]; |
|
|
let type = (this.id).split("_")[0]; |
|
|
if (type == 'saveNoteButton'){ |
|
|
if (type == 'saveNoteButton'){ |
|
|
saveNoteObject(buttonId); |
|
|
|
|
|
|
|
|
await saveNoteObject(buttonId); |
|
|
} else if (type == 'editNoteButton'){ |
|
|
} else if (type == 'editNoteButton'){ |
|
|
saveNoteObject(buttonId, true); |
|
|
|
|
|
|
|
|
await saveNoteObject(buttonId, true); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// |
|
|
console.log(buttonId) |
|
|
console.log(buttonId) |
|
|
|
|
|
// |
|
|
|
|
|
|
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
$('#noteStorage').on('click', 'button', function() { |
|
|
|
|
|
|
|
|
$('#noteStorage').on('click', 'button', async function() { |
|
|
|
|
|
// |
|
|
console.log("Delete") |
|
|
console.log("Delete") |
|
|
console.log(this) |
|
|
console.log(this) |
|
|
|
|
|
// |
|
|
|
|
|
|
|
|
let buttonId = (this.id).split("_")[1]; |
|
|
let buttonId = (this.id).split("_")[1]; |
|
|
|
|
|
|
|
|
|
|
|
// |
|
|
console.log(buttonId) |
|
|
console.log(buttonId) |
|
|
removeBrowserItem(buttonId); |
|
|
|
|
|
|
|
|
// |
|
|
|
|
|
await removeBrowserItem(buttonId); |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
//$('.browserElement').on('click', 'div', function() { |
|
|
|
|
|
// console.log("Load"); |
|
|
|
|
|
// console.log(this); |
|
|
|
|
|
// let divId = (this.id).split("_")[1]; |
|
|
|
|
|
// console.log(divId); |
|
|
|
|
|
// getSavedNote(divId); |
|
|
|
|
|
//}) |
|
|
|
|
|
|
|
|
|
|
|
$("#refreshButton").on('click', function() { |
|
|
|
|
|
|
|
|
$("#refreshButton").on('click', async function() { |
|
|
|
|
|
// |
|
|
console.log("Refresh") |
|
|
console.log("Refresh") |
|
|
updateNoteBrowser(); |
|
|
|
|
|
|
|
|
// |
|
|
|
|
|
createLoadingSign(id="", append="noteStorage"); |
|
|
|
|
|
enableLoadingSign(id=""); |
|
|
|
|
|
await sleep(2000); |
|
|
|
|
|
disableLoadingSign(id=""); |
|
|
|
|
|
await refreshBrowser(); |
|
|
}) |
|
|
}) |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createForm(){ |
|
|
function createForm(){ |
|
|
|
|
|
|
|
|
id++; |
|
|
id++; |
|
|
|
|
|
// |
|
|
console.log("createForm() "+id) |
|
|
console.log("createForm() "+id) |
|
|
let wrapper = document.createElement("div") |
|
|
|
|
|
wrapper.setAttribute('id', "note"+id) |
|
|
|
|
|
let inputsWrapper = document.createElement("div") |
|
|
|
|
|
|
|
|
// |
|
|
|
|
|
let wrapper = document.createElement("div"); |
|
|
|
|
|
wrapper.setAttribute('id', "note"+id); |
|
|
|
|
|
wrapper.style.margin = '2.5px'; |
|
|
|
|
|
let inputsWrapper = document.createElement("div"); |
|
|
inputsWrapper.setAttribute('class', "noteDiv"); |
|
|
inputsWrapper.setAttribute('class', "noteDiv"); |
|
|
|
|
|
|
|
|
let input = document.createElement("input"); |
|
|
let input = document.createElement("input"); |
|
|
|
|
|
|
|
|
input.setAttribute('placeholder', "Enter title..."); |
|
|
input.setAttribute('placeholder', "Enter title..."); |
|
|
input.style.marginBottom='5px'; |
|
|
input.style.marginBottom='5px'; |
|
|
|
|
|
|
|
|
let div1 = document.createElement("div"); |
|
|
|
|
|
|
|
|
let textAreaDiv = document.createElement("div"); |
|
|
let textarea = document.createElement("textarea"); |
|
|
let textarea = document.createElement("textarea"); |
|
|
textarea.setAttribute('name',"noteText"); |
|
|
textarea.setAttribute('name',"noteText"); |
|
|
textarea.setAttribute('id', "noteText"+id); |
|
|
textarea.setAttribute('id', "noteText"+id); |
|
|
|
|
|
|
|
|
textarea.style.width='300px'; |
|
|
textarea.style.width='300px'; |
|
|
textarea.style.height='150px'; |
|
|
textarea.style.height='150px'; |
|
|
textarea.style.boxSizing='border-box'; |
|
|
textarea.style.boxSizing='border-box'; |
|
|
div1.appendChild(textarea); |
|
|
|
|
|
|
|
|
textAreaDiv.appendChild(textarea); |
|
|
|
|
|
|
|
|
let div2 = document.createElement("div") |
|
|
|
|
|
div2.setAttribute('id', 'buttonDiv'+id) |
|
|
|
|
|
let btn = document.createElement("button"); |
|
|
|
|
|
btn.setAttribute('type',"button"); |
|
|
|
|
|
btn.setAttribute('id',"saveNoteButton_"+id); |
|
|
|
|
|
btn.innerHTML = 'Save'; |
|
|
|
|
|
|
|
|
let saveNoteButton = document.createElement("button"); |
|
|
|
|
|
saveNoteButton.setAttribute('type',"button"); |
|
|
|
|
|
saveNoteButton.setAttribute('id',"saveNoteButton_"+id); |
|
|
|
|
|
saveNoteButton.innerHTML = 'Save'; |
|
|
|
|
|
|
|
|
inputsWrapper.appendChild(input); |
|
|
inputsWrapper.appendChild(input); |
|
|
inputsWrapper.appendChild(div1); |
|
|
|
|
|
inputsWrapper.appendChild(btn); |
|
|
|
|
|
|
|
|
inputsWrapper.appendChild(textAreaDiv); |
|
|
|
|
|
inputsWrapper.appendChild(saveNoteButton); |
|
|
wrapper.appendChild(inputsWrapper); |
|
|
wrapper.appendChild(inputsWrapper); |
|
|
|
|
|
|
|
|
document.getElementById('allNotesDiv').appendChild(wrapper); |
|
|
document.getElementById('allNotesDiv').appendChild(wrapper); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function createFormWithSavedContent(id){ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createFormWithSavedContent(item, id){ |
|
|
|
|
|
// |
|
|
console.log("createFormWithSavedContent() "+id) |
|
|
console.log("createFormWithSavedContent() "+id) |
|
|
item = JSON.parse(localStorage.getItem('noteObj'+id)) |
|
|
|
|
|
|
|
|
|
|
|
console.log(item.title); |
|
|
console.log(item.title); |
|
|
console.log(item.text); |
|
|
console.log(item.text); |
|
|
|
|
|
// |
|
|
|
|
|
|
|
|
let wrapper = document.createElement("div") |
|
|
let wrapper = document.createElement("div") |
|
|
wrapper.setAttribute('id', "note"+id) |
|
|
wrapper.setAttribute('id', "note"+id) |
|
|
|
|
|
|
|
|
input.setAttribute('name',"noteTitle"); |
|
|
input.setAttribute('name',"noteTitle"); |
|
|
input.setAttribute('id', "inputTitle"+id); |
|
|
input.setAttribute('id', "inputTitle"+id); |
|
|
input.setAttribute('value', item.title); |
|
|
input.setAttribute('value', item.title); |
|
|
//document.getElementById("inputTitle"+id).value = item.title; |
|
|
|
|
|
input.style.marginBottom='5px'; |
|
|
input.style.marginBottom='5px'; |
|
|
|
|
|
|
|
|
let div1 = document.createElement("div"); |
|
|
|
|
|
|
|
|
let textAreaDiv = document.createElement("div"); |
|
|
let textarea = document.createElement("textarea"); |
|
|
let textarea = document.createElement("textarea"); |
|
|
textarea.setAttribute('name',"noteText"); |
|
|
textarea.setAttribute('name',"noteText"); |
|
|
textarea.setAttribute('id', "noteText"+id); |
|
|
textarea.setAttribute('id', "noteText"+id); |
|
|
|
|
|
|
|
|
textarea.style.width='300px'; |
|
|
textarea.style.width='300px'; |
|
|
textarea.style.height='150px'; |
|
|
textarea.style.height='150px'; |
|
|
textarea.style.boxSizing='border-box'; |
|
|
textarea.style.boxSizing='border-box'; |
|
|
//document.getElementById('noteText'+id).value = item.text; |
|
|
|
|
|
div1.appendChild(textarea); |
|
|
|
|
|
|
|
|
textAreaDiv.appendChild(textarea); |
|
|
|
|
|
|
|
|
let div2 = document.createElement("div") |
|
|
|
|
|
div2.setAttribute('id', 'buttonDiv'+id) |
|
|
|
|
|
let btn = document.createElement("button"); |
|
|
|
|
|
btn.setAttribute('type',"button"); |
|
|
|
|
|
btn.setAttribute('id',"editNoteButton_"+id); |
|
|
|
|
|
btn.innerHTML = 'Save'; |
|
|
|
|
|
|
|
|
let editNoteButton = document.createElement("button"); |
|
|
|
|
|
editNoteButton.setAttribute('type',"button"); |
|
|
|
|
|
editNoteButton.setAttribute('id',"editNoteButton_"+id); |
|
|
|
|
|
editNoteButton.innerHTML = 'Save'; |
|
|
|
|
|
|
|
|
inputsWrapper.appendChild(input); |
|
|
inputsWrapper.appendChild(input); |
|
|
inputsWrapper.appendChild(div1); |
|
|
|
|
|
inputsWrapper.appendChild(btn); |
|
|
|
|
|
|
|
|
inputsWrapper.appendChild(textAreaDiv); |
|
|
|
|
|
inputsWrapper.appendChild(editNoteButton); |
|
|
wrapper.appendChild(inputsWrapper); |
|
|
wrapper.appendChild(inputsWrapper); |
|
|
|
|
|
|
|
|
document.getElementById('allNotesDiv').appendChild(wrapper); |
|
|
document.getElementById('allNotesDiv').appendChild(wrapper); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let ctr; |
|
|
let ctr; |
|
|
|
|
|
|
|
|
function sleep(ms) { |
|
|
|
|
|
return new Promise(resolve => setTimeout(resolve, ms)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
async function sleep(ms) { |
|
|
|
|
|
try { |
|
|
|
|
|
return new Promise(resolve => setTimeout(resolve, ms)); |
|
|
|
|
|
} |
|
|
|
|
|
catch (alert) { |
|
|
|
|
|
return alert(alert); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
async function saveNoteObject(id, overwrite=false){ |
|
|
|
|
|
|
|
|
async function removeNote(id){ |
|
|
|
|
|
try { |
|
|
|
|
|
return new Promise(resolve => { |
|
|
|
|
|
localStorage.removeItem('noteObj' + id); |
|
|
|
|
|
removeBrowserItem(id); |
|
|
|
|
|
resolve(); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
catch (alert) { |
|
|
|
|
|
return alert(alert); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function saveNote(id){ |
|
|
|
|
|
try { |
|
|
|
|
|
return new Promise(resolve => { |
|
|
|
|
|
let noteTitle = document.getElementById('inputTitle' + id).value; |
|
|
|
|
|
let noteText = document.getElementById('noteText' + id).value; |
|
|
|
|
|
let noteObj = { |
|
|
|
|
|
idK: id, |
|
|
|
|
|
title: noteTitle, |
|
|
|
|
|
text: noteText |
|
|
|
|
|
}; |
|
|
|
|
|
let noteObj_serialized = JSON.stringify(noteObj); //stringify noteObj so it is displayed properly when set to local Storage |
|
|
|
|
|
localStorage.setItem("noteObj" + id, noteObj_serialized); |
|
|
|
|
|
resolve(noteObj); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
catch (alert) { |
|
|
|
|
|
return alert(alert); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function refreshBrowser(){ |
|
|
|
|
|
try { |
|
|
|
|
|
return new Promise(resolve => { |
|
|
|
|
|
let noteStorage = []; |
|
|
|
|
|
let keys = Object.keys(localStorage); |
|
|
|
|
|
let i = keys.length; |
|
|
|
|
|
while (i--) { |
|
|
|
|
|
noteStorage.push(localStorage.getItem(keys[i])); |
|
|
|
|
|
} |
|
|
|
|
|
let parentNode = document.getElementById('noteStorage'); |
|
|
|
|
|
parentNode.innerHTML = ''; |
|
|
|
|
|
noteStorage.forEach(element => { |
|
|
|
|
|
createBrowserItem(JSON.parse(element)); |
|
|
|
|
|
}); |
|
|
|
|
|
resolve(); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
catch (alert) { |
|
|
|
|
|
return alert(alert); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function saveNoteObject(id, overwrite=false){ |
|
|
|
|
|
// |
|
|
console.log("saveNoteObject() "+id) |
|
|
console.log("saveNoteObject() "+id) |
|
|
console.log(id) |
|
|
console.log(id) |
|
|
|
|
|
// |
|
|
|
|
|
createLoadingSign(id, append="note") |
|
|
enableLoadingSign(id); |
|
|
enableLoadingSign(id); |
|
|
await sleep(10000) //sleep simulates the remote server access or similar, |
|
|
|
|
|
|
|
|
await sleep(10000) //sleep() simulates the delay that would occur when there is a remote server access or similar, |
|
|
//so instead of sleep would be e.g. saveToRemoteServer()... |
|
|
//so instead of sleep would be e.g. saveToRemoteServer()... |
|
|
//the leftover code of the async function is executed after the delay |
|
|
//the leftover code of the async function is executed after the delay |
|
|
disableLoadingSign(id); |
|
|
disableLoadingSign(id); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (overwrite == true){ |
|
|
if (overwrite == true){ |
|
|
localStorage.removeItem('noteObj'+id); |
|
|
|
|
|
removeBrowserItem(id); |
|
|
|
|
|
|
|
|
await removeNote(id); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
let noteTitle = document.getElementById('inputTitle'+id).value; |
|
|
|
|
|
let noteText = document.getElementById('noteText'+id).value; |
|
|
|
|
|
let noteObj = { |
|
|
|
|
|
idK: id, |
|
|
|
|
|
title: noteTitle, |
|
|
|
|
|
text: noteText |
|
|
|
|
|
}; |
|
|
|
|
|
let noteObj_serialized = JSON.stringify(noteObj); //stringify noteObj so it is displayed properly when set to local Storage |
|
|
|
|
|
localStorage.setItem("noteObj"+id, noteObj_serialized); |
|
|
|
|
|
createBrowserItem(noteObj); |
|
|
|
|
|
|
|
|
|
|
|
console.log(noteObj_serialized) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let obj = await saveNote(id); |
|
|
|
|
|
createBrowserItem(obj); |
|
|
document.getElementById("note"+id).remove(); |
|
|
document.getElementById("note"+id).remove(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function enableLoadingSign(id){ |
|
|
function enableLoadingSign(id){ |
|
|
|
|
|
console.log("id:"+id); |
|
|
|
|
|
let target = 'loadSign'+id; |
|
|
console.log("enableLoadingSign() "+id) |
|
|
console.log("enableLoadingSign() "+id) |
|
|
createLoadingSign(id) |
|
|
|
|
|
document.getElementById('loadSign'+id).style.display = "block"; |
|
|
|
|
|
|
|
|
document.getElementById(target).style.display = "block"; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function disableLoadingSign(id){ |
|
|
function disableLoadingSign(id){ |
|
|
let sign = document.getElementById('loadSign'+id); |
|
|
|
|
|
|
|
|
console.log("id:"+id); |
|
|
|
|
|
let target = 'loadSign'+id; |
|
|
|
|
|
let sign = document.getElementById(target); |
|
|
sign.style.display = "none"; |
|
|
sign.style.display = "none"; |
|
|
sign.parentNode.removeChild(sign); |
|
|
sign.parentNode.removeChild(sign); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function createLoadingSign(id){ |
|
|
|
|
|
|
|
|
function createLoadingSign(id, append){ |
|
|
|
|
|
console.log("id:"+id); |
|
|
|
|
|
let target = 'loadSign'+id; |
|
|
|
|
|
let appendTo = append+id; |
|
|
|
|
|
console.log(appendTo); |
|
|
console.log("createLoadingSign() "+id) |
|
|
console.log("createLoadingSign() "+id) |
|
|
let loadingSign = document.createElement('div'); |
|
|
let loadingSign = document.createElement('div'); |
|
|
let loadingSignWrapper = document.createElement('div'); |
|
|
let loadingSignWrapper = document.createElement('div'); |
|
|
loadingSign.setAttribute('class', 'loader') |
|
|
loadingSign.setAttribute('class', 'loader') |
|
|
loadingSign.setAttribute('id', 'loadSign'+id); |
|
|
|
|
|
|
|
|
loadingSign.setAttribute('id', target); |
|
|
loadingSignWrapper.appendChild(loadingSign); |
|
|
loadingSignWrapper.appendChild(loadingSign); |
|
|
document.getElementById("note"+id).appendChild(loadingSignWrapper); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function updateNoteBrowser(){ |
|
|
|
|
|
|
|
|
|
|
|
let noteStorage = []; |
|
|
|
|
|
let keys = Object.keys(localStorage); |
|
|
|
|
|
let i = keys.length; |
|
|
|
|
|
|
|
|
|
|
|
while ( i-- ) { |
|
|
|
|
|
noteStorage.push(localStorage.getItem(keys[i])); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
localStorage.clear(); |
|
|
|
|
|
|
|
|
|
|
|
noteStorage.forEach(element => { |
|
|
|
|
|
createBrowserItem(JSON.parse(element)) |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
document.getElementById(appendTo).appendChild(loadingSignWrapper); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function createBrowserItem(item){ |
|
|
function createBrowserItem(item){ |
|
|
console.log(item); |
|
|
console.log(item); |
|
|
let wrapperDiv = document.createElement('div'); |
|
|
let wrapperDiv = document.createElement('div'); |
|
|
let browserItem = document.createElement('div'); |
|
|
let browserItem = document.createElement('div'); |
|
|
let button = document.createElement('button'); |
|
|
|
|
|
|
|
|
let deleteButton = document.createElement('button'); |
|
|
wrapperDiv.setAttribute('class', 'browserElement'); |
|
|
wrapperDiv.setAttribute('class', 'browserElement'); |
|
|
browserItem.innerHTML = item.title; |
|
|
browserItem.innerHTML = item.title; |
|
|
button.innerHTML = "X"; |
|
|
|
|
|
|
|
|
deleteButton.style.marginLeft = '2px'; |
|
|
|
|
|
deleteButton.innerHTML = "X"; |
|
|
browserItem.setAttribute('id', "browserItem_"+item.idK); |
|
|
browserItem.setAttribute('id', "browserItem_"+item.idK); |
|
|
browserItem.setAttribute('onClick', "getSavedNote(this.id)"); |
|
|
browserItem.setAttribute('onClick', "getSavedNote(this.id)"); |
|
|
button.setAttribute('id', "deleteItem_" + item.idK); |
|
|
|
|
|
|
|
|
deleteButton.setAttribute('id', "deleteItem_" + item.idK); |
|
|
wrapperDiv.appendChild(browserItem); |
|
|
wrapperDiv.appendChild(browserItem); |
|
|
wrapperDiv.appendChild(button); |
|
|
|
|
|
|
|
|
wrapperDiv.appendChild(deleteButton); |
|
|
document.getElementById('noteStorage').appendChild(wrapperDiv); |
|
|
document.getElementById('noteStorage').appendChild(wrapperDiv); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function removeBrowserItem(id){ |
|
|
|
|
|
console.log("removeBrowserItem() "+id) |
|
|
|
|
|
localStorage.removeItem('noteObj'+id); |
|
|
|
|
|
document.getElementById("browserItem_"+id).remove(); |
|
|
|
|
|
document.getElementById("deleteItem_"+id).remove(); |
|
|
|
|
|
|
|
|
async function removeBrowserItem(id){ |
|
|
|
|
|
try { |
|
|
|
|
|
return new Promise(resolve => { |
|
|
|
|
|
console.log("removeBrowserItem() " + id); |
|
|
|
|
|
localStorage.removeItem('noteObj' + id); |
|
|
|
|
|
document.getElementById("browserItem_" + id).remove(); |
|
|
|
|
|
document.getElementById("deleteItem_" + id).remove(); |
|
|
|
|
|
resolve(); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
catch (alert) { |
|
|
|
|
|
return alert(alert); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function getSavedNote(id){ |
|
|
|
|
|
|
|
|
async function getSavedNote(id){ |
|
|
console.log("getSavedNote() "+ id); |
|
|
console.log("getSavedNote() "+ id); |
|
|
|
|
|
createLoadingSign("", "allNotesDiv"); |
|
|
|
|
|
enableLoadingSign(""); |
|
|
|
|
|
await sleep(5000); |
|
|
|
|
|
disableLoadingSign(""); |
|
|
|
|
|
console.log("id before split " + id); |
|
|
let idTmp = id.split("_")[1]; |
|
|
let idTmp = id.split("_")[1]; |
|
|
createFormWithSavedContent(idTmp); |
|
|
|
|
|
|
|
|
console.log("idTmp " +idTmp); |
|
|
|
|
|
let item = await new Promise(resolve => { |
|
|
|
|
|
let item = JSON.parse(localStorage.getItem('noteObj'+idTmp)); |
|
|
|
|
|
console.log("in promise "+item); |
|
|
|
|
|
resolve(item); |
|
|
|
|
|
}) |
|
|
|
|
|
console.log(item); |
|
|
|
|
|
createFormWithSavedContent(item, idTmp); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|