Clean up various IntelliJ warnings
This commit is contained in:
parent
3f94629953
commit
05859a2e58
4 changed files with 58 additions and 81 deletions
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
Create a file: `~/forkalsrud.org/photo.properties` and for each named "root"
|
Create a file: `~/forkalsrud.org/photo.properties` and for each named "root"
|
||||||
(`photo` in the example below), point the `base` property and `dbdir` properties
|
(`photo` in the example below), point the `base` property and `dbdir` properties
|
||||||
to the direcory holding the photos, and the diractory to be populated with
|
to the directory holding the photos, and the directory to be populated with
|
||||||
BerkelyDB files to your photo folder:
|
BerkeleyDB files to your photo folder:
|
||||||
|
|
||||||
root.photo.base=/home/photo
|
root.photo.base=/home/photo
|
||||||
root.photo.dbdir=/home/resin/web/db
|
root.photo.dbdir=/home/resin/web/db
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,8 @@ import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.forkalsrud.album.db.DirectoryDatabase;
|
import org.forkalsrud.album.db.DirectoryDatabase;
|
||||||
|
|
@ -27,14 +24,14 @@ public class DirectoryEntry extends EntryWithChildren<Entry> {
|
||||||
|
|
||||||
public interface ServiceApi {
|
public interface ServiceApi {
|
||||||
|
|
||||||
public DirectoryDatabase getDirectoryDatabase();
|
DirectoryDatabase getDirectoryDatabase();
|
||||||
public DirectoryMetadataGenerator getMetadataGenerator();
|
DirectoryMetadataGenerator getMetadataGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceApi services;
|
ServiceApi services;
|
||||||
DirectoryProps cache;
|
DirectoryProps cache;
|
||||||
boolean childrenLoaded = false;
|
boolean childrenLoaded = false;
|
||||||
Comparator<Entry> sort = null;
|
Comparator<Entry> ordering = null;
|
||||||
Date earliest = null;
|
Date earliest = null;
|
||||||
boolean groupByYear;
|
boolean groupByYear;
|
||||||
|
|
||||||
|
|
@ -129,7 +126,7 @@ public class DirectoryEntry extends EntryWithChildren<Entry> {
|
||||||
|
|
||||||
private void sort() {
|
private void sort() {
|
||||||
|
|
||||||
Collections.sort(children, sort);
|
children.sort(ordering);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -139,28 +136,19 @@ public class DirectoryEntry extends EntryWithChildren<Entry> {
|
||||||
String coverFileName = props.getProperty("cover");
|
String coverFileName = props.getProperty("cover");
|
||||||
String caption = props.getProperty("caption");
|
String caption = props.getProperty("caption");
|
||||||
setCaption(caption);
|
setCaption(caption);
|
||||||
sort = ComparatorFactory.getSort(props.getProperty("sort"));
|
ordering = ComparatorFactory.getSort(props.getProperty("sort"));
|
||||||
|
|
||||||
HashMap<String, Entry> entryMap = new HashMap<String, Entry>();
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
||||||
|
|
||||||
Date oldest = new Date(file.lastModified());
|
for (String key : props.stringPropertyNames()) {
|
||||||
|
|
||||||
Iterator<Object> i = props.keySet().iterator();
|
|
||||||
while (i.hasNext()) {
|
|
||||||
String key = (String)i.next();
|
|
||||||
if (key.startsWith("file.") && key.endsWith(".dimensions")) {
|
if (key.startsWith("file.") && key.endsWith(".dimensions")) {
|
||||||
String name = key.substring("file.".length(), key.length() - ".dimensions".length());
|
String name = key.substring("file.".length(), key.length() - ".dimensions".length());
|
||||||
if (!entryMap.containsKey(name)) {
|
|
||||||
File f = new File(file, name);
|
File f = new File(file, name);
|
||||||
String type = props.getProperty("file." + name + ".type", "image");
|
String type = props.getProperty("file." + name + ".type", "image");
|
||||||
FileEntry entry = new FileEntry(this, f, type);
|
FileEntry entry = new FileEntry(this, f, type);
|
||||||
Thumbnail thumbnail = new Thumbnail(f, type);
|
Thumbnail thumbnail = new Thumbnail(f, type);
|
||||||
entry.setCaption(props.getProperty("file." + name + ".caption"));
|
entry.setCaption(props.getProperty("file." + name + ".caption"));
|
||||||
Date fileDate = sdf.parse(props.getProperty("file." + name + ".captureDate"));
|
Date fileDate = sdf.parse(props.getProperty("file." + name + ".captureDate"));
|
||||||
if (fileDate.before(oldest)) {
|
|
||||||
oldest = fileDate;
|
|
||||||
}
|
|
||||||
entry.setDate(fileDate);
|
entry.setDate(fileDate);
|
||||||
thumbnail.setSize(new Dimension(props.getProperty("file." + name + ".dimensions")));
|
thumbnail.setSize(new Dimension(props.getProperty("file." + name + ".dimensions")));
|
||||||
thumbnail.setOrientation(Integer.parseInt(props.getProperty("file." + name + ".orientation")));
|
thumbnail.setOrientation(Integer.parseInt(props.getProperty("file." + name + ".orientation")));
|
||||||
|
|
@ -177,7 +165,6 @@ public class DirectoryEntry extends EntryWithChildren<Entry> {
|
||||||
if (duration != null) {
|
if (duration != null) {
|
||||||
thumbnail.setDuration(duration);
|
thumbnail.setDuration(duration);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (key.startsWith("dir.") && !key.endsWith(".hidden") && !key.endsWith(".caption")) {
|
} else if (key.startsWith("dir.") && !key.endsWith(".hidden") && !key.endsWith(".caption")) {
|
||||||
String name = key.substring("dir.".length());
|
String name = key.substring("dir.".length());
|
||||||
boolean hidden = Boolean.parseBoolean(props.getProperty("dir." + name + ".hidden"));
|
boolean hidden = Boolean.parseBoolean(props.getProperty("dir." + name + ".hidden"));
|
||||||
|
|
@ -187,9 +174,7 @@ public class DirectoryEntry extends EntryWithChildren<Entry> {
|
||||||
setThumbnail(dir.getThumbnail());
|
setThumbnail(dir.getThumbnail());
|
||||||
}
|
}
|
||||||
Date fileDate = dir.getEarliest();
|
Date fileDate = dir.getEarliest();
|
||||||
if (fileDate != null && fileDate.before(oldest)) {
|
dir.setDate(fileDate);
|
||||||
oldest = fileDate;
|
|
||||||
}
|
|
||||||
dir.setCaption(props.getProperty("dir." + name + ".caption"));
|
dir.setCaption(props.getProperty("dir." + name + ".caption"));
|
||||||
if (!dir.getContents().isEmpty()) {
|
if (!dir.getContents().isEmpty()) {
|
||||||
children.add(dir);
|
children.add(dir);
|
||||||
|
|
@ -197,7 +182,10 @@ public class DirectoryEntry extends EntryWithChildren<Entry> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.earliest = oldest;
|
this.earliest = children.stream()
|
||||||
|
.map(Entry::getDate)
|
||||||
|
.min(Date::compareTo)
|
||||||
|
.orElse(new Date(file.lastModified()));
|
||||||
this.groupByYear = "year".equalsIgnoreCase(props.getProperty("group"));
|
this.groupByYear = "year".equalsIgnoreCase(props.getProperty("group"));
|
||||||
if (thumbnail == null && !children.isEmpty()) {
|
if (thumbnail == null && !children.isEmpty()) {
|
||||||
setThumbnail(children.get(0).getThumbnail());
|
setThumbnail(children.get(0).getThumbnail());
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ package org.forkalsrud.album.video;
|
||||||
|
|
||||||
public interface EncodingProcessListener {
|
public interface EncodingProcessListener {
|
||||||
|
|
||||||
public abstract void chunkAvailable(int chunkNo);
|
void chunkAvailable(int chunkNo);
|
||||||
|
|
||||||
public abstract void codingFinished(int lastCunkNo);
|
void codingFinished(int lastChunkNo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ import com.sleepycat.je.EnvironmentConfig;
|
||||||
public class AlbumServlet
|
public class AlbumServlet
|
||||||
extends HttpServlet
|
extends HttpServlet
|
||||||
{
|
{
|
||||||
private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AlbumServlet.class);
|
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AlbumServlet.class);
|
||||||
|
|
||||||
static void addDummyLoggerFor(String... names) {
|
static void addDummyLoggerFor(String... names) {
|
||||||
for (String name : names)
|
for (String name : names)
|
||||||
|
|
@ -72,7 +72,6 @@ public class AlbumServlet
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
hh = ll.getHandlers();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
@ -95,9 +94,9 @@ public class AlbumServlet
|
||||||
* maps files to URIs relative to servlet, e.g. /home/joe/photos/holiday/arrival.jpg -> /photos/holiday/arrival.jpg
|
* maps files to URIs relative to servlet, e.g. /home/joe/photos/holiday/arrival.jpg -> /photos/holiday/arrival.jpg
|
||||||
* assuming base is /home/joe/photos
|
* assuming base is /home/joe/photos
|
||||||
*/
|
*/
|
||||||
public class Mapper {
|
public static class Mapper {
|
||||||
|
|
||||||
private File base;
|
private final File base;
|
||||||
|
|
||||||
public Mapper(File base) {
|
public Mapper(File base) {
|
||||||
this.base = base;
|
this.base = base;
|
||||||
|
|
@ -108,7 +107,7 @@ public class AlbumServlet
|
||||||
return appendFile(buf, file).toString();
|
return appendFile(buf, file).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder appendFile(StringBuilder buf, File file) {
|
private StringBuilder appendFile(StringBuilder buf, File file) {
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
@ -118,16 +117,6 @@ public class AlbumServlet
|
||||||
return appendFile(buf, file.getParentFile()).append('/').append(file.getName());
|
return appendFile(buf, file.getParentFile()).append('/').append(file.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Calendar cal = Calendar.getInstance();
|
|
||||||
|
|
||||||
public String year(Date d) {
|
|
||||||
if (d == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
cal.setTime(d);
|
|
||||||
return String.valueOf(cal.get(Calendar.YEAR));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -138,7 +127,7 @@ public class AlbumServlet
|
||||||
String basePrefix;
|
String basePrefix;
|
||||||
DirectoryEntryFactory dirEntryFactory;
|
DirectoryEntryFactory dirEntryFactory;
|
||||||
|
|
||||||
private Environment environment;
|
private final Environment environment;
|
||||||
ThumbnailDatabase thumbDb;
|
ThumbnailDatabase thumbDb;
|
||||||
DirectoryDatabase dirDb;
|
DirectoryDatabase dirDb;
|
||||||
MovieDatabase movieDb;
|
MovieDatabase movieDb;
|
||||||
|
|
@ -219,8 +208,8 @@ public class AlbumServlet
|
||||||
res.setContentType("text/html");
|
res.setContentType("text/html");
|
||||||
req.setAttribute("search", query);
|
req.setAttribute("search", query);
|
||||||
req.setAttribute("entry", results);
|
req.setAttribute("entry", results);
|
||||||
req.setAttribute("thmb", new Integer(250));
|
req.setAttribute("thmb", 250);
|
||||||
req.setAttribute("full", new Integer(800));
|
req.setAttribute("full", 800);
|
||||||
RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/velocity/photo.vm");
|
RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/velocity/photo.vm");
|
||||||
rd.forward(req, res);
|
rd.forward(req, res);
|
||||||
}
|
}
|
||||||
|
|
@ -229,7 +218,7 @@ public class AlbumServlet
|
||||||
void handlePhoto(HttpServletRequest req, HttpServletResponse res, FileEntry entry) throws Exception {
|
void handlePhoto(HttpServletRequest req, HttpServletResponse res, FileEntry entry) throws Exception {
|
||||||
res.setContentType("text/html");
|
res.setContentType("text/html");
|
||||||
req.setAttribute("entry", entry);
|
req.setAttribute("entry", entry);
|
||||||
req.setAttribute("thmb", new Integer(800));
|
req.setAttribute("thmb", 800);
|
||||||
RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/velocity/photo.vm");
|
RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/velocity/photo.vm");
|
||||||
rd.forward(req, res);
|
rd.forward(req, res);
|
||||||
}
|
}
|
||||||
|
|
@ -237,20 +226,20 @@ public class AlbumServlet
|
||||||
void handleAlbum(HttpServletRequest req, HttpServletResponse res, DirectoryEntry entry) throws Exception {
|
void handleAlbum(HttpServletRequest req, HttpServletResponse res, DirectoryEntry entry) throws Exception {
|
||||||
res.setContentType("text/html");
|
res.setContentType("text/html");
|
||||||
req.setAttribute("entry", entry);
|
req.setAttribute("entry", entry);
|
||||||
req.setAttribute("thmb", new Integer(250));
|
req.setAttribute("thmb", 250);
|
||||||
req.setAttribute("full", new Integer(800));
|
req.setAttribute("full", 800);
|
||||||
req.setAttribute("D", "$");
|
req.setAttribute("D", "$");
|
||||||
RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/ng.html");
|
RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/ng.html");
|
||||||
rd.forward(req, res);
|
rd.forward(req, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleMovieFrame(HttpServletRequest req, HttpServletResponse res, FileEntry entry) throws Exception {
|
void handleMovieFrame(HttpServletRequest req, HttpServletResponse res, FileEntry entry) {
|
||||||
|
|
||||||
File file = entry.getPath();
|
File file = entry.getPath();
|
||||||
if (notModified(req, file)) {
|
if (notModified(req, file)) {
|
||||||
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||||
res.setDateHeader("Expires", System.currentTimeMillis() + (30 * 24 * 3600 * 1000L)); // 30 days
|
res.setDateHeader("Expires", System.currentTimeMillis() + (30 * 24 * 3600 * 1000L)); // 30 days
|
||||||
log.info(file.getName() + " not modified (based on date)");
|
log.info("{} not modified (based on date)", file.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int secondNo = 3;
|
int secondNo = 3;
|
||||||
|
|
@ -265,7 +254,7 @@ public class AlbumServlet
|
||||||
if (cimg.lastModified >= fileTs) {
|
if (cimg.lastModified >= fileTs) {
|
||||||
// log.info("cache hit on " + key);
|
// log.info("cache hit on " + key);
|
||||||
} else {
|
} else {
|
||||||
log.info(" " + key + " has changed so cache entry wil be refreshed");
|
log.info(" {} has changed so cache entry wil be refreshed", key);
|
||||||
cimg = null;
|
cimg = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -273,7 +262,7 @@ public class AlbumServlet
|
||||||
try {
|
try {
|
||||||
cimg = movieCoder.extractFrame(file, secondNo, entry.getThumbnail(), size);
|
cimg = movieCoder.extractFrame(file, secondNo, entry.getThumbnail(), size);
|
||||||
thumbDb.store(key, cimg);
|
thumbDb.store(key, cimg);
|
||||||
log.info(" " + key + " added to the cache with size " + cimg.bits.length + " -- now " + thumbDb.size() + " entries");
|
log.info(" {} added to the cache with size {} -- now {} entries", key, cimg.bits.length, thumbDb.size());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
//e.fillInStackTrace();
|
//e.fillInStackTrace();
|
||||||
throw new RuntimeException("sadness", e);
|
throw new RuntimeException("sadness", e);
|
||||||
|
|
@ -297,7 +286,7 @@ public class AlbumServlet
|
||||||
if (notModified(req, file)) {
|
if (notModified(req, file)) {
|
||||||
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||||
res.setDateHeader("Expires", System.currentTimeMillis() + (30 * 24 * 3600 * 1000L)); // 30 days
|
res.setDateHeader("Expires", System.currentTimeMillis() + (30 * 24 * 3600 * 1000L)); // 30 days
|
||||||
log.info(file.getName() + " not modified (based on date)");
|
log.info("{} not modified (based on date)", file.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
@ -429,7 +418,7 @@ public class AlbumServlet
|
||||||
}
|
}
|
||||||
res.setContentType("text/html");
|
res.setContentType("text/html");
|
||||||
req.setAttribute("entry", entry);
|
req.setAttribute("entry", entry);
|
||||||
req.setAttribute("thmb", new Integer(640));
|
req.setAttribute("thmb", 640);
|
||||||
RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/velocity/edit.vm");
|
RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/velocity/edit.vm");
|
||||||
rd.forward(req, res);
|
rd.forward(req, res);
|
||||||
}
|
}
|
||||||
|
|
@ -443,14 +432,14 @@ public class AlbumServlet
|
||||||
if (notModified(req, file)) {
|
if (notModified(req, file)) {
|
||||||
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||||
res.setDateHeader("Expires", System.currentTimeMillis() + (30 * 24 * 3600 * 1000L)); // 30 days
|
res.setDateHeader("Expires", System.currentTimeMillis() + (30 * 24 * 3600 * 1000L)); // 30 days
|
||||||
log.info(file.getName() + " not modified (based on date)");
|
log.info("{} not modified (based on date)", file.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String fileEtag = thumbnail.getEtag() + "-" + size;
|
String fileEtag = thumbnail.getEtag() + "-" + size;
|
||||||
if (etagMatches(req, fileEtag)) {
|
if (etagMatches(req, fileEtag)) {
|
||||||
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
||||||
res.setDateHeader("Expires", System.currentTimeMillis() + (30 * 24 * 3600 * 1000L)); // 30 days
|
res.setDateHeader("Expires", System.currentTimeMillis() + (30 * 24 * 3600 * 1000L)); // 30 days
|
||||||
log.info(file.getName() + " not modified (based on etag)");
|
log.info("{} not modified (based on etag)", file.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,7 +450,7 @@ public class AlbumServlet
|
||||||
if (cimg.lastModified == file.lastModified()) {
|
if (cimg.lastModified == file.lastModified()) {
|
||||||
// log.info("cache hit on " + key);
|
// log.info("cache hit on " + key);
|
||||||
} else {
|
} else {
|
||||||
log.info(" " + key + " has changed so cache entry wil be refreshed");
|
log.info(" {} has changed so cache entry wil be refreshed", key);
|
||||||
cimg = null;
|
cimg = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -469,7 +458,7 @@ public class AlbumServlet
|
||||||
cimg = pictureScaler.scalePicture(file, thumbnail, size);
|
cimg = pictureScaler.scalePicture(file, thumbnail, size);
|
||||||
thumbDb.store(key, cimg);
|
thumbDb.store(key, cimg);
|
||||||
int byteSize = cimg.bits != null ? cimg.bits.length : 0;
|
int byteSize = cimg.bits != null ? cimg.bits.length : 0;
|
||||||
log.info(" " + key + " added to the cache with size " + byteSize + " -- now " + thumbDb.size() + " entries");
|
log.info(" {} added to the cache with size {} -- now {} entries", key, byteSize, thumbDb.size());
|
||||||
}
|
}
|
||||||
res.setStatus(HttpServletResponse.SC_OK);
|
res.setStatus(HttpServletResponse.SC_OK);
|
||||||
res.setDateHeader("Last-Modified", file.lastModified());
|
res.setDateHeader("Last-Modified", file.lastModified());
|
||||||
|
|
@ -483,7 +472,7 @@ public class AlbumServlet
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Map<String, Root> roots = new HashMap<String, Root>();
|
Map<String, Root> roots = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
PictureScaler pictureScaler;
|
PictureScaler pictureScaler;
|
||||||
|
|
@ -570,7 +559,7 @@ public class AlbumServlet
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
log.info("Shutting down Album");
|
log.info("Shutting down Album");
|
||||||
roots.values().forEach(r -> r.close());
|
roots.values().forEach(Root::close);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -627,7 +616,7 @@ public class AlbumServlet
|
||||||
|
|
||||||
ObjectMapper json = new ObjectMapper();
|
ObjectMapper json = new ObjectMapper();
|
||||||
ArrayNode arr = json.createArrayNode();
|
ArrayNode arr = json.createArrayNode();
|
||||||
roots.values().stream().map(r -> r.getName()).forEach(arr::add);
|
roots.values().stream().map(Root::getName).forEach(arr::add);
|
||||||
json.writeValue(res.getOutputStream(), arr);
|
json.writeValue(res.getOutputStream(), arr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue