2019-11-01 14:33:11 -04:00
|
|
|
import org.elasticsearch.gradle.info.BuildParams
|
|
|
|
|
2015-10-29 14:40:19 -04:00
|
|
|
/*
|
|
|
|
* Licensed to Elasticsearch under one or more contributor
|
|
|
|
* license agreements. See the NOTICE file distributed with
|
|
|
|
* this work for additional information regarding copyright
|
|
|
|
* ownership. Elasticsearch licenses this file to you under
|
|
|
|
* the Apache License, Version 2.0 (the "License"); you may
|
|
|
|
* not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing,
|
|
|
|
* software distributed under the License is distributed on an
|
|
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
|
* KIND, either express or implied. See the License for the
|
|
|
|
* specific language governing permissions and limitations
|
|
|
|
* under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
apply plugin: 'elasticsearch.build'
|
|
|
|
apply plugin: 'nebula.optional-base'
|
2016-05-05 20:53:01 -04:00
|
|
|
apply plugin: 'nebula.maven-base-publish'
|
|
|
|
|
|
|
|
publishing {
|
|
|
|
publications {
|
|
|
|
nebula {
|
|
|
|
artifactId 'elasticsearch'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-10-29 14:40:19 -04:00
|
|
|
|
2016-03-17 16:35:16 -04:00
|
|
|
archivesBaseName = 'elasticsearch'
|
2015-10-29 14:40:19 -04:00
|
|
|
|
2020-03-31 07:48:46 -04:00
|
|
|
// we want to keep the JDKs in our IDEs set to JDK 8 until minimum JDK is bumped to 11 so we do not include this source set in our IDEs
|
2020-03-19 14:43:33 -04:00
|
|
|
if (!isEclipse) {
|
2018-01-16 15:10:29 -05:00
|
|
|
sourceSets {
|
2020-03-31 07:48:46 -04:00
|
|
|
java11 {
|
2018-01-16 15:10:29 -05:00
|
|
|
java {
|
2020-03-31 07:48:46 -04:00
|
|
|
srcDirs = ['src/main/java11']
|
2018-01-16 15:10:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-11-14 06:01:23 -05:00
|
|
|
|
2018-04-03 13:22:12 -04:00
|
|
|
configurations {
|
2020-03-31 07:48:46 -04:00
|
|
|
java11Compile.extendsFrom(compile)
|
2018-04-03 13:22:12 -04:00
|
|
|
}
|
2019-11-14 06:01:23 -05:00
|
|
|
|
2018-04-03 13:22:12 -04:00
|
|
|
dependencies {
|
2020-03-31 07:48:46 -04:00
|
|
|
java11Compile sourceSets.main.output
|
2018-04-03 13:22:12 -04:00
|
|
|
}
|
2018-01-16 15:10:29 -05:00
|
|
|
|
2020-03-31 07:48:46 -04:00
|
|
|
compileJava11Java {
|
|
|
|
sourceCompatibility = 11
|
|
|
|
targetCompatibility = 11
|
2018-01-16 15:10:29 -05:00
|
|
|
}
|
2018-08-31 02:31:55 -04:00
|
|
|
|
2020-04-15 16:23:55 -04:00
|
|
|
tasks.named('forbiddenApisJava11').configure {
|
2019-05-30 13:29:42 -04:00
|
|
|
doFirst {
|
2020-03-31 07:48:46 -04:00
|
|
|
if (BuildParams.runtimeJavaVersion < JavaVersion.VERSION_11) {
|
|
|
|
targetCompatibility = JavaVersion.VERSION_11.getMajorVersion()
|
2019-05-30 13:29:42 -04:00
|
|
|
}
|
2018-08-31 02:31:55 -04:00
|
|
|
}
|
2018-04-03 13:22:12 -04:00
|
|
|
}
|
2018-01-16 15:10:29 -05:00
|
|
|
|
|
|
|
jar {
|
2018-04-03 13:22:12 -04:00
|
|
|
metaInf {
|
2020-03-31 07:48:46 -04:00
|
|
|
into 'versions/11'
|
|
|
|
from sourceSets.java11.output
|
2018-01-16 15:10:29 -05:00
|
|
|
}
|
|
|
|
manifest.attributes('Multi-Release': 'true')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-29 14:40:19 -04:00
|
|
|
dependencies {
|
|
|
|
|
2019-06-04 16:50:23 -04:00
|
|
|
compile project(':libs:elasticsearch-core')
|
|
|
|
compile project(':libs:elasticsearch-secure-sm')
|
|
|
|
compile project(':libs:elasticsearch-x-content')
|
|
|
|
compile project(":libs:elasticsearch-geo")
|
2019-10-03 03:50:46 -04:00
|
|
|
|
2019-06-04 16:50:23 -04:00
|
|
|
compileOnly project(':libs:elasticsearch-plugin-classloader')
|
2020-03-19 14:43:33 -04:00
|
|
|
testRuntimeOnly project(':libs:elasticsearch-plugin-classloader')
|
2018-01-03 14:12:43 -05:00
|
|
|
|
2015-10-29 14:40:19 -04:00
|
|
|
// lucene
|
|
|
|
compile "org.apache.lucene:lucene-core:${versions.lucene}"
|
|
|
|
compile "org.apache.lucene:lucene-analyzers-common:${versions.lucene}"
|
2015-11-10 17:58:46 -05:00
|
|
|
compile "org.apache.lucene:lucene-backward-codecs:${versions.lucene}"
|
|
|
|
compile "org.apache.lucene:lucene-grouping:${versions.lucene}"
|
2015-10-29 14:40:19 -04:00
|
|
|
compile "org.apache.lucene:lucene-highlighter:${versions.lucene}"
|
|
|
|
compile "org.apache.lucene:lucene-join:${versions.lucene}"
|
2015-11-10 17:58:46 -05:00
|
|
|
compile "org.apache.lucene:lucene-memory:${versions.lucene}"
|
|
|
|
compile "org.apache.lucene:lucene-misc:${versions.lucene}"
|
|
|
|
compile "org.apache.lucene:lucene-queries:${versions.lucene}"
|
|
|
|
compile "org.apache.lucene:lucene-queryparser:${versions.lucene}"
|
|
|
|
compile "org.apache.lucene:lucene-sandbox:${versions.lucene}"
|
2016-03-07 04:12:23 -05:00
|
|
|
compile "org.apache.lucene:lucene-spatial-extras:${versions.lucene}"
|
2015-11-10 17:58:46 -05:00
|
|
|
compile "org.apache.lucene:lucene-spatial3d:${versions.lucene}"
|
|
|
|
compile "org.apache.lucene:lucene-suggest:${versions.lucene}"
|
2015-10-29 14:40:19 -04:00
|
|
|
|
|
|
|
// utilities
|
2019-06-04 16:50:23 -04:00
|
|
|
compile project(":libs:elasticsearch-cli")
|
2019-06-12 06:42:01 -04:00
|
|
|
compile 'com.carrotsearch:hppc:0.8.1'
|
2015-10-29 14:40:19 -04:00
|
|
|
|
|
|
|
// time handling, remove with java 8 time
|
2018-11-12 04:02:41 -05:00
|
|
|
compile "joda-time:joda-time:${versions.joda}"
|
2015-10-29 14:40:19 -04:00
|
|
|
|
|
|
|
// percentiles aggregation
|
2018-02-15 03:23:20 -05:00
|
|
|
compile 'com.tdunning:t-digest:3.2'
|
2015-10-29 14:40:19 -04:00
|
|
|
// precentil ranks aggregation
|
2017-02-21 02:50:26 -05:00
|
|
|
compile 'org.hdrhistogram:HdrHistogram:2.1.9'
|
2015-10-29 14:40:19 -04:00
|
|
|
|
|
|
|
// lucene spatial
|
2016-03-07 04:12:23 -05:00
|
|
|
compile "org.locationtech.spatial4j:spatial4j:${versions.spatial4j}", optional
|
2018-04-03 03:27:14 -04:00
|
|
|
compile "org.locationtech.jts:jts-core:${versions.jts}", optional
|
2015-10-29 14:40:19 -04:00
|
|
|
|
|
|
|
// logging
|
2017-06-08 16:09:34 -04:00
|
|
|
compile "org.apache.logging.log4j:log4j-api:${versions.log4j}"
|
2016-08-09 13:34:23 -04:00
|
|
|
compile "org.apache.logging.log4j:log4j-core:${versions.log4j}", optional
|
2015-10-29 14:40:19 -04:00
|
|
|
|
2017-04-13 03:17:50 -04:00
|
|
|
// repackaged jna with native bits linked against all elastic supported platforms
|
|
|
|
compile "org.elasticsearch:jna:${versions.jna}"
|
2015-10-29 14:40:19 -04:00
|
|
|
|
2020-03-19 14:43:33 -04:00
|
|
|
if (!isEclipse) {
|
2020-03-31 07:48:46 -04:00
|
|
|
java11Compile sourceSets.main.output
|
2018-01-16 15:10:29 -05:00
|
|
|
}
|
|
|
|
|
2019-10-03 03:50:46 -04:00
|
|
|
testCompile(project(":test:framework")) {
|
|
|
|
// tests use the locally compiled version of server
|
|
|
|
exclude group: 'org.elasticsearch', module: 'server'
|
2015-11-05 01:28:57 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-05 02:01:56 -04:00
|
|
|
compileJava.options.compilerArgs << "-Xlint:-cast,-rawtypes,-unchecked"
|
|
|
|
compileTestJava.options.compilerArgs << "-Xlint:-cast,-rawtypes,-unchecked"
|
2015-10-29 14:40:19 -04:00
|
|
|
|
2019-11-11 09:33:04 -05:00
|
|
|
// Until this project is always being formatted with spotless, we need to
|
|
|
|
// guard against `spotless()` not existing.
|
|
|
|
try {
|
|
|
|
spotless {
|
|
|
|
java {
|
|
|
|
// Contains large data tables that do not format well.
|
|
|
|
targetExclude 'src/main/java/org/elasticsearch/search/aggregations/metrics/HyperLogLogPlusPlus.java'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
if (e.getMessage().contains("Could not find method spotless") == false) {
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-29 14:40:19 -04:00
|
|
|
forbiddenPatterns {
|
|
|
|
exclude '**/*.json'
|
|
|
|
exclude '**/*.jmx'
|
2018-12-11 07:15:44 -05:00
|
|
|
exclude '**/*.dic'
|
|
|
|
exclude '**/*.binary'
|
|
|
|
exclude '**/*.st'
|
2015-10-29 14:40:19 -04:00
|
|
|
}
|
|
|
|
|
2019-01-08 06:39:03 -05:00
|
|
|
testingConventions {
|
|
|
|
naming.clear()
|
|
|
|
naming {
|
|
|
|
Tests {
|
|
|
|
baseClass "org.apache.lucene.util.LuceneTestCase"
|
|
|
|
}
|
|
|
|
IT {
|
|
|
|
baseClass "org.elasticsearch.test.ESIntegTestCase"
|
|
|
|
baseClass "org.elasticsearch.test.ESSingleNodeTestCase"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-25 16:31:04 -04:00
|
|
|
task generateModulesList {
|
|
|
|
List<String> modules = project(':modules').subprojects.collect { it.name }
|
2018-02-23 11:03:17 -05:00
|
|
|
modules.add('x-pack')
|
2016-05-25 16:31:04 -04:00
|
|
|
File modulesFile = new File(buildDir, 'generated-resources/modules.txt')
|
2017-05-18 09:33:13 -04:00
|
|
|
processResources.from(modulesFile)
|
|
|
|
inputs.property('modules', modules)
|
2016-05-25 16:31:04 -04:00
|
|
|
outputs.file(modulesFile)
|
|
|
|
doLast {
|
|
|
|
modulesFile.parentFile.mkdirs()
|
|
|
|
modulesFile.setText(modules.join('\n'), 'UTF-8')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
task generatePluginsList {
|
2018-11-19 10:17:05 -05:00
|
|
|
Set<String> plugins = new TreeSet<>(project(':plugins').childProjects.keySet())
|
|
|
|
plugins.remove('example')
|
|
|
|
|
2016-05-25 16:31:04 -04:00
|
|
|
File pluginsFile = new File(buildDir, 'generated-resources/plugins.txt')
|
2017-05-18 09:33:13 -04:00
|
|
|
processResources.from(pluginsFile)
|
|
|
|
inputs.property('plugins', plugins)
|
2016-05-25 16:31:04 -04:00
|
|
|
outputs.file(pluginsFile)
|
|
|
|
doLast {
|
|
|
|
pluginsFile.parentFile.mkdirs()
|
|
|
|
pluginsFile.setText(plugins.join('\n'), 'UTF-8')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
processResources {
|
|
|
|
dependsOn generateModulesList, generatePluginsList
|
|
|
|
}
|
|
|
|
|
2019-11-14 06:01:23 -05:00
|
|
|
thirdPartyAudit.ignoreMissingClasses(
|
2015-12-28 22:38:55 -05:00
|
|
|
// from com.fasterxml.jackson.dataformat.yaml.YAMLMapper (jackson-dataformat-yaml)
|
2016-08-09 13:34:23 -04:00
|
|
|
'com.fasterxml.jackson.databind.ObjectMapper',
|
|
|
|
|
|
|
|
// from log4j
|
2016-10-07 14:05:30 -04:00
|
|
|
'com.conversantmedia.util.concurrent.DisruptorBlockingQueue',
|
|
|
|
'com.conversantmedia.util.concurrent.SpinPolicy',
|
2016-08-09 13:34:23 -04:00
|
|
|
'com.fasterxml.jackson.annotation.JsonInclude$Include',
|
|
|
|
'com.fasterxml.jackson.databind.DeserializationContext',
|
2017-08-31 09:54:35 -04:00
|
|
|
'com.fasterxml.jackson.databind.DeserializationFeature',
|
2016-08-09 13:34:23 -04:00
|
|
|
'com.fasterxml.jackson.databind.JsonMappingException',
|
|
|
|
'com.fasterxml.jackson.databind.JsonNode',
|
|
|
|
'com.fasterxml.jackson.databind.Module$SetupContext',
|
|
|
|
'com.fasterxml.jackson.databind.ObjectReader',
|
|
|
|
'com.fasterxml.jackson.databind.ObjectWriter',
|
|
|
|
'com.fasterxml.jackson.databind.SerializerProvider',
|
|
|
|
'com.fasterxml.jackson.databind.deser.std.StdDeserializer',
|
|
|
|
'com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer',
|
|
|
|
'com.fasterxml.jackson.databind.module.SimpleModule',
|
|
|
|
'com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter',
|
|
|
|
'com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider',
|
|
|
|
'com.fasterxml.jackson.databind.ser.std.StdScalarSerializer',
|
|
|
|
'com.fasterxml.jackson.databind.ser.std.StdSerializer',
|
|
|
|
'com.fasterxml.jackson.dataformat.xml.JacksonXmlModule',
|
|
|
|
'com.fasterxml.jackson.dataformat.xml.XmlMapper',
|
|
|
|
'com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter',
|
2016-10-07 14:05:30 -04:00
|
|
|
'com.fasterxml.jackson.databind.node.ObjectNode',
|
|
|
|
'org.fusesource.jansi.Ansi',
|
|
|
|
'org.fusesource.jansi.AnsiRenderer$Code',
|
2016-08-09 13:34:23 -04:00
|
|
|
'com.lmax.disruptor.BlockingWaitStrategy',
|
|
|
|
'com.lmax.disruptor.BusySpinWaitStrategy',
|
|
|
|
'com.lmax.disruptor.EventFactory',
|
|
|
|
'com.lmax.disruptor.EventTranslator',
|
|
|
|
'com.lmax.disruptor.EventTranslatorTwoArg',
|
|
|
|
'com.lmax.disruptor.EventTranslatorVararg',
|
|
|
|
'com.lmax.disruptor.ExceptionHandler',
|
|
|
|
'com.lmax.disruptor.LifecycleAware',
|
|
|
|
'com.lmax.disruptor.RingBuffer',
|
|
|
|
'com.lmax.disruptor.Sequence',
|
|
|
|
'com.lmax.disruptor.SequenceReportingEventHandler',
|
|
|
|
'com.lmax.disruptor.SleepingWaitStrategy',
|
|
|
|
'com.lmax.disruptor.TimeoutBlockingWaitStrategy',
|
|
|
|
'com.lmax.disruptor.WaitStrategy',
|
|
|
|
'com.lmax.disruptor.YieldingWaitStrategy',
|
|
|
|
'com.lmax.disruptor.dsl.Disruptor',
|
|
|
|
'com.lmax.disruptor.dsl.ProducerType',
|
|
|
|
'javax.jms.Connection',
|
|
|
|
'javax.jms.ConnectionFactory',
|
|
|
|
'javax.jms.Destination',
|
2017-08-31 09:54:35 -04:00
|
|
|
'javax.jms.JMSException',
|
|
|
|
'javax.jms.MapMessage',
|
2016-08-09 13:34:23 -04:00
|
|
|
'javax.jms.Message',
|
|
|
|
'javax.jms.MessageConsumer',
|
|
|
|
'javax.jms.MessageProducer',
|
|
|
|
'javax.jms.Session',
|
|
|
|
'javax.mail.Authenticator',
|
|
|
|
'javax.mail.Message$RecipientType',
|
|
|
|
'javax.mail.PasswordAuthentication',
|
|
|
|
'javax.mail.Session',
|
|
|
|
'javax.mail.Transport',
|
|
|
|
'javax.mail.internet.InternetAddress',
|
|
|
|
'javax.mail.internet.InternetHeaders',
|
|
|
|
'javax.mail.internet.MimeBodyPart',
|
|
|
|
'javax.mail.internet.MimeMessage',
|
|
|
|
'javax.mail.internet.MimeMultipart',
|
|
|
|
'javax.mail.internet.MimeUtility',
|
|
|
|
'javax.mail.util.ByteArrayDataSource',
|
|
|
|
'org.apache.commons.compress.compressors.CompressorStreamFactory',
|
|
|
|
'org.apache.commons.compress.utils.IOUtils',
|
|
|
|
'org.apache.commons.csv.CSVFormat',
|
|
|
|
'org.apache.commons.csv.QuoteMode',
|
2017-04-09 07:19:16 -04:00
|
|
|
'org.apache.kafka.clients.producer.Callback',
|
2016-08-09 13:34:23 -04:00
|
|
|
'org.apache.kafka.clients.producer.KafkaProducer',
|
|
|
|
'org.apache.kafka.clients.producer.Producer',
|
|
|
|
'org.apache.kafka.clients.producer.ProducerRecord',
|
2017-04-09 07:19:16 -04:00
|
|
|
'org.apache.kafka.clients.producer.RecordMetadata',
|
2016-08-09 13:34:23 -04:00
|
|
|
'org.codehaus.stax2.XMLStreamWriter2',
|
2016-10-07 14:05:30 -04:00
|
|
|
'org.jctools.queues.MessagePassingQueue$Consumer',
|
|
|
|
'org.jctools.queues.MpscArrayQueue',
|
2016-08-09 13:34:23 -04:00
|
|
|
'org.osgi.framework.AdaptPermission',
|
|
|
|
'org.osgi.framework.AdminPermission',
|
|
|
|
'org.osgi.framework.Bundle',
|
|
|
|
'org.osgi.framework.BundleActivator',
|
|
|
|
'org.osgi.framework.BundleContext',
|
|
|
|
'org.osgi.framework.BundleEvent',
|
|
|
|
'org.osgi.framework.BundleReference',
|
|
|
|
'org.osgi.framework.FrameworkUtil',
|
2017-08-31 09:54:35 -04:00
|
|
|
'org.osgi.framework.ServiceRegistration',
|
2016-08-09 13:34:23 -04:00
|
|
|
'org.osgi.framework.SynchronousBundleListener',
|
|
|
|
'org.osgi.framework.wiring.BundleWire',
|
|
|
|
'org.osgi.framework.wiring.BundleWiring',
|
|
|
|
'org.zeromq.ZMQ$Context',
|
|
|
|
'org.zeromq.ZMQ$Socket',
|
|
|
|
'org.zeromq.ZMQ',
|
|
|
|
|
2016-03-07 04:12:23 -05:00
|
|
|
// from org.locationtech.spatial4j.io.GeoJSONReader (spatial4j)
|
2017-05-18 09:33:13 -04:00
|
|
|
'org.noggit.JSONParser',
|
2018-04-03 03:27:14 -04:00
|
|
|
|
|
|
|
// from lucene-spatial
|
|
|
|
'com.fasterxml.jackson.databind.JsonSerializer',
|
|
|
|
'com.fasterxml.jackson.databind.JsonDeserializer',
|
|
|
|
'com.fasterxml.jackson.databind.node.ArrayNode',
|
|
|
|
'com.google.common.geometry.S2Cell',
|
|
|
|
'com.google.common.geometry.S2CellId',
|
|
|
|
'com.google.common.geometry.S2Projections',
|
|
|
|
'com.google.common.geometry.S2Point',
|
|
|
|
'com.google.common.geometry.S2$Metric',
|
2019-01-07 10:24:19 -05:00
|
|
|
'com.google.common.geometry.S2LatLng'
|
|
|
|
)
|
2015-12-16 16:38:16 -05:00
|
|
|
|
2020-03-23 18:30:10 -04:00
|
|
|
if (BuildParams.runtimeJavaVersion > JavaVersion.VERSION_1_8) {
|
|
|
|
thirdPartyAudit.ignoreMissingClasses 'javax.xml.bind.DatatypeConverter'
|
2017-07-27 10:14:04 -04:00
|
|
|
}
|
|
|
|
|
2016-11-07 18:29:35 -05:00
|
|
|
dependencyLicenses {
|
|
|
|
mapping from: /lucene-.*/, to: 'lucene'
|
2017-11-18 22:42:57 -05:00
|
|
|
dependencies = project.configurations.runtime.fileCollection {
|
|
|
|
it.group.startsWith('org.elasticsearch') == false ||
|
2019-11-14 06:01:23 -05:00
|
|
|
// keep the following org.elasticsearch jars in
|
|
|
|
(it.name == 'jna' ||
|
|
|
|
it.name == 'securesm')
|
2017-11-18 22:42:57 -05:00
|
|
|
}
|
2016-11-07 18:29:35 -05:00
|
|
|
}
|
2015-12-01 20:08:27 -05:00
|
|
|
|
2019-04-09 14:52:50 -04:00
|
|
|
|
2019-10-03 03:50:46 -04:00
|
|
|
task integTest(type: Test) {
|
|
|
|
description = 'Multi-node tests'
|
|
|
|
mustRunAfter test
|
2019-04-09 14:52:50 -04:00
|
|
|
|
2019-11-14 06:01:23 -05:00
|
|
|
include '**/*IT.class'
|
2020-04-17 10:46:49 -04:00
|
|
|
if (org.elasticsearch.gradle.info.BuildParams.isSnapshotBuild() == false) {
|
|
|
|
systemProperty 'es.datastreams_feature_enabled', 'true'
|
|
|
|
}
|
2019-10-03 03:50:46 -04:00
|
|
|
}
|
2019-04-09 14:52:50 -04:00
|
|
|
|
2019-10-03 03:50:46 -04:00
|
|
|
check.dependsOn integTest
|
|
|
|
|
|
|
|
task internalClusterTest {
|
2019-11-14 06:01:23 -05:00
|
|
|
dependsOn integTest
|
2015-11-05 01:28:57 -05:00
|
|
|
}
|
2019-01-28 07:26:22 -05:00
|
|
|
|
2019-10-03 03:50:46 -04:00
|
|
|
|