loading spinner

This commit is contained in:
Paul Sori 2019-03-04 05:08:13 -08:00
parent 34b46fb0dd
commit 69ada310bc
8 changed files with 208 additions and 85 deletions

View File

@ -77,8 +77,8 @@ exports.insertEntries = function (arrayOfSongs, vpath) {
"hash": song.hash,
"albumArtFilename": song.albumArtFilename ? song.albumArtFilename : null,
"vpath": vpath,
"rating": null,
"lastPlayed": null
"rating": 0,
"lastPlayed": 0
});
saveCounter++;

View File

@ -2,6 +2,7 @@ body, html {
height: 100%; }
body {
overflow: hidden;
background: url(../img/struckaxiom.png) top left repeat;
background-position: fixed; }
@ -792,9 +793,17 @@ ul.left-nav-menu li.selected svg {
}
.app-text {
padding: 10px 10px;
font-size: 16px;
font-weight: 500;
color: #5a5a5a;
font-family: "Open Sans", "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
padding: 10px 10px;
font-size: 16px;
font-weight: 500;
color: #5a5a5a;
font-family: "Open Sans", "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
}
.loading-screen {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding-top: 70px;
}

100
public/css/spinner.css Normal file
View File

@ -0,0 +1,100 @@
.spinner {
-webkit-animation: rotator 1.5s linear infinite;
animation: rotator 1.5s linear infinite;
}
@-webkit-keyframes rotator {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(270deg);
transform: rotate(270deg);
}
}
@keyframes rotator {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(270deg);
transform: rotate(270deg);
}
}
.spinner-path {
stroke-dasharray: 257;
stroke-dashoffset: 0;
-webkit-transform-origin: center;
transform-origin: center;
-webkit-animation: spinner-dash 1.5s ease-in-out infinite, spinner-colors 6s ease-in-out infinite;
animation: spinner-dash 1.5s ease-in-out infinite, spinner-colors 6s ease-in-out infinite;
}
@-webkit-keyframes spinner-colors {
0% {
stroke: #4285F4;
}
25% {
stroke: #DE3E35;
}
50% {
stroke: #F7C223;
}
75% {
stroke: #1B9A59;
}
100% {
stroke: #4285F4;
}
}
@keyframes spinner-colors {
0% {
stroke: #4285F4;
}
25% {
stroke: #DE3E35;
}
50% {
stroke: #F7C223;
}
75% {
stroke: #1B9A59;
}
100% {
stroke: #4285F4;
}
}
@-webkit-keyframes spinner-dash {
0% {
stroke-dashoffset: 257;
}
50% {
stroke-dashoffset: 64.25;
-webkit-transform: rotate(135deg);
transform: rotate(135deg);
}
100% {
stroke-dashoffset: 257;
-webkit-transform: rotate(450deg);
transform: rotate(450deg);
}
}
@keyframes spinner-dash {
0% {
stroke-dashoffset: 257;
}
50% {
stroke-dashoffset: 64.25;
-webkit-transform: rotate(135deg);
transform: rotate(135deg);
}
100% {
stroke-dashoffset: 257;
-webkit-transform: rotate(450deg);
transform: rotate(450deg);
}
}

1
public/img/spinner.svg Normal file
View File

@ -0,0 +1 @@
<svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg>

After

Width:  |  Height:  |  Size: 222 B

View File

@ -321,7 +321,7 @@ $(document).ready(function () {
// These vars track your position within the file explorer
var fileExplorerArray = [];
var fileExplorerScrollPosition = [];
// Stores an array of searchable ojects
// Stores an array of searchable objects
var currentBrowsingList = [];
//////////////////////////////// Administrative stuff
@ -440,6 +440,9 @@ $(document).ready(function () {
directoryString += newArray[i] + "/";
}
$('.directoryName').html('/' + directoryString);
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
MSTREAMAPI.dirparser(directoryString, false, function (response, error) {
if (error !== false) {
boilerplateFailure(response, error);
@ -448,7 +451,6 @@ $(document).ready(function () {
fileExplorerArray = newArray;
// Set any directory views
$('.directoryName').html('/' + directoryString);
// hand this data off to be printed on the page
printdir(response);
// Set scroll postion
@ -469,7 +471,6 @@ $(document).ready(function () {
currentBrowsingList = response.contents;
// clear the list
$('#filelist').empty();
$('#search_folders').val('');
//parse through the json array and make an array of corresponding divs
@ -547,9 +548,7 @@ $(document).ready(function () {
}
}
}
}
});
// Post the html to the filelist div
@ -689,22 +688,24 @@ $(document).ready(function () {
$('ul.left-nav-menu li').removeClass('selected');
$('.get_all_playlists').addClass('selected');
resetPanel('Playlists', 'scrollBoxHeight1');
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
currentBrowsingList = [];
programState = [{
state: 'allPlaylists'
}]
MSTREAMAPI.getAllPlaylists(function (response, error) {
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
currentBrowsingList = [];
VUEPLAYER.playlists.length = 0;
// loop through the json array and make an array of corresponding divs
var playlists = [];
$.each(response, function () {
console.log()
playlists.push('<div data-playlistname="' + encodeURIComponent(this.name) + '" class="playlist_row_container"><span data-playlistname="' + encodeURIComponent(this.name) + '" class="playlistz force-width">' + escapeHtml(this.name) + '</span><div class="song-button-box"><span data-playlistname="' + encodeURIComponent(this.name) + '" class="deletePlaylist">Delete</span></div></div>');
this.type = 'playlist';
currentBrowsingList.push(this);
@ -761,6 +762,9 @@ $(document).ready(function () {
var playlistname = decodeURIComponent($(this).data('playlistname'));
var name = $(this).html();
$('.directoryName').html('Playlist: ' + name);
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
$('#search_folders').val('');
currentBrowsingList = [];
programState.push({
state: 'playlist',
@ -768,16 +772,14 @@ $(document).ready(function () {
})
MSTREAMAPI.loadPlaylist(playlistname, function (response, error) {
$('#search_folders').val('');
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
// Add the playlist name to the modal
$('#playlist_name').val(name);
currentBrowsingList = [];
//parse through the json array and make an array of corresponding divs
var files = [];
$.each(response, function (index, value) {
@ -855,33 +857,29 @@ $(document).ready(function () {
$('ul.left-nav-menu li').removeClass('selected');
$('.db-panel').addClass('selected');
resetPanel('Database', 'scrollBoxHeight2');
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
$('#directory_bar').hide();
currentBrowsingList = [];
MSTREAMAPI.dbStatus(function (response, error) {
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
currentBrowsingList = [];
// If there is an error
if (response.error) {
$('#filelist').html('<p>The database returned the following error:</p><p>' + response.error + '</p>');
return;
}
// Add Beets Msg
if (response.dbType == 'beets' || response.dbType == 'beets-default') {
$('#filelist').append('<h3><img style="height:40px;" src="img/database-icon.svg" >Powered by Beets DB</h3>');
}
// if the DB is locked
if (response.locked) {
$('#filelist').append(' <p class="scan-status">Scan In Progress</p><p class="scan-status-files">' + response.totalFileCount + ' files in DB</p>');
//$('#filelist').append('<p>The database is currently being built. Currently ' + response.totalFileCount + ' files are in the DB</p>');
$('#filelist').html('<p class="scan-status">Scan In Progress</p><p class="scan-status-files">' + response.totalFileCount + ' files in DB</p>');
return;
}
// If you got this far the db is made and working
$('#filelist').append('<p>Your DB has ' + response.totalFileCount + ' files</p><input type="button" value="Build Database" id="build_database">');
$('#filelist').html('<p>Your DB has ' + response.totalFileCount + ' files</p><input type="button" value="Build Database" id="build_database">');
});
});
@ -931,16 +929,19 @@ $(document).ready(function () {
$('ul.left-nav-menu li').removeClass('selected');
$('.get_all_albums').addClass('selected');
resetPanel('Albums', 'scrollBoxHeight1');
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
currentBrowsingList = [];
programState = [{
state: 'allAlbums'
}]
MSTREAMAPI.albums(function (response, error) {
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
currentBrowsingList = [];
//parse through the json array and make an array of corresponding divs
var albums = [];
$.each(response.albums, function (index, value) {
@ -967,24 +968,23 @@ $(document).ready(function () {
});
function getAlbumSongs(album) {
$('#search_folders').val('');
$('.directoryName').html('Album: ' + album);
//clear the list
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
currentBrowsingList = [];
programState.push({
state: 'album',
name: album
})
MSTREAMAPI.albumSongs(album, function (response, error) {
$('#search_folders').val('');
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
$('.directoryName').html('Album: ' + album);
//clear the list
$('#filelist').empty();
currentBrowsingList = [];
//parse through the json array and make an array of corresponding divs
var filelist = [];
$.each(response, function () {
@ -1011,15 +1011,18 @@ $(document).ready(function () {
$('ul.left-nav-menu li').removeClass('selected');
$('.get_all_artists').addClass('selected');
resetPanel('Artists', 'scrollBoxHeight1');
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
currentBrowsingList = [];
programState = [{
state: 'allArtists'
}]
MSTREAMAPI.artists(function (response, error) {
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
currentBrowsingList = [];
//parse through the json array and make an array of corresponding divs
var artists = [];
@ -1045,15 +1048,15 @@ $(document).ready(function () {
function getArtistsAlbums(artist) {
resetPanel('Albums', 'scrollBoxHeight1');
$('.directoryName').html('Artist: ' + artist);
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
$('#search_folders').val('');
currentBrowsingList = [];
MSTREAMAPI.artistAlbums(artist, function (response, error) {
$('#search_folders').val('');
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
//clear the list
currentBrowsingList = [];
var albums = [];
$.each(response.albums, function (index, value) {
@ -1078,18 +1081,20 @@ $(document).ready(function () {
$('ul.left-nav-menu li').removeClass('selected');
$('.get_rated_songs').addClass('selected');
resetPanel('Starred', 'scrollBoxHeight1');
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
$('#search_folders').val('');
currentBrowsingList = [];
programState = [{
state: 'allRated'
}]
MSTREAMAPI.getRated(function (response, error) {
$('#search_folders').val('');
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
currentBrowsingList = [];
//parse through the json array and make an array of corresponding divs
var files = [];
$.each(response, function (index, value) {

View File

@ -380,6 +380,9 @@ $(document).ready(function () {
directoryString += newArray[i] + "/";
}
$('.directoryName').html('/' + directoryString);
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
MSTREAMAPI.dirparser(directoryString, false, function (response, error) {
if (error !== false) {
boilerplateFailure(response, error);
@ -388,7 +391,6 @@ $(document).ready(function () {
fileExplorerArray = newArray;
// Set any directory views
$('.directoryName').html('/' + directoryString);
// hand this data off to be printed on the page
printdir(response);
// Set scroll postion
@ -409,7 +411,6 @@ $(document).ready(function () {
currentBrowsingList = response.contents;
// clear the list
$('#filelist').empty();
$('#search_folders').val('');
//parse through the json array and make an array of corresponding divs
@ -487,9 +488,7 @@ $(document).ready(function () {
}
}
}
}
});
// Post the html to the filelist div
@ -534,7 +533,6 @@ $(document).ready(function () {
$('#downform').empty();
});
////////////////////////////////////// Save/Load playlists
// Get all playlists
$('.get_all_playlists').on('click', function () {
getAllPlaylists();
@ -544,17 +542,19 @@ $(document).ready(function () {
$('ul.left-nav-menu li').removeClass('selected');
$('.get_all_playlists').addClass('selected');
resetPanel('Playlists', 'scrollBoxHeight1');
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
currentBrowsingList = [];
programState = [{
state: 'allPlaylists'
}]
MSTREAMAPI.getAllPlaylists(function (response, error) {
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
currentBrowsingList = [];
// loop through the json array and make an array of corresponding divs
var playlists = [];
$.each(response, function () {
@ -613,6 +613,9 @@ $(document).ready(function () {
var playlistname = decodeURIComponent($(this).data('playlistname'));
var name = $(this).html();
$('.directoryName').html('Playlist: ' + name);
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
$('#search_folders').val('');
currentBrowsingList = [];
programState.push({
state: 'playlist',
@ -620,16 +623,14 @@ $(document).ready(function () {
})
MSTREAMAPI.loadPlaylist(playlistname, function (response, error) {
$('#search_folders').val('');
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
// Add the playlist name to the modal
$('#playlist_name').val(name);
currentBrowsingList = [];
//parse through the json array and make an array of corresponding divs
var files = [];
$.each(response, function (index, value) {
@ -680,33 +681,29 @@ $(document).ready(function () {
$('ul.left-nav-menu li').removeClass('selected');
$('.db-panel').addClass('selected');
resetPanel('Database', 'scrollBoxHeight2');
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
$('#directory_bar').hide();
currentBrowsingList = [];
MSTREAMAPI.dbStatus(function (response, error) {
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
currentBrowsingList = [];
// If there is an error
if (response.error) {
$('#filelist').html('<p>The database returned the following error:</p><p>' + response.error + '</p>');
return;
}
// Add Beets Msg
if (response.dbType == 'beets' || response.dbType == 'beets-default') {
$('#filelist').append('<h3><img style="height:40px;" src="img/database-icon.svg" >Powered by Beets DB</h3>');
}
// if the DB is locked
if (response.locked) {
$('#filelist').append(' <p class="scan-status">Scan In Progress</p><p class="scan-status-files">' + response.totalFileCount + ' files in DB</p>');
//$('#filelist').append('<p>The database is currently being built. Currently ' + response.totalFileCount + ' files are in the DB</p>');
$('#filelist').html('<p class="scan-status">Scan In Progress</p><p class="scan-status-files">' + response.totalFileCount + ' files in DB</p>');
return;
}
// If you got this far the db is made and working
$('#filelist').append('<p>Your DB has ' + response.totalFileCount + ' files</p><input type="button" value="Build Database" id="build_database">');
$('#filelist').html('<p>Your DB has ' + response.totalFileCount + ' files</p><input type="button" value="Build Database" id="build_database">');
});
});
@ -756,16 +753,19 @@ $(document).ready(function () {
$('ul.left-nav-menu li').removeClass('selected');
$('.get_all_albums').addClass('selected');
resetPanel('Albums', 'scrollBoxHeight1');
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
currentBrowsingList = [];
programState = [{
state: 'allAlbums'
}]
MSTREAMAPI.albums(function (response, error) {
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
currentBrowsingList = [];
//parse through the json array and make an array of corresponding divs
var albums = [];
$.each(response.albums, function (index, value) {
@ -792,24 +792,23 @@ $(document).ready(function () {
});
function getAlbumSongs(album) {
$('#search_folders').val('');
$('.directoryName').html('Album: ' + album);
//clear the list
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
currentBrowsingList = [];
programState.push({
state: 'album',
name: album
})
MSTREAMAPI.albumSongs(album, function (response, error) {
$('#search_folders').val('');
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
$('.directoryName').html('Album: ' + album);
//clear the list
$('#filelist').empty();
currentBrowsingList = [];
//parse through the json array and make an array of corresponding divs
var filelist = [];
$.each(response, function () {
@ -836,15 +835,18 @@ $(document).ready(function () {
$('ul.left-nav-menu li').removeClass('selected');
$('.get_all_artists').addClass('selected');
resetPanel('Artists', 'scrollBoxHeight1');
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
currentBrowsingList = [];
programState = [{
state: 'allArtists'
}]
MSTREAMAPI.artists(function (response, error) {
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
currentBrowsingList = [];
//parse through the json array and make an array of corresponding divs
var artists = [];
@ -870,15 +872,15 @@ $(document).ready(function () {
function getArtistsAlbums(artist) {
resetPanel('Albums', 'scrollBoxHeight1');
$('.directoryName').html('Artist: ' + artist);
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
$('#search_folders').val('');
currentBrowsingList = [];
MSTREAMAPI.artistAlbums(artist, function (response, error) {
$('#search_folders').val('');
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
//clear the list
currentBrowsingList = [];
var albums = [];
$.each(response.albums, function (index, value) {
@ -903,18 +905,20 @@ $(document).ready(function () {
$('ul.left-nav-menu li').removeClass('selected');
$('.get_rated_songs').addClass('selected');
resetPanel('Starred', 'scrollBoxHeight1');
$('#filelist').html('<div class="loading-screen"><svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
$('#search_folders').val('');
currentBrowsingList = [];
programState = [{
state: 'allRated'
}]
MSTREAMAPI.getRated(function (response, error) {
$('#search_folders').val('');
if (error !== false) {
$('#filelist').html('<div>Server call failed</div>');
return boilerplateFailure(response, error);
}
currentBrowsingList = [];
//parse through the json array and make an array of corresponding divs
var files = [];
$.each(response, function (index, value) {

View File

@ -73,6 +73,8 @@
<script src="/public/js/lib/modal.js"></script>
<link rel="stylesheet" href="/public/css/izi-modal.min.css">
<link rel="stylesheet" href="/public/css/spinner.css">
</head>
<body>

View File

@ -68,6 +68,8 @@
<script src="/public/js/lib/modal.js"></script>
<link rel="stylesheet" href="/public/css/izi-modal.min.css">
<link rel="stylesheet" href="/public/css/spinner.css">
</head>
<body>