Cleanups; add 'make depend'.
This commit is contained in:
parent
332fdba0bd
commit
50d9efdac9
4 changed files with 265 additions and 244 deletions
19
Makefile.in
19
Makefile.in
|
|
@ -1,6 +1,9 @@
|
||||||
|
.SUFFIXES: .c .o .d .h
|
||||||
|
|
||||||
VPATH = @top_srcdir@
|
VPATH = @top_srcdir@
|
||||||
|
|
||||||
CC = @CC@
|
CC = @CC@
|
||||||
|
MAKEDEPEND = @CC@ -M
|
||||||
# _GNU_SOURCE is required for wcsdup() on older version of glibc that don't
|
# _GNU_SOURCE is required for wcsdup() on older version of glibc that don't
|
||||||
# implement XPG7.
|
# implement XPG7.
|
||||||
CPPFLAGS = @CPPFLAGS@ -D_XOPEN_SOURCE=700 -D_XOPEN_SOURCE_EXTENDED -D__EXTENSIONS__
|
CPPFLAGS = @CPPFLAGS@ -D_XOPEN_SOURCE=700 -D_XOPEN_SOURCE_EXTENDED -D__EXTENSIONS__
|
||||||
|
|
@ -25,8 +28,22 @@ install:
|
||||||
.c.o:
|
.c.o:
|
||||||
${CC} ${CPPFLAGS} ${CFLAGS} -c $<
|
${CC} ${CPPFLAGS} ${CFLAGS} -c $<
|
||||||
|
|
||||||
|
.c.d:
|
||||||
|
$(MAKEDEPEND) $(CPPFLAGS) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
vers.c: vers.c.sh configure.ac
|
vers.c: vers.c.sh configure.ac
|
||||||
sh @top_srcdir@/vers.c.sh @top_srcdir@/configure.ac
|
sh @top_srcdir@/vers.c.sh @top_srcdir@/configure.ac
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f tts *.o
|
rm -f tts ${OBJS} $(OBJS:.o=.d)
|
||||||
|
|
||||||
|
depend: $(OBJS:.o=.d)
|
||||||
|
sed '/^# Do not remove this line -- make depend needs it/,$$ d' \
|
||||||
|
<Makefile >Makefile.new
|
||||||
|
echo '# Do not remove this line -- make depend needs it' >>Makefile.new
|
||||||
|
cat *.d >> Makefile.new
|
||||||
|
mv Makefile.new Makefile
|
||||||
|
|
||||||
|
.PHONY: depend clean install libuv
|
||||||
|
|
||||||
|
# Do not remove this line -- make depend needs it
|
||||||
|
|
|
||||||
244
tts.c
244
tts.c
|
|
@ -56,11 +56,9 @@
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
|
|
||||||
extern char const *tts_version;
|
|
||||||
|
|
||||||
volatile sig_atomic_t doexit;
|
volatile sig_atomic_t doexit;
|
||||||
|
|
||||||
static time_t laststatus;
|
time_t laststatus;
|
||||||
|
|
||||||
history_t *searchhist;
|
history_t *searchhist;
|
||||||
history_t *prompthist;
|
history_t *prompthist;
|
||||||
|
|
@ -462,246 +460,6 @@ char rcfile[PATH_MAX + 1];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
drawheader()
|
|
||||||
{
|
|
||||||
WCHAR title[64];
|
|
||||||
|
|
||||||
SNPRINTF(title, WSIZEOF(title), WIDE("TTS %s - Type '?' for help"),
|
|
||||||
tts_version);
|
|
||||||
wmove(titwin, 0, 0);
|
|
||||||
WADDSTR(titwin, title);
|
|
||||||
|
|
||||||
if (itime > 0) {
|
|
||||||
WCHAR str[128];
|
|
||||||
int h, m, s;
|
|
||||||
time_t passed = time(NULL) - itime;
|
|
||||||
|
|
||||||
time_to_hms(passed, h, m, s);
|
|
||||||
SNPRINTF(str, WSIZEOF(str), WIDE(" *** MARK INTERRUPT: %02d:%02d:%02d ***"),
|
|
||||||
h, m, s);
|
|
||||||
|
|
||||||
wattron(titwin, A_BOLD);
|
|
||||||
WADDSTR(titwin, str);
|
|
||||||
wattroff(titwin, A_BOLD);
|
|
||||||
}
|
|
||||||
wclrtoeol(titwin);
|
|
||||||
wrefresh(titwin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
vdrawstatus(msg, ap)
|
|
||||||
const WCHAR *msg;
|
|
||||||
va_list ap;
|
|
||||||
{
|
|
||||||
WCHAR s[1024];
|
|
||||||
VSNPRINTF(s, WSIZEOF(s), msg, ap);
|
|
||||||
|
|
||||||
wmove(statwin, 0, 0);
|
|
||||||
WADDSTR(statwin, s);
|
|
||||||
wclrtoeol(statwin);
|
|
||||||
wrefresh(statwin);
|
|
||||||
time(&laststatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
drawstatus(const WCHAR *msg, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, msg);
|
|
||||||
vdrawstatus(msg, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
yesno(msg)
|
|
||||||
const WCHAR *msg;
|
|
||||||
{
|
|
||||||
WINDOW *pwin;
|
|
||||||
INT c;
|
|
||||||
|
|
||||||
pwin = newwin(1, COLS, LINES - 2, 0);
|
|
||||||
keypad(pwin, TRUE);
|
|
||||||
wattron(pwin, A_BOLD);
|
|
||||||
wmove(pwin, 0, 0);
|
|
||||||
WADDSTR(pwin, msg);
|
|
||||||
WADDSTR(pwin, WIDE(" [y/N]? "));
|
|
||||||
wattroff(pwin, A_BOLD);
|
|
||||||
|
|
||||||
while (WGETCH(pwin, &c) == ERR
|
|
||||||
#ifdef KEY_RESIZE
|
|
||||||
|| (c == KEY_RESIZE)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
return (c == 'Y' || c == 'y') ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
WCHAR *
|
|
||||||
prompt(msg, def, hist)
|
|
||||||
const WCHAR *msg, *def;
|
|
||||||
history_t *hist;
|
|
||||||
{
|
|
||||||
WINDOW *pwin;
|
|
||||||
WCHAR input[256];
|
|
||||||
size_t pos = 0;
|
|
||||||
histent_t *histpos = NULL;
|
|
||||||
|
|
||||||
if (hist == NULL)
|
|
||||||
hist = prompthist;
|
|
||||||
|
|
||||||
memset(input, 0, sizeof(input));
|
|
||||||
if (def) {
|
|
||||||
STRNCPY(input, def, WSIZEOF(input) - 1);
|
|
||||||
pos = STRLEN(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
pwin = newwin(1, COLS, LINES - 2, 0);
|
|
||||||
keypad(pwin, TRUE);
|
|
||||||
|
|
||||||
wattr_on(pwin, style_fg(sy_status), NULL);
|
|
||||||
wbkgd(pwin, style_bg(sy_status));
|
|
||||||
|
|
||||||
wattron(pwin, A_BOLD);
|
|
||||||
wmove(pwin, 0, 0);
|
|
||||||
WADDSTR(pwin, msg);
|
|
||||||
wattroff(pwin, A_BOLD);
|
|
||||||
|
|
||||||
curs_set(1);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
INT c;
|
|
||||||
wmove(pwin, 0, STRLEN(msg) + 1);
|
|
||||||
WADDSTR(pwin, input);
|
|
||||||
wclrtoeol(pwin);
|
|
||||||
wmove(pwin, 0, STRLEN(msg) + 1 + pos);
|
|
||||||
wrefresh(pwin);
|
|
||||||
|
|
||||||
if (WGETCH(pwin, &c) == ERR)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case '\n':
|
|
||||||
case '\r':
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
case KEY_BACKSPACE:
|
|
||||||
case 0x7F:
|
|
||||||
case 0x08:
|
|
||||||
if (pos) {
|
|
||||||
if (pos == STRLEN(input))
|
|
||||||
input[--pos] = 0;
|
|
||||||
else {
|
|
||||||
int i = STRLEN(input);
|
|
||||||
pos--;
|
|
||||||
MEMCPY(input + pos, input + pos + 1, STRLEN(input) - pos);
|
|
||||||
input[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_DC:
|
|
||||||
if (pos < STRLEN(input)) {
|
|
||||||
int i = STRLEN(input);
|
|
||||||
MEMCPY(input + pos, input + pos + 1, STRLEN(input) - pos);
|
|
||||||
input[i] = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_LEFT:
|
|
||||||
if (pos)
|
|
||||||
pos--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_RIGHT:
|
|
||||||
if (pos < STRLEN(input))
|
|
||||||
pos++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_HOME:
|
|
||||||
case 0x01: /* ^A */
|
|
||||||
pos = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_END:
|
|
||||||
case 0x05: /* ^E */
|
|
||||||
pos = STRLEN(input);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x07: /* ^G */
|
|
||||||
case 0x1B: /* ESC */
|
|
||||||
curs_set(0);
|
|
||||||
delwin(pwin);
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
case 0x15: /* ^U */
|
|
||||||
input[0] = 0;
|
|
||||||
pos = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef KEY_RESIZE
|
|
||||||
case KEY_RESIZE:
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case KEY_UP:
|
|
||||||
if (histpos == NULL) {
|
|
||||||
if ((histpos = TAILQ_LAST(&hist->hi_ents, hentlist)) == NULL) {
|
|
||||||
beep();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (TAILQ_PREV(histpos, hentlist, he_entries) == NULL) {
|
|
||||||
beep();
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
histpos = TAILQ_PREV(histpos, hentlist, he_entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
STRNCPY(input, histpos->he_text, WSIZEOF(input) - 1);
|
|
||||||
pos = STRLEN(input);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_DOWN:
|
|
||||||
if (histpos == NULL) {
|
|
||||||
beep();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TAILQ_NEXT(histpos, he_entries) == NULL) {
|
|
||||||
beep();
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
histpos = TAILQ_NEXT(histpos, he_entries);
|
|
||||||
|
|
||||||
|
|
||||||
STRNCPY(input, histpos->he_text, WSIZEOF(input) - 1);
|
|
||||||
pos = STRLEN(input);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (pos != STRLEN(input)) {
|
|
||||||
MEMMOVE(input + pos + 1, input + pos, STRLEN(input) - pos);
|
|
||||||
input[pos++] = c;
|
|
||||||
} else {
|
|
||||||
input[pos++] = c;
|
|
||||||
input[pos] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end: ;
|
|
||||||
|
|
||||||
curs_set(0);
|
|
||||||
delwin(pwin);
|
|
||||||
wtouchln(statwin, 1, 1, 1);
|
|
||||||
hist_add(hist, input);
|
|
||||||
return STRDUP(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
drawentries()
|
drawentries()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
3
tts.h
3
tts.h
|
|
@ -17,6 +17,9 @@
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
|
||||||
|
extern char const *tts_version;
|
||||||
|
extern time_t laststatus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configuration options.
|
* Configuration options.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
243
ui.c
243
ui.c
|
|
@ -8,8 +8,11 @@
|
||||||
* warranty.
|
* warranty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "tts.h"
|
#include "tts.h"
|
||||||
|
#include "style.h"
|
||||||
|
|
||||||
WINDOW *titwin, *statwin, *listwin;
|
WINDOW *titwin, *statwin, *listwin;
|
||||||
int in_curses;
|
int in_curses;
|
||||||
|
|
@ -63,3 +66,243 @@ entry_t *en;
|
||||||
curent = NULL;
|
curent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drawheader()
|
||||||
|
{
|
||||||
|
WCHAR title[64];
|
||||||
|
|
||||||
|
SNPRINTF(title, WSIZEOF(title), WIDE("TTS %s - Type '?' for help"),
|
||||||
|
tts_version);
|
||||||
|
wmove(titwin, 0, 0);
|
||||||
|
WADDSTR(titwin, title);
|
||||||
|
|
||||||
|
if (itime > 0) {
|
||||||
|
WCHAR str[128];
|
||||||
|
int h, m, s;
|
||||||
|
time_t passed = time(NULL) - itime;
|
||||||
|
|
||||||
|
time_to_hms(passed, h, m, s);
|
||||||
|
SNPRINTF(str, WSIZEOF(str), WIDE(" *** MARK INTERRUPT: %02d:%02d:%02d ***"),
|
||||||
|
h, m, s);
|
||||||
|
|
||||||
|
wattron(titwin, A_BOLD);
|
||||||
|
WADDSTR(titwin, str);
|
||||||
|
wattroff(titwin, A_BOLD);
|
||||||
|
}
|
||||||
|
wclrtoeol(titwin);
|
||||||
|
wrefresh(titwin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vdrawstatus(msg, ap)
|
||||||
|
const WCHAR *msg;
|
||||||
|
va_list ap;
|
||||||
|
{
|
||||||
|
WCHAR s[1024];
|
||||||
|
VSNPRINTF(s, WSIZEOF(s), msg, ap);
|
||||||
|
|
||||||
|
wmove(statwin, 0, 0);
|
||||||
|
WADDSTR(statwin, s);
|
||||||
|
wclrtoeol(statwin);
|
||||||
|
wrefresh(statwin);
|
||||||
|
time(&laststatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drawstatus(const WCHAR *msg, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, msg);
|
||||||
|
vdrawstatus(msg, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
yesno(msg)
|
||||||
|
const WCHAR *msg;
|
||||||
|
{
|
||||||
|
WINDOW *pwin;
|
||||||
|
INT c;
|
||||||
|
|
||||||
|
pwin = newwin(1, COLS, LINES - 2, 0);
|
||||||
|
keypad(pwin, TRUE);
|
||||||
|
wattron(pwin, A_BOLD);
|
||||||
|
wmove(pwin, 0, 0);
|
||||||
|
WADDSTR(pwin, msg);
|
||||||
|
WADDSTR(pwin, WIDE(" [y/N]? "));
|
||||||
|
wattroff(pwin, A_BOLD);
|
||||||
|
|
||||||
|
while (WGETCH(pwin, &c) == ERR
|
||||||
|
#ifdef KEY_RESIZE
|
||||||
|
|| (c == KEY_RESIZE)
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
return (c == 'Y' || c == 'y') ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WCHAR *
|
||||||
|
prompt(msg, def, hist)
|
||||||
|
const WCHAR *msg, *def;
|
||||||
|
history_t *hist;
|
||||||
|
{
|
||||||
|
WINDOW *pwin;
|
||||||
|
WCHAR input[256];
|
||||||
|
size_t pos = 0;
|
||||||
|
histent_t *histpos = NULL;
|
||||||
|
|
||||||
|
if (hist == NULL)
|
||||||
|
hist = prompthist;
|
||||||
|
|
||||||
|
memset(input, 0, sizeof(input));
|
||||||
|
if (def) {
|
||||||
|
STRNCPY(input, def, WSIZEOF(input) - 1);
|
||||||
|
pos = STRLEN(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
pwin = newwin(1, COLS, LINES - 2, 0);
|
||||||
|
keypad(pwin, TRUE);
|
||||||
|
|
||||||
|
wattr_on(pwin, style_fg(sy_status), NULL);
|
||||||
|
wbkgd(pwin, style_bg(sy_status));
|
||||||
|
|
||||||
|
wattron(pwin, A_BOLD);
|
||||||
|
wmove(pwin, 0, 0);
|
||||||
|
WADDSTR(pwin, msg);
|
||||||
|
wattroff(pwin, A_BOLD);
|
||||||
|
|
||||||
|
curs_set(1);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
INT c;
|
||||||
|
wmove(pwin, 0, STRLEN(msg) + 1);
|
||||||
|
WADDSTR(pwin, input);
|
||||||
|
wclrtoeol(pwin);
|
||||||
|
wmove(pwin, 0, STRLEN(msg) + 1 + pos);
|
||||||
|
wrefresh(pwin);
|
||||||
|
|
||||||
|
if (WGETCH(pwin, &c) == ERR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
case 0x7F:
|
||||||
|
case 0x08:
|
||||||
|
if (pos) {
|
||||||
|
if (pos == STRLEN(input))
|
||||||
|
input[--pos] = 0;
|
||||||
|
else {
|
||||||
|
int i = STRLEN(input);
|
||||||
|
pos--;
|
||||||
|
MEMCPY(input + pos, input + pos + 1, STRLEN(input) - pos);
|
||||||
|
input[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_DC:
|
||||||
|
if (pos < STRLEN(input)) {
|
||||||
|
int i = STRLEN(input);
|
||||||
|
MEMCPY(input + pos, input + pos + 1, STRLEN(input) - pos);
|
||||||
|
input[i] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_LEFT:
|
||||||
|
if (pos)
|
||||||
|
pos--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_RIGHT:
|
||||||
|
if (pos < STRLEN(input))
|
||||||
|
pos++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_HOME:
|
||||||
|
case 0x01: /* ^A */
|
||||||
|
pos = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_END:
|
||||||
|
case 0x05: /* ^E */
|
||||||
|
pos = STRLEN(input);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x07: /* ^G */
|
||||||
|
case 0x1B: /* ESC */
|
||||||
|
curs_set(0);
|
||||||
|
delwin(pwin);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
case 0x15: /* ^U */
|
||||||
|
input[0] = 0;
|
||||||
|
pos = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef KEY_RESIZE
|
||||||
|
case KEY_RESIZE:
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case KEY_UP:
|
||||||
|
if (histpos == NULL) {
|
||||||
|
if ((histpos = TAILQ_LAST(&hist->hi_ents, hentlist)) == NULL) {
|
||||||
|
beep();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (TAILQ_PREV(histpos, hentlist, he_entries) == NULL) {
|
||||||
|
beep();
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
histpos = TAILQ_PREV(histpos, hentlist, he_entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STRNCPY(input, histpos->he_text, WSIZEOF(input) - 1);
|
||||||
|
pos = STRLEN(input);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_DOWN:
|
||||||
|
if (histpos == NULL) {
|
||||||
|
beep();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TAILQ_NEXT(histpos, he_entries) == NULL) {
|
||||||
|
beep();
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
histpos = TAILQ_NEXT(histpos, he_entries);
|
||||||
|
|
||||||
|
|
||||||
|
STRNCPY(input, histpos->he_text, WSIZEOF(input) - 1);
|
||||||
|
pos = STRLEN(input);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (pos != STRLEN(input)) {
|
||||||
|
MEMMOVE(input + pos + 1, input + pos, STRLEN(input) - pos);
|
||||||
|
input[pos++] = c;
|
||||||
|
} else {
|
||||||
|
input[pos++] = c;
|
||||||
|
input[pos] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end: ;
|
||||||
|
|
||||||
|
curs_set(0);
|
||||||
|
delwin(pwin);
|
||||||
|
wtouchln(statwin, 1, 1, 1);
|
||||||
|
hist_add(hist, input);
|
||||||
|
return STRDUP(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue