From 7a9eec33ae62095bc8a011c2d93838bbcd37ee26 Mon Sep 17 00:00:00 2001 From: dimitrispie Date: Wed, 30 Dec 2020 15:56:37 +0200 Subject: [PATCH] Init repo --- README.md | 0 dump.rdb | Bin 0 -> 92 bytes pom.xml | 185 +++ .../eu/dnetlib/usagestats/UsageStatsApi.java | 24 + .../config/DataSourceConfiguration.java | 43 + .../config/SpringRedisConfiguration.java | 47 + .../config/WebMvcConfiguration.java | 40 + .../controllers/SushiLiteController.java | 92 ++ .../controllers/UsageStatsController.java | 102 ++ .../portal/CountryRepositories.java | 40 + .../usagestats/portal/CountryUsageStats.java | 60 + .../portal/CountryUsageStatsAll.java | 54 + .../usagestats/portal/MonthlyStats.java | 49 + .../usagestats/portal/MonthlyUsageStats.java | 49 + .../usagestats/portal/RepositoryStats.java | 53 + .../dnetlib/usagestats/portal/TotalStats.java | 57 + .../portal/TotalStatsReposViewsDownloads.java | 38 + .../dnetlib/usagestats/portal/UsageStats.java | 108 ++ .../usagestats/portal/YearlyStats.java | 65 + .../repositories/UsageStatsRepository.java | 1454 +++++++++++++++++ .../usagestats/services/SushiLiteService.java | 14 + .../services/SushiLiteServiceImpl.java | 357 ++++ .../services/UsageStatsService.java | 24 + .../services/UsageStatsServiceImpl.java | 148 ++ src/main/resources/log4j.properties | 25 + src/main/resources/static/assets/80x15.png | Bin 0 -> 410 bytes .../static/assets/Logo_Horizontal.png | Bin 0 -> 12549 bytes .../assets/Logo_Horizontal_white_small.png | Bin 0 -> 4630 bytes .../static/assets/apple-icon-72x72.png | Bin 0 -> 4587 bytes src/main/resources/static/assets/custom.css | 1152 +++++++++++++ src/main/resources/static/assets/custom.css.1 | 322 ++++ src/main/resources/static/assets/favicon.ico | Bin 0 -> 32988 bytes src/main/resources/static/assets/jquery.js | 5 + src/main/resources/static/assets/theme.css | 9 + .../resources/static/assets/uikit-icon-max.js | 251 +++ src/main/resources/static/assets/uikit.js | 5 + src/main/resources/static/error/404.html | 101 ++ src/main/resources/static/index.html | 107 ++ .../resources/static/sushilite/AR1/index.html | 199 +++ .../resources/static/sushilite/BR1/index.html | 204 +++ .../resources/static/sushilite/BR2/index.html | 199 +++ .../resources/static/sushilite/IR1/index.html | 239 +++ .../resources/static/sushilite/JR1/index.html | 226 +++ .../resources/static/sushilite/RR1/index.html | 230 +++ .../resources/static/sushilite/index.html | 107 ++ 45 files changed, 6484 insertions(+) create mode 100755 README.md create mode 100644 dump.rdb create mode 100755 pom.xml create mode 100755 src/main/java/eu/dnetlib/usagestats/UsageStatsApi.java create mode 100755 src/main/java/eu/dnetlib/usagestats/config/DataSourceConfiguration.java create mode 100755 src/main/java/eu/dnetlib/usagestats/config/SpringRedisConfiguration.java create mode 100755 src/main/java/eu/dnetlib/usagestats/config/WebMvcConfiguration.java create mode 100755 src/main/java/eu/dnetlib/usagestats/controllers/SushiLiteController.java create mode 100755 src/main/java/eu/dnetlib/usagestats/controllers/UsageStatsController.java create mode 100755 src/main/java/eu/dnetlib/usagestats/portal/CountryRepositories.java create mode 100755 src/main/java/eu/dnetlib/usagestats/portal/CountryUsageStats.java create mode 100755 src/main/java/eu/dnetlib/usagestats/portal/CountryUsageStatsAll.java create mode 100755 src/main/java/eu/dnetlib/usagestats/portal/MonthlyStats.java create mode 100755 src/main/java/eu/dnetlib/usagestats/portal/MonthlyUsageStats.java create mode 100755 src/main/java/eu/dnetlib/usagestats/portal/RepositoryStats.java create mode 100755 src/main/java/eu/dnetlib/usagestats/portal/TotalStats.java create mode 100755 src/main/java/eu/dnetlib/usagestats/portal/TotalStatsReposViewsDownloads.java create mode 100755 src/main/java/eu/dnetlib/usagestats/portal/UsageStats.java create mode 100755 src/main/java/eu/dnetlib/usagestats/portal/YearlyStats.java create mode 100755 src/main/java/eu/dnetlib/usagestats/repositories/UsageStatsRepository.java create mode 100755 src/main/java/eu/dnetlib/usagestats/services/SushiLiteService.java create mode 100755 src/main/java/eu/dnetlib/usagestats/services/SushiLiteServiceImpl.java create mode 100755 src/main/java/eu/dnetlib/usagestats/services/UsageStatsService.java create mode 100755 src/main/java/eu/dnetlib/usagestats/services/UsageStatsServiceImpl.java create mode 100755 src/main/resources/log4j.properties create mode 100755 src/main/resources/static/assets/80x15.png create mode 100755 src/main/resources/static/assets/Logo_Horizontal.png create mode 100755 src/main/resources/static/assets/Logo_Horizontal_white_small.png create mode 100755 src/main/resources/static/assets/apple-icon-72x72.png create mode 100755 src/main/resources/static/assets/custom.css create mode 100755 src/main/resources/static/assets/custom.css.1 create mode 100755 src/main/resources/static/assets/favicon.ico create mode 100755 src/main/resources/static/assets/jquery.js create mode 100755 src/main/resources/static/assets/theme.css create mode 100755 src/main/resources/static/assets/uikit-icon-max.js create mode 100755 src/main/resources/static/assets/uikit.js create mode 100755 src/main/resources/static/error/404.html create mode 100755 src/main/resources/static/index.html create mode 100755 src/main/resources/static/sushilite/AR1/index.html create mode 100755 src/main/resources/static/sushilite/BR1/index.html create mode 100755 src/main/resources/static/sushilite/BR2/index.html create mode 100755 src/main/resources/static/sushilite/IR1/index.html create mode 100755 src/main/resources/static/sushilite/JR1/index.html create mode 100755 src/main/resources/static/sushilite/RR1/index.html create mode 100755 src/main/resources/static/sushilite/index.html diff --git a/README.md b/README.md new file mode 100755 index 0000000..e69de29 diff --git a/dump.rdb b/dump.rdb new file mode 100644 index 0000000000000000000000000000000000000000..49869e60d40177071ccc66de04b9e1d5aff70f7a GIT binary patch literal 92 zcmWG?b@2=~Ffg$E#aWb^l3A= + + 4.0.0 + eu.dnetlib + openaire-usage-stats-api-r5 + 3.0.0-SNAPSHOT + war + + org.springframework.boot + spring-boot-starter-parent + 1.5.15.RELEASE + + + + + org.springframework.retry + spring-retry + 1.2.0.RELEASE + jar + + + org.springframework + spring-aspects + 5.2.9.RELEASE + + + org.apache.hive + hive-jdbc + 0.13.1 + + + eu.dnetlib + openaire-usage-stats-sushilite-r5 + 1.0.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + log4j + log4j + 1.2.17 + + + + + junit + junit + test + + + org.hsqldb + hsqldb + 2.3.2 + test + + + com.googlecode.json-simple + json-simple + 1.1.1 + + + + commons-dbutils + commons-dbutils + 1.7 + + + com.cloudera + ImpalaJDBC41 + 2.6.3 + runtime + + + + com.cloudera.impala + jdbc + 2.5.31 + runtime + + + org.slf4j + slf4j-log4j12 + + + org.apache.derby + derby + + + org.eclipse.jetty.aggregate + jetty-all + + + log4j + log4j + + + log4j + apache-log4j-extras + + + + + org.apache.hadoop + libthrift + 0.5.0.0 + + + + + 1.8 + 7.0.52 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + maven-war-plugin + + false + + + + usagestats + + + + + spring-releases + https://repo.spring.io/libs-release + + + + + + spring-releases + https://repo.spring.io/libs-release + + + openaire-usage-stats-api-r5 + diff --git a/src/main/java/eu/dnetlib/usagestats/UsageStatsApi.java b/src/main/java/eu/dnetlib/usagestats/UsageStatsApi.java new file mode 100755 index 0000000..7eabe86 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/UsageStatsApi.java @@ -0,0 +1,24 @@ +package eu.dnetlib.usagestats; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.context.annotation.PropertySource; +import org.springframework.context.annotation.PropertySources; +import org.springframework.retry.annotation.EnableRetry; + +@PropertySources({ + @PropertySource("classpath:usageStatsAPI.properties"), //@PropertySource("classpath:dnet-override.properties") +} +) +@EnableRetry +@SpringBootApplication +public class UsageStatsApi extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(UsageStatsApi.class, args); + } +} + + + diff --git a/src/main/java/eu/dnetlib/usagestats/config/DataSourceConfiguration.java b/src/main/java/eu/dnetlib/usagestats/config/DataSourceConfiguration.java new file mode 100755 index 0000000..f69a87f --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/config/DataSourceConfiguration.java @@ -0,0 +1,43 @@ +package eu.dnetlib.usagestats.config; + +//import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import javax.sql.DataSource; +import org.apache.log4j.Logger; +import org.apache.tomcat.jdbc.pool.PoolProperties; +import org.springframework.beans.factory.annotation.Value; + +/** + * Created by tsampikos on 8/3/2017. + */ +@Configuration +public class DataSourceConfiguration { + + private final Logger log = Logger.getLogger(this.getClass()); + @Value("${usagestats.driverClassName}") + private String driverClassName; + @Value("${usagestats.url}") + private String dbURL; + + @ConfigurationProperties(prefix = "usagestats") + @Bean + @Primary + public DataSource getDataSource() { + PoolProperties poolProperties = new PoolProperties(); + poolProperties.setUrl(dbURL); + poolProperties.setDriverClassName(driverClassName); + log.info("dbURL " + dbURL); + log.info("driverClassName " + driverClassName); + + poolProperties.setTestOnBorrow(true); + poolProperties.setValidationQuery("SELECT 1"); + poolProperties.setValidationInterval(0); + DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource(poolProperties); + return ds; + } +} diff --git a/src/main/java/eu/dnetlib/usagestats/config/SpringRedisConfiguration.java b/src/main/java/eu/dnetlib/usagestats/config/SpringRedisConfiguration.java new file mode 100755 index 0000000..4e2a3d2 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/config/SpringRedisConfiguration.java @@ -0,0 +1,47 @@ +package eu.dnetlib.usagestats.config; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * Created by tsampikos on 20/4/2017. + */ +@Configuration +public class SpringRedisConfiguration { + + private final Logger log = Logger.getLogger(this.getClass()); + + @Value("${usagestats.redis.hostname}") + private String hostname; + + @Value("${usagestats.redis.port}") + private int port; + + @Bean + public JedisConnectionFactory connectionFactory() { + JedisConnectionFactory connectionFactory = new JedisConnectionFactory(); + connectionFactory.setHostName(hostname); + connectionFactory.setPort(port); + connectionFactory.setUsePool(false); + log.info("Opening redis connection to : " + connectionFactory.getHostName() + ":" + connectionFactory.getPort()); + return connectionFactory; + } + + @Bean + @Autowired + public RedisTemplate redisTemplate() { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(connectionFactory()); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new StringRedisSerializer()); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashValueSerializer(new StringRedisSerializer()); + return redisTemplate; + } +} diff --git a/src/main/java/eu/dnetlib/usagestats/config/WebMvcConfiguration.java b/src/main/java/eu/dnetlib/usagestats/config/WebMvcConfiguration.java new file mode 100755 index 0000000..d58172e --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/config/WebMvcConfiguration.java @@ -0,0 +1,40 @@ +package eu.dnetlib.usagestats.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +/** + * Created by tsampikos on 12/4/2017. + */ +@Configuration +//public class WebMvcConfiguration implements WebMvcConfigurer { +public class WebMvcConfiguration extends WebMvcConfigurerAdapter { + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/sushilite").setViewName("redirect:/sushilite/"); + registry.addViewController("/sushilite/").setViewName("forward:/sushilite/index.html"); + + registry.addViewController("/sushilite/AR1").setViewName("redirect:/sushilite/AR1/"); + registry.addViewController("/sushilite/AR1/").setViewName("forward:/sushilite/AR1/index.html"); + + registry.addViewController("/sushilite/IR1").setViewName("redirect:/sushilite/IR1/"); + registry.addViewController("/sushilite/IR1/").setViewName("forward:/sushilite/IR1/index.html"); + + registry.addViewController("/sushilite/RR1").setViewName("redirect:/sushilite/RR1/"); + registry.addViewController("/sushilite/RR1/").setViewName("forward:/sushilite/RR1/index.html"); + + registry.addViewController("/sushilite/JR1").setViewName("redirect:/sushilite/JR1/"); + registry.addViewController("/sushilite/JR1/").setViewName("forward:/sushilite/JR1/index.html"); + + registry.addViewController("/sushilite/BR1").setViewName("redirect:/sushilite/BR1/"); + registry.addViewController("/sushilite/BR1/").setViewName("forward:/sushilite/BR1/index.html"); + + registry.addViewController("/sushilite/BR2").setViewName("redirect:/sushilite/BR2/"); + registry.addViewController("/sushilite/BR2/").setViewName("forward:/sushilite/BR2/index.html"); + + super.addViewControllers(registry); + } +} diff --git a/src/main/java/eu/dnetlib/usagestats/controllers/SushiLiteController.java b/src/main/java/eu/dnetlib/usagestats/controllers/SushiLiteController.java new file mode 100755 index 0000000..65789ec --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/controllers/SushiLiteController.java @@ -0,0 +1,92 @@ +package eu.dnetlib.usagestats.controllers; + +import eu.dnetlib.usagestats.services.SushiLiteService; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * Created by dimitris.pierrakos on 09/10/2020. + */ +@RestController +class SushiLiteController { + + private final Logger log = Logger.getLogger(this.getClass()); + + private final SushiLiteService sushiLiteService; + @Value("${download.folder}") + private String download_folder; + + public SushiLiteController(SushiLiteService sushiLiteService) { + this.sushiLiteService = sushiLiteService; + } + + @RequestMapping(value = "/sushilite/GetReport/", method = RequestMethod.GET) + public ResponseEntity getReport(@RequestParam(value = "Report", defaultValue = "") String reportP, @RequestParam(value = "Release", defaultValue = "4") String release, @RequestParam(value = "RequestorID", defaultValue = "anonymous") String requestorId, + @RequestParam(value = "BeginDate", defaultValue = "") String beginDate, @RequestParam(value = "EndDate", defaultValue = "") String endDate, @RequestParam(value = "RepositoryIdentifier", defaultValue = "") String repositoryIdentifier, + @RequestParam(value = "ItemIdentifier", defaultValue = "") String itemIdentifier, @RequestParam(value = "ItemDataType", defaultValue = "") String itemDataType, + @RequestParam(value = "hasDOI", defaultValue = "") String hasDoi, @RequestParam(value = "Granularity", defaultValue = "Monthly") String granularity, @RequestParam(value = "Callback", defaultValue = "") String callback, + @RequestParam(value = "Pretty", defaultValue = "") String pretty, + //added for compression case report + @RequestHeader(value = "User-Agent", required = false) String userAgent) throws InterruptedException, Exception { + log.info("Sushi Report request: " + reportP + " from " + requestorId); + log.info("repository identifier: " + repositoryIdentifier + " - item identifier: " + itemIdentifier); + + String report = sushiLiteService.displayReport(reportP, release, requestorId, beginDate, endDate, repositoryIdentifier, itemIdentifier, itemDataType, hasDoi, granularity, callback, pretty, userAgent); + + if (report.indexOf(".zip") < 0) { + return new ResponseEntity<>(report, HttpStatus.OK); + } else { + /* URI reportZipURL = new URI(report); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setLocation(reportZipURL);*/ + //report= "report is available. Download it from localhost:8080/download/file.zip"; + String content = "" + + "" + + "" + + "OpenAIRE SUSHI Lite Client Report" + + "" + + "" + + "

" + + "Click to download the report" + + "

" + + "" + + ""; + log.info(content); + //return new ResponseEntity<>(httpHeaders, HttpStatus.SEE_OTHER); + return new ResponseEntity<>(content, HttpStatus.OK); + } + } + + @RequestMapping(value = "/download/{file_name}", method = RequestMethod.GET) + public void downloadFile(HttpServletResponse response, @PathVariable("file_name") String filetoDownload) throws IOException { + File file = new File(download_folder + "/" + filetoDownload + ".zip"); + log.info("File downloaded at " + file.getAbsolutePath()); + String mimeType = "application/octet-stream"; + + response.setContentType(mimeType); + + /* "Content-Disposition : attachment" will be directly download, may provide save as popup, based on your browser setting*/ + response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getName())); + response.setContentLength((int) file.length()); + InputStream inputStream = new BufferedInputStream(new FileInputStream(file)); + FileCopyUtils.copy(inputStream, response.getOutputStream()); + } +} diff --git a/src/main/java/eu/dnetlib/usagestats/controllers/UsageStatsController.java b/src/main/java/eu/dnetlib/usagestats/controllers/UsageStatsController.java new file mode 100755 index 0000000..ac9b694 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/controllers/UsageStatsController.java @@ -0,0 +1,102 @@ +package eu.dnetlib.usagestats.controllers; + +import eu.dnetlib.usagestats.portal.CountryRepositories; +import eu.dnetlib.usagestats.portal.CountryUsageStats; +import eu.dnetlib.usagestats.portal.CountryUsageStatsAll; +import eu.dnetlib.usagestats.portal.MonthlyUsageStats; +import eu.dnetlib.usagestats.portal.TotalStats; +import eu.dnetlib.usagestats.portal.TotalStatsReposViewsDownloads; +import eu.dnetlib.usagestats.portal.UsageStats; + +import eu.dnetlib.usagestats.services.UsageStatsService; +import java.util.List; +import org.apache.log4j.Logger; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + + +@RestController +@CrossOrigin(methods = RequestMethod.GET, origins = "*") +public class UsageStatsController { + + private final UsageStatsService usageStatsService; + + private final Logger log = Logger.getLogger(this.getClass()); + + public UsageStatsController(UsageStatsService usageStatsService) { + this.usageStatsService = usageStatsService; + } + + @RequestMapping(value = "/datasources/{datasourceId}/clicks") + public UsageStats getDatasourceClicks(@PathVariable(value = "datasourceId") String datasourceId) { + log.info("stats request for datasource: " + datasourceId); + return usageStatsService.getDatasourceClicks(datasourceId); + } + + @RequestMapping(value = "/projects/{projectId}/clicks") + public UsageStats getProjectClicks(@PathVariable(value = "projectId") String projectId) { + log.info("stats request for project: " + projectId); + return usageStatsService.getProjectClicks(projectId); + } + + @RequestMapping(value = "/monthlyusagestats") + public List getMonthlyUsageStats() { + log.info("stats request for months"); + return usageStatsService.getMonthlyUsageStats(); + } + + @RequestMapping(value = "/countryusagestats") + public CountryUsageStatsAll getCountryUsageStatsAll() { + log.info("stats request for countries"); + return usageStatsService.getCountryUsageStatsAll(); + } + @RequestMapping(value = "/countryusagestats/{country}") + public CountryUsageStats getCountryUsageStats(@PathVariable(value = "country") String country) { + log.info("stats request for country "+country); + return usageStatsService.getCountryUsageStats(country); + } + + @RequestMapping(value = "/countryrepositories") + public List getCountryRepositories() { + log.info("stats request for countries/repos"); + return usageStatsService.getCountryRepositories(); + } + + + @RequestMapping(value = "/totals") + public TotalStats getTotalStats() { + log.info("total stats request"); + return usageStatsService.getTotalStats(); + } + + @RequestMapping(value = "/monthlyusagestats/{datasourceId}") + public List getMonthlyUsageStatsForRepo(@PathVariable(value = "datasourceId") String datasourceId) { + log.info("stats request for datasource: " + datasourceId); + return usageStatsService.getMonthlyUsageStatsForRepo(datasourceId); + } + + + /* + @RequestMapping(value = "/organizations/{organizationId}/clicks") + public UsageStats getOrganizationClicks(@PathVariable(value = "organizationId") String organizationId) { + log.info("stats request for organization: " + organizationId); + return usageStatsService.getOrganizationClicks(organizationId); + } + */ + + @RequestMapping(value = "/results/{resultId}/clicks") + public UsageStats getResultClicks(@PathVariable(value = "resultId") String resultId) { + log.info("stats request for result: " + resultId); + return usageStatsService.getResultClicks(resultId); + } + + @RequestMapping(value = "/allmetrics") + public TotalStatsReposViewsDownloads getTotalStatsReposViewsDownloads() { + log.info("total stats request"); + return usageStatsService.getTotalStatsReposViewsDownloads(); + } + +} diff --git a/src/main/java/eu/dnetlib/usagestats/portal/CountryRepositories.java b/src/main/java/eu/dnetlib/usagestats/portal/CountryRepositories.java new file mode 100755 index 0000000..ecf0b64 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/portal/CountryRepositories.java @@ -0,0 +1,40 @@ +package eu.dnetlib.usagestats.portal; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + + +public class CountryRepositories implements Serializable { + + private final static long serialVersionUID = 1; + + + private String country = ""; + private String repository = ""; + //private String pageviews = "0"; + + public CountryRepositories() { + } + + @JsonProperty("country") + public String getCountry() { + return country; + } + + @JsonProperty("repository") + public String getRepository() { + return repository; + } + + public void addCountry(String country) { + this.country=country; + } + + public void addRepository(String repository) { + this.repository=repository; + } + +} diff --git a/src/main/java/eu/dnetlib/usagestats/portal/CountryUsageStats.java b/src/main/java/eu/dnetlib/usagestats/portal/CountryUsageStats.java new file mode 100755 index 0000000..cc93f26 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/portal/CountryUsageStats.java @@ -0,0 +1,60 @@ +package eu.dnetlib.usagestats.portal; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + + +public class CountryUsageStats implements Serializable { + + private final static long serialVersionUID = 1; + + + private String country = ""; + private String total_repos = ""; + private String downloads = ""; + private String views = ""; + + //private String pageviews = "0"; + + public CountryUsageStats() { + } + + @JsonProperty("country") + public String getCountry() { + return country; + } + + @JsonProperty("total_repos") + public String getTotalRepos() { + return total_repos; + } + + @JsonProperty("downloads") + public String getDownloads() { + return downloads; + } + + @JsonProperty("views") + public String getViews() { + return views; + } + + public void addCountry(String country) { + this.country=country; + } + + public void addTotalRepos(String total_repos) { + this.total_repos=total_repos; + } + + public void addViews(String views) { + this.views=views; + } + public void addDownloads(String downloads) { + this.downloads=downloads; + } + +} diff --git a/src/main/java/eu/dnetlib/usagestats/portal/CountryUsageStatsAll.java b/src/main/java/eu/dnetlib/usagestats/portal/CountryUsageStatsAll.java new file mode 100755 index 0000000..029eb98 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/portal/CountryUsageStatsAll.java @@ -0,0 +1,54 @@ +package eu.dnetlib.usagestats.portal; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + + +public class CountryUsageStatsAll implements Serializable { + + private final static long serialVersionUID = 1; + + private String country_all = "all"; + private String downloads_all = "0"; + private String views_all = "0"; + private List countryUsageStats = new ArrayList(); + //private String pageviews = "0"; + + public CountryUsageStatsAll() { + } + + @JsonProperty("country") + public String getCountry() { + return country_all; + } + + @JsonProperty("downloads_all") + public String getDownloads() { + return downloads_all; + } + + @JsonProperty("views_all") + public String getViews() { + return views_all; + } + @JsonProperty("CountriesList") + public List getCountryUsageStats() { + return countryUsageStats; + } + + public void addViewsAll(String views_all) { + this.views_all=views_all; + } + public void addDownloadsAll(String downloads_all) { + this.downloads_all=downloads_all; + } + + public void addCountryUsageStats(List countryUsageStats) { + this.countryUsageStats = countryUsageStats; + } + + +} diff --git a/src/main/java/eu/dnetlib/usagestats/portal/MonthlyStats.java b/src/main/java/eu/dnetlib/usagestats/portal/MonthlyStats.java new file mode 100755 index 0000000..3a8e32e --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/portal/MonthlyStats.java @@ -0,0 +1,49 @@ +package eu.dnetlib.usagestats.portal; + +public class MonthlyStats { + private int month; + private int repositories; + private int items; + private int downloads; + private int views; + + public int getMonth() { + return month; + } + + public void setMonth(int month) { + this.month = month; + } + + public int getRepositories() { + return repositories; + } + + public void setRepositories(int repositories) { + this.repositories = repositories; + } + + public int getItems() { + return items; + } + + public void setItems(int items) { + this.items = items; + } + + public int getDownloads() { + return downloads; + } + + public void setDownloads(int downloads) { + this.downloads = downloads; + } + + public int getViews() { + return views; + } + + public void setViews(int views) { + this.views = views; + } +} diff --git a/src/main/java/eu/dnetlib/usagestats/portal/MonthlyUsageStats.java b/src/main/java/eu/dnetlib/usagestats/portal/MonthlyUsageStats.java new file mode 100755 index 0000000..4f45cf0 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/portal/MonthlyUsageStats.java @@ -0,0 +1,49 @@ +package eu.dnetlib.usagestats.portal; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + + +public class MonthlyUsageStats implements Serializable { + + private final static long serialVersionUID = 1; + + + private String date = "0"; + private String downloads = "0"; + private String views = "0"; + //private String pageviews = "0"; + + public MonthlyUsageStats() { + } + + @JsonProperty("date") + public String getDate() { + return date; + } + + @JsonProperty("downloads") + public String getDownloads() { + return downloads; + } + + @JsonProperty("views") + public String getViews() { + return views; + } + + public void addDate(String date) { + this.date=date; + } + + public void addViews(String views) { + this.views=views; + } + public void addDownloads(String downloads) { + this.downloads=downloads; + } + +} diff --git a/src/main/java/eu/dnetlib/usagestats/portal/RepositoryStats.java b/src/main/java/eu/dnetlib/usagestats/portal/RepositoryStats.java new file mode 100755 index 0000000..d0e9204 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/portal/RepositoryStats.java @@ -0,0 +1,53 @@ +package eu.dnetlib.usagestats.portal; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; + +/** + * Created by tsampikos on 8/11/2016. + */ +public class RepositoryStats implements Serializable { + private final static long serialVersionUID = 1; + private String datasource_name = ""; + private String datasource_id = ""; + private String value = ""; + private String openaire = ""; + + public RepositoryStats() { + } + + public RepositoryStats(String datasource_name, String datasource_id, String value, String openaire) { + this.datasource_name = datasource_name; + this.datasource_id = datasource_id; + this.value = value; + this.openaire = openaire; + } + + @JsonProperty("datasource_name") + public String getDatasource_name() { + return datasource_name; + } + + @JsonProperty("datasource_id") + public String getDatasource_id() { + return datasource_id; + } + + @JsonProperty("value") + public String getValue() { + return value; + } + + @JsonProperty("openaire") + public String getOpenaire() { + return openaire; + } + + /* + public String toString(){ + return datasource_name + " " + datasource_id + " " + value + " " + openaire; + } + */ + +} diff --git a/src/main/java/eu/dnetlib/usagestats/portal/TotalStats.java b/src/main/java/eu/dnetlib/usagestats/portal/TotalStats.java new file mode 100755 index 0000000..ef1cba3 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/portal/TotalStats.java @@ -0,0 +1,57 @@ +package eu.dnetlib.usagestats.portal; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class TotalStats { + private int repositories; + private int items; + private int downloads; + private int views; + private List yearlyStats; + + @JsonProperty("yearly_stats") + public List getYearlyStats() { + return yearlyStats; + } + + public void setYearlyStats(List yearlyStats) { + this.yearlyStats = yearlyStats; + } + + + public TotalStats() {} + + public int getRepositories() { + return repositories; + } + + public void setRepositories(int repositories) { + this.repositories = repositories; + } + + public int getItems() { + return items; + } + + public void setItems(int items) { + this.items = items; + } + + public int getDownloads() { + return downloads; + } + + public void setDownloads(int downloads) { + this.downloads = downloads; + } + + public int getViews() { + return views; + } + + public void setViews(int views) { + this.views = views; + } +} diff --git a/src/main/java/eu/dnetlib/usagestats/portal/TotalStatsReposViewsDownloads.java b/src/main/java/eu/dnetlib/usagestats/portal/TotalStatsReposViewsDownloads.java new file mode 100755 index 0000000..f86d0bc --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/portal/TotalStatsReposViewsDownloads.java @@ -0,0 +1,38 @@ +package eu.dnetlib.usagestats.portal; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class TotalStatsReposViewsDownloads { + private String repositories; + private String downloads; + private String views; + + @JsonProperty("repositories") + public String getRepositories() { + return repositories; + } + + public void addRepositories(String repositories) { + this.repositories=repositories; + } + + @JsonProperty("total_views") + public String getViews() { + return views; + } + + public void addViews(String views) { + this.views=views; + } + @JsonProperty("total_downloads") + public String getDownloads() { + return downloads; + } + + public void addDownloads(String downloads) { + this.downloads=downloads; + } + +} diff --git a/src/main/java/eu/dnetlib/usagestats/portal/UsageStats.java b/src/main/java/eu/dnetlib/usagestats/portal/UsageStats.java new file mode 100755 index 0000000..34bd6ef --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/portal/UsageStats.java @@ -0,0 +1,108 @@ +package eu.dnetlib.usagestats.portal; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + + +public class UsageStats implements Serializable { + + private final static long serialVersionUID = 1; + + private final List downloads = new ArrayList<>(); + private final List views = new ArrayList<>(); + + private String total_downloads = "0"; + private String total_views = "0"; + private String pageviews = "0"; + private String total_openaire_views = "0"; + private String total_openaire_downloads = "0"; + + public UsageStats() { + } + + @JsonProperty("downloads") + public List getDownloads() { + return downloads; + } + + @JsonProperty("views") + public List getViews() { + return views; + } + + public void addViews(RepositoryStats view) { + views.add(view); + } + + public void addDownloads(RepositoryStats download) { + downloads.add(download); + } + + @JsonProperty("total_downloads") + public String getTotal_downloads() { + return total_downloads; + } + + public void setTotal_downloads(String total_downloads) { + this.total_downloads = total_downloads; + } + + @JsonProperty("total_views") + public String getTotal_views() { + return total_views; + } + + public void setTotal_views(String total_views) { + this.total_views = total_views; + } + + @JsonProperty("pageviews") + public String getPageViews() { + return pageviews; + } + + public void setPageViews(String pageviews) { + this.pageviews = pageviews; + } + + @JsonProperty("total_openaire_views") + public String getTotal_openaire_views() { + return total_openaire_views; + } + + public void setTotal_openaire_views(String total_openaire_views) { + this.total_openaire_views = total_openaire_views; + } + + @JsonProperty("total_openaire_downloads") + public String getTotal_openaire_downloads() { + return total_openaire_downloads; + } + + public void setTotal_openaire_downloads(String total_openaire_downloads) { + this.total_openaire_downloads = total_openaire_downloads; + } + + + /* + public String toString(){ + String string; + string = total_downloads + " "; + string += total_views + " "; + string += pageviews + " "; + string += total_openaire + " "; + + for(RepositoryStats repositoryStats : downloads){ + string += repositoryStats.toString() + " "; + } + + for(RepositoryStats repositoryStats : views){ + string += repositoryStats.toString() + " "; + } + return string; + } + */ +} diff --git a/src/main/java/eu/dnetlib/usagestats/portal/YearlyStats.java b/src/main/java/eu/dnetlib/usagestats/portal/YearlyStats.java new file mode 100755 index 0000000..2018f46 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/portal/YearlyStats.java @@ -0,0 +1,65 @@ +package eu.dnetlib.usagestats.portal; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class YearlyStats { + private int year; + private int repositories; + private int items; + private int downloads; + private int views; + private List monthlyStats; + + @JsonProperty("monthly_stats") + public List getMonthlyStats() { + return monthlyStats; + } + + public void setMonthlyStats(List monthlyStats) { + this.monthlyStats = monthlyStats; + } + + public YearlyStats() {} + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public int getRepositories() { + return repositories; + } + + public void setRepositories(int repositories) { + this.repositories = repositories; + } + + public int getItems() { + return items; + } + + public void setItems(int items) { + this.items = items; + } + + public int getDownloads() { + return downloads; + } + + public void setDownloads(int downloads) { + this.downloads = downloads; + } + + public int getViews() { + return views; + } + + public void setViews(int views) { + this.views = views; + } +} diff --git a/src/main/java/eu/dnetlib/usagestats/repositories/UsageStatsRepository.java b/src/main/java/eu/dnetlib/usagestats/repositories/UsageStatsRepository.java new file mode 100755 index 0000000..85cb60c --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/repositories/UsageStatsRepository.java @@ -0,0 +1,1454 @@ +package eu.dnetlib.usagestats.repositories; + +import org.apache.log4j.Logger; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Repository; + +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.dnetlib.usagestats.portal.CountryRepositories; +import eu.dnetlib.usagestats.portal.CountryUsageStats; +import eu.dnetlib.usagestats.portal.CountryUsageStatsAll; + +import eu.dnetlib.usagestats.portal.MonthlyStats; +import eu.dnetlib.usagestats.portal.MonthlyUsageStats; +import eu.dnetlib.usagestats.portal.RepositoryStats; +import eu.dnetlib.usagestats.portal.TotalStats; +import eu.dnetlib.usagestats.portal.TotalStatsReposViewsDownloads; +import eu.dnetlib.usagestats.portal.UsageStats; +import eu.dnetlib.usagestats.portal.YearlyStats; +import eu.dnetlib.usagestats.sushilite.domain.ItemIdentifier; +import eu.dnetlib.usagestats.sushilite.domain.ItemPerformance; +import eu.dnetlib.usagestats.sushilite.domain.ReportItem; + +import org.apache.commons.dbutils.DbUtils; + +import javax.sql.DataSource; + +import java.security.MessageDigest; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import org.springframework.beans.factory.annotation.Value; + +@Repository +public class UsageStatsRepository { + + private final DataSource usageStatsDB; + + private final HashOperations jedis; + + private final Logger log = Logger.getLogger(this.getClass()); + @Value("${prod.statsdb}") + private String statsDB; + @Value("${prod.usagestatsImpalaDB}") + private String usagestatsImpalaDB; + + public UsageStatsRepository(DataSource usageStatsDB, RedisTemplate redisTemplate) { + this.usageStatsDB = usageStatsDB; + this.jedis = redisTemplate.opsForHash(); + } + + private static String MD5(String string) throws java.security.NoSuchAlgorithmException { + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(string.getBytes()); + + byte byteData[] = md.digest(); + StringBuilder sb = new StringBuilder(); + for (byte aByteData : byteData) { + sb.append(Integer.toString((aByteData & 0xff) + 0x100, 16).substring(1)); + } + + return sb.toString(); + } + + private static String toJson(Object o) throws com.fasterxml.jackson.core.JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.writeValueAsString(o); + } + + private static UsageStats fromJson(String string) throws java.io.IOException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(string, UsageStats.class); + } + + /* + private static List reportItemsFromJson(String string) throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(string, objectMapper.getTypeFactory().constructCollectionType(List.class, ReportItem.class)); + } + */ + public List executeMontlyUsageStats(String query) { + List montlhyList = new ArrayList(); + + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + try { + connection = usageStatsDB.getConnection(); + log.info(connection.toString()); + st = connection.prepareStatement(query); + log.info(st.toString()); + rs = st.executeQuery(); + while (rs.next()) { + MonthlyUsageStats monthlyUsageStats = new MonthlyUsageStats(); + monthlyUsageStats.addDate(rs.getString(1)); + monthlyUsageStats.addDownloads(rs.getString(2)); + monthlyUsageStats.addViews(rs.getString(3)); + montlhyList.add(monthlyUsageStats); + } + + } catch (Exception e) { + System.out.println(e); + } + + try { + jedis.put("test", "result", toJson(montlhyList)); + jedis.put("test", "persistent", "false"); + jedis.put("test", "fetchMode", "3"); + } catch (Exception e) { + System.out.println(e); + }finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + + return montlhyList; + } + + public TotalStatsReposViewsDownloads executeTotalStatsReposViewsDownloads(String query) { + TotalStatsReposViewsDownloads totalStatsReposViewsDownlads = new TotalStatsReposViewsDownloads(); + + String total_repos = " "; + String views = " "; + String downloads = " "; + String redis_key = ""; + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + try { + connection = usageStatsDB.getConnection(); + log.info(connection.toString()); + st = connection.prepareStatement(query); + log.info(st.toString()); + rs = st.executeQuery(); + redis_key = MD5(st.toString()); + while (rs.next()) { + totalStatsReposViewsDownlads.addRepositories(rs.getString(1)); + totalStatsReposViewsDownlads.addViews(rs.getString(2)); + totalStatsReposViewsDownlads.addDownloads(rs.getString(3)); + } + + } catch (Exception e) { + System.out.println(e); + } + + try { + jedis.put(redis_key, "result", toJson(totalStatsReposViewsDownlads)); + jedis.put(redis_key, "persistent", "false"); + jedis.put(redis_key, "fetchMode", "3"); + } catch (Exception e) { + System.out.println(e); + }finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + + return totalStatsReposViewsDownlads; + } + + public CountryUsageStatsAll executeCountryUsageStats(String query) { + CountryUsageStatsAll countryListAll = new CountryUsageStatsAll(); + + List countryList = new ArrayList(); + + String date = " "; + String total_repos = " "; + String views = " "; + String downloads = " "; + String redis_key = "redis_key"; + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + int total_views = 0; + int total_downloads = 0; + + try { + connection = usageStatsDB.getConnection(); + log.info(connection.toString()); + st = connection.prepareStatement(query); + log.info(st.toString()); + rs = st.executeQuery(); + redis_key = MD5(st.toString()); + while (rs.next()) { + CountryUsageStats countryUsageStats = new CountryUsageStats(); + countryUsageStats.addCountry(rs.getString(1)); + countryUsageStats.addTotalRepos(rs.getString(2)); + countryUsageStats.addViews(rs.getString(3)); + countryUsageStats.addDownloads(rs.getString(4)); + total_views += Integer.parseInt(rs.getString(3)); + total_downloads += Integer.parseInt(rs.getString(4)); + + countryList.add(countryUsageStats); + } + countryListAll.addViewsAll(Integer.toString(total_views)); + countryListAll.addDownloadsAll(Integer.toString(total_downloads)); + + countryListAll.addCountryUsageStats(countryList); + + } catch (Exception e) { + log.info(e); + System.out.println(e); + } + + try { + jedis.put(redis_key, "result", toJson(countryListAll)); + jedis.put(redis_key, "persistent", "false"); + jedis.put(redis_key, "fetchMode", "3"); + } catch (Exception e) { + System.out.println(e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + return countryListAll; + } + + public CountryUsageStats executeCountryUsageStats(String query, String country) { + CountryUsageStats countryUsageStats = new CountryUsageStats(); + String total_repos = " "; + String views = " "; + String downloads = " "; + String redis_key = ""; + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + int total_views = 0; + int total_downloads = 0; + + try { + connection = usageStatsDB.getConnection(); + st = connection.prepareStatement(query); + + redis_key = MD5(st.toString()); + //st.setString(1, country); + log.info(st.toString()); + rs = st.executeQuery(); + + while (rs.next()) { + countryUsageStats.addCountry(country); + countryUsageStats.addTotalRepos(rs.getString(1)); + countryUsageStats.addViews(rs.getString(2)); + countryUsageStats.addDownloads(rs.getString(3)); + + } + + } catch (Exception e) { + log.info(e); + System.out.println(e); + } + + try { + jedis.put(redis_key, "result", toJson(countryUsageStats)); + jedis.put(redis_key, "persistent", "false"); + jedis.put(redis_key, "fetchMode", "3"); + } catch (Exception e) { + System.out.println(e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + return countryUsageStats; + } + + public List executeCountryRepositories(String query) { + + List countryReposList = new ArrayList(); + + String country = " "; + String repository = " "; + String redis_key = ""; + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + try { + connection = usageStatsDB.getConnection(); + log.info(connection.toString()); + st = connection.prepareStatement(query); + log.info(st.toString()); + rs = st.executeQuery(); + redis_key = MD5(st.toString()); + while (rs.next()) { + CountryRepositories countryRepository = new CountryRepositories(); + countryRepository.addCountry(rs.getString(1)); + countryRepository.addRepository(rs.getString(2)); + countryReposList.add(countryRepository); + } + + } catch (Exception e) { + System.out.println(e); + } + + try { + jedis.put(redis_key, "result", toJson(countryReposList)); + jedis.put(redis_key, "persistent", "false"); + jedis.put(redis_key, "fetchMode", "3"); + } catch (Exception e) { + System.out.println(e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + + return countryReposList; + } + + public List executeMontlyUsageStatsForRepo(String query, String datasourceId) { + List montlhyList = new ArrayList(); + + String redis_key = ""; + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + try { + connection = usageStatsDB.getConnection(); + st = connection.prepareStatement(query); + redis_key = MD5(st.toString()); + st.setString(1, datasourceId); + log.info(connection.toString()); + rs = st.executeQuery(); + while (rs.next()) { + MonthlyUsageStats monthlyUsageStats = new MonthlyUsageStats(); + monthlyUsageStats.addDate(rs.getString(1)); + monthlyUsageStats.addDownloads(rs.getString(2)); + monthlyUsageStats.addViews(rs.getString(3)); + montlhyList.add(monthlyUsageStats); + } + + } catch (Exception e) { + System.out.println(e); + } + + try { + jedis.put(redis_key, "result", toJson(montlhyList)); + jedis.put(redis_key, "persistent", "false"); + jedis.put(redis_key, "fetchMode", "3"); + } catch (Exception e) { + System.out.println(e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + + return montlhyList; + } + + public UsageStats executeUsageStats(String query, List values, String type) { + + UsageStats usageStats = new UsageStats(); + int total_views = 0; + int total_downloads = 0; + int page_views = 0; + int openaire_downloads = 0; + int openaire_views = 0; + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + try { + connection = usageStatsDB.getConnection(); + st = connection.prepareStatement(query); + int i = 1; + for (String s : values) { + st.setString(i, s); + i++; + } + + String redis_key = MD5(st.toString()); + + String redis_result = jedis.get(redis_key, "result"); + if (redis_result != null) { + return fromJson(redis_result); + } + + rs = st.executeQuery(); + if (type.equals("result")) { + while (rs.next()) { + if (rs.getString(1).equals("views") && rs.getString(4) != null && !rs.getString(4).equals("") && !rs.getString(4).equals("null")) { + usageStats.addViews(new RepositoryStats(rs.getString(3), rs.getString(2), rs.getString(4), rs.getString(5))); + total_views += Integer.parseInt(rs.getString(4)); + openaire_views += Integer.parseInt(rs.getString(5)); + } else if (rs.getString(1).equals("downloads") && rs.getString(4) != null && !rs.getString(4).equals("") && !rs.getString(4).equals("null")) { + usageStats.addDownloads(new RepositoryStats(rs.getString(3), rs.getString(2), rs.getString(4), "0")); + total_downloads += Integer.parseInt(rs.getString(4)); + openaire_downloads += Integer.parseInt(rs.getString(5)); + } else if (rs.getString(1).equals("pageviews") && rs.getString(4) != null && !rs.getString(4).equals("") && !rs.getString(4).equals("null")) { + page_views = Integer.parseInt(rs.getString(4)); + } + } + usageStats.setTotal_views(Integer.toString(total_views)); + usageStats.setTotal_downloads(Integer.toString(total_downloads)); + usageStats.setPageViews(Integer.toString(page_views)); + usageStats.setTotal_openaire_views(Integer.toString(openaire_views)); + usageStats.setTotal_openaire_downloads(Integer.toString(openaire_downloads)); + } else if (type.equals("project") || type.equals("datasource")) { + while (rs.next()) { + if (rs.getString(1).equals("views") && rs.getString(2) != null && !rs.getString(2).equals("") && !rs.getString(2).equals("null")) { + total_views += Integer.parseInt(rs.getString(2)); + openaire_views += Integer.parseInt(rs.getString(3)); + } else if (rs.getString(1).equals("downloads") && rs.getString(2) != null && !rs.getString(2).equals("") && !rs.getString(2).equals("null")) { + total_downloads += Integer.parseInt(rs.getString(2)); + openaire_downloads += Integer.parseInt(rs.getString(3)); + } else if (rs.getString(1).equals("pageviews") && rs.getString(2) != null && !rs.getString(2).equals("") && !rs.getString(2).equals("null")) { + page_views = Integer.parseInt(rs.getString(2)); + } + /* + else if (rs.getString(1).equals("openaire") && rs.getString(2) != null && !rs.getString(2).equals("") && !rs.getString(2).equals("null")) { + openaire = Integer.parseInt(rs.getString(2)); + } + */ + + } + usageStats.setTotal_views(Integer.toString(total_views)); + usageStats.setTotal_downloads(Integer.toString(total_downloads)); + usageStats.setPageViews(Integer.toString(page_views)); + usageStats.setTotal_openaire_views(Integer.toString(openaire_views)); + usageStats.setTotal_openaire_downloads(Integer.toString(openaire_downloads)); + } + + jedis.put(redis_key, "persistent", "false"); + jedis.put(redis_key, "query", st.toString()); + //jedis.put(redis_key, "result", toString(usageStats)); + jedis.put(redis_key, "result", toJson(usageStats)); + jedis.put(redis_key, "fetchMode", "3"); + + } catch (Exception e) { + log.error("Cannot execute query2 : ", e); + + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + return usageStats; + } + + public TotalStats executeTotalStats() { + TotalStats totalStats = null; + try { + String redis_result = jedis.get("total_stats", "result"); + if (redis_result != null) { + totalStats = fromJsonTotalStats(redis_result); + } else { + return updateTotalStats(); + } + } catch (Exception e) { + log.error("Cannot execute totalStats : ", e); + } + return totalStats; + } + + public TotalStats updateTotalStats() { + TotalStats totalStats = new TotalStats(); + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + HashMap> monthlyStatsMap = new HashMap<>(); + + try { + connection = usageStatsDB.getConnection(); + //st = connection.prepareStatement("SELECT count(distinct d.repository_id) AS repository, count(distinct d.result_id) AS items, sum(d.count) AS downloads, sum(v.count) AS views from public.downloads_stats d FULL OUTER JOIN public.views_stats v ON d.source=v.source AND d.repository_id=v.repository_id AND d.result_id=v.result_id AND d.date=v.date;"); + st = connection.prepareStatement("SELECT ndv(distinct repository_id) AS repository, ndv(distinct result_id) AS items, sum(downloads) AS downloads, sum(views) AS views FROM "+usagestatsImpalaDB+".usage_stats;"); + rs = st.executeQuery(); + rs.next(); + totalStats.setRepositories(rs.getInt(1)); + totalStats.setItems(rs.getInt(2)); + totalStats.setDownloads(rs.getInt(3)); + totalStats.setViews(rs.getInt(4)); + rs.close(); + st.close(); + + //st = connection.prepareStatement("select coalesce(d.date,v.date) as month, count(distinct d.repository_id) as repository, count(distinct d.result_id) as items, sum(d.count) as downloads, sum(v.count) as views from public.downloads_stats d FULL OUTER JOIN public.views_stats v ON d.source=v.source AND d.repository_id=v.repository_id AND d.result_id=v.result_id AND d.date=v.date group by month order by month;"); + st = connection.prepareStatement("SELECT `date`, ndv(distinct repository_id) AS repository, ndv(distinct result_id) AS items, sum(downloads) AS downloads, sum(views) AS views FROM "+usagestatsImpalaDB+".usage_stats GROUP BY `date` ORDER BY `date`;"); + rs = st.executeQuery(); + while (rs.next()) { + int year = Integer.parseInt(rs.getString(1).substring(0, 4)); + int month = Integer.parseInt(rs.getString(1).substring(5)); + MonthlyStats monthlyStats = new MonthlyStats(); + monthlyStats.setMonth(month); + monthlyStats.setRepositories(rs.getInt(2)); + monthlyStats.setItems(rs.getInt(3)); + monthlyStats.setDownloads(rs.getInt(4)); + monthlyStats.setViews(rs.getInt(5)); + + if (monthlyStatsMap.get(year) != null) { + monthlyStatsMap.get(year).add(monthlyStats); + } else { + List newList = new ArrayList<>(); + newList.add(monthlyStats); + monthlyStatsMap.put(year, newList); + + } + } + rs.close(); + st.close(); + + //st = connection.prepareStatement("SELECT COALESCE(SUBSTRING(d.date FROM 1 FOR 4), SUBSTRING(v.date FROM 1 FOR 4)) AS year, COUNT(DISTINCT d.repository_id) AS repository, COUNT(DISTINCT d.result_id) AS items, SUM(d.count) AS downloads, SUM(v.count) AS views FROM public.downloads_stats d FULL OUTER JOIN public.views_stats v ON d.source=v.source AND d.repository_id=v.repository_id AND d.result_id=v.result_id AND d.date=v.date GROUP BY year ORDER BY year;"); + st = connection.prepareStatement("SELECT SUBSTR(`date`,1,4) AS year, ndv(DISTINCT repository_id) AS repository, \n" + + "ndv(DISTINCT result_id) AS items, SUM(downloads) AS downloads, SUM(views) AS views \n" + + "FROM "+usagestatsImpalaDB+".usage_stats GROUP BY year ORDER BY year;"); + rs = st.executeQuery(); + List yearlyStatsList = new ArrayList<>(); + while (rs.next()) { + YearlyStats yearlyStats = new YearlyStats(); + yearlyStats.setYear(rs.getInt(1)); + yearlyStats.setRepositories(rs.getInt(2)); + yearlyStats.setItems(rs.getInt(3)); + yearlyStats.setDownloads(rs.getInt(4)); + yearlyStats.setViews(rs.getInt(5)); + yearlyStats.setMonthlyStats(monthlyStatsMap.get(rs.getInt(1))); + yearlyStatsList.add(yearlyStats); + } + totalStats.setYearlyStats(yearlyStatsList); + jedis.put("total_stats", "result", toJson(totalStats)); + jedis.put("total_stats", "persistent", "false"); + + } catch (Exception e) { + log.error("Cannot execute totalStats : ", e); + + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + return totalStats; + } + + private static TotalStats fromJsonTotalStats(String string) throws java.io.IOException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(string, TotalStats.class); + } + + public String executeRepoId(String repositoryIdentifier, String report) { + PreparedStatement st = null; + Connection connection = null; + ResultSet rs = null; + log.info("database "+statsDB); + try { + connection = usageStatsDB.getConnection(); + String[] split = repositoryIdentifier.split(":"); + String openaire_id = "-1"; + switch (split[0].toLowerCase()) { + case "openaire": + if (!report.equals("jr1")) { + st = connection.prepareStatement("select id from "+statsDB+".datasource where id=?"); + st.setString(1, repositoryIdentifier.replaceFirst(split[0] + ":", "")); + } else { + st = connection.prepareStatement("select id from "+statsDB+".datasource where id=? AND (type='Journal' OR type='Journal Aggregator/Publisher')"); + st.setString(1, repositoryIdentifier.replaceFirst(split[0] + ":", "")); + } + + rs = st.executeQuery(); + while (rs.next()) { + openaire_id = rs.getString(1); + } + return openaire_id; + + case "opendoar": + if (!report.equals("jr1")) { + st = connection.prepareStatement("select id from "+statsDB+".datasource_oids where oid=?"); + st.setString(1, "opendoar____::" + repositoryIdentifier.replaceFirst(split[0] + ":", "")); + } else { + st = connection.prepareStatement("select distinct d.id from "+statsDB+".datasource d, "+statsDB+".datasource_oids di where di.oid=? and d.id=di.id and (type='Journal' OR type='Journal Aggregator/Publisher')"); + st.setString(1, "opendoar____::" + repositoryIdentifier.replaceFirst(split[0] + ":", "")); + } + + rs = st.executeQuery(); + while (rs.next()) { + openaire_id = rs.getString(1); + } + return openaire_id; + case "issn": + st = connection.prepareStatement("select distinct d.id from "+statsDB+".datasource d, "+statsDB+".datasource_oids di, "+statsDB+".datasource_results dr where d.id=dr.id and di.oid like ? and d.id=di.id and (type='Journal' OR type='Journal Aggregator/Publisher')"); + st.setString(1, "%" + repositoryIdentifier.replaceFirst(split[0] + ":", "") + "%"); + + rs = st.executeQuery(); + while (rs.next()) { + openaire_id = rs.getString(1); + } + return openaire_id; + default: + return "-1"; + } + } catch (Exception e) { + log.error("Repository id failed: ", e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + return "-1"; + } + + public void executeItem(List reportItems, String itemIdentifier, String repositoryIdentifier, String itemDataType, Date beginDate, Date endDate, String granularity) { + String[] split = itemIdentifier.split(":"); + switch (split[0].toLowerCase()) { + case "oid": + executeOid(reportItems, itemIdentifier.replaceFirst(split[0] + ":", ""), repositoryIdentifier, itemDataType, beginDate, endDate, granularity); + break; + case "doi": + executeDoi(reportItems, itemIdentifier.replaceFirst(split[0] + ":", ""), repositoryIdentifier, itemDataType, beginDate, endDate, granularity); + break; + case "openaire": + executeOpenaire(reportItems, itemIdentifier.replaceFirst(split[0] + ":", ""), repositoryIdentifier, itemDataType, beginDate, endDate, granularity); + break; + default: + } + } + + private void executeOid(List reportItems, String oid, String repositoryIdentifier, String itemDataType, Date beginDate, Date endDate, String granularity) { + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + try { + connection = usageStatsDB.getConnection(); + //st = connection.prepareStatement("SELECT DISTINCT roid.id FROM public.result_oids roid, public.downloads_stats s WHERE s.result_id=roid.id AND roid.orid=? UNION SELECT DISTINCT roid.id FROM public.result_oids roid, public.views_stats s WHERE s.result_id=roid.id AND roid.orid=?"); + st = connection.prepareStatement("SELECT DISTINCT roid.id FROM "+statsDB+".result_oids roid, "+usagestatsImpalaDB+".usage_stats us WHERE us.result_id=roid.id AND roid.oid=?"); + st.setString(1, oid); + //st.setString(2, oid); + + rs = st.executeQuery(); + + while (rs.next()) { + executeOpenaire(reportItems, rs.getString(1), repositoryIdentifier, itemDataType, beginDate, endDate, granularity); + } + connection.close(); + } catch (Exception e) { + log.error("Oid to OpenAIRE id failed: ", e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + } + + private void executeDoi(List reportItems, String doi, String repositoryIdentifier, String itemDataType, Date beginDate, Date endDate, String granularity) { + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + try { + connection = usageStatsDB.getConnection(); + //st = connection.prepareStatement("SELECT DISTINCT poid.id FROM public.result_pids poid, public.downloads_stats s WHERE s.result_id=poid.id AND poid.type='doi' AND poid.pid=? UNION SELECT DISTINCT poid.id FROM public.result_pids poid, public.views_stats s WHERE s.result_id=poid.id AND poid.type='doi' AND poid.pid=?"); + st = connection.prepareStatement("SELECT DISTINCT poid.id FROM "+statsDB+".result_pids poid, "+usageStatsDB+".usage_stats us WHERE us.result_id=poid.id AND poid.type='Digital Object Identifier' AND poid.pid=?"); + st.setString(1, doi); + //st.setString(2, doi); + + rs = st.executeQuery(); + + while (rs.next()) { + executeOpenaire(reportItems, rs.getString(1), repositoryIdentifier, itemDataType, beginDate, endDate, granularity); + } + } catch (Exception e) { + log.error("Doi to OpenAIRE id failed: ", e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + } + + private void executeOpenaire(List reportItems, String openaire, String repositoryIdentifier, String itemDataType, Date beginDate, Date endDate, String granularity) { + SimpleDateFormat report_dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat postgresFormat = new SimpleDateFormat("yyyy/MM"); + String beginDateStr = postgresFormat.format(beginDate); + String endDateStr = postgresFormat.format(endDate); + + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + + /* + Calendar startCalendar = Calendar.getInstance(); + startCalendar.setTime(beginDate); + Calendar endCalendar = Calendar.getInstance(); + endCalendar.setTime(endDate); + int diffYear = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR); + int diffMonth = diffYear * 12 + endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH); + */ + try { + connection = usageStatsDB.getConnection(); + if (repositoryIdentifier.equals("")) { + if (itemDataType.equals("")) { + //st = connection.prepareStatement("SELECT res.repository_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.ddate, oids.orid, res.downloads, res.views FROM (SELECT coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.result_id, vs.result_id) AS result_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.downloads_stats s WHERE s.date>=? AND s.date<=? AND s.result_id=? GROUP BY s.repository_id, s.result_id, s.date) AS ds FULL OUTER JOIN (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.views_stats s WHERE s.date>=? AND s.date<=? AND s.result_id=? GROUP BY s.repository_id, s.result_id, s.date) AS vs ON ds.result_id=vs.result_id AND ds.date=vs.date) AS res JOIN public.result r ON res.result_id=r.id JOIN public.datasource d ON d.id=res.repository_id JOIN public.result_classifications rc ON rc.id=r.id LEFT JOIN (SELECT pids.id, string_agg(pids.pid, '#!#') AS pid FROM public.result_pids pids WHERE pids.id=? AND type='doi' GROUP BY pids.id) AS pids ON pids.id=r.id LEFT JOIN (SELECT oids.id, string_agg(oids.orid, '#!#') AS orid FROM public.result_oids oids WHERE oids.id=? GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.repository_id, res.ddate;"); + //st = connection.prepareStatement("SELECT res.repository_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.date, oids.orid, res.downloads, res.views FROM (SELECT us.repository_id, us.result_id, us.date, us.downloads, us.views FROM usage_stats us WHERE us.date>=? AND us.date<=? AND us.result_id=?) AS res JOIN public.result r ON res.result_id=r.id JOIN public.datasource d ON d.id=res.repository_id JOIN public.result_classifications rc ON rc.id=r.id LEFT JOIN (SELECT pids.id, string_agg(pids.pid, '#!#') AS pid FROM public.result_pids pids WHERE pids.id=? AND type='doi' GROUP BY pids.id) AS pids ON pids.id=r.id LEFT JOIN (SELECT oids.id, string_agg(oids.orid, '#!#') AS orid FROM public.result_oids oids WHERE oids.id=? GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.repository_id, res.date;"); + st = connection.prepareStatement("SELECT distinct res.repository_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.`date`, oids.oid, res.downloads, res.views " + + "FROM (SELECT us.repository_id, us.result_id, us.`date`, us.downloads, us.views FROM "+usagestatsImpalaDB+".usage_stats us " + + "WHERE us.`date`>=? AND us.`date`<=? AND us.result_id=?) AS res " + + "JOIN "+statsDB+".result r ON res.result_id=r.id " + + "JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN (select id, group_concat(type,',') as type FROM "+statsDB+".result_classifications where id=? " + + "GROUP by id) rc ON rc.id=r.id " + + "LEFT JOIN (SELECT pids.id, group_concat(pids.pid, '#!#') AS pid FROM "+statsDB+".result_pids pids " + + "WHERE pids.id=? AND type='Digital Object Identifier' GROUP BY pids.id) AS pids ON pids.id=r.id " + + "LEFT JOIN (SELECT id, group_concat(oids.oid, '#!#') AS oid FROM "+statsDB+".result_oids oids " + + "WHERE oids.id=? GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.repository_id, res.`date`;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, openaire); + //st.setString(4, beginDateStr); + //st.setString(5, endDateStr); + //st.setString(6, openaire); + st.setString(4, openaire); + st.setString(5, openaire); + st.setString(6, openaire); + } else { + //st = connection.prepareStatement("SELECT res.repository_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.ddate, oids.orid, res.downloads, res.views FROM (SELECT coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.result_id, vs.result_id) AS result_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.downloads_stats s WHERE s.date>=? AND s.date<=? AND s.result_id=? GROUP BY s.repository_id, s.result_id, s.date) AS ds FULL OUTER JOIN (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.views_stats s WHERE s.date>=? AND s.date<=? AND s.result_id=? GROUP BY s.repository_id, s.result_id, s.date) AS vs ON ds.result_id=vs.result_id AND ds.date=vs.date) AS res JOIN public.result r ON res.result_id=r.id JOIN public.datasource d ON d.id=res.repository_id JOIN public.result_classifications rc ON rc.id=r.id AND rc.type=? LEFT JOIN (SELECT pids.id, string_agg(pids.pid, '#!#') AS pid FROM public.result_pids pids WHERE pids.id=? AND type='doi' GROUP BY pids.id) AS pids ON pids.id=r.id LEFT JOIN (SELECT oids.id, string_agg(oids.orid, '#!#') AS orid FROM public.result_oids oids WHERE oids.id=? GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.repository_id, res.ddate;"); + st = connection.prepareStatement("SELECT distinct res.repository_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.`date`, oids.oid, res.downloads, " + + "res.views FROM (SELECT us.repository_id, us.result_id, us.`date`, us.downloads, us.views FROM "+usagestatsImpalaDB+".usage_stats us " + + "WHERE us.`date`>=? AND us.`date`<=? AND us.result_id=?) AS res " + + "JOIN "+statsDB+".result r ON res.result_id=r.id " + + "JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".result_classifications rc ON rc.id=r.id AND rc.type=? " + + "LEFT JOIN (SELECT pids.id, group_concat(pids.pid, '#!#') AS pid " + + "FROM "+statsDB+".result_pids pids WHERE pids.id=? " + + "AND type='Digital Object Identifier' GROUP BY pids.id) AS pids ON pids.id=r.id " + + "LEFT JOIN (SELECT oids.id, group_concat(oids.oid, '#!#') AS oid " + + "FROM "+statsDB+".result_oids oids WHERE oids.id=? " + + "GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.repository_id, res.`date`;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, openaire); + //st.setString(4, beginDateStr); + //st.setString(5, endDateStr); + //st.setString(6, openaire); + st.setString(4, itemDataType); + st.setString(5, openaire); + st.setString(6, openaire); + } + } else { + if (itemDataType.equals("")) { + //st = connection.prepareStatement("SELECT res.repository_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.ddate, oids.orid, res.downloads, res.views FROM (SELECT coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.result_id, vs.result_id) AS result_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.downloads_stats s WHERE s.date>=? AND s.date<=? AND s.result_id=? AND s.repository_id=? GROUP BY s.repository_id, s.result_id, s.date) AS ds FULL OUTER JOIN (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.views_stats s WHERE s.date>=? AND s.date<=? AND s.result_id=? AND s.repository_id=? GROUP BY s.repository_id, s.result_id, s.date) AS vs ON ds.result_id=vs.result_id AND ds.date=vs.date) AS res JOIN public.result r ON res.result_id=r.id JOIN public.datasource d ON d.id=res.repository_id JOIN public.result_classifications rc ON rc.id=r.id LEFT JOIN (SELECT pids.id, string_agg(pids.pid, '#!#') AS pid FROM public.result_pids pids WHERE pids.id=? AND type='doi' GROUP BY pids.id) AS pids ON pids.id=r.id LEFT JOIN (SELECT oids.id, string_agg(oids.orid, '#!#') AS orid FROM public.result_oids oids WHERE oids.id=? GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.repository_id, res.ddate;"); + st = connection.prepareStatement("SELECT distinct res.repository_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.`date`, oids.oid, res.downloads, res.views " + + "FROM (SELECT us.repository_id, us.result_id, us.`date`, us.downloads, us.views " + + "FROM "+usagestatsImpalaDB+".usage_stats us WHERE us.`date`>=? AND us.`date`<=? AND us.result_id=? AND us.repository_id=?) AS res " + + "JOIN "+statsDB+".result r ON res.result_id=r.id JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN (select id, group_concat(type,',') as type from "+statsDB+".result_classifications where id=? group by id) rc ON rc.id=r.id " + + "LEFT JOIN (SELECT pids.id, group_concat(pids.pid, '#!#') AS pid FROM "+statsDB+".result_pids pids " + + "WHERE pids.id=? AND type='Digital Object Identifier' GROUP BY pids.id) AS pids ON pids.id=r.id " + + "LEFT JOIN (SELECT oids.id, group_concat(oids.oid, '#!#') AS oid FROM "+statsDB+".result_oids oids " + + "WHERE oids.id=? GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.repository_id, res.`date`;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, openaire); + st.setString(4, repositoryIdentifier); + //st.setString(5, beginDateStr); + //st.setString(6, endDateStr); + //st.setString(7, openaire); + //st.setString(8, repositoryIdentifier); + st.setString(5, openaire); + st.setString(6, openaire); + st.setString(7, openaire); + } else { + //st = connection.prepareStatement("SELECT res.repository_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.ddate, oids.orid, res.downloads, res.views FROM (SELECT coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.result_id, vs.result_id) AS result_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.downloads_stats s WHERE s.date>=? AND s.date<=? AND s.result_id=? AND s.repository_id=? GROUP BY s.repository_id, s.result_id, s.date) AS ds FULL OUTER JOIN (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.views_stats s WHERE s.date>=? AND s.date<=? AND s.result_id=? AND s.repository_id=? GROUP BY s.repository_id, s.result_id, s.date) AS vs ON ds.result_id=vs.result_id AND ds.date=vs.date) AS res JOIN public.result r ON res.result_id=r.id JOIN public.datasource d ON d.id=res.repository_id JOIN public.result_classifications rc ON rc.id=r.id AND rc.type=? LEFT JOIN (SELECT pids.id, string_agg(pids.pid, '#!#') AS pid FROM public.result_pids pids WHERE pids.id=? AND type='doi' GROUP BY pids.id) AS pids ON pids.id=r.id LEFT JOIN (SELECT oids.id, string_agg(oids.orid, '#!#') AS orid FROM public.result_oids oids WHERE oids.id=? GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.repository_id, res.ddate;"); + st = connection.prepareStatement("SELECT distinct res.repository_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.`date`, oids.oid, res.downloads,res.views " + + "FROM (SELECT us.repository_id, us.result_id, us.`date`, us.downloads, us.views FROM "+usagestatsImpalaDB+".usage_stats us " + + "WHERE us.`date`>=? AND us.`date`<=? AND us.result_id=? AND us.repository_id=?) AS res " + + "JOIN "+statsDB+".result r ON res.result_id=r.id JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".result_classifications rc ON rc.id=r.id AND rc.type=?' " + + "LEFT JOIN (SELECT pids.id, group_concat(pids.pid, '#!#') AS pid FROM "+statsDB+".result_pids pids " + + "WHERE pids.id=? AND type='Digital Object Identifier' GROUP BY pids.id) AS pids ON pids.id=r.id " + + "LEFT JOIN (SELECT oids.id, group_concat(oids.oid, '#!#') AS oid " + + "FROM "+statsDB+".result_oids oids WHERE oids.id=? " + + "GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.repository_id, res.`date`;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, openaire); + st.setString(4, repositoryIdentifier); + //st.setString(5, beginDateStr); + //st.setString(6, endDateStr); + //st.setString(7, openaire); + //st.setString(8, repositoryIdentifier); + st.setString(5, itemDataType); + st.setString(6, openaire); + st.setString(7, openaire); + } + } + + rs = st.executeQuery(); + String repository = ""; + String lastDate = ""; + ReportItem reportItem = null; + int ft_total = 0; + int abstr = 0; + + if (granularity.equalsIgnoreCase("totals")) { + while (rs.next()) { + if (!rs.getString(1).equals(repository)) { + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(beginDate), report_dateFormat.format(endDate), Integer.toString(ft_total), Integer.toString(abstr))); + reportItems.add(reportItem); + } + repository = rs.getString(1); + reportItem = new ReportItem(rs.getString(3), rs.getString(7), rs.getString(5), rs.getString(2)); + reportItem.addIdentifier(new ItemIdentifier("OpenAIRE", openaire)); + reportItem.addIdentifier(new ItemIdentifier("URLs", rs.getString(4))); + if (rs.getString(9) != null && !rs.getString(9).equals("")) { + if (rs.getString(9).contains("#!#")) { + reportItem.addIdentifier(new ItemIdentifier("OAI", rs.getString(9).substring(0, rs.getString(9).indexOf("#!#")))); + } else { + reportItem.addIdentifier(new ItemIdentifier("OAI", rs.getString(9))); + } + } + if (rs.getString(6) != null && !rs.getString(6).equals("")) { + if (rs.getString(6).contains("#!#")) { + reportItem.addIdentifier(new ItemIdentifier("DOI", rs.getString(6).substring(0, rs.getString(6).indexOf("#!#")))); + } else { + reportItem.addIdentifier(new ItemIdentifier("DOI", rs.getString(6))); + } + } + ft_total = 0; + abstr = 0; + } + ft_total += rs.getInt(10); + abstr += rs.getInt(11); + } + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(beginDate), report_dateFormat.format(endDate), Integer.toString(ft_total), Integer.toString(abstr))); + reportItems.add(reportItem); + } + } else if (granularity.equalsIgnoreCase("monthly")) { + Calendar endCal = Calendar.getInstance(); + endCal.setTime(postgresFormat.parse(endDateStr)); + endCal.add(Calendar.MONTH, 1); + Date endDateForZeros = endCal.getTime(); + while (rs.next()) { + if (!rs.getString(1).equals(repository)) { + if (reportItem != null) { + fillWithZeros(postgresFormat.parse(lastDate), endDateForZeros, reportItem); + reportItems.add(reportItem); + } + repository = rs.getString(1); + lastDate = beginDateStr; + reportItem = new ReportItem(rs.getString(3), rs.getString(7), rs.getString(5), rs.getString(2)); + reportItem.addIdentifier(new ItemIdentifier("OpenAIRE", openaire)); + reportItem.addIdentifier(new ItemIdentifier("URLs", rs.getString(4))); + if (rs.getString(9) != null && !rs.getString(9).equals("")) { + if (rs.getString(9).contains("#!#")) { + String allOAIs = rs.getString(9); + String[] oaiArray = allOAIs.split("#!#"); + for (int i = 0; i < oaiArray.length; i++) { + reportItem.addIdentifier(new ItemIdentifier("OAI", oaiArray[i])); + } + //reportItem.addIdentifier(new ItemIdentifier("OAI", rs.getString(9).substring(0, rs.getString(9).indexOf("#!#")))); + + //reportItem.addIdentifier(new ItemIdentifier("OAI", rs.getString(9).substring(0, rs.getString(9).indexOf("#!#")))); + } else { + reportItem.addIdentifier(new ItemIdentifier("OAI", rs.getString(9))); + } + } + if (rs.getString(6) != null && !rs.getString(6).equals("")) { + if (rs.getString(6).contains("#!#")) { + reportItem.addIdentifier(new ItemIdentifier("DOI", rs.getString(6).substring(0, rs.getString(6).indexOf("#!#")))); + } else { + reportItem.addIdentifier(new ItemIdentifier("DOI", rs.getString(6))); + } + } + } + fillWithZeros(postgresFormat.parse(lastDate), postgresFormat.parse(rs.getString(8)), reportItem); + Calendar endC = Calendar.getInstance(); + endC.setTime(postgresFormat.parse(rs.getString(8))); + endC.set(Calendar.DATE, endC.getActualMaximum(Calendar.DATE)); + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(postgresFormat.parse(rs.getString(8))), report_dateFormat.format(endC.getTime()), rs.getString(10), rs.getString(11))); + } + endC.setTime(postgresFormat.parse(rs.getString(8))); + endC.add(Calendar.MONTH, 1); + lastDate = postgresFormat.format(endC.getTime()); + } + if (reportItem != null) { + fillWithZeros(postgresFormat.parse(lastDate), endDateForZeros, reportItem); + reportItems.add(reportItem); + } + } + } catch (Exception e) { + log.error("Single Item Report failed: ", e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + } + + public void executeRepo(List reportItems, String repositoryIdentifier, String itemDataType, Date beginDate, Date endDate, String granularity) { + SimpleDateFormat report_dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat postgresFormat = new SimpleDateFormat("yyyy/MM"); + String beginDateStr = postgresFormat.format(beginDate); + String endDateStr = postgresFormat.format(endDate); + + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + + try { + connection = usageStatsDB.getConnection(); + + if (repositoryIdentifier.equals("")) { + if (itemDataType.equals("")) { + //st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.orid, res.ddate, res.downloads, res.views FROM (SELECT coalesce(ds.source, vs.source), coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.downloads_stats s WHERE s.date>=? AND s.date<=? GROUP BY s.source, s.repository_id, s.date) AS ds FULL OUTER JOIN (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.views_stats s WHERE s.date>=? AND s.date<=? GROUP BY s.source, s.repository_id, s.date) AS vs ON ds.source=vs.source AND ds.repository_id=vs.repository_id AND ds.date=vs.date) AS res JOIN public.datasource d ON d.id=res.repository_id JOIN public.datasource_oids dois ON d.id=dois.id WHERE dois.orid LIKE 'opendoar%' ORDER BY d.id, d.name, res.ddate ASC;"); + st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.oid, res.`date`, res.downloads, res.views " + + "FROM (SELECT us.source, us.repository_id, us.`date`, sum(us.downloads) AS downloads, sum(us.views) AS views " + + "FROM "+usagestatsImpalaDB+".usage_stats us WHERE us.`date`>=? AND us.`date`<=? GROUP BY us.source, us.repository_id, us.`date`) " + + "AS res JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".datasource_oids dois ON d.id=dois.id WHERE dois.oid " + + "LIKE 'opendoar%' ORDER BY d.id, d.name, res.`date` ASC;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + //st.setString(3, beginDateStr); + //st.setString(4, endDateStr); + } else { + //st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.orid, res.ddate, res.downloads, res.views FROM (SELECT coalesce(ds.source, vs.source), coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.downloads_stats s, result_classifications rc WHERE rc.id=s.result_id AND s.date>=? AND s.date<=? AND rc.type=? GROUP BY s.source, s.repository_id, s.date) AS ds FULL OUTER JOIN (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.views_stats s, public.result_classifications rc WHERE rc.id=s.result_id AND s.date>=? AND s.date<=? AND rc.type=? GROUP BY s.source, s.repository_id, s.date) AS vs ON ds.source=vs.source AND ds.repository_id=vs.repository_id AND ds.date=vs.date) AS res JOIN public.datasource d ON d.id=res.repository_id JOIN public.datasource_oids dois ON d.id=dois.id WHERE dois.orid LIKE 'opendoar%' ORDER BY d.id, d.name, res.ddate ASC;"); + st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.oid, res.`date`, res.downloads, res.views " + + "FROM (SELECT us.source, us.repository_id, us.`date`, sum(us.downloads) AS downloads, sum(us.views) AS views " + + "FROM "+usagestatsImpalaDB+".usage_stats us, "+statsDB+".result_classifications rc " + + "WHERE rc.id=us.result_id AND us.`date`>=? AND us.`date`<=? AND rc.type=? " + + "GROUP BY us.source, us.repository_id, us.`date`) AS res " + + "JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".datasource_oids dois ON d.id=dois.id WHERE dois.oid LIKE 'opendoar%' " + + "ORDER BY d.id, d.name, res.`date` ASC;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, itemDataType); + //st.setString(4, beginDateStr); + //st.setString(5, endDateStr); + //st.setString(6, itemDataType); + } + } else { + if (itemDataType.equals("")) { + //st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.orid, res.ddate, res.downloads, res.views FROM (SELECT coalesce(ds.source, vs.source), coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.downloads_stats s WHERE s.date>=? AND s.date<=? AND s.repository_id=? GROUP BY s.source, s.repository_id, s.date) AS ds FULL OUTER JOIN (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.views_stats s WHERE s.date>=? AND s.date<=? AND s.repository_id=? GROUP BY s.source, s.repository_id, s.date) AS vs ON ds.source=vs.source AND ds.repository_id=vs.repository_id AND ds.date=vs.date) AS res JOIN public.datasource d ON d.id=res.repository_id JOIN public.datasource_oids dois ON d.id=dois.id WHERE dois.orid LIKE 'opendoar%' ORDER BY d.id, d.name, res.ddate ASC;"); + st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.oid, res.`date`, res.downloads, res.views " + + "FROM (SELECT us.source, us.repository_id, us.`date`, sum(us.downloads) AS downloads, sum(us.views) AS views " + + "FROM "+usagestatsImpalaDB+".usage_stats us WHERE us.`date`>=? AND us.`date`<=? AND us.repository_id=? " + + "GROUP BY us.source, us.repository_id, us.`date`) AS res " + + "JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".datasource_oids dois ON d.id=dois.id " + + "WHERE dois.oid LIKE 'opendoar%' ORDER BY d.id, d.name, res.`date` ASC;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, repositoryIdentifier); + //st.setString(4, beginDateStr); + //st.setString(5, endDateStr); + //st.setString(6, repositoryIdentifier); + } else { + //st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.orid, res.ddate, res.downloads, res.views FROM (SELECT coalesce(ds.source, vs.source), coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.downloads_stats s, public.result_classifications rc WHERE rc.id=s.result_id AND s.date>=? AND s.date<=? AND rc.type=? AND s.repository_id=? GROUP BY s.source, s.repository_id, s.date) AS ds FULL OUTER JOIN (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.views_stats s, public.result_classifications rc WHERE rc.id=s.result_id AND s.date>=? AND s.date<=? AND rc.type=? AND s.repository_id=? GROUP BY s.source, s.repository_id, s.date) AS vs ON ds.source=vs.source AND ds.repository_id=vs.repository_id AND ds.date=vs.date) AS res JOIN public.datasource d ON d.id=res.repository_id JOIN public.datasource_oids dois ON d.id=dois.id WHERE dois.orid LIKE 'opendoar%' ORDER BY d.id, d.name, res.ddate ASC;"); + st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.oid, res.`date`, res.downloads, res.views " + + "FROM (SELECT us.source, us.repository_id, us.`date`, sum(us.downloads) AS downloads, sum(us.views) AS views " + + "FROM "+usagestatsImpalaDB+".usage_stats us, "+statsDB+".result_classifications rc " + + "WHERE rc.id=us.result_id AND us.`date`>=? AND us.`date`<=? AND rc.type=? " + + "AND us.repository_id=? GROUP BY us.source, us.repository_id, us.`date`) AS res " + + "JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".datasource_oids dois ON d.id=dois.id " + + "WHERE dois.oid LIKE 'opendoar%' ORDER BY d.id, d.name, res.`date` ASC;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, itemDataType); + st.setString(4, repositoryIdentifier); + //st.setString(5, beginDateStr); + //st.setString(6, endDateStr); + //st.setString(7, itemDataType); + //st.setString(8, repositoryIdentifier); + } + } + //log.error("RR STATEMENT: " + st); + + /* + String redis_key = MD5(st.toString()); + + if (jedis.hasKey(redis_key, "result")) { + reportItems.addAll(reportItemsFromJson((String) jedis.get(redis_key, "result"))); + st.close(); + connection.close(); + return; + } + */ + rs = st.executeQuery(); + String repository = ""; + String lastDate = ""; + ReportItem reportItem = null; + + /* + Calendar startCalendar = Calendar.getInstance(); + startCalendar.setTime(beginDate); + Calendar endCalendar = Calendar.getInstance(); + endCalendar.setTime(endDate); + */ + int ft_total = 0; + int abstr = 0; + if (granularity.equalsIgnoreCase("totals")) { + while (rs.next()) { + if (!rs.getString(1).equals(repository)) { + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(beginDate), report_dateFormat.format(endDate), Integer.toString(ft_total), Integer.toString(abstr))); + reportItems.add(reportItem); + } + repository = rs.getString(1); + reportItem = new ReportItem(null, rs.getString(2), "Platform", null); + reportItem.addIdentifier(new ItemIdentifier("OpenAIRE", rs.getString(1))); + reportItem.addIdentifier(new ItemIdentifier("OpenDOAR", rs.getString(4).substring(rs.getString(4).lastIndexOf(":") + 1))); + reportItem.addIdentifier(new ItemIdentifier("URL", rs.getString(3))); + ft_total = 0; + abstr = 0; + } + ft_total += rs.getInt(6); + abstr += rs.getInt(7); + } + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(beginDate), report_dateFormat.format(endDate), Integer.toString(ft_total), Integer.toString(abstr))); + reportItems.add(reportItem); + } + } else if (granularity.equalsIgnoreCase("monthly")) { + Calendar endCal = Calendar.getInstance(); + endCal.setTime(postgresFormat.parse(endDateStr)); + endCal.add(Calendar.MONTH, 1); + Date endDateForZeros = endCal.getTime(); + while (rs.next()) { + if (!rs.getString(1).equals(repository)) { + if (reportItem != null) { + fillWithZeros(postgresFormat.parse(lastDate), endDateForZeros, reportItem); + reportItems.add(reportItem); + } + repository = rs.getString(1); + lastDate = beginDateStr; + reportItem = new ReportItem(null, rs.getString(2), "Platform", null); + reportItem.addIdentifier(new ItemIdentifier("OpenAIRE", rs.getString(1))); + reportItem.addIdentifier(new ItemIdentifier("OpenDOAR", rs.getString(4).substring(rs.getString(4).lastIndexOf(":") + 1))); + reportItem.addIdentifier(new ItemIdentifier("URL", rs.getString(3))); + } + fillWithZeros(postgresFormat.parse(lastDate), postgresFormat.parse(rs.getString(5)), reportItem); + Calendar endC = Calendar.getInstance(); + endC.setTime(postgresFormat.parse(rs.getString(5))); + endC.set(Calendar.DATE, endC.getActualMaximum(Calendar.DATE)); + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(postgresFormat.parse(rs.getString(5))), report_dateFormat.format(endC.getTime()), rs.getString(6), rs.getString(7))); + } + endC.setTime(postgresFormat.parse(rs.getString(5))); + endC.add(Calendar.MONTH, 1); + lastDate = postgresFormat.format(endC.getTime()); + } + if (reportItem != null) { + fillWithZeros(postgresFormat.parse(lastDate), endDateForZeros, reportItem); + reportItems.add(reportItem); + } + } + + /* + jedis.put(redis_key, "persistent", "false"); + jedis.put(redis_key, "query", st.toString()); + jedis.put(redis_key, "result", toJson(reportItems)); + jedis.put(redis_key, "fetchMode", "3"); + */ + rs.close(); + st.close(); + connection.close(); + } catch (Exception e) { + log.error("Repository Report failed: ", e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + } + + public void executeJournal(List reportItems, String repositoryIdentifier, String itemDataType, Date beginDate, Date endDate, String granularity) { + SimpleDateFormat report_dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat postgresFormat = new SimpleDateFormat("yyyy/MM"); + String beginDateStr = postgresFormat.format(beginDate); + String endDateStr = postgresFormat.format(endDate); + + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + + try { + connection = usageStatsDB.getConnection(); + + if (repositoryIdentifier.equals("")) { + if (itemDataType.equals("")) { + //st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.orid, res.ddate, res.downloads, res.views FROM (SELECT coalesce(ds.source, vs.source), coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.downloads_stats s WHERE s.date>=? AND s.date<=? GROUP BY s.source, s.repository_id, s.date) AS ds FULL OUTER JOIN (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.views_stats s WHERE s.date>=? AND s.date<=? GROUP BY s.source, s.repository_id, s.date) AS vs ON ds.source=vs.source AND ds.repository_id=vs.repository_id AND ds.date=vs.date) AS res JOIN public.datasource d ON d.id=res.repository_id JOIN public.datasource_oids dois ON d.id=dois.id WHERE (d.type='Journal' OR d.type='Journal Aggregator/Publisher') ORDER BY d.id, d.name, res.ddate ASC;"); + st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.oid, res.`date`, res.downloads, res.views " + + "FROM (SELECT us.source, us.repository_id, us.`date`, sum(us.downloads) as downloads, sum(us.views) as views " + + "FROM "+usagestatsImpalaDB+".usage_stats us WHERE us.`date`>=? AND us.`date`<=? GROUP BY us.source, us.repository_id, us.`date`) AS res " + + "JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".datasource_oids dois ON d.id=dois.id " + + "WHERE (d.type='Journal' OR d.type='Journal Aggregator/Publisher') ORDER BY d.id, d.name, res.`date` ASC;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + //st.setString(3, beginDateStr); + //st.setString(4, endDateStr); + } else { + //st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.orid, res.ddate, res.downloads, res.views FROM (SELECT coalesce(ds.source, vs.source), coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.downloads_stats s, public.result_classifications rc WHERE rc.id=s.result_id AND s.date>=? AND s.date<=? AND rc.type=? GROUP BY s.source, s.repository_id, s.date) AS ds FULL OUTER JOIN (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.views_stats s, public.result_classifications rc WHERE rc.id=s.result_id AND s.date>=? AND s.date<=? AND rc.type=? GROUP BY s.source, s.repository_id, s.date) AS vs ON ds.source=vs.source AND ds.repository_id=vs.repository_id AND ds.date=vs.date) AS res JOIN public.datasource d ON d.id=res.repository_id JOIN public.datasource_oids dois ON d.id=dois.id WHERE (d.type='Journal' OR d.type='Journal Aggregator/Publisher') ORDER BY d.id, d.name, res.ddate ASC;"); + st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.oid, res.`date`, res.downloads, res.views " + + "FROM (SELECT us.source, us.repository_id, us.`date`, sum(us.downloads) as downloads, sum(us.views) as views " + + "FROM "+usagestatsImpalaDB+".usage_stats us, "+statsDB+".result_classifications rc " + + "WHERE rc.id=us.result_id AND us.`date`>=? AND us.`date`<=? AND rc.type=? " + + "GROUP BY us.source, us.repository_id, us.`date`) AS res " + + "JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".datasource_oids dois ON d.id=dois.id " + + "WHERE (d.type='Journal' OR d.type='Journal Aggregator/Publisher') ORDER BY d.id, d.name, res.`date` ASC;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, itemDataType); + //st.setString(4, beginDateStr); + //st.setString(5, endDateStr); + //st.setString(6, itemDataType); + } + } else { + if (itemDataType.equals("")) { + //st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.orid, res.ddate, res.downloads, res.views FROM (SELECT coalesce(ds.source, vs.source), coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.downloads_stats s WHERE s.date>=? AND s.date<=? AND s.repository_id=? GROUP BY s.source, s.repository_id, s.date) AS ds FULL OUTER JOIN (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.views_stats s WHERE s.date>=? AND s.date<=? AND s.repository_id=? GROUP BY s.source, s.repository_id, s.date) AS vs ON ds.source=vs.source AND ds.repository_id=vs.repository_id AND ds.date=vs.date) AS res JOIN public.datasource d ON d.id=res.repository_id JOIN public.datasource_oids dois ON d.id=dois.id WHERE (d.type='Journal' OR d.type='Journal Aggregator/Publisher') ORDER BY d.id, d.name, res.ddate ASC;"); + st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.oid, res.`date`, res.downloads, res.views " + + "FROM (SELECT us.source, us.repository_id, us.`date`, sum(us.downloads) as downloads, sum(us.views) as views " + + "FROM "+usagestatsImpalaDB+".usage_stats us WHERE us.`date`>=? AND us.`date`<=? AND us.repository_id=? " + + "GROUP BY us.source, us.repository_id, us.`date`) AS res JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".datasource_oids dois ON d.id=dois.id " + + "WHERE (d.type='Journal' OR d.type='Journal Aggregator/Publisher') ORDER BY d.id, d.name, res.`date` ASC;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, repositoryIdentifier); + //st.setString(4, beginDateStr); + //st.setString(5, endDateStr); + //st.setString(6, repositoryIdentifier); + } else { + //st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.orid, res.ddate, res.downloads, res.views FROM (SELECT coalesce(ds.source, vs.source), coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.downloads_stats s, public.result_classifications rc WHERE rc.id=s.result_id AND s.date>=? AND s.date<=? AND rc.type=? AND s.repository_id=? GROUP BY s.source, s.repository_id, s.date) AS ds FULL OUTER JOIN (SELECT s.source, s.repository_id, s.date, sum(s.count) FROM public.views_stats s, public.result_classifications rc WHERE rc.id=s.result_id AND s.date>=? AND s.date<=? AND rc.type=? AND s.repository_id=? GROUP BY s.source, s.repository_id, s.date) AS vs ON ds.source=vs.source AND ds.repository_id=vs.repository_id AND ds.date=vs.date) AS res JOIN public.datasource d ON d.id=res.repository_id JOIN public.datasource_oids dois ON d.id=dois.id WHERE (d.type='Journal' OR d.type='Journal Aggregator/Publisher') ORDER BY d.id, d.name, res.ddate ASC;"); + st = connection.prepareStatement("SELECT d.id, d.name, d.websiteurl, dois.oid, res.`date`, res.downloads, res.views " + + "FROM (SELECT us.source, us.repository_id, us.`date`, sum(us.downloads) as downloads, sum(us.views) as views " + + "FROM "+usagestatsImpalaDB+".usage_stats us, "+statsDB+".result_classifications rc WHERE rc.id=us.result_id " + + "AND us.`date`>=?' AND us.`date`<=? AND rc.type=? AND us.repository_id=? " + + "GROUP BY us.source, us.repository_id, us.`date`) AS res " + + "JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".datasource_oids dois ON d.id=dois.id " + + "WHERE (d.type='Journal' OR d.type='Journal Aggregator/Publisher') ORDER BY d.id, d.name, res.`date` ASC;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, itemDataType); + st.setString(4, repositoryIdentifier); + //st.setString(5, beginDateStr); + //st.setString(6, endDateStr); + //st.setString(7, itemDataType); + //st.setString(8, repositoryIdentifier); + } + } + //log.error("RR STATEMENT: " + st); + + /* + String redis_key = MD5(st.toString()); + + if (jedis.hasKey(redis_key, "result")) { + reportItems.addAll(reportItemsFromJson((String) jedis.get(redis_key, "result"))); + st.close(); + connection.close(); + return; + } + */ + rs = st.executeQuery(); + String repository = ""; + String lastDate = ""; + ReportItem reportItem = null; + + /* + Calendar startCalendar = Calendar.getInstance(); + startCalendar.setTime(beginDate); + Calendar endCalendar = Calendar.getInstance(); + endCalendar.setTime(endDate); + */ + int ft_total = 0; + int abstr = 0; + if (granularity.equalsIgnoreCase("totals")) { + while (rs.next()) { + if (!rs.getString(1).equals(repository)) { + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(beginDate), report_dateFormat.format(endDate), Integer.toString(ft_total), Integer.toString(abstr))); + reportItems.add(reportItem); + } + repository = rs.getString(1); + reportItem = new ReportItem(null, rs.getString(2), "Platform", null); + reportItem.addIdentifier(new ItemIdentifier("OpenAIRE", rs.getString(1))); + reportItem.addIdentifier(new ItemIdentifier("ISSN", rs.getString(4).substring(rs.getString(4).lastIndexOf(":") + 1))); + if (rs.getString(3) != null) { + reportItem.addIdentifier(new ItemIdentifier("URL", rs.getString(3))); + } + ft_total = 0; + abstr = 0; + } + ft_total += rs.getInt(6); + abstr += rs.getInt(7); + } + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(beginDate), report_dateFormat.format(endDate), Integer.toString(ft_total), Integer.toString(abstr))); + reportItems.add(reportItem); + } + } else if (granularity.equalsIgnoreCase("monthly")) { + Calendar endCal = Calendar.getInstance(); + endCal.setTime(postgresFormat.parse(endDateStr)); + endCal.add(Calendar.MONTH, 1); + Date endDateForZeros = endCal.getTime(); + while (rs.next()) { + if (!rs.getString(1).equals(repository)) { + if (reportItem != null) { + fillWithZeros(postgresFormat.parse(lastDate), endDateForZeros, reportItem); + reportItems.add(reportItem); + } + repository = rs.getString(1); + lastDate = beginDateStr; + reportItem = new ReportItem(null, rs.getString(2), "Platform", null); + reportItem.addIdentifier(new ItemIdentifier("OpenAIRE", rs.getString(1))); + reportItem.addIdentifier(new ItemIdentifier("ISSN", rs.getString(4).substring(rs.getString(4).lastIndexOf(":") + 1))); + if (rs.getString(3) != null) { + reportItem.addIdentifier(new ItemIdentifier("URL", rs.getString(3))); + } + } + fillWithZeros(postgresFormat.parse(lastDate), postgresFormat.parse(rs.getString(5)), reportItem); + Calendar endC = Calendar.getInstance(); + endC.setTime(postgresFormat.parse(rs.getString(5))); + endC.set(Calendar.DATE, endC.getActualMaximum(Calendar.DATE)); + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(postgresFormat.parse(rs.getString(5))), report_dateFormat.format(endC.getTime()), rs.getString(6), rs.getString(7))); + } + endC.setTime(postgresFormat.parse(rs.getString(5))); + endC.add(Calendar.MONTH, 1); + lastDate = postgresFormat.format(endC.getTime()); + } + if (reportItem != null) { + fillWithZeros(postgresFormat.parse(lastDate), endDateForZeros, reportItem); + reportItems.add(reportItem); + } + } + + /* + jedis.put(redis_key, "persistent", "false"); + jedis.put(redis_key, "query", st.toString()); + jedis.put(redis_key, "result", toJson(reportItems)); + jedis.put(redis_key, "fetchMode", "3"); + */ + rs.close(); + st.close(); + connection.close(); + } catch (Exception e) { + log.error("Repository Report failed: ", e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + } + + public void executeBatchItems(List reportItems, String repositoryIdentifier, String itemDataType, Date beginDate, Date endDate, String granularity) { + SimpleDateFormat report_dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat postgresFormat = new SimpleDateFormat("yyyy/MM"); + String beginDateStr = postgresFormat.format(beginDate); + String endDateStr = postgresFormat.format(endDate); + + Connection connection = null; + PreparedStatement st = null; + ResultSet rs = null; + + try { + connection = usageStatsDB.getConnection(); + + if (itemDataType.equals("")) { + //st = connection.prepareStatement("SELECT res.result_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.ddate, oids.orid, res.downloads, res.views FROM (SELECT coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.result_id, vs.result_id) AS result_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.downloads_stats s WHERE s.date>=? AND s.date<=? AND s.repository_id=? GROUP BY s.repository_id, s.result_id, s.date) AS ds FULL OUTER JOIN (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.views_stats s WHERE s.date>=? AND s.date<=? AND s.repository_id=? GROUP BY s.repository_id, s.result_id, s.date) AS vs ON ds.result_id=vs.result_id AND ds.date=vs.date) AS res JOIN public.result r ON res.result_id=r.id JOIN public.datasource d ON d.id=res.repository_id JOIN public.result_classifications rc ON rc.id=r.id LEFT JOIN (SELECT pids.id, string_agg(pids.pid, '#!#') AS pid FROM public.result_pids pids, public.result_datasources rd WHERE rd.id=pids.id AND type='doi' AND rd.datasource=? GROUP BY pids.id) AS pids ON pids.id=r.id LEFT JOIN (SELECT oids.id, string_agg(oids.orid, '#!#') AS orid FROM public.result_oids oids, public.result_datasources rd WHERE rd.id=oids.id AND rd.datasource=? GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.result_id, res.ddate;"); + //st = connection.prepareStatement("SELECT res.result_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.date, oids.orid, res.downloads, res.views FROM (SELECT us.repository_id, us.result_id, us.date, sum(us.downloads) as downloads, sum(us.views) as views FROM public.usage_stats us WHERE us.date>=? AND us.date<=? AND us.repository_id=? GROUP BY us.repository_id, us.result_id, us.date) AS res JOIN public.result r ON res.result_id=r.id JOIN public.datasource d ON d.id=res.repository_id JOIN public.result_classifications rc ON rc.id=r.id LEFT JOIN (SELECT pids.id, string_agg(pids.pid, '#!#') AS pid FROM public.result_pids pids, public.result_datasources rd WHERE rd.id=pids.id AND type='doi' AND rd.datasource=? GROUP BY pids.id) AS pids ON pids.id=r.id LEFT JOIN (SELECT oids.id, string_agg(oids.orid, '#!#') AS orid FROM public.result_oids oids, public.result_datasources rd WHERE rd.id=oids.id AND rd.datasource=? GROUP BY oids.id) AS oids ON oids.id=r.id ORDER BY res.result_id, res.date;"); + st = connection.prepareStatement("SELECT distinct res.result_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.`date`, oids.oid, res.downloads, res.views " + + "FROM (SELECT us.repository_id, us.result_id, us.`date`, sum(us.downloads) as downloads, sum(us.views) as views FROM "+usagestatsImpalaDB+".usage_stats us " + + "WHERE us.`date`>=? AND us.`date`<=? AND us.repository_id=? " + + "GROUP BY us.repository_id, us.result_id, us.`date`) AS res JOIN "+statsDB+".result r ON res.result_id=r.id " + + "JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".result_classifications rc ON rc.id=r.id " + + "LEFT JOIN (SELECT pids.id, group_concat(pids.pid, '#!#') AS pid " + + "FROM "+statsDB+".result_pids pids, "+statsDB+".result_datasources rd " + + "WHERE rd.id=pids.id AND type='Digital Object Identifier' AND rd.datasource=? " + + "GROUP BY pids.id) AS pids ON pids.id=r.id " + + "LEFT JOIN (SELECT oids.id, group_concat(oids.oid, '#!#') AS oid " + + "FROM "+statsDB+".result_oids oids, "+statsDB+".result_datasources rd " + + "WHERE rd.id=oids.id AND rd.datasource=? GROUP BY oids.id) " + + "AS oids ON oids.id=r.id ORDER BY res.result_id, res.`date`;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, repositoryIdentifier); + //st.setString(4, beginDateStr); + //st.setString(5, endDateStr); + //st.setString(6, repositoryIdentifier); + st.setString(4, repositoryIdentifier); + st.setString(5, repositoryIdentifier); + } else { + //st = connection.prepareStatement("SELECT res.result_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.ddate, oids.orid, res.downloads, res.views FROM (SELECT coalesce(ds.repository_id, vs.repository_id) AS repository_id, coalesce(ds.result_id, vs.result_id) AS result_id, coalesce(ds.date, vs.date) AS ddate, coalesce(ds.sum, 0) AS downloads, coalesce(vs.sum,0) AS views FROM (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.downloads_stats s WHERE s.date>=? AND s.date<=? AND s.repository_id=? GROUP BY s.repository_id, s.result_id, s.date) AS ds FULL OUTER JOIN (SELECT s.repository_id, s.result_id, s.date, sum(s.count) FROM public.views_stats s WHERE s.date>=? AND s.date<=? AND s.repository_id=? GROUP BY s.repository_id, s.result_id, s.date) AS vs ON ds.result_id=vs.result_id AND ds.date=vs.date) AS res JOIN public.result r ON res.result_id=r.id JOIN public.datasource d ON d.id=res.repository_id JOIN public.result_classifications rc ON rc.id=r.id LEFT JOIN (SELECT pids.id, string_agg(pids.pid, '#!#') AS pid FROM public.result_pids pids, result_datasources rd WHERE rd.id=pids.id AND type='doi' AND rd.datasource=? GROUP BY pids.id) AS pids ON pids.id=r.id LEFT JOIN (SELECT oids.id, string_agg(oids.orid, '#!#') AS orid FROM public.result_oids oids, public.result_datasources rd WHERE rd.id=oids.id AND rd.datasource=? GROUP BY oids.id) AS oids ON oids.id=r.id WHERE rc.type=? ORDER BY res.result_id, res.ddate;"); + st = connection.prepareStatement("SELECT distinct res.result_id, r.title, r.publisher, r.source, rc.type, pids.pid, d.name, res.`date`, oids.oid, res.downloads, res.views " + + "FROM (SELECT us.repository_id, us.result_id, us.`date`, sum(us.downloads) as downloads, sum(us.views) as views " + + "FROM "+usagestatsImpalaDB+".usage_stats us WHERE us.`date`>=? AND us.`date`<=? AND us.repository_id=? " + + "GROUP BY us.repository_id, us.result_id, us.`date`) AS res " + + "JOIN "+statsDB+".result r ON res.result_id=r.id JOIN "+statsDB+".datasource d ON d.id=res.repository_id " + + "JOIN "+statsDB+".result_classifications rc ON rc.id=r.id " + + "LEFT JOIN (SELECT pids.id, group_concat(pids.pid, '#!#') AS pid " + + "FROM "+statsDB+".result_pids pids, "+statsDB+".result_datasources rd " + + "WHERE rd.id=pids.id AND type='Digital Object Identifier' " + + "AND rd.datasource=? GROUP BY pids.id) AS pids ON pids.id=r.id " + + "LEFT JOIN (SELECT oids.id, group_concat(oids.oid, '#!#') AS oid " + + "FROM "+statsDB+".result_oids oids, "+statsDB+".result_datasources rd " + + "WHERE rd.id=oids.id AND rd.datasource=? GROUP BY oids.id) AS oids ON oids.id=r.id " + + "WHERE rc.type=? ORDER BY res.result_id, res.`date`;"); + st.setString(1, beginDateStr); + st.setString(2, endDateStr); + st.setString(3, repositoryIdentifier); + //st.setString(4, beginDateStr); + //st.setString(5, endDateStr); + //st.setString(6, repositoryIdentifier); + st.setString(4, repositoryIdentifier); + st.setString(5, repositoryIdentifier); + st.setString(6, itemDataType); + } + //log.error("IR STATEMENT: " + st); + + /* + String redis_key = MD5(st.toString()); + + if (jedis.hasKey(redis_key, "result")) { + reportItems.addAll(reportItemsFromJson((String) jedis.get(redis_key, "result"))); + st.close(); + connection.close(); + return; + } + */ + rs = st.executeQuery(); + String result = ""; + String lastDate = ""; + ReportItem reportItem = null; + + int ft_total = 0; + int abstr = 0; + if (granularity.equalsIgnoreCase("totals")) { + while (rs.next()) { + if (!rs.getString(1).equals(result)) { + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(beginDate), report_dateFormat.format(endDate), Integer.toString(ft_total), Integer.toString(abstr))); + reportItems.add(reportItem); + } + result = rs.getString(1); + reportItem = new ReportItem(rs.getString(3), rs.getString(7), rs.getString(5), rs.getString(2)); + reportItem.addIdentifier(new ItemIdentifier("OpenAIRE", rs.getString(1))); + reportItem.addIdentifier(new ItemIdentifier("URLs", rs.getString(4))); + if (rs.getString(9) != null && !rs.getString(9).equals("")) { + if (rs.getString(9).contains("#!#")) { + reportItem.addIdentifier(new ItemIdentifier("OAI", rs.getString(9).substring(0, rs.getString(9).indexOf("#!#")))); + } else { + reportItem.addIdentifier(new ItemIdentifier("OAI", rs.getString(9))); + } + } + if (rs.getString(6) != null && !rs.getString(6).equals("")) { + if (rs.getString(6).contains("#!#")) { + reportItem.addIdentifier(new ItemIdentifier("DOI", rs.getString(6).substring(0, rs.getString(6).indexOf("#!#")))); + } else { + reportItem.addIdentifier(new ItemIdentifier("DOI", rs.getString(6))); + } + } + ft_total = 0; + abstr = 0; + } + ft_total += rs.getInt(10); + abstr += rs.getInt(11); + } + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(beginDate), report_dateFormat.format(endDate), Integer.toString(ft_total), Integer.toString(abstr))); + reportItems.add(reportItem); + } + } else if (granularity.equalsIgnoreCase("monthly")) { + Calendar endCal = Calendar.getInstance(); + endCal.setTime(postgresFormat.parse(endDateStr)); + endCal.add(Calendar.MONTH, 1); + Date endDateForZeros = endCal.getTime(); + while (rs.next()) { + if (!rs.getString(1).equals(result)) { + if (reportItem != null) { + fillWithZeros(postgresFormat.parse(lastDate), endDateForZeros, reportItem); + reportItems.add(reportItem); + } + result = rs.getString(1); + lastDate = beginDateStr; + reportItem = new ReportItem(rs.getString(3), rs.getString(7), rs.getString(5), rs.getString(2)); + reportItem.addIdentifier(new ItemIdentifier("OpenAIRE", rs.getString(1))); + reportItem.addIdentifier(new ItemIdentifier("URLs", rs.getString(4))); + if (rs.getString(9) != null && !rs.getString(9).equals("")) { + if (rs.getString(9).contains("#!#")) { + reportItem.addIdentifier(new ItemIdentifier("OAI", rs.getString(9).substring(0, rs.getString(9).indexOf("#!#")))); + } else { + reportItem.addIdentifier(new ItemIdentifier("OAI", rs.getString(9))); + } + } + if (rs.getString(6) != null && !rs.getString(6).equals("")) { + if (rs.getString(6).contains("#!#")) { + reportItem.addIdentifier(new ItemIdentifier("DOI", rs.getString(6).substring(0, rs.getString(6).indexOf("#!#")))); + } else { + reportItem.addIdentifier(new ItemIdentifier("DOI", rs.getString(6))); + } + } + } + fillWithZeros(postgresFormat.parse(lastDate), postgresFormat.parse(rs.getString(8)), reportItem); + Calendar endC = Calendar.getInstance(); + endC.setTime(postgresFormat.parse(rs.getString(8))); + endC.set(Calendar.DATE, endC.getActualMaximum(Calendar.DATE)); + if (reportItem != null) { + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(postgresFormat.parse(rs.getString(8))), report_dateFormat.format(endC.getTime()), rs.getString(10), rs.getString(11))); + } + endC.setTime(postgresFormat.parse(rs.getString(8))); + endC.add(Calendar.MONTH, 1); + lastDate = postgresFormat.format(endC.getTime()); + } + if (reportItem != null) { + fillWithZeros(postgresFormat.parse(lastDate), endDateForZeros, reportItem); + reportItems.add(reportItem); + } + } + + /* + jedis.put(redis_key, "persistent", "false"); + jedis.put(redis_key, "query", st.toString()); + jedis.put(redis_key, "result", toJson(reportItems)); + jedis.put(redis_key, "fetchMode", "3"); + */ + } catch (Exception e) { + log.error("Batch Item Report failed: ", e); + } finally { + DbUtils.closeQuietly(rs); + DbUtils.closeQuietly(st); + DbUtils.closeQuietly(connection); + } + } + + private void fillWithZeros(Date from, Date to, ReportItem reportItem) { + SimpleDateFormat report_dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + + Calendar fromCalendar = Calendar.getInstance(); + fromCalendar.setTime(from); + + Calendar toCalendar = Calendar.getInstance(); + toCalendar.setTime(to); + while (from.before(to)) { + Calendar temp_c = Calendar.getInstance(); + temp_c.setTime(from); + temp_c.set(Calendar.DAY_OF_MONTH, temp_c.getActualMaximum(Calendar.DAY_OF_MONTH)); + Date temp_endDate = temp_c.getTime(); + + reportItem.addPerformance(new ItemPerformance(report_dateFormat.format(from), report_dateFormat.format(temp_endDate), "0", "0")); + fromCalendar.add(Calendar.MONTH, 1); + from = fromCalendar.getTime(); + } + } +} diff --git a/src/main/java/eu/dnetlib/usagestats/services/SushiLiteService.java b/src/main/java/eu/dnetlib/usagestats/services/SushiLiteService.java new file mode 100755 index 0000000..25b3241 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/services/SushiLiteService.java @@ -0,0 +1,14 @@ +package eu.dnetlib.usagestats.services; + +import eu.dnetlib.usagestats.sushilite.domain.ReportResponseWrapper; + +public interface SushiLiteService { + ReportResponseWrapper buildReport(String reportName, String release, String requestorId, String beginDate, + String endDate, String repositoryIdentifier, String itemIdentifier, + String itemDataType, String hasDoi, String granularity, String callback); + + String displayReport(String reportName, String release, String requestorId, String beginDate, + String endDate, String repositoryIdentifier, String itemIdentifier, + String itemDataType, String hasDoi, String granularity, String callback, String pretty, String userAgent); +} + diff --git a/src/main/java/eu/dnetlib/usagestats/services/SushiLiteServiceImpl.java b/src/main/java/eu/dnetlib/usagestats/services/SushiLiteServiceImpl.java new file mode 100755 index 0000000..be6bccf --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/services/SushiLiteServiceImpl.java @@ -0,0 +1,357 @@ +package eu.dnetlib.usagestats.services; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import eu.dnetlib.usagestats.repositories.UsageStatsRepository; +import eu.dnetlib.usagestats.sushilite.domain.ReportItem; +import eu.dnetlib.usagestats.sushilite.domain.ReportException; +import eu.dnetlib.usagestats.sushilite.domain.ReportResponse; +import eu.dnetlib.usagestats.sushilite.domain.ReportResponseWrapper; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Value; + +@Service +public class SushiLiteServiceImpl implements SushiLiteService { + + private final UsageStatsRepository usageStatsRepository; + + private final Logger log = Logger.getLogger(this.getClass()); + + @Value("${usagestats.redis.hostname}") + private String hostname; + + @Value("${usagestats.redis.port}") + private int port; + + @Value("${compression.max_number_of_records}") + private int compression_max_number_of_records; + @Value("${download.folder}") + private String download_folder; + @Value("${sushi-lite.server}") + private String sushi_lite_server; + + String finalcompressedString = ""; + boolean reportForCompression = false; + private int noOfItems = 0; + String userAgent; + + public SushiLiteServiceImpl(UsageStatsRepository usageStatsRepository) { + this.usageStatsRepository = usageStatsRepository; + } + + @Override + public ReportResponseWrapper buildReport(String reportName, String release, String requestorId, String beginDate, + String endDate, String repositoryIdentifier, String itemIdentifier, + String itemDataType, String hasDoi, String granularity, String callback) { + + List reportItems = new ArrayList<>(); + List reportExceptions = new ArrayList<>(); + + if (!granularity.equalsIgnoreCase("totals") && !granularity.equalsIgnoreCase("monthly")) { + reportExceptions.add(new ReportException("3062", "Warning", "Invalid ReportAttribute Value", "Granularity: \'" + granularity + "\' unknown. Defaulting to Monthly")); + granularity = "Monthly"; + } + + Date beginDateParsed; + if (!beginDate.equals("")) { + beginDateParsed = tryParse(beginDate); + if (beginDateParsed != null && (granularity.toLowerCase().equals("monthly") || beginDate.length() == 7)) { + Calendar temp = Calendar.getInstance(); + temp.setTime(beginDateParsed); + temp.set(Calendar.DAY_OF_MONTH, temp.getActualMinimum(Calendar.DAY_OF_MONTH)); + beginDateParsed = temp.getTime(); + } + } else { + Calendar temp = Calendar.getInstance(); + temp.add(Calendar.MONTH, -1); + temp.set(Calendar.DAY_OF_MONTH, temp.getActualMinimum(Calendar.DAY_OF_MONTH)); + beginDateParsed = temp.getTime(); + reportExceptions.add(new ReportException("3021", "Warning", "Unspecified Date Arguments", "Begin Date set to default: " + new SimpleDateFormat("yyyy-MM-dd").format(beginDateParsed))); + } + + Date endDateParsed; + if (!endDate.equals("")) { + endDateParsed = tryParse(endDate); + if (endDateParsed != null && (granularity.toLowerCase().equals("monthly") || endDate.length() == 7)) { + Calendar temp = Calendar.getInstance(); + temp.setTime(endDateParsed); + temp.set(Calendar.DAY_OF_MONTH, temp.getActualMaximum(Calendar.DAY_OF_MONTH)); + endDateParsed = temp.getTime(); + } + } else { + Calendar temp = Calendar.getInstance(); + temp.add(Calendar.MONTH, -1); + temp.set(Calendar.DAY_OF_MONTH, temp.getActualMaximum(Calendar.DAY_OF_MONTH)); + endDateParsed = temp.getTime(); + reportExceptions.add(new ReportException("3021", "Warning", "Unspecified Date Arguments", "End Date set to default: " + new SimpleDateFormat("yyyy-MM-dd").format(endDateParsed))); + } + //log.error("dates: " + beginDateParsed.toString() + " - " + endDateParsed.toString()); + + if (beginDateParsed == null) { + reportExceptions.add(new ReportException("3020", "Error", "Invalid Date Arguments", "Begin Date: " + beginDate + " is not a valid date")); + } + if (endDateParsed == null) { + reportExceptions.add(new ReportException("3020", "Error", "Invalid Date Arguments", "End Date: " + endDate + " is not a valid date")); + } + if (beginDateParsed != null && endDateParsed != null && !beginDateParsed.before(endDateParsed)) { + reportExceptions.add(new ReportException("3020", "Error", "Invalid Date Arguments", "BeginDate \'" + new SimpleDateFormat("yyyy-MM-dd").format(beginDateParsed) + "\' is greater than EndDate \'" + new SimpleDateFormat("yyyy-MM-dd").format(endDateParsed) + "\'")); + } + + String repoid = ""; + if (!repositoryIdentifier.equals("")) { + repoid = usageStatsRepository.executeRepoId(repositoryIdentifier, reportName.toLowerCase()); + if (repoid.equals("-1")) { + reportExceptions.add(new ReportException("3060", "Error", "Invalid Filter Value", "RepositoryIdentifier: " + repositoryIdentifier + " is not valid")); + } + } + String itemid = ""; + if (!itemIdentifier.equals("")) { + String[] split = itemIdentifier.split(":"); + switch (split[0].toLowerCase()) { + case "oid": + itemid = itemIdentifier; + break; + case "doi": + itemid = itemIdentifier; + break; + case "openaire": + itemid = itemIdentifier; + break; + default: + reportExceptions.add(new ReportException("3060", "Error", "Invalid Filter Value", "ItemIdentifier: " + itemIdentifier + " is not valid")); + itemid = "-1"; + } + } + if (itemid.equals("") && repoid.equals("") && !reportName.equalsIgnoreCase("rr1") && !reportName.equalsIgnoreCase("jr1")) { + reportExceptions.add(new ReportException("3070", "Error", "Required Filter Missing", "ItemIdentifier or RepositoryIdentifier must be supplied")); + } + if (reportName.equalsIgnoreCase("ar1")) { + if (!itemid.equals("-1") && !repoid.equals("-1") && beginDateParsed != null && endDateParsed != null && beginDateParsed.before(endDateParsed)) { + if (!itemid.equals("")) { + if (itemDataType.equalsIgnoreCase("") || itemDataType.equalsIgnoreCase("article")) { + usageStatsRepository.executeItem(reportItems, itemIdentifier, repoid, "Article", beginDateParsed, endDateParsed, granularity); + if (reportItems.isEmpty()) { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } else { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } else if (!repoid.equals("")) { + usageStatsRepository.executeBatchItems(reportItems, repoid, "Article", beginDateParsed, endDateParsed, granularity); + if (reportItems.isEmpty()) { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } + } + } else if (reportName.equalsIgnoreCase("br1")) { + if (!itemid.equals("-1") && !repoid.equals("-1") && beginDateParsed != null && endDateParsed != null && beginDateParsed.before(endDateParsed)) { + if (!itemid.equals("")) { + if (itemDataType.equalsIgnoreCase("") || itemDataType.equalsIgnoreCase("book")) { + usageStatsRepository.executeItem(reportItems, itemIdentifier, repoid, "Book", beginDateParsed, endDateParsed, granularity); + if (reportItems.isEmpty()) { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } else { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } else if (!repoid.equals("")) { + usageStatsRepository.executeBatchItems(reportItems, repoid, "Book", beginDateParsed, endDateParsed, granularity); + if (reportItems.isEmpty()) { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } + } + } else if (reportName.equalsIgnoreCase("br2")) { + if (!itemid.equals("-1") && !repoid.equals("-1") && beginDateParsed != null && endDateParsed != null && beginDateParsed.before(endDateParsed)) { + if (!itemid.equals("")) { + if (itemDataType.equalsIgnoreCase("") || itemDataType.equalsIgnoreCase("part of book or chapter of book")) { + usageStatsRepository.executeItem(reportItems, itemIdentifier, repoid, "Part of book or chapter of book", beginDateParsed, endDateParsed, granularity); + if (reportItems.isEmpty()) { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } else { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } else if (!repoid.equals("")) { + usageStatsRepository.executeBatchItems(reportItems, repoid, "Part of book or chapter of book", beginDateParsed, endDateParsed, granularity); + if (reportItems.isEmpty()) { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } + } + } else if (reportName.equalsIgnoreCase("ir1")) { + if (!itemid.equals("-1") && !repoid.equals("-1") && beginDateParsed != null && endDateParsed != null && beginDateParsed.before(endDateParsed)) { + if (!itemid.equals("")) { + usageStatsRepository.executeItem(reportItems, itemIdentifier, repoid, itemDataType, beginDateParsed, endDateParsed, granularity); + } else if (!repoid.equals("")) { + usageStatsRepository.executeBatchItems(reportItems, repoid, itemDataType, beginDateParsed, endDateParsed, granularity); + } + if (reportItems.isEmpty()) { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } + } else if (reportName.equalsIgnoreCase("rr1")) { + if (!repoid.equals("-1") && beginDateParsed != null && endDateParsed != null && beginDateParsed.before(endDateParsed)) { + usageStatsRepository.executeRepo(reportItems, repoid, itemDataType, beginDateParsed, endDateParsed, granularity); + } + if (reportItems.isEmpty()) { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } else if (reportName.equalsIgnoreCase("jr1")) { + if (!repoid.equals("-1") && beginDateParsed != null && endDateParsed != null && beginDateParsed.before(endDateParsed)) { + usageStatsRepository.executeJournal(reportItems, repoid, itemDataType, beginDateParsed, endDateParsed, granularity); + } + if (reportItems.isEmpty()) { + reportExceptions.add(new ReportException("3030", "Error", "No Usage Available for Requested Dates", "Service did not find any data")); + } + } else if (reportName.equals("")) { + reportExceptions.add(new ReportException("3050", "Error", "Report argument is missing", "You must supply a Report argument")); + } else { + reportExceptions.add(new ReportException("3000", "Error", "Report " + reportName + " not supported", "Supported reports: AR1, IR1, RR1, BR1, BR2")); + } + + ReportResponse reportResponse = new ReportResponse(reportName, release, requestorId, beginDate, endDate, + repositoryIdentifier, itemIdentifier, itemDataType, hasDoi, granularity, callback, reportItems, reportExceptions); + if (reportItems.size() > compression_max_number_of_records) { + log.info("Compression due to "+reportItems.size()); + reportForCompression = true; + } + + noOfItems = reportItems.size(); + return new ReportResponseWrapper(reportResponse); + } + + @Override + public String displayReport(String reportName, String release, String requestorId, String beginDate, String endDate, String repositoryIdentifier, String itemIdentifier, String itemDataType, String hasDoi, String granularity, String callback, String pretty, String userAgent) { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false); + objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); + java.sql.Timestamp timestamp = new java.sql.Timestamp(System.currentTimeMillis()); + //System.out.println("Display report start " + timestamp); + log.info("Starting process...." + timestamp); + this.userAgent = userAgent; + try { + ReportResponseWrapper reportResponseWrapper = buildReport(reportName, release, requestorId, beginDate, endDate, repositoryIdentifier, itemIdentifier, itemDataType, hasDoi, granularity, callback); + if (pretty.equalsIgnoreCase("pretty")) { + if (reportForCompression == false) { + if (userAgent.contains("Mozilla")) { + return "
" + objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(reportResponseWrapper) + "
"; + } else { + return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(reportResponseWrapper); + } + } else { + if (userAgent.contains("Mozilla")) { + byte[] sourceReport = objectMapper.writeValueAsBytes(reportResponseWrapper); + ObjectWriter writer = objectMapper.writer(); + java.sql.Timestamp timestamp1 = new java.sql.Timestamp(System.currentTimeMillis()); + //System.out.println("String start " + timestamp1); + log.info("Start building report..." + timestamp1); + String outputname = reportName + "_" + repositoryIdentifier.replace("_", "").replace(":", "") + beginDate.replace("-", "") + "_" + endDate.replace("-", ""); + String directory = new File(download_folder).getAbsolutePath(); + writer.writeValue(new File(directory + "/" + outputname + ".json"), new String(sourceReport)); + + FileOutputStream fos = new FileOutputStream(directory + "/" + outputname + ".zip"); + ZipOutputStream zipOut = new ZipOutputStream(fos); + File fileToZip = new File(directory + "/" + outputname + ".json"); + FileInputStream fis = new FileInputStream(fileToZip); + ZipEntry zipEntry = new ZipEntry(fileToZip.getName()); + zipOut.putNextEntry(zipEntry); + byte[] bytes = new byte[1024]; + int length; + while ((length = fis.read(bytes)) >= 0) { + zipOut.write(bytes, 0, length); + } + zipOut.close(); + fis.close(); + fos.close(); + fileToZip.delete(); + + java.sql.Timestamp timestamp2 = new java.sql.Timestamp(System.currentTimeMillis()); + //System.out.println("String end " + timestamp2); + log.info("Report created..." + timestamp2); + + return new String(sushi_lite_server + "/download/" + outputname + ".zip"); + //return "report is available. Download it from localhost:8080/download/"+outputname+".zip"; + } else { + byte[] sourceReport = objectMapper.writeValueAsBytes(reportResponseWrapper); + return new String(sourceReport); + } + } + } + + if (reportForCompression == false) { + byte[] sourceReport = objectMapper.writeValueAsBytes(reportResponseWrapper); + return new String(sourceReport); + } else if (userAgent.contains("Mozilla")) { + + java.sql.Timestamp timestamp3 = new java.sql.Timestamp(System.currentTimeMillis()); + //System.out.println("String start " + timestamp3); + log.info("Start building report..." + timestamp3); + + byte[] sourceReport = objectMapper.writeValueAsBytes(reportResponseWrapper); + ObjectWriter writer = objectMapper.writer(); + + String outputname = reportName + "_" + repositoryIdentifier.replace("_", "").replace(":", "") + beginDate.replace("-", "") + "_" + endDate.replace("-", ""); + + String directory = new File(download_folder).getAbsolutePath(); + writer.writeValue(new File(directory + "/" + outputname + ".json"), new String(sourceReport).replaceAll("\\\"", "")); + + FileOutputStream fos = new FileOutputStream(directory + "/" + outputname + ".zip"); + ZipOutputStream zipOut = new ZipOutputStream(fos); + File fileToZip = new File(directory + "/" + outputname + ".json"); + FileInputStream fis = new FileInputStream(fileToZip); + ZipEntry zipEntry = new ZipEntry(fileToZip.getName()); + zipOut.putNextEntry(zipEntry); + byte[] bytes = new byte[1024]; + int length; + while ((length = fis.read(bytes)) >= 0) { + zipOut.write(bytes, 0, length); + } + zipOut.close(); + fis.close(); + fos.close(); + fileToZip.delete(); + + java.sql.Timestamp timestamp4 = new java.sql.Timestamp(System.currentTimeMillis()); + //System.out.println("String end " + timestamp4); + log.info("Report created..." + timestamp4); + + return new String(sushi_lite_server + "/download/" + outputname + ".zip"); + + } else { + byte[] sourceReport = objectMapper.writeValueAsBytes(reportResponseWrapper); + return new String(sourceReport); + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private Date tryParse(String dateString) { + try { + if (dateString.length() == 7) { + return new SimpleDateFormat("yyyy-MM").parse(dateString); + } else if (dateString.length() == 10) { + return new SimpleDateFormat("yyyy-MM-dd").parse(dateString); + } + } catch (Exception e) { + log.error("ParseError: ", e); + } + return null; + } +} diff --git a/src/main/java/eu/dnetlib/usagestats/services/UsageStatsService.java b/src/main/java/eu/dnetlib/usagestats/services/UsageStatsService.java new file mode 100755 index 0000000..23324dd --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/services/UsageStatsService.java @@ -0,0 +1,24 @@ +package eu.dnetlib.usagestats.services; + +import eu.dnetlib.usagestats.portal.CountryRepositories; +import eu.dnetlib.usagestats.portal.CountryUsageStats; +import eu.dnetlib.usagestats.portal.CountryUsageStatsAll; +import eu.dnetlib.usagestats.portal.MonthlyUsageStats; +import eu.dnetlib.usagestats.portal.TotalStats; +import eu.dnetlib.usagestats.portal.TotalStatsReposViewsDownloads; +import eu.dnetlib.usagestats.portal.UsageStats; +import java.util.List; + +public interface UsageStatsService { + UsageStats getDatasourceClicks(String id); + UsageStats getProjectClicks(String id); + UsageStats getResultClicks(String id); + //UsageStats getOrganizationClicks(String id); + TotalStats getTotalStats(); + List getMonthlyUsageStats(); + List getMonthlyUsageStatsForRepo(String id); + CountryUsageStatsAll getCountryUsageStatsAll(); + CountryUsageStats getCountryUsageStats(String country); + List getCountryRepositories(); + TotalStatsReposViewsDownloads getTotalStatsReposViewsDownloads(); +} diff --git a/src/main/java/eu/dnetlib/usagestats/services/UsageStatsServiceImpl.java b/src/main/java/eu/dnetlib/usagestats/services/UsageStatsServiceImpl.java new file mode 100755 index 0000000..88cb3f6 --- /dev/null +++ b/src/main/java/eu/dnetlib/usagestats/services/UsageStatsServiceImpl.java @@ -0,0 +1,148 @@ +package eu.dnetlib.usagestats.services; + +import eu.dnetlib.usagestats.portal.CountryRepositories; +import eu.dnetlib.usagestats.portal.CountryUsageStats; +import eu.dnetlib.usagestats.portal.CountryUsageStatsAll; +import eu.dnetlib.usagestats.portal.MonthlyUsageStats; +import eu.dnetlib.usagestats.portal.TotalStats; +import eu.dnetlib.usagestats.portal.TotalStatsReposViewsDownloads; +import eu.dnetlib.usagestats.portal.UsageStats; +import eu.dnetlib.usagestats.repositories.UsageStatsRepository; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Value; + +@Service +public class UsageStatsServiceImpl implements UsageStatsService { + + private final UsageStatsRepository usageStatsRepository; + private final Logger log = Logger.getLogger(this.getClass()); + + @Value("${prod.statsdb}") + private String statsDB; + @Value("${prod.usagestatsImpalaDB}") + private String usagestatsImpalaDB; + + + public UsageStatsServiceImpl(UsageStatsRepository usageStatsRepository) { + this.usageStatsRepository = usageStatsRepository; + } + + @Override + public UsageStats getDatasourceClicks(String id) { + String query = "SELECT 'views', sum(s.count), sum(s.openaire) FROM "+usagestatsImpalaDB+".views_stats s where s.repository_id=? " + + "UNION ALL SELECT 'downloads', sum(s.count), sum(s.openaire) FROM "+usagestatsImpalaDB+".downloads_stats s where s.repository_id=? " + + "UNION ALL SELECT 'pageviews', sum(s.count), 0 FROM "+usagestatsImpalaDB+".pageviews_stats s, "+statsDB+".result_datasources rd where rd.id=s.result_id and rd.datasource=? "; + + List values = new ArrayList<>(); + values.add(id); + values.add(id); + values.add(id); + + return usageStatsRepository.executeUsageStats(query, values, "datasource"); + } + + /* + @Override + public UsageStats getOrganizationClicks(String organizationId) { + + String query = "select sum(number_of_views) from organization_stats where id=?"; + + List values = new ArrayList<>(); + values.add(organizationId); + + return usageStatsRepository.executeUsageStats(query, values, "organization"); + + } + */ + @Override + public UsageStats getProjectClicks(String projectId) { + String query = "SELECT 'views', sum(s.count), sum(s.openaire) FROM "+usagestatsImpalaDB+".views_stats s, "+statsDB+".project_results pr where pr.result=s.result_id and pr.id=? " + + "UNION ALL SELECT 'downloads', sum(s.count), sum(s.openaire) FROM "+usagestatsImpalaDB+".downloads_stats s, "+statsDB+".project_results pr where pr.result=s.result_id and pr.id=? " + + "UNION ALL SELECT 'pageviews', sum(s.count), 0 FROM "+usagestatsImpalaDB+".pageviews_stats s, "+statsDB+".project_results pr where pr.result=s.result_id and pr.id=?;"; + + List values = new ArrayList<>(); + values.add(projectId); + values.add(projectId); + values.add(projectId); + + return usageStatsRepository.executeUsageStats(query, values, "project"); + } + + @Override + public UsageStats getResultClicks(String id) { + String query = "SELECT 'views', s.repository_id, CASE WHEN s.source='OpenAIRE' THEN d.name ELSE concat(d.name,' - ',s.source) END, sum(count), sum(openaire) FROM (select distinct * from "+usagestatsImpalaDB+".views_stats) s, "+statsDB+".datasource d WHERE s.repository_id=d.id AND s.result_id=? GROUP BY s.source, s.repository_id, d.name " + + "UNION ALL SELECT 'downloads', s.repository_id, CASE WHEN s.source='OpenAIRE' THEN d.name ELSE concat(d.name,' - ',s.source) END, sum(count), sum(s.openaire) FROM (select distinct * from "+usagestatsImpalaDB+".downloads_stats) s, "+statsDB+".datasource d WHERE s.repository_id=d.id AND s.result_id=? GROUP BY s.source, s.repository_id, d.name " + + "UNION ALL SELECT 'pageviews', 'OpenAIRE id', 'OpenAIRE', sum(count), 0 FROM "+usagestatsImpalaDB+".pageviews_stats s WHERE result_id=?;"; + + List values = new ArrayList<>(); + values.add(id); + values.add(id); + values.add(id); + + return usageStatsRepository.executeUsageStats(query, values, "result"); + } + + @Override + public TotalStats getTotalStats() { + return usageStatsRepository.executeTotalStats(); + } + + @Override + public List getMonthlyUsageStats() { + String query = "select `date`, sum(downloads) as downloads, sum(views) as views from "+usagestatsImpalaDB+".usage_stats group by `date`getTotalStatsReposViewsDownloads order by `date` asc"; + return usageStatsRepository.executeMontlyUsageStats(query); + } + + @Override + public List getMonthlyUsageStatsForRepo(String id) { + String query = "select `date`, sum(downloads) as downloads, sum(views) as views from "+usagestatsImpalaDB+".usage_stats where repository_id=? group by `date` order by `date` asc"; + return usageStatsRepository.executeMontlyUsageStatsForRepo(query,id); + } + + /* @Override + public List getCountryUsageStats() { + String query = "select c.name, sum(views) as views, sum(downloads) as downloads from public.torganization t, public.organization_datasources o, public.country c, usage_stats where o.datasource=t.id\n" + + "and c.code=t.country and o.id=repository_id group by c.name "; + return usageStatsRepository.executeCountryUsageStats(query); + }*/ + @Override + public CountryUsageStatsAll getCountryUsageStatsAll() { + String query = "SELECT c.name, count(distinct repository_id) as total_repos, sum(views) as views, sum(downloads) as downloads " + + "FROM "+statsDB+".organization t, "+statsDB+".organization_datasources o, " + + ""+statsDB+".country c, "+usagestatsImpalaDB+".usage_stats " + + "WHERE o.datasource=t.id AND c.code=t.country AND o.id=repository_id GROUP BY c.name"; + return usageStatsRepository.executeCountryUsageStats(query); + } + @Override + public CountryUsageStats getCountryUsageStats(String country) { + String query = "SELECT count(distinct repository_id) as total_repos, sum(views) as views, sum(downloads) as downloads " + + "from "+statsDB+".organization t, "+statsDB+".organization_datasources o, " + + ""+statsDB+".country c, "+usagestatsImpalaDB+".usage_stats where o.datasource=t.id and c.code=t.country and o.id=repository_id " + + "and c.name='"+country+"'"; + log.info("Country Usage Stats query "+query); + return usageStatsRepository.executeCountryUsageStats(query, country); + } + + + @Override + public List getCountryRepositories() { + String query = "SELECT c.name, d.name FROM "+statsDB+".datasource d, "+statsDB+".organization t, " + + statsDB+".organization_datasources o, "+statsDB+".country c, "+usagestatsImpalaDB+".usage_stats " + + "WHERE o.datasource=t.id AND c.code=t.country AND o.id=repository_id and repository_id=d.id " + + "GROUP BY d.name, c.name ORDER BY c.name"; + return usageStatsRepository.executeCountryRepositories(query); + } + + @Override + public TotalStatsReposViewsDownloads getTotalStatsReposViewsDownloads() { + String query = "SELECT COUNT(DISTINCT repository_id) as repositories, sum(views) as views, sum(downloads) as downloads from "+usagestatsImpalaDB+".usage_stats"; + log.info("Total Repositories-Views-Downlaods "+query); + return usageStatsRepository.executeTotalStatsReposViewsDownloads(query); + + } + +} diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100755 index 0000000..270177e --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,25 @@ +#log4j.rootLogger = WARN, R +log4j.rootLogger = INFO, R + +#log4j.logger.eu.dnetlib = WARN +log4j.logger.eu.dnetlib = INFO +log4j.logger.org.springframework = INFO, S + +log4j.additivity.org.springframework = false + +log4j.appender.R=org.apache.log4j.RollingFileAppender +#log4j.appender.R.File=/var/log/dnet/usageStatsAPI/usageStatsAPI.log +#log4j.appender.R.File=/Users/dpie/Desktop/usageStatsAPI.log +log4j.appender.R.File=/Volumes/Zeus/dpie/Desktop/usageStatsAPI.log +loglog4j.appender.R.MaxFileSize=10MB +log4j.appender.R.MaxBackupIndex=10 +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern= %d %p %t [%c] - %m%n +log4j.appender.S=org.apache.log4j.RollingFileAppender +#log4j.appender.S.File=/var/log/dnet/usageStatsAPI/usageStatsAPI-spring.log +#log4j.appender.S.File=/Users/dpie/Desktop/usageStatsAPI-spring.log +log4j.appender.S.File=/Volumes/Zeus/dpie/Desktop/usageStatsAPI-spring.log +log4j.appender.S.MaxFileSize=10MB +log4j.appender.S.MaxBackupIndex=10 +log4j.appender.S.layout=org.apache.log4j.PatternLayout +log4j.appender.S.layout.ConversionPattern= %d %p %t [%c] - %m%n diff --git a/src/main/resources/static/assets/80x15.png b/src/main/resources/static/assets/80x15.png new file mode 100755 index 0000000000000000000000000000000000000000..863f00bba687de1d180382caed466322c8d7130d GIT binary patch literal 410 zcmV;L0cHM)P)IWd0001%P)t-s00030 z|NpD8szgLYcXxM)h=|P0%L3Y$PEn)85tQMARr+jAtWUu zCnzT_FfK7OF*!RqJ3Tu=LP0`8LPJACXKQDMhK7fShqJh{#>&Rs-Q93hYCr%00KZ8@ zK~#9!t&`ajf-nq4lXL?GK@=Bo-}mMJf6msaIE*g>z0;?*b9!&m05}&ql>w5`1%%yV zflt)#)^zs)`hh4OVH={>s3GvM`ns0TCz|z|0b_yE1Ev^w64_2?9^3lbOBI1bn4s4| z&O?>u$YY&(YR}&bt2!KjRHiGP#AN0H(fv_4{NLY?Lzae$XUL6x`xRU z&)ZTBYXSF5$6fa4w*q)tJNSpXEmzAsE}Bk?>sfZJ7p(vY=~-shMgRZ+07*qoM6N<$ Ef-cvre*gdg literal 0 HcmV?d00001 diff --git a/src/main/resources/static/assets/Logo_Horizontal.png b/src/main/resources/static/assets/Logo_Horizontal.png new file mode 100755 index 0000000000000000000000000000000000000000..797a31bf0c08ba7276e93a6dc92d3acbf34050af GIT binary patch literal 12549 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/assets/Logo_Horizontal_white_small.png b/src/main/resources/static/assets/Logo_Horizontal_white_small.png new file mode 100755 index 0000000000000000000000000000000000000000..e8a3a6acc61a79cdf51c77fbeeb8294dc065f0e5 GIT binary patch literal 4630 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 M07*qoM6N<$g4Tq*yZ`_I literal 0 HcmV?d00001 diff --git a/src/main/resources/static/assets/apple-icon-72x72.png b/src/main/resources/static/assets/apple-icon-72x72.png new file mode 100755 index 0000000000000000000000000000000000000000..324905aac812bea8b16b454f031ecbae3fb20f3f GIT binary patch literal 4587 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 Ym}mhe#`hYb`R6PEl!~TuCBi)TKf1hbi2wiq literal 0 HcmV?d00001 diff --git a/src/main/resources/static/assets/custom.css b/src/main/resources/static/assets/custom.css new file mode 100755 index 0000000..79585a7 --- /dev/null +++ b/src/main/resources/static/assets/custom.css @@ -0,0 +1,1152 @@ +@import url('https://fonts.googleapis.com/css?family=Josefin+Sans|Raleway|Roboto|Roboto:900|Roboto+Condensed|Roboto+Mono|Roboto+Slab'); +@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,400'); +@import url('https://fonts.googleapis.com/css?family=Merriweather|Merriweather+Sans'); +@import url('https://fonts.googleapis.com/css?family=Roboto+Slab'); +@import url('https://fonts.googleapis.com/css?family=Lora'); +@import url('https://fonts.googleapis.com/css?family=Raleway|Raleway+Dots'); + +.custom-icon { + line-height: unset; +} +/*.OPEN { + background: rgba(0, 0, 0, 0) url('images/openaccess copy.svg') no-repeat scroll right center; + /*display: inline-block;*/ +}*/ +.small-bgicon { + background-size: 25px; + padding-right:25px; +} +.medium-bgicon { + background-size: 50px; + padding-right:50px; +} +.large-bgicon { + background-size: 80px; + padding-right:80px; +} + + +body { +font-family: 'Open Sans', sans-serif!important; +font-family: Raleway, sans-serif!important; +font-weight:400!important; + +} +h1, .uk-h1, h2, .uk-h2, h3, .uk-h3 { + font-family: 'Open Sans', sans-serif !important; + text-transform:none!important; + font-weight:300; +} +h4, .uk-h4, h5, .uk-h5 { + font-family: 'Open Sans', sans-serif !important; + font-weight:bold; +} + +h6, .uk-h6 { + font-family: 'Open Sans', sans-serif !important; + font-weight: normal; +} +h2, .uk-h2 { + font-size:36px; +} + +a, .uk-link { + color: #2D72D6; +} +a:hover, .uk-link:hover{ +color: #D53B23; +} + +/*.uk-badge, .badge, a.badge { border-radius: 2px;}*/ + + +.hero_to_top { +} +.image-front-topbar { + margin-top:-40px; +} + +.tm-header { +/*padding-top:40px;*/ +} + +.tm-toolbar { +border-top: 5px solid #05007A; +position:relative; +color: #fff; +padding-top: 0px; +padding-bottom:0px; +background:rgba(255,255,255, 0.0); +z-index:10000; +/*background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,0)), url(/images/toolbar_bg.png);*/ + +} +.tm-toolbar .forimage { +background:rgba(255,255,255, 0.4); +} + +.uk-section-overlap { + /*margin-top:-40px!important;*/ +} +.uk-sticky{ +} + +.tm-header .uk-navbar-left {position:relative;z-index:9999!important;} +.tm-header .uk-logo {padding: 5px 10px 10px 10px; position:relative;z-index:1000!important;} +.tm-header .uk-navbar-transparent{ + /* background:rgba(255,255,255, 0.7);*/ + padding-top:4px; +} +.inner { + left:0px; + background-color: #05007A; + margin-top:-5px; +} +.tm-toolbar .uk-container { +padding-right:0px; +} + +.tm-toolbar ul.uk-subnav.uk-subnav-line{ + margin-top:-10px; + background-color: #05007A; + padding:10px 10px 0px 0px; + transform: skew(25deg); + margin-right:10px; +} + +.tm-toolbar .uk-subnav-line li { + padding:5px 25px 5px 25px; + /*transition: background 0.2s;*/ + /* display:inline-block;*/ + font-family:Roboto!important; + font-weight:900!important; + text-transform:uppercase!important; + font-size:12px!important; + opacity:1!important; + display:inline-block; +} +.tm-toolbar .uk-subnav-line > :before { + content: none; + display: block; + /* display: inline-block*/ + height: 10px; + vertical-align: middle +} + +.uk-subnav-line > :nth-child(n + 2):before { + margin-right: 10px; + border-left: 0px ; +} + +.tm-toolbar .uk-subnav-line li a{ + display: block; + text-decoration:none; + transform: skew(-25deg); + font-family:Roboto:900!important; + text-transform:uppercase!important; + font-size:13px!important; + opacity:1!important; + color:#fff!important; +} + + +.tm-toolbar .uk-subnav-line li:hover { + color:#05007A!important; + background:#fff; + display: block; +} + + +.tm-toolbar .uk-subnav-line .uk-active .home-hover li:hover, +li.uk-active.home-hover +{ + background:#05007A!important; +} + +.tm-toolbar .uk-dotnav, .tm-toolbar .uk-subnav { + margin-bottom:0px!important; +} + +.tm-toolbar .uk-subnav-line li a:hover, +.tm-toolbar .uk-subnav-line li:hover a { + display: block; + color:#05007A!important; +} + +.movetotop .uk-slidenav-position{ + /*top:-130px; + z-index:5;*/ +} + +.uk-navbar-container:not(.uk-navbar-transparent) { + background: #fff; + box-shadow: 2px 15px 50px rgba(41, 44, 61, .1); +} + +.uk-navbar-sticky { + box-shadow: 2px 15px 50px rgba(41, 44, 61, .1); +} + +.navbar .nav>li>.dropdown-menu, .uk-navbar-dropdown +{display: none; +position: absolute; +z-index: 1020; +box-sizing: border-box; +width: 200px; +padding: 25px; +background: #fff; +color: #4F5260; +border-radius: 2px; +box-shadow: 2px 15px 50px rgba(41, 44, 61, .1) +} + + +/* +.uk-light a, .uk-light .uk-link, +.uk-section-primary:not(.uk-preserve-color) a, .uk-section-primary:not(.uk-preserve-color) .uk-link, +.uk-section-secondary:not(.uk-preserve-color) a, .uk-section-secondary:not(.uk-preserve-color) .uk-link, +.uk-tile-primary:not(.uk-preserve-color) a, .uk-tile-primary:not(.uk-preserve-color) .uk-link, +.uk-tile-secondary:not(.uk-preserve-color) a, .uk-tile-secondary:not(.uk-preserve-color) .uk-link, +.uk-card-primary.uk-card-body a, .uk-card-primary.uk-card-body .uk-link, .uk-card-primary>:not([class*='uk-card-media']) a, +.uk-card-primary>:not([class*='uk-card-media']) .uk-link, .uk-card-secondary.uk-card-body a, +.uk-card-secondary.uk-card-body .uk-link, .uk-card-secondary>:not([class*='uk-card-media']) a, +.uk-card-secondary>:not([class*='uk-card-media']) .uk-link, .uk-overlay-primary a, .uk-overlay-primary .uk-link, +*/ +.uk-navbar-container:not(.uk-navbar-transparent) a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-link, +.uk-offcanvas-bar a, .uk-offcanvas-bar .uk-link, .tm-toolbar a, .tm-toolbar .uk-link { + color: #292C3D +} + + +.uk-navbar-container:not(.uk-navbar-transparent) a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-link, +.uk-offcanvas-bar a, .uk-offcanvas-bar .uk-link, .tm-toolbar a, .tm-toolbar .uk-link { +/*color:#292C3D; +color: #245BCC; +color: #2D72D6; +*/ +/* +font-size: 14px; +line-height: 18px; +*/ +} + +/*footer*/ +.footer-license { +font-size:11px!important; +line-height:16px!important; +} +.footer-license .uk-section-primary:not(.uk-preserve-color) a{ + color: #128DD5!important; + font-size:11px!important; +line-height:16px!important; + +} +.footer-license a:hover { + color: #D33A24; +} + +.uk-light .uk-navbar-nav>li>a, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li>a, .uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li>a, .uk-card-primary.uk-card-body .uk-navbar-nav>li>a, .uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a, .uk-card-secondary.uk-card-body .uk-navbar-nav>li>a, .uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a, .uk-overlay-primary .uk-navbar-nav>li>a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li>a, .uk-offcanvas-bar .uk-navbar-nav>li>a, .tm-toolbar .uk-navbar-nav>li>a { +color:#292C3D;} + +.uk-light .uk-navbar-nav>li.uk-active>a, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li.uk-active>a, .uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li.uk-active>a, .uk-card-primary.uk-card-body .uk-navbar-nav>li.uk-active>a, .uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li.uk-active>a, .uk-card-secondary.uk-card-body .uk-navbar-nav>li.uk-active>a, .uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li.uk-active>a, .uk-overlay-primary .uk-navbar-nav>li.uk-active>a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li.uk-active>a, .uk-offcanvas-bar .uk-navbar-nav>li.uk-active>a, .tm-toolbar .uk-navbar-nav>li.uk-active>a +color:#292C3D;} + +.uk-light .uk-navbar-nav>li>a::before, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li>a::before, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li>a::before, +.uk-card-primary.uk-card-body .uk-navbar-nav>li>a::before, +.uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a::before, . +uk-card-secondary.uk-card-body .uk-navbar-nav>li>a::before, +.uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a::before, +.uk-overlay-primary .uk-navbar-nav>li>a::before, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li>a::before, +.uk-offcanvas-bar .uk-navbar-nav>li>a::before, .tm-toolbar .uk-navbar-nav>li>a::before { + +background-color: #128DD5; +} +.uk-navbar-nav>li>a::before { +/*height:2px;*/ +background-color: #128DD5!important; +} +.uk-light .uk-navbar-nav>li:hover>a, .uk-light .uk-navbar-nav>li>a:focus, .uk-light .uk-navbar-nav>li>a.uk-open, +.uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li:hover>a, +.uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li>a:focus, +.uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li>a.uk-open, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li:hover>a, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li>a:focus, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li>a.uk-open, +.uk-card-primary.uk-card-body .uk-navbar-nav>li:hover>a, .uk-card-primary.uk-card-body .uk-navbar-nav>li>a:focus, +.uk-card-primary.uk-card-body .uk-navbar-nav>li>a.uk-open, +.uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li:hover>a, +.uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a:focus, +.uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a.uk-open, +.uk-card-secondary.uk-card-body .uk-navbar-nav>li:hover>a, +.uk-card-secondary.uk-card-body .uk-navbar-nav>li>a:focus, +.uk-card-secondary.uk-card-body .uk-navbar-nav>li>a.uk-open, +.uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li:hover>a, +.uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a:focus, +.uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a.uk-open, +.uk-overlay-primary .uk-navbar-nav>li:hover>a, .uk-overlay-primary .uk-navbar-nav>li>a:focus, +.uk-overlay-primary .uk-navbar-nav>li>a.uk-open, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li:hover>a, +.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li>a:focus, +.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li>a.uk-open, +.uk-offcanvas-bar .uk-navbar-nav>li:hover>a, .uk-offcanvas-bar .uk-navbar-nav>li>a:focus, +.uk-offcanvas-bar .uk-navbar-nav>li>a.uk-open, .tm-toolbar .uk-navbar-nav>li:hover>a, +.tm-toolbar .uk-navbar-nav>li>a:focus, .tm-toolbar .uk-navbar-nav>li>a.uk-open { +color: #128DD5; +} + +.uk-light .uk-navbar-nav > li:hover > a, .uk-light .uk-navbar-nav > li > a:focus, +.uk-light .uk-navbar-nav > li > a.uk-open, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav > li:hover > a, +.uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav > li > a:focus, +.uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav > li > a.uk-open, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav > li:hover > a, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav > li > a:focus, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav > li > a.uk-open, +.uk-card-primary.uk-card-body .uk-navbar-nav > li:hover > a, .uk-card-primary.uk-card-body .uk-navbar-nav > li > a:focus, +.uk-card-primary.uk-card-body .uk-navbar-nav > li > a.uk-open, .uk-card-primary > :not([class * ='uk-card-media']) .uk-navbar-nav > li:hover > a, +.uk-card-primary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a:focus, +.uk-card-primary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a.uk-open, +.uk-card-secondary.uk-card-body .uk-navbar-nav > li:hover > a, .uk-card-secondary.uk-card-body .uk-navbar-nav > li > a:focus, +.uk-card-secondary.uk-card-body .uk-navbar-nav > li > a.uk-open, .uk-card-secondary > :not([class * ='uk-card-media']) .uk-navbar-nav > li:hover > a, +.uk-card-secondary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a:focus, +.uk-card-secondary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a.uk-open, +.uk-overlay-primary .uk-navbar-nav > li:hover > a, .uk-overlay-primary .uk-navbar-nav > li > a:focus, +.uk-overlay-primary .uk-navbar-nav > li > a.uk-open, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li:hover > a, +.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li > a:focus, +.uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li > a.uk-open, +.uk-offcanvas-bar .uk-navbar-nav > li:hover > a, .uk-offcanvas-bar .uk-navbar-nav > li > a:focus, +.uk-offcanvas-bar .uk-navbar-nav > li > a.uk-open, .tm-toolbar .uk-navbar-nav > li:hover > a, +.tm-toolbar .uk-navbar-nav > li > a:focus, .tm-toolbar .uk-navbar-nav > li > a.uk-open { + color: #128DD5!important; +} +.uk-light .uk-navbar-nav>li.uk-active>a, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li.uk-active>a, .uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li.uk-active>a, .uk-card-primary.uk-card-body .uk-navbar-nav>li.uk-active>a, .uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li.uk-active>a, .uk-card-secondary.uk-card-body .uk-navbar-nav>li.uk-active>a, .uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li.uk-active>a, .uk-overlay-primary .uk-navbar-nav>li.uk-active>a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li.uk-active>a, .uk-offcanvas-bar .uk-navbar-nav>li.uk-active>a, .tm-toolbar .uk-navbar-nav>li.uk-active>a { + color: #128DD5!important; +} +.uk-light a:hover, .uk-light .uk-link:hover, +.uk-section-primary:not(.uk-preserve-color) a:hover, .uk-section-primary:not(.uk-preserve-color) .uk-link:hover, +.uk-section-secondary:not(.uk-preserve-color) a:hover, .uk-section-secondary:not(.uk-preserve-color) .uk-link:hover, +.uk-card-primary.uk-card-body a:hover, .uk-card-primary.uk-card-body .uk-link:hover, +.uk-card-primary>:not([class*='uk-card-media']) a:hover, .uk-card-primary>:not([class*='uk-card-media']) .uk-link:hover, +.uk-card-secondary.uk-card-body a:hover, .uk-card-secondary.uk-card-body .uk-link:hover, +.uk-card-secondary>:not([class*='uk-card-media']) a:hover, .uk-card-secondary>:not([class*='uk-card-media']) .uk-link:hover, +.uk-overlay-primary a:hover, .uk-overlay-primary .uk-link:hover, +.uk-navbar-container:not(.uk-navbar-transparent) a:hover, .uk-navbar-container:not(.uk-navbar-transparent) .uk-link:hover, +.uk-offcanvas-bar a:hover, .uk-offcanvas-bar .uk-link:hover, .tm-toolbar a:hover, .tm-toolbar .uk-link:hover { + color: #128DD5!important; +} + +.uk-navbar-dropdown-nav>li.uk-active>a { + color: #128DD5!important; +} +.uk-light .uk-navbar-nav > li > a:active, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav > li > a:active, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav > li > a:active, +.uk-card-primary.uk-card-body .uk-navbar-nav > li > a:active, .uk-card-primary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a:active, +.uk-card-secondary.uk-card-body .uk-navbar-nav > li > a:active, .uk-card-secondary > :not([class * ='uk-card-media']) .uk-navbar-nav > li > a:active, +.uk-overlay-primary .uk-navbar-nav > li > a:active, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li > a:active, +.uk-offcanvas-bar .uk-navbar-nav > li > a:active, .tm-toolbar .uk-navbar-nav > li > a:active { + color: #292C3D!important; +} + +.uk-light .uk-navbar-nav > li.uk-active > a, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav > li.uk-active > a, +.uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav > li.uk-active > a, +.uk-card-primary.uk-card-body .uk-navbar-nav > li.uk-active > a, .uk-card-primary > :not([class * ='uk-card-media']) .uk-navbar-nav > li.uk-active > a, +.uk-card-secondary.uk-card-body .uk-navbar-nav > li.uk-active > a, +.uk-card-secondary > :not([class * ='uk-card-media']) .uk-navbar-nav > li.uk-active > a, +.uk-overlay-primary .uk-navbar-nav > li.uk-active > a, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav > li.uk-active > a, +.uk-offcanvas-bar .uk-navbar-nav > li.uk-active > a, .tm-toolbar .uk-navbar-nav > li.uk-active > a { + color: #292C3D!important; +} +.uk-light .uk-navbar-nav>li>a:active, .uk-section-primary:not(.uk-preserve-color) .uk-navbar-nav>li>a:active, .uk-section-secondary:not(.uk-preserve-color) .uk-navbar-nav>li>a:active, .uk-card-primary.uk-card-body .uk-navbar-nav>li>a:active, .uk-card-primary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a:active, .uk-card-secondary.uk-card-body .uk-navbar-nav>li>a:active, .uk-card-secondary>:not([class*='uk-card-media']) .uk-navbar-nav>li>a:active, .uk-overlay-primary .uk-navbar-nav>li>a:active, .uk-navbar-container:not(.uk-navbar-transparent) .uk-navbar-nav>li>a:active, .uk-offcanvas-bar .uk-navbar-nav>li>a:active, .tm-toolbar .uk-navbar-nav>li>a:active { +color:#128DD5!important; +} + +.uk-navbar-dropdown-nav { + font-size:14px; +} +.uk-navbar-nav>li>a, .uk-navbar-item, .uk-navbar-toggle, .navbar .brand, .navbar-search, .navbar .nav>li>a { + font-size: 14px; + font-family: Roboto; + font-family: "Merriweather", serif; + font-family: 'Merriweather Sans', sans-serif; + font-family: 'Roboto Slab', serif; + font-size: 16px; + line-height: 23px; +text-transform:none; +color: rgba(0, 0, 0, 0.8)!important; + font-weight: 500 !important; +} +.uk-nav-default .uk-nav-header, +.uk-navbar-dropdown-nav .uk-nav-header { +color: #245CCF; +font-size:14px; +} + +.sidemenu .uk-h3{ + +padding-bottom: 15px; +font-weight: 300; +text-transform: none; +color:#040067; +} +.sidemenu .uk-nav, .uk-nav ul, .dropdown-menu { +font-weight: 300; +font-size: 14px; +color: #80828B; + +} +.sidemenu ul>li>ul, .sidemenu ul>li>ol, .sidemenu ol>li>ol, .sidemenu ol>li>ul{ +padding-left: 40px; +} +.sidemenu ul>li>ul a { +color: #80828B!important; +color: rgba(99, 104, 114, 0.8)!important; +} +.sidemenu ul>li>ul a:hover { +color: #D53B23!important; +} +.uk-nav-header:not(:first-child) {margin-top:10px;} +.uk-navbar-dropdown, .navbar .nav>li>.dropdown-menu { + background:#fff; +} +.uk-nav>li>a, +.uk-navbar-dropdown-nav>li>a, +.uk-navbar-dropdown-nav .uk-nav-sub a { + color:#292C3D; + font-weight:300; + padding:4px 0; +} +.uk-section-secondary:not(.uk-preserve-color) h3, +.uk-section-secondary:not(.uk-preserve-color) h3 a, +.uk-section-secondary:not(.uk-preserve-color) a:hover { color:#444!important;} + + +.uk-article-title { +font-size: 38px; +line-height: 1.1; +} + +.uk-text-meta { +font-size: 14px; +line-height: 1.4; +color: #90929D; +font-family: PT Serif; +font-weight: 400; +text-transform: none; +letter-spacing: 0; +font-style: italic; +} +.uk-card-default .uk-card-title { +color: #292C3D !important; + +} +.uk-light .uk-text-meta, .uk-section-primary:not(.uk-preserve-color) .uk-text-meta, .uk-section-secondary:not(.uk-preserve-color) .uk-text-meta, .uk-card-primary.uk-card-body .uk-text-meta, .uk-card-primary>:not([class*='uk-card-media']) .uk-text-meta, .uk-card-secondary.uk-card-body .uk-text-meta, .uk-card-secondary>:not([class*='uk-card-media']) .uk-text-meta, .uk-overlay-primary .uk-text-meta, .uk-navbar-container:not(.uk-navbar-transparent) .uk-text-meta, .uk-offcanvas-bar .uk-text-meta, .tm-toolbar .uk-text-meta{ +color: #90929D; +} + +.uk-text-primary {color: #040067!important;} +.uk-text-secondary {color: #00a0de!important;} +.uk-section-primary { + background: #040067; +} +.uk-section-secondary { + background: #00a0de; +} +.first_page_section { + /*position: relative;*/ + } +.first_page_section .uk-section>:last-child { +position: relative; +top: 50%; +transform: translateY(-50%); +} + +.first_page_section .first_page_banner_headline { + /*position: relative;*/ + font-family: 'Open Sans', sans-serif; + font-weight: 300; + color:#fff; + +} +.first_page_panel h3.uk-h1 { + color:#fff; +} +.first_page_panel { + border: 0px solid #e5e5e7!important; + padding:20px 20px!important; +/*width:100%!important;*/ + font-size:24pt!important; + padding:20px!important; + color:#fff; +} +.first_page_panel .banner_text_bottom { + font-size:20pt; + padding:20px; +} +.mainHdr {background-color: rgb(4, 0, 103)!important; +} + + +/*tabs*/ +.wk-tab::before { + content: ""; + position: absolute; + bottom: 0; + left: 20px; + right: 0; + border-bottom: 1px solid #e5e5e5; +} +.wk-tab>li.wk-active>a { +border-color: transparent transparent #1678CB transparent !important; +background:tranparent; +border-bottom: 2px solid #1678CB; +} +.wk-tab>*>a { + display: block; + text-align: center; + padding: 9px 20px; + color: #444!important; + border-bottom: 2px solid transparent; + font-size: 12px; + text-transform: uppercase; + -webkit-transition: color 0.1s ease-in-out; + transition: color 0.1s ease-in-out; + line-height: 20px; +} + +.wk-tab>li.wk-open>a, .wk-tab>li>a:focus, .wk-tab>li>a:hover { +border-color: transparent transparent #1678CB transparent !important; +background: transparent!important; +color: #1678CB!important; +outline: 0 +} + +.serviceicon .wk-panel h3{ text-transform: uppercase!important; font-weight: 700; font-size:12px; +} +.serviceicon .wk-panel:hover h3{ + color: #D53B23!important; +} +.serviceicon .wk-margin, +.serviceicon .wk-panel-teaser, .serviceicon .wk-panel-title {margin-bottom:10px;} +.serviceicon *+.wk-margin {margin-top:10px;} + +.key_message { + color: #128DD5!important; +} +.larger-font { + font-size:120%; +} + +.nspArt h4.nspHeader { +font-family: 'Open Sans', sans-serif !important; +font-weight: 400; +font-size: 16px; +margin: 0; +padding: 5px 0 5px 0; +} +.nspArt p, .nspArt ul, .nspArt ol, .nspArt dl, .nspArt pre, .nspArt address, .nspArt fieldset, .nspArt figure { + margin-top: 0px; + margin-bottom: 8px; +} +.nspArt p.nspText {margin-bottom:15px;} +.readon , .readon:link{ + margin: 0; + border: 1px solid #eaeaea; + overflow: visible; + font: inherit; + color: inherit; + text-transform: none; + display: inline-block; + box-sizing: border-box; + padding: 0 25px; + vertical-align: middle; + font-size: 13px; + line-height: 40px; + text-align: center; + text-decoration: none; + -webkit-transition: .1s ease-in-out; + transition: .1s ease-in-out; + -webkit-transition-property: color, background-color, border-color, box-shadow; + transition-property: color, background-color, border-color, box-shadow; + font-family: Roboto; + font-weight: normal; + text-transform: uppercase; + border-radius: 2px; + background-color: #fff; + color: #5b5b5b; + box-shadow: 0px 3px 12px rgba(0, 0, 0, 0.07); +} + +.readon:hover{ +background-color: #fff; +color: #00a0de; +box-shadow: 0 6px 50px rgba(0, 0, 0, 0.05); +} +.banner_text_white {font-weight: 300; font-size: 28px; color:white;} + + +/*custom classes */ +.partner_slider .wk-link-reset, .partner_slider .wk-link-reset a, .partner_slider .wk-link-reset a:focus, +.partner_slider .wk-link-reset a:hover, .partner_slider .wk-link-reset:focus, .partner_slider .wk-link-reset:hover { +color: black; +} +.dark-divider hr, .dark-divider .uk-hr { +border-top: 1px solid #6c6c6c; +} + +/*events*/ +.calendar h3{text-transform:none; font-weight:300; margin-bottom:5px; margin-top:5px;} +.mod_events_latest_table td { + padding-top:5px; + padding-bottom:5px; +} +.mod_events_latest_table td p{ + margin-bottom:10px; + margin-top:0px; +} + +.mod_events_latest_date { + width: 18%; + float: left; + position: relative; + color:#757575; + color:#fff; + font-size:12px!important; + background: #9c9c9c; + font-weight:400; + /* + border-radius: 1px; + -moz-border-radius: 1px; + -webkit-border-radius: 1px; + border: 1px solid #757575; + -moz-box-shadow: 0px 0px 3px #757575; + -webkit-box-shadow: 0px 0px 3px #757575; + box-shadow: 0px 0px 3px #757575; + */ + margin-right:8px; + margin-top:5px; + text-align:center; + padding:10px 0px; + line-height:20px; + +} +.mod_events_latest_date .larger_font { + font-size:28px!important; + font-weight:700!important;} + +.mod_events_latest_time { + //float: left; + position: relative; + width: 75%; + overflow:visible; + line-height:14px; + font-weight:400; + font-size:12px; + padding: 5px 0px; + margin-bottom: 8px; + text-transform:none; +} +.mod_events_latest_time { + font-size:12px; +} +.mod_events_latest_table td .content{ + font-size:12px!important; + font-weight:300; + text-transform:none; +} +.mod_events_latest_table td .hdr{ + font-size:14px!important; + line-height: 16px; + font-weight:400!important; + text-transform:none; +} +.mod_events_latest_rsslink a { +color: #767779; + +} +.mod_events_latest_rsslink{ +padding: 30; +line-height: 1.625; +background: 0; +color: #767779; +position: relative; +padding-right: 27px; +margin: 0; +border: 0; +overflow: visible; +font: inherit; +display: block; +box-sizing: border-box; +vertical-align: middle; +font-size: 13px; +display:inline-block; +text-decoration: none; +-webkit-transition: .1s ease-in-out; +transition: .1s ease-in-out; +-webkit-transition-property: color, background-color, border-color, box-shadow; +transition-property: color, background-color, border-color, box-shadow; +font-family: Roboto; +font-weight: normal; +text-transform: uppercase; +border-radius: 2px; +background-origin: border-box; +} +.mod_events_latest_rsslink a:hover { +color: #00a0de; + +} +.mod_events_latest_rsslink:hover::before { +background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2223%22%20height%3D%2211%22%20viewBox%3D%220%200%2023%2011%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Cpolyline%20fill%3D%22none%22%20stroke%3D%22%2300a0de%22%20points%3D%2217%201%2022%205.5%2017%2010%20%22%3E%3C%2Fpolyline%3E%0A%20%20%20%20%3Cline%20fill%3D%22none%22%20stroke%3D%22%2300a0de%22%20x1%3D%220%22%20y1%3D%225.5%22%20x2%3D%2222.4%22%20y2%3D%225.5%22%3E%3C%2Fline%3E%0A%3C%2Fsvg%3E"); +background-position: 100% 50%; + +} +.mod_events_latest_rsslink::before{ +content: ""; +position: absolute; +top: 0; +bottom: 0; +right: 0; +width: 22px; +background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2223%22%20height%3D%2211%22%20viewBox%3D%220%200%2023%2011%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Cpolyline%20fill%3D%22none%22%20stroke%3D%22%23767779%22%20points%3D%2217%201%2022%205.5%2017%2010%20%22%3E%3C%2Fpolyline%3E%0A%20%20%20%20%3Cline%20fill%3D%22none%22%20stroke%3D%22%23767779%22%20x1%3D%220%22%20y1%3D%225.5%22%20x2%3D%2222.4%22%20y2%3D%225.5%22%3E%3C%2Fline%3E%0A%3C%2Fsvg%3E"); +background-repeat: no-repeat; +background-position: calc(100% - 5px) 50%; +-webkit-transition: background-position .2s ease-out; +transition: background-position .2s ease-out; +} +.mod_events_latest_callink a, .mod_events_latest_callink a:hover{ + color: #fff!important; +} +.mod_events_latest_callink { +padding:0px; + margin:10px 0px; + background-color: #00a0de; + color: #fff!important; + display: inline-block; + box-sizing: border-box; +padding: 0 25px; +vertical-align: middle; +font-size: 13px; +line-height: 40px; +text-align: center; +text-decoration: none; +-webkit-transition: .1s ease-in-out; +transition: .1s ease-in-out; +-webkit-transition-property: color, background-color, border-color, box-shadow; +transition-property: color, background-color, border-color, box-shadow; +font-family: Roboto; +font-weight: normal; +text-transform: uppercase; +border-radius: 2px; +background-origin: border-box; +} + +.mod_events_latest_callink:hover { +background-color: #008ec5; +color: #fff!important; +} +/* news pro */ +.nspLinks ul li h4 { +font-weight: 400; +font-size: 16px; +line-height: 18px; +} +.nspLinks ul li p { + text-transform:none; + font-size: 14px; + font-weight:300; + margin:10px; +} +.readon-button{ +text-transform: none; +font-size: 14px; +line-height: 20px; +font-weight: 300; +font-family: 'Open Sans', sans-serif !important; +} +.readon-button:hover { +} +.newsletter .uk-h2 {font-size:28px!important;} +.newsletter .uk-icon { +padding-left: 10px; +padding-bottom: 15px; +vertical-align: middle; +} +.newsletter .el-title{ +display: inline-block; +fill: currentcolor; +margin-bottom:0; +} + +.newsletter .acymailing_mootoolsbutton a:link, +.newsletter .acymailing_mootoolsbutton a:visited { +background:none!important; +border:none!important; +text-shadow:none!important; +color: rgba(255, 255, 255, 0.5)!important; +font-size: 14px; +font-weight: 300; +line-height: 20px; +} + +.newsletter .acysubbuttons input.button, .newsletter .acysubbuttons .button { +padding: 0 15px!important; +line-height: 30px; +font-size: 13px; +border-radius: 2px; +margin: 0; +border: 0; +overflow: visible; +font-family: Roboto; +font-weight: normal; + +color: inherit; +text-transform: none; +display: inline-block; +box-sizing: border-box; +vertical-align: middle; +text-align: center; +text-decoration: none; +-webkit-transition: .1s ease-in-out; +transition: .1s ease-in-out; +-webkit-transition-property: color, background-color, border-color, box-shadow; +transition-property: color, background-color, border-color, box-shadow; +font-family: Roboto; +font-weight: normal; +text-transform: uppercase; +background-origin: border-box; +box-shadow: 0 3px 12px rgba(0, 0, 0, 0.07); +} + +.newsletter .acysubbuttons input.button:hover, .newsletter .acysubbuttons .button:hover { +color:#444; +background-color:#fff!important; +background-image:none!important; +} + +.newsletter .acysubbuttons input.button:hover, .newsletter .acysubbuttons .button:hover, +.newsletter .acysubbuttons button.validate:hover, .newsletter .acymailing_mootoolsbutton a:hover, +.newsletter .acymailing_mootoolsbutton a:active { +box-shadow:none!important; +-moz-box-shadow:none!important; +-webkit-box-shadow:none!important; +color: #00a0de!important; +box-shadow: 0 6px 50px rgba(0, 0, 0, 0.05)!important; +} +.acymailing_module a.acymailing_togglemodule { +font-size: 14px; +font-weight: 300; +color: rgba(255, 255, 255, 0.5)!important; +} + + +/*login button */ +#btl .btl-panel > span .btl-dropdown { border:3!important;} + +#btl .btl-panel > span{ + border: 0px!important; + background-color: transparent!important; + color:#444!important; + padding-right:30px; + padding-left:6px; + height:0px!important; + line-height:20px!important; + margin:0px !important; + box-shadow: 0px 0px 0px; + border-radius:0px!important; + display: inline-table!important; + text-transform:none!important; + font-size: 14px; + font-family: 'Roboto Slab', serif; + font-size: 16px; + line-height: 23px; + font-weight: 500 !important; +} +.loginLink { +text-transform:none!important; +color: rgba(0, 0, 0, 0.8)!important; +} + +/*.btl-panel { + background: url(../images/key_login.png) right 40% no-repeat; +}*/ +#btl-panel-login >span { + border: 5px solid #d0d0d0!important; +} +.uk-navbar-item .btlogin{ color: red!important; +} + +#btl .btl-panel > #btl-panel-profile { +color: #040067!important; +font-size: 13px !important; +font-family: Roboto; +} + +.btl-content-block { +-webkit-font-smoothing: antialiased; +background-attachment: scroll; +background-clip: border-box; +background-color: rgb(255, 255, 255); +background-image: none; +background-origin: padding-box; +background-size: auto; +border-bottom-left-radius: 2px; +border-bottom-right-radius: 2px; +border-top-left-radius: 2px; +border-top-right-radius: 2px; +box-shadow: rgba(41, 44, 61, 0.0980392) 2px 15px 50px 0px; +box-sizing: border-box; +color: rgb(79, 82, 96); +display: none; +height: auto; +margin-top: 0px; +padding-bottom: 25px; +padding-left: 25px; +padding-right: 25px; +padding-top: 25px; +position: absolute; +text-align: left; +text-rendering: optimizeLegibility; +} + +#btl-content #btl-content-profile #module-in-profile ul li img, +#btl-content #btl-content-profile #module-in-profile ul li a {padding-right: 5px!important;} + +#btl-content #btl-content-profile #module-in-profile ul li a { +-webkit-font-smoothing: antialiased; +-webkit-text-decoration-skip: objects; +/*background-color: rgba(0, 0, 0, 0);*/ +box-sizing: border-box; +color: rgb(41, 44, 61); +cursor: pointer; +display: block; +font-family: Roboto; +font-size: 14px; +font-weight: 300; +height: auto; +line-height: 20px; +list-style-image: none; +list-style-position: outside; +list-style-type: none; +padding-bottom: 6px; +padding-left: 0px; +padding-right: 0px; +padding-top: 6px; +text-align: left; +text-decoration: none; +text-rendering: optimizeLegibility; +width: auto; +} + +#module-in-profile ul li a:hover { +color: #128DD5 !important; +} + +/*FAQs*/ + +.searchifaq label { +font-family: Roboto, sans-serif; +font-weight:500; +font-size:16px; +color: #040067; +} +.btn, +.buttonifaq{ +margin-top:10px; +background-color: #fff; + color: #5b5b5b; + box-shadow: 0 3px 12px rgba(0,0,0,0.07); + display: inline-block; + border:none; + box-sizing: border-box; + padding: 0 25px; + vertical-align: middle; + font-size: 13px; + line-height: 40px; + text-align: center; + text-decoration: none; + -webkit-transition: .1s ease-in-out; + transition: .1s ease-in-out; + -webkit-transition-property: color,background-color,border-color,box-shadow; + transition-property: color,background-color,border-color,box-shadow; + font-family: Roboto; + font-weight: normal; + text-transform: uppercase; + border-radius: 2px; + background-origin: border-box; + } +.buttonifaq:hover{ background-color: #fff; + color: #00a0de; + box-shadow: 0 6px 50px rgba(0,0,0,0.05); +} +.ifaq h5.ifaq-item-header { +margin-bottom:10px; +margin-top:10px; +} +.ifaq-tpl-clean_blue_arrow .collapse-open .ifaq-item-header { +font-weight:normal; +} +.ifaq .uk-tab>*>a, .ifaq .nav-tabs>li>a { +text-align:left; +color: #2D72D6; +} +.ifaq .nav-tabs>li>a:hover { + border-color:transparent; + color: #D53B23; +} + +.ifaq .nav>li>a:hover, .ifaq .nav>li>a:focus { background:none;} + +.ifaq-tpl-clean_blue_arrow .ifaq-panel { +box-shadow:none; + border-bottom: 1px solid #eee; + +} + +.ifaq-tpl-clean_blue_arrow .ifaq-collapsible > a { +display: block; padding: 1px 0 1px 0px; +background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%2213%22%20height%3D%221%22%20x%3D%220%22%20y%3D%226%22%3E%3C%2Frect%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%221%22%20height%3D%2213%22%20x%3D%226%22%20y%3D%220%22%3E%3C%2Frect%3E%0A%3C%2Fsvg%3E"); +background-repeat: no-repeat; +background-position: 98% 50%; +} + +.ifaq-tpl-clean_blue_arrow .ifaq-collapsible { + text-shadow:none; + background:transparent; + box-shadow:none; + border-bottom: 1px solid #eee; +} +.ifaq-tpl-clean_blue_arrow .collapse-open, .ifaq-tpl-clean_blue_arrow .collapse-open > a { + background: transparent; + background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%2213%22%20height%3D%221%22%20x%3D%220%22%20y%3D%226%22%3E%3C%2Frect%3E%0A%3C%2Fsvg%3E"); +background-repeat: no-repeat; + background-position: 98% 50%; +} +.ifaq-tpl-clean_blue_arrow .collapse-close:hover { + background:transparent; +} + +.ifaq-tpl-clean_blue_arrow .ifaq-collapsible > a:hover { +background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%2213%22%20height%3D%221%22%20x%3D%220%22%20y%3D%226%22%3E%3C%2Frect%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%221%22%20height%3D%2213%22%20x%3D%226%22%20y%3D%220%22%3E%3C%2Frect%3E%0A%3C%2Fsvg%3E"); + background-repeat: no-repeat; + background-position: 98% 50%; +} + +.ifaq-tpl-clean_blue_arrow .collapse-open > a:hover { +background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Crect%20fill%3D%22%236C6D74%22%20width%3D%2213%22%20height%3D%221%22%20x%3D%220%22%20y%3D%226%22%3E%3C%2Frect%3E%0A%3C%2Fsvg%3E"); +background-repeat: no-repeat; +background-position: 98% 50%; +} + +/*widget accordion */ +.wk-accordion, .wk-text-left {display:block!important;} + + +.faq .wk-accordion-title { + text-transform:none; + font-weight: 400; + font-size:16px; +} + +/* for DISCOVERY PORTAL */ +.discoverHrd {background-color: #f25f30!important;} + +.search_box_bg .uk-input, .search_box_bg .uk-input:focus { +background-color: rgba(255, 255, 255, 1.0)!important; +color: rgba(0, 0, 0, 1.0)!important; +} +.search_box_bg .uk-input::placeholder{ +color: rgba(0, 0, 0, 0.6)!important; +} + +.search_box_bg .uk-text-background{ +background-color: rgba(255, 255, 255, 1.0); +font-size:28px!important; +font-weight: 500; +} +.search_box_bg .uk-grid-divider>:not(.uk-first-column)::before { +border-left-color: rgba(255, 255, 255, 0.6)!important; +} + +/*tags */ +.uk-label-arrow{ + display: inline-block; + height: 21px; + margin: 0 10px 0 0; + padding: 0 7px 0 14px; + white-space: nowrap; + position: relative; + + background-color: #5A9EDA; + + color: white; + font: normal 11px/21px Arial, Tahoma, sans-serif; + text-decoration: none; + + border-top: 1px solid #5A9EDA; + border-bottom: 1px solid #5A9EDA; + border-right: 1px solid #5A9EDA; + border-radius: 1px 3px 3px 1px; +} +.uk-label-arrow:before { + content: ''; + position: absolute; + top: 5px; + left: -6px; + width: 10px; + height: 10px; + + background-color: #5A9EDA; + border-left: 1px solid #5A9EDA; + border-bottom: 1px solid #5A9EDA; + border-radius: 0 0 0 2px; +} +.uk-label-arrow:before { + -webkit-transform: scale(1, 1.5) rotate(45deg); + -moz-transform: scale(1, 1.5) rotate(45deg); + -ms-transform: scale(1, 1.5) rotate(45deg); + transform: scale(1, 1.5) rotate(45deg); +} +.uk-label-arrow:after { + content: ''; + position: absolute; + top: 7px; + left: 1px; + width: 5px; + height: 5px; + background: #FFF; + border-radius: 4px; + border: 1px solid #5A9EDA; +} +.uk-label-arrow a:hover { + color: #FFF; + text-shadow: -1px -1px 0 rgba(153,102,51,0.3); +} +.featurednews.uk-card-default { +background: rgba(255,255,255, 0.6)!important; +color: black; +} +.custom-offcanvas-bar{ + background: grey !important; + width:100% !important; + +} +.custom-offcanvas-bar .filtersModal{ + color:grey !important; + +} +.list-horizontal{ + display: flex; + } +.list-horizontal span{ + margin-right:5px; + padding-left: 0px !important; + +} +.list-horizontal-line span { + margin-right: 5px; + border-right: 1px solid #f1f1f1; + padding-right: 5px; + +} + +.list-horizontal-line > span:last-child { + border-right:none; +} diff --git a/src/main/resources/static/assets/custom.css.1 b/src/main/resources/static/assets/custom.css.1 new file mode 100755 index 0000000..5423d16 --- /dev/null +++ b/src/main/resources/static/assets/custom.css.1 @@ -0,0 +1,322 @@ + +.tm-toolbar .uk-subnav-line .custom-discover-li { + color:#05007A !important; + background:#fff; + display: block; +} +.tm-toolbar .uk-subnav-line .custom-discover-li a{ + color:#05007A !important; +} +.custom-discover-toolbar ul.uk-subnav.uk-subnav-line{ + background-color: #f25f30 !important; + } + + .custom-discover-toolbar .inner { + background-color: #f25f30 !important; + } + + .custom-discover-toolbar{ + border-top-color:#f25f30 !important; + } +.custom-footer{ + position:relative; + bottom:0; + left:0; +} +.custom-external { + background: rgba(0, 0, 0, 0) url("/assets/icon_external.png") no-repeat scroll left center; + padding: 0 0 0 16px; +} + +.custom-navbar-toggle-icon, .custom-user-mini-panel{ + color:#444 !important +} +.custom-user-mini-panel a{ + color:rgb(36, 91, 204); +} +.custom-main-content{ + min-height: 550px; +} + +.custom-autocomplete .uk-nav-autocomplete > li > a:hover { + background: #00a8e6 none repeat scroll 0 0; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.05) inset; + color: #FFF; + outline: medium none; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.1); +} + +.custom-autocomplete .uk-nav-navbar > li > a { + color: #444; +} +.custom-description-list-horizontal{ line-height:200%} +.uk-alert-default { + background: #fff none repeat scroll 0 0; + border: 1px solid #ddd; + border-radius: 4px; + color: #444; + height: 30px; + max-width: 100%; + padding: 4px 6px; + +} +.custom-hidden-dropdown-menu {position:static !important;} +.searchFilterBoxValues {overflow:auto; max-height:200px; } +.selected-filters-box {margin:5px; background-color:#F8F8F8; } +.search-form {margin:5px; } +.clickable { cursor:pointer; } +.search-filters .uk-accordion-title{ + font-size: 14px; + line-height: 18px; +} +.search-results { + min-height: 1100px; +} +.other-results { + min-height: 300px; +} +.OPEN { + background: rgba(0, 0, 0, 0) url("/assets/openAccess.png") no-repeat scroll right center; + padding-right: 18px; + min-height: 18px; +} + +.EMBARGO, .CLOSED, .RESTRICTED { + background: rgba(0, 0, 0, 0) url("/assets/closedAccess.png") no-repeat scroll right center; + padding-right: 18px; +} + +.sc39 { + background: rgba(0, 0, 0, 0) url("/assets/sc39.png") no-repeat scroll right center; + padding-right: 24px; +} + +.projectIcon { + display: inline-table; +} + +.dateFilter .mydp{ + margin-top:5px; +} + + +/*.tooltip { + max-width: none; + background: rgba(100, 100, 100, 1); +}*/ +.tooltip-custom-font-size { + font-size: 120%; +} + +.custom-select-mini{ + max-width:170px !important; +} +.custom-icon { + line-height: unset; +} +/*.custom-tab-content-large{ + min-height: 800px; +} + */ +.custom-tab-content { + min-height: 250px; +} + +.custom-dataTable-content { + min-height: 600px; +} + +.custom-html-table-height { + height: 500px; +} + + + + +.filterItem span { +display: inline-flex; +} +.filterItem .filterName { +max-width: 71%; + +} +.browseFilters .filterItem .filterName { +max-width: 68%; +} + +.filterItem .filterNumber { +width: 20%; +} +.filterItem span { + +white-space: nowrap; +} +.browseFilters .filterItem span div { + /*min-width: 45px;*/ +} +.filterItem span div { +overflow: hidden; +text-overflow: ellipsis; +/*min-width: 81px;*/ +} + +.browseFilters{ +overflow-y: auto; +overflow-x: hidden; +max-height:265px; +} + + + +.custom-offcanvas-close { + position: relative; + right: 0; + top: 0; +} +.uk-link{ + color: #292C3D !important; +} +.uk-breadcrumb > :last-child > * { + color:#cbcbcb !important; +} +.uk-breadcrumb .uk-active a{ + color: #767779 !important; +} + +.publicationTitleIcon { + background: url("/assets/publication.png") no-repeat; +} +.datasetTitleIcon { + background: url("/assets/dataset.png") no-repeat; +} +.projectTitleIcon { + background: url("/assets/project.png") no-repeat; +} +.organizationTitleIcon { + background: url("/assets/organization.png") no-repeat; +} +.datasourceTitleIcon { + background: url("/assets/datasource.png") no-repeat; +} +.entityTitleIcon{ + background-repeat: :no-repeat; + content: ''; + display: inline-block; + height: 36px; + width: 42px; + vertical-align: middle; +} +.entityIcon{ + height: 15px; + width: 20px; + +} +/*.uk-tab{ + border-bottom: 1px #cbcbcb solid; +}*/ +.label-underCuration{ + background: #fef5d2 !important; +} + +.label-blue { + background:#d4f3ff; + color:#00a0de +} +.label-green { + background:#d1f6e8; + color:#01a566 +} +.label-yellow { + background:#fef5d2; + color:#cca607 +} +.label-red { + background:#fef0ef; + color:#f54f43 +} +.label-grey{ + background: #f8f8f8; + color: #666; +} +.label-orange{ + background: #fef5d2; +color: #f0506e; + +} +.uk-tab { + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -ms-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; + margin-left: -20px; + padding: 0; + list-style: none; + position: relative; +} +.uk-tab::before { + content: ""; + position: absolute; + bottom: 0; + left: 20px; + right: 0; + border-bottom: 1px solid #e5e5e5; +} +.mainPageSearchForm{ + background-image: url("./globe_tech.jpg"); background-color: rgb(255, 255, 255); box-sizing: border-box; min-height: calc(100vh - 412.767px); +} +.searchForm, .publicationsSearchForm, .projectsSearchForm, .organizationsSearchForm, .datasetsSearchForm, .datasourcesSearchForm, .journalsSearchForm, +.entityRegistriesSearchForm, .compatibleDatasourcesSearchForm, +.journalsTableSearchForm, .compatibleDatasourcesTableSearchForm, .entityRegistriesTableSearchForm{ + background-image: url('./formImage.jpg'); box-sizing: border-box; height: 250px; +} + +.divider-table tbody td, .uk-table th { + border-bottom: 1px solid #E5E5E5; + } + + #feedback { + float: left; + position: fixed; + top: calc(50% - 47px); + right: 0; + } + + #feedback a { + background: #F25F30; + border-radius: 5px 0 0 5px; + box-shadow: 0 0 3px rgba(0, 0, 0, .3); + border: 3px solid #fff; + border-right: 0; + display: block; + padding: 20px 12px; + transition: all .2s ease-in-out; + } + + #feedback a:hover { + padding-right: 20px; + } + +.descriptionText{ + Padding-left: 25px !important; + Border-left: 10px solid #fafafa; + +} + + +/* +li span { + display: inline-flex; +} + +.item span { + width: 100px; + margin-left: 1em; + white-space: nowrap; +} + +.item span div { + overflow: hidden; + text-overflow: ellipsis; +}*/ diff --git a/src/main/resources/static/assets/favicon.ico b/src/main/resources/static/assets/favicon.ico new file mode 100755 index 0000000000000000000000000000000000000000..151eca1baaa93b204ded4693423dac971f11d08d GIT binary patch literal 32988 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 NnkCRIfj^D}{tq}S<$C}C literal 0 HcmV?d00001 diff --git a/src/main/resources/static/assets/jquery.js b/src/main/resources/static/assets/jquery.js new file mode 100755 index 0000000..e836475 --- /dev/null +++ b/src/main/resources/static/assets/jquery.js @@ -0,0 +1,5 @@ +/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0; +}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"

","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:l.htmlSerialize?[0,"",""]:[1,"X
","
"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("',t,e)};s.onerror=function(){return a(640,320)},s.onload=function(){120===s.width&&90===s.height?r?a(640,320):(r=!0,s.src="//img.youtube.com/vi/"+o+"/0.jpg"):a(s.width,s.height)},s.src="//img.youtube.com/vi/"+o+"/maxresdefault.jpg",t.stopImmediatePropagation()}}}},"lightbox"),t.mixin({events:{showitem:function(t){var e,i=this,o=this.getItem();if(e=o.source.match(/(\/\/.*?)vimeo\.[a-z]+\/([0-9]+).*?/)){var s=e[2],r=function(t,e){return i.setItem(o,'',t,e)};n({type:"GET",url:"http://vimeo.com/api/oembed.json?url="+encodeURI(o.source),jsonp:"callback",dataType:"jsonp"}).then(function(t){return r(t.width,t.height)}),t.stopImmediatePropagation()}}}},"lightbox")}}function qt(t){if(!qt.installed){var e=t.util,i=e.$,n=e.each,o=e.pointerEnter,s=e.pointerLeave,r=e.Transition,a={};t.component("notification",{functional:!0,args:["message","status"],defaults:{message:"",status:"",timeout:5e3,group:null,pos:"top-center",onClose:null,clsClose:"uk-notification-close"},created:function(){a[this.pos]||(a[this.pos]=i('
').appendTo(t.container)),this.$mount(i('
\n \n
'+this.message+"
\n
").appendTo(a[this.pos].show())[0])},ready:function(){var t=this,e=parseInt(this.$el.css("margin-bottom"),10);r.start(this.$el.css({opacity:0,marginTop:-1*this.$el.outerHeight(),marginBottom:0}),{opacity:1,marginTop:0,marginBottom:e}).then(function(){t.timeout&&(t.timer=setTimeout(t.close,t.timeout),t.$el.on(o,function(){return clearTimeout(t.timer)}).on(s,function(){return t.timer=setTimeout(t.close,t.timeout)}))})},events:{click:function(t){i(t.target).closest('a[href="#"]').length&&t.preventDefault(),this.close()}},methods:{close:function(t){var e=this,i=function(){e.onClose&&e.onClose(),e.$el.trigger("close",[e]).remove(),a[e.pos].children().length||a[e.pos].hide()};this.timer&&clearTimeout(this.timer),t?i():r.start(this.$el,{opacity:0,marginTop:-1*this.$el.outerHeight(),marginBottom:0}).then(i)}}}),t.notification.closeAll=function(e,i){n(t.instances,function(t,n){"notification"!==n.$options.name||e&&e!==n.group||n.close(i)})}}}function Yt(t){function e(i){return t.getComponent(i,"sortable")||i.parentNode&&e(i.parentNode)}function i(){var t=setTimeout(function(){return r.trigger("click")},0),e=function(i){i.preventDefault(),i.stopPropagation(),clearTimeout(t),u(r,"click",e,!0)};c(r,"click",e,!0)}if(!Yt.installed){var n=t.mixin,o=t.util,s=o.$,r=o.docElement,a=o.extend,l=o.getDimensions,h=o.isWithin,c=o.on,u=o.off,d=o.offsetTop,f=o.pointerDown,p=o.pointerMove,g=o.pointerUp,m=o.promise,v=o.win;t.component("sortable",{mixins:[n.class],props:{group:String,animation:Number,threshold:Number,clsItem:String,clsPlaceholder:String,clsDrag:String,clsDragState:String,clsBase:String,clsNoDrag:String,clsEmpty:String,clsCustom:String,handle:String},defaults:{group:!1,animation:150,threshold:5,clsItem:"uk-sortable-item",clsPlaceholder:"uk-sortable-placeholder",clsDrag:"uk-sortable-drag",clsDragState:"uk-drag",clsBase:"uk-sortable",clsNoDrag:"uk-sortable-nodrag",clsEmpty:"uk-sortable-empty",clsCustom:"",handle:!1},init:function(){var t=this;["init","start","move","end"].forEach(function(e){var i=t[e];t[e]=function(e){e=e.originalEvent||e,t.scrollY=window.scrollY;var n=e.touches&&e.touches[0]||e,o=n.pageX,s=n.pageY;t.pos={x:o,y:s},i(e)}})},events:(w={},w[f]="init",w),update:{write:function(){var t=this;if(this.clsEmpty&&this.$el.toggleClass(this.clsEmpty,!this.$el.children().length),this.drag){this.drag.offset({top:this.pos.y+this.origin.top,left:this.pos.x+this.origin.left});var e=d(this.drag),i=e+this.drag[0].offsetHeight;e>0&&ewindow.innerHeight+this.scrollY&&setTimeout(function(){return v.scrollTop(t.scrollY+5)},5)}}},methods:{init:function(t){var e=s(t.target),i=this.$el.children().filter(function(e,i){return h(t.target,i)});!i.length||e.is(":input")||this.handle&&!h(e,this.handle)||t.button&&0!==t.button||h(e,"."+this.clsNoDrag)||(t.preventDefault(),t.stopPropagation(),this.touched=[this],this.placeholder=i,this.origin=a({target:e,index:this.placeholder.index()},this.pos),r.on(p,this.move),r.on(g,this.end),v.on("scroll",this.scroll),this.threshold||this.start(t))},start:function(e){this.drag=s(this.placeholder[0].outerHTML.replace(/^
  • $/i,"div>")).attr("uk-no-boot","").addClass(this.clsDrag+" "+this.clsCustom).css({boxSizing:"border-box",width:this.placeholder.outerWidth(),height:this.placeholder.outerHeight()}).css(this.placeholder.css(["paddingLeft","paddingRight","paddingTop","paddingBottom"])).appendTo(t.container),this.drag.children().first().height(this.placeholder.children().height());var i=l(this.placeholder),n=i.left,o=i.top;a(this.origin,{left:n-this.pos.x,top:o-this.pos.y}),this.placeholder.addClass(this.clsPlaceholder),this.$el.children().addClass(this.clsItem),r.addClass(this.clsDragState),this.$el.trigger("start",[this,this.placeholder,this.drag]),this.move(e)},move:function(t){if(!this.drag)return void((Math.abs(this.pos.x-this.origin.x)>this.threshold||Math.abs(this.pos.y-this.origin.y)>this.threshold)&&this.start(t));this.$emit();var i="mousemove"===t.type?t.target:document.elementFromPoint(this.pos.x-document.body.scrollLeft,this.pos.y-document.body.scrollTop),n=e(i),o=e(this.placeholder[0]),r=n!==o;if(n&&!h(i,this.placeholder)&&(!r||n.group&&n.group===o.group)){if(i=n.$el.is(i.parentNode)&&s(i)||n.$el.children().has(i),r)o.remove(this.placeholder);else if(!i.length)return;n.insert(this.placeholder,i),~this.touched.indexOf(n)||this.touched.push(n)}},scroll:function(){var t=window.scrollY;t!==this.scrollY&&(this.pos.y+=t-this.scrollY,this.scrollY=t,this.$emit())},end:function(t){if(r.off(p,this.move),r.off(g,this.end),v.off("scroll",this.scroll),!this.drag)return void("mouseup"!==t.type&&h(t.target,"a[href]")&&(location.href=s(t.target).closest("a[href]").attr("href")));i();var n=e(this.placeholder[0]);this===n?this.origin.index!==this.placeholder.index()&&this.$el.trigger("change",[this,this.placeholder,"moved"]):(n.$el.trigger("change",[n,this.placeholder,"added"]),this.$el.trigger("change",[this,this.placeholder,"removed"])),this.$el.trigger("stop",[this]),this.drag.remove(),this.drag=null,this.touched.forEach(function(t){return t.$el.children().removeClass(t.clsPlaceholder+" "+t.clsItem)}),r.removeClass(this.clsDragState)},insert:function(t,e){var i=this;this.$el.children().addClass(this.clsItem);var n=function(){e.length?!i.$el.has(t).length||t.prevAll().filter(e).length?t.insertBefore(e):t.insertAfter(e):i.$el.append(t)};this.animation?this.animate(n):n()},remove:function(t){this.$el.has(t).length&&(this.animation?this.animate(function(){return t.detach()}):t.detach())},animate:function(t){var e=this,i=[],n=this.$el.children().toArray().map(function(t){return t=s(t),i.push(a({position:"absolute",pointerEvents:"none",width:t.outerWidth(),height:t.outerHeight()},t.position())),t}),o={position:"",width:"",height:"",pointerEvents:"",top:"",left:""};t(),n.forEach(function(t){return t.stop()}),this.$el.children().css(o),this.$updateSync("update",!0),this.$el.css("min-height",this.$el.height());var r=n.map(function(t){return t.position()});m.all(n.map(function(t,n){return t.css(i[n]).animate(r[n],e.animation).promise()})).then(function(){e.$el.css("min-height","").children().css(o),e.$updateSync("update",!0)})}}});var w}}function Rt(t){if(!Rt.installed){var e,i=t.util,n=t.mixin,o=i.$,s=i.doc,r=i.fastdom,a=i.flipPosition,l=i.isTouch,h=i.isWithin,c=i.pointerDown,u=i.pointerEnter,d=i.pointerLeave;t.component("tooltip",{attrs:!0,mixins:[n.togglable,n.position],props:{delay:Number,container:Boolean,title:String},defaults:{pos:"top",title:"",delay:0,animation:["uk-animation-scale-up"],duration:100,cls:"uk-active",clsPos:"uk-tooltip",container:!0},computed:{container:function(){return o(!0===this.$props.container&&t.container||this.$props.container||t.container)}},connected:function(){var t=this;r.mutate(function(){return t.$el.removeAttr("title").attr("aria-expanded",!1)})},disconnected:function(){this.hide()},methods:{show:function(){var t=this;e!==this&&(e&&e.hide(),e=this,s.on("click."+this.$options.name,function(e){h(e.target,t.$el)||t.hide()}),clearTimeout(this.showTimer),this.tooltip=o('").appendTo(this.container),this.$el.attr("aria-expanded",!0),this.positionAt(this.tooltip,this.$el),this.origin="y"===this.getAxis()?a(this.dir)+"-"+this.align:this.align+"-"+a(this.dir),this.showTimer=setTimeout(function(){t.toggleElement(t.tooltip,!0),t.hideTimer=setInterval(function(){t.$el.is(":visible")||t.hide()},150)},this.delay))},hide:function(){this.$el.is("input")&&this.$el[0]===document.activeElement||(e=e!==this&&e||!1,clearTimeout(this.showTimer),clearInterval(this.hideTimer),this.$el.attr("aria-expanded",!1),this.toggleElement(this.tooltip,!1),this.tooltip&&this.tooltip.remove(),this.tooltip=!1,s.off("click."+this.$options.name))}},events:(f={blur:"hide"},f["focus "+u+" "+c]=function(t){t.type===c&&l(t)||this.show()},f[d]=function(t){l(t)||this.hide()},f)});var f}}function Ut(t){function e(t,e){return e.match(new RegExp("^"+t.replace(/\//g,"\\/").replace(/\*\*/g,"(\\/[^\\/]+)*").replace(/\*/g,"[^\\/]+").replace(/((?!\\))\?/g,"$1.")+"$","i"))}function i(t,e){for(var i=[],n=0;ni[t]?n.ratio(e,t,i[t]):e}),e},cover:function(e,i){var n=this;return e=this.fit(e,i),t.each(e,function(t){return e=e[t]0||navigator.pointerEnabled&&navigator.maxTouchPoints>0,de=ue?le?"touchstart":"pointerdown":"mousedown",fe=ue?le?"touchmove":"pointermove":"mousemove",pe=ue?le?"touchend":"pointerup":"mouseup",ge=ue&&he?"pointerenter":"mouseenter",me=ue&&he?"pointerleave":"mouseleave",ve=ue&&le?"touchcancel":"pointercancel",we=L("transition","transition-end"),ye=L("animation","animation-start"),be=L("animation","animation-end"),$e={reads:[],writes:[],measure:function(t){return this.reads.push(t),F(this),t},mutate:function(t){return this.writes.push(t),F(this),t},clear:function(t){return q(this.reads,t)||q(this.writes,t)}};Y.prototype={positions:[],position:null,init:function(){var t=this;this.positions=[],this.position=null;var e=!1;this.handler=function(i){e||setTimeout(function(){var n=Date.now(),o=t.positions.length;o&&n-t.positions[o-1].time>100&&t.positions.splice(0,o),t.positions.push({time:n,x:i.pageX,y:i.pageY}),t.positions.length>5&&t.positions.shift(),e=!1},5),e=!0},Gt.on("mousemove",this.handler)},cancel:function(){this.handler&&Gt.off("mousemove",this.handler)},movesTo:function(t){if(this.positions.length<2)return!1;var e=X(t),i=this.positions[this.positions.length-1],n=this.positions[0];if(e.left<=i.x&&i.x<=e.right&&e.top<=i.y&&i.y<=e.bottom)return!1;var o=[[{x:e.left,y:e.top},{x:e.right,y:e.bottom}],[{x:e.right,y:e.top},{x:e.left,y:e.bottom}]];return e.right<=i.x||(e.left>=i.x?(o[0].reverse(),o[1].reverse()):e.bottom<=i.y?o[0].reverse():e.top>=i.y&&o[1].reverse()),!!o.reduce(function(t,e){return t+(R(n,e[0])R(i,e[1]))},0)}};var xe={};xe.args=xe.created=xe.events=xe.init=xe.ready=xe.connected=xe.disconnected=xe.destroy=function(e,i){return e=e&&!t.isArray(e)?[e]:e,i?e?e.concat(i):t.isArray(i)?i:[i]:e},xe.update=function(e,i){return xe.args(e,t.isFunction(i)?{write:i}:i)},xe.props=function(e,i){return t.isArray(i)&&(i=i.reduce(function(t,e){return t[e]=String,t},{})),xe.methods(e,i)},xe.computed=xe.defaults=xe.methods=function(e,i){return i?e?t.extend(!0,{},e,i):i:e};var ke,Ce,Te,_e,Se,Ee=function(t,e){return T(e)?t:e},Ae={x:["width","left","right"],y:["height","top","bottom"]},Oe={};i(function(){var e,i,o,s=0,r=0;"MSGesture"in window&&(_e=new MSGesture,_e.target=document.body),n(document,"click",function(){return Se=!0},!0);var a=function(t){var e=t.velocityX>1?"Right":t.velocityX<-1?"Left":t.velocityY>1?"Down":t.velocityY<-1?"Up":null;e&&void 0!==Oe.el&&(Oe.el.trigger("swipe"),Oe.el.trigger("swipe"+e))};n(document,"MSGestureEnd",a),n(document,"gestureend",a),n(document,de,function(t){o=t.touches?t.touches[0]:t,e=Date.now(),i=e-(Oe.last||e),Oe.el=Vt("tagName"in o.target?o.target:o.target.parentNode),ke&&clearTimeout(ke),Oe.x1=o.pageX,Oe.y1=o.pageY,i>0&&i<=250&&(Oe.isDoubleTap=!0),Oe.last=e,!_e||"pointerdown"!==t.type&&"touchstart"!==t.type||_e.addPointer(t.pointerId),Se=t.button>0}),n(document,fe,function(t){o=t.touches?t.touches[0]:t,Oe.x2=o.pageX,Oe.y2=o.pageY,s+=Math.abs(Oe.x1-Oe.x2),r+=Math.abs(Oe.y1-Oe.y2)}),n(document,pe,function(){Oe.x2&&Math.abs(Oe.x1-Oe.x2)>30||Oe.y2&&Math.abs(Oe.y1-Oe.y2)>30?Te=setTimeout(function(){void 0!==Oe.el&&(Oe.el.trigger("swipe"),Oe.el.trigger("swipe"+et(Oe.x1,Oe.x2,Oe.y1,Oe.y2))),Oe={}},0):"last"in Oe&&(isNaN(s)||s<30&&r<30?Ce=setTimeout(function(){var e=t.Event("tap");e.cancelTouch=it,void 0!==Oe.el&&Oe.el.trigger(e),Oe.isDoubleTap?(void 0!==Oe.el&&Oe.el.trigger("doubleTap"),Oe={}):ke=setTimeout(function(){ke=null,void 0!==Oe.el&&(Oe.el.trigger("singleTap"),Se||Oe.el.trigger("click")),Oe={}},300)}):Oe={},s=r=0)}),n(document,ve,it),n(window,"scroll",it)});var De=!1;n(document,"touchstart",function(){return De=!0},!0),n(document,"click",function(){De=!1}),n(document,"touchcancel",function(){return De=!1},!0);var Ie=Object.freeze({win:Xt,doc:Gt,docElement:Qt,isRtl:Jt,isReady:e,ready:i,on:n,off:o,transition:s,Transition:Zt,animate:r,Animation:Kt,isJQuery:a,isWithin:l,attrFilter:h,removeClass:c,createEvent:u,isInView:d,getIndex:f,isVoidElement:p,Dimensions:ee,query:g,Observer:re,requestAnimationFrame:ae,hasPromise:ce,hasTouch:ue,pointerDown:de,pointerMove:fe,pointerUp:pe,pointerEnter:ge,pointerLeave:me,pointerCancel:ve,transitionend:we,animationstart:ye,animationend:be,getStyle:M,getCssVar:j,fastdom:$e,$:Vt,bind:m,hasOwn:v,promise:w,classify:y,hyphenate:b,camelize:$,isString:k,isNumber:C,isUndefined:T,isContextSelector:_,getContextSelectors:S,toJQuery:E,toNode:A,toBoolean:O,toNumber:D,toList:I,toMedia:N,coerce:B,toMs:P,swap:H,ajax:t.ajax,contains:t.contains,each:t.each,Event:t.Event,extend:t.extend,map:t.map,merge:t.merge,isArray:t.isArray,isNumeric:t.isNumeric,isFunction:t.isFunction,isPlainObject:t.isPlainObject,MouseTracker:Y,mergeOptions:U,position:V,getDimensions:X,offsetTop:G,flipPosition:tt,isTouch:nt}),Ne=function(t){this._init(t)};Ne.util=Ie,Ne.data="__uikit__",Ne.prefix="uk-",Ne.options={},Ne.instances={},Ne.elements=[],function(t){var e=t.data;t.use=function(t){if(!t.installed)return t.call(null,this),t.installed=!0,this},t.mixin=function(e,i){i=(k(i)?t.components[i]:i)||this,e=U({},e),e.mixins=i.options.mixins,delete i.options.mixins,i.options=U(e,i.options)},t.extend=function(t){t=t||{};var e=this,i=t.name||e.options.name,n=ot(i||"UIkitComponent");return n.prototype=Object.create(e.prototype),n.prototype.constructor=n,n.options=U(e.options,t),n.super=e,n.extend=e.extend,n},t.update=function(i,n,o){if(void 0===o&&(o=!1),i=u(i||"update"),!n)return void rt(t.instances,i);if(n=A(n),o)do{rt(n[e],i),n=n.parentNode}while(n);else st(n,function(t){return rt(t[e],i)})};var i;Object.defineProperty(t,"container",{get:function(){return i||document.body},set:function(t){i=t}})}(Ne),function(t){t.prototype._callHook=function(t){var e=this,i=this.$options[t];i&&i.forEach(function(t){return t.call(e)})},t.prototype._callReady=function(){this._isReady||(this._isReady=!0,this._callHook("ready"),this._callUpdate())},t.prototype._callConnected=function(){var e=this;this._connected||(~t.elements.indexOf(this.$options.el)||t.elements.push(this.$options.el),t.instances[this._uid]=this,this._initEvents(),this._callHook("connected"),this._connected=!0,this._initObserver(),this._isReady||i(function(){return e._callReady()}),this._callUpdate())},t.prototype._callDisconnected=function(){if(this._connected){this._observer&&(this._observer.disconnect(),this._observer=null);var e=t.elements.indexOf(this.$options.el);~e&&t.elements.splice(e,1),delete t.instances[this._uid],this._initEvents(!0),this._callHook("disconnected"),this._connected=!1}},t.prototype._callUpdate=function(t){var e=this;t=u(t||"update"),"update"===t.type&&(this._computeds={});var i=this.$options.update;i&&i.forEach(function(i,n){if("update"===t.type||i.events&&~i.events.indexOf(t.type)){if(t.sync)return i.read&&i.read.call(e,t),void(i.write&&i.write.call(e,t));i.read&&!~$e.reads.indexOf(e._frames.reads[n])&&(e._frames.reads[n]=$e.measure(function(){i.read.call(e,t),delete e._frames.reads[n]})),i.write&&!~$e.writes.indexOf(e._frames.writes[n])&&(e._frames.writes[n]=$e.mutate(function(){i.write.call(e,t),delete e._frames.writes[n]}))}})}}(Ne),function(e){var i=0;e.prototype.props={},e.prototype._init=function(t){t=t||{},t=this.$options=U(this.constructor.options,t,this),this.$el=null,this.$name=e.prefix+b(this.$options.name),this.$props={},this._uid=i++,this._initData(),this._initMethods(),this._initComputeds(),this._callHook("created"),this._frames={reads:{},writes:{}},t.el&&this.$mount(t.el)},e.prototype._initData=function(){var e=this,i=t.extend(!0,{},this.$options.defaults),n=this.$options.data||{},o=this.$options.args||[],s=this.$options.props||{};if(i){o.length&&t.isArray(n)&&(n=n.slice(0,o.length).reduce(function(e,i,n){return t.isPlainObject(i)?t.extend(e,i):e[o[n]]=i,e},{}));for(var r in i)e.$props[r]=e[r]=v(n,r)?B(s[r],n[r],e.$options.el):i[r]}},e.prototype._initMethods=function(){var t=this,e=this.$options.methods;if(e)for(var i in e)t[i]=m(e[i],t)},e.prototype._initComputeds=function(){var t=this,e=this.$options.computed;if(this._computeds={},e)for(var i in e)at(t,i,e[i])},e.prototype._initProps=function(e){var i=this;this._computeds={},t.extend(this.$props,e||this._getProps());var n=[this.$options.computed,this.$options.methods];for(var o in i.$props)ct(n,o)&&(i[o]=i.$props[o])},e.prototype._initEvents=function(t){var e=this,i=this.$options.events;i&&i.forEach(function(i){if(v(i,"handler"))lt(e,t,i);else for(var n in i)lt(e,t,i[n],n)})},e.prototype._initObserver=function(){var e=this;if(!this._observer&&this.$options.props&&this.$options.attrs&&re){var i=t.isArray(this.$options.attrs)?this.$options.attrs:Object.keys(this.$options.props).map(function(t){return b(t)});this._observer=new re(function(){var t=e._getProps();i.some(function(i){return!ut(t[i],e.$props[i])})&&e.$reset(t)}),this._observer.observe(this.$options.el,{attributes:!0,attributeFilter:i.concat([this.$name,"data-"+this.$name])})}},e.prototype._getProps=function(){var t,e,i={},n=this.$el[0],o=this.$options.args||[],s=this.$options.props||{},r=n.getAttribute(this.$name)||n.getAttribute("data-"+this.$name);if(!s)return i;for(t in s)if(e=b(t),n.hasAttribute(e)){var a=B(s[t],n.getAttribute(e),n);if("target"===e&&(!a||0===a.lastIndexOf("_",0)))continue;i[t]=a}if(!r)return i;if("{"===r[0])try{r=JSON.parse(r)}catch(t){console.warn("Invalid JSON."),r={}}else if(o.length&&!~r.indexOf(":")){l={},l[o[0]]=r,r=l;var l}else{var h={};r.split(";").forEach(function(t){var e=t.split(/:(.+)/),i=e[0],n=e[1];i&&n&&(h[i.trim()]=n.trim())}),r=h}for(t in r||{})e=$(t),void 0!==s[e]&&(i[e]=B(s[e],r[t],n));return i}}(Ne),function(t){var e=t.data;t.prototype.$mount=function(t){var i=this.$options.name;if(t[e]||(t[e]={}),t[e][i])return void console.warn('Component "'+i+'" is already mounted on element: ',t);t[e][i]=this,this.$el=Vt(t),this._initProps(),this._callHook("init"),document.documentElement.contains(t)&&this._callConnected()},t.prototype.$emit=function(t){this._callUpdate(t)},t.prototype.$emitSync=function(t){this._callUpdate(u(t||"update",!0,!1,{sync:!0}))},t.prototype.$update=function(e,i){t.update(e,this.$el,i)},t.prototype.$updateSync=function(t,e){this.$update(u(t||"update",!0,!1,{sync:!0}),e)},t.prototype.$reset=function(t){this._callDisconnected(),this._initProps(t),this._callConnected()},t.prototype.$destroy=function(t){void 0===t&&(t=!1);var i=this.$options.el;i&&this._callDisconnected(),this._callHook("destroy"),i&&i[e]&&(delete i[e][this.$options.name],Object.keys(i[e]).length||delete i[e],t&&this.$el.remove())}}(Ne),function(e){var i=e.data;e.components={},e.component=function(i,n){var o=$(i);return t.isPlainObject(n)?(n.name=o,n=e.extend(n)):n.options.name=o,e.components[o]=n,e[o]=function(i,n){for(var s=arguments.length,r=Array(s);s--;)r[s]=arguments[s];return t.isPlainObject(i)?new e.components[o]({data:i}):e.components[o].options.functional?new e.components[o]({data:[].concat(r)}):Vt(i).toArray().map(function(t){return e.getComponent(t,o)||new e.components[o]({el:t,data:n||{}})})[0]},e._initialized&&!n.options.functional&&$e.measure(function(){return e[o]("[uk-"+i+"],[data-uk-"+i+"]")}),e.components[o]},e.getComponents=function(t){return t&&(t=a(t)?t[0]:t)&&t[i]||{}},e.getComponent=function(t,i){return e.getComponents(t)[i]},e.connect=function(t){var n;if(t[i])for(n in t[i])t[i][n]._callConnected();for(var o=0;o',We='',ze='',qe='',Ye='',Re='',Ue='',Ve='',Xe='',Ge='',Qe='',Je='',Ze='',Ke='',ti='',ei={},ii=new DOMParser;return Ne.version="3.0.0-beta.22",function(t){t.mixin.class=He,t.mixin.modal=je,t.mixin.position=Le,t.mixin.togglable=Me}(Ne),function(t){var e,i,o,s=null,r=0;Xt.on("load",t.update).on("resize",function(e){o||(ae(function(){t.update(e),o=!1}),o=!0)}).on("scroll",function(n){null===s&&(s=0),s!==window.pageYOffset&&(e=s + + + + + + + + + OpenAIRE SUSHI Lite Client + + + + + + + + +
    + + + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +

    + 404: Page not found +

    +
    +
    +
    +
    +
    + + +
    + + diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html new file mode 100755 index 0000000..537c250 --- /dev/null +++ b/src/main/resources/static/index.html @@ -0,0 +1,107 @@ + + + + + + + + + + OpenAIRE SUSHI Lite Client + + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    +
    + +
    +

    Supported Reports

    + +
    +
    +
    +
    +
    + + +
    + + diff --git a/src/main/resources/static/sushilite/AR1/index.html b/src/main/resources/static/sushilite/AR1/index.html new file mode 100755 index 0000000..26d8c54 --- /dev/null +++ b/src/main/resources/static/sushilite/AR1/index.html @@ -0,0 +1,199 @@ + + + + + + + + + + OpenAIRE SUSHI Lite Client + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Report Request

    +
    +
    + Report Name: +
    +
    + +
    +
    +
    +
    + Release: +
    +
    + +
    +
    +
    +
    + Requestor: +
    +
    + +
    +
    +

    Report Filters

    +
    Date range
    +

    Valid date formats are yyyy-mm-dd or yyyy-mm. Default range is the last available month. +

    +
    +
    + Begin Date: +
    +
    + +
    +
    +
    +
    + End Date: +
    +
    + +
    +
    +
    Filters
    +

    Provide either a Repository Identifier or an Item Identifier
    + Identifier format: namespace:value
    + Valid namespace for Repository Identifier: openaire or opendoar.
    + Valid namespace for Item Identifier: openaire, doi or oid(for OAI-PMH). +

    +
    +
    + Repository Identifier: +
    +
    + +
    +
    +
    +
    + Item Identifier: +
    +
    + +
    +
    + +

    Report Attributes

    +

    Valid Granularity values: Monthly or Totals

    +
    +
    + Granularity: +
    +
    + +
    +
    + +

    The Pretty attribute is just for humans playing with the API and looking at results in a browser.

    +

    Pretty print json(p) for humans

    + + +
    +
    +
    +
    + + +
    + + diff --git a/src/main/resources/static/sushilite/BR1/index.html b/src/main/resources/static/sushilite/BR1/index.html new file mode 100755 index 0000000..cc50ca3 --- /dev/null +++ b/src/main/resources/static/sushilite/BR1/index.html @@ -0,0 +1,204 @@ + + + + + + + + + + OpenAIRE SUSHI Lite Client + + + + + + + + +
    + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Report Request

    +
    +
    + Report Name: +
    +
    + +
    +
    +
    +
    + Release: +
    +
    + +
    +
    +
    +
    + Requestor: +
    +
    + +
    +
    +

    Report Filters

    +
    Date range
    +

    Valid date formats are yyyy-mm-dd or yyyy-mm. Default range is the last available month. +

    +
    +
    + Begin Date: +
    +
    + +
    +
    +
    +
    + End Date: +
    +
    + +
    +
    +
    Filters
    +

    Provide either a Repository Identifier or an Item Identifier
    + Identifier format: namespace:value
    + Valid namespace for Repository Identifier: openaire or opendoar.
    + Valid namespace for Item Identifier: openaire, doi or oid(for OAI-PMH). +

    +
    +
    + Repository Identifier: +
    +
    + +
    +
    +
    +
    + Item Identifier: +
    +
    + +
    +
    + +

    Report Attributes

    +

    Valid Granularity values: Monthly or Totals

    +
    +
    + Granularity: +
    +
    + +
    +
    + +

    The Pretty attribute is just for humans playing with the API and looking at results in a browser.

    +

    Pretty print json(p) for humans

    + + +
    +
    +
    +
    + + +
    + + diff --git a/src/main/resources/static/sushilite/BR2/index.html b/src/main/resources/static/sushilite/BR2/index.html new file mode 100755 index 0000000..093eb0a --- /dev/null +++ b/src/main/resources/static/sushilite/BR2/index.html @@ -0,0 +1,199 @@ + + + + + + + + + + OpenAIRE SUSHI Lite Client + + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Report Request

    +
    +
    + Report Name: +
    +
    + +
    +
    +
    +
    + Release: +
    +
    + +
    +
    +
    +
    + Requestor: +
    +
    + +
    +
    +

    Report Filters

    +
    Date range
    +

    Valid date formats are yyyy-mm-dd or yyyy-mm. Default range is the last available month. +

    +
    +
    + Begin Date: +
    +
    + +
    +
    +
    +
    + End Date: +
    +
    + +
    +
    +
    Filters
    +

    Provide either a Repository Identifier or an Item Identifier
    + Identifier format: namespace:value
    + Valid namespace for Repository Identifier: openaire or opendoar.
    + Valid namespace for Item Identifier: openaire, doi or oid(for OAI-PMH). +

    +
    +
    + Repository Identifier: +
    +
    + +
    +
    +
    +
    + Item Identifier: +
    +
    + +
    +
    + +

    Report Attributes

    +

    Valid Granularity values: Monthly or Totals

    +
    +
    + Granularity: +
    +
    + +
    +
    + +

    The Pretty attribute is just for humans playing with the API and looking at results in a browser.

    +

    Pretty print json(p) for humans

    + + +
    +
    +
    +
    + + +
    + + diff --git a/src/main/resources/static/sushilite/IR1/index.html b/src/main/resources/static/sushilite/IR1/index.html new file mode 100755 index 0000000..36e175b --- /dev/null +++ b/src/main/resources/static/sushilite/IR1/index.html @@ -0,0 +1,239 @@ + + + + + + + + + + OpenAIRE SUSHI Lite Client + + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Report Request

    +
    +
    + Report Name: +
    +
    + +
    +
    +
    +
    + Release: +
    +
    + +
    +
    +
    +
    + Requestor: +
    +
    + +
    +
    +

    Report Filters

    +
    Date range
    +

    Valid date formats are yyyy-mm-dd or yyyy-mm. Default range is the last available month. +

    +
    +
    + Begin Date: +
    +
    + +
    +
    +
    +
    + End Date: +
    +
    + +
    +
    +
    Filters
    +

    Provide either a Repository Identifier or an Item Identifier
    + Identifier format: namespace:value
    + Valid namespace for Repository Identifier: openaire or opendoar.
    + Valid namespace for Item Identifier: openaire, doi or oid(for OAI-PMH). +

    +
    +
    + Repository Identifier: +
    +
    + +
    +
    +
    +
    + Item Identifier: +
    +
    + +
    +
    +

    Optional filter to only show results for a single item type, e.g. article, book, etc.

    +
    +
    + Item Data Type: +
    +
    + +
    +
    + +

    Report Attributes

    +

    Valid Granularity values: Monthly or Totals

    +
    +
    + Granularity: +
    +
    + +
    +
    + +

    The Pretty attribute is just for humans playing with the API and looking at results in a browser.

    +

    Pretty print json(p) for humans

    + + +
    +
    +
    +
    + + +
    + + diff --git a/src/main/resources/static/sushilite/JR1/index.html b/src/main/resources/static/sushilite/JR1/index.html new file mode 100755 index 0000000..a2d43d7 --- /dev/null +++ b/src/main/resources/static/sushilite/JR1/index.html @@ -0,0 +1,226 @@ + + + + + + + + + + OpenAIRE SUSHI Lite Client + + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Report Request

    +
    +
    + Report Name: +
    +
    + +
    +
    +
    +
    + Release: +
    +
    + +
    +
    +
    +
    + Requestor: +
    +
    + +
    +
    +

    Report Filters

    +
    Date range
    +

    Valid date formats are yyyy-mm-dd or yyyy-mm. Default range is the last available month. +

    +
    +
    + Begin Date: +
    +
    + +
    +
    +
    +
    + End Date: +
    +
    + +
    +
    +
    Optional Filters
    +
    +
    + Journal Identifier: +
    +
    + +
    +
    +

    Optional filter to only show results for a single item type, e.g. article, book, etc.

    +
    +
    + Item Data Type: +
    +
    + +
    +
    + +

    Report Attributes

    +

    Valid Granularity values: Monthly or Totals

    +
    +
    + Granularity: +
    +
    + +
    +
    + +

    The Pretty attribute is just for humans playing with the API and looking at results in a browser.

    +

    Pretty print json(p) for humans

    + + +
    +
    +
    +
    + + +
    + + diff --git a/src/main/resources/static/sushilite/RR1/index.html b/src/main/resources/static/sushilite/RR1/index.html new file mode 100755 index 0000000..49f9556 --- /dev/null +++ b/src/main/resources/static/sushilite/RR1/index.html @@ -0,0 +1,230 @@ + + + + + + + + + + OpenAIRE SUSHI Lite Client + + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Report Request

    +
    +
    + Report Name: +
    +
    + +
    +
    +
    +
    + Release: +
    +
    + +
    +
    +
    +
    + Requestor: +
    +
    + +
    +
    +

    Report Filters

    +
    Date range
    +

    Valid date formats are yyyy-mm-dd or yyyy-mm. Default range is the last available month. +

    +
    +
    + Begin Date: +
    +
    + +
    +
    +
    +
    + End Date: +
    +
    + +
    +
    +
    Optional Filters
    +

    By default results are returned for all repositories. Use this filter to get results for a single repository
    + Repository Identifier format: namespace:value
    + valid namespace: openaire or opendoar.
    +

    +
    +
    + Repository identifier: +
    +
    + +
    +
    +

    Optional filter to only show results for a single item type, e.g. article, book, etc.

    +
    +
    + Item Data Type: +
    +
    + +
    +
    + +

    Report Attributes

    +

    Valid Granularity values: Monthly or Totals

    +
    +
    + Granularity: +
    +
    + +
    +
    + +

    The Pretty attribute is just for humans playing with the API and looking at results in a browser.

    +

    Pretty print json(p) for humans

    + + +
    +
    +
    +
    + + +
    + + diff --git a/src/main/resources/static/sushilite/index.html b/src/main/resources/static/sushilite/index.html new file mode 100755 index 0000000..521fa71 --- /dev/null +++ b/src/main/resources/static/sushilite/index.html @@ -0,0 +1,107 @@ + + + + + + + + + + OpenAIRE SUSHI Lite Client + + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    +
    + +
    +

    Supported Reports

    + +
    +
    +
    +
    +
    + + +
    + +